https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cbc63d876c3295635a6bb…
commit cbc63d876c3295635a6bb1b30993e9bd79873941
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Thu Sep 28 07:34:25 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Thu Sep 28 07:34:25 2023 +0900
[MSPAINT] "Selection Clone" and "Selection Brush" (#5734)
- Stamp the image of the selection when the user clicks on
the selection while holding down the Ctrl key.
- Draw the image of the selection continuously when the user
starts dragging the selection while holding down the Shift key.
CORE-19094
---
base/applications/mspaint/canvas.cpp | 15 +++++++++++++++
base/applications/mspaint/history.cpp | 13 +++++++++++++
base/applications/mspaint/history.h | 1 +
base/applications/mspaint/mouse.cpp | 6 ------
base/applications/mspaint/selectionmodel.cpp | 11 +++++++++++
base/applications/mspaint/selectionmodel.h | 1 +
base/applications/mspaint/winproc.cpp | 10 ++++++++++
7 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/base/applications/mspaint/canvas.cpp b/base/applications/mspaint/canvas.cpp
index a403c8bd456..d62779f39a6 100644
--- a/base/applications/mspaint/canvas.cpp
+++ b/base/applications/mspaint/canvas.cpp
@@ -268,9 +268,18 @@ LRESULT CCanvasWindow::OnLRButtonDown(BOOL bLeftButton, UINT nMsg,
WPARAM wParam
HITTEST hitSelection = SelectionHitTest(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
@@ -790,6 +799,12 @@ VOID CCanvasWindow::StartSelectionDrag(HITTEST hit, POINT ptImage)
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);
}
diff --git a/base/applications/mspaint/history.cpp
b/base/applications/mspaint/history.cpp
index e44eca7dc4d..9e924b9e3db 100644
--- a/base/applications/mspaint/history.cpp
+++ b/base/applications/mspaint/history.cpp
@@ -299,3 +299,16 @@ void ImageModel::UnlockBitmap(HBITMAP hbmLocked)
m_hBms[m_currInd] = hbmLocked;
m_hbmOld = ::SelectObject(m_hDrawingDC, hbmLocked); // Re-select
}
+
+void ImageModel::SelectionClone(BOOL bUndoable)
+{
+ if (!selectionModel.m_bShow || ::IsRectEmpty(&selectionModel.m_rc))
+ return;
+
+ if (bUndoable)
+ PushImageForUndo(CopyBitmap());
+
+ selectionModel.DrawSelection(m_hDrawingDC, paletteModel.GetBgColor(),
+ toolsModel.IsBackgroundTransparent());
+ NotifyImageChanged();
+}
diff --git a/base/applications/mspaint/history.h b/base/applications/mspaint/history.h
index fb369dff72c..24f1e09cd13 100644
--- a/base/applications/mspaint/history.h
+++ b/base/applications/mspaint/history.h
@@ -41,6 +41,7 @@ public:
void NotifyImageChanged();
BOOL IsBlackAndWhite();
void PushBlackAndWhite();
+ void SelectionClone(BOOL bUndoable = TRUE);
protected:
HDC m_hDrawingDC; // The device context for this class
diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp
index d8e3585c252..70247293361 100644
--- a/base/applications/mspaint/mouse.cpp
+++ b/base/applications/mspaint/mouse.cpp
@@ -112,10 +112,7 @@ struct FreeSelTool : ToolBase
void OnDrawOverlayOnImage(HDC hdc) override
{
if (!selectionModel.IsLanded())
- {
- selectionModel.DrawBackgroundPoly(hdc, selectionModel.m_rgbBack);
selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(),
toolsModel.IsBackgroundTransparent());
- }
if (canvasWindow.m_drawing)
{
@@ -208,10 +205,7 @@ struct RectSelTool : ToolBase
void OnDrawOverlayOnImage(HDC hdc) override
{
if (!selectionModel.IsLanded())
- {
- selectionModel.DrawBackgroundRect(hdc, selectionModel.m_rgbBack);
selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(),
toolsModel.IsBackgroundTransparent());
- }
if (canvasWindow.m_drawing)
{
diff --git a/base/applications/mspaint/selectionmodel.cpp
b/base/applications/mspaint/selectionmodel.cpp
index c768c360744..e7263fa4e1f 100644
--- a/base/applications/mspaint/selectionmodel.cpp
+++ b/base/applications/mspaint/selectionmodel.cpp
@@ -187,6 +187,17 @@ BOOL SelectionModel::TakeOff()
// Save the selection area
m_rcOld = m_rc;
+ if (toolsModel.GetActiveTool() == TOOL_RECTSEL)
+ {
+ imageModel.PushImageForUndo();
+ selectionModel.DrawBackgroundRect(imageModel.GetDC(), selectionModel.m_rgbBack);
+ }
+ else if (toolsModel.GetActiveTool() == TOOL_FREESEL)
+ {
+ imageModel.PushImageForUndo();
+ selectionModel.DrawBackgroundPoly(imageModel.GetDC(), selectionModel.m_rgbBack);
+ }
+
imageModel.NotifyImageChanged();
return TRUE;
}
diff --git a/base/applications/mspaint/selectionmodel.h
b/base/applications/mspaint/selectionmodel.h
index 1d0c1b28614..308952a6e67 100644
--- a/base/applications/mspaint/selectionmodel.h
+++ b/base/applications/mspaint/selectionmodel.h
@@ -23,6 +23,7 @@ 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();
diff --git a/base/applications/mspaint/winproc.cpp
b/base/applications/mspaint/winproc.cpp
index 99658fccd52..b0330b4292d 100644
--- a/base/applications/mspaint/winproc.cpp
+++ b/base/applications/mspaint/winproc.cpp
@@ -704,6 +704,16 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
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;
}
}