xref: /reactos/base/applications/mspaint/mouse.cpp (revision ccef43f3)
1 /*
2  * PROJECT:     PAINT for ReactOS
3  * LICENSE:     LGPL
4  * FILE:        base/applications/mspaint/mouse.cpp
5  * PURPOSE:     Things which should not be in the mouse event handler itself
6  * PROGRAMMERS: Benedikt Freisen
7  *              Katayama Hirofumi MZ
8  */
9 
10 /* INCLUDES *********************************************************/
11 
12 #include "precomp.h"
13 
14 INT ToolBase::pointSP = 0;
15 POINT ToolBase::pointStack[256] = { { 0 } };
16 
17 /* FUNCTIONS ********************************************************/
18 
19 void
20 regularize(LONG x0, LONG y0, LONG& x1, LONG& y1)
21 {
22     if (abs(x1 - x0) >= abs(y1 - y0))
23         y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0));
24     else
25         x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0));
26 }
27 
28 void
29 roundTo8Directions(LONG x0, LONG y0, LONG& x1, LONG& y1)
30 {
31     if (abs(x1 - x0) >= abs(y1 - y0))
32     {
33         if (abs(y1 - y0) * 5 < abs(x1 - x0) * 2)
34             y1 = y0;
35         else
36             y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0));
37     }
38     else
39     {
40         if (abs(x1 - x0) * 5 < abs(y1 - y0) * 2)
41             x1 = x0;
42         else
43             x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0));
44     }
45 }
46 
47 BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1)
48 {
49     INT cxThreshold = toolsModel.GetLineWidth() + UnZoomed(GetSystemMetrics(SM_CXDRAG));
50     INT cyThreshold = toolsModel.GetLineWidth() + UnZoomed(GetSystemMetrics(SM_CYDRAG));
51     return (abs(x1 - x0) <= cxThreshold) && (abs(y1 - y0) <= cyThreshold);
52 }
53 
54 void updateStartAndLast(LONG x, LONG y)
55 {
56     start.x = last.x = x;
57     start.y = last.y = y;
58 }
59 
60 void updateLast(LONG x, LONG y)
61 {
62     last.x = x;
63     last.y = y;
64 }
65 
66 void ToolBase::reset()
67 {
68     pointSP = 0;
69     start.x = start.y = last.x = last.y = -1;
70     selectionModel.ResetPtStack();
71     if (selectionModel.m_bShow)
72     {
73         selectionModel.Landing();
74         selectionModel.m_bShow = FALSE;
75     }
76 }
77 
78 void ToolBase::OnCancelDraw()
79 {
80     reset();
81 }
82 
83 void ToolBase::OnFinishDraw()
84 {
85     reset();
86 }
87 
88 void ToolBase::beginEvent()
89 {
90     m_hdc = imageModel.GetDC();
91     m_fg = paletteModel.GetFgColor();
92     m_bg = paletteModel.GetBgColor();
93 }
94 
95 void ToolBase::endEvent()
96 {
97     m_hdc = NULL;
98 }
99 
100 /* TOOLS ********************************************************/
101 
102 // TOOL_FREESEL
103 struct FreeSelTool : ToolBase
104 {
105     BOOL m_bLeftButton;
106 
107     FreeSelTool() : ToolBase(TOOL_FREESEL), m_bLeftButton(FALSE)
108     {
109     }
110 
111     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
112     {
113         selectionModel.Landing();
114         if (bLeftButton)
115         {
116             imageModel.CopyPrevious();
117             selectionModel.m_bShow = FALSE;
118             selectionModel.ResetPtStack();
119             POINT pt = { x, y };
120             selectionModel.PushToPtStack(pt);
121         }
122         m_bLeftButton = bLeftButton;
123     }
124 
125     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
126     {
127         if (bLeftButton)
128         {
129             POINT pt = { x, y };
130             imageModel.Bound(pt);
131             selectionModel.PushToPtStack(pt);
132             imageModel.ResetToPrevious();
133             selectionModel.DrawFramePoly(m_hdc);
134         }
135     }
136 
137     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
138     {
139         if (bLeftButton)
140         {
141             imageModel.ResetToPrevious();
142             if (selectionModel.PtStackSize() > 2)
143             {
144                 selectionModel.BuildMaskFromPtStack();
145                 selectionModel.TakeOff();
146                 selectionModel.m_bShow = TRUE;
147             }
148             else
149             {
150                 imageModel.Undo(TRUE);
151                 selectionModel.ResetPtStack();
152                 selectionModel.m_bShow = FALSE;
153             }
154             imageArea.Invalidate(FALSE);
155         }
156     }
157 
158     void OnFinishDraw()
159     {
160         if (m_bLeftButton)
161             imageArea.Invalidate(FALSE);
162 
163         m_bLeftButton = FALSE;
164         ToolBase::OnFinishDraw();
165     }
166 
167     void OnCancelDraw()
168     {
169         if (m_bLeftButton)
170             imageModel.Undo(TRUE);
171         m_bLeftButton = FALSE;
172         ToolBase::OnCancelDraw();
173     }
174 };
175 
176 // TOOL_RECTSEL
177 struct RectSelTool : ToolBase
178 {
179     BOOL m_bLeftButton;
180 
181     RectSelTool() : ToolBase(TOOL_RECTSEL), m_bLeftButton(FALSE)
182     {
183     }
184 
185     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
186     {
187         selectionModel.Landing();
188         if (bLeftButton)
189         {
190             imageModel.CopyPrevious();
191             selectionModel.m_bShow = FALSE;
192             ::SetRectEmpty(&selectionModel.m_rc);
193         }
194         m_bLeftButton = bLeftButton;
195     }
196 
197     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
198     {
199         if (bLeftButton)
200         {
201             imageModel.ResetToPrevious();
202             POINT pt = { x, y };
203             imageModel.Bound(pt);
204             selectionModel.SetRectFromPoints(start, pt);
205             RectSel(m_hdc, start.x, start.y, pt.x, pt.y);
206         }
207     }
208 
209     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
210     {
211         if (bLeftButton)
212         {
213             imageModel.ResetToPrevious();
214             if (start.x == x && start.y == y)
215                 imageModel.Undo(TRUE);
216             selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty();
217             imageArea.Invalidate(FALSE);
218         }
219     }
220 
221     void OnFinishDraw()
222     {
223         if (m_bLeftButton)
224             imageArea.Invalidate(FALSE);
225 
226         m_bLeftButton = FALSE;
227         ToolBase::OnFinishDraw();
228     }
229 
230     void OnCancelDraw()
231     {
232         if (m_bLeftButton)
233             imageModel.Undo(TRUE);
234         m_bLeftButton = FALSE;
235         ToolBase::OnCancelDraw();
236     }
237 };
238 
239 struct GenericDrawTool : ToolBase
240 {
241     GenericDrawTool(TOOLTYPE type) : ToolBase(type)
242     {
243     }
244 
245     virtual void draw(BOOL bLeftButton, LONG x, LONG y) = 0;
246 
247     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
248     {
249         imageModel.CopyPrevious();
250         draw(bLeftButton, x, y);
251     }
252 
253     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
254     {
255         draw(bLeftButton, x, y);
256     }
257 
258     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
259     {
260         draw(bLeftButton, x, y);
261     }
262 
263     void OnCancelDraw()
264     {
265         OnButtonUp(FALSE, 0, 0);
266         imageModel.Undo(TRUE);
267         ToolBase::OnCancelDraw();
268     }
269 };
270 
271 // TOOL_RUBBER
272 struct RubberTool : GenericDrawTool
273 {
274     RubberTool() : GenericDrawTool(TOOL_RUBBER)
275     {
276     }
277 
278     virtual void draw(BOOL bLeftButton, LONG x, LONG y)
279     {
280         if (bLeftButton)
281             Erase(m_hdc, last.x, last.y, x, y, m_bg, toolsModel.GetRubberRadius());
282         else
283             Replace(m_hdc, last.x, last.y, x, y, m_fg, m_bg, toolsModel.GetRubberRadius());
284     }
285 };
286 
287 // TOOL_FILL
288 struct FillTool : ToolBase
289 {
290     FillTool() : ToolBase(TOOL_FILL)
291     {
292     }
293 
294     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
295     {
296         imageModel.CopyPrevious();
297         Fill(m_hdc, x, y, bLeftButton ? m_fg : m_bg);
298     }
299 };
300 
301 // TOOL_COLOR
302 struct ColorTool : ToolBase
303 {
304     ColorTool() : ToolBase(TOOL_COLOR)
305     {
306     }
307 
308     void fetchColor(BOOL bLeftButton, LONG x, LONG y)
309     {
310         COLORREF rgbColor;
311 
312         if (0 <= x && x < imageModel.GetWidth() && 0 <= y && y < imageModel.GetHeight())
313             rgbColor = GetPixel(m_hdc, x, y);
314         else
315             rgbColor = RGB(255, 255, 255); // Outside is white
316 
317         if (bLeftButton)
318             paletteModel.SetFgColor(rgbColor);
319         else
320             paletteModel.SetBgColor(rgbColor);
321     }
322 
323     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
324     {
325         fetchColor(bLeftButton, x, y);
326     }
327 
328     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
329     {
330         fetchColor(bLeftButton, x, y);
331         toolsModel.SetActiveTool(toolsModel.GetOldActiveTool());
332     }
333 };
334 
335 // TOOL_ZOOM
336 struct ZoomTool : ToolBase
337 {
338     ZoomTool() : ToolBase(TOOL_ZOOM)
339     {
340     }
341 
342     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
343     {
344         imageModel.CopyPrevious();
345         if (bLeftButton)
346         {
347             if (toolsModel.GetZoom() < MAX_ZOOM)
348                 zoomTo(toolsModel.GetZoom() * 2, x, y);
349         }
350         else
351         {
352             if (toolsModel.GetZoom() > MIN_ZOOM)
353                 zoomTo(toolsModel.GetZoom() / 2, x, y);
354         }
355     }
356 };
357 
358 // TOOL_PEN
359 struct PenTool : GenericDrawTool
360 {
361     PenTool() : GenericDrawTool(TOOL_PEN)
362     {
363     }
364 
365     virtual void draw(BOOL bLeftButton, LONG x, LONG y)
366     {
367         COLORREF rgb = bLeftButton ? m_fg : m_bg;
368         Line(m_hdc, last.x, last.y, x, y, rgb, 1);
369         SetPixel(m_hdc, x, y, rgb);
370     }
371 };
372 
373 // TOOL_BRUSH
374 struct BrushTool : GenericDrawTool
375 {
376     BrushTool() : GenericDrawTool(TOOL_BRUSH)
377     {
378     }
379 
380     virtual void draw(BOOL bLeftButton, LONG x, LONG y)
381     {
382         COLORREF rgb = bLeftButton ? m_fg : m_bg;
383         Brush(m_hdc, last.x, last.y, x, y, rgb, toolsModel.GetBrushStyle());
384     }
385 };
386 
387 // TOOL_AIRBRUSH
388 struct AirBrushTool : GenericDrawTool
389 {
390     AirBrushTool() : GenericDrawTool(TOOL_AIRBRUSH)
391     {
392     }
393 
394     virtual void draw(BOOL bLeftButton, LONG x, LONG y)
395     {
396         COLORREF rgb = bLeftButton ? m_fg : m_bg;
397         Airbrush(m_hdc, x, y, rgb, toolsModel.GetAirBrushWidth());
398     }
399 };
400 
401 // TOOL_TEXT
402 struct TextTool : ToolBase
403 {
404     TextTool() : ToolBase(TOOL_TEXT)
405     {
406     }
407 
408     void UpdatePoint(LONG x, LONG y)
409     {
410         imageModel.ResetToPrevious();
411         POINT pt = { x, y };
412         imageModel.Bound(pt);
413         selectionModel.SetRectFromPoints(start, pt);
414         RectSel(m_hdc, start.x, start.y, pt.x, pt.y);
415     }
416 
417     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
418     {
419         if (!textEditWindow.IsWindow())
420             textEditWindow.Create(imageArea);
421 
422         imageModel.CopyPrevious();
423         UpdatePoint(x, y);
424     }
425 
426     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
427     {
428         UpdatePoint(x, y);
429     }
430 
431     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
432     {
433         imageModel.Undo(TRUE);
434 
435         POINT pt = { x, y };
436         imageModel.Bound(pt);
437         selectionModel.SetRectFromPoints(start, pt);
438 
439         BOOL bTextBoxShown = ::IsWindowVisible(textEditWindow);
440         if (bTextBoxShown && textEditWindow.GetWindowTextLength() > 0)
441         {
442             CString szText;
443             textEditWindow.GetWindowText(szText);
444 
445             RECT rc;
446             textEditWindow.InvalidateEditRect();
447             textEditWindow.GetEditRect(&rc);
448 
449             INT style = (toolsModel.IsBackgroundTransparent() ? 0 : 1);
450             imageModel.CopyPrevious();
451             Text(m_hdc, rc.left, rc.top, rc.right, rc.bottom, m_fg, m_bg, szText,
452                  textEditWindow.GetFont(), style);
453 
454             if (selectionModel.m_rc.IsRectEmpty())
455             {
456                 textEditWindow.ShowWindow(SW_HIDE);
457                 textEditWindow.SetWindowText(NULL);
458                 return;
459             }
460         }
461 
462         if (registrySettings.ShowTextTool)
463         {
464             if (!fontsDialog.IsWindow())
465                 fontsDialog.Create(mainWindow);
466 
467             fontsDialog.ShowWindow(SW_SHOWNOACTIVATE);
468         }
469 
470         RECT rc = selectionModel.m_rc;
471 
472         // Enlarge if tool small
473         INT cxMin = CX_MINTEXTEDIT, cyMin = CY_MINTEXTEDIT;
474         if (selectionModel.m_rc.IsRectEmpty())
475         {
476             SetRect(&rc, x, y, x + cxMin, y + cyMin);
477         }
478         else
479         {
480             if (rc.right - rc.left < cxMin)
481                 rc.right = rc.left + cxMin;
482             if (rc.bottom - rc.top < cyMin)
483                 rc.bottom = rc.top + cyMin;
484         }
485 
486         if (!textEditWindow.IsWindow())
487             textEditWindow.Create(imageArea);
488 
489         textEditWindow.SetWindowText(NULL);
490         textEditWindow.ValidateEditRect(&rc);
491         textEditWindow.ShowWindow(SW_SHOWNOACTIVATE);
492         textEditWindow.SetFocus();
493     }
494 
495     void OnFinishDraw()
496     {
497         toolsModel.OnButtonDown(TRUE, -1, -1, TRUE);
498         toolsModel.OnButtonUp(TRUE, -1, -1);
499         ToolBase::OnFinishDraw();
500     }
501 };
502 
503 // TOOL_LINE
504 struct LineTool : GenericDrawTool
505 {
506     LineTool() : GenericDrawTool(TOOL_LINE)
507     {
508     }
509 
510     virtual void draw(BOOL bLeftButton, LONG x, LONG y)
511     {
512         imageModel.ResetToPrevious();
513         if (GetAsyncKeyState(VK_SHIFT) < 0)
514             roundTo8Directions(start.x, start.y, x, y);
515         COLORREF rgb = bLeftButton ? m_fg : m_bg;
516         Line(m_hdc, start.x, start.y, x, y, rgb, toolsModel.GetLineWidth());
517     }
518 };
519 
520 // TOOL_BEZIER
521 struct BezierTool : ToolBase
522 {
523     BOOL m_bLeftButton;
524 
525     BezierTool() : ToolBase(TOOL_BEZIER), m_bLeftButton(FALSE)
526     {
527     }
528 
529     void draw(BOOL bLeftButton)
530     {
531         COLORREF rgb = (bLeftButton ? m_fg : m_bg);
532         switch (pointSP)
533         {
534             case 1:
535                 Line(m_hdc, pointStack[0].x, pointStack[0].y, pointStack[1].x, pointStack[1].y, rgb,
536                      toolsModel.GetLineWidth());
537                 break;
538             case 2:
539                 Bezier(m_hdc, pointStack[0], pointStack[2], pointStack[2], pointStack[1], rgb, toolsModel.GetLineWidth());
540                 break;
541             case 3:
542                 Bezier(m_hdc, pointStack[0], pointStack[2], pointStack[3], pointStack[1], rgb, toolsModel.GetLineWidth());
543                 break;
544         }
545         m_bLeftButton = bLeftButton;
546     }
547 
548     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
549     {
550         pointStack[pointSP].x = x;
551         pointStack[pointSP].y = y;
552 
553         if (pointSP == 0)
554         {
555             imageModel.CopyPrevious();
556             pointSP++;
557         }
558     }
559 
560     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
561     {
562         imageModel.ResetToPrevious();
563         pointStack[pointSP].x = x;
564         pointStack[pointSP].y = y;
565         draw(bLeftButton);
566     }
567 
568     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
569     {
570         imageModel.ResetToPrevious();
571         draw(bLeftButton);
572         pointSP++;
573         if (pointSP == 4)
574             pointSP = 0;
575     }
576 
577     void OnCancelDraw()
578     {
579         OnButtonUp(FALSE, 0, 0);
580         imageModel.Undo(TRUE);
581         ToolBase::OnCancelDraw();
582     }
583 
584     void OnFinishDraw()
585     {
586         if (pointSP)
587         {
588             imageModel.ResetToPrevious();
589             --pointSP;
590             draw(m_bLeftButton);
591         }
592         ToolBase::OnFinishDraw();
593     }
594 };
595 
596 // TOOL_RECT
597 struct RectTool : GenericDrawTool
598 {
599     RectTool() : GenericDrawTool(TOOL_RECT)
600     {
601     }
602 
603     virtual void draw(BOOL bLeftButton, LONG x, LONG y)
604     {
605         imageModel.ResetToPrevious();
606         if (GetAsyncKeyState(VK_SHIFT) < 0)
607             regularize(start.x, start.y, x, y);
608         if (bLeftButton)
609             Rect(m_hdc, start.x, start.y, x, y, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
610         else
611             Rect(m_hdc, start.x, start.y, x, y, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
612     }
613 };
614 
615 // TOOL_SHAPE
616 struct ShapeTool : ToolBase
617 {
618     BOOL m_bLeftButton;
619 
620     ShapeTool() : ToolBase(TOOL_SHAPE), m_bLeftButton(FALSE)
621     {
622     }
623 
624     void draw(BOOL bLeftButton, LONG x, LONG y, BOOL bClosed = FALSE)
625     {
626         if (pointSP + 1 >= 2)
627         {
628             if (bLeftButton)
629                 Poly(m_hdc, pointStack, pointSP + 1, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), bClosed, FALSE);
630             else
631                 Poly(m_hdc, pointStack, pointSP + 1, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), bClosed, FALSE);
632         }
633         m_bLeftButton = bLeftButton;
634     }
635 
636     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
637     {
638         pointStack[pointSP].x = x;
639         pointStack[pointSP].y = y;
640 
641         if (pointSP == 0 && !bDoubleClick)
642         {
643             imageModel.CopyPrevious();
644             draw(bLeftButton, x, y);
645             pointSP++;
646         }
647         else
648         {
649             draw(bLeftButton, x, y, bDoubleClick);
650         }
651     }
652 
653     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
654     {
655         imageModel.ResetToPrevious();
656         pointStack[pointSP].x = x;
657         pointStack[pointSP].y = y;
658         if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
659             roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y, x, y);
660         draw(bLeftButton, x, y, FALSE);
661     }
662 
663     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
664     {
665         imageModel.ResetToPrevious();
666         if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
667             roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y, x, y);
668 
669         if (nearlyEqualPoints(x, y, pointStack[0].x, pointStack[0].y))
670         {
671             pointSP--;
672             draw(bLeftButton, x, y, TRUE);
673             pointSP = 0;
674         }
675         else
676         {
677             pointSP++;
678             pointStack[pointSP].x = x;
679             pointStack[pointSP].y = y;
680             draw(bLeftButton, x, y, FALSE);
681         }
682 
683         if (pointSP == _countof(pointStack))
684             pointSP--;
685     }
686 
687     void OnCancelDraw()
688     {
689         imageModel.Undo(TRUE);
690         ToolBase::OnCancelDraw();
691     }
692 
693     void OnFinishDraw()
694     {
695         if (pointSP)
696         {
697             imageModel.ResetToPrevious();
698             --pointSP;
699             draw(m_bLeftButton, -1, -1, TRUE);
700         }
701         ToolBase::OnFinishDraw();
702     }
703 };
704 
705 // TOOL_ELLIPSE
706 struct EllipseTool : GenericDrawTool
707 {
708     EllipseTool() : GenericDrawTool(TOOL_ELLIPSE)
709     {
710     }
711 
712     virtual void draw(BOOL bLeftButton, LONG x, LONG y)
713     {
714         imageModel.ResetToPrevious();
715         if (GetAsyncKeyState(VK_SHIFT) < 0)
716             regularize(start.x, start.y, x, y);
717         if (bLeftButton)
718             Ellp(m_hdc, start.x, start.y, x, y, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
719         else
720             Ellp(m_hdc, start.x, start.y, x, y, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
721     }
722 };
723 
724 // TOOL_RRECT
725 struct RRectTool : GenericDrawTool
726 {
727     RRectTool() : GenericDrawTool(TOOL_RRECT)
728     {
729     }
730 
731     virtual void draw(BOOL bLeftButton, LONG x, LONG y)
732     {
733         imageModel.ResetToPrevious();
734         if (GetAsyncKeyState(VK_SHIFT) < 0)
735             regularize(start.x, start.y, x, y);
736         if (bLeftButton)
737             RRect(m_hdc, start.x, start.y, x, y, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
738         else
739             RRect(m_hdc, start.x, start.y, x, y, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
740     }
741 };
742 
743 /*static*/ ToolBase*
744 ToolBase::createToolObject(TOOLTYPE type)
745 {
746     switch (type)
747     {
748         case TOOL_FREESEL:  return new FreeSelTool();
749         case TOOL_RECTSEL:  return new RectSelTool();
750         case TOOL_RUBBER:   return new RubberTool();
751         case TOOL_FILL:     return new FillTool();
752         case TOOL_COLOR:    return new ColorTool();
753         case TOOL_ZOOM:     return new ZoomTool();
754         case TOOL_PEN:      return new PenTool();
755         case TOOL_BRUSH:    return new BrushTool();
756         case TOOL_AIRBRUSH: return new AirBrushTool();
757         case TOOL_TEXT:     return new TextTool();
758         case TOOL_LINE:     return new LineTool();
759         case TOOL_BEZIER:   return new BezierTool();
760         case TOOL_RECT:     return new RectTool();
761         case TOOL_SHAPE:    return new ShapeTool();
762         case TOOL_ELLIPSE:  return new EllipseTool();
763         case TOOL_RRECT:    return new RRectTool();
764     }
765     UNREACHABLE;
766     return NULL;
767 }
768