ToolPointer.cs 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. using System;
  2. using System.Windows.Forms;
  3. using System.Drawing;
  4. namespace DrawTools
  5. {
  6. /// <summary>
  7. /// Pointer tool
  8. /// </summary>
  9. class ToolPointer : DrawTools.Tool
  10. {
  11. private enum SelectionMode
  12. {
  13. None,
  14. NetSelection, // group selection is active
  15. Move, // object(s) are moves
  16. Size // object is resized
  17. }
  18. private SelectionMode selectMode = SelectionMode.None;
  19. // Object which is currently resized:
  20. private DrawObject resizedObject;
  21. private int resizedObjectHandle;
  22. // Keep state about last and current point (used to move and resize objects)
  23. private Point lastPoint = new Point(0,0);
  24. private Point startPoint = new Point(0, 0);
  25. private CommandChangeState commandChangeState;
  26. bool wasMove;
  27. public ToolPointer()
  28. {
  29. }
  30. /// <summary>
  31. /// Left mouse button is pressed
  32. /// </summary>
  33. /// <param name="drawArea"></param>
  34. /// <param name="e"></param>
  35. public override void OnMouseDown(DrawArea drawArea, MouseEventArgs e)
  36. {
  37. commandChangeState = null;
  38. wasMove = false;
  39. selectMode = SelectionMode.None;
  40. Point point = new Point(e.X, e.Y);
  41. // Test for resizing (only if control is selected, cursor is on the handle)
  42. foreach (DrawObject o in drawArea.GraphicsList.Selection)
  43. {
  44. int handleNumber = o.HitTest(point);
  45. if (handleNumber > 0)
  46. {
  47. selectMode = SelectionMode.Size;
  48. // keep resized object in class member
  49. resizedObject = o;
  50. resizedObjectHandle = handleNumber;
  51. // Since we want to resize only one object, unselect all other objects
  52. drawArea.GraphicsList.UnselectAll();
  53. o.Selected = true;
  54. commandChangeState = new CommandChangeState(drawArea.GraphicsList);
  55. break;
  56. }
  57. }
  58. // Test for move (cursor is on the object)
  59. if ( selectMode == SelectionMode.None )
  60. {
  61. int n1 = drawArea.GraphicsList.Count;
  62. DrawObject o = null;
  63. for ( int i = 0; i < n1; i++ )
  64. {
  65. if ( drawArea.GraphicsList[i].HitTest(point) == 0 )
  66. {
  67. o = drawArea.GraphicsList[i];
  68. break;
  69. }
  70. }
  71. if ( o != null )
  72. {
  73. selectMode = SelectionMode.Move;
  74. // Unselect all if Ctrl is not pressed and clicked object is not selected yet
  75. if ( ( Control.ModifierKeys & Keys.Control ) == 0 && !o.Selected )
  76. drawArea.GraphicsList.UnselectAll();
  77. // Select clicked object
  78. o.Selected = true;
  79. commandChangeState = new CommandChangeState(drawArea.GraphicsList);
  80. drawArea.Cursor = Cursors.SizeAll;
  81. }
  82. }
  83. // Net selection
  84. if ( selectMode == SelectionMode.None )
  85. {
  86. // click on background
  87. if ( ( Control.ModifierKeys & Keys.Control ) == 0 )
  88. drawArea.GraphicsList.UnselectAll();
  89. selectMode = SelectionMode.NetSelection;
  90. }
  91. lastPoint.X = e.X;
  92. lastPoint.Y = e.Y;
  93. startPoint.X = e.X;
  94. startPoint.Y = e.Y;
  95. drawArea.Capture = true;
  96. drawArea.Refresh();
  97. if ( selectMode == SelectionMode.NetSelection )
  98. {
  99. // Draw selection rectangle in initial position
  100. ControlPaint.DrawReversibleFrame(
  101. drawArea.RectangleToScreen(DrawRectangle.GetNormalizedRectangle(startPoint, lastPoint)),
  102. Color.Black,
  103. FrameStyle.Dashed);
  104. }
  105. }
  106. /// <summary>
  107. /// Mouse is moved.
  108. /// None button is pressed, or left button is pressed.
  109. /// </summary>
  110. /// <param name="drawArea"></param>
  111. /// <param name="e"></param>
  112. public override void OnMouseMove(DrawArea drawArea, MouseEventArgs e)
  113. {
  114. Point point = new Point(e.X, e.Y);
  115. Point oldPoint = lastPoint;
  116. wasMove = true;
  117. // set cursor when mouse button is not pressed
  118. if (e.Button == MouseButtons.None)
  119. {
  120. Cursor cursor = null;
  121. for (int i = 0; i < drawArea.GraphicsList.Count; i++)
  122. {
  123. int n = drawArea.GraphicsList[i].HitTest(point);
  124. if (n > 0)
  125. {
  126. cursor = drawArea.GraphicsList[i].GetHandleCursor(n);
  127. break;
  128. }
  129. }
  130. if (cursor == null)
  131. cursor = Cursors.Default;
  132. drawArea.Cursor = cursor;
  133. return;
  134. }
  135. if (e.Button != MouseButtons.Left)
  136. return;
  137. /// Left button is pressed
  138. // Find difference between previous and current position
  139. int dx = e.X - lastPoint.X;
  140. int dy = e.Y - lastPoint.Y;
  141. lastPoint.X = e.X;
  142. lastPoint.Y = e.Y;
  143. // resize
  144. if (selectMode == SelectionMode.Size)
  145. {
  146. if (resizedObject != null)
  147. {
  148. resizedObject.MoveHandleTo(point, resizedObjectHandle);
  149. drawArea.SetDirty();
  150. drawArea.Refresh();
  151. }
  152. }
  153. // move
  154. if (selectMode == SelectionMode.Move)
  155. {
  156. foreach (DrawObject o in drawArea.GraphicsList.Selection)
  157. {
  158. o.Move(dx, dy);
  159. }
  160. drawArea.Cursor = Cursors.SizeAll;
  161. drawArea.SetDirty();
  162. drawArea.Refresh();
  163. }
  164. if (selectMode == SelectionMode.NetSelection)
  165. {
  166. // Remove old selection rectangle
  167. ControlPaint.DrawReversibleFrame(
  168. drawArea.RectangleToScreen(DrawRectangle.GetNormalizedRectangle(startPoint, oldPoint)),
  169. Color.Black,
  170. FrameStyle.Dashed);
  171. // Draw new selection rectangle
  172. ControlPaint.DrawReversibleFrame(
  173. drawArea.RectangleToScreen(DrawRectangle.GetNormalizedRectangle(startPoint, point)),
  174. Color.Black,
  175. FrameStyle.Dashed);
  176. return;
  177. }
  178. }
  179. /// <summary>
  180. /// Right mouse button is released
  181. /// </summary>
  182. /// <param name="drawArea"></param>
  183. /// <param name="e"></param>
  184. public override void OnMouseUp(DrawArea drawArea, MouseEventArgs e)
  185. {
  186. if ( selectMode == SelectionMode.NetSelection )
  187. {
  188. // Remove old selection rectangle
  189. ControlPaint.DrawReversibleFrame(
  190. drawArea.RectangleToScreen(DrawRectangle.GetNormalizedRectangle(startPoint, lastPoint)),
  191. Color.Black,
  192. FrameStyle.Dashed);
  193. // Make group selection
  194. drawArea.GraphicsList.SelectInRectangle(
  195. DrawRectangle.GetNormalizedRectangle(startPoint, lastPoint));
  196. selectMode = SelectionMode.None;
  197. }
  198. if ( resizedObject != null )
  199. {
  200. // after resizing
  201. resizedObject.Normalize();
  202. resizedObject = null;
  203. }
  204. drawArea.Capture = false;
  205. drawArea.Refresh();
  206. if ( commandChangeState != null && wasMove )
  207. {
  208. // Keep state after moving/resizing and add command to history
  209. commandChangeState.NewState(drawArea.GraphicsList);
  210. drawArea.AddCommandToHistory(commandChangeState);
  211. commandChangeState = null;
  212. }
  213. }
  214. }
  215. }