https://git.reactos.org/?p=reactos.git;a=commitdiff;h=aac89519ec9270ffe0935…
commit aac89519ec9270ffe0935cad267a4a87faccc92f
Author: Katayama Hirofumi MZ <katayama.hirofumi.mz(a)gmail.com>
AuthorDate: Sat Apr 1 22:01:04 2023 +0900
Commit: GitHub <noreply(a)github.com>
CommitDate: Sat Apr 1 22:01:04 2023 +0900
[MSPAINT] Make selection window-less (#5208)
- Delete selection.cpp and selection.h and selectionWindow.
- Extend ColorKeyedMaskBlt function.
- Implement selection resizing.
CORE-18867
---
base/applications/mspaint/CMakeLists.txt | 1 -
base/applications/mspaint/canvas.cpp | 23 +-
base/applications/mspaint/common.h | 1 -
base/applications/mspaint/dib.cpp | 8 +-
base/applications/mspaint/dib.h | 2 +-
base/applications/mspaint/drawing.cpp | 97 +++--
base/applications/mspaint/drawing.h | 6 +-
base/applications/mspaint/globalvar.h | 1 -
base/applications/mspaint/history.cpp | 28 +-
base/applications/mspaint/history.h | 1 -
base/applications/mspaint/imgarea.cpp | 205 +++++++---
base/applications/mspaint/imgarea.h | 12 +-
base/applications/mspaint/mouse.cpp | 129 +++----
base/applications/mspaint/palettemodel.cpp | 4 +-
base/applications/mspaint/precomp.h | 1 -
base/applications/mspaint/selection.cpp | 237 ------------
base/applications/mspaint/selection.h | 75 ----
base/applications/mspaint/selectionmodel.cpp | 544 +++++++++++++++------------
base/applications/mspaint/selectionmodel.h | 72 ++--
base/applications/mspaint/toolbox.cpp | 2 +-
base/applications/mspaint/toolsmodel.cpp | 10 +-
base/applications/mspaint/toolsmodel.h | 28 ++
base/applications/mspaint/winproc.cpp | 30 +-
23 files changed, 695 insertions(+), 822 deletions(-)
diff --git a/base/applications/mspaint/CMakeLists.txt
b/base/applications/mspaint/CMakeLists.txt
index 2d6e24dc46d..57532cba22d 100644
--- a/base/applications/mspaint/CMakeLists.txt
+++ b/base/applications/mspaint/CMakeLists.txt
@@ -20,7 +20,6 @@ list(APPEND SOURCE
palette.cpp
palettemodel.cpp
registry.cpp
- selection.cpp
selectionmodel.cpp
sizebox.cpp
textedit.cpp
diff --git a/base/applications/mspaint/canvas.cpp b/base/applications/mspaint/canvas.cpp
index d538925f39d..c0fc4ad9210 100644
--- a/base/applications/mspaint/canvas.cpp
+++ b/base/applications/mspaint/canvas.cpp
@@ -150,14 +150,25 @@ LRESULT CCanvasWindow::OnLButtonDown(UINT nMsg, WPARAM wParam,
LPARAM lParam, BO
if (hit == HIT_NONE || hit == HIT_BORDER)
{
- if (toolsModel.GetActiveTool() == TOOL_BEZIER ||
- toolsModel.GetActiveTool() == TOOL_SHAPE)
+ switch (toolsModel.GetActiveTool())
{
- if (ToolBase::pointSP != 0)
- {
- toolsModel.OnCancelDraw();
+ case TOOL_BEZIER:
+ case TOOL_SHAPE:
+ if (ToolBase::pointSP != 0)
+ {
+ toolsModel.OnCancelDraw();
+ imageArea.Invalidate();
+ }
+ break;
+
+ case TOOL_FREESEL:
+ case TOOL_RECTSEL:
+ toolsModel.OnFinishDraw();
imageArea.Invalidate();
- }
+ break;
+
+ default:
+ break;
}
toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier
functions
diff --git a/base/applications/mspaint/common.h b/base/applications/mspaint/common.h
index 619133fc550..0b9890d27f9 100644
--- a/base/applications/mspaint/common.h
+++ b/base/applications/mspaint/common.h
@@ -56,6 +56,5 @@ enum CANVAS_HITTEST // hit
BOOL zoomTo(int newZoom, int mouseX, int mouseY);
BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1);
-void placeSelWin(void);
void updateStartAndLast(LONG x, LONG y);
void updateLast(LONG x, LONG y);
diff --git a/base/applications/mspaint/dib.cpp b/base/applications/mspaint/dib.cpp
index 96218a824a3..f46ef419934 100644
--- a/base/applications/mspaint/dib.cpp
+++ b/base/applications/mspaint/dib.cpp
@@ -220,9 +220,13 @@ HBITMAP DoLoadImageFile(HWND hwnd, LPCTSTR name, BOOL fIsMainFile)
return hBitmap;
}
-HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight)
+HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono)
{
- HBITMAP hbm2 = CreateDIBWithProperties(cy, cx);
+ HBITMAP hbm2;
+ if (bMono)
+ hbm2 = ::CreateBitmap(cy, cx, 1, 1, NULL);
+ else
+ hbm2 = CreateDIBWithProperties(cy, cx);
if (!hbm2)
return NULL;
diff --git a/base/applications/mspaint/dib.h b/base/applications/mspaint/dib.h
index 82ccde6e9ed..f9eb7d37384 100644
--- a/base/applications/mspaint/dib.h
+++ b/base/applications/mspaint/dib.h
@@ -28,7 +28,7 @@ void ShowFileLoadError(LPCTSTR name);
HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL isFile);
-HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight);
+HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono);
HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical);
diff --git a/base/applications/mspaint/drawing.cpp
b/base/applications/mspaint/drawing.cpp
index f94da436eca..86711c0f6f0 100644
--- a/base/applications/mspaint/drawing.cpp
+++ b/base/applications/mspaint/drawing.cpp
@@ -290,33 +290,76 @@ Text(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg,
COLORREF bg, LPCT
BOOL
ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
- HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int
yMask,
- DWORD dwRop, COLORREF keyColor)
+ HDC hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight,
+ HBITMAP hbmMask, COLORREF keyColor)
{
- HDC hTempDC;
- HDC hTempDC2;
- HBITMAP hTempBm;
- HBRUSH hTempBrush;
- HBITMAP hTempMask;
-
- hTempDC = CreateCompatibleDC(hdcSrc);
- hTempDC2 = CreateCompatibleDC(hdcSrc);
- hTempBm = CreateCompatibleBitmap(hTempDC, nWidth, nHeight);
- SelectObject(hTempDC, hTempBm);
- hTempBrush = CreateSolidBrush(keyColor);
- SelectObject(hTempDC, hTempBrush);
- BitBlt(hTempDC, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY);
- PatBlt(hTempDC, 0, 0, nWidth, nHeight, PATINVERT);
- hTempMask = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
- SelectObject(hTempDC2, hTempMask);
- BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, 0, 0, SRCCOPY);
- SelectObject(hTempDC, hbmMask);
- BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, xMask, yMask, SRCAND);
- MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, hTempMask,
xMask, yMask, dwRop);
- DeleteDC(hTempDC);
- DeleteDC(hTempDC2);
- DeleteObject(hTempBm);
- DeleteObject(hTempBrush);
- DeleteObject(hTempMask);
+ HDC hTempDC1, hTempDC2;
+ HBITMAP hbmTempColor, hbmTempMask;
+ HGDIOBJ hbmOld1, hbmOld2;
+
+ if (hbmMask == NULL)
+ {
+ if (keyColor == CLR_INVALID)
+ {
+ ::StretchBlt(hdcDest, nXDest, nYDest, nWidth, nHeight,
+ hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, SRCCOPY);
+ }
+ else
+ {
+ ::GdiTransparentBlt(hdcDest, nXDest, nYDest, nWidth, nHeight,
+ hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, keyColor);
+ }
+ return TRUE;
+ }
+ else if (nWidth == nSrcWidth && nHeight == nSrcHeight && keyColor ==
CLR_INVALID)
+ {
+ ::MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight,
+ hdcSrc, nXSrc, nYSrc, hbmMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0029));
+ return TRUE;
+ }
+
+ hTempDC1 = ::CreateCompatibleDC(hdcDest);
+ hTempDC2 = ::CreateCompatibleDC(hdcDest);
+ hbmTempMask = ::CreateBitmap(nWidth, nHeight, 1, 1, NULL);
+ hbmTempColor = CreateColorDIB(nWidth, nHeight, RGB(255, 255, 255));
+
+ // hbmTempMask <-- hbmMask (stretched)
+ hbmOld1 = ::SelectObject(hTempDC1, hbmMask);
+ hbmOld2 = ::SelectObject(hTempDC2, hbmTempMask);
+ ::StretchBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC1, 0, 0, nSrcWidth, nSrcHeight,
SRCCOPY);
+ ::SelectObject(hTempDC2, hbmOld2);
+ ::SelectObject(hTempDC1, hbmOld1);
+
+ hbmOld1 = ::SelectObject(hTempDC1, hbmTempColor);
+ if (keyColor == CLR_INVALID)
+ {
+ // hbmTempColor <-- hdcSrc (stretched)
+ ::StretchBlt(hTempDC1, 0, 0, nWidth, nHeight,
+ hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, SRCCOPY);
+
+ // hdcDest <-- hbmTempColor (masked)
+ ::MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hTempDC1, 0, 0,
+ hbmTempMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0029));
+ }
+ else
+ {
+ // hbmTempColor <-- hdcDest
+ ::BitBlt(hTempDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
+
+ // hbmTempColor <-- hdcSrc (color key)
+ ::GdiTransparentBlt(hTempDC1, 0, 0, nWidth, nHeight,
+ hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, keyColor);
+
+ // hdcDest <-- hbmTempColor (masked)
+ ::MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hTempDC1, 0, 0,
+ hbmTempMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0029));
+ }
+ ::SelectObject(hTempDC1, hbmOld1);
+
+ ::DeleteObject(hbmTempColor);
+ ::DeleteObject(hbmTempMask);
+ ::DeleteDC(hTempDC2);
+ ::DeleteDC(hTempDC1);
+
return TRUE;
}
diff --git a/base/applications/mspaint/drawing.h b/base/applications/mspaint/drawing.h
index 5401168f92c..8fb0f54c6a6 100644
--- a/base/applications/mspaint/drawing.h
+++ b/base/applications/mspaint/drawing.h
@@ -34,7 +34,7 @@ void RectSel(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2);
void Text(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LPCTSTR
lpchText, HFONT font, LONG style);
-extern BOOL
+BOOL
ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
- HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int
yMask,
- DWORD dwRop, COLORREF keyColor);
+ HDC hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight,
+ HBITMAP hbmMask, COLORREF keyColor);
diff --git a/base/applications/mspaint/globalvar.h
b/base/applications/mspaint/globalvar.h
index fe9e47f5f0b..058117f9390 100644
--- a/base/applications/mspaint/globalvar.h
+++ b/base/applications/mspaint/globalvar.h
@@ -52,6 +52,5 @@ extern CToolBox toolBoxContainer;
extern CToolSettingsWindow toolSettingsWindow;
extern CPaletteWindow paletteWindow;
extern CCanvasWindow canvasWindow;
-extern CSelectionWindow selectionWindow;
extern CImgAreaWindow imageArea;
extern CTextEditWindow textEditWindow;
diff --git a/base/applications/mspaint/history.cpp
b/base/applications/mspaint/history.cpp
index 847e6c6db81..0680865c2a6 100644
--- a/base/applications/mspaint/history.cpp
+++ b/base/applications/mspaint/history.cpp
@@ -64,7 +64,7 @@ void ImageModel::Undo(BOOL bClearRedo)
{
int oldWidth = GetWidth();
int oldHeight = GetHeight();
- selectionWindow.ShowWindow(SW_HIDE);
+ selectionModel.m_bShow = FALSE;
currInd = (currInd + HISTORYSIZE - 1) % HISTORYSIZE;
SelectObject(hDrawingDC, hBms[currInd]);
undoSteps--;
@@ -85,7 +85,7 @@ void ImageModel::Redo()
{
int oldWidth = GetWidth();
int oldHeight = GetHeight();
- selectionWindow.ShowWindow(SW_HIDE);
+ selectionModel.m_bShow = FALSE;
currInd = (currInd + 1) % HISTORYSIZE;
SelectObject(hDrawingDC, hBms[currInd]);
redoSteps--;
@@ -264,7 +264,7 @@ void ImageModel::RotateNTimes90Degrees(int iN)
case 1:
case 3:
DeleteObject(hBms[(currInd + 1) % HISTORYSIZE]);
- hBms[(currInd + 1) % HISTORYSIZE] = Rotate90DegreeBlt(hDrawingDC, GetWidth(),
GetHeight(), iN == 1);
+ hBms[(currInd + 1) % HISTORYSIZE] = Rotate90DegreeBlt(hDrawingDC, GetWidth(),
GetHeight(), iN == 1, FALSE);
currInd = (currInd + 1) % HISTORYSIZE;
if (undoSteps < HISTORYSIZE - 1)
undoSteps++;
@@ -282,23 +282,15 @@ void ImageModel::RotateNTimes90Degrees(int iN)
NotifyImageChanged();
}
-void ImageModel::DrawSelectionBackground(COLORREF rgbBG)
-{
- if (toolsModel.GetActiveTool() == TOOL_FREESEL)
- selectionModel.DrawBackgroundPoly(hDrawingDC, rgbBG);
- else
- selectionModel.DrawBackgroundRect(hDrawingDC, rgbBG);
-}
-
void ImageModel::DeleteSelection()
{
- if (selectionWindow.IsWindowVisible())
- ResetToPrevious();
- CopyPrevious();
- if (selectionWindow.IsWindowVisible())
- Undo(TRUE);
- DrawSelectionBackground(paletteModel.GetBgColor());
- selectionWindow.ShowWindow(SW_HIDE);
+ if (!selectionModel.m_bShow)
+ return;
+
+ selectionModel.TakeOff();
+ selectionModel.m_bShow = FALSE;
+ selectionModel.ClearColor();
+ selectionModel.ClearMask();
NotifyImageChanged();
}
diff --git a/base/applications/mspaint/history.h b/base/applications/mspaint/history.h
index 17ef43b9e48..40792f8d661 100644
--- a/base/applications/mspaint/history.h
+++ b/base/applications/mspaint/history.h
@@ -45,7 +45,6 @@ public:
void FlipHorizontally();
void FlipVertically();
void RotateNTimes90Degrees(int iN);
- void DrawSelectionBackground(COLORREF rgbBG);
void DeleteSelection();
void Bound(POINT& pt);
};
diff --git a/base/applications/mspaint/imgarea.cpp
b/base/applications/mspaint/imgarea.cpp
index dfb93455b43..abae54c89a5 100644
--- a/base/applications/mspaint/imgarea.cpp
+++ b/base/applications/mspaint/imgarea.cpp
@@ -21,7 +21,6 @@ LRESULT CImgAreaWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL&
m_hCurZoom = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_ZOOM));
m_hCurPen = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_PEN));
m_hCurAirbrush = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_AIRBRUSH));
-
return 0;
}
@@ -71,49 +70,61 @@ LRESULT CImgAreaWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
LRESULT CImgAreaWindow::OnEraseBkGnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
- HDC hdc = (HDC)wParam;
-
- if (toolsModel.GetActiveTool() == TOOL_TEXT &&
!toolsModel.IsBackgroundTransparent() &&
- ::IsWindowVisible(textEditWindow))
- {
- // Do clipping
- HWND hChild = textEditWindow;
- RECT rcChild;
- ::GetWindowRect(hChild, &rcChild);
- ::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcChild, 2);
- ExcludeClipRect(hdc, rcChild.left, rcChild.top, rcChild.right, rcChild.bottom);
- }
-
- return DefWindowProc(nMsg, wParam, lParam);
+ return TRUE; // Don't fill background
}
LRESULT CImgAreaWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
+ RECT rcClient;
+ GetClientRect(&rcClient);
+
PAINTSTRUCT ps;
HDC hdc = BeginPaint(&ps);
- int imgXRes = imageModel.GetWidth();
- int imgYRes = imageModel.GetHeight();
- StretchBlt(hdc, 0, 0, Zoomed(imgXRes), Zoomed(imgYRes), imageModel.GetDC(), 0, 0,
imgXRes,
- imgYRes, SRCCOPY);
+
+ // We use a memory bitmap to reduce flickering
+ HDC hdcMem = ::CreateCompatibleDC(hdc);
+ HBITMAP hbm = ::CreateCompatibleBitmap(hdc, rcClient.right, rcClient.bottom);
+ HGDIOBJ hbmOld = ::SelectObject(hdcMem, hbm);
+
+ // Draw the image
+ SIZE size = { imageModel.GetWidth(), imageModel.GetHeight() };
+ StretchBlt(hdcMem, 0, 0, ::Zoomed(size.cx), ::Zoomed(size.cy),
+ imageModel.GetDC(), 0, 0, size.cx, size.cy, SRCCOPY);
+
+ // Draw the grid
if (showGrid && (toolsModel.GetZoom() >= 4000))
{
- HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 1, 0x00a0a0a0));
- int counter;
- for(counter = 0; counter <= imgYRes; counter++)
+ HPEN oldPen = (HPEN) SelectObject(hdcMem, CreatePen(PS_SOLID, 1, 0x00a0a0a0));
+ for (int counter = 0; counter <= size.cy; counter++)
{
- MoveToEx(hdc, 0, Zoomed(counter), NULL);
- LineTo(hdc, Zoomed(imgXRes), Zoomed(counter));
+ ::MoveToEx(hdcMem, 0, ::Zoomed(counter), NULL);
+ ::LineTo(hdcMem, ::Zoomed(size.cx), ::Zoomed(counter));
}
- for(counter = 0; counter <= imgXRes; counter++)
+ for (int counter = 0; counter <= size.cx; counter++)
{
- MoveToEx(hdc, Zoomed(counter), 0, NULL);
- LineTo(hdc, Zoomed(counter), Zoomed(imgYRes));
+ ::MoveToEx(hdcMem, ::Zoomed(counter), 0, NULL);
+ ::LineTo(hdcMem, ::Zoomed(counter), ::Zoomed(size.cy));
}
- DeleteObject(SelectObject(hdc, oldPen));
+ ::DeleteObject(::SelectObject(hdcMem, oldPen));
}
+
+ // Draw selection
+ if (selectionModel.m_bShow)
+ {
+ RECT rc = selectionModel.m_rc;
+ Zoomed(rc);
+ ::InflateRect(&rc, GRIP_SIZE, GRIP_SIZE);
+ drawSizeBoxes(hdcMem, &rc, TRUE, &ps.rcPaint);
+ ::InflateRect(&rc, -GRIP_SIZE, -GRIP_SIZE);
+ selectionModel.DrawSelection(hdcMem, &rc, paletteModel.GetBgColor(),
+ toolsModel.IsBackgroundTransparent());
+ }
+
+ // Transfer bits
+ ::BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcMem, 0, 0, SRCCOPY);
+ ::SelectObject(hdcMem, hbmOld);
EndPaint(&ps);
- if (selectionWindow.IsWindow())
- selectionWindow.Invalidate(FALSE);
+
if (miniature.IsWindow())
miniature.Invalidate(FALSE);
if (textEditWindow.IsWindow())
@@ -121,8 +132,57 @@ LRESULT CImgAreaWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& b
return 0;
}
+CANVAS_HITTEST CImgAreaWindow::SelectionHitTest(POINT ptZoomed)
+{
+ if (!selectionModel.m_bShow)
+ return HIT_NONE;
+
+ RECT rcSelection = selectionModel.m_rc;
+ Zoomed(rcSelection);
+ ::InflateRect(&rcSelection, GRIP_SIZE, GRIP_SIZE);
+
+ return getSizeBoxHitTest(ptZoomed, &rcSelection);
+}
+
+void CImgAreaWindow::StartSelectionDrag(CANVAS_HITTEST hit, POINT ptUnZoomed)
+{
+ m_hitSelection = hit;
+ selectionModel.m_ptHit = ptUnZoomed;
+ selectionModel.TakeOff();
+
+ SetCapture();
+ Invalidate(FALSE);
+}
+
+void CImgAreaWindow::SelectionDragging(POINT ptUnZoomed)
+{
+ selectionModel.Dragging(m_hitSelection, ptUnZoomed);
+ Invalidate(FALSE);
+}
+
+void CImgAreaWindow::EndSelectionDrag(POINT ptUnZoomed)
+{
+ selectionModel.Dragging(m_hitSelection, ptUnZoomed);
+ m_hitSelection = HIT_NONE;
+ Invalidate(FALSE);
+}
+
LRESULT CImgAreaWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
+ POINT pt;
+ ::GetCursorPos(&pt);
+ ScreenToClient(&pt);
+
+ CANVAS_HITTEST hit = SelectionHitTest(pt);
+ if (hit != HIT_NONE)
+ {
+ if (!setCursorOnSizeBox(hit))
+ ::SetCursor(::LoadCursor(NULL, IDC_SIZEALL));
+ return 0;
+ }
+
+ UnZoomed(pt);
+
switch (toolsModel.GetActiveTool())
{
case TOOL_FILL:
@@ -148,20 +208,31 @@ LRESULT CImgAreaWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOO
LRESULT CImgAreaWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
+ POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+
+ CANVAS_HITTEST hit = SelectionHitTest(pt);
+ if (hit != HIT_NONE)
+ {
+ UnZoomed(pt);
+ StartSelectionDrag(hit, pt);
+ return 0;
+ }
+
+ UnZoomed(pt);
drawing = TRUE;
SetCapture();
- INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
- toolsModel.OnButtonDown(TRUE, UnZoomed(x), UnZoomed(y), FALSE);
+ toolsModel.OnButtonDown(TRUE, pt.x, pt.y, FALSE);
Invalidate(FALSE);
return 0;
}
LRESULT CImgAreaWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
+ POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ UnZoomed(pt);
drawing = FALSE;
ReleaseCapture();
- INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
- toolsModel.OnButtonDown(TRUE, UnZoomed(x), UnZoomed(y), TRUE);
+ toolsModel.OnButtonDown(TRUE, pt.x, pt.y, TRUE);
toolsModel.resetTool();
Invalidate(FALSE);
return 0;
@@ -169,20 +240,22 @@ LRESULT CImgAreaWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam,
LPARAM lParam,
LRESULT CImgAreaWindow::OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
+ POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ UnZoomed(pt);
drawing = TRUE;
SetCapture();
- INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
- toolsModel.OnButtonDown(FALSE, UnZoomed(x), UnZoomed(y), FALSE);
+ toolsModel.OnButtonDown(FALSE, pt.x, pt.y, FALSE);
Invalidate(FALSE);
return 0;
}
LRESULT CImgAreaWindow::OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
+ POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ UnZoomed(pt);
drawing = FALSE;
ReleaseCapture();
- INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
- toolsModel.OnButtonDown(FALSE, UnZoomed(x), UnZoomed(y), TRUE);
+ toolsModel.OnButtonDown(FALSE, pt.x, pt.y, TRUE);
toolsModel.resetTool();
Invalidate(FALSE);
return 0;
@@ -190,20 +263,28 @@ LRESULT CImgAreaWindow::OnRButtonDblClk(UINT nMsg, WPARAM wParam,
LPARAM lParam,
LRESULT CImgAreaWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
+ POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ UnZoomed(pt);
if (drawing)
{
drawing = FALSE;
- INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
- toolsModel.OnButtonUp(TRUE, UnZoomed(x), UnZoomed(y));
+ toolsModel.OnButtonUp(TRUE, pt.x, pt.y);
Invalidate(FALSE);
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
}
+ else if (m_hitSelection != HIT_NONE)
+ {
+ EndSelectionDrag(pt);
+ }
ReleaseCapture();
return 0;
}
void CImgAreaWindow::cancelDrawing()
{
+ selectionModel.ClearColor();
+ selectionModel.ClearMask();
+ m_hitSelection = HIT_NONE;
drawing = FALSE;
toolsModel.OnCancelDraw();
Invalidate(FALSE);
@@ -226,7 +307,7 @@ LRESULT CImgAreaWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL&
}
else
{
- if (drawing || ToolBase::pointSP != 0 || selectionWindow.IsWindowVisible())
+ if (drawing || ToolBase::pointSP != 0 || selectionModel.m_bShow)
cancelDrawing();
}
}
@@ -235,22 +316,34 @@ LRESULT CImgAreaWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL&
LRESULT CImgAreaWindow::OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
+ POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ UnZoomed(pt);
if (drawing)
{
drawing = FALSE;
- INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
- toolsModel.OnButtonUp(FALSE, UnZoomed(x), UnZoomed(y));
+ toolsModel.OnButtonUp(FALSE, pt.x, pt.y);
Invalidate(FALSE);
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
}
+ else if (m_hitSelection != HIT_NONE)
+ {
+ EndSelectionDrag(pt);
+ }
ReleaseCapture();
return 0;
}
LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
{
- LONG xNow = UnZoomed(GET_X_LPARAM(lParam));
- LONG yNow = UnZoomed(GET_Y_LPARAM(lParam));
+ POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
+ UnZoomed(pt);
+
+ if (m_hitSelection != HIT_NONE)
+ {
+ SelectionDragging(pt);
+ return 0;
+ }
+
if ((!drawing) || (toolsModel.GetActiveTool() <= TOOL_AIRBRUSH))
{
TRACKMOUSEEVENT tme;
@@ -271,26 +364,26 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOO
if (!drawing)
{
CString strCoord;
- strCoord.Format(_T("%ld, %ld"), xNow, yNow);
+ strCoord.Format(_T("%ld, %ld"), pt.x, pt.y);
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord);
}
}
if (drawing)
{
/* values displayed in statusbar */
- LONG xRel = xNow - start.x;
- LONG yRel = yNow - start.y;
+ LONG xRel = pt.x - start.x;
+ LONG yRel = pt.y - start.y;
/* freesel, rectsel and text tools always show numbers limited to fit into image
area */
if ((toolsModel.GetActiveTool() == TOOL_FREESEL) || (toolsModel.GetActiveTool()
== TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_TEXT))
{
if (xRel < 0)
- xRel = (xNow < 0) ? -start.x : xRel;
- else if (xNow > imageModel.GetWidth())
+ xRel = (pt.x < 0) ? -start.x : xRel;
+ else if (pt.x > imageModel.GetWidth())
xRel = imageModel.GetWidth() - start.x;
if (yRel < 0)
- yRel = (yNow < 0) ? -start.y : yRel;
- else if (yNow > imageModel.GetHeight())
- yRel = imageModel.GetHeight() - start.y;
+ yRel = (pt.y < 0) ? -start.y : yRel;
+ else if (pt.y > imageModel.GetHeight())
+ yRel = imageModel.GetHeight() - start.y;
}
/* rectsel and shape tools always show non-negative numbers when drawing */
if ((toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool()
== TOOL_SHAPE))
@@ -310,7 +403,7 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOO
case TOOL_SHAPE:
{
CString strCoord;
- strCoord.Format(_T("%ld, %ld"), xNow, yNow);
+ strCoord.Format(_T("%ld, %ld"), pt.x, pt.y);
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord);
break;
}
@@ -319,7 +412,7 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOO
}
if (wParam & MK_LBUTTON)
{
- toolsModel.OnMouseMove(TRUE, xNow, yNow);
+ toolsModel.OnMouseMove(TRUE, pt.x, pt.y);
Invalidate(FALSE);
if ((toolsModel.GetActiveTool() >= TOOL_TEXT) ||
(toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() ==
TOOL_FREESEL))
{
@@ -332,7 +425,7 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOO
}
if (wParam & MK_RBUTTON)
{
- toolsModel.OnMouseMove(FALSE, xNow, yNow);
+ toolsModel.OnMouseMove(FALSE, pt.x, pt.y);
Invalidate(FALSE);
if (toolsModel.GetActiveTool() >= TOOL_TEXT)
{
diff --git a/base/applications/mspaint/imgarea.h b/base/applications/mspaint/imgarea.h
index daef656590a..941424d0af9 100644
--- a/base/applications/mspaint/imgarea.h
+++ b/base/applications/mspaint/imgarea.h
@@ -13,9 +13,15 @@
class CImgAreaWindow : public CWindowImpl<CImgAreaWindow>
{
public:
- CImgAreaWindow() : drawing(FALSE) { }
+ CImgAreaWindow()
+ : drawing(FALSE)
+ , m_hitSelection(HIT_NONE)
+ {
+ }
BOOL drawing;
+ CANVAS_HITTEST m_hitSelection;
+
void cancelDrawing();
void finishDrawing();
@@ -71,4 +77,8 @@ private:
LRESULT OnCtlColorEdit(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
void drawZoomFrame(int mouseX, int mouseY);
+ CANVAS_HITTEST SelectionHitTest(POINT ptZoomed);
+ void StartSelectionDrag(CANVAS_HITTEST hit, POINT ptUnZoomed);
+ void SelectionDragging(POINT ptUnZoomed);
+ void EndSelectionDrag(POINT ptUnZoomed);
};
diff --git a/base/applications/mspaint/mouse.cpp b/base/applications/mspaint/mouse.cpp
index 57f289487c6..5d1c4fcefea 100644
--- a/base/applications/mspaint/mouse.cpp
+++ b/base/applications/mspaint/mouse.cpp
@@ -16,20 +16,6 @@ POINT ToolBase::pointStack[256] = { { 0 } };
/* FUNCTIONS ********************************************************/
-void
-placeSelWin()
-{
- CRect rc;
- rc.left = Zoomed(selectionModel.GetDestRectLeft());
- rc.top = Zoomed(selectionModel.GetDestRectTop());
- rc.right = rc.left + Zoomed(selectionModel.GetDestRectWidth());
- rc.bottom = rc.top + Zoomed(selectionModel.GetDestRectHeight());
- ::InflateRect(&rc, GRIP_SIZE, GRIP_SIZE);
- selectionWindow.MoveWindow(rc.left, rc.top, rc.Width(), rc.Height(), TRUE);
- selectionWindow.BringWindowToTop();
- imageArea.InvalidateRect(NULL, FALSE);
-}
-
void
regularize(LONG x0, LONG y0, LONG& x1, LONG& y1)
{
@@ -82,8 +68,11 @@ void ToolBase::reset()
pointSP = 0;
start.x = start.y = last.x = last.y = -1;
selectionModel.ResetPtStack();
- if (selectionWindow.IsWindow())
- selectionWindow.ShowWindow(SW_HIDE);
+ if (selectionModel.m_bShow)
+ {
+ selectionModel.Landing();
+ selectionModel.m_bShow = FALSE;
+ }
}
void ToolBase::OnCancelDraw()
@@ -121,12 +110,14 @@ struct FreeSelTool : ToolBase
void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
{
+ selectionModel.Landing();
if (bLeftButton)
{
imageModel.CopyPrevious();
- selectionWindow.ShowWindow(SW_HIDE);
+ selectionModel.m_bShow = FALSE;
selectionModel.ResetPtStack();
- selectionModel.PushToPtStack(x, y);
+ POINT pt = { x, y };
+ selectionModel.PushToPtStack(pt);
}
m_bLeftButton = bLeftButton;
}
@@ -137,7 +128,7 @@ struct FreeSelTool : ToolBase
{
POINT pt = { x, y };
imageModel.Bound(pt);
- selectionModel.PushToPtStack(pt.x, pt.y);
+ selectionModel.PushToPtStack(pt);
imageModel.ResetToPrevious();
selectionModel.DrawFramePoly(m_hdc);
}
@@ -150,28 +141,25 @@ struct FreeSelTool : ToolBase
imageModel.ResetToPrevious();
if (selectionModel.PtStackSize() > 2)
{
- selectionModel.CalculateBoundingBoxAndContents(m_hdc);
- placeSelWin();
- selectionWindow.IsMoved(FALSE);
- selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
+ selectionModel.BuildMaskFromPtStack();
+ selectionModel.TakeOff();
+ selectionModel.m_bShow = TRUE;
}
else
{
imageModel.Undo(TRUE);
- selectionWindow.IsMoved(FALSE);
selectionModel.ResetPtStack();
- selectionWindow.ShowWindow(SW_HIDE);
+ selectionModel.m_bShow = FALSE;
}
+ imageArea.Invalidate(FALSE);
}
}
void OnFinishDraw()
{
if (m_bLeftButton)
- {
- selectionWindow.IsMoved(FALSE);
- selectionWindow.ForceRefreshSelectionContents();
- }
+ imageArea.Invalidate(FALSE);
+
m_bLeftButton = FALSE;
ToolBase::OnFinishDraw();
}
@@ -181,7 +169,6 @@ struct FreeSelTool : ToolBase
if (m_bLeftButton)
imageModel.Undo(TRUE);
m_bLeftButton = FALSE;
- selectionWindow.IsMoved(FALSE);
ToolBase::OnCancelDraw();
}
};
@@ -197,11 +184,12 @@ struct RectSelTool : ToolBase
void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
{
+ selectionModel.Landing();
if (bLeftButton)
{
imageModel.CopyPrevious();
- selectionWindow.ShowWindow(SW_HIDE);
- selectionModel.SetSrcRectSizeToZero();
+ selectionModel.m_bShow = FALSE;
+ ::SetRectEmpty(&selectionModel.m_rc);
}
m_bLeftButton = bLeftButton;
}
@@ -213,7 +201,7 @@ struct RectSelTool : ToolBase
imageModel.ResetToPrevious();
POINT pt = { x, y };
imageModel.Bound(pt);
- selectionModel.SetSrcAndDestRectFromPoints(start, pt);
+ selectionModel.SetRectFromPoints(start, pt);
RectSel(m_hdc, start.x, start.y, pt.x, pt.y);
}
}
@@ -225,23 +213,16 @@ struct RectSelTool : ToolBase
imageModel.ResetToPrevious();
if (start.x == x && start.y == y)
imageModel.Undo(TRUE);
- selectionModel.CalculateContents(m_hdc);
- placeSelWin();
- selectionWindow.IsMoved(FALSE);
- if (selectionModel.IsSrcRectSizeNonzero())
- selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
- else
- selectionWindow.ShowWindow(SW_HIDE);
+ selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty();
+ imageArea.Invalidate(FALSE);
}
}
void OnFinishDraw()
{
if (m_bLeftButton)
- {
- selectionWindow.IsMoved(FALSE);
- selectionWindow.ForceRefreshSelectionContents();
- }
+ imageArea.Invalidate(FALSE);
+
m_bLeftButton = FALSE;
ToolBase::OnFinishDraw();
}
@@ -251,7 +232,6 @@ struct RectSelTool : ToolBase
if (m_bLeftButton)
imageModel.Undo(TRUE);
m_bLeftButton = FALSE;
- selectionWindow.IsMoved(FALSE);
ToolBase::OnCancelDraw();
}
};
@@ -430,7 +410,7 @@ struct TextTool : ToolBase
imageModel.ResetToPrevious();
POINT pt = { x, y };
imageModel.Bound(pt);
- selectionModel.SetSrcAndDestRectFromPoints(start, pt);
+ selectionModel.SetRectFromPoints(start, pt);
RectSel(m_hdc, start.x, start.y, pt.x, pt.y);
}
@@ -452,6 +432,10 @@ struct TextTool : ToolBase
{
imageModel.Undo(TRUE);
+ POINT pt = { x, y };
+ imageModel.Bound(pt);
+ selectionModel.SetRectFromPoints(start, pt);
+
BOOL bTextBoxShown = ::IsWindowVisible(textEditWindow);
if (bTextBoxShown && textEditWindow.GetWindowTextLength() > 0)
{
@@ -466,6 +450,13 @@ struct TextTool : ToolBase
imageModel.CopyPrevious();
Text(m_hdc, rc.left, rc.top, rc.right, rc.bottom, m_fg, m_bg, szText,
textEditWindow.GetFont(), style);
+
+ if (selectionModel.m_rc.IsRectEmpty())
+ {
+ textEditWindow.ShowWindow(SW_HIDE);
+ textEditWindow.SetWindowText(NULL);
+ return;
+ }
}
if (registrySettings.ShowTextTool)
@@ -476,45 +467,35 @@ struct TextTool : ToolBase
fontsDialog.ShowWindow(SW_SHOWNOACTIVATE);
}
- if (!bTextBoxShown || selectionModel.IsSrcRectSizeNonzero())
- {
- RECT rc;
- selectionModel.GetRect(&rc);
+ RECT rc = selectionModel.m_rc;
- // Enlarge if tool small
- INT cxMin = CX_MINTEXTEDIT, cyMin = CY_MINTEXTEDIT;
- if (selectionModel.IsSrcRectSizeNonzero())
- {
- if (rc.right - rc.left < cxMin)
- rc.right = rc.left + cxMin;
- if (rc.bottom - rc.top < cyMin)
- rc.bottom = rc.top + cyMin;
- }
- else
- {
- SetRect(&rc, x, y, x + cxMin, y + cyMin);
- }
-
- if (!textEditWindow.IsWindow())
- textEditWindow.Create(imageArea);
-
- textEditWindow.SetWindowText(NULL);
- textEditWindow.ValidateEditRect(&rc);
- textEditWindow.ShowWindow(SW_SHOWNOACTIVATE);
- textEditWindow.SetFocus();
+ // Enlarge if tool small
+ INT cxMin = CX_MINTEXTEDIT, cyMin = CY_MINTEXTEDIT;
+ if (selectionModel.m_rc.IsRectEmpty())
+ {
+ SetRect(&rc, x, y, x + cxMin, y + cyMin);
}
else
{
- textEditWindow.ShowWindow(SW_HIDE);
- textEditWindow.SetWindowText(NULL);
+ if (rc.right - rc.left < cxMin)
+ rc.right = rc.left + cxMin;
+ if (rc.bottom - rc.top < cyMin)
+ rc.bottom = rc.top + cyMin;
}
+
+ if (!textEditWindow.IsWindow())
+ textEditWindow.Create(imageArea);
+
+ textEditWindow.SetWindowText(NULL);
+ textEditWindow.ValidateEditRect(&rc);
+ textEditWindow.ShowWindow(SW_SHOWNOACTIVATE);
+ textEditWindow.SetFocus();
}
void OnFinishDraw()
{
toolsModel.OnButtonDown(TRUE, -1, -1, TRUE);
toolsModel.OnButtonUp(TRUE, -1, -1);
- selectionWindow.IsMoved(FALSE);
ToolBase::OnFinishDraw();
}
};
diff --git a/base/applications/mspaint/palettemodel.cpp
b/base/applications/mspaint/palettemodel.cpp
index b4ae440658f..cf920bc43e0 100644
--- a/base/applications/mspaint/palettemodel.cpp
+++ b/base/applications/mspaint/palettemodel.cpp
@@ -97,8 +97,8 @@ void PaletteModel::NotifyColorChanged()
{
if (paletteWindow.IsWindow())
paletteWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED);
- if (selectionWindow.IsWindow())
- selectionWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED);
+ if (imageArea.IsWindow())
+ imageArea.SendMessage(WM_PALETTEMODELCOLORCHANGED);
if (textEditWindow.IsWindow())
textEditWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED);
}
diff --git a/base/applications/mspaint/precomp.h b/base/applications/mspaint/precomp.h
index 5dda7a9c682..ae4e584e229 100644
--- a/base/applications/mspaint/precomp.h
+++ b/base/applications/mspaint/precomp.h
@@ -43,7 +43,6 @@
#include "palette.h"
#include "palettemodel.h"
#include "registry.h"
-#include "selection.h"
#include "selectionmodel.h"
#include "sizebox.h"
#include "canvas.h"
diff --git a/base/applications/mspaint/selection.cpp
b/base/applications/mspaint/selection.cpp
deleted file mode 100644
index 1426e086d59..00000000000
--- a/base/applications/mspaint/selection.cpp
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * PROJECT: PAINT for ReactOS
- * LICENSE: LGPL
- * FILE: base/applications/mspaint/selection.cpp
- * PURPOSE: Window procedure of the selection window
- * PROGRAMMERS: Benedikt Freisen
- * Katayama Hirofumi MZ
- */
-
-#include "precomp.h"
-
-CSelectionWindow selectionWindow;
-
-/* FUNCTIONS ********************************************************/
-
-const LPCTSTR CSelectionWindow::m_lpszCursorLUT[9] = { /* action to mouse cursor lookup
table */
- IDC_SIZEALL,
-
- IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW,
- IDC_SIZEWE, IDC_SIZEWE,
- IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE
-};
-
-void CSelectionWindow::ForceRefreshSelectionContents()
-{
- if (::IsWindowVisible(selectionWindow))
- {
- imageModel.ResetToPrevious();
- imageModel.DrawSelectionBackground(m_rgbBack);
- selectionModel.DrawSelection(imageModel.GetDC(), paletteModel.GetBgColor(),
toolsModel.IsBackgroundTransparent());
- }
-}
-
-int CSelectionWindow::IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight)
-{
- return 0;
-}
-
-LRESULT CSelectionWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
-{
- PAINTSTRUCT ps;
- HDC hDC = BeginPaint(&ps);
- if (!m_bMoving)
- {
- RECT rcClient;
- GetClientRect(&rcClient);
- drawSizeBoxes(hDC, &rcClient, TRUE, &ps.rcPaint);
- }
- EndPaint(&ps);
- return 0;
-}
-
-LRESULT CSelectionWindow::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
-{
- // do nothing => transparent background
- return TRUE;
-}
-
-LRESULT CSelectionWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
-{
- m_bMoving = FALSE;
- m_iAction = ACTION_MOVE;
- /* update the system selection color */
- Invalidate();
- return 0;
-}
-
-LRESULT CSelectionWindow::OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
-{
- /* update the system selection color */
- Invalidate();
- return 0;
-}
-
-LRESULT CSelectionWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
-{
- RECT rcClient;
- GetClientRect(&rcClient);
-
- POINT pt;
- ::GetCursorPos(&pt);
- ScreenToClient(&pt);
-
- if (!setCursorOnSizeBox(getSizeBoxHitTest(pt, &rcClient)))
- ::SetCursor(::LoadCursor(NULL, IDC_SIZEALL));
-
- return 0;
-}
-
-LRESULT CSelectionWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
-{
- m_ptPos.x = GET_X_LPARAM(lParam);
- m_ptPos.y = GET_Y_LPARAM(lParam);
- m_ptDelta.x = 0;
- m_ptDelta.y = 0;
- SetCapture();
- if (m_iAction != ACTION_MOVE)
- SetCursor(LoadCursor(NULL, m_lpszCursorLUT[m_iAction]));
- m_bMoving = TRUE;
- imageArea.InvalidateRect(NULL, FALSE);
- imageArea.SendMessage(WM_PAINT, 0, 0);
- m_rgbBack = paletteModel.GetBgColor();
- return 0;
-}
-
-LRESULT CSelectionWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
-{
- if (m_bMoving)
- {
- imageModel.ResetToPrevious();
- imageModel.DrawSelectionBackground(m_rgbBack);
- m_ptFrac.x += GET_X_LPARAM(lParam) - m_ptPos.x;
- m_ptFrac.y += GET_Y_LPARAM(lParam) - m_ptPos.y;
- m_ptDelta.x += UnZoomed(m_ptFrac.x);
- m_ptDelta.y += UnZoomed(m_ptFrac.y);
- if (toolsModel.GetZoom() < 1000)
- {
- m_ptFrac.x = 0;
- m_ptFrac.y = 0;
- }
- else
- {
- m_ptFrac.x -= Zoomed(UnZoomed(m_ptFrac.x));
- m_ptFrac.y -= Zoomed(UnZoomed(m_ptFrac.y));
- }
- selectionModel.ModifyDestRect(m_ptDelta, m_iAction);
-
- CString strSize;
- strSize.Format(_T("%ld x %ld"), selectionModel.GetDestRectWidth(),
selectionModel.GetDestRectHeight());
- SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize);
-
- if (m_iAction != ACTION_MOVE)
- selectionModel.DrawSelectionStretched(imageModel.GetDC());
- else
- selectionModel.DrawSelection(imageModel.GetDC(), paletteModel.GetBgColor(),
toolsModel.IsBackgroundTransparent());
- imageArea.InvalidateRect(NULL, FALSE);
- imageArea.SendMessage(WM_PAINT, 0, 0);
- m_ptPos.x = GET_X_LPARAM(lParam);
- m_ptPos.y = GET_Y_LPARAM(lParam);
- }
- else
- {
- int w = Zoomed(selectionModel.GetDestRectWidth()) + 2 * GRIP_SIZE;
- int h = Zoomed(selectionModel.GetDestRectHeight()) + 2 * GRIP_SIZE;
- m_ptPos.x = GET_X_LPARAM(lParam);
- m_ptPos.y = GET_Y_LPARAM(lParam);
- SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) NULL);
- m_iAction = IdentifyCorner(m_ptPos.x, m_ptPos.y, w, h);
- if (m_iAction != ACTION_MOVE)
- SetCursor(LoadCursor(NULL, m_lpszCursorLUT[m_iAction]));
- }
- return 0;
-}
-
-LRESULT CSelectionWindow::OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
-{
- m_bMoved = TRUE;
- return 0;
-}
-
-LRESULT CSelectionWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
-{
- if (m_bMoving)
- {
- m_bMoving = FALSE;
- ReleaseCapture();
- if (m_iAction != ACTION_MOVE && toolsModel.GetActiveTool() != TOOL_TEXT)
- {
- imageModel.Undo();
- imageModel.DrawSelectionBackground(m_rgbBack);
- selectionModel.ScaleContentsToFit();
- imageModel.CopyPrevious();
- }
- placeSelWin();
- }
- return 0;
-}
-
-LRESULT CSelectionWindow::OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
-{
- if (m_bMoving)
- {
- m_bMoving = FALSE;
- if (m_iAction == ACTION_MOVE)
- {
- if (toolsModel.GetActiveTool() == TOOL_RECTSEL)
- imageArea.cancelDrawing();
- else
- placeSelWin();
- }
- else
- {
- m_iAction = ACTION_MOVE;
- }
- ShowWindow(SW_HIDE);
- }
- return 0;
-}
-
-LRESULT CSelectionWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
-{
- if (wParam == VK_ESCAPE)
- {
- if (GetCapture() == m_hWnd)
- {
- ReleaseCapture();
- }
- }
- return 0;
-}
-
-LRESULT CSelectionWindow::OnPaletteModelColorChanged(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bHandled)
-{
- return 0;
-}
-
-LRESULT CSelectionWindow::OnToolsModelSettingsChanged(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bHandled)
-{
- return 0;
-}
-
-LRESULT CSelectionWindow::OnSelectionModelRefreshNeeded(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bHandled)
-{
- ForceRefreshSelectionContents();
- return 0;
-}
-
-LRESULT CSelectionWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
-{
- return ::SendMessage(GetParent(), nMsg, wParam, lParam);
-}
-
-LRESULT CSelectionWindow::OnToolsModelZoomChanged(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bHandled)
-{
- placeSelWin();
- return 0;
-}
diff --git a/base/applications/mspaint/selection.h
b/base/applications/mspaint/selection.h
deleted file mode 100644
index 8e61b77d9ef..00000000000
--- a/base/applications/mspaint/selection.h
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * PROJECT: PAINT for ReactOS
- * LICENSE: LGPL
- * FILE: base/applications/mspaint/selection.h
- * PURPOSE: Window procedure of the selection window
- * PROGRAMMERS: Benedikt Freisen
- * Katayama Hirofumi MZ
- */
-
-#pragma once
-
-class CSelectionWindow : public CWindowImpl<CSelectionWindow>
-{
-public:
- CSelectionWindow() : m_bMoved(FALSE)
- {
- }
-
- BOOL IsMoved() const { return m_bMoved; }
- void IsMoved(BOOL bMoved) { m_bMoved = bMoved; }
-
- void ForceRefreshSelectionContents();
-
- DECLARE_WND_CLASS_EX(_T("Selection"), CS_DBLCLKS, COLOR_BTNFACE)
-
- BEGIN_MSG_MAP(CSelectionWindow)
- MESSAGE_HANDLER(WM_PAINT, OnPaint)
- MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
- MESSAGE_HANDLER(WM_CREATE, OnCreate)
- MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange)
- MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
- MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
- MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
- MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
- MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
- MESSAGE_HANDLER(WM_MOVE, OnMove)
- MESSAGE_HANDLER(WM_PALETTEMODELCOLORCHANGED, OnPaletteModelColorChanged)
- MESSAGE_HANDLER(WM_TOOLSMODELSETTINGSCHANGED, OnToolsModelSettingsChanged)
- MESSAGE_HANDLER(WM_TOOLSMODELZOOMCHANGED, OnToolsModelZoomChanged)
- MESSAGE_HANDLER(WM_SELECTIONMODELREFRESHNEEDED, OnSelectionModelRefreshNeeded)
- MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
- MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
- END_MSG_MAP()
-
- LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled);
- LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT OnPaletteModelColorChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled);
- LRESULT OnToolsModelSettingsChanged(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled);
- LRESULT OnToolsModelZoomChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled);
- LRESULT OnSelectionModelRefreshNeeded(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled);
- LRESULT OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled);
- LRESULT OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
- LRESULT OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
-
-private:
- static const LPCTSTR m_lpszCursorLUT[9];
- BOOL m_bMoved;
- BOOL m_bMoving;
- int m_iAction;
- POINT m_ptPos;
- POINT m_ptFrac;
- POINT m_ptDelta;
- COLORREF m_rgbBack;
-
- int IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight);
-};
-
-void ForceRefreshSelectionContents();
diff --git a/base/applications/mspaint/selectionmodel.cpp
b/base/applications/mspaint/selectionmodel.cpp
index 2079f7afd9b..f7c61d16c28 100644
--- a/base/applications/mspaint/selectionmodel.cpp
+++ b/base/applications/mspaint/selectionmodel.cpp
@@ -14,225 +14,295 @@ SelectionModel selectionModel;
/* FUNCTIONS ********************************************************/
SelectionModel::SelectionModel()
- : m_hDC(CreateCompatibleDC(NULL))
- , m_hBm(NULL)
- , m_hMask(NULL)
+ : m_hbmColor(NULL)
+ , m_hbmMask(NULL)
, m_ptStack(NULL)
, m_iPtSP(0)
+ , m_bShow(FALSE)
{
- SetRectEmpty(&m_rcSrc);
- SetRectEmpty(&m_rcDest);
+ ::SetRectEmpty(&m_rc);
+ m_ptHit.x = m_ptHit.y = -1;
}
SelectionModel::~SelectionModel()
{
- DeleteDC(m_hDC);
+ ClearColor();
+ ClearMask();
ResetPtStack();
- if (m_hBm)
- {
- DeleteObject(m_hBm);
- }
- if (m_hMask)
- {
- DeleteObject(m_hMask);
- }
}
void SelectionModel::ResetPtStack()
{
- if (m_ptStack != NULL)
- HeapFree(GetProcessHeap(), 0, m_ptStack);
- m_ptStack = NULL;
+ if (m_ptStack)
+ {
+ free(m_ptStack);
+ m_ptStack = NULL;
+ }
m_iPtSP = 0;
}
-void SelectionModel::PushToPtStack(LONG x, LONG y)
+void SelectionModel::PushToPtStack(POINT pt)
{
- if (m_iPtSP % 1024 == 0)
+#define GROW_COUNT 256
+ if (m_iPtSP % GROW_COUNT == 0)
{
- if (m_ptStack)
- m_ptStack = (POINT*) HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS,
m_ptStack, sizeof(POINT) * (m_iPtSP + 1024));
- else
- m_ptStack = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS,
sizeof(POINT) * 1024);
+ 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].x = x;
- m_ptStack[m_iPtSP].y = y;
+ m_ptStack[m_iPtSP] = pt;
m_iPtSP++;
+#undef GROW_COUNT
}
-void SelectionModel::CalculateBoundingBoxAndContents(HDC hDCImage)
+void SelectionModel::ShiftPtStack(BOOL bPlus)
{
- int i;
- m_rcSrc.left = m_rcSrc.top = MAXLONG;
- m_rcSrc.right = m_rcSrc.bottom = 0;
- for (i = 0; i < m_iPtSP; i++)
+ if (bPlus)
{
- if (m_ptStack[i].x < m_rcSrc.left)
- m_rcSrc.left = m_ptStack[i].x;
- if (m_ptStack[i].y < m_rcSrc.top)
- m_rcSrc.top = m_ptStack[i].y;
- if (m_ptStack[i].x > m_rcSrc.right)
- m_rcSrc.right = m_ptStack[i].x;
- if (m_ptStack[i].y > m_rcSrc.bottom)
- m_rcSrc.bottom = m_ptStack[i].y;
+ for (INT i = 0; i < m_iPtSP; ++i)
+ {
+ POINT& pt = m_ptStack[i];
+ pt.x += m_rc.left;
+ pt.y += m_rc.top;
+ }
}
- m_rcSrc.right += 1;
- m_rcSrc.bottom += 1;
- m_rcDest.left = m_rcSrc.left;
- m_rcDest.top = m_rcSrc.top;
- m_rcDest.right = m_rcSrc.right;
- m_rcDest.bottom = m_rcSrc.bottom;
-
- if (m_iPtSP > 1)
+ else
{
- DeleteObject(m_hMask);
- m_hMask = CreateBitmap(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 1, 1, NULL);
- DeleteObject(SelectObject(m_hDC, m_hMask));
- POINT *m_ptStackCopy = (POINT*) HeapAlloc(GetProcessHeap(),
HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * m_iPtSP);
- for (i = 0; i < m_iPtSP; i++)
+ for (INT i = 0; i < m_iPtSP; ++i)
{
- m_ptStackCopy[i].x = m_ptStack[i].x - m_rcSrc.left;
- m_ptStackCopy[i].y = m_ptStack[i].y - m_rcSrc.top;
+ POINT& pt = m_ptStack[i];
+ pt.x -= m_rc.left;
+ pt.y -= m_rc.top;
}
- Poly(m_hDC, m_ptStackCopy, m_iPtSP, 0x00ffffff, 0x00ffffff, 1, 2, TRUE, FALSE);
- HeapFree(GetProcessHeap(), 0, m_ptStackCopy);
- SelectObject(m_hDC, m_hBm = CreateDIBWithProperties(RECT_WIDTH(m_rcSrc),
RECT_HEIGHT(m_rcSrc)));
- imageModel.ResetToPrevious();
- MaskBlt(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), hDCImage,
m_rcSrc.left,
- m_rcSrc.top, m_hMask, 0, 0, MAKEROP4(SRCCOPY, WHITENESS));
}
}
-void SelectionModel::CalculateContents(HDC hDCImage)
+void SelectionModel::BuildMaskFromPtStack()
{
- DeleteObject(m_hMask);
- m_hMask = CreateBitmap(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 1, 1, NULL);
- DeleteObject(SelectObject(m_hDC, m_hMask));
- Rect(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 0x00ffffff, 0x00ffffff,
1, 2);
- SelectObject(m_hDC, m_hBm = CreateDIBWithProperties(RECT_WIDTH(m_rcSrc),
RECT_HEIGHT(m_rcSrc)));
- BitBlt(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), hDCImage,
m_rcSrc.left,
- m_rcSrc.top, SRCCOPY);
+ CRect rc = { MAXLONG, MAXLONG, 0, 0 };
+ for (INT i = 0; i < m_iPtSP; ++i)
+ {
+ POINT& pt = m_ptStack[i];
+ rc.left = min(pt.x, rc.left);
+ rc.top = min(pt.y, rc.top);
+ rc.right = max(pt.x, rc.right);
+ rc.bottom = max(pt.y, rc.bottom);
+ }
+ rc.right += 1;
+ rc.bottom += 1;
+
+ m_rc = rc;
+
+ ShiftPtStack(FALSE);
+
+ ClearMask();
+
+ 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);
}
void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg)
{
- Poly(hDCImage, m_ptStack, m_iPtSP, crBg, crBg, 1, 2, TRUE, FALSE);
+ ShiftPtStack(TRUE);
+
+ 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);
+
+ ShiftPtStack(FALSE);
}
void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg)
{
- Rect(hDCImage, m_rcSrc.left, m_rcSrc.top, m_rcSrc.right, m_rcSrc.bottom, crBg, crBg,
0, 1);
+ Rect(hDCImage, m_rc.left, m_rc.top, m_rc.right, m_rc.bottom, crBg, crBg, 0, 1);
}
-void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent)
+void SelectionModel::DrawSelection(HDC hDCImage, LPCRECT prc, COLORREF crBg, BOOL
bBgTransparent)
{
- if (!bBgTransparent)
- MaskBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest),
RECT_HEIGHT(m_rcDest),
- m_hDC, 0, 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
- else
- ColorKeyedMaskBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest),
RECT_HEIGHT(m_rcDest),
- m_hDC, 0, 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND), crBg);
+ CRect rc = *prc;
+ if (::IsRectEmpty(&rc))
+ return;
+
+ BITMAP bm;
+ GetObject(m_hbmColor, sizeof(BITMAP), &bm);
+
+ COLORREF keyColor = (bBgTransparent ? crBg : CLR_INVALID);
+
+ HDC hMemDC = CreateCompatibleDC(hDCImage);
+ HGDIOBJ hbmOld = SelectObject(hMemDC, m_hbmColor);
+ ColorKeyedMaskBlt(hDCImage, rc.left, rc.top, rc.Width(), rc.Height(),
+ hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, m_hbmMask, keyColor);
+ SelectObject(hMemDC, hbmOld);
+ DeleteDC(hMemDC);
+}
+
+void SelectionModel::GetSelectionContents(HDC hDCImage)
+{
+ ClearColor();
+
+ HDC hMemDC = ::CreateCompatibleDC(NULL);
+ m_hbmColor = CreateColorDIB(m_rc.Width(), m_rc.Height(), RGB(255, 255, 255));
+ HGDIOBJ hbmOld = ::SelectObject(hMemDC, m_hbmColor);
+ ::BitBlt(hMemDC, 0, 0, m_rc.Width(), m_rc.Height(), hDCImage, m_rc.left, m_rc.top,
SRCCOPY);
+ ::SelectObject(hMemDC, hbmOld);
+ ::DeleteDC(hMemDC);
}
-void SelectionModel::DrawSelectionStretched(HDC hDCImage)
+BOOL SelectionModel::TakeOff()
{
- StretchBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest),
RECT_HEIGHT(m_rcDest), m_hDC, 0, 0, GetDIBWidth(m_hBm), GetDIBHeight(m_hBm), SRCCOPY);
+ if (m_hbmColor || ::IsRectEmpty(&m_rc))
+ return FALSE;
+
+ HDC hDCImage = imageModel.GetDC();
+ GetSelectionContents(hDCImage);
+
+ if (toolsModel.GetActiveTool() == TOOL_FREESEL)
+ {
+ DrawBackgroundPoly(hDCImage, paletteModel.GetBgColor());
+ }
+ else
+ {
+ ClearMask();
+ DrawBackgroundRect(hDCImage, paletteModel.GetBgColor());
+ }
+
+ imageArea.Invalidate(FALSE);
+ return TRUE;
}
-void SelectionModel::ScaleContentsToFit()
+void SelectionModel::Landing()
{
- HDC hTempDC;
- HBITMAP hTempBm;
- hTempDC = CreateCompatibleDC(m_hDC);
- hTempBm = CreateDIBWithProperties(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest));
- SelectObject(hTempDC, hTempBm);
- SelectObject(m_hDC, m_hBm);
- StretchBlt(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0,
- GetDIBWidth(m_hBm), GetDIBHeight(m_hBm), SRCCOPY);
- DeleteObject(m_hBm);
- m_hBm = hTempBm;
- hTempBm = CreateBitmap(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 1, 1, NULL);
- SelectObject(hTempDC, hTempBm);
- SelectObject(m_hDC, m_hMask);
- StretchBlt(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0,
- GetDIBWidth(m_hMask), GetDIBHeight(m_hMask), SRCCOPY);
- DeleteObject(m_hMask);
- m_hMask = hTempBm;
- SelectObject(m_hDC, m_hBm);
- DeleteDC(hTempDC);
+ if (!m_hbmColor)
+ return;
+
+ DrawSelection(imageModel.GetDC(), &m_rc, paletteModel.GetBgColor(),
toolsModel.IsBackgroundTransparent());
+
+ ::SetRectEmpty(&m_rc);
+ ClearMask();
+ ClearColor();
+
+ imageModel.CopyPrevious();
}
void SelectionModel::InsertFromHBITMAP(HBITMAP hBm, INT x, INT y)
{
- HDC hTempDC;
- HBITMAP hTempMask;
-
- m_hBm = CopyDIBImage(hBm);
- DeleteObject(SelectObject(m_hDC, m_hBm));
-
- SetRectEmpty(&m_rcSrc);
- m_rcDest.left = x;
- m_rcDest.top = y;
- m_rcDest.right = m_rcDest.left + GetDIBWidth(m_hBm);
- m_rcDest.bottom = m_rcDest.top + GetDIBHeight(m_hBm);
-
- hTempDC = CreateCompatibleDC(m_hDC);
- hTempMask = CreateBitmap(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 1, 1, NULL);
- SelectObject(hTempDC, hTempMask);
- Rect(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 0x00ffffff,
0x00ffffff, 1, 1);
- DeleteObject(m_hMask);
- m_hMask = hTempMask;
- DeleteDC(hTempDC);
+ m_hbmColor = CopyDIBImage(hBm);
+ ::DeleteObject(m_hbmColor);
+
+ m_rc.left = x;
+ m_rc.top = y;
+ m_rc.right = m_rc.left + GetDIBWidth(hBm);
+ m_rc.bottom = m_rc.top + GetDIBHeight(hBm);
+
+ ClearMask();
}
void SelectionModel::FlipHorizontally()
{
- SelectObject(m_hDC, m_hMask);
- StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, 0, -RECT_WIDTH(m_rcDest),
RECT_HEIGHT(m_rcDest), m_hDC,
- 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
- SelectObject(m_hDC, m_hBm);
- StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, 0, -RECT_WIDTH(m_rcDest),
RECT_HEIGHT(m_rcDest), m_hDC,
- 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
+ TakeOff();
+
+ HDC hdcMem = ::CreateCompatibleDC(NULL);
+ if (m_hbmMask)
+ {
+ ::SelectObject(hdcMem, m_hbmMask);
+ ::StretchBlt(hdcMem, m_rc.Width() - 1, 0, -m_rc.Width(), m_rc.Height(),
+ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
+ }
+ if (m_hbmColor)
+ {
+ ::SelectObject(hdcMem, m_hbmColor);
+ ::StretchBlt(hdcMem, m_rc.Width() - 1, 0, -m_rc.Width(), m_rc.Height(),
+ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
+ }
+ ::DeleteDC(hdcMem);
+
NotifyRefreshNeeded();
}
void SelectionModel::FlipVertically()
{
- SelectObject(m_hDC, m_hMask);
- StretchBlt(m_hDC, 0, RECT_HEIGHT(m_rcDest) - 1, RECT_WIDTH(m_rcDest),
-RECT_HEIGHT(m_rcDest), m_hDC,
- 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
- SelectObject(m_hDC, m_hBm);
- StretchBlt(m_hDC, 0, RECT_HEIGHT(m_rcDest) - 1, RECT_WIDTH(m_rcDest),
-RECT_HEIGHT(m_rcDest), m_hDC,
- 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
+ TakeOff();
+
+ HDC hdcMem = ::CreateCompatibleDC(NULL);
+ if (m_hbmMask)
+ {
+ ::SelectObject(hdcMem, m_hbmMask);
+ ::StretchBlt(hdcMem, 0, m_rc.Height() - 1, m_rc.Width(), -m_rc.Height(),
+ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
+ }
+ if (m_hbmColor)
+ {
+ ::SelectObject(hdcMem, m_hbmColor);
+ ::StretchBlt(hdcMem, 0, m_rc.Height() - 1, m_rc.Width(), -m_rc.Height(),
+ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
+ }
+ ::DeleteDC(hdcMem);
+
NotifyRefreshNeeded();
}
void SelectionModel::RotateNTimes90Degrees(int iN)
{
HBITMAP hbm;
+ HGDIOBJ hbmOld;
+ HDC hdcMem = ::CreateCompatibleDC(NULL);
+
switch (iN)
{
- case 1:
- case 3:
- imageModel.DeleteSelection();
- imageModel.CopyPrevious();
- SelectObject(m_hDC, m_hBm);
- hbm = Rotate90DegreeBlt(m_hDC, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), iN ==
1);
- InsertFromHBITMAP(hbm, m_rcDest.left, m_rcDest.top);
- DeleteObject(hbm);
- selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
- selectionWindow.ForceRefreshSelectionContents();
- placeSelWin();
- break;
- case 2:
- SelectObject(m_hDC, m_hMask);
- StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, RECT_HEIGHT(m_rcDest) - 1,
-RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC,
- 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
- SelectObject(m_hDC, m_hBm);
- StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, RECT_HEIGHT(m_rcDest) - 1,
-RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC,
- 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
- break;
+ case 1:
+ case 3:
+ TakeOff();
+ if (m_hbmColor)
+ {
+ hbmOld = ::SelectObject(hdcMem, m_hbmColor);
+ hbm = Rotate90DegreeBlt(hdcMem, m_rc.Width(), m_rc.Height(), iN == 1,
FALSE);
+ ::SelectObject(hdcMem, hbmOld);
+ ::DeleteObject(m_hbmColor);
+ m_hbmColor = hbm;
+ }
+ if (m_hbmMask)
+ {
+ hbmOld = ::SelectObject(hdcMem, m_hbmMask);
+ hbm = Rotate90DegreeBlt(hdcMem, m_rc.Width(), m_rc.Height(), iN == 1,
TRUE);
+ ::SelectObject(hdcMem, hbmOld);
+ ::DeleteObject(m_hbmMask);
+ m_hbmMask = hbm;
+ }
+ break;
+
+ case 2:
+ TakeOff();
+ if (m_hbmColor)
+ {
+ hbmOld = ::SelectObject(hdcMem, m_hbmColor);
+ ::StretchBlt(hdcMem, m_rc.Width() - 1, m_rc.Height() - 1, -m_rc.Width(),
-m_rc.Height(),
+ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
+ ::SelectObject(hdcMem, hbmOld);
+ }
+ if (m_hbmMask)
+ {
+ hbmOld = ::SelectObject(hdcMem, m_hbmMask);
+ ::StretchBlt(hdcMem, m_rc.Width() - 1, m_rc.Height() - 1, -m_rc.Width(),
-m_rc.Height(),
+ hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
+ ::SelectObject(hdcMem, hbmOld);
+ }
+ break;
}
+
+ ::DeleteDC(hdcMem);
NotifyRefreshNeeded();
}
@@ -241,47 +311,47 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int
nStretchPercentY, int
if (nStretchPercentX == 100 && nStretchPercentY == 100 && nSkewDegX
== 0 && nSkewDegY == 0)
return;
- imageModel.DeleteSelection();
- imageModel.CopyPrevious();
+ TakeOff();
- INT oldWidth = RECT_WIDTH(m_rcDest);
- INT oldHeight = RECT_HEIGHT(m_rcDest);
+ INT oldWidth = m_rc.Width();
+ INT oldHeight = m_rc.Height();
INT newWidth = oldWidth * nStretchPercentX / 100;
INT newHeight = oldHeight * nStretchPercentY / 100;
if (oldWidth != newWidth || oldHeight != newHeight)
{
- SelectObject(m_hDC, m_hBm);
- HBITMAP hbm0 = CopyDIBImage(m_hBm, newWidth, newHeight);
- InsertFromHBITMAP(hbm0, m_rcDest.left, m_rcDest.top);
- DeleteObject(hbm0);
+ HBITMAP hbm0 = CopyDIBImage(m_hbmColor, newWidth, newHeight);
+ InsertFromHBITMAP(hbm0, m_rc.left, m_rc.top);
+ ::DeleteObject(hbm0);
}
+ HDC hDC = ::CreateCompatibleDC(NULL);
+
if (nSkewDegX)
{
- SelectObject(m_hDC, m_hBm);
- HBITMAP hbm1 = SkewDIB(m_hDC, m_hBm, nSkewDegX, FALSE);
- InsertFromHBITMAP(hbm1, m_rcDest.left, m_rcDest.top);
- DeleteObject(hbm1);
+ ::SelectObject(hDC, m_hbmColor);
+ HBITMAP hbm1 = SkewDIB(hDC, m_hbmColor, nSkewDegX, FALSE);
+ InsertFromHBITMAP(hbm1, m_rc.left, m_rc.top);
+ ::DeleteObject(hbm1);
}
if (nSkewDegY)
{
- SelectObject(m_hDC, m_hBm);
- HBITMAP hbm2 = SkewDIB(m_hDC, m_hBm, nSkewDegY, TRUE);
- InsertFromHBITMAP(hbm2, m_rcDest.left, m_rcDest.top);
- DeleteObject(hbm2);
+ ::SelectObject(hDC, m_hbmColor);
+ HBITMAP hbm2 = SkewDIB(hDC, m_hbmColor, nSkewDegY, TRUE);
+ InsertFromHBITMAP(hbm2, m_rc.left, m_rc.top);
+ ::DeleteObject(hbm2);
}
- selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
- selectionWindow.ForceRefreshSelectionContents();
- placeSelWin();
+ ::DeleteDC(hDC);
+
+ m_bShow = TRUE;
NotifyRefreshNeeded();
}
HBITMAP SelectionModel::GetBitmap() const
{
- return m_hBm;
+ return m_hbmColor;
}
int SelectionModel::PtStackSize() const
@@ -291,114 +361,92 @@ int SelectionModel::PtStackSize() const
void SelectionModel::DrawFramePoly(HDC hDCImage)
{
- Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE); /* draw the freehand
selection inverted/xored */
-}
-
-void SelectionModel::SetSrcAndDestRectFromPoints(const POINT& ptFrom, const
POINT& ptTo)
-{
- m_rcDest.left = m_rcSrc.left = min(ptFrom.x, ptTo.x);
- m_rcDest.top = m_rcSrc.top = min(ptFrom.y, ptTo.y);
- m_rcDest.right = m_rcSrc.right = max(ptFrom.x, ptTo.x);
- m_rcDest.bottom = m_rcSrc.bottom = max(ptFrom.y, ptTo.y);
-}
-
-void SelectionModel::SetSrcRectSizeToZero()
-{
- m_rcSrc.right = m_rcSrc.left;
- m_rcSrc.bottom = m_rcSrc.top;
+ /* draw the freehand selection inverted/xored */
+ Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE);
}
-BOOL SelectionModel::IsSrcRectSizeNonzero() const
+void SelectionModel::SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo)
{
- return (RECT_WIDTH(m_rcSrc) != 0) && (RECT_HEIGHT(m_rcSrc) != 0);
+ m_rc.left = min(ptFrom.x, ptTo.x);
+ m_rc.top = min(ptFrom.y, ptTo.y);
+ m_rc.right = max(ptFrom.x, ptTo.x);
+ m_rc.bottom = max(ptFrom.y, ptTo.y);
}
-void SelectionModel::ModifyDestRect(POINT& ptDelta, int iAction)
+void SelectionModel::Dragging(CANVAS_HITTEST hit, POINT pt)
{
- POINT ptDeltaUsed;
-
- switch (iAction)
+ switch (hit)
{
- case ACTION_MOVE: /* move selection */
- ptDeltaUsed.x = ptDelta.x;
- ptDeltaUsed.y = ptDelta.y;
- OffsetRect(&m_rcDest, ptDeltaUsed.x, ptDeltaUsed.y);
+ case HIT_NONE:
+ break;
+ case HIT_UPPER_LEFT:
+ m_rc.left += pt.x - m_ptHit.x;
+ m_rc.top += pt.y - m_ptHit.y;
break;
- case ACTION_RESIZE_TOP_LEFT: /* resize at upper left corner */
- ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
- ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
- m_rcDest.left += ptDeltaUsed.x;
- m_rcDest.top += ptDeltaUsed.y;
+ case HIT_UPPER_CENTER:
+ m_rc.top += pt.y - m_ptHit.y;
break;
- case ACTION_RESIZE_TOP: /* resize at top edge */
- ptDeltaUsed.x = ptDelta.x;
- ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
- m_rcDest.top += ptDeltaUsed.y;
+ case HIT_UPPER_RIGHT:
+ m_rc.right += pt.x - m_ptHit.x;
+ m_rc.top += pt.y - m_ptHit.y;
break;
- case ACTION_RESIZE_TOP_RIGHT: /* resize at upper right corner */
- ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
- ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
- m_rcDest.top += ptDeltaUsed.y;
- m_rcDest.right += ptDeltaUsed.x;
+ case HIT_MIDDLE_LEFT:
+ m_rc.left += pt.x - m_ptHit.x;
break;
- case ACTION_RESIZE_LEFT: /* resize at left edge */
- ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
- ptDeltaUsed.y = ptDelta.y;
- m_rcDest.left += ptDeltaUsed.x;
+ case HIT_MIDDLE_RIGHT:
+ m_rc.right += pt.x - m_ptHit.x;
break;
- case ACTION_RESIZE_RIGHT: /* resize at right edge */
- ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
- ptDeltaUsed.y = ptDelta.y;
- m_rcDest.right += ptDeltaUsed.x;
+ case HIT_LOWER_LEFT:
+ m_rc.left += pt.x - m_ptHit.x;
+ m_rc.bottom += pt.y - m_ptHit.y;
break;
- case ACTION_RESIZE_BOTTOM_LEFT: /* resize at lower left corner */
- ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
- ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
- m_rcDest.left += ptDeltaUsed.x;
- m_rcDest.bottom += ptDeltaUsed.y;
+ case HIT_LOWER_CENTER:
+ m_rc.bottom += pt.y - m_ptHit.y;
break;
- case ACTION_RESIZE_BOTTOM: /* resize at bottom edge */
- ptDeltaUsed.x = ptDelta.x;
- ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
- m_rcDest.bottom += ptDeltaUsed.y;
+ case HIT_LOWER_RIGHT:
+ m_rc.right += pt.x - m_ptHit.x;
+ m_rc.bottom += pt.y - m_ptHit.y;
break;
- case ACTION_RESIZE_BOTTOM_RIGHT: /* resize at lower right corner */
- ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
- ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
- m_rcDest.right += ptDeltaUsed.x;
- m_rcDest.bottom += ptDeltaUsed.y;
+ case HIT_BORDER:
+ case HIT_INNER:
+ OffsetRect(&m_rc, pt.x - m_ptHit.x, pt.y - m_ptHit.y);
break;
}
- ptDelta.x -= ptDeltaUsed.x;
- ptDelta.y -= ptDeltaUsed.y;
+ m_ptHit = pt;
}
-LONG SelectionModel::GetDestRectWidth() const
+void SelectionModel::NotifyRefreshNeeded()
{
- return m_rcDest.right - m_rcDest.left;
+ imageArea.Invalidate(FALSE);
}
-LONG SelectionModel::GetDestRectHeight() const
+void SelectionModel::ClearMask()
{
- return m_rcDest.bottom - m_rcDest.top;
+ if (m_hbmMask)
+ {
+ ::DeleteObject(m_hbmMask);
+ m_hbmMask = NULL;
+ }
}
-LONG SelectionModel::GetDestRectLeft() const
+void SelectionModel::ClearColor()
{
- return m_rcDest.left;
+ if (m_hbmColor)
+ {
+ ::DeleteObject(m_hbmColor);
+ m_hbmColor = NULL;
+ }
}
-LONG SelectionModel::GetDestRectTop() const
+void SelectionModel::CancelSelection()
{
- return m_rcDest.top;
-}
+ if (!m_bShow)
+ return;
-void SelectionModel::NotifyRefreshNeeded()
-{
- selectionWindow.SendMessage(WM_SELECTIONMODELREFRESHNEEDED);
-}
+ imageModel.CopyPrevious();
+ if (m_bShow)
+ imageModel.Undo(TRUE);
-void SelectionModel::GetRect(LPRECT prc) const
-{
- *prc = m_rcDest;
+ m_bShow = FALSE;
+ imageArea.Invalidate(FALSE);
}
diff --git a/base/applications/mspaint/selectionmodel.h
b/base/applications/mspaint/selectionmodel.h
index fbb208fed4b..fc1420de7fd 100644
--- a/base/applications/mspaint/selectionmodel.h
+++ b/base/applications/mspaint/selectionmodel.h
@@ -9,66 +9,54 @@
#pragma once
-/* DEFINES **********************************************************/
-
-#define ACTION_MOVE 0
-#define ACTION_RESIZE_TOP_LEFT 1
-#define ACTION_RESIZE_TOP 2
-#define ACTION_RESIZE_TOP_RIGHT 3
-#define ACTION_RESIZE_LEFT 4
-#define ACTION_RESIZE_RIGHT 5
-#define ACTION_RESIZE_BOTTOM_LEFT 6
-#define ACTION_RESIZE_BOTTOM 7
-#define ACTION_RESIZE_BOTTOM_RIGHT 8
-
-/* CLASSES **********************************************************/
-
class SelectionModel
{
private:
- HDC m_hDC;
- RECT m_rcSrc;
- RECT m_rcDest;
- HBITMAP m_hBm;
- HBITMAP m_hMask;
+ HBITMAP m_hbmColor;
+ HBITMAP m_hbmMask;
POINT *m_ptStack;
int m_iPtSP;
-// void NotifySelectionChanging();
-// void NotifySelectionChanged();
- void NotifyRefreshNeeded();
-
public:
+ BOOL m_bShow;
+ CRect m_rc; // in image pixel coordinates
+ POINT m_ptHit; // in image pixel coordinates
+
SelectionModel();
~SelectionModel();
+
void ResetPtStack();
- void PushToPtStack(LONG x, LONG y);
- void CalculateBoundingBoxAndContents(HDC hDCImage);
- void CalculateContents(HDC hDCImage);
+ void PushToPtStack(POINT pt);
+ int PtStackSize() const;
+ void SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo);
+ void BuildMaskFromPtStack();
+
+ BOOL TakeOff();
+ void Landing();
+
+ HBITMAP GetBitmap() const;
+ void GetSelectionContents(HDC hDCImage);
+ void DrawFramePoly(HDC hDCImage);
void DrawBackgroundPoly(HDC hDCImage, COLORREF crBg);
void DrawBackgroundRect(HDC hDCImage, COLORREF crBg);
- void DrawSelection(HDC hDCImage, COLORREF crBg = 0, BOOL bBgTransparent = FALSE);
- void DrawSelectionStretched(HDC hDCImage);
- void ScaleContentsToFit();
+ void DrawSelection(HDC hDCImage, LPCRECT prc, COLORREF crBg = 0, BOOL bBgTransparent
= FALSE);
void InsertFromHBITMAP(HBITMAP hBm, INT x = 0, INT y = 0);
+
+ // operation
void FlipHorizontally();
void FlipVertically();
void RotateNTimes90Degrees(int iN);
- void StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX = 0, int
nSkewDegY = 0);
- HBITMAP GetBitmap() const;
- int PtStackSize() const;
- void DrawFramePoly(HDC hDCImage);
- void SetSrcAndDestRectFromPoints(const POINT& ptFrom, const POINT& ptTo);
- void SetSrcRectSizeToZero();
- BOOL IsSrcRectSizeNonzero() const;
- void ModifyDestRect(POINT& ptDelta, int iAction);
- LONG GetDestRectWidth() const;
- LONG GetDestRectHeight() const;
- LONG GetDestRectLeft() const;
- LONG GetDestRectTop() const;
- void GetRect(LPRECT prc) const;
+ void StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX, int
nSkewDegY);
+
+ void CancelSelection();
+ void NotifyRefreshNeeded();
+ void Dragging(CANVAS_HITTEST hit, POINT pt);
+ void ClearMask();
+ void ClearColor();
private:
SelectionModel(const SelectionModel&);
SelectionModel& operator=(const SelectionModel&);
+
+ void ShiftPtStack(BOOL bPlus);
};
diff --git a/base/applications/mspaint/toolbox.cpp
b/base/applications/mspaint/toolbox.cpp
index 6ba23375ebb..64f90f9c807 100644
--- a/base/applications/mspaint/toolbox.cpp
+++ b/base/applications/mspaint/toolbox.cpp
@@ -114,7 +114,7 @@ LRESULT CToolBox::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHand
LRESULT CToolBox::OnToolsModelToolChanged(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHandled)
{
- selectionWindow.ShowWindow(SW_HIDE);
+ selectionModel.m_bShow = FALSE;
toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier
functions
// Check the toolbar button
diff --git a/base/applications/mspaint/toolsmodel.cpp
b/base/applications/mspaint/toolsmodel.cpp
index 34341635554..5f07ddf6132 100644
--- a/base/applications/mspaint/toolsmodel.cpp
+++ b/base/applications/mspaint/toolsmodel.cpp
@@ -141,8 +141,8 @@ void ToolsModel::SetBackgroundTransparent(BOOL bTransparent)
{
m_transpBg = bTransparent;
NotifyToolSettingsChanged();
- if (selectionWindow.IsWindow())
- selectionWindow.ForceRefreshSelectionContents();
+ if (imageArea.IsWindow())
+ imageArea.Invalidate(FALSE);
}
int ToolsModel::GetZoom() const
@@ -172,8 +172,6 @@ void ToolsModel::NotifyToolSettingsChanged()
{
if (toolSettingsWindow.IsWindow())
toolSettingsWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
- if (selectionWindow.IsWindow())
- selectionWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
if (textEditWindow.IsWindow())
textEditWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
}
@@ -184,8 +182,8 @@ void ToolsModel::NotifyZoomChanged()
toolSettingsWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
if (textEditWindow.IsWindow())
textEditWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
- if (selectionWindow.IsWindow())
- selectionWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
+ if (imageArea.IsWindow())
+ imageArea.SendMessage(WM_TOOLSMODELZOOMCHANGED);
}
void ToolsModel::OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
diff --git a/base/applications/mspaint/toolsmodel.h
b/base/applications/mspaint/toolsmodel.h
index c7fc2302415..da0e06cfa2f 100644
--- a/base/applications/mspaint/toolsmodel.h
+++ b/base/applications/mspaint/toolsmodel.h
@@ -132,3 +132,31 @@ static inline int UnZoomed(int xy)
{
return xy * 1000 / toolsModel.GetZoom();
}
+
+static inline void Zoomed(POINT& pt)
+{
+ pt.x = Zoomed(pt.x);
+ pt.y = Zoomed(pt.y);
+}
+
+static inline void Zoomed(RECT& rc)
+{
+ rc.left = Zoomed(rc.left);
+ rc.top = Zoomed(rc.top);
+ rc.right = Zoomed(rc.right);
+ rc.bottom = Zoomed(rc.bottom);
+}
+
+static inline void UnZoomed(POINT& pt)
+{
+ pt.x = UnZoomed(pt.x);
+ pt.y = UnZoomed(pt.y);
+}
+
+static inline void UnZoomed(RECT& rc)
+{
+ rc.left = UnZoomed(rc.left);
+ rc.top = UnZoomed(rc.top);
+ rc.right = UnZoomed(rc.right);
+ rc.bottom = UnZoomed(rc.bottom);
+}
diff --git a/base/applications/mspaint/winproc.cpp
b/base/applications/mspaint/winproc.cpp
index ee09d6fba99..b44534a8043 100644
--- a/base/applications/mspaint/winproc.cpp
+++ b/base/applications/mspaint/winproc.cpp
@@ -182,11 +182,9 @@ void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND
window)
toolBoxContainer.SendMessage(WM_COMMAND, ID_RECTSEL);
imageModel.CopyPrevious();
- selectionModel.InsertFromHBITMAP(bitmap);
-
- placeSelWin();
- selectionWindow.ShowWindow(SW_SHOW);
- selectionWindow.ForceRefreshSelectionContents();
+ selectionModel.InsertFromHBITMAP(bitmap, 0, 0);
+ selectionModel.m_bShow = TRUE;
+ imageArea.Invalidate(FALSE);
}
LRESULT CMainWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
bHandled)
@@ -279,9 +277,6 @@ LRESULT CMainWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam,
BOOL& bHa
// Creating the window inside the canvas
imageArea.Create(canvasWindow, rcEmpty, NULL, WS_CHILD | WS_VISIBLE);
- // Create selection window (initially hidden)
- selectionWindow.Create(imageArea, rcEmpty, NULL, WS_CHILD | BS_OWNERDRAW);
-
// Create and show the miniature if necessary
if (registrySettings.ShowThumbnail)
{
@@ -407,7 +402,7 @@ LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam, LPARAM
lParam, BO
{
HMENU menu = (HMENU)wParam;
BOOL trueSelection =
- (::IsWindowVisible(selectionWindow) &&
+ (selectionModel.m_bShow &&
((toolsModel.GetActiveTool() == TOOL_FREESEL) || (toolsModel.GetActiveTool() ==
TOOL_RECTSEL)));
switch (lParam)
@@ -438,7 +433,7 @@ LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam, LPARAM
lParam, BO
CheckMenuItem(menu, IDM_VIEWSHOWMINIATURE,
CHECKED_IF(registrySettings.ShowThumbnail));
break;
case 3: /* Image menu */
- EnableMenuItem(menu, IDM_IMAGECROP,
ENABLED_IF(::IsWindowVisible(selectionWindow)));
+ EnableMenuItem(menu, IDM_IMAGECROP, ENABLED_IF(selectionModel.m_bShow));
CheckMenuItem(menu, IDM_IMAGEDRAWOPAQUE,
CHECKED_IF(!toolsModel.IsBackgroundTransparent()));
break;
}
@@ -484,7 +479,6 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
if (hwndCapture)
{
if (canvasWindow.m_hWnd == hwndCapture ||
- selectionWindow.m_hWnd == hwndCapture ||
imageArea.m_hWnd == hwndCapture ||
fullscreenWindow.m_hWnd == hwndCapture)
{
@@ -610,7 +604,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
case IDM_EDITUNDO:
if (toolsModel.GetActiveTool() == TOOL_TEXT &&
::IsWindowVisible(textEditWindow))
break;
- if (selectionWindow.IsWindowVisible())
+ if (selectionModel.m_bShow)
{
if (toolsModel.GetActiveTool() == TOOL_RECTSEL ||
toolsModel.GetActiveTool() == TOOL_FREESEL)
@@ -736,31 +730,31 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd))
{
case 1: /* flip horizontally */
- if (::IsWindowVisible(selectionWindow))
+ if (selectionModel.m_bShow)
selectionModel.FlipHorizontally();
else
imageModel.FlipHorizontally();
break;
case 2: /* flip vertically */
- if (::IsWindowVisible(selectionWindow))
+ if (selectionModel.m_bShow)
selectionModel.FlipVertically();
else
imageModel.FlipVertically();
break;
case 3: /* rotate 90 degrees */
- if (::IsWindowVisible(selectionWindow))
+ if (selectionModel.m_bShow)
selectionModel.RotateNTimes90Degrees(1);
else
imageModel.RotateNTimes90Degrees(1);
break;
case 4: /* rotate 180 degrees */
- if (::IsWindowVisible(selectionWindow))
+ if (selectionModel.m_bShow)
selectionModel.RotateNTimes90Degrees(2);
else
imageModel.RotateNTimes90Degrees(2);
break;
case 5: /* rotate 270 degrees */
- if (::IsWindowVisible(selectionWindow))
+ if (selectionModel.m_bShow)
selectionModel.RotateNTimes90Degrees(3);
else
imageModel.RotateNTimes90Degrees(3);
@@ -779,7 +773,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM
lParam, BOOL& bH
{
if (stretchSkewDialog.DoModal(mainWindow.m_hWnd))
{
- if (::IsWindowVisible(selectionWindow))
+ if (selectionModel.m_bShow)
{
selectionModel.StretchSkew(stretchSkewDialog.percentage.x,
stretchSkewDialog.percentage.y,
stretchSkewDialog.angle.x,
stretchSkewDialog.angle.y);