Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ed27f81

Browse files
use matrix
1 parent 22d284d commit ed27f81

File tree

6 files changed

+163
-18
lines changed

6 files changed

+163
-18
lines changed
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
using System.Windows;
2+
using System.Windows.Media;
3+
using static System.Math;
4+
5+
namespace SimpleStateMachineNodeEditor.Helpers.Extensions
6+
{
7+
public static class MatrixExtension
8+
{
9+
/// <summary>
10+
/// Creates a translation matrix using the specified offsets.
11+
/// </summary>
12+
/// <param name="offsetX">X-coordinate offset.</param>
13+
/// <param name="offsetY">Y-coordinate offset.</param>
14+
/// <returns>The created translation matrix.</returns>
15+
public static Matrix Translate(double offsetX, double offsetY)
16+
{
17+
return new Matrix(1.0, 0.0, 0.0, 1.0, offsetX, offsetY);
18+
}
19+
20+
/// <summary>
21+
/// Prepends a translation around the center of provided matrix.
22+
/// </summary>
23+
/// <param name="matrix">The matrix to prepend translation.</param>
24+
/// <param name="offsetX">X-coordinate offset.</param>
25+
/// <param name="offsetY">Y-coordinate offset.</param>
26+
/// <returns>The created translation matrix.</returns>
27+
public static Matrix TranslatePrepend(Matrix matrix, double offsetX, double offsetY)
28+
{
29+
return Translate(offsetX, offsetY) * matrix;
30+
}
31+
32+
/// <summary>
33+
/// Creates a matrix that scales along the x-axis and y-axis.
34+
/// </summary>
35+
/// <param name="scaleX">Scaling factor that is applied along the x-axis.</param>
36+
/// <param name="scaleY">Scaling factor that is applied along the y-axis.</param>
37+
/// <returns>The created scaling matrix.</returns>
38+
public static Matrix Scale(double scaleX, double scaleY)
39+
{
40+
return new Matrix(scaleX, 0, 0, scaleY, 0.0, 0.0);
41+
}
42+
43+
/// <summary>
44+
/// Creates a matrix that is scaling from a specified center.
45+
/// </summary>
46+
/// <param name="scaleX">Scaling factor that is applied along the x-axis.</param>
47+
/// <param name="scaleY">Scaling factor that is applied along the y-axis.</param>
48+
/// <param name="centerX">The center X-coordinate of the scaling.</param>
49+
/// <param name="centerY">The center Y-coordinate of the scaling.</param>
50+
/// <returns>The created scaling matrix.</returns>
51+
public static Matrix ScaleAt(double scaleX, double scaleY, double centerX, double centerY)
52+
{
53+
return new Matrix(scaleX, 0, 0, scaleY, centerX - (scaleX * centerX), centerY - (scaleY * centerY));
54+
}
55+
56+
/// <summary>
57+
/// Prepends a scale around the center of provided matrix.
58+
/// </summary>
59+
/// <param name="matrix">The matrix to prepend scale.</param>
60+
/// <param name="scaleX">Scaling factor that is applied along the x-axis.</param>
61+
/// <param name="scaleY">Scaling factor that is applied along the y-axis.</param>
62+
/// <param name="centerX">The center X-coordinate of the scaling.</param>
63+
/// <param name="centerY">The center Y-coordinate of the scaling.</param>
64+
/// <returns>The created scaling matrix.</returns>
65+
public static Matrix ScaleAtPrepend(Matrix matrix, double scaleX, double scaleY, double centerX, double centerY)
66+
{
67+
return ScaleAt(scaleX, scaleY, centerX, centerY) * matrix;
68+
}
69+
70+
/// <summary>
71+
/// Creates a skew matrix.
72+
/// </summary>
73+
/// <param name="angleX">Angle of skew along the X-axis in radians.</param>
74+
/// <param name="angleY">Angle of skew along the Y-axis in radians.</param>
75+
/// <returns>When the method completes, contains the created skew matrix.</returns>
76+
public static Matrix Skew(float angleX, float angleY)
77+
{
78+
return new Matrix(1.0, Tan(angleX), Tan(angleY), 1.0, 0.0, 0.0);
79+
}
80+
81+
/// <summary>
82+
/// Creates a matrix that rotates.
83+
/// </summary>
84+
/// <param name="radians">Angle of rotation in radians. Angles are measured clockwise when looking along the rotation axis.</param>
85+
/// <returns>The created rotation matrix.</returns>
86+
public static Matrix Rotation(double radians)
87+
{
88+
double cos = Cos(radians);
89+
double sin = Sin(radians);
90+
return new Matrix(cos, sin, -sin, cos, 0, 0);
91+
}
92+
93+
/// <summary>
94+
/// Creates a matrix that rotates about a specified center.
95+
/// </summary>
96+
/// <param name="angle">Angle of rotation in radians.</param>
97+
/// <param name="centerX">The center X-coordinate of the rotation.</param>
98+
/// <param name="centerY">The center Y-coordinate of the rotation.</param>
99+
/// <returns>The created rotation matrix.</returns>
100+
public static Matrix Rotation(double angle, double centerX, double centerY)
101+
{
102+
return Translate(-centerX, -centerY) * Rotation(angle) * Translate(centerX, centerY);
103+
}
104+
105+
/// <summary>
106+
/// Creates a matrix that rotates about a specified center.
107+
/// </summary>
108+
/// <param name="angle">Angle of rotation in radians.</param>
109+
/// <param name="center">The center of the rotation.</param>
110+
/// <returns>The created rotation matrix.</returns>
111+
public static Matrix Rotation(double angle, Vector center)
112+
{
113+
return Translate(-center.X, -center.Y) * Rotation(angle) * Translate(center.X, center.Y);
114+
}
115+
116+
/// <summary>
117+
/// Transforms a point by this matrix.
118+
/// </summary>
119+
/// <param name="matrix">The matrix to use as a transformation matrix.</param>
120+
/// <param name="point">>The original point to apply the transformation.</param>
121+
/// <returns>The result of the transformation for the input point.</returns>
122+
public static Point TransformPoint(Matrix matrix, Point point)
123+
{
124+
return new Point(
125+
(point.X * matrix.M11) + (point.Y * matrix.M21) + matrix.OffsetX,
126+
(point.X * matrix.M12) + (point.Y * matrix.M22) + matrix.OffsetY);
127+
}
128+
}
129+
}

‎SimpleStateMachineNodeEditor/Helpers/MyUtils.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ public static void FindParents<TParent1, TParent2>(DependencyObject currentObjec
7777
} while ((parent1 == default(TParent1)) || (parent2 == default(TParent2)));
7878
}
7979

80-
public static void PanelToImage(Panel panel, string filename, ImageFormats format)
80+
public static void PanelToImage(FrameworkElement panel, string filename, ImageFormats format)
8181
{
8282
int width = (int)panel.ActualWidth;
8383
int height = (int)panel.ActualHeight;

‎SimpleStateMachineNodeEditor/SimpleStateMachineNodeEditor.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ ReactiveUI 11.4.17</PackageReleaseNotes>
6969
<PackageReference Include="ReactiveUI.WPF" Version="11.4.17" />
7070
<PackageReference Include="Splat" Version="9.4.5" />
7171
<PackageReference Include="Splat.Drawing" Version="9.4.5" />
72-
<PackageReference Include="Wpf.Controls.PanAndZoom" Version="2.3.3" />
72+
<PackageReference Include="Wpf.Controls.PanAndZoom" Version="3.0.999-build20200622-01" />
7373
</ItemGroup>
7474

7575
<ItemGroup>

‎SimpleStateMachineNodeEditor/View/ViewNodesCanvas.xaml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@
99
xmlns:paz="clr-namespace:Wpf.Controls.PanAndZoom;assembly=Wpf.Controls.PanAndZoom"
1010
mc:Ignorable="d"
1111
d:DesignHeight="450" d:DesignWidth="800" Focusable="True" AllowDrop="True" ClipToBounds="True">
12-
<paz:ZoomBorder Name="zoomBorder" Stretch="None" ZoomSpeed="1.2"
12+
<!--<paz:ZoomBorder Name="zoomBorder" Stretch="None" ZoomSpeed="1.2"
1313
Background="SlateBlue" ClipToBounds="True" Focusable="True"
1414
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
15-
Grid.Row="4" Grid.Column="1" >
16-
<Canvasx:Name="Canvas" Background="{DynamicResource ColorNodesCanvasBackground}">
17-
15+
Grid.Row="4" Grid.Column="1" EnablePan="False" MaxZoomX="5" MaxZoomY="5" MinZoomX="0.2" MinZoomY="0.2">-->
16+
<BorderName="BorderElement" Background="SlateBlue">
17+
<Canvasx:Name="Canvas"Background="{DynamicResource ColorNodesCanvasBackground}"ClipToBounds="True">
1818
<local:ViewSelector x:Name="Selector" Panel.ZIndex="999"/>
1919
<local:ViewCutter x:Name="Cutter" Panel.ZIndex="999"/>
2020

@@ -24,7 +24,6 @@
2424
VirtualizingPanel.CacheLength="1"
2525
VirtualizingPanel.CacheLengthUnit="Page"
2626
VirtualizingPanel.ScrollUnit="Pixel">
27-
2827
<ItemsControl.RenderTransform>
2928
<TransformGroup x:Name="TransformGroup">
3029
<ScaleTransform x:Name="Scale" ScaleX="1" ScaleY="1" />
@@ -35,7 +34,7 @@
3534
</ItemsControl.RenderTransform>
3635
<ItemsControl.ItemsPanel>
3736
<ItemsPanelTemplate>
38-
<Grid x:Name="ElementGrid" Background="{x:Null}">
37+
<Grid x:Name="ElementGrid" Background="Pink">
3938
</Grid>
4039
</ItemsPanelTemplate>
4140
</ItemsControl.ItemsPanel>
@@ -55,7 +54,7 @@
5554
</ItemsControl.ItemsSource>
5655
</ItemsControl>
5756
</Canvas>
58-
</paz:ZoomBorder>
57+
</Border>
5958
<UserControl.ContextMenu >
6059
<ContextMenu Template="{DynamicResource TemplateContextMenu}" Background="{DynamicResource ColorMenuBackground}" Foreground="{DynamicResource ColorMenuForeground}" BorderBrush="{DynamicResource ColorMenuBorder}" OpacityMask="{DynamicResource ColorMenuBackgroundMouseOver}" BorderThickness="1" HorizontalAlignment="Left" VerticalAlignment="Center" >
6160
<MenuItem Header="Add" x:Name="ItemAddNode" InputGestureText="Ctrl + N" Style="{DynamicResource StyleContextMenuItem}" >

‎SimpleStateMachineNodeEditor/View/ViewNodesCanvas.xaml.cs

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -62,15 +62,14 @@ public ViewNodesCanvas()
6262
private void SetupBinding()
6363
{
6464
this.WhenActivated(disposable =>
65-
{
66-
65+
{
6766
this.OneWayBind(this.ViewModel, x => x.NodesForView, x => x.Nodes.Collection).DisposeWith(disposable);
6867

6968
this.OneWayBind(this.ViewModel, x => x.Connects, x => x.Connects.Collection).DisposeWith(disposable);
7069

71-
this.OneWayBind(this.ViewModel, x => x.Scale.Scales.X, x => x.Scale.ScaleX).DisposeWith(disposable);
70+
//this.OneWayBind(this.ViewModel, x => x.Scale.Scales.X, x => x.Scale.ScaleX).DisposeWith(disposable);
7271

73-
this.OneWayBind(this.ViewModel, x => x.Scale.Scales.Y, x => x.Scale.ScaleY).DisposeWith(disposable);
72+
//this.OneWayBind(this.ViewModel, x => x.Scale.Scales.Y, x => x.Scale.ScaleY).DisposeWith(disposable);
7473

7574
this.OneWayBind(this.ViewModel, x => x.Selector, x => x.Selector.ViewModel).DisposeWith(disposable);
7675

@@ -114,6 +113,10 @@ private void SetupSubscriptions()
114113
this.WhenAnyValue(x => x.ViewModel.Selector.Size).WithoutParameter().InvokeCommand(ViewModel, x => x.CommandSelectorIntersect).DisposeWith(disposable);
115114
this.WhenAnyValue(x => x.ViewModel.Cutter.EndPoint).WithoutParameter().InvokeCommand(ViewModel, x => x.CommandCutterIntersect).DisposeWith(disposable);
116115
this.WhenAnyValue(x => x.ViewModel.ImagePath).Where(x => !string.IsNullOrEmpty(x)).Subscribe(value => SaveCanvasToImage(value, ImageFormats.JPEG)).DisposeWith(disposable);
116+
117+
//here need use ZoomIn and ZoomOut
118+
119+
//this.WhenAnyValue(x=>x.ViewModel.Scale.Value).Subscribe(x=> {this.zoomBorder.ZoomDeltaTo })
117120
});
118121
}
119122

@@ -128,12 +131,12 @@ private void SetupEvents()
128131
this.Events().MouseRightButtonDown.Subscribe(e => OnEventMouseRightDown(e)).DisposeWith(disposable);
129132
this.Events().MouseUp.Subscribe(e => OnEventMouseUp(e)).DisposeWith(disposable);
130133
this.Events().MouseMove.Subscribe(e => OnEventMouseMove(e)).DisposeWith(disposable);
131-
this.Events().MouseWheel.Subscribe(e => OnEventMouseWheel(e)).DisposeWith(disposable);
134+
this.BorderElement.Events().MouseWheel.Subscribe(e => OnEventMouseWheel(e)).DisposeWith(disposable);
132135
this.Events().DragOver.Subscribe(e => OnEventDragOver(e)).DisposeWith(disposable);
133136
this.Cutter.Events().MouseLeftButtonUp.InvokeCommand(this.ViewModel.CommandDeleteSelectedConnectors).DisposeWith(disposable);
134137
this.Events().PreviewMouseLeftButtonDown.Subscribe(e => OnEventPreviewMouseLeftButtonDown(e)).DisposeWith(disposable);
135138
this.Events().PreviewMouseRightButtonDown.Subscribe(e => OnEventPreviewMouseRightButtonDown(e)).DisposeWith(disposable);
136-
this.WhenAnyValue(x => x.ViewModel.Scale.Value).Subscribe(value => { this.Canvas.Height /= value; this.Canvas.Width /= value; }).DisposeWith(disposable);
139+
//this.WhenAnyValue(x => x.ViewModel.Scale.Value).Subscribe(value => { this.Canvas.Height /= value; this.Canvas.Width /= value; }).DisposeWith(disposable);
137140
});
138141
}
139142
private void OnEventMouseLeftDown(MouseButtonEventArgs e)
@@ -170,7 +173,20 @@ private void OnEventMouseRightDown(MouseButtonEventArgs e)
170173
}
171174
private void OnEventMouseWheel(MouseWheelEventArgs e)
172175
{
173-
this.ViewModel.CommandZoom.ExecuteWithSubscribe(e.Delta);
176+
//this.ElementItemControl.Width = ActualWidth + 100;
177+
Point point = e.GetPosition(this.Canvas);
178+
//this.Scale.CenterX = point.X;
179+
//this.Scale.CenterY = point.Y;
180+
181+
Matrix value = this.Canvas.RenderTransform.Value;
182+
double step = 1.2;
183+
double zoom = e.Delta > 0 ? step : 1 / step;
184+
value = MatrixExtension.ScaleAtPrepend(value,zoom, zoom, point.X, point.Y);
185+
this.Canvas.RenderTransform = new MatrixTransform(value);
186+
187+
//this.ViewModel.CommandZoom.ExecuteWithSubscribe(e.Delta);
188+
//_element.RenderTransform = new MatrixTransform(_matrix);
189+
174190
}
175191
private void OnEventMouseUp(MouseButtonEventArgs e)
176192
{
@@ -203,7 +219,7 @@ private void OnEventMouseMove(MouseEventArgs e)
203219
}
204220
private void OnEventDragOver(DragEventArgs e)
205221
{
206-
Point point = e.GetPosition(this);
222+
Point point = e.GetPosition(this.Canvas);
207223
if (this.ViewModel.DraggedConnect != null)
208224
{
209225
point = point.Subtraction(2);
@@ -236,6 +252,7 @@ private Point GetDeltaMove()
236252

237253
private void SaveCanvasToImage(string filename, ImageFormats format)
238254
{
255+
//this.zoomBorder.Uniform();
239256
MyUtils.PanelToImage(this.Canvas, filename, format);
240257
ViewModel.CommandLogDebug.ExecuteWithSubscribe(String.Format("Scheme was exported to \"{0}\"", filename));
241258
}

‎SimpleStateMachineNodeEditor/View/ViewSelector.xaml.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ private void OnMouseMoves(MouseEventArgs e)
9797
//find canvas
9898
ViewNodesCanvas NodesCanvas = MyUtils.FindParent<ViewNodesCanvas>(this);
9999

100-
ViewModel.Point2 = e.GetPosition(NodesCanvas);
100+
ViewModel.Point2 = e.GetPosition(NodesCanvas.Canvas);
101101

102102
e.Handled = true;
103103
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /