MainDrawingPanel.xaml.cs 10.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. using PixiEditor.ViewModels;
  2. using System;
  3. using System.Windows;
  4. using System.Windows.Automation;
  5. using System.Windows.Controls;
  6. using System.Windows.Input;
  7. using PixiEditor.Models.Tools.Tools;
  8. using Xceed.Wpf.Toolkit.Core.Input;
  9. using Xceed.Wpf.Toolkit.Zoombox;
  10. using PixiEditor.Models.Position;
  11. namespace PixiEditor.Views
  12. {
  13. /// <summary>
  14. /// Interaction logic for MainDrawingPanel.xaml
  15. /// </summary>
  16. public partial class MainDrawingPanel : UserControl
  17. {
  18. // Using a DependencyProperty as the backing store for Center. This enables animation, styling, binding, etc...
  19. public static readonly DependencyProperty CenterProperty =
  20. DependencyProperty.Register("Center", typeof(bool), typeof(MainDrawingPanel),
  21. new PropertyMetadata(true, OnCenterChanged));
  22. // Using a DependencyProperty as the backing store for MouseX. This enables animation, styling, binding, etc...
  23. public static readonly DependencyProperty MouseXProperty =
  24. DependencyProperty.Register("MouseX", typeof(double), typeof(MainDrawingPanel), new PropertyMetadata(null));
  25. // Using a DependencyProperty as the backing store for MouseX. This enables animation, styling, binding, etc...
  26. public static readonly DependencyProperty MouseYProperty =
  27. DependencyProperty.Register("MouseY", typeof(double), typeof(MainDrawingPanel), new PropertyMetadata(null));
  28. // Using a DependencyProperty as the backing store for MouseMoveCommand. This enables animation, styling, binding, etc...
  29. public static readonly DependencyProperty MouseMoveCommandProperty =
  30. DependencyProperty.Register("MouseMoveCommand", typeof(ICommand), typeof(MainDrawingPanel),
  31. new PropertyMetadata(null));
  32. // Using a DependencyProperty as the backing store for CenterOnStart. This enables animation, styling, binding, etc...
  33. public static readonly DependencyProperty CenterOnStartProperty =
  34. DependencyProperty.Register("CenterOnStart", typeof(bool), typeof(MainDrawingPanel),
  35. new PropertyMetadata(false));
  36. // Using a DependencyProperty as the backing store for Item. This enables animation, styling, binding, etc...
  37. public static readonly DependencyProperty ItemProperty =
  38. DependencyProperty.Register("Item", typeof(object), typeof(MainDrawingPanel), new PropertyMetadata(default(FrameworkElement)));
  39. // Using a DependencyProperty as the backing store for Item. This enables animation, styling, binding, etc...
  40. public static readonly DependencyProperty IsUsingZoomToolProperty =
  41. DependencyProperty.Register("IsUsingZoomTool", typeof(bool), typeof(MainDrawingPanel), new PropertyMetadata(false));
  42. public double ZoomPercentage
  43. {
  44. get { return (double)GetValue(ZoomPercentageProperty); }
  45. set { SetValue(ZoomPercentageProperty, value); }
  46. }
  47. // Using a DependencyProperty as the backing store for ZoomPercentage. This enables animation, styling, binding, etc...
  48. public static readonly DependencyProperty ZoomPercentageProperty =
  49. DependencyProperty.Register("ZoomPercentage", typeof(double), typeof(MainDrawingPanel), new PropertyMetadata(0.0, ZoomPercentegeChanged));
  50. public Point ViewportPosition
  51. {
  52. get { return (Point)GetValue(ViewportPositionProperty); }
  53. set { SetValue(ViewportPositionProperty, value); }
  54. }
  55. // Using a DependencyProperty as the backing store for ViewportPosition. This enables animation, styling, binding, etc...
  56. public static readonly DependencyProperty ViewportPositionProperty =
  57. DependencyProperty.Register("ViewportPosition", typeof(Point),
  58. typeof(MainDrawingPanel), new PropertyMetadata(default(Point), ViewportPosCallback));
  59. public bool Center
  60. {
  61. get => (bool) GetValue(CenterProperty);
  62. set => SetValue(CenterProperty, value);
  63. }
  64. public double MouseX
  65. {
  66. get => (double) GetValue(MouseXProperty);
  67. set => SetValue(MouseXProperty, value);
  68. }
  69. public double MouseY
  70. {
  71. get => (double) GetValue(MouseYProperty);
  72. set => SetValue(MouseYProperty, value);
  73. }
  74. public ICommand MouseMoveCommand
  75. {
  76. get => (ICommand) GetValue(MouseMoveCommandProperty);
  77. set => SetValue(MouseMoveCommandProperty, value);
  78. }
  79. public bool CenterOnStart
  80. {
  81. get => (bool) GetValue(CenterOnStartProperty);
  82. set => SetValue(CenterOnStartProperty, value);
  83. }
  84. public object Item
  85. {
  86. get => GetValue(ItemProperty);
  87. set => SetValue(ItemProperty, value);
  88. }
  89. public bool IsUsingZoomTool
  90. {
  91. get => (bool) GetValue(IsUsingZoomToolProperty);
  92. set => SetValue(IsUsingZoomToolProperty, value);
  93. }
  94. public ICommand MiddleMouseClickedCommand
  95. {
  96. get { return (ICommand)GetValue(MiddleMouseClickedCommandProperty); }
  97. set { SetValue(MiddleMouseClickedCommandProperty, value); }
  98. }
  99. // Using a DependencyProperty as the backing store for MiddleMouseClickedCommand. This enables animation, styling, binding, etc...
  100. public static readonly DependencyProperty MiddleMouseClickedCommandProperty =
  101. DependencyProperty.Register("MiddleMouseClickedCommand", typeof(ICommand), typeof(MainDrawingPanel), new PropertyMetadata(default(ICommand)));
  102. public object MiddleMouseClickedCommandParameter
  103. {
  104. get { return (object)GetValue(MiddleMouseClickedCommandParameterProperty); }
  105. set { SetValue(MiddleMouseClickedCommandParameterProperty, value); }
  106. }
  107. // Using a DependencyProperty as the backing store for MiddleMouseClickedCommandParameter. This enables animation, styling, binding, etc...
  108. public static readonly DependencyProperty MiddleMouseClickedCommandParameterProperty =
  109. DependencyProperty.Register("MiddleMouseClickedCommandParameter", typeof(object), typeof(MainDrawingPanel),
  110. new PropertyMetadata(default(object)));
  111. private static void ZoomPercentegeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  112. {
  113. MainDrawingPanel panel = (MainDrawingPanel)d;
  114. double percentage = (double)e.NewValue;
  115. if(percentage == 100)
  116. {
  117. panel.SetClickValues();
  118. }
  119. panel.Zoombox.ZoomTo(panel.ClickScale * ((double)e.NewValue / 100.0));
  120. }
  121. public double ClickScale;
  122. public Point ClickPosition;
  123. public MainDrawingPanel()
  124. {
  125. InitializeComponent();
  126. Zoombox.ZoomToSelectionModifiers = new KeyModifierCollection() { KeyModifier.RightAlt };
  127. }
  128. private static void ViewportPosCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
  129. {
  130. MainDrawingPanel panel = (MainDrawingPanel)d;
  131. if (PresentationSource.FromVisual(panel.Zoombox) == null)
  132. {
  133. panel.Zoombox.Position = default;
  134. return;
  135. }
  136. TranslateZoombox(panel, (Point)e.NewValue);
  137. }
  138. private static void TranslateZoombox(MainDrawingPanel panel, Point vector)
  139. {
  140. var newPos = new Point(panel.ClickPosition.X + vector.X,
  141. panel.ClickPosition.Y + vector.Y);
  142. panel.Zoombox.Position = newPos;
  143. }
  144. private void Zoombox_CurrentViewChanged(object sender, ZoomboxViewChangedEventArgs e)
  145. {
  146. Zoombox.MinScale = 32 / ((FrameworkElement)Item).Width;
  147. Zoombox.KeepContentInBounds = !(Zoombox.Scale > Zoombox.MinScale * 35.0);
  148. }
  149. private void Zoombox_PreviewMouseDown(object sender, MouseButtonEventArgs e)
  150. {
  151. if (ZoomPercentage == 100)
  152. {
  153. SetClickValues();
  154. }
  155. }
  156. private void SetClickValues()
  157. {
  158. if (!IsUsingZoomTool) return;
  159. ClickScale = Zoombox.Scale;
  160. SetZoomOrigin();
  161. }
  162. private void SetZoomOrigin()
  163. {
  164. var item = (FrameworkElement)Item;
  165. if (item == null) return;
  166. var mousePos = Mouse.GetPosition(item);
  167. Zoombox.ZoomOrigin = new Point(Math.Clamp(mousePos.X / item.Width, 0, 1), Math.Clamp(mousePos.Y / item.Height, 0, 1));
  168. }
  169. private static void OnCenterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  170. {
  171. MainDrawingPanel panel = (MainDrawingPanel) d;
  172. panel.Zoombox.CenterContent();
  173. }
  174. private void Zoombox_Loaded(object sender, RoutedEventArgs e)
  175. {
  176. if (CenterOnStart) ((Zoombox) sender).CenterContent();
  177. ClickScale = Zoombox.Scale;
  178. }
  179. private void Zoombox_MouseWheel(object sender, MouseWheelEventArgs e)
  180. {
  181. SetZoomOrigin();
  182. }
  183. private void mainDrawingPanel_MouseDown(object sender, MouseButtonEventArgs e)
  184. {
  185. IsUsingZoomTool = ViewModelMain.Current.BitmapManager.SelectedTool is ZoomTool;
  186. Mouse.Capture((IInputElement)sender, CaptureMode.SubTree);
  187. ClickPosition = ((FrameworkElement)Item).TranslatePoint(new Point(0, 0), Zoombox);
  188. SetClickValues();
  189. }
  190. private void mainDrawingPanel_PreviewMouseUp(object sender, MouseButtonEventArgs e)
  191. {
  192. ((IInputElement)sender).ReleaseMouseCapture();
  193. }
  194. private void Zoombox_MouseDown(object sender, MouseButtonEventArgs e)
  195. {
  196. if (e.MiddleButton == MouseButtonState.Pressed &&
  197. MiddleMouseClickedCommand.CanExecute(MiddleMouseClickedCommandParameter))
  198. {
  199. MiddleMouseClickedCommand.Execute(MiddleMouseClickedCommandParameter);
  200. }
  201. }
  202. }
  203. }