https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f710e5a260d77985394244e98aa57b3f5063c762

commit f710e5a260d77985394244e98aa57b3f5063c762
Author:     Katayama Hirofumi MZ <[email protected]>
AuthorDate: Fri Nov 24 15:44:16 2023 +0900
Commit:     GitHub <[email protected]>
CommitDate: Fri Nov 24 15:44:16 2023 +0900

    [MSPAINT] Define SelectionBaseTool and use it (#6034)
    
    Refactoring and arrangement for selection handling.
    - Move some selection-related codes in canvas.cpp to mouse.cpp.
    - Add SelectionBaseTool structure for FreeSelTool and RectSelTool.
    CORE-19094
---
 base/applications/mspaint/canvas.cpp       |  72 +-----
 base/applications/mspaint/canvas.h         |   5 -
 base/applications/mspaint/main.cpp         |  30 +--
 base/applications/mspaint/mouse.cpp        | 366 ++++++++++++++++-------------
 base/applications/mspaint/selectionmodel.h |   1 -
 5 files changed, 212 insertions(+), 262 deletions(-)

diff --git a/base/applications/mspaint/canvas.cpp 
b/base/applications/mspaint/canvas.cpp
index cf529e0f67d..fa6201cdf21 100644
--- a/base/applications/mspaint/canvas.cpp
+++ b/base/applications/mspaint/canvas.cpp
@@ -13,7 +13,6 @@ CCanvasWindow canvasWindow;
 
 CCanvasWindow::CCanvasWindow()
     : m_drawing(FALSE)
-    , m_hitSelection(HIT_NONE)
     , m_hitCanvasSizeBox(HIT_NONE)
     , m_ptOrig { -1, -1 }
 {
@@ -316,25 +315,11 @@ LRESULT CCanvasWindow::OnButtonDown(UINT nMsg, WPARAM 
wParam, LPARAM lParam, BOO
     HITTEST hitSelection = selectionModel.hitTest(pt);
     if (hitSelection != HIT_NONE)
     {
-        selectionModel.m_nSelectionBrush = 0; // Selection Brush is OFF
-        if (bLeftButton)
-        {
-            CanvasToImage(pt);
-            if (::GetKeyState(VK_CONTROL) < 0) // Ctrl+Click is Selection Clone
-            {
-                imageModel.SelectionClone();
-            }
-            else if (::GetKeyState(VK_SHIFT) < 0) // Shift+Dragging is 
Selection Brush
-            {
-                selectionModel.m_nSelectionBrush = 1; // Selection Brush is ON
-            }
-            StartSelectionDrag(hitSelection, pt);
-        }
-        else
-        {
-            ClientToScreen(&pt);
-            mainWindow.TrackPopupMenu(pt, 0);
-        }
+        m_drawing = TRUE;
+        CanvasToImage(pt);
+        SetCapture();
+        toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, FALSE);
+        Invalidate();
         return 0;
     }
 
@@ -370,7 +355,7 @@ LRESULT CCanvasWindow::OnButtonDown(UINT nMsg, WPARAM 
wParam, LPARAM lParam, BOO
         m_drawing = TRUE;
         SetCapture();
         toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, FALSE);
-        Invalidate(FALSE);
+        Invalidate();
         return 0;
     }
 
@@ -395,7 +380,7 @@ LRESULT CCanvasWindow::OnButtonDblClk(UINT nMsg, WPARAM 
wParam, LPARAM lParam, B
 
     toolsModel.OnButtonDown(nMsg == WM_LBUTTONDBLCLK, pt.x, pt.y, TRUE);
     toolsModel.resetTool();
-    Invalidate(FALSE);
+    Invalidate();
     return 0;
 }
 
@@ -418,12 +403,6 @@ LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM 
wParam, LPARAM lParam, BOOL
     if (toolsModel.GetActiveTool() == TOOL_ZOOM)
         Invalidate();
 
-    if (m_hitSelection != HIT_NONE)
-    {
-        SelectionDragging(pt);
-        return 0;
-    }
-
     if (!m_drawing || toolsModel.GetActiveTool() <= TOOL_AIRBRUSH)
     {
         TRACKMOUSEEVENT tme = { sizeof(tme) };
@@ -444,7 +423,7 @@ LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM 
wParam, LPARAM lParam, BOOL
         }
     }
 
-    if (m_drawing)
+    if (m_drawing || toolsModel.IsSelection())
     {
         toolsModel.DrawWithMouseTool(pt, wParam);
         return 0;
@@ -549,11 +528,6 @@ LRESULT CCanvasWindow::OnButtonUp(UINT nMsg, WPARAM 
wParam, LPARAM lParam, BOOL&
         ::SendMessageW(g_hStatusBar, SB_SETTEXT, 2, (LPARAM)L"");
         return 0;
     }
-    else if (m_hitSelection != HIT_NONE && bLeftButton)
-    {
-        EndSelectionDrag(pt);
-        return 0;
-    }
 
     if (m_hitCanvasSizeBox == HIT_NONE || !bLeftButton)
         return 0;
@@ -728,7 +702,6 @@ VOID CCanvasWindow::cancelDrawing()
 {
     selectionModel.ClearColorImage();
     selectionModel.ClearMaskImage();
-    m_hitSelection = HIT_NONE;
     m_drawing = FALSE;
     toolsModel.OnEndDraw(TRUE);
     Invalidate(FALSE);
@@ -741,35 +714,6 @@ VOID CCanvasWindow::finishDrawing()
     Invalidate(FALSE);
 }
 
-VOID CCanvasWindow::StartSelectionDrag(HITTEST hit, POINT ptImage)
-{
-    m_hitSelection = hit;
-    selectionModel.m_ptHit = ptImage;
-    selectionModel.TakeOff();
-
-    SetCapture();
-    Invalidate(FALSE);
-}
-
-VOID CCanvasWindow::SelectionDragging(POINT ptImage)
-{
-    if (selectionModel.m_nSelectionBrush)
-    {
-        imageModel.SelectionClone(selectionModel.m_nSelectionBrush == 1);
-        selectionModel.m_nSelectionBrush = 2; // Selection Brush is ON and 
drawn
-    }
-
-    selectionModel.Dragging(m_hitSelection, ptImage);
-    Invalidate(FALSE);
-}
-
-VOID CCanvasWindow::EndSelectionDrag(POINT ptImage)
-{
-    selectionModel.Dragging(m_hitSelection, ptImage);
-    m_hitSelection = HIT_NONE;
-    Invalidate(FALSE);
-}
-
 LRESULT CCanvasWindow::OnCtlColorEdit(UINT nMsg, WPARAM wParam, LPARAM lParam, 
BOOL& bHandled)
 {
     SetTextColor((HDC)wParam, paletteModel.GetFgColor());
diff --git a/base/applications/mspaint/canvas.h 
b/base/applications/mspaint/canvas.h
index e59b37cc670..5bdd1def467 100644
--- a/base/applications/mspaint/canvas.h
+++ b/base/applications/mspaint/canvas.h
@@ -56,7 +56,6 @@ public:
     VOID zoomTo(INT newZoom, LONG left = 0, LONG top = 0);
 
 protected:
-    HITTEST m_hitSelection;
     HITTEST m_hitCanvasSizeBox;
     POINT m_ptOrig; // The origin of drag start
     HBITMAP m_ahbmCached[2]; // The cached buffer bitmaps
@@ -67,10 +66,6 @@ protected:
     VOID DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint);
     VOID OnHVScroll(WPARAM wParam, INT fnBar);
 
-    VOID StartSelectionDrag(HITTEST hit, POINT ptImage);
-    VOID SelectionDragging(POINT ptImage);
-    VOID EndSelectionDrag(POINT ptImage);
-
     LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
     LRESULT OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
     LRESULT OnVScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
diff --git a/base/applications/mspaint/main.cpp 
b/base/applications/mspaint/main.cpp
index 535db5b42c8..7e3364678f1 100644
--- a/base/applications/mspaint/main.cpp
+++ b/base/applications/mspaint/main.cpp
@@ -963,29 +963,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bH
                 textEditWindow.PostMessage(WM_UNDO, 0, 0);
                 break;
             }
-            if (selectionModel.m_bShow)
-            {
-                if (toolsModel.IsSelection())
-                {
-                    canvasWindow.cancelDrawing();
-                    if (toolsModel.GetActiveTool() == TOOL_FREESEL ||
-                        toolsModel.GetActiveTool() == TOOL_RECTSEL)
-                    {
-                        imageModel.Undo();
-                        if (selectionModel.m_nSelectionBrush == 2) // 
Selection Brush is drawn
-                        {
-                            imageModel.Undo();
-                            selectionModel.m_nSelectionBrush = 0;
-                        }
-                    }
-                    break;
-                }
-            }
-            if (ToolBase::s_pointSP != 0) // drawing something?
-            {
-                canvasWindow.cancelDrawing();
-                break;
-            }
+            canvasWindow.finishDrawing();
             imageModel.Undo();
             break;
         case IDM_EDITREDO:
@@ -994,11 +972,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, 
LPARAM lParam, BOOL& bH
                 // There is no "WM_REDO" in EDIT control
                 break;
             }
-            if (ToolBase::s_pointSP != 0) // drawing something?
-            {
-                canvasWindow.finishDrawing();
-                break;
-            }
+            canvasWindow.finishDrawing();
             imageModel.Redo();
             break;
         case IDM_EDITCOPY:
diff --git a/base/applications/mspaint/mouse.cpp 
b/base/applications/mspaint/mouse.cpp
index 625834b1c0c..2dcec274e80 100644
--- a/base/applications/mspaint/mouse.cpp
+++ b/base/applications/mspaint/mouse.cpp
@@ -121,170 +121,6 @@ void ToolBase::pushToPtStack(LONG x, LONG y)
 
 /* TOOLS ********************************************************/
 
-// TOOL_FREESEL
-struct FreeSelTool : ToolBase
-{
-    BOOL m_bLeftButton = FALSE;
-
-    void OnDrawOverlayOnImage(HDC hdc) override
-    {
-        if (!selectionModel.IsLanded())
-            selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), 
toolsModel.IsBackgroundTransparent());
-
-        if (canvasWindow.m_drawing)
-        {
-            selectionModel.DrawFramePoly(hdc);
-        }
-    }
-
-    void OnDrawOverlayOnCanvas(HDC hdc) override
-    {
-        selectionModel.drawFrameOnCanvas(hdc);
-    }
-
-    void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) 
override
-    {
-        selectionModel.Landing();
-        if (bLeftButton)
-        {
-            selectionModel.HideSelection();
-            selectionModel.ResetPtStack();
-            POINT pt = { x, y };
-            selectionModel.PushToPtStack(pt);
-        }
-        m_bLeftButton = bLeftButton;
-    }
-
-    BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
-    {
-        if (bLeftButton)
-        {
-            POINT pt = { x, y };
-            imageModel.Clamp(pt);
-            selectionModel.PushToPtStack(pt);
-            imageModel.NotifyImageChanged();
-        }
-        return TRUE;
-    }
-
-    BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
-    {
-        if (bLeftButton)
-        {
-            if (selectionModel.PtStackSize() > 2)
-            {
-                selectionModel.BuildMaskFromPtStack();
-                selectionModel.m_bShow = TRUE;
-            }
-            else
-            {
-                selectionModel.ResetPtStack();
-                selectionModel.m_bShow = FALSE;
-            }
-            imageModel.NotifyImageChanged();
-        }
-        else
-        {
-            POINT pt = { x, y };
-            canvasWindow.ClientToScreen(&pt);
-            mainWindow.TrackPopupMenu(pt, 0);
-        }
-        return TRUE;
-    }
-
-    void OnEndDraw(BOOL bCancel) override
-    {
-        if (bCancel)
-            selectionModel.HideSelection();
-        else
-            selectionModel.Landing();
-        ToolBase::OnEndDraw(bCancel);
-    }
-
-    void OnSpecialTweak(BOOL bMinus) override
-    {
-        selectionModel.StretchSelection(bMinus);
-    }
-};
-
-// TOOL_RECTSEL
-struct RectSelTool : ToolBase
-{
-    BOOL m_bLeftButton = FALSE;
-
-    void OnDrawOverlayOnImage(HDC hdc) override
-    {
-        if (!selectionModel.IsLanded())
-            selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), 
toolsModel.IsBackgroundTransparent());
-
-        if (canvasWindow.m_drawing)
-        {
-            CRect& rc = selectionModel.m_rc;
-            if (!rc.IsRectEmpty())
-                RectSel(hdc, rc.left, rc.top, rc.right, rc.bottom);
-        }
-    }
-
-    void OnDrawOverlayOnCanvas(HDC hdc) override
-    {
-        selectionModel.drawFrameOnCanvas(hdc);
-    }
-
-    void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) 
override
-    {
-        selectionModel.Landing();
-        if (bLeftButton)
-        {
-            selectionModel.HideSelection();
-        }
-        m_bLeftButton = bLeftButton;
-    }
-
-    BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
-    {
-        if (bLeftButton)
-        {
-            POINT pt = { x, y };
-            imageModel.Clamp(pt);
-            selectionModel.SetRectFromPoints(g_ptStart, pt);
-            imageModel.NotifyImageChanged();
-        }
-        return TRUE;
-    }
-
-    BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
-    {
-        POINT pt = { x, y };
-        if (bLeftButton)
-        {
-            imageModel.Clamp(pt);
-            selectionModel.SetRectFromPoints(g_ptStart, pt);
-            selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty();
-            imageModel.NotifyImageChanged();
-        }
-        else
-        {
-            canvasWindow.ClientToScreen(&pt);
-            mainWindow.TrackPopupMenu(pt, 0);
-        }
-        return TRUE;
-    }
-
-    void OnEndDraw(BOOL bCancel) override
-    {
-        if (bCancel)
-            selectionModel.HideSelection();
-        else
-            selectionModel.Landing();
-        ToolBase::OnEndDraw(bCancel);
-    }
-
-    void OnSpecialTweak(BOOL bMinus) override
-    {
-        selectionModel.StretchSelection(bMinus);
-    }
-};
-
 struct TwoPointDrawTool : ToolBase
 {
     BOOL m_bLeftButton = FALSE;
@@ -491,6 +327,208 @@ struct SmoothDrawTool : ToolBase
     }
 };
 
+struct SelectionBaseTool : SmoothDrawTool
+{
+    BOOL m_bLeftButton = FALSE;
+    BOOL m_bCtrlKey = FALSE;
+    BOOL m_bShiftKey = FALSE;
+    BOOL m_bDrawing = FALSE;
+    HITTEST m_hitSelection = HIT_NONE;
+
+    BOOL isRectSelect() const
+    {
+        return (toolsModel.GetActiveTool() == TOOL_RECTSEL);
+    }
+
+    void OnDrawOverlayOnImage(HDC hdc) override
+    {
+        if (!selectionModel.IsLanded())
+            selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), 
toolsModel.IsBackgroundTransparent());
+    }
+
+    void OnDrawOverlayOnCanvas(HDC hdc) override
+    {
+        selectionModel.drawFrameOnCanvas(hdc);
+    }
+
+    void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) 
override
+    {
+        m_bLeftButton = bLeftButton;
+        m_bCtrlKey = (::GetKeyState(VK_CONTROL) < 0);
+        m_bShiftKey = (::GetKeyState(VK_SHIFT) < 0);
+        m_bDrawing = FALSE;
+        m_hitSelection = HIT_NONE;
+
+        POINT pt = { x, y };
+        if (!m_bLeftButton) // Show context menu on Right-click
+        {
+            canvasWindow.ImageToCanvas(pt);
+            canvasWindow.ClientToScreen(&pt);
+            mainWindow.TrackPopupMenu(pt, 0);
+            return;
+        }
+
+        POINT ptCanvas = pt;
+        canvasWindow.ImageToCanvas(ptCanvas);
+        HITTEST hit = selectionModel.hitTest(ptCanvas);
+        if (hit != HIT_NONE) // Dragging of selection started?
+        {
+            if (m_bCtrlKey || m_bShiftKey)
+                imageModel.SelectionClone();
+
+            m_hitSelection = hit;
+            selectionModel.m_ptHit = pt;
+            selectionModel.TakeOff();
+
+            imageModel.NotifyImageChanged();
+            return;
+        }
+
+        selectionModel.Landing();
+        m_bDrawing = TRUE;
+
+        imageModel.Clamp(pt);
+        if (isRectSelect())
+        {
+            selectionModel.SetRectFromPoints(g_ptStart, pt);
+        }
+        else
+        {
+            selectionModel.ResetPtStack();
+            selectionModel.PushToPtStack(pt);
+        }
+
+        imageModel.NotifyImageChanged();
+    }
+
+    BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override
+    {
+        POINT pt = { x, y };
+
+        if (!m_bLeftButton)
+            return TRUE;
+
+        if (m_hitSelection != HIT_NONE) // Now dragging selection?
+        {
+            if (m_bShiftKey)
+                imageModel.SelectionClone(m_bShiftKey);
+
+            selectionModel.Dragging(m_hitSelection, pt);
+            imageModel.NotifyImageChanged();
+            return TRUE;
+        }
+
+        imageModel.Clamp(pt);
+        if (isRectSelect())
+            selectionModel.SetRectFromPoints(g_ptStart, pt);
+        else
+            selectionModel.PushToPtStack(pt);
+
+        imageModel.NotifyImageChanged();
+        return TRUE;
+    }
+
+    BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override
+    {
+        POINT pt = { x, y };
+        m_bDrawing = FALSE;
+
+        if (!m_bLeftButton)
+            return TRUE;
+
+        if (m_hitSelection != HIT_NONE) // Dragging of selection ended?
+        {
+            selectionModel.Dragging(m_hitSelection, pt);
+            m_hitSelection = HIT_NONE;
+            imageModel.NotifyImageChanged();
+            return TRUE;
+        }
+
+        imageModel.Clamp(pt);
+        if (isRectSelect())
+        {
+            selectionModel.SetRectFromPoints(g_ptStart, pt);
+            selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty();
+        }
+        else
+        {
+            if (selectionModel.PtStackSize() > 2)
+            {
+                selectionModel.BuildMaskFromPtStack();
+                selectionModel.m_bShow = TRUE;
+            }
+            else
+            {
+                selectionModel.ResetPtStack();
+                selectionModel.m_bShow = FALSE;
+            }
+        }
+
+        imageModel.NotifyImageChanged();
+        return TRUE;
+    }
+
+    void OnEndDraw(BOOL bCancel) override
+    {
+        if (bCancel)
+            selectionModel.HideSelection();
+        else
+            selectionModel.Landing();
+
+        m_hitSelection = HIT_NONE;
+        ToolBase::OnEndDraw(bCancel);
+    }
+
+    void OnSpecialTweak(BOOL bMinus) override
+    {
+        selectionModel.StretchSelection(bMinus);
+    }
+};
+
+// TOOL_FREESEL
+struct FreeSelTool : SelectionBaseTool
+{
+    void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override
+    {
+        if (m_bShiftKey && !m_bCtrlKey)
+        {
+            // TODO:
+        }
+    }
+
+    void OnDrawOverlayOnImage(HDC hdc) override
+    {
+        SelectionBaseTool::OnDrawOverlayOnImage(hdc);
+
+        if (!selectionModel.m_bShow && m_bDrawing)
+            selectionModel.DrawFramePoly(hdc);
+    }
+};
+
+// TOOL_RECTSEL
+struct RectSelTool : SelectionBaseTool
+{
+    void OnDraw(HDC hdc, BOOL bLeftButton, POINT pt0, POINT pt1) override
+    {
+        if (m_bShiftKey && !m_bCtrlKey)
+        {
+            // TODO:
+        }
+    }
+
+    void OnDrawOverlayOnImage(HDC hdc) override
+    {
+        SelectionBaseTool::OnDrawOverlayOnImage(hdc);
+
+        if (!selectionModel.m_bShow && m_bDrawing)
+        {
+            CRect& rc = selectionModel.m_rc;
+            if (!rc.IsRectEmpty())
+                RectSel(hdc, rc.left, rc.top, rc.right, rc.bottom);
+        }
+    }
+};
+
 // TOOL_RUBBER
 struct RubberTool : SmoothDrawTool
 {
diff --git a/base/applications/mspaint/selectionmodel.h 
b/base/applications/mspaint/selectionmodel.h
index 37cf74ca38f..e83786191ff 100644
--- a/base/applications/mspaint/selectionmodel.h
+++ b/base/applications/mspaint/selectionmodel.h
@@ -23,7 +23,6 @@ public:
     CRect m_rc;    // in image pixel coordinates
     POINT m_ptHit; // in image pixel coordinates
     CRect m_rcOld; // in image pixel coordinates
-    INT m_nSelectionBrush = 0;
 
     SelectionModel();
     ~SelectionModel();

Reply via email to