https://git.reactos.org/?p=reactos.git;a=commitdiff;h=b8598e095d313bffd8169…
commit b8598e095d313bffd8169bd1ca8c1ee7b22026bd
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Nov 25 13:44:31 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Nov 25 13:44:31 2023 +0900
[MSPAINT] Improve Undo/Redo handling of selection (#6035)
Consistent behavior of the application.
- Add ShiftPtStack and BuildMaskFromPtStack
helper functions.
- Move some codes of selectionModel to
mouse.cpp.
CORE-19226
---
base/applications/mspaint/canvas.cpp | 17 +---
base/applications/mspaint/canvas.h | 3 +-
base/applications/mspaint/history.cpp | 20 ++---
base/applications/mspaint/history.h | 1 -
base/applications/mspaint/main.cpp | 36 ++------
base/applications/mspaint/mouse.cpp | 128 +++++++++++++++++++--------
base/applications/mspaint/selectionmodel.cpp | 120 +++++--------------------
base/applications/mspaint/selectionmodel.h | 10 +--
base/applications/mspaint/toolsmodel.cpp | 3 +
base/applications/mspaint/toolsmodel.h | 1 -
10 files changed, 134 insertions(+), 205 deletions(-)
diff --git a/base/applications/mspaint/canvas.cpp b/base/applications/mspaint/canvas.cpp
index fa6201cdf21..06074cf0c45 100644
--- a/base/applications/mspaint/canvas.cpp
+++ b/base/applications/mspaint/canvas.cpp
@@ -648,9 +648,9 @@ LRESULT CCanvasWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL
LRESULT CCanvasWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
- if (wParam == VK_ESCAPE && ::GetCapture() == m_hWnd)
+ if (wParam == VK_ESCAPE)
{
- cancelDrawing();
+ OnEndDraw(TRUE);
::ReleaseCapture();
m_nMouseDownMsg = 0;
m_hitCanvasSizeBox = HIT_NONE;
@@ -698,19 +698,10 @@ LRESULT CCanvasWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
return 0;
}
-VOID CCanvasWindow::cancelDrawing()
+VOID CCanvasWindow::OnEndDraw(BOOL bCancel)
{
- selectionModel.ClearColorImage();
- selectionModel.ClearMaskImage();
- m_drawing = FALSE;
- toolsModel.OnEndDraw(TRUE);
- Invalidate(FALSE);
-}
-
-VOID CCanvasWindow::finishDrawing()
-{
- toolsModel.OnEndDraw(FALSE);
m_drawing = FALSE;
+ toolsModel.OnEndDraw(bCancel);
Invalidate(FALSE);
}
diff --git a/base/applications/mspaint/canvas.h b/base/applications/mspaint/canvas.h
index 5bdd1def467..ef0323df65f 100644
--- a/base/applications/mspaint/canvas.h
+++ b/base/applications/mspaint/canvas.h
@@ -42,8 +42,7 @@ public:
BOOL m_drawing;
- VOID cancelDrawing();
- VOID finishDrawing();
+ VOID OnEndDraw(BOOL bCancel);
VOID updateScrollRange();
VOID updateScrollPos(INT x = 0, INT y = 0);
diff --git a/base/applications/mspaint/history.cpp
b/base/applications/mspaint/history.cpp
index 696e02656c2..c7b32cc5ab4 100644
--- a/base/applications/mspaint/history.cpp
+++ b/base/applications/mspaint/history.cpp
@@ -164,8 +164,13 @@ void ImageModel::PushImageForUndo(const RECT& rcPartial)
part.m_bPartial = TRUE;
part.m_rcPart = rcPartial;
+ CRect rcImage = { 0, 0, GetWidth(), GetHeight() };
+ CRect& rc = part.m_rcPart;
+ if (!rc.IntersectRect(rc, rcImage))
+ rc.SetRect(-1, -1, 0, 0);
+
HBITMAP hbmMaster = LockBitmap();
- part.m_hbmImage = getSubImage(hbmMaster, rcPartial);
+ part.m_hbmImage = getSubImage(hbmMaster, rc);
UnlockBitmap(hbmMaster);
PushDone();
@@ -351,16 +356,3 @@ void ImageModel::UnlockBitmap(HBITMAP hbmLocked)
m_hbmMaster = hbmLocked;
m_hbmOld = ::SelectObject(m_hDrawingDC, m_hbmMaster); // Re-select
}
-
-void ImageModel::SelectionClone(BOOL bUndoable)
-{
- if (!selectionModel.m_bShow || selectionModel.m_rc.IsRectEmpty())
- return;
-
- if (bUndoable)
- PushImageForUndo();
-
- selectionModel.DrawSelection(m_hDrawingDC, paletteModel.GetBgColor(),
- toolsModel.IsBackgroundTransparent());
- NotifyImageChanged();
-}
diff --git a/base/applications/mspaint/history.h b/base/applications/mspaint/history.h
index 87c98515136..7dc949b31f4 100644
--- a/base/applications/mspaint/history.h
+++ b/base/applications/mspaint/history.h
@@ -51,7 +51,6 @@ 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/main.cpp b/base/applications/mspaint/main.cpp
index 7e3364678f1..c93a41a886a 100644
--- a/base/applications/mspaint/main.cpp
+++ b/base/applications/mspaint/main.cpp
@@ -406,7 +406,7 @@ void CMainWindow::alignChildrenToMainWindow()
void CMainWindow::saveImage(BOOL overwrite)
{
- canvasWindow.finishDrawing();
+ canvasWindow.OnEndDraw(FALSE);
// Is the extension not supported?
PWCHAR pchDotExt = PathFindExtensionW(g_szFileName);
@@ -606,7 +606,7 @@ LRESULT CMainWindow::OnDestroy(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
BOOL CMainWindow::ConfirmSave()
{
- canvasWindow.finishDrawing();
+ canvasWindow.OnEndDraw(FALSE);
if (imageModel.IsImageSaved())
return TRUE;
@@ -693,8 +693,6 @@ BOOL CMainWindow::CanUndo() const
return (BOOL)textEditWindow.SendMessage(EM_CANUNDO);
if (selectionModel.m_bShow && toolsModel.IsSelection())
return TRUE;
- if (ToolBase::s_pointSP != 0)
- return TRUE;
return imageModel.CanUndo();
}
@@ -702,8 +700,6 @@ BOOL CMainWindow::CanRedo() const
{
if (toolsModel.GetActiveTool() == TOOL_TEXT &&
::IsWindowVisible(textEditWindow))
return FALSE; // There is no "WM_REDO" in EDIT control
- if (ToolBase::s_pointSP != 0)
- return TRUE;
return imageModel.CanRedo();
}
@@ -802,29 +798,11 @@ LRESULT CMainWindow::OnGetMinMaxInfo(UINT nMsg, WPARAM wParam,
LPARAM lParam, BO
LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
- HWND hwndCapture;
switch (wParam)
{
case VK_ESCAPE:
- hwndCapture = GetCapture();
- if (hwndCapture)
- {
- if (canvasWindow.m_hWnd == hwndCapture ||
- fullscreenWindow.m_hWnd == hwndCapture)
- {
- ::SendMessageW(hwndCapture, nMsg, wParam, lParam);
- }
- }
- else if (selectionModel.m_bShow)
- {
- selectionModel.HideSelection();
- }
- else
- {
- canvasWindow.cancelDrawing();
- }
+ canvasWindow.PostMessage(nMsg, wParam, lParam);
break;
-
case VK_LEFT:
selectionModel.moveSelection(-1, 0);
break;
@@ -932,7 +910,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
GlobalFree(pd.hDevNames);
break;
case IDM_FILESEND:
- canvasWindow.finishDrawing();
+ canvasWindow.OnEndDraw(FALSE);
if (!OpenMailer(m_hWnd, g_szFileName))
{
ShowError(IDS_CANTSENDMAIL);
@@ -963,7 +941,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
textEditWindow.PostMessage(WM_UNDO, 0, 0);
break;
}
- canvasWindow.finishDrawing();
+ canvasWindow.OnEndDraw(FALSE);
imageModel.Undo();
break;
case IDM_EDITREDO:
@@ -972,7 +950,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
// There is no "WM_REDO" in EDIT control
break;
}
- canvasWindow.finishDrawing();
+ canvasWindow.OnEndDraw(FALSE);
imageModel.Redo();
break;
case IDM_EDITCOPY:
@@ -1087,7 +1065,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
break;
case TOOL_TEXT:
- canvasWindow.cancelDrawing();
+ canvasWindow.OnEndDraw(TRUE);
break;
default:
break;
diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp
index 2dcec274e80..2f97ad9d079 100644
--- a/base/applications/mspaint/mouse.cpp
+++ b/base/applications/mspaint/mouse.cpp
@@ -9,9 +9,11 @@
#include "precomp.h"
#include <atlalloc.h>
-SIZE_T ToolBase::s_pointSP = 0;
-static SIZE_T s_maxPointSP = 0;
-static CHeapPtr<POINT, CLocalAllocator> s_pointStack;
+static SIZE_T s_pointSP = 0;
+static CHeapPtr<POINT, CLocalAllocator> s_pointsAllocated;
+static POINT s_staticPointStack[512]; // 512 is enough
+static SIZE_T s_maxPointSP = _countof(s_staticPointStack);
+static LPPOINT s_pointStack = s_staticPointStack;
static POINT g_ptStart, g_ptEnd;
/* FUNCTIONS ********************************************************/
@@ -69,13 +71,50 @@ void getBoundaryOfPtStack(RECT& rcBoundary, INT cPoints, const
POINT *pPoints)
rcBoundary = rc;
}
+void ShiftPtStack(INT dx, INT dy)
+{
+ for (SIZE_T i = 0; i < s_pointSP; ++i)
+ {
+ POINT& pt = s_pointStack[i];
+ pt.x += dx;
+ pt.y += dy;
+ }
+}
+
+void BuildMaskFromPtStack()
+{
+ CRect rc;
+ getBoundaryOfPtStack(rc, s_pointSP, s_pointStack);
+
+ ShiftPtStack(-rc.left, -rc.top);
+
+ HDC hdcMem = ::CreateCompatibleDC(NULL);
+ HBITMAP hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL);
+ HGDIOBJ hbmOld = ::SelectObject(hdcMem, hbmMask);
+ ::FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH));
+ HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN));
+ HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH));
+ ::Polygon(hdcMem, s_pointStack, s_pointSP);
+ ::SelectObject(hdcMem, hbrOld);
+ ::SelectObject(hdcMem, hPenOld);
+ ::SelectObject(hdcMem, hbmOld);
+ ::DeleteDC(hdcMem);
+
+ selectionModel.setMask(rc, hbmMask);
+}
+
void ToolBase::reset()
{
+ if (s_pointStack != s_staticPointStack)
+ {
+ s_pointsAllocated.Free();
+ s_pointStack = s_staticPointStack;
+ s_maxPointSP = _countof(s_staticPointStack);
+ }
+
s_pointSP = 0;
g_ptEnd = g_ptStart = { -1, -1 };
- selectionModel.ResetPtStack();
-
if (selectionModel.m_bShow)
{
selectionModel.Landing();
@@ -103,16 +142,20 @@ void ToolBase::endEvent()
void ToolBase::pushToPtStack(LONG x, LONG y)
{
- if (s_pointSP >= s_maxPointSP)
+ if (s_pointSP + 1 >= s_maxPointSP)
{
SIZE_T newMax = s_maxPointSP + 512;
SIZE_T cbNew = newMax * sizeof(POINT);
- if (!s_pointStack.ReallocateBytes(cbNew))
+ if (!s_pointsAllocated.ReallocateBytes(cbNew))
{
ATLTRACE("%d, %d, %d\n", (INT)s_pointSP, (INT)s_maxPointSP,
(INT)cbNew);
return;
}
+ if (s_pointStack == s_staticPointStack)
+ CopyMemory(s_pointsAllocated, s_staticPointStack, s_pointSP *
sizeof(POINT));
+
+ s_pointStack = s_pointsAllocated;
s_maxPointSP = newMax;
}
@@ -327,12 +370,13 @@ struct SmoothDrawTool : ToolBase
}
};
-struct SelectionBaseTool : SmoothDrawTool
+struct SelectionBaseTool : ToolBase
{
BOOL m_bLeftButton = FALSE;
BOOL m_bCtrlKey = FALSE;
BOOL m_bShiftKey = FALSE;
BOOL m_bDrawing = FALSE;
+ BOOL m_bNoDrawBack = FALSE;
HITTEST m_hitSelection = HIT_NONE;
BOOL isRectSelect() const
@@ -342,13 +386,19 @@ struct SelectionBaseTool : SmoothDrawTool
void OnDrawOverlayOnImage(HDC hdc) override
{
- if (!selectionModel.IsLanded())
- selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(),
toolsModel.IsBackgroundTransparent());
+ if (selectionModel.IsLanded() || !selectionModel.m_bShow)
+ return;
+
+ if (!m_bNoDrawBack)
+ selectionModel.DrawBackground(hdc, selectionModel.m_rgbBack);
+
+ selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(),
toolsModel.IsBackgroundTransparent());
}
void OnDrawOverlayOnCanvas(HDC hdc) override
{
- selectionModel.drawFrameOnCanvas(hdc);
+ if (m_bDrawing || selectionModel.m_bShow)
+ selectionModel.drawFrameOnCanvas(hdc);
}
void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override
@@ -374,12 +424,14 @@ struct SelectionBaseTool : SmoothDrawTool
if (hit != HIT_NONE) // Dragging of selection started?
{
if (m_bCtrlKey || m_bShiftKey)
- imageModel.SelectionClone();
-
+ {
+ imageModel.PushImageForUndo();
+ toolsModel.OnDrawOverlayOnImage(imageModel.GetDC());
+ }
m_hitSelection = hit;
selectionModel.m_ptHit = pt;
selectionModel.TakeOff();
-
+ m_bNoDrawBack |= (m_bCtrlKey || m_bShiftKey);
imageModel.NotifyImageChanged();
return;
}
@@ -394,8 +446,8 @@ struct SelectionBaseTool : SmoothDrawTool
}
else
{
- selectionModel.ResetPtStack();
- selectionModel.PushToPtStack(pt);
+ s_pointSP = 0;
+ pushToPtStack(pt.x, pt.y);
}
imageModel.NotifyImageChanged();
@@ -411,18 +463,22 @@ struct SelectionBaseTool : SmoothDrawTool
if (m_hitSelection != HIT_NONE) // Now dragging selection?
{
if (m_bShiftKey)
- imageModel.SelectionClone(m_bShiftKey);
+ toolsModel.OnDrawOverlayOnImage(imageModel.GetDC());
selectionModel.Dragging(m_hitSelection, pt);
imageModel.NotifyImageChanged();
return TRUE;
}
+ if (isRectSelect() && ::GetKeyState(VK_SHIFT) < 0)
+ regularize(g_ptStart.x, g_ptStart.y, pt.x, pt.y);
+
imageModel.Clamp(pt);
+
if (isRectSelect())
selectionModel.SetRectFromPoints(g_ptStart, pt);
else
- selectionModel.PushToPtStack(pt);
+ pushToPtStack(pt.x, pt.y);
imageModel.NotifyImageChanged();
return TRUE;
@@ -438,13 +494,20 @@ struct SelectionBaseTool : SmoothDrawTool
if (m_hitSelection != HIT_NONE) // Dragging of selection ended?
{
+ if (m_bShiftKey)
+ toolsModel.OnDrawOverlayOnImage(imageModel.GetDC());
+
selectionModel.Dragging(m_hitSelection, pt);
m_hitSelection = HIT_NONE;
imageModel.NotifyImageChanged();
return TRUE;
}
+ if (isRectSelect() && ::GetKeyState(VK_SHIFT) < 0)
+ regularize(g_ptStart.x, g_ptStart.y, pt.x, pt.y);
+
imageModel.Clamp(pt);
+
if (isRectSelect())
{
selectionModel.SetRectFromPoints(g_ptStart, pt);
@@ -452,18 +515,19 @@ struct SelectionBaseTool : SmoothDrawTool
}
else
{
- if (selectionModel.PtStackSize() > 2)
+ if (s_pointSP > 2)
{
- selectionModel.BuildMaskFromPtStack();
+ BuildMaskFromPtStack();
selectionModel.m_bShow = TRUE;
}
else
{
- selectionModel.ResetPtStack();
+ s_pointSP = 0;
selectionModel.m_bShow = FALSE;
}
}
+ m_bNoDrawBack = FALSE;
imageModel.NotifyImageChanged();
return TRUE;
}
@@ -475,6 +539,7 @@ struct SelectionBaseTool : SmoothDrawTool
else
selectionModel.Landing();
+ m_bDrawing = FALSE;
m_hitSelection = HIT_NONE;
ToolBase::OnEndDraw(bCancel);
}
@@ -488,34 +553,21 @@ struct SelectionBaseTool : SmoothDrawTool
// 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);
+ {
+ /* Draw the freehand selection inverted/xored */
+ Poly(hdc, s_pointStack, s_pointSP, 0, 0, 2, 0, FALSE, TRUE);
+ }
}
};
// 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);
diff --git a/base/applications/mspaint/selectionmodel.cpp
b/base/applications/mspaint/selectionmodel.cpp
index ee18b521188..2699a8517e9 100644
--- a/base/applications/mspaint/selectionmodel.cpp
+++ b/base/applications/mspaint/selectionmodel.cpp
@@ -15,8 +15,6 @@ SelectionModel selectionModel;
SelectionModel::SelectionModel()
: m_hbmColor(NULL)
, m_hbmMask(NULL)
- , m_ptStack(NULL)
- , m_iPtSP(0)
, m_rgbBack(RGB(255, 255, 255))
, m_bShow(FALSE)
, m_bContentChanged(FALSE)
@@ -30,69 +28,6 @@ SelectionModel::~SelectionModel()
{
ClearColorImage();
ClearMaskImage();
- ResetPtStack();
-}
-
-void SelectionModel::ResetPtStack()
-{
- if (m_ptStack)
- {
- free(m_ptStack);
- m_ptStack = NULL;
- }
- m_iPtSP = 0;
-}
-
-void SelectionModel::PushToPtStack(POINT pt)
-{
-#define GROW_COUNT 256
- if (m_iPtSP % GROW_COUNT == 0)
- {
- INT nNewCount = m_iPtSP + GROW_COUNT;
- LPPOINT pptNew = (LPPOINT)realloc(m_ptStack, sizeof(POINT) * nNewCount);
- if (pptNew == NULL)
- return;
- m_ptStack = pptNew;
- }
- m_ptStack[m_iPtSP] = pt;
- m_iPtSP++;
-#undef GROW_COUNT
-}
-
-void SelectionModel::ShiftPtStack(INT dx, INT dy)
-{
- for (INT i = 0; i < m_iPtSP; ++i)
- {
- POINT& pt = m_ptStack[i];
- pt.x += dx;
- pt.y += dy;
- }
-}
-
-void SelectionModel::BuildMaskFromPtStack()
-{
- CRect rc;
- getBoundaryOfPtStack(rc, m_iPtSP, m_ptStack);
-
- m_rc = m_rcOld = rc;
-
- ClearMaskImage();
-
- ShiftPtStack(-m_rcOld.left, -m_rcOld.top);
-
- HDC hdcMem = ::CreateCompatibleDC(NULL);
- m_hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL);
- HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_hbmMask);
- ::FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH));
- HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN));
- HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH));
- ::Polygon(hdcMem, m_ptStack, m_iPtSP);
- ::SelectObject(hdcMem, hbrOld);
- ::SelectObject(hdcMem, hPenOld);
- ::SelectObject(hdcMem, hbmOld);
- ::DeleteDC(hdcMem);
-
- ShiftPtStack(+m_rcOld.left, +m_rcOld.top);
}
void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg)
@@ -100,11 +35,11 @@ void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg)
if (m_rcOld.IsRectEmpty())
return;
- HGDIOBJ hPenOld = ::SelectObject(hDCImage, ::GetStockObject(NULL_PEN));
- HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::CreateSolidBrush(crBg));
- ::Polygon(hDCImage, m_ptStack, m_iPtSP);
- ::DeleteObject(::SelectObject(hDCImage, hbrOld));
- ::SelectObject(hDCImage, hPenOld);
+ HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::GetStockObject(DC_BRUSH));
+ ::SetDCBrushColor(hDCImage, crBg);
+ ::MaskBlt(hDCImage, m_rcOld.left, m_rcOld.top, m_rcOld.Width(), m_rcOld.Height(),
+ hDCImage, m_rcOld.left, m_rcOld.top, m_hbmMask, 0, 0, MAKEROP4(PATCOPY,
SRCCOPY));
+ ::SelectObject(hDCImage, hbrOld);
}
void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg)
@@ -115,12 +50,12 @@ void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg)
Rect(hDCImage, m_rcOld.left, m_rcOld.top, m_rcOld.right, m_rcOld.bottom, crBg, crBg,
0, 1);
}
-void SelectionModel::DrawBackground(HDC hDCImage)
+void SelectionModel::DrawBackground(HDC hDCImage, COLORREF crBg)
{
if (toolsModel.GetActiveTool() == TOOL_FREESEL)
- DrawBackgroundPoly(hDCImage, paletteModel.GetBgColor());
+ DrawBackgroundPoly(hDCImage, crBg);
else
- DrawBackgroundRect(hDCImage, paletteModel.GetBgColor());
+ DrawBackgroundRect(hDCImage, crBg);
}
void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent)
@@ -143,6 +78,15 @@ void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL
bBgTranspar
DeleteDC(hMemDC);
}
+void SelectionModel::setMask(const CRect& rc, HBITMAP hbmMask)
+{
+ if (m_hbmMask)
+ ::DeleteObject(m_hbmMask);
+
+ m_hbmMask = hbmMask;
+ m_rc = m_rcOld = rc;
+}
+
HBITMAP SelectionModel::GetSelectionContents()
{
if (m_hbmColor)
@@ -178,17 +122,6 @@ 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;
}
@@ -201,12 +134,12 @@ void SelectionModel::Landing()
return;
}
- m_bShow = FALSE;
-
if (m_bContentChanged ||
(!m_rc.EqualRect(m_rcOld) && !m_rc.IsRectEmpty() &&
!m_rcOld.IsRectEmpty()))
{
- imageModel.PushImageForUndo();
+ CRect rc;
+ rc.UnionRect(m_rc, m_rcOld);
+ imageModel.PushImageForUndo(rc);
canvasWindow.m_drawing = FALSE;
toolsModel.OnDrawOverlayOnImage(imageModel.GetDC());
@@ -397,17 +330,6 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int
nStretchPercentY, int
NotifyContentChanged();
}
-int SelectionModel::PtStackSize() const
-{
- return m_iPtSP;
-}
-
-void SelectionModel::DrawFramePoly(HDC hDCImage)
-{
- /* draw the freehand selection inverted/xored */
- Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE);
-}
-
void SelectionModel::SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo)
{
m_rc = CRect(ptFrom, ptTo);
@@ -491,7 +413,7 @@ void SelectionModel::DeleteSelection()
TakeOff();
imageModel.PushImageForUndo();
- DrawBackground(imageModel.GetDC());
+ DrawBackground(imageModel.GetDC(), paletteModel.GetBgColor());
HideSelection();
}
diff --git a/base/applications/mspaint/selectionmodel.h
b/base/applications/mspaint/selectionmodel.h
index e83786191ff..d9007d6df00 100644
--- a/base/applications/mspaint/selectionmodel.h
+++ b/base/applications/mspaint/selectionmodel.h
@@ -13,8 +13,6 @@ class SelectionModel
private:
HBITMAP m_hbmColor;
HBITMAP m_hbmMask;
- POINT *m_ptStack;
- int m_iPtSP;
public:
COLORREF m_rgbBack;
@@ -27,11 +25,8 @@ public:
SelectionModel();
~SelectionModel();
- void ResetPtStack();
- void PushToPtStack(POINT pt);
- int PtStackSize() const;
void SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo);
- void BuildMaskFromPtStack();
+ void setMask(const CRect& rc, HBITMAP hbmMask);
BOOL TakeOff();
void Landing();
@@ -43,8 +38,7 @@ public:
void moveSelection(INT xDelta, INT yDelta);
HBITMAP GetSelectionContents();
- void DrawFramePoly(HDC hDCImage);
- void DrawBackground(HDC hDCImage);
+ void DrawBackground(HDC hDCImage, COLORREF crBg);
void DrawBackgroundPoly(HDC hDCImage, COLORREF crBg);
void DrawBackgroundRect(HDC hDCImage, COLORREF crBg);
void DrawSelection(HDC hDCImage, COLORREF crBg = 0, BOOL bBgTransparent = FALSE);
diff --git a/base/applications/mspaint/toolsmodel.cpp
b/base/applications/mspaint/toolsmodel.cpp
index c19a1152c24..f789fbf9d6a 100644
--- a/base/applications/mspaint/toolsmodel.cpp
+++ b/base/applications/mspaint/toolsmodel.cpp
@@ -209,6 +209,9 @@ SIZE ToolsModel::GetToolSize() const
{
case TOOL_FREESEL:
case TOOL_RECTSEL:
+ size.cx = selectionModel.m_rc.Width();
+ size.cy = selectionModel.m_rc.Height();
+ break;
case TOOL_COLOR:
case TOOL_ZOOM:
case TOOL_TEXT:
diff --git a/base/applications/mspaint/toolsmodel.h
b/base/applications/mspaint/toolsmodel.h
index 668c7820bb3..2cd2e68d235 100644
--- a/base/applications/mspaint/toolsmodel.h
+++ b/base/applications/mspaint/toolsmodel.h
@@ -42,7 +42,6 @@ struct ToolBase
{
HDC m_hdc;
COLORREF m_fg, m_bg;
- static SIZE_T s_pointSP;
ToolBase() : m_hdc(NULL) { }
virtual ~ToolBase() { }