Created
June 15, 2018 19:36
-
-
Save felipebaltazar/8a67fb25aebc0fa7c6f6c5e1366996a2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Draw.Application.Aplication; | |
using Draw.Application.Helpers; | |
using Draw.Application.Helpers.Managers.Commands; | |
using Draw.Application.Ressources.Languages; | |
using Draw.Core.Extensions; | |
using Draw.Core.Helpers; | |
using Draw.Math.Helpers; | |
using Draw.Math.Models; | |
using Draw.Models.DraftModels; | |
using Draw.Models.WallModels; | |
using SkiaSharp; | |
using SkiaSharp.Views.Forms; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Reflection; | |
using Xamarin.Forms; | |
namespace Draw.Application.DrawSpace | |
{ | |
public class BluePrint : Ambient2D | |
{ | |
#region Bindable Properties | |
public static readonly BindableProperty SnapModeProperty = BindableProperty.Create( | |
propertyName: nameof(SnapMode), | |
returnType: typeof(bool), | |
declaringType: typeof(BluePrint), | |
defaultValue: true, | |
defaultBindingMode: BindingMode.TwoWay, | |
propertyChanged: OnSnapModeChanged); | |
public static readonly BindableProperty QuotasOnProperty = BindableProperty.Create( | |
propertyName: nameof(QuotasOn), | |
returnType: typeof(bool), | |
declaringType: typeof(BluePrint), | |
defaultValue: true, | |
defaultBindingMode: BindingMode.TwoWay, | |
propertyChanged: OnQuotasOnChanged); | |
public static readonly BindableProperty ChildsOnProperty = BindableProperty.Create( | |
propertyName: nameof(ChildsOn), | |
returnType: typeof(bool), | |
declaringType: typeof(BluePrint), | |
defaultValue: true, | |
defaultBindingMode: BindingMode.TwoWay, | |
propertyChanged: OnChildsOnChanged); | |
public static readonly BindableProperty VertsOnProperty = BindableProperty.Create( | |
propertyName: nameof(VertsOn), | |
returnType: typeof(bool), | |
declaringType: typeof(BluePrint), | |
defaultValue: true, | |
defaultBindingMode: BindingMode.TwoWay, | |
propertyChanged: OnVertsOnChanged); | |
public static readonly BindableProperty IsDrawingProperty = BindableProperty.Create( | |
propertyName: nameof(IsDrawing), | |
returnType: typeof(bool), | |
declaringType: typeof(BluePrint), | |
defaultValue: false, | |
defaultBindingMode: BindingMode.TwoWay, | |
propertyChanged: OnIsDrawingChanged); | |
public static readonly BindableProperty SelectedWallProperty = BindableProperty.Create( | |
propertyName: nameof(SelectedWall), | |
returnType: typeof(WallProperty), | |
declaringType: typeof(BluePrint), | |
defaultValue: null, | |
defaultBindingMode: BindingMode.TwoWay, | |
propertyChanged: OnSelectedWallChanged); | |
#endregion | |
#region Bindable Events | |
private static void OnSelectedWallChanged(BindableObject bindable, object oldValue, object newValue) | |
{ | |
if(bindable is BluePrint control) | |
{ | |
if(newValue is WallProperty selectedWall) | |
{ | |
control.SelectedWall = selectedWall; | |
} | |
} | |
} | |
private static void OnIsDrawingChanged(BindableObject bindable, object oldValue, object newValue) | |
{ | |
if (bindable is BluePrint control) | |
{ | |
if (newValue is bool isDrawing) | |
control.IsDrawing = isDrawing; | |
} | |
} | |
private static void OnQuotasOnChanged(BindableObject bindable, object oldValue, object newValue) | |
{ | |
if (bindable is BluePrint control) | |
{ | |
if (newValue is bool quotasOn) | |
control.QuotasOn = quotasOn; | |
} | |
} | |
private static void OnVertsOnChanged(BindableObject bindable, object oldValue, object newValue) | |
{ | |
if (bindable is BluePrint control) | |
{ | |
if (newValue is bool vertsOn) | |
control.VertsOn = vertsOn; | |
} | |
} | |
private static void OnSnapModeChanged(BindableObject bindable, object oldValue, object newValue) | |
{ | |
if (bindable is BluePrint control) | |
{ | |
if (newValue is bool snapMode) | |
control.SnapMode = snapMode; | |
} | |
} | |
private static void OnChildsOnChanged(BindableObject bindable, object oldValue, object newValue) | |
{ | |
if (bindable is BluePrint control) | |
{ | |
if (newValue is bool childsOn) | |
control.ChildsOn = childsOn; | |
} | |
} | |
#endregion | |
#region Private values | |
private int _gridStep = 50; | |
private int _rulerSize = 150; | |
private int _wallHeight = 2600; | |
private int _rulerFontSize = 35; | |
private int _quotaFontSize = 35; | |
private int _quotaDistance = 300; | |
private int _gridDivisions = 250; | |
private int _wallThickness = 150; | |
private bool _drawSingleVertice; | |
private bool _snapMode = true; | |
private bool _childsOn = true; | |
private bool _quotasOn = true; | |
private bool _vertsOn = true; | |
private Vector2D _selectedVertice; | |
private WallProperty _selectedWall; | |
private BluePrintCommands _commands; | |
private Vector2D _previousVertPosition = new Vector2D(); | |
#endregion | |
#region Public properties | |
public ObservableRangeCollection<WallProperty> DraftWalls { get; set; } | |
public Vector2D SelectedWallIntersect { get; set; } | |
public Alignment Alignment { get; set; } | |
public BluePrintCommands Commands | |
{ | |
get { return _commands; } | |
set | |
{ | |
if (value == _commands) | |
return; | |
_commands = value; | |
OnPropertyChanged(); | |
} | |
} | |
public WallProperty SelectedWall | |
{ | |
get => _selectedWall; | |
set | |
{ | |
if (_selectedWall != value) | |
{ | |
if (value == null) | |
SelectedWallIntersect = null; | |
else | |
{ | |
if(TouchLocation != null) | |
SelectedWallIntersect = new Vector2D( | |
TouchLocation.X, TouchLocation.Y); | |
} | |
_selectedWall = value; | |
MessagingCenter.Send(this, MessagingDictionary.SELECTEDWALL_CHANGED, value); | |
} | |
} | |
} | |
public Vector2D SelectedVertice | |
{ | |
get => _selectedVertice; | |
set | |
{ | |
if (value == _selectedVertice) | |
return; | |
if (value == null) | |
{ | |
PreviousPosition.X = 0; | |
PreviousPosition.Y = 0; | |
} | |
_selectedVertice = value; | |
} | |
} | |
public int QuotaFontSize | |
{ | |
get => _quotaFontSize; | |
set | |
{ | |
if(_quotaDistance == value) | |
return; | |
_quotaFontSize = value; | |
CanvasView?.InvalidateSurface(); | |
} | |
} | |
public int QuotaDistance | |
{ | |
get => _quotaDistance; | |
set | |
{ | |
if(_quotaDistance == value) | |
return; | |
_quotaDistance = value; | |
CanvasView?.InvalidateSurface(); | |
} | |
} | |
public int WallThickness | |
{ | |
get { return _wallThickness; } | |
set | |
{ | |
if (value == _wallThickness) | |
return; | |
_wallThickness = value; | |
OnPropertyChanged(); | |
} | |
} | |
public int WallHeight | |
{ | |
get { return _wallHeight; } | |
set | |
{ | |
if (_wallHeight == value) | |
return; | |
_wallHeight = value; | |
OnPropertyChanged(); | |
} | |
} | |
public bool SnapMode | |
{ | |
get { return _snapMode; } | |
set | |
{ | |
if (_snapMode == value) | |
return; | |
_snapMode = value; | |
OnPropertyChanged(); | |
} | |
} | |
public bool QuotasOn | |
{ | |
get => _quotasOn; | |
set | |
{ | |
if(value == _quotasOn) | |
return; | |
_quotasOn = value; | |
OnPropertyChanged(); | |
CanvasView?.InvalidateSurface(); | |
} | |
} | |
public bool ChildsOn | |
{ | |
get => _childsOn; | |
set | |
{ | |
if(value == _childsOn) | |
return; | |
_childsOn = value; | |
OnPropertyChanged(); | |
CanvasView?.InvalidateSurface(); | |
} | |
} | |
public bool VertsOn | |
{ | |
get => _vertsOn; | |
set | |
{ | |
if(value == _vertsOn) | |
return; | |
_vertsOn = value; | |
OnPropertyChanged(); | |
CanvasView?.InvalidateSurface(); | |
} | |
} | |
#endregion | |
#region Constructors | |
public BluePrint() : base() | |
{ | |
if(DraftWalls == null) | |
DraftWalls = new ObservableRangeCollection<WallProperty>(); | |
Commands = new BluePrintCommands(this); | |
_gridDivisions = AppConfig.SettingsDao?.List? | |
.LastOrDefault()?.GridDivisions?.ToInt32() ?? _gridDivisions; | |
} | |
#endregion | |
#region Override Methods | |
internal override void OnCanvasViewPaintSurface(object sender, | |
SKPaintSurfaceEventArgs args) | |
{ | |
if (!KeepSelection) | |
{ | |
SelectedVertice = null; | |
SelectedWall = null; | |
} | |
else | |
{ | |
KeepSelection = false; | |
} | |
var info = args.Info; | |
var surface = args.Surface; | |
var canvas = surface.Canvas; | |
base.OnCanvasViewPaintSurface(sender, args); | |
canvas.Clear(); | |
DrawGrid(info, surface, canvas); | |
if(_drawSingleVertice && IsDrawing) | |
{ | |
canvas.Save(); | |
canvas.Translate(LastTouch.X, LastTouch.Y); | |
using (var rectPaint = new SKPaint()) | |
{ | |
rectPaint.Style = SKPaintStyle.Fill; | |
rectPaint.Color = Color.Blue.ToSKColor(); | |
var vertPoint = new SKRect() | |
{ | |
Location = new SKPoint(-50, -50), | |
Size = new SKSize(100, 100) | |
}; | |
canvas.DrawRect(vertPoint, rectPaint); | |
} | |
canvas.Restore(); | |
} | |
DrawDraft(info, surface, canvas); | |
DrawMoveArrows(info, surface, canvas); | |
DrawRuler(info, surface, canvas); | |
} | |
internal override void SingleTapGestureTapped(object sender) | |
{ | |
base.SingleTapGestureTapped(sender); | |
if (LastTouch != null && TouchLocation != null && LastTouch != TouchLocation) | |
{ | |
var wallStart = new Vector2D(); | |
var wallEnd = new Vector2D(); | |
if (CheckAnyCollision()) | |
return; | |
Commands.InsertUndo(); | |
DraftWalls.Add(new WallProperty | |
{ | |
WallName = Guid.NewGuid().ToString(), | |
WallStartX = LastTouch.X, | |
WallStartY = LastTouch.Y, | |
WallEndX = TouchLocation.X, | |
WallEndY = TouchLocation.Y, | |
Wallthickness = WallThickness, | |
StartHeight = WallHeight, | |
EndHeight = WallHeight | |
}); | |
LastTouch.X = TouchLocation.X; | |
LastTouch.Y = TouchLocation.Y; | |
_drawSingleVertice = false; | |
CanvasView?.InvalidateSurface(); | |
} | |
else | |
{ | |
LastTouch = new Vector2D(TouchLocation.X, TouchLocation.Y); | |
_drawSingleVertice = true; | |
CanvasView?.InvalidateSurface(); | |
} | |
} | |
internal override void PanGesturePanUpdated(object sender, PanUpdatedEventArgs e) | |
{ | |
if (e.StatusType == GestureStatus.Running) | |
{ | |
if (SelectedVertice != null) | |
{ | |
MoveSelectedVertice(e); | |
return; | |
} | |
} | |
base.PanGesturePanUpdated(sender, e); | |
} | |
internal override void CenterDraw() | |
{ | |
if (!(DraftWalls?.Count > 0)) | |
{ | |
ResetLocation(); | |
return; | |
} | |
var (max, min) = Math2D.GetDrawLimits(DraftWalls); | |
var center = Math2D.Center(min, max); | |
var centerXScreen = WidthScreen > 0 ? WidthScreen / 2 : 0; | |
var centerYScreen = HeightScreen > 0 ? HeightScreen / 2 : 0; | |
CanvasPosition = new Vector2D(centerXScreen - center.X, | |
centerYScreen - center.Y); | |
CanvasView?.InvalidateSurface(); | |
} | |
#endregion | |
#region Private Methods | |
private void DrawMoveArrows(SKImageInfo info, | |
SKSurface surface, SKCanvas canvas) | |
{ | |
if (SelectedVertice == null) | |
return; | |
canvas.Save(); | |
canvas.Translate(SelectedVertice.X, SelectedVertice.Y); | |
var arrowSize = 100 / CanvasScale; | |
var assembly = Assembly.GetExecutingAssembly(); | |
using (var resource = assembly.GetManifestResourceStream("Draw.Application.Ressources.ToolBox.move.png")) | |
using (var stream = new SKManagedStream(resource)) | |
using (var source = SKBitmap.Decode(stream)) | |
{ | |
var rec = new SKRect(0, 0, arrowSize, arrowSize) | |
{ | |
Location = new SKPoint(-arrowSize / 2, -arrowSize / 2) | |
}; | |
canvas.DrawImage(SKImage.FromBitmap(source), rec); | |
} | |
canvas.Restore(); | |
} | |
private void DrawGrid(SKImageInfo info, SKSurface surface, SKCanvas canvas) | |
{ | |
WidthScreen = canvas.LocalClipBounds.Size.Width; | |
HeightScreen = canvas.LocalClipBounds.Size.Height; | |
var divisionsParameter = GetDivisionsParameter(); | |
var largeDivisionParameter = divisionsParameter * 4; | |
var xRepetitions = (System.Math.Round(WidthScreen / largeDivisionParameter) + 1).ToInt32(); | |
var yRepetitions = (System.Math.Round(HeightScreen / largeDivisionParameter) + 1).ToInt32(); | |
var largeDisplacementX = (System.Math.Round(canvas.LocalClipBounds.Location.X / largeDivisionParameter)).ToInt32(); | |
var largeDisplacementY = (System.Math.Round(canvas.LocalClipBounds.Location.Y / largeDivisionParameter)).ToInt32(); | |
var skinnyDisplacementX = (System.Math.Round(canvas.LocalClipBounds.Location.X / divisionsParameter)).ToInt32(); | |
var skinnyDisplacementY = (System.Math.Round(canvas.LocalClipBounds.Location.Y / divisionsParameter)).ToInt32(); | |
var paint = new SKPaint | |
{ | |
Style = SKPaintStyle.Fill, | |
Color = BackgroundColor.ToSKColor(), | |
StrokeWidth = 2 / CanvasScale, | |
IsAntialias = HasAntialias(), | |
}; | |
if(IsZooning || IsPanning) | |
{ | |
using(var backgroundPath = new SKPath()) | |
{ | |
backgroundPath.MoveTo( | |
canvas.LocalClipBounds.Location.X, canvas.LocalClipBounds.Location.Y); | |
backgroundPath.LineTo( | |
canvas.LocalClipBounds.Location.X + canvas.LocalClipBounds.Size.Width, | |
canvas.LocalClipBounds.Location.Y); | |
backgroundPath.LineTo( | |
canvas.LocalClipBounds.Location.X + canvas.LocalClipBounds.Size.Width, | |
canvas.LocalClipBounds.Location.Y + canvas.LocalClipBounds.Size.Height); | |
backgroundPath.LineTo( | |
canvas.LocalClipBounds.Location.X, | |
canvas.LocalClipBounds.Location.Y + canvas.LocalClipBounds.Size.Height); | |
backgroundPath.Close(); | |
canvas.DrawPath(backgroundPath,paint); | |
} | |
} | |
paint.Color = Color.LightGray.ToSKColor(); | |
paint.Style = SKPaintStyle.Stroke; | |
paint.IsStroke = true; | |
#region grid 0,250 m² | |
xRepetitions = xRepetitions * 4; | |
yRepetitions = yRepetitions * 4; | |
for (int i = 0; i <= xRepetitions; i++) | |
{ | |
using (var skinnyLinesPath = new SKPath()) | |
{ | |
skinnyLinesPath.MoveTo((i * divisionsParameter) + (skinnyDisplacementX * divisionsParameter), | |
canvas.LocalClipBounds.Location.Y); | |
skinnyLinesPath.LineTo((i * divisionsParameter) + (skinnyDisplacementX * divisionsParameter), | |
(HeightScreen) + canvas.LocalClipBounds.Location.Y); | |
canvas.DrawPath(skinnyLinesPath, paint); | |
} | |
} | |
for (int i = 0; i <= yRepetitions; i++) | |
{ | |
using (var skinnyLinesPath = new SKPath()) | |
{ | |
skinnyLinesPath.MoveTo(canvas.LocalClipBounds.Location.X, | |
(i * divisionsParameter) + (skinnyDisplacementY * divisionsParameter)); | |
skinnyLinesPath.LineTo((WidthScreen) + canvas.LocalClipBounds.Location.X, | |
(i * divisionsParameter) + (skinnyDisplacementY * divisionsParameter)); | |
canvas.DrawPath(skinnyLinesPath, paint); | |
} | |
} | |
#endregion | |
#region grid 1 m² | |
xRepetitions = xRepetitions / 4; | |
yRepetitions = yRepetitions / 4; | |
paint.StrokeWidth = 3 / CanvasScale; | |
paint.Color = Color.Gray.ToSKColor(); | |
for (int i = 0; i <= xRepetitions; i++) | |
{ | |
using (var largeLinesPath = new SKPath()) | |
{ | |
largeLinesPath.MoveTo((i * largeDivisionParameter) + (largeDisplacementX * largeDivisionParameter), | |
canvas.LocalClipBounds.Location.Y); | |
largeLinesPath.LineTo((i * largeDivisionParameter) + (largeDisplacementX * largeDivisionParameter), | |
HeightScreen + canvas.LocalClipBounds.Location.Y); | |
canvas.DrawPath(largeLinesPath, paint); | |
} | |
} | |
for (int i = 0; i <= yRepetitions; i++) | |
{ | |
using (var largeLinesPath = new SKPath()) | |
{ | |
largeLinesPath.MoveTo(canvas.LocalClipBounds.Location.X, | |
(i * largeDivisionParameter) + (largeDisplacementY * largeDivisionParameter)); | |
largeLinesPath.LineTo(WidthScreen + canvas.LocalClipBounds.Location.X, | |
(i * largeDivisionParameter) + (largeDisplacementY * largeDivisionParameter)); | |
canvas.DrawPath(largeLinesPath, paint); | |
} | |
} | |
#endregion | |
} | |
private void DrawDraft(SKImageInfo info, | |
SKSurface surface, SKCanvas canvas) | |
{ | |
DrawFloor(info, surface, canvas); | |
DrawWalls(info, surface, canvas); | |
} | |
private void DrawFloor(SKImageInfo info, | |
SKSurface surface, SKCanvas canvas) | |
{ | |
var paint = new SKPaint | |
{ | |
Style = SKPaintStyle.Fill, | |
Color = Color.WhiteSmoke.ToSKColor(), | |
StrokeWidth = 3 / CanvasScale, | |
TextSize = 3, | |
IsAntialias = HasAntialias() | |
}; | |
using (var floorPath = new SKPath()) | |
{ | |
foreach (var wall in DraftWalls) | |
{ | |
var previousWall = Math2D.GetPreviousWall(wall, DraftWalls); | |
if(previousWall == null) | |
floorPath.MoveTo(wall.WallStartX, wall.WallStartY); | |
floorPath.LineTo(wall.WallEndX, wall.WallEndY); | |
var nexWall = Math2D.GetNextWall(wall, DraftWalls); | |
if (nexWall == null) | |
{ | |
if (previousWall != null) | |
{ | |
floorPath.Close(); | |
canvas.DrawPath(floorPath, paint); | |
floorPath.Reset(); | |
} | |
} | |
} | |
floorPath.Close(); | |
canvas.DrawPath(floorPath, paint); | |
} | |
} | |
private void DrawWalls(SKImageInfo info, | |
SKSurface surface, SKCanvas canvas) | |
{ | |
var paint = new SKPaint | |
{ | |
Style = SKPaintStyle.Stroke, | |
Color = Color.Black.ToSKColor(), | |
StrokeWidth = 3 / CanvasScale, | |
TextSize = 3, | |
IsAntialias = HasAntialias() | |
}; | |
foreach (var wall in DraftWalls) | |
{ | |
paint.Style = SKPaintStyle.Fill; | |
paint.Color = Color.LightGray.ToSKColor(); | |
using (var wallsPath = new SKPath()) | |
{ | |
var previousWall = Math2D.GetPreviousWall(wall, DraftWalls); | |
var nextWall = Math2D.GetNextWall(wall, DraftWalls); | |
var startPoint = new Vector2D(wall.WallStartX, wall.WallStartY); | |
var endPoint = new Vector2D(wall.WallEndX, wall.WallEndY); | |
var wallAngle = Math2D.AngleByTwoPoints( | |
startPoint, | |
endPoint); | |
var width = Math2D.CalculeWidthByTwoPoints( | |
startPoint, | |
endPoint); | |
double previousConnection = 0; | |
double nextConnection = 0; | |
if(previousWall != null) | |
{ | |
var angleBetweenWalls = Math2D.AngleByThreePoints(previousWall,startPoint,endPoint); | |
angleBetweenWalls = (180 - angleBetweenWalls) ; | |
previousConnection = Math2D.GetConnection(angleBetweenWalls, wall.Wallthickness); | |
} | |
if(nextWall != null) | |
{ | |
var angleBetweenWalls = Math2D.AngleByThreePoints(startPoint, endPoint, nextWall); | |
angleBetweenWalls = (180 - angleBetweenWalls); | |
nextConnection = Math2D.GetConnection(angleBetweenWalls, wall.Wallthickness); | |
} | |
if (SelectedWall == wall || | |
(!IsDrawing && !IsPanning && !IsZooning && SelectedWall == null | |
&& SelectedVertice == null && IsTouched(startPoint, endPoint, TouchLocation))) | |
{ | |
paint.Color = Color.Red.ToSKColor(); | |
SelectedWall = wall; | |
} | |
canvas.Save(); | |
canvas.Translate(wall.WallStartX, wall.WallStartY); | |
canvas.RotateDegrees(wallAngle.ToSingle()); | |
wallsPath.MoveTo(0,0); | |
wallsPath.LineTo(width,0); | |
wallsPath.LineTo(width + nextConnection.ToSingle(), -wall.Wallthickness); | |
wallsPath.LineTo(0 - previousConnection.ToSingle(), -wall.Wallthickness); | |
wallsPath.Close(); | |
canvas.DrawPath(wallsPath, paint); | |
var assembly = Assembly.GetExecutingAssembly(); | |
using (var resource = assembly.GetManifestResourceStream("Draw.Application.Ressources.Identity.hatch.png")) | |
using (var stream = new SKManagedStream(resource)) | |
using (var source = SKBitmap.Decode(stream)) | |
{ | |
var matrix = SKMatrix.MakeRotation(30.0f); | |
matrix.ScaleX = 0.7f / CanvasScale; | |
matrix.ScaleY = 0.7f / CanvasScale; | |
using (var shader = SKShader.CreateBitmap(source, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, matrix)) | |
using (var hatchPaint = new SKPaint()) | |
{ | |
hatchPaint.Style = SKPaintStyle.Fill; | |
hatchPaint.StrokeWidth = 6 / CanvasScale; | |
hatchPaint.TextSize = 3; | |
hatchPaint.IsAntialias = HasAntialias(); | |
hatchPaint.Shader = shader; | |
canvas.DrawPath(wallsPath, hatchPaint); | |
}; | |
} | |
paint.Color = Color.Black.ToSKColor(); | |
paint.Style = SKPaintStyle.Stroke; | |
canvas.DrawPath(wallsPath, paint); | |
if (VertsOn) | |
DrawVertices(canvas, width, startPoint, endPoint); | |
if (ChildsOn) | |
DrawWallChilds(canvas, width, wall.Wallthickness, wall.Children.ToArray()); | |
if (QuotasOn) | |
DrawQuotas(canvas, width, wallAngle.ToSingle()); | |
canvas.Restore(); | |
} | |
} | |
paint.Dispose(); | |
} | |
private void DrawRuler(SKImageInfo info, SKSurface surface, SKCanvas canvas) | |
{ | |
var divisionsParameter = GetDivisionsParameter(); | |
var scaledRulerSize = _rulerSize / CanvasScale; | |
using (var paint = new SKPaint() | |
{ | |
Style = SKPaintStyle.Fill, | |
Color = Color.White.ToSKColor(), | |
StrokeWidth = 2 / CanvasScale, | |
IsAntialias = HasAntialias(), | |
TextSize = _rulerFontSize / CanvasScale, | |
TextAlign = SKTextAlign.Center | |
}) | |
{ | |
using (var ruler = new SKPath()) | |
{ | |
ruler.MoveTo(canvas.LocalClipBounds.Location.X, canvas.LocalClipBounds.Location.Y); | |
ruler.LineTo(canvas.LocalClipBounds.Location.X + canvas.LocalClipBounds.Size.Width, | |
canvas.LocalClipBounds.Location.Y); | |
ruler.LineTo(canvas.LocalClipBounds.Location.X + canvas.LocalClipBounds.Size.Width, | |
canvas.LocalClipBounds.Location.Y + scaledRulerSize); | |
ruler.LineTo(canvas.LocalClipBounds.Location.X + scaledRulerSize, | |
canvas.LocalClipBounds.Location.Y + scaledRulerSize); | |
ruler.LineTo(canvas.LocalClipBounds.Location.X + scaledRulerSize, | |
canvas.LocalClipBounds.Location.Y + canvas.LocalClipBounds.Size.Height); | |
ruler.LineTo(canvas.LocalClipBounds.Location.X, | |
canvas.LocalClipBounds.Location.Y + canvas.LocalClipBounds.Size.Height); | |
ruler.Close(); | |
canvas.DrawPath(ruler, paint); | |
paint.Color = Color.Black.ToSKColor(); | |
paint.Style = SKPaintStyle.Stroke; | |
canvas.DrawPath(ruler, paint); | |
} | |
var largeDivisionParameter = divisionsParameter * 4; | |
var xRepetitions = ((WidthScreen / largeDivisionParameter).Round() + 1).ToInt32(); | |
var yRepetitions = ((HeightScreen / largeDivisionParameter).Round() + 1).ToInt32(); | |
var largeDisplacementX = ((canvas.LocalClipBounds.Location.X / largeDivisionParameter).Round()).ToInt32(); | |
var largeDisplacementY = ((canvas.LocalClipBounds.Location.Y / largeDivisionParameter).Round()).ToInt32(); | |
var skinnyDisplacementX = ((canvas.LocalClipBounds.Location.X / divisionsParameter).Round()).ToInt32(); | |
var skinnyDisplacementY = ((canvas.LocalClipBounds.Location.Y / divisionsParameter).Round()).ToInt32(); | |
paint.Style = SKPaintStyle.Stroke; | |
paint.StrokeWidth = 4 / CanvasScale; | |
paint.Color = Color.Black.ToSKColor(); | |
paint.IsAntialias = HasAntialias(); | |
paint.IsStroke = true; | |
var largeXPositions = new List<float>(); | |
var largeYPositions = new List<float>(); | |
#region grid 1 m² | |
for (int i = 0; i <= xRepetitions; i++) | |
{ | |
using (var largeLinesPath = new SKPath()) | |
{ | |
var xPosition = (i * largeDivisionParameter) + (largeDisplacementX * largeDivisionParameter); | |
var yEndPosition = (scaledRulerSize - (scaledRulerSize / 1.3f)) + canvas.LocalClipBounds.Location.Y; | |
largeXPositions.Add(xPosition); | |
largeLinesPath.MoveTo(xPosition, canvas.LocalClipBounds.Location.Y + scaledRulerSize); | |
largeLinesPath.LineTo(xPosition, yEndPosition); | |
canvas.DrawPath(largeLinesPath, paint); | |
paint.Style = SKPaintStyle.Fill; | |
canvas.DrawText($"{xPosition} mm", | |
xPosition, | |
yEndPosition, | |
paint); | |
paint.Style = SKPaintStyle.Stroke; | |
} | |
} | |
for (int i = 0; i <= yRepetitions; i++) | |
{ | |
using (var largeLinesPath = new SKPath()) | |
{ | |
var xEndPosition = (scaledRulerSize - (scaledRulerSize / 1.3f)) + canvas.LocalClipBounds.Location.X; | |
var yPosition = (i * largeDivisionParameter) + (largeDisplacementY * largeDivisionParameter); | |
largeYPositions.Add(yPosition); | |
largeLinesPath.MoveTo(canvas.LocalClipBounds.Location.X + scaledRulerSize, yPosition); | |
largeLinesPath.LineTo(xEndPosition, yPosition); | |
canvas.DrawPath(largeLinesPath, paint); | |
paint.Style = SKPaintStyle.Fill; | |
canvas.Save(); | |
canvas.Translate(xEndPosition, yPosition); | |
canvas.RotateDegrees(-90); | |
canvas.DrawText($"{yPosition} mm", 0, 0, paint); | |
canvas.Restore(); | |
paint.Style = SKPaintStyle.Stroke; | |
} | |
} | |
#endregion | |
#region grid 0,250 m² | |
paint.Color = Color.DarkGray.ToSKColor(); | |
paint.StrokeWidth = 3 / CanvasScale; | |
xRepetitions = xRepetitions * 4; | |
yRepetitions = yRepetitions * 4; | |
for (int i = 0; i <= xRepetitions; i++) | |
{ | |
using (var skinnyLinesPath = new SKPath()) | |
{ | |
var xPosition = (i * divisionsParameter) + (skinnyDisplacementX * divisionsParameter); | |
if (largeXPositions.Any(l => l == xPosition)) | |
continue; | |
var xLargePosition = (i * largeDivisionParameter) + (largeDisplacementX * largeDivisionParameter); | |
var yEndPosition = (scaledRulerSize - (scaledRulerSize / 2)) + canvas.LocalClipBounds.Location.Y; | |
skinnyLinesPath.MoveTo(xPosition, | |
canvas.LocalClipBounds.Location.Y + scaledRulerSize); | |
skinnyLinesPath.LineTo(xPosition, yEndPosition); | |
canvas.DrawPath(skinnyLinesPath, paint); | |
paint.Style = SKPaintStyle.Fill; | |
canvas.DrawText($"{xPosition} mm", | |
xPosition, | |
yEndPosition, | |
paint); | |
paint.Style = SKPaintStyle.Stroke; | |
} | |
} | |
for (int i = 0; i <= yRepetitions; i++) | |
{ | |
using (var skinnyLinesPath = new SKPath()) | |
{ | |
var yPosition = (i * divisionsParameter) + (skinnyDisplacementY * divisionsParameter); | |
if (largeYPositions.Any(l => l == yPosition)) | |
continue; | |
var xEndPosition = (scaledRulerSize - (scaledRulerSize / 2)) + canvas.LocalClipBounds.Location.X; | |
var yLargePosition = (i * largeDivisionParameter) + (largeDisplacementY * largeDivisionParameter); | |
skinnyLinesPath.MoveTo( | |
canvas.LocalClipBounds.Location.X + scaledRulerSize, | |
yPosition); | |
skinnyLinesPath.LineTo(xEndPosition, yPosition); | |
canvas.DrawPath(skinnyLinesPath, paint); | |
paint.Style = SKPaintStyle.Fill; | |
canvas.Save(); | |
canvas.Translate(xEndPosition, yPosition); | |
canvas.RotateDegrees(-90); | |
canvas.DrawText($"{yPosition} mm", 0, 0, paint); | |
canvas.Restore(); | |
paint.Style = SKPaintStyle.Stroke; | |
} | |
} | |
#endregion | |
using (var ruler = new SKPath()) | |
{ | |
paint.Color = Color.LightGray.ToSKColor(); | |
paint.Style = SKPaintStyle.Fill; | |
var xPosition = canvas.LocalClipBounds.Location.X + scaledRulerSize; | |
var yPosition = canvas.LocalClipBounds.Location.Y + scaledRulerSize; | |
ruler.MoveTo(canvas.LocalClipBounds.Location.X, canvas.LocalClipBounds.Location.Y); | |
ruler.LineTo(xPosition, canvas.LocalClipBounds.Location.Y); | |
ruler.LineTo(xPosition, yPosition); | |
ruler.LineTo(canvas.LocalClipBounds.Location.X, yPosition); | |
ruler.Close(); | |
canvas.DrawPath(ruler, paint); | |
paint.Color = Color.Black.ToSKColor(); | |
paint.Style = SKPaintStyle.Stroke; | |
canvas.DrawPath(ruler, paint); | |
paint.Style = SKPaintStyle.Fill; | |
paint.TextSize = 50 / CanvasScale; | |
canvas.DrawText($"{System.Math.Round(CanvasScale, 2)}/1", | |
canvas.LocalClipBounds.Location.X + scaledRulerSize / 2, | |
canvas.LocalClipBounds.Location.Y + scaledRulerSize / 2 + paint.TextSize / 2, | |
paint); | |
} | |
}; | |
} | |
private bool IsTouched(Vector2D startPoint, Vector2D endPoint, Vector2D touchLocation) | |
{ | |
if (touchLocation == null) | |
return false; | |
var parameter = 300; | |
var touchedStart1 = new Vector2D(touchLocation.X + parameter, touchLocation.Y + parameter); | |
var touchedEnd1 = new Vector2D(touchLocation.X - parameter, touchLocation.Y - parameter); | |
var touchedStart2 = new Vector2D(touchLocation.X + parameter, touchLocation.Y - parameter); | |
var touchedEnd2 = new Vector2D(touchLocation.X - parameter, touchLocation.Y + parameter); | |
return (Math2D.IsIntersecting(startPoint, endPoint, touchedStart1, touchedEnd1) || | |
Math2D.IsIntersecting(startPoint, endPoint, touchedStart2, touchedEnd2)) && | |
!(Math2D.InDistance(touchLocation, endPoint, 300) || | |
Math2D.InDistance(touchLocation, startPoint, 300)); | |
} | |
private bool CheckAnyCollision(float? startX = null, float? startY = null, | |
float? endX = null, float? endY = null) | |
{ | |
var startPositionX = startX ?? LastTouch.X; | |
var startPositionY = startY ?? LastTouch.Y; | |
var endPositionX = endX ?? TouchLocation.X; | |
var endPositionY = endY ?? TouchLocation.Y; | |
return DraftWalls.Any(w => | |
!(w.WallEndX == startPositionX && w.WallEndY == startPositionY) | |
&& !(w.WallStartX == endPositionX && w.WallStartY == endPositionY) | |
&& !(w.WallStartX == startPositionX && w.WallStartY == startPositionY) | |
&& !(w.WallEndX == endPositionX && w.WallEndY == endPositionY) | |
&& Math2D.IsIntersecting(w.WallStartX, w.WallStartY, w.WallEndX, w.WallEndY, | |
startPositionX, startPositionY, endPositionX, endPositionY)); | |
} | |
private float GetDivisionsParameter() => | |
((((_gridDivisions / CanvasScale).Round() / _gridStep).Round()) * _gridStep).ToSingle(); | |
private void MoveSelectedVertice(PanUpdatedEventArgs e) | |
{ | |
var newPosition = new Vector2D(); | |
if (e.TotalX == 0 && e.TotalY == 0) | |
{ | |
_previousVertPosition.X = 0; | |
_previousVertPosition.Y = 0; | |
} | |
foreach (var w in DraftWalls) | |
{ | |
if (w.WallEndX == SelectedVertice.X | |
&& w.WallEndY == SelectedVertice.Y) | |
{ | |
var newX = w.WallEndX + ((e.TotalX - _previousVertPosition.X) | |
/ CanvasScale * TouchSensibility).ToSingle(); | |
var newY = w.WallEndY + ((e.TotalY - _previousVertPosition.Y) | |
/ CanvasScale * TouchSensibility).ToSingle(); | |
var next = Math2D.GetNextWall(w, DraftWalls); | |
var previous = Math2D.GetPreviousWall(w, DraftWalls); | |
if (CheckAnyCollision(w.WallStartX, w.WallStartY, newX, newY) | |
|| (next != null && CheckAnyCollision(w.WallStartX, w.WallStartY, next.X, next.Y)) | |
|| (previous != null && CheckAnyCollision(previous.X, previous.Y, w.WallStartX, w.WallStartY))) | |
{ | |
break; | |
} | |
w.WallEndX = newX; | |
w.WallEndY = newY; | |
newPosition.X = w.WallEndX; | |
newPosition.Y = w.WallEndY; | |
} | |
else if (w.WallStartX == SelectedVertice.X | |
&& w.WallStartY == SelectedVertice.Y) | |
{ | |
var newX = w.WallStartX + ((e.TotalX - _previousVertPosition.X) | |
/ CanvasScale * TouchSensibility).ToSingle(); | |
var newY = w.WallStartY + ((e.TotalY - _previousVertPosition.Y) | |
/ CanvasScale * TouchSensibility).ToSingle(); | |
var next = Math2D.GetNextWall(w, DraftWalls); | |
var previous = Math2D.GetPreviousWall(w, DraftWalls); | |
if (CheckAnyCollision(newX, newY, w.WallEndX, w.WallEndY) | |
|| (next != null && CheckAnyCollision(w.WallStartX, w.WallStartY, next.X, next.Y)) | |
|| (previous != null && CheckAnyCollision(previous.X, previous.Y, w.WallStartX, w.WallStartY))) | |
{ | |
break; | |
} | |
w.WallStartX = newX; | |
w.WallStartY = newY; | |
newPosition.X = w.WallStartX; | |
newPosition.Y = w.WallStartY; | |
} | |
} | |
_previousVertPosition.X = e.TotalX.ToSingle(); | |
_previousVertPosition.Y = e.TotalY.ToSingle(); | |
SelectedVertice.X = newPosition.X; | |
SelectedVertice.Y = newPosition.Y; | |
StopCanvasActions(); | |
KeepSelection = true; | |
CanvasView.InvalidateSurface(); | |
} | |
private void DrawWallChilds(SKCanvas canvas, float width, int wallThickness, params WallChildren[] children) | |
{ | |
foreach (var child in children) | |
{ | |
switch (child.Type) | |
{ | |
case "Window": | |
DrawWindow(canvas, width, wallThickness, child); | |
break; | |
case "HydraulicPoint": | |
case "EletricPoint": | |
DrawPoint(canvas, width, wallThickness, child); | |
break; | |
default: | |
case "Door": | |
DrawDoor(canvas, width, wallThickness, child); | |
break; | |
} | |
} | |
} | |
private void DrawDoor(SKCanvas canvas, float width, int wallThickness, WallChildren child) | |
{ | |
using (var doorPaint = new SKPaint()) | |
using (var doorPath = new SKPath()) | |
{ | |
var doorThickness = 60; | |
doorPaint.Color = Color.White.ToSKColor(); | |
doorPaint.Style = SKPaintStyle.Fill; | |
doorPaint.IsAntialias = HasAntialias(); | |
doorPaint.StrokeWidth = 2 / CanvasScale; | |
doorPaint.TextSize = QuotaFontSize / CanvasScale; | |
doorPaint.TextAlign = SKTextAlign.Center; | |
var zeroPointX = width - child.LeftSpace; | |
doorPath.MoveTo(zeroPointX, 0); | |
doorPath.LineTo(zeroPointX - child.Width, 0); | |
doorPath.LineTo(zeroPointX - child.Width, -wallThickness); | |
doorPath.LineTo(zeroPointX, -wallThickness); | |
doorPath.Close(); | |
canvas.DrawPath(doorPath, doorPaint); | |
doorPaint.Color = Color.Black.ToSKColor(); | |
doorPaint.Style = SKPaintStyle.Stroke; | |
canvas.DrawPath(doorPath, doorPaint); | |
doorPath.Reset(); | |
var doorPivoX = child.Inverted ? zeroPointX : zeroPointX - child.Width; | |
var rect = new SKRect( | |
doorPivoX - child.Width, | |
-child.Width, | |
doorPivoX + child.Width, | |
child.Width); | |
doorPaint.Style = SKPaintStyle.Fill; | |
doorPaint.Color = Color.LightGray.ToSKColor(); | |
doorPath.MoveTo(doorPivoX, 0); | |
doorPath.LineTo(doorPivoX + (child.Inverted ? -child.Width : child.Width), 0); | |
doorPath.LineTo(doorPivoX, child.Width); | |
doorPath.Close(); | |
canvas.DrawPath(doorPath, doorPaint); | |
doorPath.Reset(); | |
doorPath.AddArc(rect, (child.Inverted ? 90 : 0), 90); | |
canvas.DrawPath(doorPath, doorPaint); | |
doorPath.Reset(); | |
doorPaint.Color = Color.Black.ToSKColor(); | |
doorPath.MoveTo(doorPivoX, 0); | |
doorPath.LineTo(doorPivoX, child.Width); | |
doorPath.LineTo(doorPivoX + (child.Inverted ? -doorThickness : doorThickness), child.Width); | |
doorPath.LineTo(doorPivoX + (child.Inverted ? -doorThickness : doorThickness), 0); | |
doorPaint.Style = SKPaintStyle.Fill; | |
canvas.DrawPath(doorPath, doorPaint); | |
doorPath.Reset(); | |
doorPaint.StrokeWidth = 15; | |
doorPaint.Style = SKPaintStyle.Stroke; | |
doorPath.MoveTo(doorPivoX, child.Width - doorThickness); | |
doorPath.LineTo(doorPivoX + (child.Inverted ? 30 : -30), child.Width - doorThickness); | |
doorPath.LineTo(doorPivoX + (child.Inverted ? 30 : -30), child.Width - doorThickness -60); | |
doorPath.MoveTo(doorPivoX + (child.Inverted ? -doorThickness : doorThickness), child.Width - doorThickness); | |
doorPath.LineTo(doorPivoX + (child.Inverted ? -doorThickness : doorThickness) + (child.Inverted ? -30 : 30), child.Width - doorThickness); | |
doorPath.LineTo(doorPivoX + (child.Inverted ? -doorThickness : doorThickness) + (child.Inverted ? -30 : 30), child.Width - doorThickness -60); | |
canvas.DrawPath(doorPath, doorPaint); | |
}; | |
} | |
private void DrawPoint(SKCanvas canvas, float width, int wallThickness, WallChildren child) | |
{ | |
using (var pointPaint = new SKPaint()) | |
using (var pointPath = new SKPath()) | |
{ | |
pointPaint.Color = Color.Black.ToSKColor(); | |
pointPaint.Style = SKPaintStyle.Fill; | |
pointPaint.IsAntialias = HasAntialias(); | |
pointPaint.StrokeWidth = 6; | |
pointPaint.TextSize = QuotaFontSize / CanvasScale; | |
pointPaint.TextAlign = SKTextAlign.Center; | |
var zeroPointX = width - child.LeftSpace; | |
pointPath.MoveTo(zeroPointX - 2, 0); | |
pointPath.LineTo(zeroPointX, QuotaDistance + 60); | |
pointPath.LineTo(zeroPointX + 60, QuotaDistance + 60); | |
pointPath.LineTo(zeroPointX, QuotaDistance + 120); | |
pointPath.LineTo(zeroPointX - 60, QuotaDistance + 60); | |
pointPath.LineTo(zeroPointX + 2, QuotaDistance + 60); | |
pointPath.Close(); | |
canvas.DrawPath(pointPath, pointPaint); | |
canvas.DrawText( | |
child.Type == "HydraulicPoint" ? "H" : "E", | |
zeroPointX, | |
QuotaDistance + 140 + (pointPaint.TextSize /2), | |
pointPaint); | |
}; | |
} | |
private void DrawWindow(SKCanvas canvas, float width, int wallThickness, WallChildren child) | |
{ | |
using (var windowPaint = new SKPaint()) | |
using (var windowPath = new SKPath()) | |
{ | |
windowPaint.Color = Color.White.ToSKColor(); | |
windowPaint.Style = SKPaintStyle.Fill; | |
windowPaint.IsAntialias = HasAntialias(); | |
windowPaint.StrokeWidth = 2 / CanvasScale; | |
windowPaint.TextSize = QuotaFontSize / CanvasScale; | |
windowPaint.TextAlign = SKTextAlign.Center; | |
var zeroPointX = width - child.LeftSpace; | |
windowPath.MoveTo(zeroPointX, 0); | |
windowPath.LineTo(zeroPointX - child.Width, 0); | |
windowPath.LineTo(zeroPointX - child.Width, - wallThickness); | |
windowPath.LineTo(zeroPointX, - wallThickness); | |
windowPath.Close(); | |
canvas.DrawPath(windowPath, windowPaint); | |
windowPaint.Color = Color.Black.ToSKColor(); | |
windowPaint.Style = SKPaintStyle.Stroke; | |
canvas.DrawPath(windowPath, windowPaint); | |
windowPath.Reset(); | |
windowPaint.StrokeWidth = wallThickness / 3; | |
windowPath.MoveTo(zeroPointX, -wallThickness / 3); | |
windowPath.LineTo(zeroPointX - child.Width /2, -wallThickness / 3); | |
windowPath.MoveTo(zeroPointX - child.Width / 2, -(wallThickness / 3) * 2); | |
windowPath.LineTo(zeroPointX - child.Width, -(wallThickness / 3) * 2); | |
canvas.DrawPath(windowPath, windowPaint); | |
}; | |
} | |
private void DrawQuotas(SKCanvas canvas, float width, float angle) | |
{ | |
using (var paint = new SKPaint()) | |
using (var path = new SKPath()) | |
{ | |
paint.Color = Color.Blue.ToSKColor(); | |
paint.Style = SKPaintStyle.Stroke; | |
paint.IsAntialias = HasAntialias(); | |
paint.StrokeWidth = 2 / CanvasScale; | |
paint.TextSize = QuotaFontSize / CanvasScale; | |
paint.TextAlign = SKTextAlign.Center; | |
path.MoveTo(0, 0); | |
path.LineTo(0, _quotaDistance); | |
path.MoveTo(0, _quotaDistance / 2); | |
path.LineTo(width, _quotaDistance / 2); | |
path.MoveTo(width, 0); | |
path.LineTo(width, _quotaDistance); | |
canvas.DrawPath(path, paint); | |
paint.Color = Color.Black.ToSKColor(); | |
if (angle > 90 || angle < -90) | |
{ | |
canvas.Translate(width / 2, 0); | |
canvas.RotateDegrees(180); | |
canvas.DrawText(width.ToString(), 0, -(_quotaDistance), paint); | |
canvas.RotateDegrees(180); | |
canvas.Translate(-width / 2, 0); | |
} | |
else | |
{ | |
canvas.DrawText(width.ToString(), width / 2, _quotaDistance + paint.TextSize/2, paint); | |
} | |
paint.Color = Color.Blue.ToSKColor(); | |
paint.Style = SKPaintStyle.Fill; | |
var arrowDepth = 130; | |
var arrowHeight = 60; | |
using (var rightArrowPath = new SKPath()) | |
{ | |
rightArrowPath.MoveTo(0, _quotaDistance / 2); | |
rightArrowPath.LineTo(arrowDepth, _quotaDistance / 2 + arrowHeight / 2); | |
rightArrowPath.LineTo(arrowDepth, _quotaDistance / 2 - arrowHeight / 2); | |
rightArrowPath.Close(); | |
canvas.DrawPath(rightArrowPath, paint); | |
} | |
using (var leftArrowPath = new SKPath()) | |
{ | |
leftArrowPath.MoveTo(width, _quotaDistance / 2); | |
leftArrowPath.LineTo(width - arrowDepth, _quotaDistance / 2 + arrowHeight / 2); | |
leftArrowPath.LineTo(width - arrowDepth, _quotaDistance / 2 - arrowHeight / 2); | |
leftArrowPath.Close(); | |
canvas.DrawPath(leftArrowPath, paint); | |
} | |
} | |
} | |
private void DrawVertices(SKCanvas canvas, float width, Vector2D startPoint, Vector2D endPoint) | |
{ | |
using (var rectPaint = new SKPaint()) | |
{ | |
var sizeParam = 100; | |
var locationParam = 50; | |
rectPaint.Style = SKPaintStyle.Fill; | |
rectPaint.Color = Color.Blue.ToSKColor(); | |
if ((TouchLocation != null && Math2D.InDistance(TouchLocation, startPoint, 300) && SelectedVertice == null | |
&& !IsDrawing && !IsPanning && !IsZooning) || SelectedVertice == startPoint) | |
{ | |
SelectedWall = null; | |
SelectedVertice = startPoint; | |
rectPaint.Color = Color.Red.ToSKColor(); | |
sizeParam = 250; | |
locationParam = 125; | |
} | |
var vertPoint = new SKRect() | |
{ | |
Location = new SKPoint(-locationParam, -locationParam), | |
Size = new SKSize(sizeParam, sizeParam) | |
}; | |
canvas.DrawRect(vertPoint, rectPaint); | |
rectPaint.Color = Color.Blue.ToSKColor(); | |
sizeParam = 100; | |
locationParam = 50; | |
if ((TouchLocation != null && Math2D.InDistance(TouchLocation, endPoint, 300) && SelectedVertice == null | |
&& !IsDrawing && !IsPanning && !IsZooning && SelectedWall == null) || SelectedVertice == endPoint) | |
{ | |
SelectedWall = null; | |
SelectedVertice = endPoint; | |
rectPaint.Color = Color.Red.ToSKColor(); | |
sizeParam = 250; | |
locationParam = 125; | |
} | |
vertPoint.Location = new SKPoint(width - locationParam, -locationParam); | |
canvas.DrawRect(vertPoint, rectPaint); | |
} | |
} | |
#endregion | |
#region Public Methods | |
public void SubscribeEvents() | |
{ | |
MessagingCenter.Subscribe<DrawPageViewModel>( | |
this, MessagingDictionary.VERTICE_ADD, (sender) => | |
{ | |
if (!Commands.VerticeAddCommand()) | |
{ | |
App.Current.MainPage.DisplayAlert( | |
AppResources.VerticeAddlbl, | |
AppResources.VerticeAddErrorMsg, | |
AppResources.AlertWarningOk); | |
} | |
}); | |
MessagingCenter.Subscribe<DrawPageViewModel>( | |
this, MessagingDictionary.VERTICE_REMOVE, (sender) => | |
{ | |
if (!Commands.VerticeRemoveCommand()) | |
{ | |
App.Current.MainPage.DisplayAlert( | |
AppResources.VerticeRemovelbl, | |
AppResources.VerticeRemoveErrorMsg, | |
AppResources.AlertWarningOk); | |
} | |
}); | |
MessagingCenter.Subscribe<DrawPageViewModel>( | |
this, MessagingDictionary.UNDO, (sender) => | |
{ | |
if (!Commands.UndoCommand()) | |
{ | |
App.Current.MainPage.DisplayAlert( | |
AppResources.Undolbl, | |
AppResources.UndoErrorMsg, | |
AppResources.AlertWarningOk); | |
} | |
}); | |
MessagingCenter.Subscribe<DrawPageViewModel>( | |
this, MessagingDictionary.REDO, (sender) => | |
{ | |
if (!Commands.RedoCommand()) | |
{ | |
App.Current.MainPage.DisplayAlert( | |
AppResources.Redolbl, | |
AppResources.RedoErrorMsg, | |
AppResources.AlertWarningOk); | |
} | |
}); | |
MessagingCenter.Subscribe<DrawPageViewModel>( | |
this, MessagingDictionary.ALIGNAMENT_MODE, (sender) => | |
Commands.AlignamentCommand()); | |
MessagingCenter.Subscribe<DrawPageViewModel>( | |
this, MessagingDictionary.CANVAS_NEED_REFRESH, (sender) => | |
CanvasView?.InvalidateSurface()); | |
} | |
public void UnsubscribeEvents() | |
{ | |
MessagingCenter.Unsubscribe<DrawPageViewModel>( | |
this, MessagingDictionary.VERTICE_REMOVE); | |
MessagingCenter.Unsubscribe<DrawPageViewModel>( | |
this, MessagingDictionary.VERTICE_ADD); | |
MessagingCenter.Unsubscribe<DrawPageViewModel>( | |
this, MessagingDictionary.UNDO); | |
MessagingCenter.Unsubscribe<DrawPageViewModel>( | |
this, MessagingDictionary.REDO); | |
MessagingCenter.Unsubscribe<DrawPageViewModel>( | |
this, MessagingDictionary.ALIGNAMENT_MODE); | |
MessagingCenter.Unsubscribe<DrawPageViewModel>( | |
this, MessagingDictionary.CANVAS_NEED_REFRESH); | |
} | |
#endregion | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment