From 421341ad756e0d7f32a117ceb170346630c1d80a Mon Sep 17 00:00:00 2001 From: Katayama Hirofumi MZ Date: Sat, 25 Nov 2023 13:50:20 +0900 Subject: [PATCH] sync --- canvas.cpp | 89 ++-------- canvas.h | 8 +- dialogs.cpp | 5 - drawing.cpp | 2 - history.cpp | 20 +-- history.h | 1 - main.cpp | 62 +------ mouse.cpp | 434 +++++++++++++++++++++++++++------------------ precomp.h | 14 +- reactos/buildno.h | 12 +- rsrc.rc | 2 - selectionmodel.cpp | 120 +++---------- selectionmodel.h | 11 +- toolsettings.cpp | 2 - toolsmodel.cpp | 3 + toolsmodel.h | 1 - 16 files changed, 327 insertions(+), 459 deletions(-) diff --git a/canvas.cpp b/canvas.cpp index cf529e0..06074cf 100644 --- a/canvas.cpp +++ b/canvas.cpp @@ -13,7 +13,6 @@ CCanvasWindow canvasWindow; CCanvasWindow::CCanvasWindow() : m_drawing(FALSE) - , m_hitSelection(HIT_NONE) , m_hitCanvasSizeBox(HIT_NONE) , m_ptOrig { -1, -1 } { @@ -316,25 +315,11 @@ LRESULT CCanvasWindow::OnButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO HITTEST hitSelection = selectionModel.hitTest(pt); if (hitSelection != HIT_NONE) { - selectionModel.m_nSelectionBrush = 0; // Selection Brush is OFF - if (bLeftButton) - { - CanvasToImage(pt); - if (::GetKeyState(VK_CONTROL) < 0) // Ctrl+Click is Selection Clone - { - imageModel.SelectionClone(); - } - else if (::GetKeyState(VK_SHIFT) < 0) // Shift+Dragging is Selection Brush - { - selectionModel.m_nSelectionBrush = 1; // Selection Brush is ON - } - StartSelectionDrag(hitSelection, pt); - } - else - { - ClientToScreen(&pt); - mainWindow.TrackPopupMenu(pt, 0); - } + m_drawing = TRUE; + CanvasToImage(pt); + SetCapture(); + toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, FALSE); + Invalidate(); return 0; } @@ -370,7 +355,7 @@ LRESULT CCanvasWindow::OnButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO m_drawing = TRUE; SetCapture(); toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, FALSE); - Invalidate(FALSE); + Invalidate(); return 0; } @@ -395,7 +380,7 @@ LRESULT CCanvasWindow::OnButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, B toolsModel.OnButtonDown(nMsg == WM_LBUTTONDBLCLK, pt.x, pt.y, TRUE); toolsModel.resetTool(); - Invalidate(FALSE); + Invalidate(); return 0; } @@ -418,12 +403,6 @@ LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL if (toolsModel.GetActiveTool() == TOOL_ZOOM) Invalidate(); - if (m_hitSelection != HIT_NONE) - { - SelectionDragging(pt); - return 0; - } - if (!m_drawing || toolsModel.GetActiveTool() <= TOOL_AIRBRUSH) { TRACKMOUSEEVENT tme = { sizeof(tme) }; @@ -444,7 +423,7 @@ LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL } } - if (m_drawing) + if (m_drawing || toolsModel.IsSelection()) { toolsModel.DrawWithMouseTool(pt, wParam); return 0; @@ -549,11 +528,6 @@ LRESULT CCanvasWindow::OnButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& ::SendMessageW(g_hStatusBar, SB_SETTEXT, 2, (LPARAM)L""); return 0; } - else if (m_hitSelection != HIT_NONE && bLeftButton) - { - EndSelectionDrag(pt); - return 0; - } if (m_hitCanvasSizeBox == HIT_NONE || !bLeftButton) return 0; @@ -674,9 +648,9 @@ LRESULT CCanvasWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL LRESULT CCanvasWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - if (wParam == VK_ESCAPE && ::GetCapture() == m_hWnd) + if (wParam == VK_ESCAPE) { - cancelDrawing(); + OnEndDraw(TRUE); ::ReleaseCapture(); m_nMouseDownMsg = 0; m_hitCanvasSizeBox = HIT_NONE; @@ -724,49 +698,10 @@ LRESULT CCanvasWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH return 0; } -VOID CCanvasWindow::cancelDrawing() +VOID CCanvasWindow::OnEndDraw(BOOL bCancel) { - selectionModel.ClearColorImage(); - selectionModel.ClearMaskImage(); - m_hitSelection = HIT_NONE; m_drawing = FALSE; - toolsModel.OnEndDraw(TRUE); - Invalidate(FALSE); -} - -VOID CCanvasWindow::finishDrawing() -{ - toolsModel.OnEndDraw(FALSE); - m_drawing = FALSE; - Invalidate(FALSE); -} - -VOID CCanvasWindow::StartSelectionDrag(HITTEST hit, POINT ptImage) -{ - m_hitSelection = hit; - selectionModel.m_ptHit = ptImage; - selectionModel.TakeOff(); - - SetCapture(); - Invalidate(FALSE); -} - -VOID CCanvasWindow::SelectionDragging(POINT ptImage) -{ - if (selectionModel.m_nSelectionBrush) - { - imageModel.SelectionClone(selectionModel.m_nSelectionBrush == 1); - selectionModel.m_nSelectionBrush = 2; // Selection Brush is ON and drawn - } - - selectionModel.Dragging(m_hitSelection, ptImage); - Invalidate(FALSE); -} - -VOID CCanvasWindow::EndSelectionDrag(POINT ptImage) -{ - selectionModel.Dragging(m_hitSelection, ptImage); - m_hitSelection = HIT_NONE; + toolsModel.OnEndDraw(bCancel); Invalidate(FALSE); } diff --git a/canvas.h b/canvas.h index e59b37c..ef0323d 100644 --- a/canvas.h +++ b/canvas.h @@ -42,8 +42,7 @@ class CCanvasWindow : public CWindowImpl BOOL m_drawing; - VOID cancelDrawing(); - VOID finishDrawing(); + VOID OnEndDraw(BOOL bCancel); VOID updateScrollRange(); VOID updateScrollPos(INT x = 0, INT y = 0); @@ -56,7 +55,6 @@ class CCanvasWindow : public CWindowImpl VOID zoomTo(INT newZoom, LONG left = 0, LONG top = 0); protected: - HITTEST m_hitSelection; HITTEST m_hitCanvasSizeBox; POINT m_ptOrig; // The origin of drag start HBITMAP m_ahbmCached[2]; // The cached buffer bitmaps @@ -67,10 +65,6 @@ class CCanvasWindow : public CWindowImpl VOID DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint); VOID OnHVScroll(WPARAM wParam, INT fnBar); - VOID StartSelectionDrag(HITTEST hit, POINT ptImage); - VOID SelectionDragging(POINT ptImage); - VOID EndSelectionDrag(POINT ptImage); - LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnVScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); diff --git a/dialogs.cpp b/dialogs.cpp index 3684163..5e2cca7 100644 --- a/dialogs.cpp +++ b/dialogs.cpp @@ -5,16 +5,11 @@ * COPYRIGHT: Copyright 2015 Benedikt Freisen */ -/* INCLUDES *********************************************************/ - #include "precomp.h" - #include "dialogs.h" #include -/* GLOBALS **********************************************************/ - CMirrorRotateDialog mirrorRotateDialog; CAttributesDialog attributesDialog; CStretchSkewDialog stretchSkewDialog; diff --git a/drawing.cpp b/drawing.cpp index 5304709..70d9f20 100644 --- a/drawing.cpp +++ b/drawing.cpp @@ -5,8 +5,6 @@ * COPYRIGHT: Copyright 2015 Benedikt Freisen */ -/* INCLUDES *********************************************************/ - #include "precomp.h" /* FUNCTIONS ********************************************************/ diff --git a/history.cpp b/history.cpp index 696e026..c7b32cc 100644 --- a/history.cpp +++ b/history.cpp @@ -164,8 +164,13 @@ void ImageModel::PushImageForUndo(const RECT& rcPartial) part.m_bPartial = TRUE; part.m_rcPart = rcPartial; + CRect rcImage = { 0, 0, GetWidth(), GetHeight() }; + CRect& rc = part.m_rcPart; + if (!rc.IntersectRect(rc, rcImage)) + rc.SetRect(-1, -1, 0, 0); + HBITMAP hbmMaster = LockBitmap(); - part.m_hbmImage = getSubImage(hbmMaster, rcPartial); + part.m_hbmImage = getSubImage(hbmMaster, rc); UnlockBitmap(hbmMaster); PushDone(); @@ -351,16 +356,3 @@ void ImageModel::UnlockBitmap(HBITMAP hbmLocked) m_hbmMaster = hbmLocked; m_hbmOld = ::SelectObject(m_hDrawingDC, m_hbmMaster); // Re-select } - -void ImageModel::SelectionClone(BOOL bUndoable) -{ - if (!selectionModel.m_bShow || selectionModel.m_rc.IsRectEmpty()) - return; - - if (bUndoable) - PushImageForUndo(); - - selectionModel.DrawSelection(m_hDrawingDC, paletteModel.GetBgColor(), - toolsModel.IsBackgroundTransparent()); - NotifyImageChanged(); -} diff --git a/history.h b/history.h index 87c9851..7dc949b 100644 --- a/history.h +++ b/history.h @@ -51,7 +51,6 @@ class ImageModel void NotifyImageChanged(); BOOL IsBlackAndWhite(); void PushBlackAndWhite(); - void SelectionClone(BOOL bUndoable = TRUE); protected: HDC m_hDrawingDC; // The device context for this class diff --git a/main.cpp b/main.cpp index 535db5b..c93a41a 100644 --- a/main.cpp +++ b/main.cpp @@ -406,7 +406,7 @@ void CMainWindow::alignChildrenToMainWindow() void CMainWindow::saveImage(BOOL overwrite) { - canvasWindow.finishDrawing(); + canvasWindow.OnEndDraw(FALSE); // Is the extension not supported? PWCHAR pchDotExt = PathFindExtensionW(g_szFileName); @@ -606,7 +606,7 @@ LRESULT CMainWindow::OnDestroy(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH BOOL CMainWindow::ConfirmSave() { - canvasWindow.finishDrawing(); + canvasWindow.OnEndDraw(FALSE); if (imageModel.IsImageSaved()) return TRUE; @@ -693,8 +693,6 @@ BOOL CMainWindow::CanUndo() const return (BOOL)textEditWindow.SendMessage(EM_CANUNDO); if (selectionModel.m_bShow && toolsModel.IsSelection()) return TRUE; - if (ToolBase::s_pointSP != 0) - return TRUE; return imageModel.CanUndo(); } @@ -702,8 +700,6 @@ BOOL CMainWindow::CanRedo() const { if (toolsModel.GetActiveTool() == TOOL_TEXT && ::IsWindowVisible(textEditWindow)) return FALSE; // There is no "WM_REDO" in EDIT control - if (ToolBase::s_pointSP != 0) - return TRUE; return imageModel.CanRedo(); } @@ -802,29 +798,11 @@ LRESULT CMainWindow::OnGetMinMaxInfo(UINT nMsg, WPARAM wParam, LPARAM lParam, BO LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) { - HWND hwndCapture; switch (wParam) { case VK_ESCAPE: - hwndCapture = GetCapture(); - if (hwndCapture) - { - if (canvasWindow.m_hWnd == hwndCapture || - fullscreenWindow.m_hWnd == hwndCapture) - { - ::SendMessageW(hwndCapture, nMsg, wParam, lParam); - } - } - else if (selectionModel.m_bShow) - { - selectionModel.HideSelection(); - } - else - { - canvasWindow.cancelDrawing(); - } + canvasWindow.PostMessage(nMsg, wParam, lParam); break; - case VK_LEFT: selectionModel.moveSelection(-1, 0); break; @@ -932,7 +910,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH GlobalFree(pd.hDevNames); break; case IDM_FILESEND: - canvasWindow.finishDrawing(); + canvasWindow.OnEndDraw(FALSE); if (!OpenMailer(m_hWnd, g_szFileName)) { ShowError(IDS_CANTSENDMAIL); @@ -963,29 +941,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH textEditWindow.PostMessage(WM_UNDO, 0, 0); break; } - if (selectionModel.m_bShow) - { - if (toolsModel.IsSelection()) - { - canvasWindow.cancelDrawing(); - if (toolsModel.GetActiveTool() == TOOL_FREESEL || - toolsModel.GetActiveTool() == TOOL_RECTSEL) - { - imageModel.Undo(); - if (selectionModel.m_nSelectionBrush == 2) // Selection Brush is drawn - { - imageModel.Undo(); - selectionModel.m_nSelectionBrush = 0; - } - } - break; - } - } - if (ToolBase::s_pointSP != 0) // drawing something? - { - canvasWindow.cancelDrawing(); - break; - } + canvasWindow.OnEndDraw(FALSE); imageModel.Undo(); break; case IDM_EDITREDO: @@ -994,11 +950,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH // There is no "WM_REDO" in EDIT control break; } - if (ToolBase::s_pointSP != 0) // drawing something? - { - canvasWindow.finishDrawing(); - break; - } + canvasWindow.OnEndDraw(FALSE); imageModel.Redo(); break; case IDM_EDITCOPY: @@ -1113,7 +1065,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH break; case TOOL_TEXT: - canvasWindow.cancelDrawing(); + canvasWindow.OnEndDraw(TRUE); break; default: break; diff --git a/mouse.cpp b/mouse.cpp index a496d08..2f97ad9 100644 --- a/mouse.cpp +++ b/mouse.cpp @@ -6,14 +6,14 @@ * Copyright 2021-2023 Katayama Hirofumi MZ */ -/* INCLUDES *********************************************************/ - #include "precomp.h" #include -SIZE_T ToolBase::s_pointSP = 0; -static SIZE_T s_maxPointSP = 0; -static CHeapPtr s_pointStack; +static SIZE_T s_pointSP = 0; +static CHeapPtr s_pointsAllocated; +static POINT s_staticPointStack[512]; // 512 is enough +static SIZE_T s_maxPointSP = _countof(s_staticPointStack); +static LPPOINT s_pointStack = s_staticPointStack; static POINT g_ptStart, g_ptEnd; /* FUNCTIONS ********************************************************/ @@ -71,13 +71,50 @@ void getBoundaryOfPtStack(RECT& rcBoundary, INT cPoints, const POINT *pPoints) rcBoundary = rc; } +void ShiftPtStack(INT dx, INT dy) +{ + for (SIZE_T i = 0; i < s_pointSP; ++i) + { + POINT& pt = s_pointStack[i]; + pt.x += dx; + pt.y += dy; + } +} + +void BuildMaskFromPtStack() +{ + CRect rc; + getBoundaryOfPtStack(rc, s_pointSP, s_pointStack); + + ShiftPtStack(-rc.left, -rc.top); + + HDC hdcMem = ::CreateCompatibleDC(NULL); + HBITMAP hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL); + HGDIOBJ hbmOld = ::SelectObject(hdcMem, hbmMask); + ::FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH)); + HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN)); + HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH)); + ::Polygon(hdcMem, s_pointStack, s_pointSP); + ::SelectObject(hdcMem, hbrOld); + ::SelectObject(hdcMem, hPenOld); + ::SelectObject(hdcMem, hbmOld); + ::DeleteDC(hdcMem); + + selectionModel.setMask(rc, hbmMask); +} + void ToolBase::reset() { + if (s_pointStack != s_staticPointStack) + { + s_pointsAllocated.Free(); + s_pointStack = s_staticPointStack; + s_maxPointSP = _countof(s_staticPointStack); + } + s_pointSP = 0; g_ptEnd = g_ptStart = { -1, -1 }; - selectionModel.ResetPtStack(); - if (selectionModel.m_bShow) { selectionModel.Landing(); @@ -105,16 +142,20 @@ void ToolBase::endEvent() void ToolBase::pushToPtStack(LONG x, LONG y) { - if (s_pointSP >= s_maxPointSP) + if (s_pointSP + 1 >= s_maxPointSP) { SIZE_T newMax = s_maxPointSP + 512; SIZE_T cbNew = newMax * sizeof(POINT); - if (!s_pointStack.ReallocateBytes(cbNew)) + if (!s_pointsAllocated.ReallocateBytes(cbNew)) { ATLTRACE("%d, %d, %d\n", (INT)s_pointSP, (INT)s_maxPointSP, (INT)cbNew); return; } + if (s_pointStack == s_staticPointStack) + CopyMemory(s_pointsAllocated, s_staticPointStack, s_pointSP * sizeof(POINT)); + + s_pointStack = s_pointsAllocated; s_maxPointSP = newMax; } @@ -123,170 +164,6 @@ void ToolBase::pushToPtStack(LONG x, LONG y) /* TOOLS ********************************************************/ -// TOOL_FREESEL -struct FreeSelTool : ToolBase -{ - BOOL m_bLeftButton = FALSE; - - void OnDrawOverlayOnImage(HDC hdc) override - { - if (!selectionModel.IsLanded()) - selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); - - if (canvasWindow.m_drawing) - { - selectionModel.DrawFramePoly(hdc); - } - } - - void OnDrawOverlayOnCanvas(HDC hdc) override - { - selectionModel.drawFrameOnCanvas(hdc); - } - - void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override - { - selectionModel.Landing(); - if (bLeftButton) - { - selectionModel.HideSelection(); - selectionModel.ResetPtStack(); - POINT pt = { x, y }; - selectionModel.PushToPtStack(pt); - } - m_bLeftButton = bLeftButton; - } - - BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override - { - if (bLeftButton) - { - POINT pt = { x, y }; - imageModel.Clamp(pt); - selectionModel.PushToPtStack(pt); - imageModel.NotifyImageChanged(); - } - return TRUE; - } - - BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override - { - if (bLeftButton) - { - if (selectionModel.PtStackSize() > 2) - { - selectionModel.BuildMaskFromPtStack(); - selectionModel.m_bShow = TRUE; - } - else - { - selectionModel.ResetPtStack(); - selectionModel.m_bShow = FALSE; - } - imageModel.NotifyImageChanged(); - } - else - { - POINT pt = { x, y }; - canvasWindow.ClientToScreen(&pt); - mainWindow.TrackPopupMenu(pt, 0); - } - return TRUE; - } - - void OnEndDraw(BOOL bCancel) override - { - if (bCancel) - selectionModel.HideSelection(); - else - selectionModel.Landing(); - ToolBase::OnEndDraw(bCancel); - } - - void OnSpecialTweak(BOOL bMinus) override - { - selectionModel.StretchSelection(bMinus); - } -}; - -// TOOL_RECTSEL -struct RectSelTool : ToolBase -{ - BOOL m_bLeftButton = FALSE; - - void OnDrawOverlayOnImage(HDC hdc) override - { - if (!selectionModel.IsLanded()) - selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); - - if (canvasWindow.m_drawing) - { - CRect& rc = selectionModel.m_rc; - if (!rc.IsRectEmpty()) - RectSel(hdc, rc.left, rc.top, rc.right, rc.bottom); - } - } - - void OnDrawOverlayOnCanvas(HDC hdc) override - { - selectionModel.drawFrameOnCanvas(hdc); - } - - void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override - { - selectionModel.Landing(); - if (bLeftButton) - { - selectionModel.HideSelection(); - } - m_bLeftButton = bLeftButton; - } - - BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override - { - if (bLeftButton) - { - POINT pt = { x, y }; - imageModel.Clamp(pt); - selectionModel.SetRectFromPoints(g_ptStart, pt); - imageModel.NotifyImageChanged(); - } - return TRUE; - } - - BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override - { - POINT pt = { x, y }; - if (bLeftButton) - { - imageModel.Clamp(pt); - selectionModel.SetRectFromPoints(g_ptStart, pt); - selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty(); - imageModel.NotifyImageChanged(); - } - else - { - canvasWindow.ClientToScreen(&pt); - mainWindow.TrackPopupMenu(pt, 0); - } - return TRUE; - } - - void OnEndDraw(BOOL bCancel) override - { - if (bCancel) - selectionModel.HideSelection(); - else - selectionModel.Landing(); - ToolBase::OnEndDraw(bCancel); - } - - void OnSpecialTweak(BOOL bMinus) override - { - selectionModel.StretchSelection(bMinus); - } -}; - struct TwoPointDrawTool : ToolBase { BOOL m_bLeftButton = FALSE; @@ -493,6 +370,217 @@ struct SmoothDrawTool : ToolBase } }; +struct SelectionBaseTool : ToolBase +{ + BOOL m_bLeftButton = FALSE; + BOOL m_bCtrlKey = FALSE; + BOOL m_bShiftKey = FALSE; + BOOL m_bDrawing = FALSE; + BOOL m_bNoDrawBack = FALSE; + HITTEST m_hitSelection = HIT_NONE; + + BOOL isRectSelect() const + { + return (toolsModel.GetActiveTool() == TOOL_RECTSEL); + } + + void OnDrawOverlayOnImage(HDC hdc) override + { + if (selectionModel.IsLanded() || !selectionModel.m_bShow) + return; + + if (!m_bNoDrawBack) + selectionModel.DrawBackground(hdc, selectionModel.m_rgbBack); + + selectionModel.DrawSelection(hdc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent()); + } + + void OnDrawOverlayOnCanvas(HDC hdc) override + { + if (m_bDrawing || selectionModel.m_bShow) + selectionModel.drawFrameOnCanvas(hdc); + } + + void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) override + { + m_bLeftButton = bLeftButton; + m_bCtrlKey = (::GetKeyState(VK_CONTROL) < 0); + m_bShiftKey = (::GetKeyState(VK_SHIFT) < 0); + m_bDrawing = FALSE; + m_hitSelection = HIT_NONE; + + POINT pt = { x, y }; + if (!m_bLeftButton) // Show context menu on Right-click + { + canvasWindow.ImageToCanvas(pt); + canvasWindow.ClientToScreen(&pt); + mainWindow.TrackPopupMenu(pt, 0); + return; + } + + POINT ptCanvas = pt; + canvasWindow.ImageToCanvas(ptCanvas); + HITTEST hit = selectionModel.hitTest(ptCanvas); + if (hit != HIT_NONE) // Dragging of selection started? + { + if (m_bCtrlKey || m_bShiftKey) + { + imageModel.PushImageForUndo(); + toolsModel.OnDrawOverlayOnImage(imageModel.GetDC()); + } + m_hitSelection = hit; + selectionModel.m_ptHit = pt; + selectionModel.TakeOff(); + m_bNoDrawBack |= (m_bCtrlKey || m_bShiftKey); + imageModel.NotifyImageChanged(); + return; + } + + selectionModel.Landing(); + m_bDrawing = TRUE; + + imageModel.Clamp(pt); + if (isRectSelect()) + { + selectionModel.SetRectFromPoints(g_ptStart, pt); + } + else + { + s_pointSP = 0; + pushToPtStack(pt.x, pt.y); + } + + imageModel.NotifyImageChanged(); + } + + BOOL OnMouseMove(BOOL bLeftButton, LONG& x, LONG& y) override + { + POINT pt = { x, y }; + + if (!m_bLeftButton) + return TRUE; + + if (m_hitSelection != HIT_NONE) // Now dragging selection? + { + if (m_bShiftKey) + toolsModel.OnDrawOverlayOnImage(imageModel.GetDC()); + + selectionModel.Dragging(m_hitSelection, pt); + imageModel.NotifyImageChanged(); + return TRUE; + } + + if (isRectSelect() && ::GetKeyState(VK_SHIFT) < 0) + regularize(g_ptStart.x, g_ptStart.y, pt.x, pt.y); + + imageModel.Clamp(pt); + + if (isRectSelect()) + selectionModel.SetRectFromPoints(g_ptStart, pt); + else + pushToPtStack(pt.x, pt.y); + + imageModel.NotifyImageChanged(); + return TRUE; + } + + BOOL OnButtonUp(BOOL bLeftButton, LONG& x, LONG& y) override + { + POINT pt = { x, y }; + m_bDrawing = FALSE; + + if (!m_bLeftButton) + return TRUE; + + if (m_hitSelection != HIT_NONE) // Dragging of selection ended? + { + if (m_bShiftKey) + toolsModel.OnDrawOverlayOnImage(imageModel.GetDC()); + + selectionModel.Dragging(m_hitSelection, pt); + m_hitSelection = HIT_NONE; + imageModel.NotifyImageChanged(); + return TRUE; + } + + if (isRectSelect() && ::GetKeyState(VK_SHIFT) < 0) + regularize(g_ptStart.x, g_ptStart.y, pt.x, pt.y); + + imageModel.Clamp(pt); + + if (isRectSelect()) + { + selectionModel.SetRectFromPoints(g_ptStart, pt); + selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty(); + } + else + { + if (s_pointSP > 2) + { + BuildMaskFromPtStack(); + selectionModel.m_bShow = TRUE; + } + else + { + s_pointSP = 0; + selectionModel.m_bShow = FALSE; + } + } + + m_bNoDrawBack = FALSE; + imageModel.NotifyImageChanged(); + return TRUE; + } + + void OnEndDraw(BOOL bCancel) override + { + if (bCancel) + selectionModel.HideSelection(); + else + selectionModel.Landing(); + + m_bDrawing = FALSE; + m_hitSelection = HIT_NONE; + ToolBase::OnEndDraw(bCancel); + } + + void OnSpecialTweak(BOOL bMinus) override + { + selectionModel.StretchSelection(bMinus); + } +}; + +// TOOL_FREESEL +struct FreeSelTool : SelectionBaseTool +{ + void OnDrawOverlayOnImage(HDC hdc) override + { + SelectionBaseTool::OnDrawOverlayOnImage(hdc); + + if (!selectionModel.m_bShow && m_bDrawing) + { + /* Draw the freehand selection inverted/xored */ + Poly(hdc, s_pointStack, s_pointSP, 0, 0, 2, 0, FALSE, TRUE); + } + } +}; + +// TOOL_RECTSEL +struct RectSelTool : SelectionBaseTool +{ + void OnDrawOverlayOnImage(HDC hdc) override + { + SelectionBaseTool::OnDrawOverlayOnImage(hdc); + + if (!selectionModel.m_bShow && m_bDrawing) + { + CRect& rc = selectionModel.m_rc; + if (!rc.IsRectEmpty()) + RectSel(hdc, rc.left, rc.top, rc.right, rc.bottom); + } + } +}; + // TOOL_RUBBER struct RubberTool : SmoothDrawTool { diff --git a/precomp.h b/precomp.h index a1b1a24..d868327 100644 --- a/precomp.h +++ b/precomp.h @@ -51,12 +51,6 @@ #define WM_TOOLSMODELZOOMCHANGED (WM_APP + 2) #define WM_PALETTEMODELCOLORCHANGED (WM_APP + 3) -/* this simplifies checking and unchecking menu items */ -#define CHECKED_IF(a) ((a) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND)) - -/* this simplifies enabling or graying menu items */ -#define ENABLED_IF(a) ((a) ? (MF_ENABLED | MF_BYCOMMAND) : (MF_GRAYED | MF_BYCOMMAND)) - enum HITTEST // hit { HIT_NONE = 0, // Nothing hit or outside @@ -82,6 +76,14 @@ void getBoundaryOfPtStack(RECT& rcBoundary, INT cPoints, const POINT *pPoints); #define DEG2RAD(degree) (((degree) * M_PI) / 180) #define RAD2DEG(radian) ((LONG)(((radian) * 180) / M_PI)) +/* This simplifies checking and unchecking menu items */ +#define CHECKED_IF(bChecked) \ + ((bChecked) ? (MF_CHECKED | MF_BYCOMMAND) : (MF_UNCHECKED | MF_BYCOMMAND)) + +/* This simplifies enabling or graying menu items */ +#define ENABLED_IF(bEnabled) \ + ((bEnabled) ? (MF_ENABLED | MF_BYCOMMAND) : (MF_GRAYED | MF_BYCOMMAND)) + template inline void Swap(T& a, T& b) { diff --git a/reactos/buildno.h b/reactos/buildno.h index 24af5ae..4c452bd 100644 --- a/reactos/buildno.h +++ b/reactos/buildno.h @@ -2,17 +2,17 @@ #ifndef _INC_REACTOS_BUILDNO #define _INC_REACTOS_BUILDNO -#define KERNEL_VERSION_BUILD 20231123 -#define KERNEL_VERSION_BUILD_STR "20231123-0.4.15-dev-7043-gaf4a3fa" -#define KERNEL_VERSION_BUILD_RC "20231123-0.4.15-dev-7043-gaf4a3fa\0" +#define KERNEL_VERSION_BUILD 20231124 +#define KERNEL_VERSION_BUILD_STR "20231124-0.4.15-dev-7059-gbd06299" +#define KERNEL_VERSION_BUILD_RC "20231124-0.4.15-dev-7059-gbd06299\0" #define KERNEL_VERSION_RC "0.4.15-x86-dev\0" #define KERNEL_VERSION_STR "0.4.15-x86-dev" -#define KERNEL_VERSION_REVISION_RC "0.4.15-dev-7043-gaf4a3fa\0" -#define KERNEL_VERSION_REVISION_STR "0.4.15-dev-7043-gaf4a3fa" +#define KERNEL_VERSION_REVISION_RC "0.4.15-dev-7059-gbd06299\0" +#define KERNEL_VERSION_REVISION_STR "0.4.15-dev-7059-gbd06299" -#define KERNEL_VERSION_COMMIT_HASH "af4a3fac7d2c6aadc39c5001bdbd2c1913d982f1" +#define KERNEL_VERSION_COMMIT_HASH "bd0629905963e0002ef778cd3b26ebcd95185dbb" #define REACTOS_DLL_VERSION_MAJOR 42 #define REACTOS_DLL_VERSION_RC "42.4.15-dev\0" diff --git a/rsrc.rc b/rsrc.rc index e16d27f..a190357 100644 --- a/rsrc.rc +++ b/rsrc.rc @@ -5,8 +5,6 @@ * COPYRIGHT: Copyright 2009 Benedikt Freisen */ -/* INCLUDES *********************************************************/ - #include #include #include diff --git a/selectionmodel.cpp b/selectionmodel.cpp index ee18b52..2699a85 100644 --- a/selectionmodel.cpp +++ b/selectionmodel.cpp @@ -15,8 +15,6 @@ SelectionModel selectionModel; SelectionModel::SelectionModel() : m_hbmColor(NULL) , m_hbmMask(NULL) - , m_ptStack(NULL) - , m_iPtSP(0) , m_rgbBack(RGB(255, 255, 255)) , m_bShow(FALSE) , m_bContentChanged(FALSE) @@ -30,69 +28,6 @@ SelectionModel::~SelectionModel() { ClearColorImage(); ClearMaskImage(); - ResetPtStack(); -} - -void SelectionModel::ResetPtStack() -{ - if (m_ptStack) - { - free(m_ptStack); - m_ptStack = NULL; - } - m_iPtSP = 0; -} - -void SelectionModel::PushToPtStack(POINT pt) -{ -#define GROW_COUNT 256 - if (m_iPtSP % GROW_COUNT == 0) - { - INT nNewCount = m_iPtSP + GROW_COUNT; - LPPOINT pptNew = (LPPOINT)realloc(m_ptStack, sizeof(POINT) * nNewCount); - if (pptNew == NULL) - return; - m_ptStack = pptNew; - } - m_ptStack[m_iPtSP] = pt; - m_iPtSP++; -#undef GROW_COUNT -} - -void SelectionModel::ShiftPtStack(INT dx, INT dy) -{ - for (INT i = 0; i < m_iPtSP; ++i) - { - POINT& pt = m_ptStack[i]; - pt.x += dx; - pt.y += dy; - } -} - -void SelectionModel::BuildMaskFromPtStack() -{ - CRect rc; - getBoundaryOfPtStack(rc, m_iPtSP, m_ptStack); - - m_rc = m_rcOld = rc; - - ClearMaskImage(); - - ShiftPtStack(-m_rcOld.left, -m_rcOld.top); - - HDC hdcMem = ::CreateCompatibleDC(NULL); - m_hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL); - HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_hbmMask); - ::FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH)); - HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN)); - HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH)); - ::Polygon(hdcMem, m_ptStack, m_iPtSP); - ::SelectObject(hdcMem, hbrOld); - ::SelectObject(hdcMem, hPenOld); - ::SelectObject(hdcMem, hbmOld); - ::DeleteDC(hdcMem); - - ShiftPtStack(+m_rcOld.left, +m_rcOld.top); } void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg) @@ -100,11 +35,11 @@ void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg) if (m_rcOld.IsRectEmpty()) return; - HGDIOBJ hPenOld = ::SelectObject(hDCImage, ::GetStockObject(NULL_PEN)); - HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::CreateSolidBrush(crBg)); - ::Polygon(hDCImage, m_ptStack, m_iPtSP); - ::DeleteObject(::SelectObject(hDCImage, hbrOld)); - ::SelectObject(hDCImage, hPenOld); + HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::GetStockObject(DC_BRUSH)); + ::SetDCBrushColor(hDCImage, crBg); + ::MaskBlt(hDCImage, m_rcOld.left, m_rcOld.top, m_rcOld.Width(), m_rcOld.Height(), + hDCImage, m_rcOld.left, m_rcOld.top, m_hbmMask, 0, 0, MAKEROP4(PATCOPY, SRCCOPY)); + ::SelectObject(hDCImage, hbrOld); } void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg) @@ -115,12 +50,12 @@ void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg) Rect(hDCImage, m_rcOld.left, m_rcOld.top, m_rcOld.right, m_rcOld.bottom, crBg, crBg, 0, 1); } -void SelectionModel::DrawBackground(HDC hDCImage) +void SelectionModel::DrawBackground(HDC hDCImage, COLORREF crBg) { if (toolsModel.GetActiveTool() == TOOL_FREESEL) - DrawBackgroundPoly(hDCImage, paletteModel.GetBgColor()); + DrawBackgroundPoly(hDCImage, crBg); else - DrawBackgroundRect(hDCImage, paletteModel.GetBgColor()); + DrawBackgroundRect(hDCImage, crBg); } void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent) @@ -143,6 +78,15 @@ void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTranspar DeleteDC(hMemDC); } +void SelectionModel::setMask(const CRect& rc, HBITMAP hbmMask) +{ + if (m_hbmMask) + ::DeleteObject(m_hbmMask); + + m_hbmMask = hbmMask; + m_rc = m_rcOld = rc; +} + HBITMAP SelectionModel::GetSelectionContents() { if (m_hbmColor) @@ -178,17 +122,6 @@ BOOL SelectionModel::TakeOff() // Save the selection area m_rcOld = m_rc; - if (toolsModel.GetActiveTool() == TOOL_RECTSEL) - { - imageModel.PushImageForUndo(); - selectionModel.DrawBackgroundRect(imageModel.GetDC(), selectionModel.m_rgbBack); - } - else if (toolsModel.GetActiveTool() == TOOL_FREESEL) - { - imageModel.PushImageForUndo(); - selectionModel.DrawBackgroundPoly(imageModel.GetDC(), selectionModel.m_rgbBack); - } - imageModel.NotifyImageChanged(); return TRUE; } @@ -201,12 +134,12 @@ void SelectionModel::Landing() return; } - m_bShow = FALSE; - if (m_bContentChanged || (!m_rc.EqualRect(m_rcOld) && !m_rc.IsRectEmpty() && !m_rcOld.IsRectEmpty())) { - imageModel.PushImageForUndo(); + CRect rc; + rc.UnionRect(m_rc, m_rcOld); + imageModel.PushImageForUndo(rc); canvasWindow.m_drawing = FALSE; toolsModel.OnDrawOverlayOnImage(imageModel.GetDC()); @@ -397,17 +330,6 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int NotifyContentChanged(); } -int SelectionModel::PtStackSize() const -{ - return m_iPtSP; -} - -void SelectionModel::DrawFramePoly(HDC hDCImage) -{ - /* draw the freehand selection inverted/xored */ - Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE); -} - void SelectionModel::SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo) { m_rc = CRect(ptFrom, ptTo); @@ -491,7 +413,7 @@ void SelectionModel::DeleteSelection() TakeOff(); imageModel.PushImageForUndo(); - DrawBackground(imageModel.GetDC()); + DrawBackground(imageModel.GetDC(), paletteModel.GetBgColor()); HideSelection(); } diff --git a/selectionmodel.h b/selectionmodel.h index 37cf74c..d9007d6 100644 --- a/selectionmodel.h +++ b/selectionmodel.h @@ -13,8 +13,6 @@ class SelectionModel private: HBITMAP m_hbmColor; HBITMAP m_hbmMask; - POINT *m_ptStack; - int m_iPtSP; public: COLORREF m_rgbBack; @@ -23,16 +21,12 @@ class SelectionModel CRect m_rc; // in image pixel coordinates POINT m_ptHit; // in image pixel coordinates CRect m_rcOld; // in image pixel coordinates - INT m_nSelectionBrush = 0; SelectionModel(); ~SelectionModel(); - void ResetPtStack(); - void PushToPtStack(POINT pt); - int PtStackSize() const; void SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo); - void BuildMaskFromPtStack(); + void setMask(const CRect& rc, HBITMAP hbmMask); BOOL TakeOff(); void Landing(); @@ -44,8 +38,7 @@ class SelectionModel void moveSelection(INT xDelta, INT yDelta); HBITMAP GetSelectionContents(); - void DrawFramePoly(HDC hDCImage); - void DrawBackground(HDC hDCImage); + void DrawBackground(HDC hDCImage, COLORREF crBg); void DrawBackgroundPoly(HDC hDCImage, COLORREF crBg); void DrawBackgroundRect(HDC hDCImage, COLORREF crBg); void DrawSelection(HDC hDCImage, COLORREF crBg = 0, BOOL bBgTransparent = FALSE); diff --git a/toolsettings.cpp b/toolsettings.cpp index 589e7e4..36caff7 100644 --- a/toolsettings.cpp +++ b/toolsettings.cpp @@ -7,8 +7,6 @@ * Copyright 2021-2023 Katayama Hirofumi MZ */ -/* INCLUDES *********************************************************/ - #include "precomp.h" #define X_TOOLSETTINGS 0 diff --git a/toolsmodel.cpp b/toolsmodel.cpp index c19a115..f789fbf 100644 --- a/toolsmodel.cpp +++ b/toolsmodel.cpp @@ -209,6 +209,9 @@ SIZE ToolsModel::GetToolSize() const { case TOOL_FREESEL: case TOOL_RECTSEL: + size.cx = selectionModel.m_rc.Width(); + size.cy = selectionModel.m_rc.Height(); + break; case TOOL_COLOR: case TOOL_ZOOM: case TOOL_TEXT: diff --git a/toolsmodel.h b/toolsmodel.h index 668c782..2cd2e68 100644 --- a/toolsmodel.h +++ b/toolsmodel.h @@ -42,7 +42,6 @@ struct ToolBase { HDC m_hdc; COLORREF m_fg, m_bg; - static SIZE_T s_pointSP; ToolBase() : m_hdc(NULL) { } virtual ~ToolBase() { }