[MSPAINT] Improve CMiniatureWindow (#5337)

- Save the position and size of the miniature window.
- Improve drawing of the miniature window.
- Sync with the canvas.
CORE-18867
This commit is contained in:
Katayama Hirofumi MZ 2023-06-14 18:51:40 +09:00 committed by GitHub
parent 113656563a
commit bfd42c67a1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 86 additions and 34 deletions

View file

@ -17,6 +17,8 @@ void ImageModel::NotifyImageChanged()
{
if (canvasWindow.IsWindow())
canvasWindow.Invalidate(FALSE);
if (miniature.IsWindow())
miniature.Invalidate(FALSE);
}
ImageModel::ImageModel()
@ -264,7 +266,7 @@ void ImageModel::DeleteSelection()
NotifyImageChanged();
}
void ImageModel::Bound(POINT& pt)
void ImageModel::Bound(POINT& pt) const
{
pt.x = max(0, min(pt.x, GetWidth()));
pt.y = max(0, min(pt.y, GetHeight()));

View file

@ -36,7 +36,8 @@ public:
void FlipVertically();
void RotateNTimes90Degrees(int iN);
void DeleteSelection();
void Bound(POINT& pt);
void Bound(POINT& pt) const;
void NotifyImageChanged();
protected:
HDC hDrawingDC; // The device context for this class
@ -44,6 +45,4 @@ protected:
int undoSteps; // The undo-able count
int redoSteps; // The redo-able count
HBITMAP hBms[HISTORYSIZE]; // A rotation buffer of HBITMAPs
void NotifyImageChanged();
};

View file

@ -5,6 +5,7 @@
* PURPOSE: Window procedure of the main window and all children apart from
* hPalWin, hToolSettings and hSelection
* PROGRAMMERS: Benedikt Freisen
* Katayama Hirofumi MZ
*/
#include "precomp.h"
@ -32,6 +33,30 @@ HWND CMiniatureWindow::DoCreate(HWND hwndParent)
return Create(hwndParent, rc, strTitle, style, WS_EX_PALETTEWINDOW);
}
LRESULT CMiniatureWindow::OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (IsWindowVisible() && !IsIconic() && !IsZoomed())
{
CRect rc;
GetWindowRect(&rc);
registrySettings.ThumbXPos = rc.left;
registrySettings.ThumbYPos = rc.top;
}
return 0;
}
LRESULT CMiniatureWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (IsWindowVisible() && !IsIconic() && !IsZoomed())
{
CRect rc;
GetWindowRect(&rc);
registrySettings.ThumbWidth = rc.Width();
registrySettings.ThumbHeight = rc.Height();
}
return 0;
}
LRESULT CMiniatureWindow::OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
ShowWindow(SW_HIDE);
@ -39,16 +64,45 @@ LRESULT CMiniatureWindow::OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
return 0;
}
LRESULT CMiniatureWindow::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return TRUE; /* Avoid flickering */
}
LRESULT CMiniatureWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
RECT rc;
GetClientRect(&rc);
// Start painting
PAINTSTRUCT ps;
HDC hDC = BeginPaint(&ps);
StretchBlt(hDC, 0, 0, rc.right, rc.bottom,
imageModel.GetDC(), 0, 0, imageModel.GetWidth(), imageModel.GetHeight(),
SRCCOPY);
if (!hDC)
return 0;
// Use a memory bitmap to reduce flickering
HDC hdcMem = ::CreateCompatibleDC(hDC);
HGDIOBJ hbmOld = ::SelectObject(hdcMem, ::CreateCompatibleBitmap(hDC, rc.right, rc.bottom));
// FIXME: Consider aspect ratio
// Fill the background
::FillRect(hdcMem, &rc, (HBRUSH)(COLOR_BTNFACE + 1));
// Draw the image (hdcMem <-- imageModel)
int cxImage = imageModel.GetWidth();
int cyImage = imageModel.GetHeight();
::StretchBlt(hdcMem, 0, 0, rc.right, rc.bottom,
imageModel.GetDC(), 0, 0, cxImage, cyImage,
SRCCOPY);
// Move the image (hDC <-- hdcMem)
::BitBlt(hDC, 0, 0, rc.right, rc.bottom, hdcMem, 0, 0, SRCCOPY);
// Clean up
::DeleteObject(::SelectObject(hdcMem, hbmOld));
::DeleteDC(hdcMem);
EndPaint(&ps);
return 0;
}

View file

@ -16,14 +16,20 @@ public:
COLOR_BTNFACE)
BEGIN_MSG_MAP(CMiniatureWindow)
MESSAGE_HANDLER(WM_MOVE, OnMove)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_CLOSE, OnClose)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
END_MSG_MAP()
HWND DoCreate(HWND hwndParent);
private:
LRESULT OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnClose(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
};

View file

@ -78,11 +78,13 @@ void ToolBase::reset()
void ToolBase::OnCancelDraw()
{
reset();
imageModel.NotifyImageChanged();
}
void ToolBase::OnFinishDraw()
{
reset();
imageModel.NotifyImageChanged();
}
void ToolBase::beginEvent()
@ -151,15 +153,12 @@ struct FreeSelTool : ToolBase
selectionModel.ResetPtStack();
selectionModel.m_bShow = FALSE;
}
canvasWindow.Invalidate(FALSE);
imageModel.NotifyImageChanged();
}
}
void OnFinishDraw() override
{
if (m_bLeftButton)
canvasWindow.Invalidate(FALSE);
m_bLeftButton = FALSE;
ToolBase::OnFinishDraw();
}
@ -214,15 +213,12 @@ struct RectSelTool : ToolBase
if (start.x == x && start.y == y)
imageModel.Undo(TRUE);
selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty();
canvasWindow.Invalidate(FALSE);
imageModel.NotifyImageChanged();
}
}
void OnFinishDraw() override
{
if (m_bLeftButton)
canvasWindow.Invalidate(FALSE);
m_bLeftButton = FALSE;
ToolBase::OnFinishDraw();
}
@ -253,11 +249,13 @@ struct GenericDrawTool : ToolBase
void OnMouseMove(BOOL bLeftButton, LONG x, LONG y) override
{
draw(bLeftButton, x, y);
imageModel.NotifyImageChanged();
}
void OnButtonUp(BOOL bLeftButton, LONG x, LONG y) override
{
draw(bLeftButton, x, y);
imageModel.NotifyImageChanged();
}
void OnCancelDraw() override
@ -574,6 +572,7 @@ struct BezierTool : ToolBase
pointSP++;
if (pointSP == 4)
pointSP = 0;
imageModel.NotifyImageChanged();
}
void OnCancelDraw() override
@ -649,6 +648,7 @@ struct ShapeTool : ToolBase
else
{
draw(bLeftButton, x, y, bDoubleClick);
imageModel.NotifyImageChanged();
}
}

View file

@ -179,7 +179,7 @@ BOOL SelectionModel::TakeOff()
DrawBackgroundRect(hDCImage, paletteModel.GetBgColor());
}
canvasWindow.Invalidate(FALSE);
imageModel.NotifyImageChanged();
return TRUE;
}
@ -229,7 +229,7 @@ void SelectionModel::FlipHorizontally()
}
::DeleteDC(hdcMem);
NotifyRefreshNeeded();
imageModel.NotifyImageChanged();
}
void SelectionModel::FlipVertically()
@ -251,7 +251,7 @@ void SelectionModel::FlipVertically()
}
::DeleteDC(hdcMem);
NotifyRefreshNeeded();
imageModel.NotifyImageChanged();
}
void SelectionModel::RotateNTimes90Degrees(int iN)
@ -303,7 +303,7 @@ void SelectionModel::RotateNTimes90Degrees(int iN)
}
::DeleteDC(hdcMem);
NotifyRefreshNeeded();
imageModel.NotifyImageChanged();
}
void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX, int nSkewDegY)
@ -346,7 +346,7 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int
::DeleteDC(hDC);
m_bShow = TRUE;
NotifyRefreshNeeded();
imageModel.NotifyImageChanged();
}
HBITMAP SelectionModel::GetBitmap()
@ -417,11 +417,6 @@ void SelectionModel::Dragging(CANVAS_HITTEST hit, POINT pt)
m_ptHit = pt;
}
void SelectionModel::NotifyRefreshNeeded()
{
canvasWindow.Invalidate(FALSE);
}
void SelectionModel::ClearMask()
{
if (m_hbmMask)
@ -450,5 +445,5 @@ void SelectionModel::CancelSelection()
imageModel.Undo(TRUE);
m_bShow = FALSE;
canvasWindow.Invalidate(FALSE);
imageModel.NotifyImageChanged();
}

View file

@ -49,7 +49,6 @@ public:
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();

View file

@ -141,8 +141,7 @@ void ToolsModel::SetBackgroundTransparent(BOOL bTransparent)
{
m_transpBg = bTransparent;
NotifyToolSettingsChanged();
if (canvasWindow.IsWindow())
canvasWindow.Invalidate(FALSE);
imageModel.NotifyImageChanged();
}
int ToolsModel::GetZoom() const

View file

@ -207,7 +207,7 @@ void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND window)
imageModel.PushImageForUndo();
selectionModel.InsertFromHBITMAP(bitmap, 0, 0);
selectionModel.m_bShow = TRUE;
canvasWindow.Invalidate(FALSE);
imageModel.NotifyImageChanged();
}
LRESULT CMainWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
@ -510,7 +510,7 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
{
selectionModel.Landing();
selectionModel.m_bShow = FALSE;
canvasWindow.Invalidate(FALSE);
imageModel.NotifyImageChanged();
}
break;
@ -656,7 +656,6 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
break;
}
imageModel.Undo();
canvasWindow.Invalidate(FALSE);
break;
case IDM_EDITREDO:
if (toolsModel.GetActiveTool() == TOOL_TEXT && ::IsWindowVisible(textEditWindow))
@ -667,7 +666,6 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
break;
}
imageModel.Redo();
canvasWindow.Invalidate(FALSE);
break;
case IDM_EDITCOPY:
if (OpenClipboard())
@ -763,7 +761,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
case IDM_IMAGEDELETEIMAGE:
imageModel.PushImageForUndo();
Rect(imageModel.GetDC(), 0, 0, imageModel.GetWidth(), imageModel.GetHeight(), paletteModel.GetBgColor(), paletteModel.GetBgColor(), 0, TRUE);
canvasWindow.Invalidate(FALSE);
imageModel.NotifyImageChanged();
break;
case IDM_IMAGEROTATEMIRROR:
switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd))