https://git.reactos.org/?p=reactos.git;a=commitdiff;h=f710e5a260d7798539424…
commit f710e5a260d77985394244e98aa57b3f5063c762
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Fri Nov 24 15:44:16 2023 +0900
Commit: GitHub <noreply(a)github.com>
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();