[MSPAINT] Make selection window-less (#5208)
authorKatayama Hirofumi MZ <katayama.hirofumi.mz@gmail.com>
Sat, 1 Apr 2023 13:01:04 +0000 (22:01 +0900)
committerGitHub <noreply@github.com>
Sat, 1 Apr 2023 13:01:04 +0000 (22:01 +0900)
- Delete selection.cpp and selection.h and selectionWindow.
- Extend ColorKeyedMaskBlt function.
- Implement selection resizing.
CORE-18867

23 files changed:
base/applications/mspaint/CMakeLists.txt
base/applications/mspaint/canvas.cpp
base/applications/mspaint/common.h
base/applications/mspaint/dib.cpp
base/applications/mspaint/dib.h
base/applications/mspaint/drawing.cpp
base/applications/mspaint/drawing.h
base/applications/mspaint/globalvar.h
base/applications/mspaint/history.cpp
base/applications/mspaint/history.h
base/applications/mspaint/imgarea.cpp
base/applications/mspaint/imgarea.h
base/applications/mspaint/mouse.cpp
base/applications/mspaint/palettemodel.cpp
base/applications/mspaint/precomp.h
base/applications/mspaint/selection.cpp [deleted file]
base/applications/mspaint/selection.h [deleted file]
base/applications/mspaint/selectionmodel.cpp
base/applications/mspaint/selectionmodel.h
base/applications/mspaint/toolbox.cpp
base/applications/mspaint/toolsmodel.cpp
base/applications/mspaint/toolsmodel.h
base/applications/mspaint/winproc.cpp

index 2d6e24d..57532cb 100644 (file)
@@ -20,7 +20,6 @@ list(APPEND SOURCE
     palette.cpp
     palettemodel.cpp
     registry.cpp
-    selection.cpp
     selectionmodel.cpp
     sizebox.cpp
     textedit.cpp
index d538925..c0fc4ad 100644 (file)
@@ -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
index 619133f..0b9890d 100644 (file)
@@ -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);
index 96218a8..f46ef41 100644 (file)
@@ -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;
 
index 82ccde6..f9eb7d3 100644 (file)
@@ -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);
 
index f94da43..86711c0 100644 (file)
@@ -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;
 }
index 5401168..8fb0f54 100644 (file)
@@ -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);
index fe9e47f..058117f 100644 (file)
@@ -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;
index 847e6c6..0680865 100644 (file)
@@ -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();
 }
 
index 17ef43b..40792f8 100644 (file)
@@ -45,7 +45,6 @@ public:
     void FlipHorizontally();
     void FlipVertically();
     void RotateNTimes90Degrees(int iN);
-    void DrawSelectionBackground(COLORREF rgbBG);
     void DeleteSelection();
     void Bound(POINT& pt);
 };
index dfb9345..abae54c 100644 (file)
@@ -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)
             {
index daef656..941424d 100644 (file)
 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);
 };
index 57f2894..5d1c4fc 100644 (file)
@@ -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();
     }
 };
index b4ae440..cf920bc 100644 (file)
@@ -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);
 }
index 5dda7a9..ae4e584 100644 (file)
@@ -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 (file)
index 1426e08..0000000
+++ /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 (file)
index 8e61b77..0000000
+++ /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();
index 2079f7a..f7c61d1 100644 (file)
@@ -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);
 }
index fbb208f..fc1420d 100644 (file)
@@ -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);
 };
index 6ba2337..64f90f9 100644 (file)
@@ -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
index 3434163..5f07ddf 100644 (file)
@@ -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)
index c7fc230..da0e06c 100644 (file)
@@ -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);
+}
index ee09d6f..b44534a 100644 (file)
@@ -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);