xref: /reactos/base/applications/mspaint/mouse.cpp (revision 1aeebfda)
1c2c66affSColin Finck /*
2c2c66affSColin Finck  * PROJECT:    PAINT for ReactOS
38f1f1c7aSStanislav Motylkov  * LICENSE:    LGPL-2.0-or-later (https://spdx.org/licenses/LGPL-2.0-or-later)
4c2c66affSColin Finck  * PURPOSE:    Things which should not be in the mouse event handler itself
5f5200e6cSStanislav Motylkov  * COPYRIGHT:  Copyright 2015 Benedikt Freisen <b.freisen@gmx.net>
6fa4b38d9SKatayama Hirofumi MZ  *             Copyright 2021-2023 Katayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
7c2c66affSColin Finck  */
8c2c66affSColin Finck 
9c2c66affSColin Finck /* INCLUDES *********************************************************/
10c2c66affSColin Finck 
11c2c66affSColin Finck #include "precomp.h"
12e5792200SKatayama Hirofumi MZ #include <atlalloc.h>
13c2c66affSColin Finck 
14e5792200SKatayama Hirofumi MZ SIZE_T ToolBase::s_pointSP = 0;
15e5792200SKatayama Hirofumi MZ static SIZE_T s_maxPointSP = 0;
16e5792200SKatayama Hirofumi MZ static CHeapPtr<POINT, CLocalAllocator> s_pointStack;
17fa4b38d9SKatayama Hirofumi MZ static POINT g_ptStart, g_ptEnd;
18ee132a05SKatayama Hirofumi MZ 
19c2c66affSColin Finck /* FUNCTIONS ********************************************************/
20c2c66affSColin Finck 
21c2c66affSColin Finck void
22c2c66affSColin Finck regularize(LONG x0, LONG y0, LONG& x1, LONG& y1)
23c2c66affSColin Finck {
24389d0465SKatayama Hirofumi MZ     if (labs(x1 - x0) >= labs(y1 - y0))
25389d0465SKatayama Hirofumi MZ         y1 = y0 + (y1 > y0 ? labs(x1 - x0) : -labs(x1 - x0));
26c2c66affSColin Finck     else
27389d0465SKatayama Hirofumi MZ         x1 = x0 + (x1 > x0 ? labs(y1 - y0) : -labs(y1 - y0));
28c2c66affSColin Finck }
29c2c66affSColin Finck 
30c2c66affSColin Finck void
31c2c66affSColin Finck roundTo8Directions(LONG x0, LONG y0, LONG& x1, LONG& y1)
32c2c66affSColin Finck {
33389d0465SKatayama Hirofumi MZ     if (labs(x1 - x0) >= labs(y1 - y0))
34c2c66affSColin Finck     {
35389d0465SKatayama Hirofumi MZ         if (labs(y1 - y0) * 5 < labs(x1 - x0) * 2)
36c2c66affSColin Finck             y1 = y0;
37c2c66affSColin Finck         else
38389d0465SKatayama Hirofumi MZ             y1 = y0 + (y1 > y0 ? labs(x1 - x0) : -labs(x1 - x0));
39c2c66affSColin Finck     }
40c2c66affSColin Finck     else
41c2c66affSColin Finck     {
42389d0465SKatayama Hirofumi MZ         if (labs(x1 - x0) * 5 < labs(y1 - y0) * 2)
43c2c66affSColin Finck             x1 = x0;
44c2c66affSColin Finck         else
45389d0465SKatayama Hirofumi MZ             x1 = x0 + (x1 > x0 ? labs(y1 - y0) : -labs(y1 - y0));
46c2c66affSColin Finck     }
47c2c66affSColin Finck }
48c2c66affSColin Finck 
49ce54a8a5SKatayama Hirofumi MZ BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1)
50ce54a8a5SKatayama Hirofumi MZ {
51ce54a8a5SKatayama Hirofumi MZ     INT cxThreshold = toolsModel.GetLineWidth() + UnZoomed(GetSystemMetrics(SM_CXDRAG));
52ce54a8a5SKatayama Hirofumi MZ     INT cyThreshold = toolsModel.GetLineWidth() + UnZoomed(GetSystemMetrics(SM_CYDRAG));
53ce54a8a5SKatayama Hirofumi MZ     return (abs(x1 - x0) <= cxThreshold) && (abs(y1 - y0) <= cyThreshold);
54ce54a8a5SKatayama Hirofumi MZ }
55ce54a8a5SKatayama Hirofumi MZ 
56e5792200SKatayama Hirofumi MZ void getBoundaryOfPtStack(RECT& rcBoundary, INT cPoints, const POINT *pPoints)
57e5792200SKatayama Hirofumi MZ {
58e5792200SKatayama Hirofumi MZ     POINT ptMin = { MAXLONG, MAXLONG }, ptMax = { (LONG)MINLONG, (LONG)MINLONG };
59e5792200SKatayama Hirofumi MZ     while (cPoints-- > 0)
60e5792200SKatayama Hirofumi MZ     {
61e5792200SKatayama Hirofumi MZ         LONG x = pPoints->x, y = pPoints->y;
62e5792200SKatayama Hirofumi MZ         ptMin = { min(x, ptMin.x), min(y, ptMin.y) };
63e5792200SKatayama Hirofumi MZ         ptMax = { max(x, ptMax.x), max(y, ptMax.y) };
64e5792200SKatayama Hirofumi MZ         ++pPoints;
65e5792200SKatayama Hirofumi MZ     }
66e5792200SKatayama Hirofumi MZ 
67e5792200SKatayama Hirofumi MZ     ptMax.x += 1;
68e5792200SKatayama Hirofumi MZ     ptMax.y += 1;
69e5792200SKatayama Hirofumi MZ 
70e5792200SKatayama Hirofumi MZ     CRect rc(ptMin, ptMax);
71e5792200SKatayama Hirofumi MZ     rcBoundary = rc;
72e5792200SKatayama Hirofumi MZ }
73e5792200SKatayama Hirofumi MZ 
74ee132a05SKatayama Hirofumi MZ void ToolBase::reset()
75c2c66affSColin Finck {
76ec53d422SKatayama Hirofumi MZ     s_pointSP = 0;
77e5792200SKatayama Hirofumi MZ     g_ptEnd = g_ptStart = { -1, -1 };
78e5792200SKatayama Hirofumi MZ 
7908397115SKatayama Hirofumi MZ     selectionModel.ResetPtStack();
80e5792200SKatayama Hirofumi MZ 
81aac89519SKatayama Hirofumi MZ     if (selectionModel.m_bShow)
82aac89519SKatayama Hirofumi MZ     {
83aac89519SKatayama Hirofumi MZ         selectionModel.Landing();
84e8c7e300SKatayama Hirofumi MZ         selectionModel.HideSelection();
85aac89519SKatayama Hirofumi MZ     }
86ee132a05SKatayama Hirofumi MZ }
87ee132a05SKatayama Hirofumi MZ 
8837f56d24SKatayama Hirofumi MZ void ToolBase::OnEndDraw(BOOL bCancel)
8908397115SKatayama Hirofumi MZ {
9008397115SKatayama Hirofumi MZ     reset();
91bfd42c67SKatayama Hirofumi MZ     imageModel.NotifyImageChanged();
9208397115SKatayama Hirofumi MZ }
9308397115SKatayama Hirofumi MZ 
94ee132a05SKatayama Hirofumi MZ void ToolBase::beginEvent()
95ee132a05SKatayama Hirofumi MZ {
96ee132a05SKatayama Hirofumi MZ     m_hdc = imageModel.GetDC();
97ee132a05SKatayama Hirofumi MZ     m_fg = paletteModel.GetFgColor();
98ee132a05SKatayama Hirofumi MZ     m_bg = paletteModel.GetBgColor();
99ee132a05SKatayama Hirofumi MZ }
100ee132a05SKatayama Hirofumi MZ 
101ee132a05SKatayama Hirofumi MZ void ToolBase::endEvent()
102ee132a05SKatayama Hirofumi MZ {
103ee132a05SKatayama Hirofumi MZ     m_hdc = NULL;
104ee132a05SKatayama Hirofumi MZ }
105ee132a05SKatayama Hirofumi MZ 
106e5792200SKatayama Hirofumi MZ void ToolBase::pushToPtStack(LONG x, LONG y)
107e5792200SKatayama Hirofumi MZ {
108e5792200SKatayama Hirofumi MZ     if (s_pointSP >= s_maxPointSP)
109e5792200SKatayama Hirofumi MZ     {
110e5792200SKatayama Hirofumi MZ         SIZE_T newMax = s_maxPointSP + 512;
111e5792200SKatayama Hirofumi MZ         SIZE_T cbNew = newMax * sizeof(POINT);
112e5792200SKatayama Hirofumi MZ         if (!s_pointStack.ReallocateBytes(cbNew))
113e5792200SKatayama Hirofumi MZ         {
114e5792200SKatayama Hirofumi MZ             ATLTRACE("%d, %d, %d\n", (INT)s_pointSP, (INT)s_maxPointSP, (INT)cbNew);
115e5792200SKatayama Hirofumi MZ             return;
116e5792200SKatayama Hirofumi MZ         }
117e5792200SKatayama Hirofumi MZ 
118e5792200SKatayama Hirofumi MZ         s_maxPointSP = newMax;
119e5792200SKatayama Hirofumi MZ     }
120e5792200SKatayama Hirofumi MZ 
121e5792200SKatayama Hirofumi MZ     s_pointStack[s_pointSP++] = { x, y };
122e5792200SKatayama Hirofumi MZ }
123e5792200SKatayama Hirofumi MZ 
124ee132a05SKatayama Hirofumi MZ /* TOOLS ********************************************************/
125ee132a05SKatayama Hirofumi MZ 
126ee132a05SKatayama Hirofumi MZ // TOOL_FREESEL
127ee132a05SKatayama Hirofumi MZ struct FreeSelTool : ToolBase
128ee132a05SKatayama Hirofumi MZ {
129e8c7e300SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
13008397115SKatayama Hirofumi MZ 
131e8c7e300SKatayama Hirofumi MZ     FreeSelTool() : ToolBase(TOOL_FREESEL)
132ee132a05SKatayama Hirofumi MZ     {
133ee132a05SKatayama Hirofumi MZ     }
134ee132a05SKatayama Hirofumi MZ 
135e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
136e8c7e300SKatayama Hirofumi MZ     {
137e8c7e300SKatayama Hirofumi MZ         if (!selectionModel.IsLanded())
138e8c7e300SKatayama Hirofumi MZ             selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
139e8c7e300SKatayama Hirofumi MZ 
140e8c7e300SKatayama Hirofumi MZ         if (canvasWindow.m_drawing)
141e8c7e300SKatayama Hirofumi MZ         {
142e8c7e300SKatayama Hirofumi MZ             selectionModel.DrawFramePoly(hdc);
143e8c7e300SKatayama Hirofumi MZ         }
144e8c7e300SKatayama Hirofumi MZ     }
145e8c7e300SKatayama Hirofumi MZ 
146e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnCanvas(HDC hdc) override
147e8c7e300SKatayama Hirofumi MZ     {
1484a52a4b0SKatayama Hirofumi MZ         selectionModel.drawFrameOnCanvas(hdc);
149e8c7e300SKatayama Hirofumi MZ     }
150e8c7e300SKatayama Hirofumi MZ 
1516d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
152ee132a05SKatayama Hirofumi MZ     {
153aac89519SKatayama Hirofumi MZ         selectionModel.Landing();
15408397115SKatayama Hirofumi MZ         if (bLeftButton)
15508397115SKatayama Hirofumi MZ         {
156e8c7e300SKatayama Hirofumi MZ             selectionModel.HideSelection();
157c2c66affSColin Finck             selectionModel.ResetPtStack();
158aac89519SKatayama Hirofumi MZ             POINT pt = { x, y };
159aac89519SKatayama Hirofumi MZ             selectionModel.PushToPtStack(pt);
160c2c66affSColin Finck         }
16108397115SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
16208397115SKatayama Hirofumi MZ     }
163c2c66affSColin Finck 
164389d0465SKatayama Hirofumi MZ     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
165c2c66affSColin Finck     {
16608397115SKatayama Hirofumi MZ         if (bLeftButton)
16708397115SKatayama Hirofumi MZ         {
16808397115SKatayama Hirofumi MZ             POINT pt = { x, y };
169d04e0492SKatayama Hirofumi MZ             imageModel.Clamp(pt);
170aac89519SKatayama Hirofumi MZ             selectionModel.PushToPtStack(pt);
171e8c7e300SKatayama Hirofumi MZ             imageModel.NotifyImageChanged();
172ee132a05SKatayama Hirofumi MZ         }
173389d0465SKatayama Hirofumi MZ         return TRUE;
17408397115SKatayama Hirofumi MZ     }
175ee132a05SKatayama Hirofumi MZ 
176389d0465SKatayama Hirofumi MZ     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
177ee132a05SKatayama Hirofumi MZ     {
17808397115SKatayama Hirofumi MZ         if (bLeftButton)
179ee132a05SKatayama Hirofumi MZ         {
18008397115SKatayama Hirofumi MZ             if (selectionModel.PtStackSize() > 2)
18108397115SKatayama Hirofumi MZ             {
182aac89519SKatayama Hirofumi MZ                 selectionModel.BuildMaskFromPtStack();
183aac89519SKatayama Hirofumi MZ                 selectionModel.m_bShow = TRUE;
184ee132a05SKatayama Hirofumi MZ             }
18508397115SKatayama Hirofumi MZ             else
18608397115SKatayama Hirofumi MZ             {
187ee132a05SKatayama Hirofumi MZ                 selectionModel.ResetPtStack();
188aac89519SKatayama Hirofumi MZ                 selectionModel.m_bShow = FALSE;
18908397115SKatayama Hirofumi MZ             }
190bfd42c67SKatayama Hirofumi MZ             imageModel.NotifyImageChanged();
19108397115SKatayama Hirofumi MZ         }
1927aadc1e1SKatayama Hirofumi MZ         else
1937aadc1e1SKatayama Hirofumi MZ         {
1947aadc1e1SKatayama Hirofumi MZ             POINT pt = { x, y };
1957aadc1e1SKatayama Hirofumi MZ             canvasWindow.ClientToScreen(&pt);
1967aadc1e1SKatayama Hirofumi MZ             mainWindow.TrackPopupMenu(pt, 0);
1977aadc1e1SKatayama Hirofumi MZ         }
198389d0465SKatayama Hirofumi MZ         return TRUE;
19908397115SKatayama Hirofumi MZ     }
20008397115SKatayama Hirofumi MZ 
20137f56d24SKatayama Hirofumi MZ     void OnEndDraw(BOOL bCancel) override
20208397115SKatayama Hirofumi MZ     {
20337f56d24SKatayama Hirofumi MZ         if (bCancel)
204e8c7e300SKatayama Hirofumi MZ             selectionModel.HideSelection();
20537f56d24SKatayama Hirofumi MZ         else
20637f56d24SKatayama Hirofumi MZ             selectionModel.Landing();
20737f56d24SKatayama Hirofumi MZ         ToolBase::OnEndDraw(bCancel);
208ee132a05SKatayama Hirofumi MZ     }
209ed9973f8SKatayama Hirofumi MZ 
210ed9973f8SKatayama Hirofumi MZ     void OnSpecialTweak(BOOL bMinus) override
211ed9973f8SKatayama Hirofumi MZ     {
212ed9973f8SKatayama Hirofumi MZ         selectionModel.StretchSelection(bMinus);
213ed9973f8SKatayama Hirofumi MZ     }
214ee132a05SKatayama Hirofumi MZ };
215ee132a05SKatayama Hirofumi MZ 
216ee132a05SKatayama Hirofumi MZ // TOOL_RECTSEL
217ee132a05SKatayama Hirofumi MZ struct RectSelTool : ToolBase
218ee132a05SKatayama Hirofumi MZ {
219e8c7e300SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
22008397115SKatayama Hirofumi MZ 
221e8c7e300SKatayama Hirofumi MZ     RectSelTool() : ToolBase(TOOL_RECTSEL)
222ee132a05SKatayama Hirofumi MZ     {
223ee132a05SKatayama Hirofumi MZ     }
224ee132a05SKatayama Hirofumi MZ 
225e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
226e8c7e300SKatayama Hirofumi MZ     {
227e8c7e300SKatayama Hirofumi MZ         if (!selectionModel.IsLanded())
228e8c7e300SKatayama Hirofumi MZ             selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
229e8c7e300SKatayama Hirofumi MZ 
230e8c7e300SKatayama Hirofumi MZ         if (canvasWindow.m_drawing)
231e8c7e300SKatayama Hirofumi MZ         {
232*1aeebfdaSKatayama Hirofumi MZ             CRect& rc = selectionModel.m_rc;
233*1aeebfdaSKatayama Hirofumi MZ             if (!rc.IsRectEmpty())
234e8c7e300SKatayama Hirofumi MZ                 RectSel(hdc, rc.left, rc.top, rc.right, rc.bottom);
235e8c7e300SKatayama Hirofumi MZ         }
236e8c7e300SKatayama Hirofumi MZ     }
237e8c7e300SKatayama Hirofumi MZ 
238e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnCanvas(HDC hdc) override
239e8c7e300SKatayama Hirofumi MZ     {
2404a52a4b0SKatayama Hirofumi MZ         selectionModel.drawFrameOnCanvas(hdc);
241e8c7e300SKatayama Hirofumi MZ     }
242e8c7e300SKatayama Hirofumi MZ 
2436d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
244ee132a05SKatayama Hirofumi MZ     {
245aac89519SKatayama Hirofumi MZ         selectionModel.Landing();
246ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
247ee132a05SKatayama Hirofumi MZ         {
248e8c7e300SKatayama Hirofumi MZ             selectionModel.HideSelection();
249ee132a05SKatayama Hirofumi MZ         }
25008397115SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
251ee132a05SKatayama Hirofumi MZ     }
252ee132a05SKatayama Hirofumi MZ 
253389d0465SKatayama Hirofumi MZ     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
254ee132a05SKatayama Hirofumi MZ     {
255ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
256ee132a05SKatayama Hirofumi MZ         {
25708397115SKatayama Hirofumi MZ             POINT pt = { x, y };
258d04e0492SKatayama Hirofumi MZ             imageModel.Clamp(pt);
259e8c7e300SKatayama Hirofumi MZ             selectionModel.SetRectFromPoints(g_ptStart, pt);
260e8c7e300SKatayama Hirofumi MZ             imageModel.NotifyImageChanged();
261ee132a05SKatayama Hirofumi MZ         }
262389d0465SKatayama Hirofumi MZ         return TRUE;
263ee132a05SKatayama Hirofumi MZ     }
264ee132a05SKatayama Hirofumi MZ 
265389d0465SKatayama Hirofumi MZ     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
266ee132a05SKatayama Hirofumi MZ     {
2677aadc1e1SKatayama Hirofumi MZ         POINT pt = { x, y };
268ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
269ee132a05SKatayama Hirofumi MZ         {
270d04e0492SKatayama Hirofumi MZ             imageModel.Clamp(pt);
271e8c7e300SKatayama Hirofumi MZ             selectionModel.SetRectFromPoints(g_ptStart, pt);
272aac89519SKatayama Hirofumi MZ             selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty();
273bfd42c67SKatayama Hirofumi MZ             imageModel.NotifyImageChanged();
274ee132a05SKatayama Hirofumi MZ         }
2757aadc1e1SKatayama Hirofumi MZ         else
2767aadc1e1SKatayama Hirofumi MZ         {
2777aadc1e1SKatayama Hirofumi MZ             canvasWindow.ClientToScreen(&pt);
2787aadc1e1SKatayama Hirofumi MZ             mainWindow.TrackPopupMenu(pt, 0);
2797aadc1e1SKatayama Hirofumi MZ         }
280389d0465SKatayama Hirofumi MZ         return TRUE;
281ee132a05SKatayama Hirofumi MZ     }
28208397115SKatayama Hirofumi MZ 
28337f56d24SKatayama Hirofumi MZ     void OnEndDraw(BOOL bCancel) override
28408397115SKatayama Hirofumi MZ     {
28537f56d24SKatayama Hirofumi MZ         if (bCancel)
286e8c7e300SKatayama Hirofumi MZ             selectionModel.HideSelection();
28737f56d24SKatayama Hirofumi MZ         else
28837f56d24SKatayama Hirofumi MZ             selectionModel.Landing();
28937f56d24SKatayama Hirofumi MZ         ToolBase::OnEndDraw(bCancel);
290ee132a05SKatayama Hirofumi MZ     }
291ed9973f8SKatayama Hirofumi MZ 
292ed9973f8SKatayama Hirofumi MZ     void OnSpecialTweak(BOOL bMinus) override
293ed9973f8SKatayama Hirofumi MZ     {
294ed9973f8SKatayama Hirofumi MZ         selectionModel.StretchSelection(bMinus);
295ed9973f8SKatayama Hirofumi MZ     }
296ee132a05SKatayama Hirofumi MZ };
297ee132a05SKatayama Hirofumi MZ 
298e8c7e300SKatayama Hirofumi MZ struct TwoPointDrawTool : ToolBase
299ee132a05SKatayama Hirofumi MZ {
300e8c7e300SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
301e8c7e300SKatayama Hirofumi MZ     BOOL m_bDrawing = FALSE;
302e8c7e300SKatayama Hirofumi MZ 
303e8c7e300SKatayama Hirofumi MZ     TwoPointDrawTool(TOOLTYPE type) : ToolBase(type)
304e8c7e300SKatayama Hirofumi MZ     {
305e8c7e300SKatayama Hirofumi MZ     }
306e8c7e300SKatayama Hirofumi MZ 
307e8c7e300SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
308e8c7e300SKatayama Hirofumi MZ     {
309e8c7e300SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
310e8c7e300SKatayama Hirofumi MZ         m_bDrawing = TRUE;
311e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
312e8c7e300SKatayama Hirofumi MZ     }
313e8c7e300SKatayama Hirofumi MZ 
314389d0465SKatayama Hirofumi MZ     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
315e8c7e300SKatayama Hirofumi MZ     {
316e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
317389d0465SKatayama Hirofumi MZ         return TRUE;
318e8c7e300SKatayama Hirofumi MZ     }
319e8c7e300SKatayama Hirofumi MZ 
320389d0465SKatayama Hirofumi MZ     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
321e8c7e300SKatayama Hirofumi MZ     {
32272081168SKatayama Hirofumi MZ         CRect rcPartial(g_ptStart, g_ptEnd);
32372081168SKatayama Hirofumi MZ         rcPartial.NormalizeRect();
32472081168SKatayama Hirofumi MZ         SIZE size = toolsModel.GetToolSize();
32572081168SKatayama Hirofumi MZ         rcPartial.InflateRect((size.cx + 1) / 2, (size.cy + 1) / 2);
32672081168SKatayama Hirofumi MZ         imageModel.PushImageForUndo(rcPartial);
32772081168SKatayama Hirofumi MZ 
328e8c7e300SKatayama Hirofumi MZ         OnDrawOverlayOnImage(m_hdc);
329e8c7e300SKatayama Hirofumi MZ         m_bDrawing = FALSE;
330e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
331389d0465SKatayama Hirofumi MZ         return TRUE;
332e8c7e300SKatayama Hirofumi MZ     }
333e8c7e300SKatayama Hirofumi MZ 
33437f56d24SKatayama Hirofumi MZ     void OnEndDraw(BOOL bCancel) override
335e8c7e300SKatayama Hirofumi MZ     {
336e8c7e300SKatayama Hirofumi MZ         m_bDrawing = FALSE;
33737f56d24SKatayama Hirofumi MZ         ToolBase::OnEndDraw(bCancel);
338e8c7e300SKatayama Hirofumi MZ     }
339f2a01224SKatayama Hirofumi MZ 
340f2a01224SKatayama Hirofumi MZ     void OnSpecialTweak(BOOL bMinus) override
341f2a01224SKatayama Hirofumi MZ     {
342f2a01224SKatayama Hirofumi MZ         toolsModel.MakeLineThickerOrThinner(bMinus);
343f2a01224SKatayama Hirofumi MZ     }
344e8c7e300SKatayama Hirofumi MZ };
345e8c7e300SKatayama Hirofumi MZ 
346389d0465SKatayama Hirofumi MZ typedef enum DIRECTION
347389d0465SKatayama Hirofumi MZ {
348389d0465SKatayama Hirofumi MZ     NO_DIRECTION = -1,
349389d0465SKatayama Hirofumi MZ     DIRECTION_HORIZONTAL,
350389d0465SKatayama Hirofumi MZ     DIRECTION_VERTICAL,
351389d0465SKatayama Hirofumi MZ     DIRECTION_DIAGONAL_RIGHT_DOWN,
352389d0465SKatayama Hirofumi MZ     DIRECTION_DIAGONAL_RIGHT_UP,
353389d0465SKatayama Hirofumi MZ } DIRECTION;
354389d0465SKatayama Hirofumi MZ 
355389d0465SKatayama Hirofumi MZ #define THRESHOULD_DEG 15
356389d0465SKatayama Hirofumi MZ 
357389d0465SKatayama Hirofumi MZ static DIRECTION
358389d0465SKatayama Hirofumi MZ GetDirection(LONG x0, LONG y0, LONG x1, LONG y1)
359389d0465SKatayama Hirofumi MZ {
360389d0465SKatayama Hirofumi MZ     LONG dx = x1 - x0, dy = y1 - y0;
361389d0465SKatayama Hirofumi MZ 
362389d0465SKatayama Hirofumi MZ     if (labs(dx) <= 8 && labs(dy) <= 8)
363389d0465SKatayama Hirofumi MZ         return NO_DIRECTION;
364389d0465SKatayama Hirofumi MZ 
365389d0465SKatayama Hirofumi MZ     double radian = atan2((double)dy, (double)dx);
366389d0465SKatayama Hirofumi MZ     if (radian < DEG2RAD(-180 + THRESHOULD_DEG))
367389d0465SKatayama Hirofumi MZ     {
368389d0465SKatayama Hirofumi MZ         ATLTRACE("DIRECTION_HORIZONTAL: %ld\n", RAD2DEG(radian));
369389d0465SKatayama Hirofumi MZ         return DIRECTION_HORIZONTAL;
370389d0465SKatayama Hirofumi MZ     }
371389d0465SKatayama Hirofumi MZ     if (radian < DEG2RAD(-90 - THRESHOULD_DEG))
372389d0465SKatayama Hirofumi MZ     {
373389d0465SKatayama Hirofumi MZ         ATLTRACE("DIRECTION_DIAGONAL_RIGHT_DOWN: %ld\n", RAD2DEG(radian));
374389d0465SKatayama Hirofumi MZ         return DIRECTION_DIAGONAL_RIGHT_DOWN;
375389d0465SKatayama Hirofumi MZ     }
376389d0465SKatayama Hirofumi MZ     if (radian < DEG2RAD(-90 + THRESHOULD_DEG))
377389d0465SKatayama Hirofumi MZ     {
378389d0465SKatayama Hirofumi MZ         ATLTRACE("DIRECTION_VERTICAL: %ld\n", RAD2DEG(radian));
379389d0465SKatayama Hirofumi MZ         return DIRECTION_VERTICAL;
380389d0465SKatayama Hirofumi MZ     }
381389d0465SKatayama Hirofumi MZ     if (radian < DEG2RAD(-THRESHOULD_DEG))
382389d0465SKatayama Hirofumi MZ     {
383389d0465SKatayama Hirofumi MZ         ATLTRACE("DIRECTION_DIAGONAL_RIGHT_UP: %ld\n", RAD2DEG(radian));
384389d0465SKatayama Hirofumi MZ         return DIRECTION_DIAGONAL_RIGHT_UP;
385389d0465SKatayama Hirofumi MZ     }
386389d0465SKatayama Hirofumi MZ     if (radian < DEG2RAD(+THRESHOULD_DEG))
387389d0465SKatayama Hirofumi MZ     {
388389d0465SKatayama Hirofumi MZ         ATLTRACE("DIRECTION_HORIZONTAL: %ld\n", RAD2DEG(radian));
389389d0465SKatayama Hirofumi MZ         return DIRECTION_HORIZONTAL;
390389d0465SKatayama Hirofumi MZ     }
391389d0465SKatayama Hirofumi MZ     if (radian < DEG2RAD(+90 - THRESHOULD_DEG))
392389d0465SKatayama Hirofumi MZ     {
393389d0465SKatayama Hirofumi MZ         ATLTRACE("DIRECTION_DIAGONAL_RIGHT_DOWN: %ld\n", RAD2DEG(radian));
394389d0465SKatayama Hirofumi MZ         return DIRECTION_DIAGONAL_RIGHT_DOWN;
395389d0465SKatayama Hirofumi MZ     }
396389d0465SKatayama Hirofumi MZ     if (radian < DEG2RAD(+90 + THRESHOULD_DEG))
397389d0465SKatayama Hirofumi MZ     {
398389d0465SKatayama Hirofumi MZ         ATLTRACE("DIRECTION_VERTICAL: %ld\n", RAD2DEG(radian));
399389d0465SKatayama Hirofumi MZ         return DIRECTION_VERTICAL;
400389d0465SKatayama Hirofumi MZ     }
401389d0465SKatayama Hirofumi MZ     if (radian < DEG2RAD(+180 - THRESHOULD_DEG))
402389d0465SKatayama Hirofumi MZ     {
403389d0465SKatayama Hirofumi MZ         ATLTRACE("DIRECTION_DIAGONAL_RIGHT_UP: %ld\n", RAD2DEG(radian));
404389d0465SKatayama Hirofumi MZ         return DIRECTION_DIAGONAL_RIGHT_UP;
405389d0465SKatayama Hirofumi MZ     }
406389d0465SKatayama Hirofumi MZ     ATLTRACE("DIRECTION_HORIZONTAL: %ld\n", RAD2DEG(radian));
407389d0465SKatayama Hirofumi MZ     return DIRECTION_HORIZONTAL;
408389d0465SKatayama Hirofumi MZ }
409389d0465SKatayama Hirofumi MZ 
410389d0465SKatayama Hirofumi MZ static void
411389d0465SKatayama Hirofumi MZ RestrictDrawDirection(DIRECTION dir, LONG x0, LONG y0, LONG& x1, LONG& y1)
412389d0465SKatayama Hirofumi MZ {
413389d0465SKatayama Hirofumi MZ     switch (dir)
414389d0465SKatayama Hirofumi MZ     {
415389d0465SKatayama Hirofumi MZ         case NO_DIRECTION:
416389d0465SKatayama Hirofumi MZ         default:
417389d0465SKatayama Hirofumi MZ             return;
418389d0465SKatayama Hirofumi MZ 
419389d0465SKatayama Hirofumi MZ         case DIRECTION_HORIZONTAL:
420389d0465SKatayama Hirofumi MZ             y1 = y0;
421389d0465SKatayama Hirofumi MZ             break;
422389d0465SKatayama Hirofumi MZ 
423389d0465SKatayama Hirofumi MZ         case DIRECTION_VERTICAL:
424389d0465SKatayama Hirofumi MZ             x1 = x0;
425389d0465SKatayama Hirofumi MZ             break;
426389d0465SKatayama Hirofumi MZ 
427389d0465SKatayama Hirofumi MZ         case DIRECTION_DIAGONAL_RIGHT_DOWN:
428389d0465SKatayama Hirofumi MZ             y1 = y0 + (x1 - x0);
429389d0465SKatayama Hirofumi MZ             break;
430389d0465SKatayama Hirofumi MZ 
431389d0465SKatayama Hirofumi MZ         case DIRECTION_DIAGONAL_RIGHT_UP:
432389d0465SKatayama Hirofumi MZ             x1 = x0 - (y1 - y0);
433389d0465SKatayama Hirofumi MZ             break;
434389d0465SKatayama Hirofumi MZ     }
435389d0465SKatayama Hirofumi MZ }
436389d0465SKatayama Hirofumi MZ 
437e8c7e300SKatayama Hirofumi MZ struct SmoothDrawTool : ToolBase
438e8c7e300SKatayama Hirofumi MZ {
439389d0465SKatayama Hirofumi MZ     DIRECTION m_direction = NO_DIRECTION;
440fd1e1584SKatayama Hirofumi MZ     BOOL m_bShiftDown = FALSE;
441e5792200SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
442389d0465SKatayama Hirofumi MZ 
443e8c7e300SKatayama Hirofumi MZ     SmoothDrawTool(TOOLTYPE type) : ToolBase(type)
444ee132a05SKatayama Hirofumi MZ     {
445ee132a05SKatayama Hirofumi MZ     }
446ee132a05SKatayama Hirofumi MZ 
447e5792200SKatayama Hirofumi MZ     virtual void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) = 0;
448ee132a05SKatayama Hirofumi MZ 
4496d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
450ee132a05SKatayama Hirofumi MZ     {
451389d0465SKatayama Hirofumi MZ         m_direction = NO_DIRECTION;
452fd1e1584SKatayama Hirofumi MZ         m_bShiftDown = (::GetKeyState(VK_SHIFT) & 0x8000); // Is Shift key pressed?
453e5792200SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
454e5792200SKatayama Hirofumi MZ         s_pointSP = 0;
455e5792200SKatayama Hirofumi MZ         pushToPtStack(x, y);
456e5792200SKatayama Hirofumi MZ         pushToPtStack(x, y); // We have to draw the first point
457e5792200SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
458389d0465SKatayama Hirofumi MZ     }
459389d0465SKatayama Hirofumi MZ 
460389d0465SKatayama Hirofumi MZ     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
461389d0465SKatayama Hirofumi MZ     {
462e5792200SKatayama Hirofumi MZ         if (!m_bShiftDown)
463389d0465SKatayama Hirofumi MZ         {
464e5792200SKatayama Hirofumi MZ             pushToPtStack(x, y);
465e5792200SKatayama Hirofumi MZ             imageModel.NotifyImageChanged();
466e5792200SKatayama Hirofumi MZ             return TRUE;
467e5792200SKatayama Hirofumi MZ         }
468e5792200SKatayama Hirofumi MZ 
469389d0465SKatayama Hirofumi MZ         if (m_direction == NO_DIRECTION)
470389d0465SKatayama Hirofumi MZ         {
471389d0465SKatayama Hirofumi MZ             m_direction = GetDirection(g_ptStart.x, g_ptStart.y, x, y);
472389d0465SKatayama Hirofumi MZ             if (m_direction == NO_DIRECTION)
473389d0465SKatayama Hirofumi MZ                 return FALSE;
474389d0465SKatayama Hirofumi MZ         }
475389d0465SKatayama Hirofumi MZ 
476389d0465SKatayama Hirofumi MZ         RestrictDrawDirection(m_direction, g_ptStart.x, g_ptStart.y, x, y);
477e5792200SKatayama Hirofumi MZ         pushToPtStack(x, y);
478bfd42c67SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
479389d0465SKatayama Hirofumi MZ         return TRUE;
480ee132a05SKatayama Hirofumi MZ     }
481ee132a05SKatayama Hirofumi MZ 
482389d0465SKatayama Hirofumi MZ     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
483ee132a05SKatayama Hirofumi MZ     {
484fd1e1584SKatayama Hirofumi MZ         if (m_bShiftDown && m_direction != NO_DIRECTION)
485389d0465SKatayama Hirofumi MZ             RestrictDrawDirection(m_direction, g_ptStart.x, g_ptStart.y, x, y);
486389d0465SKatayama Hirofumi MZ 
487e5792200SKatayama Hirofumi MZ         pushToPtStack(x, y);
488e5792200SKatayama Hirofumi MZ 
489e5792200SKatayama Hirofumi MZ         CRect rcPartial;
490e5792200SKatayama Hirofumi MZ         getBoundaryOfPtStack(rcPartial, s_pointSP, s_pointStack);
491e5792200SKatayama Hirofumi MZ 
492e5792200SKatayama Hirofumi MZ         SIZE size = toolsModel.GetToolSize();
493e5792200SKatayama Hirofumi MZ         rcPartial.InflateRect((size.cx + 1) / 2, (size.cy + 1) / 2);
494e5792200SKatayama Hirofumi MZ 
495e5792200SKatayama Hirofumi MZ         imageModel.PushImageForUndo(rcPartial);
496e5792200SKatayama Hirofumi MZ 
497e5792200SKatayama Hirofumi MZ         OnDrawOverlayOnImage(m_hdc);
498e5792200SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
49937f56d24SKatayama Hirofumi MZ         OnEndDraw(FALSE);
500389d0465SKatayama Hirofumi MZ         return TRUE;
501e8c7e300SKatayama Hirofumi MZ     }
502e8c7e300SKatayama Hirofumi MZ 
503e5792200SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
504e8c7e300SKatayama Hirofumi MZ     {
505e5792200SKatayama Hirofumi MZ         for (SIZE_T i = 1; i < s_pointSP; ++i)
506ee132a05SKatayama Hirofumi MZ         {
507e5792200SKatayama Hirofumi MZ             OnDraw(hdc, m_bLeftButton, s_pointStack[i - 1], s_pointStack[i]);
50837f56d24SKatayama Hirofumi MZ         }
509ee132a05SKatayama Hirofumi MZ     }
510ee132a05SKatayama Hirofumi MZ };
511ee132a05SKatayama Hirofumi MZ 
512ee132a05SKatayama Hirofumi MZ // TOOL_RUBBER
513e8c7e300SKatayama Hirofumi MZ struct RubberTool : SmoothDrawTool
514ee132a05SKatayama Hirofumi MZ {
515e8c7e300SKatayama Hirofumi MZ     RubberTool() : SmoothDrawTool(TOOL_RUBBER)
516ee132a05SKatayama Hirofumi MZ     {
517ee132a05SKatayama Hirofumi MZ     }
518ee132a05SKatayama Hirofumi MZ 
519e5792200SKatayama Hirofumi MZ     void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override
520ee132a05SKatayama Hirofumi MZ     {
521ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
522e5792200SKatayama Hirofumi MZ             Erase(hdc, pt0.x, pt0.y, pt1.x, pt1.y, m_bg, toolsModel.GetRubberRadius());
523ee132a05SKatayama Hirofumi MZ         else
524e5792200SKatayama Hirofumi MZ             Replace(hdc, pt0.x, pt0.y, pt1.x, pt1.y, m_fg, m_bg, toolsModel.GetRubberRadius());
525ee132a05SKatayama Hirofumi MZ     }
526945ee4b2SKatayama Hirofumi MZ 
527945ee4b2SKatayama Hirofumi MZ     void OnSpecialTweak(BOOL bMinus) override
528945ee4b2SKatayama Hirofumi MZ     {
529945ee4b2SKatayama Hirofumi MZ         toolsModel.MakeRubberThickerOrThinner(bMinus);
530945ee4b2SKatayama Hirofumi MZ     }
531ee132a05SKatayama Hirofumi MZ };
532ee132a05SKatayama Hirofumi MZ 
533ee132a05SKatayama Hirofumi MZ // TOOL_FILL
534ee132a05SKatayama Hirofumi MZ struct FillTool : ToolBase
535ee132a05SKatayama Hirofumi MZ {
536ee132a05SKatayama Hirofumi MZ     FillTool() : ToolBase(TOOL_FILL)
537ee132a05SKatayama Hirofumi MZ     {
538ee132a05SKatayama Hirofumi MZ     }
539ee132a05SKatayama Hirofumi MZ 
5406d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
541ee132a05SKatayama Hirofumi MZ     {
5422b623c1dSKatayama Hirofumi MZ         imageModel.PushImageForUndo();
543ee132a05SKatayama Hirofumi MZ         Fill(m_hdc, x, y, bLeftButton ? m_fg : m_bg);
544ee132a05SKatayama Hirofumi MZ     }
545ee132a05SKatayama Hirofumi MZ };
546ee132a05SKatayama Hirofumi MZ 
547ee132a05SKatayama Hirofumi MZ // TOOL_COLOR
548ee132a05SKatayama Hirofumi MZ struct ColorTool : ToolBase
549ee132a05SKatayama Hirofumi MZ {
550ee132a05SKatayama Hirofumi MZ     ColorTool() : ToolBase(TOOL_COLOR)
551ee132a05SKatayama Hirofumi MZ     {
552ee132a05SKatayama Hirofumi MZ     }
553ee132a05SKatayama Hirofumi MZ 
55408397115SKatayama Hirofumi MZ     void fetchColor(BOOL bLeftButton, LONG x, LONG y)
555ee132a05SKatayama Hirofumi MZ     {
55608397115SKatayama Hirofumi MZ         COLORREF rgbColor;
557ee132a05SKatayama Hirofumi MZ 
558ee132a05SKatayama Hirofumi MZ         if (0 <= x && x < imageModel.GetWidth() && 0 <= y && y < imageModel.GetHeight())
55908397115SKatayama Hirofumi MZ             rgbColor = GetPixel(m_hdc, x, y);
560ee132a05SKatayama Hirofumi MZ         else
56108397115SKatayama Hirofumi MZ             rgbColor = RGB(255, 255, 255); // Outside is white
562ee132a05SKatayama Hirofumi MZ 
563ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
56408397115SKatayama Hirofumi MZ             paletteModel.SetFgColor(rgbColor);
565ee132a05SKatayama Hirofumi MZ         else
56608397115SKatayama Hirofumi MZ             paletteModel.SetBgColor(rgbColor);
56708397115SKatayama Hirofumi MZ     }
568ee132a05SKatayama Hirofumi MZ 
569389d0465SKatayama Hirofumi MZ     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
57008397115SKatayama Hirofumi MZ     {
57108397115SKatayama Hirofumi MZ         fetchColor(bLeftButton, x, y);
572389d0465SKatayama Hirofumi MZ         return TRUE;
57308397115SKatayama Hirofumi MZ     }
57408397115SKatayama Hirofumi MZ 
575389d0465SKatayama Hirofumi MZ     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
57608397115SKatayama Hirofumi MZ     {
57708397115SKatayama Hirofumi MZ         fetchColor(bLeftButton, x, y);
578ee132a05SKatayama Hirofumi MZ         toolsModel.SetActiveTool(toolsModel.GetOldActiveTool());
579389d0465SKatayama Hirofumi MZ         return TRUE;
580ee132a05SKatayama Hirofumi MZ     }
581ee132a05SKatayama Hirofumi MZ };
582ee132a05SKatayama Hirofumi MZ 
583ee132a05SKatayama Hirofumi MZ // TOOL_ZOOM
584ee132a05SKatayama Hirofumi MZ struct ZoomTool : ToolBase
585ee132a05SKatayama Hirofumi MZ {
5868f1eb03aSKatayama Hirofumi MZ     BOOL m_bZoomed = FALSE;
5878f1eb03aSKatayama Hirofumi MZ 
588ee132a05SKatayama Hirofumi MZ     ZoomTool() : ToolBase(TOOL_ZOOM)
589ee132a05SKatayama Hirofumi MZ     {
590ee132a05SKatayama Hirofumi MZ     }
591ee132a05SKatayama Hirofumi MZ 
5928f1eb03aSKatayama Hirofumi MZ     BOOL getNewZoomRect(CRect& rcView, INT newZoom);
5938f1eb03aSKatayama Hirofumi MZ 
59462eeb158SKatayama Hirofumi MZ     void OnDrawOverlayOnCanvas(HDC hdc) override
59562eeb158SKatayama Hirofumi MZ     {
5968f1eb03aSKatayama Hirofumi MZ         CRect rcView;
5978f1eb03aSKatayama Hirofumi MZ         INT oldZoom = toolsModel.GetZoom();
5988f1eb03aSKatayama Hirofumi MZ         if (oldZoom < MAX_ZOOM && getNewZoomRect(rcView, oldZoom * 2))
5998f1eb03aSKatayama Hirofumi MZ             DrawXorRect(hdc, &rcView);
60062eeb158SKatayama Hirofumi MZ     }
60162eeb158SKatayama Hirofumi MZ 
6026d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
603ee132a05SKatayama Hirofumi MZ     {
6048f1eb03aSKatayama Hirofumi MZ         INT newZoom, oldZoom = toolsModel.GetZoom();
605ee132a05SKatayama Hirofumi MZ         if (bLeftButton)
6068f1eb03aSKatayama Hirofumi MZ             newZoom = (oldZoom < MAX_ZOOM) ? (oldZoom * 2) : MIN_ZOOM;
607ee132a05SKatayama Hirofumi MZ         else
6088f1eb03aSKatayama Hirofumi MZ             newZoom = (oldZoom > MIN_ZOOM) ? (oldZoom / 2) : MAX_ZOOM;
6098f1eb03aSKatayama Hirofumi MZ 
6108f1eb03aSKatayama Hirofumi MZ         m_bZoomed = FALSE;
6118f1eb03aSKatayama Hirofumi MZ 
6128f1eb03aSKatayama Hirofumi MZ         if (oldZoom != newZoom)
613ee132a05SKatayama Hirofumi MZ         {
6148f1eb03aSKatayama Hirofumi MZ             CRect rcView;
6158f1eb03aSKatayama Hirofumi MZ             if (getNewZoomRect(rcView, newZoom))
6168f1eb03aSKatayama Hirofumi MZ             {
6178f1eb03aSKatayama Hirofumi MZ                 canvasWindow.zoomTo(newZoom, rcView.left, rcView.top);
6188f1eb03aSKatayama Hirofumi MZ                 m_bZoomed = TRUE;
619ee132a05SKatayama Hirofumi MZ             }
620ee132a05SKatayama Hirofumi MZ         }
6218f1eb03aSKatayama Hirofumi MZ     }
6228f1eb03aSKatayama Hirofumi MZ 
6238f1eb03aSKatayama Hirofumi MZ     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
6248f1eb03aSKatayama Hirofumi MZ     {
6258f1eb03aSKatayama Hirofumi MZ         if (m_bZoomed)
6268f1eb03aSKatayama Hirofumi MZ             toolsModel.SetActiveTool(toolsModel.GetOldActiveTool());
6278f1eb03aSKatayama Hirofumi MZ 
6288f1eb03aSKatayama Hirofumi MZ         return TRUE;
6298f1eb03aSKatayama Hirofumi MZ     }
630ee132a05SKatayama Hirofumi MZ };
631ee132a05SKatayama Hirofumi MZ 
6328f1eb03aSKatayama Hirofumi MZ BOOL ZoomTool::getNewZoomRect(CRect& rcView, INT newZoom)
6338f1eb03aSKatayama Hirofumi MZ {
6348f1eb03aSKatayama Hirofumi MZ     CPoint pt;
6358f1eb03aSKatayama Hirofumi MZ     ::GetCursorPos(&pt);
6368f1eb03aSKatayama Hirofumi MZ     canvasWindow.ScreenToClient(&pt);
6378f1eb03aSKatayama Hirofumi MZ 
6388f1eb03aSKatayama Hirofumi MZ     canvasWindow.getNewZoomRect(rcView, newZoom, pt);
6398f1eb03aSKatayama Hirofumi MZ 
6408f1eb03aSKatayama Hirofumi MZ     CRect rc;
6418f1eb03aSKatayama Hirofumi MZ     canvasWindow.GetImageRect(rc);
6428f1eb03aSKatayama Hirofumi MZ     canvasWindow.ImageToCanvas(rc);
6438f1eb03aSKatayama Hirofumi MZ 
6448f1eb03aSKatayama Hirofumi MZ     return rc.PtInRect(pt);
6458f1eb03aSKatayama Hirofumi MZ }
6468f1eb03aSKatayama Hirofumi MZ 
647ee132a05SKatayama Hirofumi MZ // TOOL_PEN
648e8c7e300SKatayama Hirofumi MZ struct PenTool : SmoothDrawTool
649ee132a05SKatayama Hirofumi MZ {
650e8c7e300SKatayama Hirofumi MZ     PenTool() : SmoothDrawTool(TOOL_PEN)
651ee132a05SKatayama Hirofumi MZ     {
652ee132a05SKatayama Hirofumi MZ     }
653ee132a05SKatayama Hirofumi MZ 
654e5792200SKatayama Hirofumi MZ     void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override
655ee132a05SKatayama Hirofumi MZ     {
656ee132a05SKatayama Hirofumi MZ         COLORREF rgb = bLeftButton ? m_fg : m_bg;
657e5792200SKatayama Hirofumi MZ         Line(hdc, pt0.x, pt0.y, pt1.x, pt1.y, rgb, toolsModel.GetPenWidth());
658f2a01224SKatayama Hirofumi MZ     }
659f2a01224SKatayama Hirofumi MZ 
660f2a01224SKatayama Hirofumi MZ     void OnSpecialTweak(BOOL bMinus) override
661f2a01224SKatayama Hirofumi MZ     {
662f2a01224SKatayama Hirofumi MZ         toolsModel.MakePenThickerOrThinner(bMinus);
663ee132a05SKatayama Hirofumi MZ     }
664ee132a05SKatayama Hirofumi MZ };
665ee132a05SKatayama Hirofumi MZ 
666ee132a05SKatayama Hirofumi MZ // TOOL_BRUSH
667e8c7e300SKatayama Hirofumi MZ struct BrushTool : SmoothDrawTool
668ee132a05SKatayama Hirofumi MZ {
669e8c7e300SKatayama Hirofumi MZ     BrushTool() : SmoothDrawTool(TOOL_BRUSH)
670ee132a05SKatayama Hirofumi MZ     {
671ee132a05SKatayama Hirofumi MZ     }
672ee132a05SKatayama Hirofumi MZ 
673e5792200SKatayama Hirofumi MZ     void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override
674ee132a05SKatayama Hirofumi MZ     {
675ee132a05SKatayama Hirofumi MZ         COLORREF rgb = bLeftButton ? m_fg : m_bg;
676e5792200SKatayama Hirofumi MZ         Brush(hdc, pt0.x, pt0.y, pt1.x, pt1.y, rgb, toolsModel.GetBrushStyle(),
6778a4787b3SKatayama Hirofumi MZ               toolsModel.GetBrushWidth());
678f2a01224SKatayama Hirofumi MZ     }
679f2a01224SKatayama Hirofumi MZ 
680f2a01224SKatayama Hirofumi MZ     void OnSpecialTweak(BOOL bMinus) override
681f2a01224SKatayama Hirofumi MZ     {
6828a4787b3SKatayama Hirofumi MZ         toolsModel.MakeBrushThickerOrThinner(bMinus);
683ee132a05SKatayama Hirofumi MZ     }
684ee132a05SKatayama Hirofumi MZ };
685ee132a05SKatayama Hirofumi MZ 
686ee132a05SKatayama Hirofumi MZ // TOOL_AIRBRUSH
687e8c7e300SKatayama Hirofumi MZ struct AirBrushTool : SmoothDrawTool
688ee132a05SKatayama Hirofumi MZ {
689e5792200SKatayama Hirofumi MZ     DWORD m_dwTick = 0;
690e5792200SKatayama Hirofumi MZ 
691e8c7e300SKatayama Hirofumi MZ     AirBrushTool() : SmoothDrawTool(TOOL_AIRBRUSH)
692ee132a05SKatayama Hirofumi MZ     {
693ee132a05SKatayama Hirofumi MZ     }
694ee132a05SKatayama Hirofumi MZ 
695e5792200SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
696e5792200SKatayama Hirofumi MZ     {
697e5792200SKatayama Hirofumi MZ         m_dwTick = GetTickCount();
698e5792200SKatayama Hirofumi MZ         SmoothDrawTool::OnButtonDown(bLeftButton, x, y, bDoubleClick);
699e5792200SKatayama Hirofumi MZ     }
700e5792200SKatayama Hirofumi MZ 
701e5792200SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
702e5792200SKatayama Hirofumi MZ     {
703e5792200SKatayama Hirofumi MZ         srand(m_dwTick);
704e5792200SKatayama Hirofumi MZ         SmoothDrawTool::OnDrawOverlayOnImage(hdc);
705e5792200SKatayama Hirofumi MZ     }
706e5792200SKatayama Hirofumi MZ 
707e5792200SKatayama Hirofumi MZ     void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override
708ee132a05SKatayama Hirofumi MZ     {
709ee132a05SKatayama Hirofumi MZ         COLORREF rgb = bLeftButton ? m_fg : m_bg;
710e5792200SKatayama Hirofumi MZ         Airbrush(hdc, pt1.x, pt1.y, rgb, toolsModel.GetAirBrushRadius());
711ee132a05SKatayama Hirofumi MZ     }
712945ee4b2SKatayama Hirofumi MZ 
713945ee4b2SKatayama Hirofumi MZ     void OnSpecialTweak(BOOL bMinus) override
714945ee4b2SKatayama Hirofumi MZ     {
715945ee4b2SKatayama Hirofumi MZ         toolsModel.MakeAirBrushThickerOrThinner(bMinus);
716945ee4b2SKatayama Hirofumi MZ     }
717ee132a05SKatayama Hirofumi MZ };
718ee132a05SKatayama Hirofumi MZ 
719ee132a05SKatayama Hirofumi MZ // TOOL_TEXT
720ee132a05SKatayama Hirofumi MZ struct TextTool : ToolBase
721ee132a05SKatayama Hirofumi MZ {
722ee132a05SKatayama Hirofumi MZ     TextTool() : ToolBase(TOOL_TEXT)
723ee132a05SKatayama Hirofumi MZ     {
724ee132a05SKatayama Hirofumi MZ     }
725ee132a05SKatayama Hirofumi MZ 
726e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
727e8c7e300SKatayama Hirofumi MZ     {
728e8c7e300SKatayama Hirofumi MZ         if (canvasWindow.m_drawing)
729e8c7e300SKatayama Hirofumi MZ         {
730*1aeebfdaSKatayama Hirofumi MZ             CRect& rc = selectionModel.m_rc;
731*1aeebfdaSKatayama Hirofumi MZ             if (!rc.IsRectEmpty())
732e8c7e300SKatayama Hirofumi MZ                 RectSel(hdc, rc.left, rc.top, rc.right, rc.bottom);
733e8c7e300SKatayama Hirofumi MZ         }
734e8c7e300SKatayama Hirofumi MZ     }
735e8c7e300SKatayama Hirofumi MZ 
736361a2ce4SKatayama Hirofumi MZ     void UpdatePoint(LONG x, LONG y)
737c2c66affSColin Finck     {
73808397115SKatayama Hirofumi MZ         POINT pt = { x, y };
739d04e0492SKatayama Hirofumi MZ         imageModel.Clamp(pt);
740e8c7e300SKatayama Hirofumi MZ         selectionModel.SetRectFromPoints(g_ptStart, pt);
741e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
742c2c66affSColin Finck     }
743c2c66affSColin Finck 
7446d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
745361a2ce4SKatayama Hirofumi MZ     {
746361a2ce4SKatayama Hirofumi MZ         if (!textEditWindow.IsWindow())
747efe7368cSKatayama Hirofumi MZ             textEditWindow.Create(canvasWindow);
748361a2ce4SKatayama Hirofumi MZ 
749361a2ce4SKatayama Hirofumi MZ         UpdatePoint(x, y);
750361a2ce4SKatayama Hirofumi MZ     }
751361a2ce4SKatayama Hirofumi MZ 
752389d0465SKatayama Hirofumi MZ     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
753361a2ce4SKatayama Hirofumi MZ     {
754361a2ce4SKatayama Hirofumi MZ         UpdatePoint(x, y);
755389d0465SKatayama Hirofumi MZ         return TRUE;
756361a2ce4SKatayama Hirofumi MZ     }
757361a2ce4SKatayama Hirofumi MZ 
758e8c7e300SKatayama Hirofumi MZ     void draw(HDC hdc)
759361a2ce4SKatayama Hirofumi MZ     {
760640d67d1SKatayama Hirofumi MZ         CStringW szText;
761361a2ce4SKatayama Hirofumi MZ         textEditWindow.GetWindowText(szText);
762361a2ce4SKatayama Hirofumi MZ 
763*1aeebfdaSKatayama Hirofumi MZ         CRect rc;
764361a2ce4SKatayama Hirofumi MZ         textEditWindow.InvalidateEditRect();
765361a2ce4SKatayama Hirofumi MZ         textEditWindow.GetEditRect(&rc);
766*1aeebfdaSKatayama Hirofumi MZ         rc.InflateRect(-GRIP_SIZE / 2, -GRIP_SIZE / 2);
767361a2ce4SKatayama Hirofumi MZ 
768bddd8b05SKatayama Hirofumi MZ         // Draw the text
769361a2ce4SKatayama Hirofumi MZ         INT style = (toolsModel.IsBackgroundTransparent() ? 0 : 1);
770e8c7e300SKatayama Hirofumi MZ         Text(hdc, rc.left, rc.top, rc.right, rc.bottom, m_fg, m_bg, szText,
771361a2ce4SKatayama Hirofumi MZ              textEditWindow.GetFont(), style);
772e8c7e300SKatayama Hirofumi MZ     }
773e8c7e300SKatayama Hirofumi MZ 
774e8c7e300SKatayama Hirofumi MZ     void quit()
775e8c7e300SKatayama Hirofumi MZ     {
776e8c7e300SKatayama Hirofumi MZ         if (textEditWindow.IsWindow())
777e8c7e300SKatayama Hirofumi MZ             textEditWindow.ShowWindow(SW_HIDE);
778e8c7e300SKatayama Hirofumi MZ         selectionModel.HideSelection();
779e8c7e300SKatayama Hirofumi MZ     }
780e8c7e300SKatayama Hirofumi MZ 
781389d0465SKatayama Hirofumi MZ     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
782e8c7e300SKatayama Hirofumi MZ     {
783e8c7e300SKatayama Hirofumi MZ         POINT pt = { x, y };
784d04e0492SKatayama Hirofumi MZ         imageModel.Clamp(pt);
785e8c7e300SKatayama Hirofumi MZ         selectionModel.SetRectFromPoints(g_ptStart, pt);
786e8c7e300SKatayama Hirofumi MZ 
787e8c7e300SKatayama Hirofumi MZ         BOOL bTextBoxShown = ::IsWindowVisible(textEditWindow);
7887aadc1e1SKatayama Hirofumi MZ         if (bTextBoxShown)
7897aadc1e1SKatayama Hirofumi MZ         {
7907aadc1e1SKatayama Hirofumi MZ             if (textEditWindow.GetWindowTextLength() > 0)
791e8c7e300SKatayama Hirofumi MZ             {
7929f56e67bSKatayama Hirofumi MZ                 imageModel.PushImageForUndo();
793e8c7e300SKatayama Hirofumi MZ                 draw(m_hdc);
7947aadc1e1SKatayama Hirofumi MZ             }
795*1aeebfdaSKatayama Hirofumi MZ             if (selectionModel.m_rc.IsRectEmpty())
796aac89519SKatayama Hirofumi MZ             {
7979f56e67bSKatayama Hirofumi MZ                 quit();
798389d0465SKatayama Hirofumi MZ                 return TRUE;
799aac89519SKatayama Hirofumi MZ             }
800361a2ce4SKatayama Hirofumi MZ         }
801361a2ce4SKatayama Hirofumi MZ 
802361a2ce4SKatayama Hirofumi MZ         if (registrySettings.ShowTextTool)
803361a2ce4SKatayama Hirofumi MZ         {
804361a2ce4SKatayama Hirofumi MZ             if (!fontsDialog.IsWindow())
805361a2ce4SKatayama Hirofumi MZ                 fontsDialog.Create(mainWindow);
806361a2ce4SKatayama Hirofumi MZ 
807361a2ce4SKatayama Hirofumi MZ             fontsDialog.ShowWindow(SW_SHOWNOACTIVATE);
808361a2ce4SKatayama Hirofumi MZ         }
809361a2ce4SKatayama Hirofumi MZ 
810*1aeebfdaSKatayama Hirofumi MZ         CRect rc = selectionModel.m_rc;
811361a2ce4SKatayama Hirofumi MZ 
812361a2ce4SKatayama Hirofumi MZ         // Enlarge if tool small
813361a2ce4SKatayama Hirofumi MZ         INT cxMin = CX_MINTEXTEDIT, cyMin = CY_MINTEXTEDIT;
814aac89519SKatayama Hirofumi MZ         if (selectionModel.m_rc.IsRectEmpty())
815aac89519SKatayama Hirofumi MZ         {
816*1aeebfdaSKatayama Hirofumi MZ             rc.SetRect(x, y, x + cxMin, y + cyMin);
817aac89519SKatayama Hirofumi MZ         }
818aac89519SKatayama Hirofumi MZ         else
819c2c66affSColin Finck         {
820361a2ce4SKatayama Hirofumi MZ             if (rc.right - rc.left < cxMin)
821361a2ce4SKatayama Hirofumi MZ                 rc.right = rc.left + cxMin;
822361a2ce4SKatayama Hirofumi MZ             if (rc.bottom - rc.top < cyMin)
823361a2ce4SKatayama Hirofumi MZ                 rc.bottom = rc.top + cyMin;
824361a2ce4SKatayama Hirofumi MZ         }
825c2c66affSColin Finck 
826361a2ce4SKatayama Hirofumi MZ         if (!textEditWindow.IsWindow())
827efe7368cSKatayama Hirofumi MZ             textEditWindow.Create(canvasWindow);
828361a2ce4SKatayama Hirofumi MZ 
829361a2ce4SKatayama Hirofumi MZ         textEditWindow.SetWindowText(NULL);
830361a2ce4SKatayama Hirofumi MZ         textEditWindow.ValidateEditRect(&rc);
831361a2ce4SKatayama Hirofumi MZ         textEditWindow.ShowWindow(SW_SHOWNOACTIVATE);
832361a2ce4SKatayama Hirofumi MZ         textEditWindow.SetFocus();
833389d0465SKatayama Hirofumi MZ         return TRUE;
834361a2ce4SKatayama Hirofumi MZ     }
835ee132a05SKatayama Hirofumi MZ 
83637f56d24SKatayama Hirofumi MZ     void OnEndDraw(BOOL bCancel) override
83737f56d24SKatayama Hirofumi MZ     {
83837f56d24SKatayama Hirofumi MZ         if (!bCancel)
839ee132a05SKatayama Hirofumi MZ         {
8403579ea78SKatayama Hirofumi MZ             if (::IsWindowVisible(textEditWindow) &&
8413579ea78SKatayama Hirofumi MZ                 textEditWindow.GetWindowTextLength() > 0)
8427aadc1e1SKatayama Hirofumi MZ             {
8439f56e67bSKatayama Hirofumi MZ                 imageModel.PushImageForUndo();
844e8c7e300SKatayama Hirofumi MZ                 draw(m_hdc);
8457aadc1e1SKatayama Hirofumi MZ             }
846c2c66affSColin Finck         }
847e8c7e300SKatayama Hirofumi MZ         quit();
84837f56d24SKatayama Hirofumi MZ         ToolBase::OnEndDraw(bCancel);
849e8c7e300SKatayama Hirofumi MZ     }
850ee132a05SKatayama Hirofumi MZ };
851ee132a05SKatayama Hirofumi MZ 
852ee132a05SKatayama Hirofumi MZ // TOOL_LINE
853e8c7e300SKatayama Hirofumi MZ struct LineTool : TwoPointDrawTool
854c2c66affSColin Finck {
855e8c7e300SKatayama Hirofumi MZ     LineTool() : TwoPointDrawTool(TOOL_LINE)
856c2c66affSColin Finck     {
857c2c66affSColin Finck     }
858ee132a05SKatayama Hirofumi MZ 
859e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
860ee132a05SKatayama Hirofumi MZ     {
861e8c7e300SKatayama Hirofumi MZ         if (!m_bDrawing)
862e8c7e300SKatayama Hirofumi MZ             return;
863c2c66affSColin Finck         if (GetAsyncKeyState(VK_SHIFT) < 0)
864e8c7e300SKatayama Hirofumi MZ             roundTo8Directions(g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y);
865e8c7e300SKatayama Hirofumi MZ         COLORREF rgb = m_bLeftButton ? m_fg : m_bg;
866e8c7e300SKatayama Hirofumi MZ         Line(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, rgb, toolsModel.GetLineWidth());
867ee132a05SKatayama Hirofumi MZ     }
868ee132a05SKatayama Hirofumi MZ };
869ee132a05SKatayama Hirofumi MZ 
870ee132a05SKatayama Hirofumi MZ // TOOL_BEZIER
871ee132a05SKatayama Hirofumi MZ struct BezierTool : ToolBase
872c2c66affSColin Finck {
873e8c7e300SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
87408397115SKatayama Hirofumi MZ 
875e8c7e300SKatayama Hirofumi MZ     BezierTool() : ToolBase(TOOL_BEZIER)
876c2c66affSColin Finck     {
877c2c66affSColin Finck     }
878c2c66affSColin Finck 
879e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc)
880c2c66affSColin Finck     {
881e8c7e300SKatayama Hirofumi MZ         COLORREF rgb = (m_bLeftButton ? m_fg : m_bg);
882ec53d422SKatayama Hirofumi MZ         switch (s_pointSP)
883c2c66affSColin Finck         {
884e5792200SKatayama Hirofumi MZ             case 2:
885ec53d422SKatayama Hirofumi MZ                 Line(hdc, s_pointStack[0].x, s_pointStack[0].y, s_pointStack[1].x, s_pointStack[1].y, rgb,
886c2c66affSColin Finck                      toolsModel.GetLineWidth());
887c2c66affSColin Finck                 break;
888e5792200SKatayama Hirofumi MZ             case 3:
889ec53d422SKatayama Hirofumi MZ                 Bezier(hdc, s_pointStack[0], s_pointStack[2], s_pointStack[2], s_pointStack[1], rgb, toolsModel.GetLineWidth());
890c2c66affSColin Finck                 break;
891e5792200SKatayama Hirofumi MZ             case 4:
892ec53d422SKatayama Hirofumi MZ                 Bezier(hdc, s_pointStack[0], s_pointStack[2], s_pointStack[3], s_pointStack[1], rgb, toolsModel.GetLineWidth());
893c2c66affSColin Finck                 break;
894c2c66affSColin Finck         }
895ee132a05SKatayama Hirofumi MZ     }
896ee132a05SKatayama Hirofumi MZ 
8976d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
898ee132a05SKatayama Hirofumi MZ     {
899e8c7e300SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
900e8c7e300SKatayama Hirofumi MZ 
901e5792200SKatayama Hirofumi MZ         if (s_pointSP == 0)
902e8c7e300SKatayama Hirofumi MZ         {
903e5792200SKatayama Hirofumi MZ             pushToPtStack(x, y);
904e5792200SKatayama Hirofumi MZ             pushToPtStack(x, y);
905e8c7e300SKatayama Hirofumi MZ         }
906e8c7e300SKatayama Hirofumi MZ         else
907e8c7e300SKatayama Hirofumi MZ         {
908e5792200SKatayama Hirofumi MZ             s_pointStack[s_pointSP - 1] = { x, y };
909ee132a05SKatayama Hirofumi MZ         }
910e8c7e300SKatayama Hirofumi MZ 
911e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
912ee132a05SKatayama Hirofumi MZ     }
913ee132a05SKatayama Hirofumi MZ 
914389d0465SKatayama Hirofumi MZ     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
915ee132a05SKatayama Hirofumi MZ     {
916e5792200SKatayama Hirofumi MZ         if (s_pointSP > 0)
917e5792200SKatayama Hirofumi MZ             s_pointStack[s_pointSP - 1] = { x, y };
918e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
919389d0465SKatayama Hirofumi MZ         return TRUE;
920c2c66affSColin Finck     }
921c2c66affSColin Finck 
922389d0465SKatayama Hirofumi MZ     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
923c2c66affSColin Finck     {
924e5792200SKatayama Hirofumi MZ         if (s_pointSP >= 4)
925e8c7e300SKatayama Hirofumi MZ         {
92637f56d24SKatayama Hirofumi MZ             OnEndDraw(FALSE);
927389d0465SKatayama Hirofumi MZ             return TRUE;
928e8c7e300SKatayama Hirofumi MZ         }
929e5792200SKatayama Hirofumi MZ         pushToPtStack(x, y);
930bfd42c67SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
931389d0465SKatayama Hirofumi MZ         return TRUE;
932ee132a05SKatayama Hirofumi MZ     }
933ee132a05SKatayama Hirofumi MZ 
93437f56d24SKatayama Hirofumi MZ     void OnEndDraw(BOOL bCancel) override
935ee132a05SKatayama Hirofumi MZ     {
936e5792200SKatayama Hirofumi MZ         if (!bCancel && s_pointSP > 1)
93708397115SKatayama Hirofumi MZ         {
938e5792200SKatayama Hirofumi MZ             // FIXME: I couldn't calculate boundary rectangle from Bezier curve
939e8c7e300SKatayama Hirofumi MZ             imageModel.PushImageForUndo();
940e8c7e300SKatayama Hirofumi MZ             OnDrawOverlayOnImage(m_hdc);
94137f56d24SKatayama Hirofumi MZ         }
94237f56d24SKatayama Hirofumi MZ         ToolBase::OnEndDraw(bCancel);
94308397115SKatayama Hirofumi MZ     }
944f2a01224SKatayama Hirofumi MZ 
945f2a01224SKatayama Hirofumi MZ     void OnSpecialTweak(BOOL bMinus) override
946f2a01224SKatayama Hirofumi MZ     {
947f2a01224SKatayama Hirofumi MZ         toolsModel.MakeLineThickerOrThinner(bMinus);
948f2a01224SKatayama Hirofumi MZ     }
949ee132a05SKatayama Hirofumi MZ };
950ee132a05SKatayama Hirofumi MZ 
951ee132a05SKatayama Hirofumi MZ // TOOL_RECT
952e8c7e300SKatayama Hirofumi MZ struct RectTool : TwoPointDrawTool
953ee132a05SKatayama Hirofumi MZ {
954e8c7e300SKatayama Hirofumi MZ     RectTool() : TwoPointDrawTool(TOOL_RECT)
955ee132a05SKatayama Hirofumi MZ     {
956ee132a05SKatayama Hirofumi MZ     }
957ee132a05SKatayama Hirofumi MZ 
958e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
959ee132a05SKatayama Hirofumi MZ     {
960e8c7e300SKatayama Hirofumi MZ         if (!m_bDrawing)
961e8c7e300SKatayama Hirofumi MZ             return;
962c2c66affSColin Finck         if (GetAsyncKeyState(VK_SHIFT) < 0)
963e8c7e300SKatayama Hirofumi MZ             regularize(g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y);
964e8c7e300SKatayama Hirofumi MZ         if (m_bLeftButton)
965e8c7e300SKatayama Hirofumi MZ             Rect(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
966ee132a05SKatayama Hirofumi MZ         else
967e8c7e300SKatayama Hirofumi MZ             Rect(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
968ee132a05SKatayama Hirofumi MZ     }
969ee132a05SKatayama Hirofumi MZ };
970ee132a05SKatayama Hirofumi MZ 
971ee132a05SKatayama Hirofumi MZ // TOOL_SHAPE
972ee132a05SKatayama Hirofumi MZ struct ShapeTool : ToolBase
973ee132a05SKatayama Hirofumi MZ {
974e8c7e300SKatayama Hirofumi MZ     BOOL m_bLeftButton = FALSE;
975e8c7e300SKatayama Hirofumi MZ     BOOL m_bClosed = FALSE;
97608397115SKatayama Hirofumi MZ 
977e8c7e300SKatayama Hirofumi MZ     ShapeTool() : ToolBase(TOOL_SHAPE)
978ee132a05SKatayama Hirofumi MZ     {
979ee132a05SKatayama Hirofumi MZ     }
980ee132a05SKatayama Hirofumi MZ 
981e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc)
982ee132a05SKatayama Hirofumi MZ     {
983ec53d422SKatayama Hirofumi MZ         if (s_pointSP <= 0)
984e8c7e300SKatayama Hirofumi MZ             return;
985e8c7e300SKatayama Hirofumi MZ 
986e8c7e300SKatayama Hirofumi MZ         if (m_bLeftButton)
987e5792200SKatayama Hirofumi MZ             Poly(hdc, s_pointStack, s_pointSP, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE);
988ee132a05SKatayama Hirofumi MZ         else
989e5792200SKatayama Hirofumi MZ             Poly(hdc, s_pointStack, s_pointSP, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), m_bClosed, FALSE);
990ee132a05SKatayama Hirofumi MZ     }
991ee132a05SKatayama Hirofumi MZ 
9926d9b7f77SKatayama Hirofumi MZ     void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
993ee132a05SKatayama Hirofumi MZ     {
994e8c7e300SKatayama Hirofumi MZ         m_bLeftButton = bLeftButton;
995e8c7e300SKatayama Hirofumi MZ         m_bClosed = FALSE;
996e8c7e300SKatayama Hirofumi MZ 
997ec53d422SKatayama Hirofumi MZ         if ((s_pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
998ec53d422SKatayama Hirofumi MZ             roundTo8Directions(s_pointStack[s_pointSP - 1].x, s_pointStack[s_pointSP - 1].y, x, y);
9993fa6d74aSKatayama Hirofumi MZ 
1000e5792200SKatayama Hirofumi MZ         pushToPtStack(x, y);
1001ee132a05SKatayama Hirofumi MZ 
1002e5792200SKatayama Hirofumi MZ         if (s_pointSP > 1 && bDoubleClick)
1003ee132a05SKatayama Hirofumi MZ         {
100437f56d24SKatayama Hirofumi MZ             OnEndDraw(FALSE);
1005e8c7e300SKatayama Hirofumi MZ             return;
1006e8c7e300SKatayama Hirofumi MZ         }
1007e8c7e300SKatayama Hirofumi MZ 
1008e5792200SKatayama Hirofumi MZ         if (s_pointSP == 1)
1009e5792200SKatayama Hirofumi MZ             pushToPtStack(x, y); // We have to draw the first point
1010e8c7e300SKatayama Hirofumi MZ 
1011bfd42c67SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
1012ee132a05SKatayama Hirofumi MZ     }
1013ee132a05SKatayama Hirofumi MZ 
1014389d0465SKatayama Hirofumi MZ     BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
1015ee132a05SKatayama Hirofumi MZ     {
1016e5792200SKatayama Hirofumi MZ         if (s_pointSP > 1)
1017e5792200SKatayama Hirofumi MZ         {
1018e5792200SKatayama Hirofumi MZ             if (GetAsyncKeyState(VK_SHIFT) < 0)
1019e5792200SKatayama Hirofumi MZ                 roundTo8Directions(s_pointStack[s_pointSP - 2].x, s_pointStack[s_pointSP - 2].y, x, y);
1020e8c7e300SKatayama Hirofumi MZ 
1021e5792200SKatayama Hirofumi MZ             s_pointStack[s_pointSP - 1] = { x, y };
1022e5792200SKatayama Hirofumi MZ         }
10233fa6d74aSKatayama Hirofumi MZ 
1024e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
1025389d0465SKatayama Hirofumi MZ         return TRUE;
1026ee132a05SKatayama Hirofumi MZ     }
1027ee132a05SKatayama Hirofumi MZ 
1028389d0465SKatayama Hirofumi MZ     BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
1029c2c66affSColin Finck     {
1030e5792200SKatayama Hirofumi MZ         if ((s_pointSP > 1) && (GetAsyncKeyState(VK_SHIFT) < 0))
1031e5792200SKatayama Hirofumi MZ             roundTo8Directions(s_pointStack[s_pointSP - 2].x, s_pointStack[s_pointSP - 2].y, x, y);
1032ee132a05SKatayama Hirofumi MZ 
1033e8c7e300SKatayama Hirofumi MZ         m_bClosed = FALSE;
1034ec53d422SKatayama Hirofumi MZ         if (nearlyEqualPoints(x, y, s_pointStack[0].x, s_pointStack[0].y))
1035c2c66affSColin Finck         {
103637f56d24SKatayama Hirofumi MZ             OnEndDraw(FALSE);
1037389d0465SKatayama Hirofumi MZ             return TRUE;
1038c2c66affSColin Finck         }
1039ee132a05SKatayama Hirofumi MZ 
1040e5792200SKatayama Hirofumi MZ         pushToPtStack(x, y);
1041e8c7e300SKatayama Hirofumi MZ         imageModel.NotifyImageChanged();
1042389d0465SKatayama Hirofumi MZ         return TRUE;
1043c2c66affSColin Finck     }
1044ee132a05SKatayama Hirofumi MZ 
104537f56d24SKatayama Hirofumi MZ     void OnEndDraw(BOOL bCancel) override
1046ee132a05SKatayama Hirofumi MZ     {
1047e5792200SKatayama Hirofumi MZ         if (!bCancel && s_pointSP > 1)
104808397115SKatayama Hirofumi MZ         {
1049e5792200SKatayama Hirofumi MZ             CRect rcPartial;
1050e5792200SKatayama Hirofumi MZ             getBoundaryOfPtStack(rcPartial, s_pointSP, s_pointStack);
1051e8c7e300SKatayama Hirofumi MZ 
1052e5792200SKatayama Hirofumi MZ             SIZE size = toolsModel.GetToolSize();
1053e5792200SKatayama Hirofumi MZ             rcPartial.InflateRect((size.cx + 1) / 2, (size.cy + 1) / 2);
1054e5792200SKatayama Hirofumi MZ 
1055e5792200SKatayama Hirofumi MZ             imageModel.PushImageForUndo(rcPartial);
1056e5792200SKatayama Hirofumi MZ 
1057e5792200SKatayama Hirofumi MZ             m_bClosed = TRUE;
1058e8c7e300SKatayama Hirofumi MZ             OnDrawOverlayOnImage(m_hdc);
105908397115SKatayama Hirofumi MZ         }
1060e8c7e300SKatayama Hirofumi MZ         m_bClosed = FALSE;
106137f56d24SKatayama Hirofumi MZ         ToolBase::OnEndDraw(bCancel);
106208397115SKatayama Hirofumi MZ     }
1063f2a01224SKatayama Hirofumi MZ 
1064f2a01224SKatayama Hirofumi MZ     void OnSpecialTweak(BOOL bMinus) override
1065f2a01224SKatayama Hirofumi MZ     {
1066f2a01224SKatayama Hirofumi MZ         toolsModel.MakeLineThickerOrThinner(bMinus);
1067f2a01224SKatayama Hirofumi MZ     }
1068ee132a05SKatayama Hirofumi MZ };
1069ee132a05SKatayama Hirofumi MZ 
1070ee132a05SKatayama Hirofumi MZ // TOOL_ELLIPSE
1071e8c7e300SKatayama Hirofumi MZ struct EllipseTool : TwoPointDrawTool
1072ee132a05SKatayama Hirofumi MZ {
1073e8c7e300SKatayama Hirofumi MZ     EllipseTool() : TwoPointDrawTool(TOOL_ELLIPSE)
1074ee132a05SKatayama Hirofumi MZ     {
1075ee132a05SKatayama Hirofumi MZ     }
1076ee132a05SKatayama Hirofumi MZ 
1077e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
1078ee132a05SKatayama Hirofumi MZ     {
1079e8c7e300SKatayama Hirofumi MZ         if (!m_bDrawing)
1080e8c7e300SKatayama Hirofumi MZ             return;
1081ee132a05SKatayama Hirofumi MZ         if (GetAsyncKeyState(VK_SHIFT) < 0)
1082e8c7e300SKatayama Hirofumi MZ             regularize(g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y);
1083e8c7e300SKatayama Hirofumi MZ         if (m_bLeftButton)
1084e8c7e300SKatayama Hirofumi MZ             Ellp(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
1085ee132a05SKatayama Hirofumi MZ         else
1086e8c7e300SKatayama Hirofumi MZ             Ellp(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
1087ee132a05SKatayama Hirofumi MZ     }
1088ee132a05SKatayama Hirofumi MZ };
1089ee132a05SKatayama Hirofumi MZ 
1090ee132a05SKatayama Hirofumi MZ // TOOL_RRECT
1091e8c7e300SKatayama Hirofumi MZ struct RRectTool : TwoPointDrawTool
1092ee132a05SKatayama Hirofumi MZ {
1093e8c7e300SKatayama Hirofumi MZ     RRectTool() : TwoPointDrawTool(TOOL_RRECT)
1094ee132a05SKatayama Hirofumi MZ     {
1095ee132a05SKatayama Hirofumi MZ     }
1096ee132a05SKatayama Hirofumi MZ 
1097e8c7e300SKatayama Hirofumi MZ     void OnDrawOverlayOnImage(HDC hdc) override
1098ee132a05SKatayama Hirofumi MZ     {
1099e8c7e300SKatayama Hirofumi MZ         if (!m_bDrawing)
1100e8c7e300SKatayama Hirofumi MZ             return;
1101ee132a05SKatayama Hirofumi MZ         if (GetAsyncKeyState(VK_SHIFT) < 0)
1102e8c7e300SKatayama Hirofumi MZ             regularize(g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y);
1103e8c7e300SKatayama Hirofumi MZ         if (m_bLeftButton)
1104e8c7e300SKatayama Hirofumi MZ             RRect(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_fg, m_bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
1105ee132a05SKatayama Hirofumi MZ         else
1106e8c7e300SKatayama Hirofumi MZ             RRect(hdc, g_ptStart.x, g_ptStart.y, g_ptEnd.x, g_ptEnd.y, m_bg, m_fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
1107ee132a05SKatayama Hirofumi MZ     }
1108ee132a05SKatayama Hirofumi MZ };
1109ee132a05SKatayama Hirofumi MZ 
1110ee132a05SKatayama Hirofumi MZ /*static*/ ToolBase*
1111ee132a05SKatayama Hirofumi MZ ToolBase::createToolObject(TOOLTYPE type)
1112ee132a05SKatayama Hirofumi MZ {
1113ee132a05SKatayama Hirofumi MZ     switch (type)
1114ee132a05SKatayama Hirofumi MZ     {
1115ee132a05SKatayama Hirofumi MZ         case TOOL_FREESEL:  return new FreeSelTool();
1116ee132a05SKatayama Hirofumi MZ         case TOOL_RECTSEL:  return new RectSelTool();
1117ee132a05SKatayama Hirofumi MZ         case TOOL_RUBBER:   return new RubberTool();
1118ee132a05SKatayama Hirofumi MZ         case TOOL_FILL:     return new FillTool();
1119ee132a05SKatayama Hirofumi MZ         case TOOL_COLOR:    return new ColorTool();
1120ee132a05SKatayama Hirofumi MZ         case TOOL_ZOOM:     return new ZoomTool();
1121ee132a05SKatayama Hirofumi MZ         case TOOL_PEN:      return new PenTool();
1122ee132a05SKatayama Hirofumi MZ         case TOOL_BRUSH:    return new BrushTool();
1123ee132a05SKatayama Hirofumi MZ         case TOOL_AIRBRUSH: return new AirBrushTool();
1124ee132a05SKatayama Hirofumi MZ         case TOOL_TEXT:     return new TextTool();
1125ee132a05SKatayama Hirofumi MZ         case TOOL_LINE:     return new LineTool();
1126ee132a05SKatayama Hirofumi MZ         case TOOL_BEZIER:   return new BezierTool();
1127ee132a05SKatayama Hirofumi MZ         case TOOL_RECT:     return new RectTool();
1128ee132a05SKatayama Hirofumi MZ         case TOOL_SHAPE:    return new ShapeTool();
1129ee132a05SKatayama Hirofumi MZ         case TOOL_ELLIPSE:  return new EllipseTool();
1130ee132a05SKatayama Hirofumi MZ         case TOOL_RRECT:    return new RRectTool();
1131ee132a05SKatayama Hirofumi MZ     }
1132ee132a05SKatayama Hirofumi MZ     UNREACHABLE;
1133ee132a05SKatayama Hirofumi MZ     return NULL;
1134c2c66affSColin Finck }
1135fa4b38d9SKatayama Hirofumi MZ 
1136fa4b38d9SKatayama Hirofumi MZ void ToolsModel::OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
1137fa4b38d9SKatayama Hirofumi MZ {
1138fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->beginEvent();
1139e5792200SKatayama Hirofumi MZ     g_ptEnd = g_ptStart = { x, y };
1140fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->OnButtonDown(bLeftButton, x, y, bDoubleClick);
1141fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->endEvent();
1142fa4b38d9SKatayama Hirofumi MZ }
1143fa4b38d9SKatayama Hirofumi MZ 
1144fa4b38d9SKatayama Hirofumi MZ void ToolsModel::OnMouseMove(BOOL bLeftButton, LONG x, LONG y)
1145fa4b38d9SKatayama Hirofumi MZ {
1146fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->beginEvent();
1147fa4b38d9SKatayama Hirofumi MZ     if (m_pToolObject->OnMouseMove(bLeftButton, x, y))
1148e5792200SKatayama Hirofumi MZ         g_ptEnd = { x, y };
1149e5792200SKatayama Hirofumi MZ 
1150fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->endEvent();
1151fa4b38d9SKatayama Hirofumi MZ }
1152fa4b38d9SKatayama Hirofumi MZ 
1153fa4b38d9SKatayama Hirofumi MZ void ToolsModel::OnButtonUp(BOOL bLeftButton, LONG x, LONG y)
1154fa4b38d9SKatayama Hirofumi MZ {
1155fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->beginEvent();
1156fa4b38d9SKatayama Hirofumi MZ     if (m_pToolObject->OnButtonUp(bLeftButton, x, y))
1157e5792200SKatayama Hirofumi MZ         g_ptEnd = { x, y };
1158e5792200SKatayama Hirofumi MZ 
1159fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->endEvent();
1160fa4b38d9SKatayama Hirofumi MZ }
1161fa4b38d9SKatayama Hirofumi MZ 
1162fa4b38d9SKatayama Hirofumi MZ void ToolsModel::OnEndDraw(BOOL bCancel)
1163fa4b38d9SKatayama Hirofumi MZ {
1164fa4b38d9SKatayama Hirofumi MZ     ATLTRACE("ToolsModel::OnEndDraw(%d)\n", bCancel);
1165fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->beginEvent();
1166fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->OnEndDraw(bCancel);
1167fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->endEvent();
1168fa4b38d9SKatayama Hirofumi MZ }
1169fa4b38d9SKatayama Hirofumi MZ 
1170fa4b38d9SKatayama Hirofumi MZ void ToolsModel::OnDrawOverlayOnImage(HDC hdc)
1171fa4b38d9SKatayama Hirofumi MZ {
1172fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->OnDrawOverlayOnImage(hdc);
1173fa4b38d9SKatayama Hirofumi MZ }
1174fa4b38d9SKatayama Hirofumi MZ 
1175fa4b38d9SKatayama Hirofumi MZ void ToolsModel::OnDrawOverlayOnCanvas(HDC hdc)
1176fa4b38d9SKatayama Hirofumi MZ {
1177fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->OnDrawOverlayOnCanvas(hdc);
1178fa4b38d9SKatayama Hirofumi MZ }
1179fa4b38d9SKatayama Hirofumi MZ 
1180fa4b38d9SKatayama Hirofumi MZ void ToolsModel::SpecialTweak(BOOL bMinus)
1181fa4b38d9SKatayama Hirofumi MZ {
1182fa4b38d9SKatayama Hirofumi MZ     m_pToolObject->OnSpecialTweak(bMinus);
1183fa4b38d9SKatayama Hirofumi MZ }
1184fa4b38d9SKatayama Hirofumi MZ 
1185fa4b38d9SKatayama Hirofumi MZ void ToolsModel::DrawWithMouseTool(POINT pt, WPARAM wParam)
1186fa4b38d9SKatayama Hirofumi MZ {
1187fa4b38d9SKatayama Hirofumi MZ     LONG xRel = pt.x - g_ptStart.x, yRel = pt.y - g_ptStart.y;
1188fa4b38d9SKatayama Hirofumi MZ 
1189fa4b38d9SKatayama Hirofumi MZ     switch (m_activeTool)
1190fa4b38d9SKatayama Hirofumi MZ     {
1191fa4b38d9SKatayama Hirofumi MZ         // freesel, rectsel and text tools always show numbers limited to fit into image area
1192fa4b38d9SKatayama Hirofumi MZ         case TOOL_FREESEL:
1193fa4b38d9SKatayama Hirofumi MZ         case TOOL_RECTSEL:
1194fa4b38d9SKatayama Hirofumi MZ         case TOOL_TEXT:
1195fa4b38d9SKatayama Hirofumi MZ             if (xRel < 0)
1196fa4b38d9SKatayama Hirofumi MZ                 xRel = (pt.x < 0) ? -g_ptStart.x : xRel;
1197fa4b38d9SKatayama Hirofumi MZ             else if (pt.x > imageModel.GetWidth())
1198fa4b38d9SKatayama Hirofumi MZ                 xRel = imageModel.GetWidth() - g_ptStart.x;
1199fa4b38d9SKatayama Hirofumi MZ             if (yRel < 0)
1200fa4b38d9SKatayama Hirofumi MZ                 yRel = (pt.y < 0) ? -g_ptStart.y : yRel;
1201fa4b38d9SKatayama Hirofumi MZ             else if (pt.y > imageModel.GetHeight())
1202fa4b38d9SKatayama Hirofumi MZ                 yRel = imageModel.GetHeight() - g_ptStart.y;
1203fa4b38d9SKatayama Hirofumi MZ             break;
1204fa4b38d9SKatayama Hirofumi MZ 
1205fa4b38d9SKatayama Hirofumi MZ         // while drawing, update cursor coordinates only for tools 3, 7, 8, 9, 14
1206fa4b38d9SKatayama Hirofumi MZ         case TOOL_RUBBER:
1207fa4b38d9SKatayama Hirofumi MZ         case TOOL_PEN:
1208fa4b38d9SKatayama Hirofumi MZ         case TOOL_BRUSH:
1209fa4b38d9SKatayama Hirofumi MZ         case TOOL_AIRBRUSH:
1210fa4b38d9SKatayama Hirofumi MZ         case TOOL_SHAPE:
1211fa4b38d9SKatayama Hirofumi MZ         {
1212fa4b38d9SKatayama Hirofumi MZ             CStringW strCoord;
1213fa4b38d9SKatayama Hirofumi MZ             strCoord.Format(L"%ld, %ld", pt.x, pt.y);
1214fa4b38d9SKatayama Hirofumi MZ             ::SendMessageW(g_hStatusBar, SB_SETTEXT, 1, (LPARAM)(LPCWSTR)strCoord);
1215fa4b38d9SKatayama Hirofumi MZ             break;
1216fa4b38d9SKatayama Hirofumi MZ         }
1217fa4b38d9SKatayama Hirofumi MZ         default:
1218fa4b38d9SKatayama Hirofumi MZ             break;
1219fa4b38d9SKatayama Hirofumi MZ     }
1220fa4b38d9SKatayama Hirofumi MZ 
1221fa4b38d9SKatayama Hirofumi MZ     // rectsel and shape tools always show non-negative numbers when drawing
1222fa4b38d9SKatayama Hirofumi MZ     if (m_activeTool == TOOL_RECTSEL || m_activeTool == TOOL_SHAPE)
1223fa4b38d9SKatayama Hirofumi MZ     {
1224fa4b38d9SKatayama Hirofumi MZ         xRel = labs(xRel);
1225fa4b38d9SKatayama Hirofumi MZ         yRel = labs(yRel);
1226fa4b38d9SKatayama Hirofumi MZ     }
1227fa4b38d9SKatayama Hirofumi MZ 
1228fa4b38d9SKatayama Hirofumi MZ     if (wParam & MK_LBUTTON)
1229fa4b38d9SKatayama Hirofumi MZ     {
1230fa4b38d9SKatayama Hirofumi MZ         OnMouseMove(TRUE, pt.x, pt.y);
1231fa4b38d9SKatayama Hirofumi MZ         canvasWindow.Invalidate(FALSE);
1232fa4b38d9SKatayama Hirofumi MZ         if ((m_activeTool >= TOOL_TEXT) || IsSelection())
1233fa4b38d9SKatayama Hirofumi MZ         {
1234fa4b38d9SKatayama Hirofumi MZ             CStringW strSize;
1235fa4b38d9SKatayama Hirofumi MZ             if ((m_activeTool >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0))
1236fa4b38d9SKatayama Hirofumi MZ                 yRel = xRel;
1237fa4b38d9SKatayama Hirofumi MZ             strSize.Format(L"%ld x %ld", xRel, yRel);
1238fa4b38d9SKatayama Hirofumi MZ             ::SendMessageW(g_hStatusBar, SB_SETTEXT, 2, (LPARAM)(LPCWSTR)strSize);
1239fa4b38d9SKatayama Hirofumi MZ         }
1240fa4b38d9SKatayama Hirofumi MZ     }
1241fa4b38d9SKatayama Hirofumi MZ 
1242fa4b38d9SKatayama Hirofumi MZ     if (wParam & MK_RBUTTON)
1243fa4b38d9SKatayama Hirofumi MZ     {
1244fa4b38d9SKatayama Hirofumi MZ         OnMouseMove(FALSE, pt.x, pt.y);
1245fa4b38d9SKatayama Hirofumi MZ         canvasWindow.Invalidate(FALSE);
1246fa4b38d9SKatayama Hirofumi MZ         if (m_activeTool >= TOOL_TEXT)
1247fa4b38d9SKatayama Hirofumi MZ         {
1248fa4b38d9SKatayama Hirofumi MZ             CStringW strSize;
1249fa4b38d9SKatayama Hirofumi MZ             if ((m_activeTool >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0))
1250fa4b38d9SKatayama Hirofumi MZ                 yRel = xRel;
1251fa4b38d9SKatayama Hirofumi MZ             strSize.Format(L"%ld x %ld", xRel, yRel);
1252fa4b38d9SKatayama Hirofumi MZ             ::SendMessageW(g_hStatusBar, SB_SETTEXT, 2, (LPARAM)(LPCWSTR)strSize);
1253fa4b38d9SKatayama Hirofumi MZ         }
1254fa4b38d9SKatayama Hirofumi MZ     }
1255fa4b38d9SKatayama Hirofumi MZ }
1256