PageRenderTime 213ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/Main/src/DynamicDataDisplay/Charts/Navigation/KeyboardNavigation.cs

#
C# | 459 lines | 348 code | 99 blank | 12 comment | 5 complexity | dde15f0da9f00583ccb98bc4712c96dd MD5 | raw file
Possible License(s): CC-BY-SA-3.0
  1. using System.Windows;
  2. using System.Windows.Input;
  3. using System.Windows.Media;
  4. using Microsoft.Win32;
  5. using System;
  6. using Microsoft.Research.DynamicDataDisplay.Common.UndoSystem;
  7. using System.Collections.Generic;
  8. using Microsoft.Research.DynamicDataDisplay.Charts.Navigation;
  9. namespace Microsoft.Research.DynamicDataDisplay.Navigation
  10. {
  11. /// <summary>Provides keyboard navigation around viewport of ChartPlotter.</summary>
  12. public class KeyboardNavigation : IPlotterElement
  13. {
  14. /// <summary>
  15. /// Initializes a new instance of the <see cref="KeyboardNavigation"/> class.
  16. /// </summary>
  17. public KeyboardNavigation() { }
  18. private bool isReversed = true;
  19. /// <summary>
  20. /// Gets or sets a value indicating whether panning directions are reversed.
  21. /// </summary>
  22. /// <value>
  23. /// <c>true</c> if panning directions are reversed; otherwise, <c>false</c>.
  24. /// </value>
  25. public bool IsReversed
  26. {
  27. get { return isReversed; }
  28. set { isReversed = value; }
  29. }
  30. private readonly List<CommandBinding> addedBindings = new List<CommandBinding>();
  31. private void AddBinding(CommandBinding binding)
  32. {
  33. plotter2D.CommandBindings.Add(binding);
  34. addedBindings.Add(binding);
  35. }
  36. private void InitCommands()
  37. {
  38. if (plotter2D == null)
  39. return;
  40. var zoomOutToMouseCommandBinding = new CommandBinding(
  41. ChartCommands.ZoomOutToMouse,
  42. ZoomOutToMouseExecute,
  43. ZoomOutToMouseCanExecute);
  44. AddBinding(zoomOutToMouseCommandBinding);
  45. var zoomInToMouseCommandBinding = new CommandBinding(
  46. ChartCommands.ZoomInToMouse,
  47. ZoomInToMouseExecute,
  48. ZoomInToMouseCanExecute);
  49. AddBinding(zoomInToMouseCommandBinding);
  50. var zoomWithParamCommandBinding = new CommandBinding(
  51. ChartCommands.ZoomWithParameter,
  52. ZoomWithParamExecute,
  53. ZoomWithParamCanExecute);
  54. AddBinding(zoomWithParamCommandBinding);
  55. var zoomInCommandBinding = new CommandBinding(
  56. ChartCommands.ZoomIn,
  57. ZoomInExecute,
  58. ZoomInCanExecute);
  59. AddBinding(zoomInCommandBinding);
  60. var zoomOutCommandBinding = new CommandBinding(
  61. ChartCommands.ZoomOut,
  62. ZoomOutExecute,
  63. ZoomOutCanExecute);
  64. AddBinding(zoomOutCommandBinding);
  65. var fitToViewCommandBinding = new CommandBinding(
  66. ChartCommands.FitToView,
  67. FitToViewExecute,
  68. FitToViewCanExecute);
  69. AddBinding(fitToViewCommandBinding);
  70. var ScrollLeftCommandBinding = new CommandBinding(
  71. ChartCommands.ScrollLeft,
  72. ScrollLeftExecute,
  73. ScrollLeftCanExecute);
  74. AddBinding(ScrollLeftCommandBinding);
  75. var ScrollRightCommandBinding = new CommandBinding(
  76. ChartCommands.ScrollRight,
  77. ScrollRightExecute,
  78. ScrollRightCanExecute);
  79. AddBinding(ScrollRightCommandBinding);
  80. var ScrollUpCommandBinding = new CommandBinding(
  81. ChartCommands.ScrollUp,
  82. ScrollUpExecute,
  83. ScrollUpCanExecute);
  84. AddBinding(ScrollUpCommandBinding);
  85. var ScrollDownCommandBinding = new CommandBinding(
  86. ChartCommands.ScrollDown,
  87. ScrollDownExecute,
  88. ScrollDownCanExecute);
  89. AddBinding(ScrollDownCommandBinding);
  90. var SaveScreenshotCommandBinding = new CommandBinding(
  91. ChartCommands.SaveScreenshot,
  92. SaveScreenshotExecute,
  93. SaveScreenshotCanExecute);
  94. AddBinding(SaveScreenshotCommandBinding);
  95. var CopyScreenshotCommandBinding = new CommandBinding(
  96. ChartCommands.CopyScreenshot,
  97. CopyScreenshotExecute,
  98. CopyScreenshotCanExecute);
  99. AddBinding(CopyScreenshotCommandBinding);
  100. var ShowHelpCommandBinding = new CommandBinding(
  101. ChartCommands.ShowHelp,
  102. ShowHelpExecute,
  103. ShowHelpCanExecute);
  104. AddBinding(ShowHelpCommandBinding);
  105. var UndoCommandBinding = new CommandBinding(
  106. ApplicationCommands.Undo,
  107. UndoExecute,
  108. UndoCanExecute);
  109. AddBinding(UndoCommandBinding);
  110. var RedoCommandBinding = new CommandBinding(
  111. ApplicationCommands.Redo,
  112. RedoExecute,
  113. RedoCanExecute);
  114. AddBinding(RedoCommandBinding);
  115. }
  116. #region Zoom Out To Mouse
  117. private void ZoomToPoint(double coeff)
  118. {
  119. Point pt = Mouse.GetPosition(plotter2D.CentralGrid);
  120. Point dataPoint = Viewport.Transform.ScreenToData(pt);
  121. DataRect visible = Viewport.Visible;
  122. Viewport.SetChangeType(ChangeType.Zoom);
  123. Viewport.Visible = visible.Zoom(dataPoint, coeff);
  124. Viewport.SetChangeType();
  125. }
  126. private void ZoomOutToMouseExecute(object target, ExecutedRoutedEventArgs e)
  127. {
  128. ZoomToPoint(zoomOutCoeff);
  129. e.Handled = true;
  130. }
  131. private void ZoomOutToMouseCanExecute(object target, CanExecuteRoutedEventArgs e)
  132. {
  133. e.CanExecute = true;
  134. }
  135. #endregion
  136. #region Zoom In To Mouse
  137. private void ZoomInToMouseExecute(object target, ExecutedRoutedEventArgs e)
  138. {
  139. ZoomToPoint(zoomInCoeff);
  140. e.Handled = true;
  141. }
  142. private void ZoomInToMouseCanExecute(object target, CanExecuteRoutedEventArgs e)
  143. {
  144. e.CanExecute = true;
  145. }
  146. #endregion
  147. #region Zoom With param
  148. private void ZoomWithParamExecute(object target, ExecutedRoutedEventArgs e)
  149. {
  150. double zoomParam = (double)e.Parameter;
  151. plotter2D.Viewport.Zoom(zoomParam);
  152. e.Handled = true;
  153. }
  154. private void ZoomWithParamCanExecute(object target, CanExecuteRoutedEventArgs e)
  155. {
  156. e.CanExecute = true;
  157. }
  158. #endregion
  159. #region Zoom in
  160. private const double zoomInCoeff = 0.9;
  161. private void ZoomInExecute(object target, ExecutedRoutedEventArgs e)
  162. {
  163. Viewport.Zoom(zoomInCoeff);
  164. e.Handled = true;
  165. }
  166. private void ZoomInCanExecute(object target, CanExecuteRoutedEventArgs e)
  167. {
  168. e.CanExecute = true;
  169. }
  170. #endregion
  171. #region Zoom out
  172. private const double zoomOutCoeff = 1 / zoomInCoeff;
  173. private void ZoomOutExecute(object target, ExecutedRoutedEventArgs e)
  174. {
  175. Viewport.Zoom(zoomOutCoeff);
  176. e.Handled = true;
  177. }
  178. private void ZoomOutCanExecute(object target, CanExecuteRoutedEventArgs e)
  179. {
  180. e.CanExecute = true;
  181. }
  182. #endregion
  183. #region Fit to view
  184. private void FitToViewExecute(object target, ExecutedRoutedEventArgs e)
  185. {
  186. // todo сделать нормально.
  187. (Viewport as Viewport2D).FitToView();
  188. e.Handled = true;
  189. }
  190. private void FitToViewCanExecute(object target, CanExecuteRoutedEventArgs e)
  191. {
  192. // todo add a check if viewport is already fitted to view.
  193. e.CanExecute = true;
  194. }
  195. #endregion
  196. #region Scroll
  197. private double scrollCoeff = 0.05;
  198. private void ScrollVisibleProportionally(double xShiftCoeff, double yShiftCoeff)
  199. {
  200. DataRect visible = Viewport.Visible;
  201. DataRect oldVisible = visible;
  202. double width = visible.Width;
  203. double height = visible.Height;
  204. double reverseCoeff = isReversed ? -1 : 1;
  205. visible.Offset(reverseCoeff * xShiftCoeff * width, reverseCoeff * yShiftCoeff * height);
  206. Viewport.SetChangeType(xShiftCoeff == 0 ? ChangeType.PanY : ChangeType.PanX);
  207. Viewport.Visible = visible;
  208. Viewport.SetChangeType();
  209. plotter2D.UndoProvider.AddAction(new DependencyPropertyChangedUndoAction(Viewport, Viewport2D.VisibleProperty, oldVisible, visible));
  210. }
  211. #region ScrollLeft
  212. private void ScrollLeftExecute(object target, ExecutedRoutedEventArgs e)
  213. {
  214. ScrollVisibleProportionally(scrollCoeff, 0);
  215. e.Handled = true;
  216. }
  217. private void ScrollLeftCanExecute(object target, CanExecuteRoutedEventArgs e)
  218. {
  219. e.CanExecute = true;
  220. }
  221. #endregion
  222. #region ScrollRight
  223. private void ScrollRightExecute(object target, ExecutedRoutedEventArgs e)
  224. {
  225. ScrollVisibleProportionally(-scrollCoeff, 0);
  226. e.Handled = true;
  227. }
  228. private void ScrollRightCanExecute(object target, CanExecuteRoutedEventArgs e)
  229. {
  230. e.CanExecute = true;
  231. }
  232. #endregion
  233. #region ScrollUp
  234. private void ScrollUpExecute(object target, ExecutedRoutedEventArgs e)
  235. {
  236. ScrollVisibleProportionally(0, -scrollCoeff);
  237. e.Handled = true;
  238. }
  239. private void ScrollUpCanExecute(object target, CanExecuteRoutedEventArgs e)
  240. {
  241. e.CanExecute = true;
  242. }
  243. #endregion
  244. #region ScrollDown
  245. private void ScrollDownExecute(object target, ExecutedRoutedEventArgs e)
  246. {
  247. ScrollVisibleProportionally(0, scrollCoeff);
  248. e.Handled = true;
  249. }
  250. private void ScrollDownCanExecute(object target, CanExecuteRoutedEventArgs e)
  251. {
  252. e.CanExecute = true;
  253. }
  254. #endregion
  255. #endregion
  256. #region SaveScreenshot
  257. private void SaveScreenshotExecute(object target, ExecutedRoutedEventArgs e)
  258. {
  259. SaveFileDialog dlg = new SaveFileDialog();
  260. dlg.Filter = "PNG (*.png)|*.png|JPEG (*.jpg)|*.jpg|BMP (*.bmp)|*.bmp|GIF (*.gif)|*.gif";
  261. dlg.FilterIndex = 1;
  262. dlg.AddExtension = true;
  263. if (dlg.ShowDialog().GetValueOrDefault(false))
  264. {
  265. string filePath = dlg.FileName;
  266. plotter2D.SaveScreenshot(filePath);
  267. e.Handled = true;
  268. }
  269. }
  270. private void SaveScreenshotCanExecute(object target, CanExecuteRoutedEventArgs e)
  271. {
  272. e.CanExecute = true;
  273. }
  274. #endregion
  275. #region CopyScreenshot
  276. private void CopyScreenshotExecute(object target, ExecutedRoutedEventArgs e)
  277. {
  278. plotter2D.CopyScreenshotToClipboard();
  279. e.Handled = true;
  280. }
  281. private void CopyScreenshotCanExecute(object target, CanExecuteRoutedEventArgs e)
  282. {
  283. e.CanExecute = true;
  284. }
  285. #endregion
  286. #region ShowHelp
  287. private bool aboutWindowOpened = false;
  288. private void ShowHelpExecute(object target, ExecutedRoutedEventArgs e)
  289. {
  290. if (!aboutWindowOpened)
  291. {
  292. AboutWindow window = new AboutWindow();
  293. window.Closed += new EventHandler(aboutWindow_Closed);
  294. window.DataContext = plotter2D;
  295. window.Owner = Window.GetWindow(plotter2D);
  296. aboutWindowOpened = true;
  297. window.Show();
  298. e.Handled = true;
  299. }
  300. }
  301. void aboutWindow_Closed(object sender, EventArgs e)
  302. {
  303. Window window = (Window)sender;
  304. window.Closed -= aboutWindow_Closed;
  305. aboutWindowOpened = false;
  306. }
  307. private void ShowHelpCanExecute(object target, CanExecuteRoutedEventArgs e)
  308. {
  309. e.CanExecute = !aboutWindowOpened;
  310. }
  311. #endregion
  312. #region Undo
  313. private void UndoExecute(object target, ExecutedRoutedEventArgs e)
  314. {
  315. plotter2D.UndoProvider.Undo();
  316. e.Handled = true;
  317. }
  318. private void UndoCanExecute(object target, CanExecuteRoutedEventArgs e)
  319. {
  320. e.CanExecute = plotter2D.UndoProvider.CanUndo;
  321. }
  322. #endregion
  323. #region Redo
  324. private void RedoExecute(object target, ExecutedRoutedEventArgs e)
  325. {
  326. plotter2D.UndoProvider.Redo();
  327. e.Handled = true;
  328. }
  329. private void RedoCanExecute(object target, CanExecuteRoutedEventArgs e)
  330. {
  331. e.CanExecute = plotter2D.UndoProvider.CanRedo;
  332. }
  333. #endregion
  334. #region IPlotterElement Members
  335. private Viewport2D Viewport
  336. {
  337. get { return plotter2D.Viewport; }
  338. }
  339. private Plotter2D plotter2D;
  340. void IPlotterElement.OnPlotterAttached(Plotter plotter)
  341. {
  342. plotter2D = (Plotter2D)plotter;
  343. InitCommands();
  344. }
  345. void IPlotterElement.OnPlotterDetaching(Plotter plotter)
  346. {
  347. foreach (var commandBinding in addedBindings)
  348. {
  349. plotter.CommandBindings.Remove(commandBinding);
  350. }
  351. addedBindings.Clear();
  352. this.plotter2D = null;
  353. }
  354. Plotter IPlotterElement.Plotter
  355. {
  356. get { return plotter2D; }
  357. }
  358. #endregion
  359. }
  360. }