Skip to content

Commit

Permalink
Fix for scaling.
Browse files Browse the repository at this point in the history
I use matrix for render tranform.

Some refactoring
  • Loading branch information
RomanSoloweow committed Jul 3, 2020
1 parent f89a5c4 commit 17f3684
Show file tree
Hide file tree
Showing 38 changed files with 346 additions and 427 deletions.
109 changes: 4 additions & 105 deletions SimpleStateMachineNodeEditor/Helpers/Extensions/MatrixExtension.cs
Expand Up @@ -6,124 +6,23 @@ namespace SimpleStateMachineNodeEditor.Helpers.Extensions
{
public static class MatrixExtension
{
/// <summary>
/// Creates a translation matrix using the specified offsets.
/// </summary>
/// <param name="offsetX">X-coordinate offset.</param>
/// <param name="offsetY">Y-coordinate offset.</param>
/// <returns>The created translation matrix.</returns>
public static Matrix Translate(double offsetX, double offsetY)
{
return new Matrix(1.0, 0.0, 0.0, 1.0, offsetX, offsetY);
}

/// <summary>
/// Prepends a translation around the center of provided matrix.
/// </summary>
/// <param name="matrix">The matrix to prepend translation.</param>
/// <param name="offsetX">X-coordinate offset.</param>
/// <param name="offsetY">Y-coordinate offset.</param>
/// <returns>The created translation matrix.</returns>
public static Matrix TranslatePrepend(Matrix matrix, double offsetX, double offsetY)
{
return Translate(offsetX, offsetY) * matrix;
}

/// <summary>
/// Creates a matrix that scales along the x-axis and y-axis.
/// </summary>
/// <param name="scaleX">Scaling factor that is applied along the x-axis.</param>
/// <param name="scaleY">Scaling factor that is applied along the y-axis.</param>
/// <returns>The created scaling matrix.</returns>
public static Matrix Scale(double scaleX, double scaleY)
{
return new Matrix(scaleX, 0, 0, scaleY, 0.0, 0.0);
}

/// <summary>
/// Creates a matrix that is scaling from a specified center.
/// </summary>
/// <param name="scaleX">Scaling factor that is applied along the x-axis.</param>
/// <param name="scaleY">Scaling factor that is applied along the y-axis.</param>
/// <param name="centerX">The center X-coordinate of the scaling.</param>
/// <param name="centerY">The center Y-coordinate of the scaling.</param>
/// <returns>The created scaling matrix.</returns>
public static Matrix ScaleAt(double scaleX, double scaleY, double centerX, double centerY)
{
return new Matrix(scaleX, 0, 0, scaleY, centerX - (scaleX * centerX), centerY - (scaleY * centerY));
}

/// <summary>
/// Prepends a scale around the center of provided matrix.
/// </summary>
/// <param name="matrix">The matrix to prepend scale.</param>
/// <param name="scaleX">Scaling factor that is applied along the x-axis.</param>
/// <param name="scaleY">Scaling factor that is applied along the y-axis.</param>
/// <param name="centerX">The center X-coordinate of the scaling.</param>
/// <param name="centerY">The center Y-coordinate of the scaling.</param>
/// <returns>The created scaling matrix.</returns>
public static Matrix ScaleAtPrepend(Matrix matrix, double scaleX, double scaleY, double centerX, double centerY)
{
return ScaleAt(scaleX, scaleY, centerX, centerY) * matrix;
}

/// <summary>
/// Creates a skew matrix.
/// </summary>
/// <param name="angleX">Angle of skew along the X-axis in radians.</param>
/// <param name="angleY">Angle of skew along the Y-axis in radians.</param>
/// <returns>When the method completes, contains the created skew matrix.</returns>
public static Matrix Skew(float angleX, float angleY)
public static Matrix ScaleAtPrepend(Matrix matrix, double scaleX, double scaleY)
{
return new Matrix(1.0, Tan(angleX), Tan(angleY), 1.0, 0.0, 0.0);
return ScaleAt2(scaleX, scaleY, matrix.OffsetX, matrix.OffsetY) * matrix;
}

/// <summary>
/// Creates a matrix that rotates.
/// </summary>
/// <param name="radians">Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis.</param>
/// <returns>The created rotation matrix.</returns>
public static Matrix Rotation(double radians)
{
double cos = Cos(radians);
double sin = Sin(radians);
return new Matrix(cos, sin, -sin, cos, 0, 0);
}

/// <summary>
/// Creates a matrix that rotates about a specified center.
/// </summary>
/// <param name="angle">Angle of rotation in radians.</param>
/// <param name="centerX">The center X-coordinate of the rotation.</param>
/// <param name="centerY">The center Y-coordinate of the rotation.</param>
/// <returns>The created rotation matrix.</returns>
public static Matrix Rotation(double angle, double centerX, double centerY)
{
return Translate(-centerX, -centerY) * Rotation(angle) * Translate(centerX, centerY);
}

/// <summary>
/// Creates a matrix that rotates about a specified center.
/// </summary>
/// <param name="angle">Angle of rotation in radians.</param>
/// <param name="center">The center of the rotation.</param>
/// <returns>The created rotation matrix.</returns>
public static Matrix Rotation(double angle, Vector center)
{
return Translate(-center.X, -center.Y) * Rotation(angle) * Translate(center.X, center.Y);
}

/// <summary>
/// Transforms a point by this matrix.
/// </summary>
/// <param name="matrix">The matrix to use as a transformation matrix.</param>
/// <param name="point">>The original point to apply the transformation.</param>
/// <returns>The result of the transformation for the input point.</returns>
public static Point TransformPoint(Matrix matrix, Point point)
public static Matrix ScaleAt2(double scaleX, double scaleY, double centerX, double centerY)
{
return new Point(
(point.X * matrix.M11) + (point.Y * matrix.M21) + matrix.OffsetX,
(point.X * matrix.M12) + (point.Y * matrix.M22) + matrix.OffsetY);
return new Matrix(scaleX, 0, 0, scaleY, 1, 1);
}
}
}
Expand Up @@ -72,7 +72,6 @@ ReactiveUI 11.4.17</PackageReleaseNotes>
<PackageReference Include="ReactiveUI.WPF" Version="11.4.17" />
<PackageReference Include="Splat" Version="9.4.5" />
<PackageReference Include="Splat.Drawing" Version="9.4.5" />
<PackageReference Include="Wpf.Controls.PanAndZoom" Version="3.0.999-build20200622-01" />
</ItemGroup>

<ItemGroup>
Expand Down
@@ -1,4 +1,4 @@
<UserControl x:Class="SimpleStateMachineNodeEditor.View.ViewConnect"
<UserControl x:Class="SimpleStateMachineNodeEditor.View.Connect"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Expand Down
Expand Up @@ -20,24 +20,24 @@ namespace SimpleStateMachineNodeEditor.View
/// <summary>
/// Interaction logic for ViewConnect.xaml
/// </summary>
public partial class ViewConnect : UserControl, IViewFor<ViewModelConnect>
public partial class Connect : UserControl, IViewFor<ConnectViewModel>
{
#region ViewModel
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(ViewModelConnect), typeof(ViewConnect), new PropertyMetadata(null));
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(ConnectViewModel), typeof(Connect), new PropertyMetadata(null));

public ViewModelConnect ViewModel
public ConnectViewModel ViewModel
{
get { return (ViewModelConnect)GetValue(ViewModelProperty); }
get { return (ConnectViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}

object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (ViewModelConnect)value; }
set { ViewModel = (ConnectViewModel)value; }
}
#endregion ViewModel
public ViewConnect()
public Connect()
{
InitializeComponent();
SetupBinding();
Expand All @@ -62,7 +62,7 @@ private void SetupBinding()
this.OneWayBind(this.ViewModel, x => x.StrokeDashArray, x => x.PathElement.StrokeDashArray).DisposeWith(disposable);
this.OneWayBind(this.ViewModel, x => x.FromConnector.NodesCanvas.Scale.Value, x => x.PathElement.StrokeThickness).DisposeWith(disposable);
//this.OneWayBind(this.ViewModel, x => x.FromConnector.NodesCanvas.Scale.Value, x => x.PathElement.StrokeThickness).DisposeWith(disposable);
this.WhenAnyValue(x => x.ViewModel.ToConnector).Where(x=>x!=null).Subscribe(_ => UpdateZindex()).DisposeWith(disposable);
});
Expand Down
@@ -1,4 +1,4 @@
<UserControl x:Class="SimpleStateMachineNodeEditor.View.ViewCutter"
<UserControl x:Class="SimpleStateMachineNodeEditor.View.Cutter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Expand Down
Expand Up @@ -21,24 +21,24 @@ namespace SimpleStateMachineNodeEditor.View
/// <summary>
/// Interaction logic for ViewCutter.xaml
/// </summary>
public partial class ViewCutter : UserControl, IViewFor<ViewModelCutter>
public partial class Cutter : UserControl, IViewFor<CutterViewModel>
{
#region ViewModel
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(ViewModelCutter), typeof(ViewCutter), new PropertyMetadata(null));
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(CutterViewModel), typeof(Cutter), new PropertyMetadata(null));

public ViewModelCutter ViewModel
public CutterViewModel ViewModel
{
get { return (ViewModelCutter)GetValue(ViewModelProperty); }
get { return (CutterViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}

object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (ViewModelCutter)value; }
set { ViewModel = (CutterViewModel)value; }
}
#endregion ViewModel
public ViewCutter()
public Cutter()
{
InitializeComponent();
SetupBinding();
Expand Down Expand Up @@ -86,9 +86,8 @@ private void SetupEvents()
}
private void OnMouseMoves(MouseEventArgs e)
{
ViewNodesCanvas NodesCanvas = MyUtils.FindParent<ViewNodesCanvas>(this);

ViewModel.EndPoint = e.GetPosition(NodesCanvas.Canvas);
NodesCanvas NodesCanvas = MyUtils.FindParent<NodesCanvas>(this);
ViewModel.EndPoint = e.GetPosition(NodesCanvas.CanvasElement);

e.Handled = true;

Expand Down
@@ -1,4 +1,4 @@
<UserControl x:Class="SimpleStateMachineNodeEditor.View.ViewDialog"
<UserControl x:Class="SimpleStateMachineNodeEditor.View.Dialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Expand Down
Expand Up @@ -13,24 +13,24 @@ namespace SimpleStateMachineNodeEditor.View
/// <summary>
/// Interaction logic for ViewDialog.xaml
/// </summary>
public partial class ViewDialog : System.Windows.Controls.UserControl, IViewFor<ViewModelDialog>
public partial class Dialog : System.Windows.Controls.UserControl, IViewFor<DialogViewModel>
{
#region ViewModel
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(ViewModelDialog), typeof(ViewDialog), new PropertyMetadata(null));
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(DialogViewModel), typeof(Dialog), new PropertyMetadata(null));

public ViewModelDialog ViewModel
public DialogViewModel ViewModel
{
get { return (ViewModelDialog)GetValue(ViewModelProperty); }
get { return (DialogViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}

object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (ViewModelDialog)value; }
set { ViewModel = (DialogViewModel)value; }
}
#endregion ViewModel
public ViewDialog()
public Dialog()
{
InitializeComponent();
SetupBinding();
Expand Down
@@ -1,11 +1,11 @@
<UserControl x:Class="SimpleStateMachineNodeEditor.View.ViewLeftConnector"
<UserControl x:Class="SimpleStateMachineNodeEditor.View.LeftConnector"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SimpleStateMachineNodeEditor.View"
xmlns:styles="clr-namespace:SimpleStateMachineNodeEditor.Styles"
x:Name="LeftConnector" HorizontalAlignment="Stretch" VerticalAlignment="Top" AllowDrop="True" >
x:Name="LeftConnectorElement" HorizontalAlignment="Stretch" VerticalAlignment="Top" AllowDrop="True" >
<Grid x:Name="GridElement" Background="#00000000">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
Expand Down
Expand Up @@ -22,24 +22,24 @@ namespace SimpleStateMachineNodeEditor.View
/// <summary>
/// Interaction logic for ViewLeftConnector.xaml
/// </summary>
public partial class ViewLeftConnector : UserControl, IViewFor<ViewModelConnector>
public partial class LeftConnector : UserControl, IViewFor<ConnectorViewModel>
{
#region ViewModel
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(ViewModelConnector), typeof(ViewLeftConnector), new PropertyMetadata(null));
public static readonly DependencyProperty ViewModelProperty = DependencyProperty.Register(nameof(ViewModel), typeof(ConnectorViewModel), typeof(LeftConnector), new PropertyMetadata(null));

public ViewModelConnector ViewModel
public ConnectorViewModel ViewModel
{
get { return (ViewModelConnector)GetValue(ViewModelProperty); }
get { return (ConnectorViewModel)GetValue(ViewModelProperty); }
set { SetValue(ViewModelProperty, value); }
}

object IViewFor.ViewModel
{
get { return ViewModel; }
set { ViewModel = (ViewModelConnector)value; }
set { ViewModel = (ConnectorViewModel)value; }
}
#endregion ViewModel
public ViewLeftConnector()
public LeftConnector()
{
InitializeComponent();
SetupBinding();
Expand All @@ -64,7 +64,7 @@ private void SetupBinding()
this.OneWayBind(this.ViewModel, x => x.FormFill, x => x.EllipseElement.Fill).DisposeWith(disposable);
this.OneWayBind(this.ViewModel, x => x.Visible, x => x.LeftConnector.Visibility).DisposeWith(disposable);
this.OneWayBind(this.ViewModel, x => x.Visible, x => x.LeftConnectorElement.Visibility).DisposeWith(disposable);
});
}
Expand Down Expand Up @@ -102,13 +102,14 @@ void UpdatePosition()
{
Point positionConnectPoint = EllipseElement.TranslatePoint(new Point(EllipseElement.Width/2, EllipseElement.Height / 2), this);

ViewNodesCanvas NodesCanvas = MyUtils.FindParent<ViewNodesCanvas>(this);
NodesCanvas NodesCanvas = MyUtils.FindParent<NodesCanvas>(this);
if (NodesCanvas == null)
return;

positionConnectPoint = this.TransformToAncestor(NodesCanvas).Transform(positionConnectPoint);

this.ViewModel.PositionConnectPoint = positionConnectPoint.Division(this.ViewModel.NodesCanvas.Scale.Value);
//this.ViewModel.PositionConnectPoint = positionConnectPoint.Division(this.ViewModel.NodesCanvas.Scale.Value);
this.ViewModel.PositionConnectPoint = positionConnectPoint;
}
}
}
8 changes: 4 additions & 4 deletions SimpleStateMachineNodeEditor/View/MainWindow.xaml
Expand Up @@ -15,7 +15,7 @@
<RowDefinition Height="auto"/>
<RowDefinition Height="auto" x:Name="Fotter" MinHeight="18"/>
</Grid.RowDefinitions>
<view:ViewDialog x:Name="Dialog"/>
<view:Dialog x:Name="Dialog"/>

<!--#region Header-->
<DockPanel x:Name="Header" Grid.Row="0" Background="{DynamicResource ColorWindowHeader}" LastChildFill="False">
Expand Down Expand Up @@ -181,7 +181,7 @@
<!--BorderBrush - it's color on IsMouseOver, OpacityMask - it's color on IsPressed-->
<TabControl Grid.Column="0" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="Green" TabStripPlacement="Top" Padding="2,2,2,0" >
<TabItem Header="Node editor" Style="{DynamicResource StyleTabItem}" Background="{DynamicResource ColorWindowHeader}" Foreground="{DynamicResource ColorWindowHeaderTabItemForeground}" BorderBrush="{DynamicResource ColorElementMouseOver}" OpacityMask="{DynamicResource ColorElementMouseOver}">
<view:ViewNodesCanvas x:Name="NodesCanvas" />
<view:NodesCanvas x:Name="NodesCanvas" />
</TabItem>
</TabControl>
<GridSplitter Grid.Column="1" HorizontalAlignment="Center" x:Name="TableOfTransitionsSplitter" VerticalAlignment="Stretch" Background="{DynamicResource ColorWindowHeader}" Width="3" ShowsPreview="False" IsEnabled="False" />
Expand Down Expand Up @@ -221,7 +221,7 @@
VirtualizingStackPanel.ScrollUnit="Pixel">
<ListBox.ItemTemplate>
<DataTemplate>
<view:ViewTableOfTransitionsItem ViewModel="{Binding}" />
<view:TableOfTransitionsItem ViewModel="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Expand Down Expand Up @@ -282,7 +282,7 @@
</ListBox.ContextMenu>
<ListBox.ItemTemplate>
<DataTemplate>
<view:ViewMessage ViewModel="{Binding}" />
<view:Message ViewModel="{Binding}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Expand Down

0 comments on commit 17f3684

Please sign in to comment.