xref: /reactos/base/applications/mspaint/mouse.cpp (revision 3fa6d74a)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:     PAINT for ReactOS
3c2c66affSColin Finck  * LICENSE:     LGPL
4c2c66affSColin Finck  * FILE:        base/applications/mspaint/mouse.cpp
5c2c66affSColin Finck  * PURPOSE:     Things which should not be in the mouse event handler itself
6c2c66affSColin Finck  * PROGRAMMERS: Benedikt Freisen
7ce54a8a5SKatayama Hirofumi MZ  *              Katayama Hirofumi MZ
8c2c66affSColin Finck  */
9c2c66affSColin Finck 
10c2c66affSColin Finck /* INCLUDES *********************************************************/
11c2c66affSColin Finck 
12c2c66affSColin Finck #include "precomp.h"
13c2c66affSColin Finck 
14ee132a05SKatayama Hirofumi MZ INT ToolBase::pointSP = 0;
15ee132a05SKatayama Hirofumi MZ POINT ToolBase::pointStack[256] = { { 0 } };
16ee132a05SKatayama Hirofumi MZ 
17c2c66affSColin Finck /* FUNCTIONS ********************************************************/
18c2c66affSColin Finck 
19c2c66affSColin Finck void
20c2c66affSColin Finck regularize(LONG x0, LONG y0, LONG& x1, LONG& y1)
21c2c66affSColin Finck {
22c2c66affSColin Finck     if (abs(x1 - x0) >= abs(y1 - y0))
23c2c66affSColin Finck         y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0));
24c2c66affSColin Finck     else
25c2c66affSColin Finck         x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0));
26c2c66affSColin Finck }
27c2c66affSColin Finck 
28c2c66affSColin Finck void
29c2c66affSColin Finck roundTo8Directions(LONG x0, LONG y0, LONG& x1, LONG& y1)
30c2c66affSColin Finck {
31c2c66affSColin Finck     if (abs(x1 - x0) >= abs(y1 - y0))
32c2c66affSColin Finck     {
33c2c66affSColin Finck         if (abs(y1 - y0) * 5 < abs(x1 - x0) * 2)
34c2c66affSColin Finck             y1 = y0;
35c2c66affSColin Finck         else
36c2c66affSColin Finck             y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0));
37c2c66affSColin Finck     }
38c2c66affSColin Finck     else
39c2c66affSColin Finck     {
40c2c66affSColin Finck         if (abs(x1 - x0) * 5 < abs(y1 - y0) * 2)
41c2c66affSColin Finck             x1 = x0;
42c2c66affSColin Finck         else
43c2c66affSColin Finck             x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0));
44c2c66affSColin Finck     }
45c2c66affSColin Finck }
46c2c66affSColin Finck 
47ce54a8a5SKatayama Hirofumi MZ BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1)
48ce54a8a5SKatayama Hirofumi MZ {
49ce54a8a5SKatayama Hirofumi MZ     INT cxThreshold = toolsModel.GetLineWidth() + UnZoomed(GetSystemMetrics(SM_CXDRAG));
50ce54a8a5SKatayama Hirofumi MZ     INT cyThreshold = toolsModel.GetLineWidth() + UnZoomed(GetSystemMetrics(SM_CYDRAG));
51ce54a8a5SKatayama Hirofumi MZ     return (abs(x1 - x0) <= cxThreshold) && (abs(y1 - y0) <= cyThreshold);
52ce54a8a5SKatayama Hirofumi MZ }
53ce54a8a5SKatayama Hirofumi MZ 
54ee132a05SKatayama Hirofumi MZ void updateStartAndLast(LONG x, LONG y)
55c2c66affSColin Finck {
56e8c7e300SKatayama Hirofumi MZ     g_ptStart.x = g_ptEnd.x = x;
57e8c7e300SKatayama Hirofumi MZ     g_ptStart.y = g_ptEnd.y = y;
58ee132a05SKatayama Hirofumi MZ }
59ee132a05SKatayama Hirofumi MZ 
60ee132a05SKatayama Hirofumi MZ void updateLast(LONG x, LONG y)
61ee132a05SKatayama Hirofumi MZ {
62e8c7e300SKatayama Hirofumi MZ     g_ptEnd.x = x;
63e8c7e300SKatayama Hirofumi MZ     g_ptEnd.y = y;
64ee132a05SKatayama Hirofumi MZ }
65ee132a05SKatayama Hirofumi MZ 
66ee132a05SKatayama Hirofumi MZ void ToolBase::reset()
67c2c66affSColin Finck {
68ee132a05SKatayama Hirofumi MZ     pointSP = 0;
69e8c7e300SKatayama Hirofumi MZ     g_ptStart.x = g_ptStart.y = g_ptEnd.x = g_ptEnd.y = -1;
7008397115SKatayama Hirofumi MZ     selectionModel.ResetPtStack();
71aac89519SKatayama Hirofumi MZ     if (selectionModel.m_bShow)
72aac89519SKatayama Hirofumi MZ     {
73aac89519SKatayama Hirofumi MZ         selectionModel.Landing();
74e8c7e300SKatayama Hirofumi MZ         selectionModel.HideSelection();
75aac89519SKatayama Hirofumi MZ     }
76ee132a05SKatayama Hirofumi MZ }
77ee132a05SKatayama Hirofumi MZ 
78ee132a05SKatayama Hirofumi MZ void ToolBase::OnCancelDraw()
79ee132a05SKatayama Hirofumi MZ {
80ee132a05SKatayama Hirofumi MZ     reset();
81bfd42c67SKatayama Hirofumi MZ     imageModel.NotifyImageChanged();
82ee132a05SKatayama Hirofumi MZ }
83ee132a05SKatayama Hirofumi MZ 
8408397115SKatayama Hirofumi MZ void ToolBase::OnFinishDraw()
8508397115SKatayama Hirofumi MZ {
8608397115SKatayama Hirofumi MZ     reset();
87bfd42c67SKatayama Hirofumi MZ     imageModel.NotifyImageChanged();
8808397115SKatayama Hirofumi MZ }
8908397115SKatayama Hirofumi MZ 
90ee132a05SKatayama Hirofumi MZ void ToolBase::beginEvent()
91ee132a05SKatayama Hirofumi MZ {
92ee132a05SKatayama Hirofumi MZ     m_hdc = imageModel.GetDC();
93ee132a05SKatayama Hirofumi MZ     m_fg = paletteModel.GetFgColor();
94ee132a05SKatayama Hirofumi MZ     m_bg = paletteModel.GetBgColor();
95ee132a05SKatayama Hirofumi MZ }
96ee132a05SKatayama Hirofumi MZ 
97ee132a05SKatayama Hirofumi MZ void ToolBase::endEvent()
98ee132a05SKatayama Hirofumi MZ {
99ee132a05SKatayama Hirofumi MZ     m_hdc = NULL;
100ee132a05SKatayama Hirofumi MZ }
101ee132a05SKatayama Hirofumi MZ 
102e8c7e300SKatayama Hirofumi MZ void ToolBase::OnDrawSelectionOnCanvas(HDC hdc)
103e8c7e300SKatayama Hirofumi MZ {
104e8c7e300SKatayama Hirofumi MZ     if (!selectionModel.m_bShow)
105e8c7e300SKatayama Hirofumi MZ         return;
106e8c7e300SKatayama Hirofumi MZ 
107e8c7e300SKatayama Hirofumi MZ     RECT rcSelection = selectionModel.m_rc;
108e8c7e300SKatayama Hirofumi MZ     canvasWindow.ImageToCanvas(rcSelection);
109e8c7e300SKatayama Hirofumi MZ 
110e8c7e300SKatayama Hirofumi MZ     ::InflateRect(&rcSelection, GRIP_SIZE, GRIP_SIZE);
111e8c7e300SKatayama Hirofumi MZ     drawSizeBoxes(hdc, &rcSelection, TRUE);
112e8c7e300SKatayama Hirofumi MZ }
113e8c7e300SKatayama Hirofumi MZ 
114ee132a05SKatayama Hirofumi MZ /* TOOLS ********************************************************/
115ee132a05SKatayama Hirofumi MZ 
116ee132a05SKatayama Hirofumi MZ // TOOL_FREESEL
117ee132a05SKatayama Hirofumi MZ struct FreeSelTool : ToolBase
118ee132a05SKatayama Hirofumi MZ {
119e8c7e300SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
12008397115SKatayama Hirofumi MZ 
121e8c7e300SKatayama Hirofumi MZ     FreeSelTool() : ToolBase(TOOL_FREESEL)
122ee132a05SKatayama Hirofumi MZ     {
123ee132a05SKatayama Hirofumi MZ     }
124ee132a05SKatayama Hirofumi MZ 
125e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
126e8c7e300SKatayama Hirofumi MZ     {
127e8c7e300SKatayama Hirofumi MZ         if (!selectionModel.IsLanded())
128e8c7e300SKatayama Hirofumi MZ         {
129e8c7e300SKatayama Hirofumi MZ             selectionModel.DrawBackgroundPoly(hdc, selectionModel.m_rgbBack);
130e8c7e300SKatayama Hirofumi MZ             selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
131e8c7e300SKatayama Hirofumi MZ         }
132e8c7e300SKatayama Hirofumi MZ 
133e8c7e300SKatayama Hirofumi MZ         if (canvasWindow.m_drawing)
134e8c7e300SKatayama Hirofumi MZ         {
135e8c7e300SKatayama Hirofumi MZ             selectionModel.DrawFramePoly(hdc);
136e8c7e300SKatayama Hirofumi MZ         }
137e8c7e300SKatayama Hirofumi MZ     }
138e8c7e300SKatayama Hirofumi MZ 
139e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnCanvas(HDC hdc) override
140e8c7e300SKatayama Hirofumi MZ     {
141e8c7e300SKatayama Hirofumi MZ         OnDrawSelectionOnCanvas(hdc);
142e8c7e300SKatayama Hirofumi MZ     }
143e8c7e300SKatayama Hirofumi MZ 
1446d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
145ee132a05SKatayama Hirofumi MZ     {
146aac89519SKatayama Hirofumi MZ         selectionModel.Landing();
14708397115SKatayama Hirofumi MZ         if (bLeftButton)
14808397115SKatayama Hirofumi MZ         {
149e8c7e300SKatayama Hirofumi MZ             selectionModel.HideSelection();
150c2c66affSColin Finck             selectionModel.ResetPtStack();
151aac89519SKatayama Hirofumi MZ             POINT pt = { x, y };
152aac89519SKatayama Hirofumi MZ             selectionModel.PushToPtStack(pt);
153c2c66affSColin Finck         }
15408397115SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
15508397115SKatayama Hirofumi MZ     }
156c2c66affSColin Finck 
1576d9b7f77SKatayama Hirofumi MZ     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) override
158c2c66affSColin Finck     {
15908397115SKatayama Hirofumi MZ         if (bLeftButton)
16008397115SKatayama Hirofumi MZ         {
16108397115SKatayama Hirofumi MZ             POINT pt = { x, y };
16208397115SKatayama Hirofumi MZ             imageModel.Bound(pt);
163aac89519SKatayama Hirofumi MZ             selectionModel.PushToPtStack(pt);
164e8c7e300SKatayama Hirofumi MZ             imageModel.NotifyImageChanged();
165ee132a05SKatayama Hirofumi MZ         }
16608397115SKatayama Hirofumi MZ     }
167ee132a05SKatayama Hirofumi MZ 
1686d9b7f77SKatayama Hirofumi MZ     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) override
169ee132a05SKatayama Hirofumi MZ     {
17008397115SKatayama Hirofumi MZ         if (bLeftButton)
171ee132a05SKatayama Hirofumi MZ         {
17208397115SKatayama Hirofumi MZ             if (selectionModel.PtStackSize() > 2)
17308397115SKatayama Hirofumi MZ             {
174aac89519SKatayama Hirofumi MZ                 selectionModel.BuildMaskFromPtStack();
175aac89519SKatayama Hirofumi MZ                 selectionModel.m_bShow = TRUE;
176ee132a05SKatayama Hirofumi MZ             }
17708397115SKatayama Hirofumi MZ             else
17808397115SKatayama Hirofumi MZ             {
179ee132a05SKatayama Hirofumi MZ                 selectionModel.ResetPtStack();
180aac89519SKatayama Hirofumi MZ                 selectionModel.m_bShow = FALSE;
18108397115SKatayama Hirofumi MZ             }
182bfd42c67SKatayama Hirofumi MZ             imageModel.NotifyImageChanged();
18308397115SKatayama Hirofumi MZ         }
1847aadc1e1SKatayama Hirofumi MZ         else
1857aadc1e1SKatayama Hirofumi MZ         {
1867aadc1e1SKatayama Hirofumi MZ             POINT pt = { x, y };
1877aadc1e1SKatayama Hirofumi MZ             canvasWindow.ClientToScreen(&pt);
1887aadc1e1SKatayama Hirofumi MZ             mainWindow.TrackPopupMenu(pt, 0);
1897aadc1e1SKatayama Hirofumi MZ         }
19008397115SKatayama Hirofumi MZ     }
19108397115SKatayama Hirofumi MZ 
1926d9b7f77SKatayama Hirofumi MZ     void OnFinishDraw() override
19308397115SKatayama Hirofumi MZ     {
194e8c7e300SKatayama Hirofumi MZ         selectionModel.Landing();
19508397115SKatayama Hirofumi MZ         ToolBase::OnFinishDraw();
196ee132a05SKatayama Hirofumi MZ     }
197ee132a05SKatayama Hirofumi MZ 
1986d9b7f77SKatayama Hirofumi MZ     void OnCancelDraw() override
199ee132a05SKatayama Hirofumi MZ     {
200e8c7e300SKatayama Hirofumi MZ         selectionModel.HideSelection();
201ee132a05SKatayama Hirofumi MZ         ToolBase::OnCancelDraw();
202ee132a05SKatayama Hirofumi MZ     }
203ee132a05SKatayama Hirofumi MZ };
204ee132a05SKatayama Hirofumi MZ 
205ee132a05SKatayama Hirofumi MZ // TOOL_RECTSEL
206ee132a05SKatayama Hirofumi MZ struct RectSelTool : ToolBase
207ee132a05SKatayama Hirofumi MZ {
208e8c7e300SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
20908397115SKatayama Hirofumi MZ 
210e8c7e300SKatayama Hirofumi MZ     RectSelTool() : ToolBase(TOOL_RECTSEL)
211ee132a05SKatayama Hirofumi MZ     {
212ee132a05SKatayama Hirofumi MZ     }
213ee132a05SKatayama Hirofumi MZ 
214e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
215e8c7e300SKatayama Hirofumi MZ     {
216e8c7e300SKatayama Hirofumi MZ         if (!selectionModel.IsLanded())
217e8c7e300SKatayama Hirofumi MZ         {
218e8c7e300SKatayama Hirofumi MZ             selectionModel.DrawBackgroundRect(hdc, selectionModel.m_rgbBack);
219e8c7e300SKatayama Hirofumi MZ             selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
220e8c7e300SKatayama Hirofumi MZ         }
221e8c7e300SKatayama Hirofumi MZ 
222e8c7e300SKatayama Hirofumi MZ         if (canvasWindow.m_drawing)
223e8c7e300SKatayama Hirofumi MZ         {
224e8c7e300SKatayama Hirofumi MZ             RECT rc = selectionModel.m_rc;
225e8c7e300SKatayama Hirofumi MZ             if (!::IsRectEmpty(&rc))
226e8c7e300SKatayama Hirofumi MZ                 RectSel(hdc, rc.left, rc.top, rc.right, rc.bottom);
227e8c7e300SKatayama Hirofumi MZ         }
228e8c7e300SKatayama Hirofumi MZ     }
229e8c7e300SKatayama Hirofumi MZ 
230e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnCanvas(HDC hdc) override
231e8c7e300SKatayama Hirofumi MZ     {
232e8c7e300SKatayama Hirofumi MZ         OnDrawSelectionOnCanvas(hdc);
233e8c7e300SKatayama Hirofumi MZ     }
234e8c7e300SKatayama Hirofumi MZ 
2356d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
236ee132a05SKatayama Hirofumi MZ     {
237aac89519SKatayama Hirofumi MZ         selectionModel.Landing();
238ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
239ee132a05SKatayama Hirofumi MZ         {
240e8c7e300SKatayama Hirofumi MZ             selectionModel.HideSelection();
241ee132a05SKatayama Hirofumi MZ         }
24208397115SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
243ee132a05SKatayama Hirofumi MZ     }
244ee132a05SKatayama Hirofumi MZ 
2456d9b7f77SKatayama Hirofumi MZ     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) override
246ee132a05SKatayama Hirofumi MZ     {
247ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
248ee132a05SKatayama Hirofumi MZ         {
24908397115SKatayama Hirofumi MZ             POINT pt = { x, y };
25008397115SKatayama Hirofumi MZ             imageModel.Bound(pt);
251e8c7e300SKatayama Hirofumi MZ             selectionModel.SetRectFromPoints(g_ptStart, pt);
252e8c7e300SKatayama Hirofumi MZ             imageModel.NotifyImageChanged();
253ee132a05SKatayama Hirofumi MZ         }
254ee132a05SKatayama Hirofumi MZ     }
255ee132a05SKatayama Hirofumi MZ 
2566d9b7f77SKatayama Hirofumi MZ     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) override
257ee132a05SKatayama Hirofumi MZ     {
2587aadc1e1SKatayama Hirofumi MZ         POINT pt = { x, y };
259ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
260ee132a05SKatayama Hirofumi MZ         {
261e8c7e300SKatayama Hirofumi MZ             imageModel.Bound(pt);
262e8c7e300SKatayama Hirofumi MZ             selectionModel.SetRectFromPoints(g_ptStart, pt);
263aac89519SKatayama Hirofumi MZ             selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty();
264bfd42c67SKatayama Hirofumi MZ             imageModel.NotifyImageChanged();
265ee132a05SKatayama Hirofumi MZ         }
2667aadc1e1SKatayama Hirofumi MZ         else
2677aadc1e1SKatayama Hirofumi MZ         {
2687aadc1e1SKatayama Hirofumi MZ             canvasWindow.ClientToScreen(&pt);
2697aadc1e1SKatayama Hirofumi MZ             mainWindow.TrackPopupMenu(pt, 0);
2707aadc1e1SKatayama Hirofumi MZ         }
271ee132a05SKatayama Hirofumi MZ     }
27208397115SKatayama Hirofumi MZ 
2736d9b7f77SKatayama Hirofumi MZ     void OnFinishDraw() override
27408397115SKatayama Hirofumi MZ     {
275e8c7e300SKatayama Hirofumi MZ         selectionModel.Landing();
27608397115SKatayama Hirofumi MZ         ToolBase::OnFinishDraw();
277ee132a05SKatayama Hirofumi MZ     }
278ee132a05SKatayama Hirofumi MZ 
2796d9b7f77SKatayama Hirofumi MZ     void OnCancelDraw() override
280ee132a05SKatayama Hirofumi MZ     {
281e8c7e300SKatayama Hirofumi MZ         selectionModel.HideSelection();
282ee132a05SKatayama Hirofumi MZ         ToolBase::OnCancelDraw();
283ee132a05SKatayama Hirofumi MZ     }
284ee132a05SKatayama Hirofumi MZ };
285ee132a05SKatayama Hirofumi MZ 
286e8c7e300SKatayama Hirofumi MZ struct TwoPointDrawTool : ToolBase
287ee132a05SKatayama Hirofumi MZ {
288e8c7e300SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
289e8c7e300SKatayama Hirofumi MZ     BOOL m_bDrawing = FALSE;
290e8c7e300SKatayama Hirofumi MZ 
291e8c7e300SKatayama Hirofumi MZ     TwoPointDrawTool(TOOLTYPE type) : ToolBase(type)
292e8c7e300SKatayama Hirofumi MZ     {
293e8c7e300SKatayama Hirofumi MZ     }
294e8c7e300SKatayama Hirofumi MZ 
295e8c7e300SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
296e8c7e300SKatayama Hirofumi MZ     {
297e8c7e300SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
298e8c7e300SKatayama Hirofumi MZ         m_bDrawing = TRUE;
299e8c7e300SKatayama Hirofumi MZ         g_ptStart.x = g_ptEnd.x = x;
300e8c7e300SKatayama Hirofumi MZ         g_ptStart.y = g_ptEnd.y = y;
301e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
302e8c7e300SKatayama Hirofumi MZ     }
303e8c7e300SKatayama Hirofumi MZ 
304e8c7e300SKatayama Hirofumi MZ     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) override
305e8c7e300SKatayama Hirofumi MZ     {
306e8c7e300SKatayama Hirofumi MZ         g_ptEnd.x = x;
307e8c7e300SKatayama Hirofumi MZ         g_ptEnd.y = y;
308e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
309e8c7e300SKatayama Hirofumi MZ     }
310e8c7e300SKatayama Hirofumi MZ 
311e8c7e300SKatayama Hirofumi MZ     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) override
312e8c7e300SKatayama Hirofumi MZ     {
313e8c7e300SKatayama Hirofumi MZ         g_ptEnd.x = x;
314e8c7e300SKatayama Hirofumi MZ         g_ptEnd.y = y;
315e8c7e300SKatayama Hirofumi MZ         imageModel.PushImageForUndo();
316e8c7e300SKatayama Hirofumi MZ         OnDrawOverlayOnImage(m_hdc);
317e8c7e300SKatayama Hirofumi MZ         m_bDrawing = FALSE;
318e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
319e8c7e300SKatayama Hirofumi MZ     }
320e8c7e300SKatayama Hirofumi MZ 
321e8c7e300SKatayama Hirofumi MZ     void OnFinishDraw() override
322e8c7e300SKatayama Hirofumi MZ     {
323e8c7e300SKatayama Hirofumi MZ         m_bDrawing = FALSE;
324e8c7e300SKatayama Hirofumi MZ         ToolBase::OnFinishDraw();
325e8c7e300SKatayama Hirofumi MZ     }
326e8c7e300SKatayama Hirofumi MZ 
327e8c7e300SKatayama Hirofumi MZ     void OnCancelDraw() override
328e8c7e300SKatayama Hirofumi MZ     {
329e8c7e300SKatayama Hirofumi MZ         m_bDrawing = FALSE;
330e8c7e300SKatayama Hirofumi MZ         ToolBase::OnCancelDraw();
331e8c7e300SKatayama Hirofumi MZ     }
332e8c7e300SKatayama Hirofumi MZ };
333e8c7e300SKatayama Hirofumi MZ 
334e8c7e300SKatayama Hirofumi MZ struct SmoothDrawTool : ToolBase
335e8c7e300SKatayama Hirofumi MZ {
336e8c7e300SKatayama Hirofumi MZ     SmoothDrawTool(TOOLTYPE type) : ToolBase(type)
337ee132a05SKatayama Hirofumi MZ     {
338ee132a05SKatayama Hirofumi MZ     }
339ee132a05SKatayama Hirofumi MZ 
340ee132a05SKatayama Hirofumi MZ     virtual void draw(BOOL bLeftButton, LONG x, LONG y) = 0;
341ee132a05SKatayama Hirofumi MZ 
3426d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
343ee132a05SKatayama Hirofumi MZ     {
3442b623c1dSKatayama Hirofumi MZ         imageModel.PushImageForUndo();
345e8c7e300SKatayama Hirofumi MZ         g_ptStart.x = g_ptEnd.x = x;
346e8c7e300SKatayama Hirofumi MZ         g_ptStart.y = g_ptEnd.y = y;
347e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
348ee132a05SKatayama Hirofumi MZ     }
349ee132a05SKatayama Hirofumi MZ 
3506d9b7f77SKatayama Hirofumi MZ     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) override
351ee132a05SKatayama Hirofumi MZ     {
352ee132a05SKatayama Hirofumi MZ         draw(bLeftButton, x, y);
353bfd42c67SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
354ee132a05SKatayama Hirofumi MZ     }
355ee132a05SKatayama Hirofumi MZ 
3566d9b7f77SKatayama Hirofumi MZ     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) override
357ee132a05SKatayama Hirofumi MZ     {
358ee132a05SKatayama Hirofumi MZ         draw(bLeftButton, x, y);
359e8c7e300SKatayama Hirofumi MZ         OnFinishDraw();
360e8c7e300SKatayama Hirofumi MZ     }
361e8c7e300SKatayama Hirofumi MZ 
362e8c7e300SKatayama Hirofumi MZ     void OnFinishDraw() override
363e8c7e300SKatayama Hirofumi MZ     {
364e8c7e300SKatayama Hirofumi MZ         ToolBase::OnFinishDraw();
365ee132a05SKatayama Hirofumi MZ     }
366ee132a05SKatayama Hirofumi MZ 
3676d9b7f77SKatayama Hirofumi MZ     void OnCancelDraw() override
368ee132a05SKatayama Hirofumi MZ     {
369ee132a05SKatayama Hirofumi MZ         OnButtonUp(FALSE, 0, 0);
37008397115SKatayama Hirofumi MZ         imageModel.Undo(TRUE);
371ee132a05SKatayama Hirofumi MZ         ToolBase::OnCancelDraw();
372ee132a05SKatayama Hirofumi MZ     }
373ee132a05SKatayama Hirofumi MZ };
374ee132a05SKatayama Hirofumi MZ 
375ee132a05SKatayama Hirofumi MZ // TOOL_RUBBER
376e8c7e300SKatayama Hirofumi MZ struct RubberTool : SmoothDrawTool
377ee132a05SKatayama Hirofumi MZ {
378e8c7e300SKatayama Hirofumi MZ     RubberTool() : SmoothDrawTool(TOOL_RUBBER)
379ee132a05SKatayama Hirofumi MZ     {
380ee132a05SKatayama Hirofumi MZ     }
381ee132a05SKatayama Hirofumi MZ 
3826d9b7f77SKatayama Hirofumi MZ     void draw(BOOL bLeftButton, LONG x, LONG y) override
383ee132a05SKatayama Hirofumi MZ     {
384ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
385e8c7e300SKatayama Hirofumi MZ             Erase(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, m_bg, toolsModel.GetRubberRadius());
386ee132a05SKatayama Hirofumi MZ         else
387e8c7e300SKatayama Hirofumi MZ             Replace(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, m_fg, m_bg, toolsModel.GetRubberRadius());
388e8c7e300SKatayama Hirofumi MZ         g_ptEnd.x = x;
389e8c7e300SKatayama Hirofumi MZ         g_ptEnd.y = y;
390ee132a05SKatayama Hirofumi MZ     }
391ee132a05SKatayama Hirofumi MZ };
392ee132a05SKatayama Hirofumi MZ 
393ee132a05SKatayama Hirofumi MZ // TOOL_FILL
394ee132a05SKatayama Hirofumi MZ struct FillTool : ToolBase
395ee132a05SKatayama Hirofumi MZ {
396ee132a05SKatayama Hirofumi MZ     FillTool() : ToolBase(TOOL_FILL)
397ee132a05SKatayama Hirofumi MZ     {
398ee132a05SKatayama Hirofumi MZ     }
399ee132a05SKatayama Hirofumi MZ 
4006d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
401ee132a05SKatayama Hirofumi MZ     {
4022b623c1dSKatayama Hirofumi MZ         imageModel.PushImageForUndo();
403ee132a05SKatayama Hirofumi MZ         Fill(m_hdc, x, y, bLeftButton ? m_fg : m_bg);
404ee132a05SKatayama Hirofumi MZ     }
405ee132a05SKatayama Hirofumi MZ };
406ee132a05SKatayama Hirofumi MZ 
407ee132a05SKatayama Hirofumi MZ // TOOL_COLOR
408ee132a05SKatayama Hirofumi MZ struct ColorTool : ToolBase
409ee132a05SKatayama Hirofumi MZ {
410ee132a05SKatayama Hirofumi MZ     ColorTool() : ToolBase(TOOL_COLOR)
411ee132a05SKatayama Hirofumi MZ     {
412ee132a05SKatayama Hirofumi MZ     }
413ee132a05SKatayama Hirofumi MZ 
41408397115SKatayama Hirofumi MZ     void fetchColor(BOOL bLeftButton, LONG x, LONG y)
415ee132a05SKatayama Hirofumi MZ     {
41608397115SKatayama Hirofumi MZ         COLORREF rgbColor;
417ee132a05SKatayama Hirofumi MZ 
418ee132a05SKatayama Hirofumi MZ         if (0 <= x && x < imageModel.GetWidth() && 0 <= y && y < imageModel.GetHeight())
41908397115SKatayama Hirofumi MZ             rgbColor = GetPixel(m_hdc, x, y);
420ee132a05SKatayama Hirofumi MZ         else
42108397115SKatayama Hirofumi MZ             rgbColor = RGB(255, 255, 255); // Outside is white
422ee132a05SKatayama Hirofumi MZ 
423ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
42408397115SKatayama Hirofumi MZ             paletteModel.SetFgColor(rgbColor);
425ee132a05SKatayama Hirofumi MZ         else
42608397115SKatayama Hirofumi MZ             paletteModel.SetBgColor(rgbColor);
42708397115SKatayama Hirofumi MZ     }
428ee132a05SKatayama Hirofumi MZ 
4296d9b7f77SKatayama Hirofumi MZ     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) override
43008397115SKatayama Hirofumi MZ     {
43108397115SKatayama Hirofumi MZ         fetchColor(bLeftButton, x, y);
43208397115SKatayama Hirofumi MZ     }
43308397115SKatayama Hirofumi MZ 
4346d9b7f77SKatayama Hirofumi MZ     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) override
43508397115SKatayama Hirofumi MZ     {
43608397115SKatayama Hirofumi MZ         fetchColor(bLeftButton, x, y);
437ee132a05SKatayama Hirofumi MZ         toolsModel.SetActiveTool(toolsModel.GetOldActiveTool());
438ee132a05SKatayama Hirofumi MZ     }
439ee132a05SKatayama Hirofumi MZ };
440ee132a05SKatayama Hirofumi MZ 
441ee132a05SKatayama Hirofumi MZ // TOOL_ZOOM
442ee132a05SKatayama Hirofumi MZ struct ZoomTool : ToolBase
443ee132a05SKatayama Hirofumi MZ {
444ee132a05SKatayama Hirofumi MZ     ZoomTool() : ToolBase(TOOL_ZOOM)
445ee132a05SKatayama Hirofumi MZ     {
446ee132a05SKatayama Hirofumi MZ     }
447ee132a05SKatayama Hirofumi MZ 
4486d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
449ee132a05SKatayama Hirofumi MZ     {
4502b623c1dSKatayama Hirofumi MZ         imageModel.PushImageForUndo();
451ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
452ee132a05SKatayama Hirofumi MZ         {
453ee132a05SKatayama Hirofumi MZ             if (toolsModel.GetZoom() < MAX_ZOOM)
454ee132a05SKatayama Hirofumi MZ                 zoomTo(toolsModel.GetZoom() * 2, x, y);
455ee132a05SKatayama Hirofumi MZ         }
456ee132a05SKatayama Hirofumi MZ         else
457ee132a05SKatayama Hirofumi MZ         {
458ee132a05SKatayama Hirofumi MZ             if (toolsModel.GetZoom() > MIN_ZOOM)
459ee132a05SKatayama Hirofumi MZ                 zoomTo(toolsModel.GetZoom() / 2, x, y);
460ee132a05SKatayama Hirofumi MZ         }
461ee132a05SKatayama Hirofumi MZ     }
462ee132a05SKatayama Hirofumi MZ };
463ee132a05SKatayama Hirofumi MZ 
464ee132a05SKatayama Hirofumi MZ // TOOL_PEN
465e8c7e300SKatayama Hirofumi MZ struct PenTool : SmoothDrawTool
466ee132a05SKatayama Hirofumi MZ {
467e8c7e300SKatayama Hirofumi MZ     PenTool() : SmoothDrawTool(TOOL_PEN)
468ee132a05SKatayama Hirofumi MZ     {
469ee132a05SKatayama Hirofumi MZ     }
470ee132a05SKatayama Hirofumi MZ 
4716d9b7f77SKatayama Hirofumi MZ     void draw(BOOL bLeftButton, LONG x, LONG y) override
472ee132a05SKatayama Hirofumi MZ     {
473ee132a05SKatayama Hirofumi MZ         COLORREF rgb = bLeftButton ? m_fg : m_bg;
474e8c7e300SKatayama Hirofumi MZ         Line(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, rgb, 1);
475318b2e78SKatayama Hirofumi MZ         ::SetPixelV(m_hdc, x, y, rgb);
476e8c7e300SKatayama Hirofumi MZ         g_ptEnd.x = x;
477e8c7e300SKatayama Hirofumi MZ         g_ptEnd.y = y;
478ee132a05SKatayama Hirofumi MZ     }
479ee132a05SKatayama Hirofumi MZ };
480ee132a05SKatayama Hirofumi MZ 
481ee132a05SKatayama Hirofumi MZ // TOOL_BRUSH
482e8c7e300SKatayama Hirofumi MZ struct BrushTool : SmoothDrawTool
483ee132a05SKatayama Hirofumi MZ {
484e8c7e300SKatayama Hirofumi MZ     BrushTool() : SmoothDrawTool(TOOL_BRUSH)
485ee132a05SKatayama Hirofumi MZ     {
486ee132a05SKatayama Hirofumi MZ     }
487ee132a05SKatayama Hirofumi MZ 
4886d9b7f77SKatayama Hirofumi MZ     void draw(BOOL bLeftButton, LONG x, LONG y) override
489ee132a05SKatayama Hirofumi MZ     {
490ee132a05SKatayama Hirofumi MZ         COLORREF rgb = bLeftButton ? m_fg : m_bg;
491e8c7e300SKatayama Hirofumi MZ         Brush(m_hdc, g_ptEnd.x, g_ptEnd.y, x, y, rgb, toolsModel.GetBrushStyle());
492e8c7e300SKatayama Hirofumi MZ         g_ptEnd.x = x;
493e8c7e300SKatayama Hirofumi MZ         g_ptEnd.y = y;
494ee132a05SKatayama Hirofumi MZ     }
495ee132a05SKatayama Hirofumi MZ };
496ee132a05SKatayama Hirofumi MZ 
497ee132a05SKatayama Hirofumi MZ // TOOL_AIRBRUSH
498e8c7e300SKatayama Hirofumi MZ struct AirBrushTool : SmoothDrawTool
499ee132a05SKatayama Hirofumi MZ {
500e8c7e300SKatayama Hirofumi MZ     AirBrushTool() : SmoothDrawTool(TOOL_AIRBRUSH)
501ee132a05SKatayama Hirofumi MZ     {
502ee132a05SKatayama Hirofumi MZ     }
503ee132a05SKatayama Hirofumi MZ 
5046d9b7f77SKatayama Hirofumi MZ     void draw(BOOL bLeftButton, LONG x, LONG y) override
505ee132a05SKatayama Hirofumi MZ     {
506ee132a05SKatayama Hirofumi MZ         COLORREF rgb = bLeftButton ? m_fg : m_bg;
507ee132a05SKatayama Hirofumi MZ         Airbrush(m_hdc, x, y, rgb, toolsModel.GetAirBrushWidth());
508ee132a05SKatayama Hirofumi MZ     }
509ee132a05SKatayama Hirofumi MZ };
510ee132a05SKatayama Hirofumi MZ 
511ee132a05SKatayama Hirofumi MZ // TOOL_TEXT
512ee132a05SKatayama Hirofumi MZ struct TextTool : ToolBase
513ee132a05SKatayama Hirofumi MZ {
514ee132a05SKatayama Hirofumi MZ     TextTool() : ToolBase(TOOL_TEXT)
515ee132a05SKatayama Hirofumi MZ     {
516ee132a05SKatayama Hirofumi MZ     }
517ee132a05SKatayama Hirofumi MZ 
518e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
519e8c7e300SKatayama Hirofumi MZ     {
520e8c7e300SKatayama Hirofumi MZ         if (canvasWindow.m_drawing)
521e8c7e300SKatayama Hirofumi MZ         {
522e8c7e300SKatayama Hirofumi MZ             RECT rc = selectionModel.m_rc;
523e8c7e300SKatayama Hirofumi MZ             if (!::IsRectEmpty(&rc))
524e8c7e300SKatayama Hirofumi MZ                 RectSel(hdc, rc.left, rc.top, rc.right, rc.bottom);
525e8c7e300SKatayama Hirofumi MZ         }
526e8c7e300SKatayama Hirofumi MZ     }
527e8c7e300SKatayama Hirofumi MZ 
528361a2ce4SKatayama Hirofumi MZ     void UpdatePoint(LONG x, LONG y)
529c2c66affSColin Finck     {
53008397115SKatayama Hirofumi MZ         POINT pt = { x, y };
53108397115SKatayama Hirofumi MZ         imageModel.Bound(pt);
532e8c7e300SKatayama Hirofumi MZ         selectionModel.SetRectFromPoints(g_ptStart, pt);
533e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
534c2c66affSColin Finck     }
535c2c66affSColin Finck 
5366d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
537361a2ce4SKatayama Hirofumi MZ     {
538361a2ce4SKatayama Hirofumi MZ         if (!textEditWindow.IsWindow())
539efe7368cSKatayama Hirofumi MZ             textEditWindow.Create(canvasWindow);
540361a2ce4SKatayama Hirofumi MZ 
541361a2ce4SKatayama Hirofumi MZ         UpdatePoint(x, y);
542361a2ce4SKatayama Hirofumi MZ     }
543361a2ce4SKatayama Hirofumi MZ 
5446d9b7f77SKatayama Hirofumi MZ     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) override
545361a2ce4SKatayama Hirofumi MZ     {
546361a2ce4SKatayama Hirofumi MZ         UpdatePoint(x, y);
547361a2ce4SKatayama Hirofumi MZ     }
548361a2ce4SKatayama Hirofumi MZ 
549e8c7e300SKatayama Hirofumi MZ     void draw(HDC hdc)
550361a2ce4SKatayama Hirofumi MZ     {
551361a2ce4SKatayama Hirofumi MZ         CString szText;
552361a2ce4SKatayama Hirofumi MZ         textEditWindow.GetWindowText(szText);
553361a2ce4SKatayama Hirofumi MZ 
554361a2ce4SKatayama Hirofumi MZ         RECT rc;
555361a2ce4SKatayama Hirofumi MZ         textEditWindow.InvalidateEditRect();
556361a2ce4SKatayama Hirofumi MZ         textEditWindow.GetEditRect(&rc);
557bddd8b05SKatayama Hirofumi MZ         ::InflateRect(&rc, -GRIP_SIZE / 2, -GRIP_SIZE / 2);
558361a2ce4SKatayama Hirofumi MZ 
559bddd8b05SKatayama Hirofumi MZ         // Draw the text
560361a2ce4SKatayama Hirofumi MZ         INT style = (toolsModel.IsBackgroundTransparent() ? 0 : 1);
561e8c7e300SKatayama Hirofumi MZ         Text(hdc, rc.left, rc.top, rc.right, rc.bottom, m_fg, m_bg, szText,
562361a2ce4SKatayama Hirofumi MZ              textEditWindow.GetFont(), style);
563e8c7e300SKatayama Hirofumi MZ     }
564e8c7e300SKatayama Hirofumi MZ 
565e8c7e300SKatayama Hirofumi MZ     void quit()
566e8c7e300SKatayama Hirofumi MZ     {
567e8c7e300SKatayama Hirofumi MZ         if (textEditWindow.IsWindow())
568e8c7e300SKatayama Hirofumi MZ             textEditWindow.ShowWindow(SW_HIDE);
569e8c7e300SKatayama Hirofumi MZ         selectionModel.HideSelection();
570e8c7e300SKatayama Hirofumi MZ     }
571e8c7e300SKatayama Hirofumi MZ 
572e8c7e300SKatayama Hirofumi MZ     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) override
573e8c7e300SKatayama Hirofumi MZ     {
574e8c7e300SKatayama Hirofumi MZ         POINT pt = { x, y };
575e8c7e300SKatayama Hirofumi MZ         imageModel.Bound(pt);
576e8c7e300SKatayama Hirofumi MZ         selectionModel.SetRectFromPoints(g_ptStart, pt);
577e8c7e300SKatayama Hirofumi MZ 
578e8c7e300SKatayama Hirofumi MZ         BOOL bTextBoxShown = ::IsWindowVisible(textEditWindow);
5797aadc1e1SKatayama Hirofumi MZ         if (bTextBoxShown)
5807aadc1e1SKatayama Hirofumi MZ         {
5817aadc1e1SKatayama Hirofumi MZ             if (textEditWindow.GetWindowTextLength() > 0)
582e8c7e300SKatayama Hirofumi MZ             {
5839f56e67bSKatayama Hirofumi MZ                 imageModel.PushImageForUndo();
584e8c7e300SKatayama Hirofumi MZ                 draw(m_hdc);
5857aadc1e1SKatayama Hirofumi MZ             }
5869f56e67bSKatayama Hirofumi MZ             if (::IsRectEmpty(&selectionModel.m_rc))
587aac89519SKatayama Hirofumi MZ             {
5889f56e67bSKatayama Hirofumi MZ                 quit();
589aac89519SKatayama Hirofumi MZ                 return;
590aac89519SKatayama Hirofumi MZ             }
591361a2ce4SKatayama Hirofumi MZ         }
592361a2ce4SKatayama Hirofumi MZ 
593361a2ce4SKatayama Hirofumi MZ         if (registrySettings.ShowTextTool)
594361a2ce4SKatayama Hirofumi MZ         {
595361a2ce4SKatayama Hirofumi MZ             if (!fontsDialog.IsWindow())
596361a2ce4SKatayama Hirofumi MZ                 fontsDialog.Create(mainWindow);
597361a2ce4SKatayama Hirofumi MZ 
598361a2ce4SKatayama Hirofumi MZ             fontsDialog.ShowWindow(SW_SHOWNOACTIVATE);
599361a2ce4SKatayama Hirofumi MZ         }
600361a2ce4SKatayama Hirofumi MZ 
601aac89519SKatayama Hirofumi MZ         RECT rc = selectionModel.m_rc;
602361a2ce4SKatayama Hirofumi MZ 
603361a2ce4SKatayama Hirofumi MZ         // Enlarge if tool small
604361a2ce4SKatayama Hirofumi MZ         INT cxMin = CX_MINTEXTEDIT, cyMin = CY_MINTEXTEDIT;
605aac89519SKatayama Hirofumi MZ         if (selectionModel.m_rc.IsRectEmpty())
606aac89519SKatayama Hirofumi MZ         {
607aac89519SKatayama Hirofumi MZ             SetRect(&rc, x, y, x + cxMin, y + cyMin);
608aac89519SKatayama Hirofumi MZ         }
609aac89519SKatayama Hirofumi MZ         else
610c2c66affSColin Finck         {
611361a2ce4SKatayama Hirofumi MZ             if (rc.right - rc.left < cxMin)
612361a2ce4SKatayama Hirofumi MZ                 rc.right = rc.left + cxMin;
613361a2ce4SKatayama Hirofumi MZ             if (rc.bottom - rc.top < cyMin)
614361a2ce4SKatayama Hirofumi MZ                 rc.bottom = rc.top + cyMin;
615361a2ce4SKatayama Hirofumi MZ         }
616c2c66affSColin Finck 
617361a2ce4SKatayama Hirofumi MZ         if (!textEditWindow.IsWindow())
618efe7368cSKatayama Hirofumi MZ             textEditWindow.Create(canvasWindow);
619361a2ce4SKatayama Hirofumi MZ 
620361a2ce4SKatayama Hirofumi MZ         textEditWindow.SetWindowText(NULL);
621361a2ce4SKatayama Hirofumi MZ         textEditWindow.ValidateEditRect(&rc);
622361a2ce4SKatayama Hirofumi MZ         textEditWindow.ShowWindow(SW_SHOWNOACTIVATE);
623361a2ce4SKatayama Hirofumi MZ         textEditWindow.SetFocus();
624361a2ce4SKatayama Hirofumi MZ     }
625ee132a05SKatayama Hirofumi MZ 
6266d9b7f77SKatayama Hirofumi MZ     void OnFinishDraw() override
627ee132a05SKatayama Hirofumi MZ     {
6287aadc1e1SKatayama Hirofumi MZ         if (textEditWindow.GetWindowTextLength() > 0)
6297aadc1e1SKatayama Hirofumi MZ         {
6309f56e67bSKatayama Hirofumi MZ             imageModel.PushImageForUndo();
631e8c7e300SKatayama Hirofumi MZ             draw(m_hdc);
6327aadc1e1SKatayama Hirofumi MZ         }
633e8c7e300SKatayama Hirofumi MZ         quit();
63408397115SKatayama Hirofumi MZ         ToolBase::OnFinishDraw();
635c2c66affSColin Finck     }
636e8c7e300SKatayama Hirofumi MZ 
637e8c7e300SKatayama Hirofumi MZ     void OnCancelDraw() override
638e8c7e300SKatayama Hirofumi MZ     {
639e8c7e300SKatayama Hirofumi MZ         quit();
640e8c7e300SKatayama Hirofumi MZ         ToolBase::OnCancelDraw();
641e8c7e300SKatayama Hirofumi MZ     }
642ee132a05SKatayama Hirofumi MZ };
643ee132a05SKatayama Hirofumi MZ 
644ee132a05SKatayama Hirofumi MZ // TOOL_LINE
645e8c7e300SKatayama Hirofumi MZ struct LineTool : TwoPointDrawTool
646c2c66affSColin Finck {
647e8c7e300SKatayama Hirofumi MZ     LineTool() : TwoPointDrawTool(TOOL_LINE)
648c2c66affSColin Finck     {
649c2c66affSColin Finck     }
650ee132a05SKatayama Hirofumi MZ 
651e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
652ee132a05SKatayama Hirofumi MZ     {
653e8c7e300SKatayama Hirofumi MZ         if (!m_bDrawing)
654e8c7e300SKatayama Hirofumi MZ             return;
655c2c66affSColin Finck         if (GetAsyncKeyState(VK_SHIFT) < 0)
656e8c7e300SKatayama Hirofumi MZ             roundTo8Directions(g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y);
657e8c7e300SKatayama Hirofumi MZ         COLORREF rgb = m_bLeftButton ? m_fg : m_bg;
658e8c7e300SKatayama Hirofumi MZ         Line(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, rgb, toolsModel.GetLineWidth());
659ee132a05SKatayama Hirofumi MZ     }
660ee132a05SKatayama Hirofumi MZ };
661ee132a05SKatayama Hirofumi MZ 
662ee132a05SKatayama Hirofumi MZ // TOOL_BEZIER
663ee132a05SKatayama Hirofumi MZ struct BezierTool : ToolBase
664c2c66affSColin Finck {
665e8c7e300SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
666e8c7e300SKatayama Hirofumi MZ     BOOL m_bDrawing = FALSE;
66708397115SKatayama Hirofumi MZ 
668e8c7e300SKatayama Hirofumi MZ     BezierTool() : ToolBase(TOOL_BEZIER)
669c2c66affSColin Finck     {
670c2c66affSColin Finck     }
671c2c66affSColin Finck 
672e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc)
673c2c66affSColin Finck     {
674e8c7e300SKatayama Hirofumi MZ         if (!m_bDrawing)
675e8c7e300SKatayama Hirofumi MZ             return;
676e8c7e300SKatayama Hirofumi MZ 
677e8c7e300SKatayama Hirofumi MZ         COLORREF rgb = (m_bLeftButton ? m_fg : m_bg);
678c2c66affSColin Finck         switch (pointSP)
679c2c66affSColin Finck         {
680c2c66affSColin Finck             case 1:
681e8c7e300SKatayama Hirofumi MZ                 Line(hdc, pointStack[0].x, pointStack[0].y, pointStack[1].x, pointStack[1].y, rgb,
682c2c66affSColin Finck                      toolsModel.GetLineWidth());
683c2c66affSColin Finck                 break;
684c2c66affSColin Finck             case 2:
685e8c7e300SKatayama Hirofumi MZ                 Bezier(hdc, pointStack[0], pointStack[2], pointStack[2], pointStack[1], rgb, toolsModel.GetLineWidth());
686c2c66affSColin Finck                 break;
687c2c66affSColin Finck             case 3:
688e8c7e300SKatayama Hirofumi MZ                 Bezier(hdc, pointStack[0], pointStack[2], pointStack[3], pointStack[1], rgb, toolsModel.GetLineWidth());
689c2c66affSColin Finck                 break;
690c2c66affSColin Finck         }
691ee132a05SKatayama Hirofumi MZ     }
692ee132a05SKatayama Hirofumi MZ 
6936d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
694ee132a05SKatayama Hirofumi MZ     {
695e8c7e300SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
696e8c7e300SKatayama Hirofumi MZ 
697e8c7e300SKatayama Hirofumi MZ         if (!m_bDrawing)
698e8c7e300SKatayama Hirofumi MZ         {
699e8c7e300SKatayama Hirofumi MZ             m_bDrawing = TRUE;
700e8c7e300SKatayama Hirofumi MZ             pointStack[pointSP].x = pointStack[pointSP + 1].x = x;
701e8c7e300SKatayama Hirofumi MZ             pointStack[pointSP].y = pointStack[pointSP + 1].y = y;
702e8c7e300SKatayama Hirofumi MZ             ++pointSP;
703e8c7e300SKatayama Hirofumi MZ         }
704e8c7e300SKatayama Hirofumi MZ         else
705e8c7e300SKatayama Hirofumi MZ         {
706e8c7e300SKatayama Hirofumi MZ             ++pointSP;
707ee132a05SKatayama Hirofumi MZ             pointStack[pointSP].x = x;
708ee132a05SKatayama Hirofumi MZ             pointStack[pointSP].y = y;
709ee132a05SKatayama Hirofumi MZ         }
710e8c7e300SKatayama Hirofumi MZ 
711e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
712ee132a05SKatayama Hirofumi MZ     }
713ee132a05SKatayama Hirofumi MZ 
7146d9b7f77SKatayama Hirofumi MZ     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) override
715ee132a05SKatayama Hirofumi MZ     {
716c2c66affSColin Finck         pointStack[pointSP].x = x;
717c2c66affSColin Finck         pointStack[pointSP].y = y;
718e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
719c2c66affSColin Finck     }
720c2c66affSColin Finck 
7216d9b7f77SKatayama Hirofumi MZ     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) override
722c2c66affSColin Finck     {
723e8c7e300SKatayama Hirofumi MZ         pointStack[pointSP].x = x;
724e8c7e300SKatayama Hirofumi MZ         pointStack[pointSP].y = y;
725e8c7e300SKatayama Hirofumi MZ         if (pointSP >= 3)
726e8c7e300SKatayama Hirofumi MZ         {
727e8c7e300SKatayama Hirofumi MZ             OnFinishDraw();
728e8c7e300SKatayama Hirofumi MZ             return;
729e8c7e300SKatayama Hirofumi MZ         }
730bfd42c67SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
731ee132a05SKatayama Hirofumi MZ     }
732ee132a05SKatayama Hirofumi MZ 
7336d9b7f77SKatayama Hirofumi MZ     void OnCancelDraw() override
734ee132a05SKatayama Hirofumi MZ     {
735e8c7e300SKatayama Hirofumi MZ         m_bDrawing = FALSE;
736ee132a05SKatayama Hirofumi MZ         ToolBase::OnCancelDraw();
737ee132a05SKatayama Hirofumi MZ     }
73808397115SKatayama Hirofumi MZ 
7396d9b7f77SKatayama Hirofumi MZ     void OnFinishDraw() override
74008397115SKatayama Hirofumi MZ     {
741e8c7e300SKatayama Hirofumi MZ         imageModel.PushImageForUndo();
742e8c7e300SKatayama Hirofumi MZ         OnDrawOverlayOnImage(m_hdc);
743e8c7e300SKatayama Hirofumi MZ         m_bDrawing = FALSE;
74408397115SKatayama Hirofumi MZ         ToolBase::OnFinishDraw();
74508397115SKatayama Hirofumi MZ     }
746ee132a05SKatayama Hirofumi MZ };
747ee132a05SKatayama Hirofumi MZ 
748ee132a05SKatayama Hirofumi MZ // TOOL_RECT
749e8c7e300SKatayama Hirofumi MZ struct RectTool : TwoPointDrawTool
750ee132a05SKatayama Hirofumi MZ {
751e8c7e300SKatayama Hirofumi MZ     RectTool() : TwoPointDrawTool(TOOL_RECT)
752ee132a05SKatayama Hirofumi MZ     {
753ee132a05SKatayama Hirofumi MZ     }
754ee132a05SKatayama Hirofumi MZ 
755e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
756ee132a05SKatayama Hirofumi MZ     {
757e8c7e300SKatayama Hirofumi MZ         if (!m_bDrawing)
758e8c7e300SKatayama Hirofumi MZ             return;
759c2c66affSColin Finck         if (GetAsyncKeyState(VK_SHIFT) < 0)
760e8c7e300SKatayama Hirofumi MZ             regularize(g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y);
761e8c7e300SKatayama Hirofumi MZ         if (m_bLeftButton)
762e8c7e300SKatayama Hirofumi MZ             Rect(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
763ee132a05SKatayama Hirofumi MZ         else
764e8c7e300SKatayama Hirofumi MZ             Rect(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
765ee132a05SKatayama Hirofumi MZ     }
766ee132a05SKatayama Hirofumi MZ };
767ee132a05SKatayama Hirofumi MZ 
768ee132a05SKatayama Hirofumi MZ // TOOL_SHAPE
769ee132a05SKatayama Hirofumi MZ struct ShapeTool : ToolBase
770ee132a05SKatayama Hirofumi MZ {
771e8c7e300SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
772e8c7e300SKatayama Hirofumi MZ     BOOL m_bClosed = FALSE;
77308397115SKatayama Hirofumi MZ 
774e8c7e300SKatayama Hirofumi MZ     ShapeTool() : ToolBase(TOOL_SHAPE)
775ee132a05SKatayama Hirofumi MZ     {
776ee132a05SKatayama Hirofumi MZ     }
777ee132a05SKatayama Hirofumi MZ 
778e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc)
779ee132a05SKatayama Hirofumi MZ     {
780e8c7e300SKatayama Hirofumi MZ         if (pointSP <= 0)
781e8c7e300SKatayama Hirofumi MZ             return;
782e8c7e300SKatayama Hirofumi MZ 
783e8c7e300SKatayama Hirofumi MZ         if (m_bLeftButton)
784e8c7e300SKatayama Hirofumi MZ             Poly(hdc, pointStack, pointSP + 1, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE);
785ee132a05SKatayama Hirofumi MZ         else
786e8c7e300SKatayama Hirofumi MZ             Poly(hdc, pointStack, pointSP + 1, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE);
787ee132a05SKatayama Hirofumi MZ     }
788ee132a05SKatayama Hirofumi MZ 
7896d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
790ee132a05SKatayama Hirofumi MZ     {
791e8c7e300SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
792e8c7e300SKatayama Hirofumi MZ         m_bClosed = FALSE;
793e8c7e300SKatayama Hirofumi MZ 
794*3fa6d74aSKatayama Hirofumi MZ         if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
795*3fa6d74aSKatayama Hirofumi MZ             roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y, x, y);
796*3fa6d74aSKatayama Hirofumi MZ 
797ee132a05SKatayama Hirofumi MZ         pointStack[pointSP].x = x;
798ee132a05SKatayama Hirofumi MZ         pointStack[pointSP].y = y;
799ee132a05SKatayama Hirofumi MZ 
800e8c7e300SKatayama Hirofumi MZ         if (pointSP && bDoubleClick)
801ee132a05SKatayama Hirofumi MZ         {
802e8c7e300SKatayama Hirofumi MZ             OnFinishDraw();
803e8c7e300SKatayama Hirofumi MZ             return;
804e8c7e300SKatayama Hirofumi MZ         }
805e8c7e300SKatayama Hirofumi MZ 
806e8c7e300SKatayama Hirofumi MZ         if (pointSP == 0)
807e8c7e300SKatayama Hirofumi MZ         {
808ee132a05SKatayama Hirofumi MZ             pointSP++;
809e8c7e300SKatayama Hirofumi MZ             pointStack[pointSP].x = x;
810e8c7e300SKatayama Hirofumi MZ             pointStack[pointSP].y = y;
811ee132a05SKatayama Hirofumi MZ         }
812e8c7e300SKatayama Hirofumi MZ 
813bfd42c67SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
814ee132a05SKatayama Hirofumi MZ     }
815ee132a05SKatayama Hirofumi MZ 
8166d9b7f77SKatayama Hirofumi MZ     void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) override
817ee132a05SKatayama Hirofumi MZ     {
818c2c66affSColin Finck         if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
819ee132a05SKatayama Hirofumi MZ             roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y, x, y);
820e8c7e300SKatayama Hirofumi MZ 
821*3fa6d74aSKatayama Hirofumi MZ         pointStack[pointSP].x = x;
822*3fa6d74aSKatayama Hirofumi MZ         pointStack[pointSP].y = y;
823*3fa6d74aSKatayama Hirofumi MZ 
824e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
825ee132a05SKatayama Hirofumi MZ     }
826ee132a05SKatayama Hirofumi MZ 
8276d9b7f77SKatayama Hirofumi MZ     void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) override
828c2c66affSColin Finck     {
829ee132a05SKatayama Hirofumi MZ         if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
830ee132a05SKatayama Hirofumi MZ             roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y, x, y);
831ee132a05SKatayama Hirofumi MZ 
832e8c7e300SKatayama Hirofumi MZ         m_bClosed = FALSE;
833ce54a8a5SKatayama Hirofumi MZ         if (nearlyEqualPoints(x, y, pointStack[0].x, pointStack[0].y))
834c2c66affSColin Finck         {
835e8c7e300SKatayama Hirofumi MZ             OnFinishDraw();
836e8c7e300SKatayama Hirofumi MZ             return;
837c2c66affSColin Finck         }
838c2c66affSColin Finck         else
839c2c66affSColin Finck         {
840ee132a05SKatayama Hirofumi MZ             pointSP++;
841ee132a05SKatayama Hirofumi MZ             pointStack[pointSP].x = x;
842ee132a05SKatayama Hirofumi MZ             pointStack[pointSP].y = y;
843c2c66affSColin Finck         }
844ee132a05SKatayama Hirofumi MZ 
845ee132a05SKatayama Hirofumi MZ         if (pointSP == _countof(pointStack))
846c2c66affSColin Finck             pointSP--;
847e8c7e300SKatayama Hirofumi MZ 
848e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
849c2c66affSColin Finck     }
850ee132a05SKatayama Hirofumi MZ 
8516d9b7f77SKatayama Hirofumi MZ     void OnCancelDraw() override
852ee132a05SKatayama Hirofumi MZ     {
853ee132a05SKatayama Hirofumi MZ         ToolBase::OnCancelDraw();
854ee132a05SKatayama Hirofumi MZ     }
85508397115SKatayama Hirofumi MZ 
8566d9b7f77SKatayama Hirofumi MZ     void OnFinishDraw() override
85708397115SKatayama Hirofumi MZ     {
85808397115SKatayama Hirofumi MZ         if (pointSP)
85908397115SKatayama Hirofumi MZ         {
86008397115SKatayama Hirofumi MZ             --pointSP;
861e8c7e300SKatayama Hirofumi MZ             m_bClosed = TRUE;
862e8c7e300SKatayama Hirofumi MZ 
863e8c7e300SKatayama Hirofumi MZ             imageModel.PushImageForUndo();
864e8c7e300SKatayama Hirofumi MZ             OnDrawOverlayOnImage(m_hdc);
86508397115SKatayama Hirofumi MZ         }
866e8c7e300SKatayama Hirofumi MZ 
867e8c7e300SKatayama Hirofumi MZ         m_bClosed = FALSE;
868e8c7e300SKatayama Hirofumi MZ         pointSP = 0;
869e8c7e300SKatayama Hirofumi MZ 
87008397115SKatayama Hirofumi MZ         ToolBase::OnFinishDraw();
87108397115SKatayama Hirofumi MZ     }
872ee132a05SKatayama Hirofumi MZ };
873ee132a05SKatayama Hirofumi MZ 
874ee132a05SKatayama Hirofumi MZ // TOOL_ELLIPSE
875e8c7e300SKatayama Hirofumi MZ struct EllipseTool : TwoPointDrawTool
876ee132a05SKatayama Hirofumi MZ {
877e8c7e300SKatayama Hirofumi MZ     EllipseTool() : TwoPointDrawTool(TOOL_ELLIPSE)
878ee132a05SKatayama Hirofumi MZ     {
879ee132a05SKatayama Hirofumi MZ     }
880ee132a05SKatayama Hirofumi MZ 
881e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
882ee132a05SKatayama Hirofumi MZ     {
883e8c7e300SKatayama Hirofumi MZ         if (!m_bDrawing)
884e8c7e300SKatayama Hirofumi MZ             return;
885ee132a05SKatayama Hirofumi MZ         if (GetAsyncKeyState(VK_SHIFT) < 0)
886e8c7e300SKatayama Hirofumi MZ             regularize(g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y);
887e8c7e300SKatayama Hirofumi MZ         if (m_bLeftButton)
888e8c7e300SKatayama Hirofumi MZ             Ellp(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
889ee132a05SKatayama Hirofumi MZ         else
890e8c7e300SKatayama Hirofumi MZ             Ellp(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
891ee132a05SKatayama Hirofumi MZ     }
892ee132a05SKatayama Hirofumi MZ };
893ee132a05SKatayama Hirofumi MZ 
894ee132a05SKatayama Hirofumi MZ // TOOL_RRECT
895e8c7e300SKatayama Hirofumi MZ struct RRectTool : TwoPointDrawTool
896ee132a05SKatayama Hirofumi MZ {
897e8c7e300SKatayama Hirofumi MZ     RRectTool() : TwoPointDrawTool(TOOL_RRECT)
898ee132a05SKatayama Hirofumi MZ     {
899ee132a05SKatayama Hirofumi MZ     }
900ee132a05SKatayama Hirofumi MZ 
901e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
902ee132a05SKatayama Hirofumi MZ     {
903e8c7e300SKatayama Hirofumi MZ         if (!m_bDrawing)
904e8c7e300SKatayama Hirofumi MZ             return;
905ee132a05SKatayama Hirofumi MZ         if (GetAsyncKeyState(VK_SHIFT) < 0)
906e8c7e300SKatayama Hirofumi MZ             regularize(g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y);
907e8c7e300SKatayama Hirofumi MZ         if (m_bLeftButton)
908e8c7e300SKatayama Hirofumi MZ             RRect(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
909ee132a05SKatayama Hirofumi MZ         else
910e8c7e300SKatayama Hirofumi MZ             RRect(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
911ee132a05SKatayama Hirofumi MZ     }
912ee132a05SKatayama Hirofumi MZ };
913ee132a05SKatayama Hirofumi MZ 
914ee132a05SKatayama Hirofumi MZ /*static*/ ToolBase*
915ee132a05SKatayama Hirofumi MZ ToolBase::createToolObject(TOOLTYPE type)
916ee132a05SKatayama Hirofumi MZ {
917ee132a05SKatayama Hirofumi MZ     switch (type)
918ee132a05SKatayama Hirofumi MZ     {
919ee132a05SKatayama Hirofumi MZ         case TOOL_FREESEL:  return new FreeSelTool();
920ee132a05SKatayama Hirofumi MZ         case TOOL_RECTSEL:  return new RectSelTool();
921ee132a05SKatayama Hirofumi MZ         case TOOL_RUBBER:   return new RubberTool();
922ee132a05SKatayama Hirofumi MZ         case TOOL_FILL:     return new FillTool();
923ee132a05SKatayama Hirofumi MZ         case TOOL_COLOR:    return new ColorTool();
924ee132a05SKatayama Hirofumi MZ         case TOOL_ZOOM:     return new ZoomTool();
925ee132a05SKatayama Hirofumi MZ         case TOOL_PEN:      return new PenTool();
926ee132a05SKatayama Hirofumi MZ         case TOOL_BRUSH:    return new BrushTool();
927ee132a05SKatayama Hirofumi MZ         case TOOL_AIRBRUSH: return new AirBrushTool();
928ee132a05SKatayama Hirofumi MZ         case TOOL_TEXT:     return new TextTool();
929ee132a05SKatayama Hirofumi MZ         case TOOL_LINE:     return new LineTool();
930ee132a05SKatayama Hirofumi MZ         case TOOL_BEZIER:   return new BezierTool();
931ee132a05SKatayama Hirofumi MZ         case TOOL_RECT:     return new RectTool();
932ee132a05SKatayama Hirofumi MZ         case TOOL_SHAPE:    return new ShapeTool();
933ee132a05SKatayama Hirofumi MZ         case TOOL_ELLIPSE:  return new EllipseTool();
934ee132a05SKatayama Hirofumi MZ         case TOOL_RRECT:    return new RRectTool();
935ee132a05SKatayama Hirofumi MZ     }
936ee132a05SKatayama Hirofumi MZ     UNREACHABLE;
937ee132a05SKatayama Hirofumi MZ     return NULL;
938c2c66affSColin Finck }
939