[MSPAINT] Realize context menu on canvas (#5352)

- Add actions on Right-Click.
- Add ID_POPUPMENU resource menu.
- Use TrackPopupMenu to show the context menu.
- Improve CMainWindow::OnInitMenuPopup to display context menu.
- Add SelectionModel::m_bContentChanged flag to indicate whether the selection content is changed.
- Fix IDM_IMAGEINVERTCOLORS and IDM_IMAGEROTATEMIRROR commands.
CORE-18867
This commit is contained in:
Katayama Hirofumi MZ 2023-06-19 07:51:19 +09:00 committed by GitHub
parent 0972f71d9a
commit 7aadc1e1fe
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 725 additions and 62 deletions

View file

@ -19,6 +19,7 @@ SelectionModel::SelectionModel()
, m_ptStack(NULL)
, m_iPtSP(0)
, m_bShow(FALSE)
, m_bContentChanged(FALSE)
{
::SetRectEmpty(&m_rc);
::SetRectEmpty(&m_rcOld);
@ -123,6 +124,14 @@ 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)
{
if (toolsModel.GetActiveTool() == TOOL_FREESEL)
DrawBackgroundPoly(hDCImage, paletteModel.GetBgColor());
else
DrawBackgroundRect(hDCImage, paletteModel.GetBgColor());
}
void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent)
{
CRect rc = m_rc;
@ -187,7 +196,8 @@ void SelectionModel::Landing()
m_bShow = FALSE;
if (!::EqualRect(m_rc, m_rcOld) && !::IsRectEmpty(m_rc) && !::IsRectEmpty(m_rcOld))
if (m_bContentChanged ||
(!::EqualRect(m_rc, m_rcOld) && !::IsRectEmpty(m_rc) && !::IsRectEmpty(m_rcOld)))
{
imageModel.PushImageForUndo();
@ -208,9 +218,7 @@ void SelectionModel::InsertFromHBITMAP(HBITMAP hBm, INT x, INT y)
m_rc.right = x + GetDIBWidth(hBm);
m_rc.bottom = y + GetDIBHeight(hBm);
// If m_rc and m_rcOld were same, the image cannot be pasted to the canvas.
// See also SelectionModel::Landing
::SetRect(&m_rcOld, -2, -2, -1, -1); // Outside of image
NotifyContentChanged();
ClearMask();
}
@ -234,7 +242,7 @@ void SelectionModel::FlipHorizontally()
}
::DeleteDC(hdcMem);
imageModel.NotifyImageChanged();
NotifyContentChanged();
}
void SelectionModel::FlipVertically()
@ -256,7 +264,7 @@ void SelectionModel::FlipVertically()
}
::DeleteDC(hdcMem);
imageModel.NotifyImageChanged();
NotifyContentChanged();
}
void SelectionModel::RotateNTimes90Degrees(int iN)
@ -267,9 +275,10 @@ void SelectionModel::RotateNTimes90Degrees(int iN)
switch (iN)
{
case 1:
case 3:
case 1: /* rotate 90 degrees */
case 3: /* rotate 270 degrees */
TakeOff();
if (m_hbmColor)
{
hbmOld = ::SelectObject(hdcMem, m_hbmColor);
@ -286,10 +295,13 @@ void SelectionModel::RotateNTimes90Degrees(int iN)
::DeleteObject(m_hbmMask);
m_hbmMask = hbm;
}
SwapWidthAndHeight();
break;
case 2:
case 2: /* rotate 180 degrees */
TakeOff();
if (m_hbmColor)
{
hbmOld = ::SelectObject(hdcMem, m_hbmColor);
@ -308,7 +320,7 @@ void SelectionModel::RotateNTimes90Degrees(int iN)
}
::DeleteDC(hdcMem);
imageModel.NotifyImageChanged();
NotifyContentChanged();
}
void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX, int nSkewDegY)
@ -351,7 +363,7 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int
::DeleteDC(hDC);
m_bShow = TRUE;
imageModel.NotifyImageChanged();
NotifyContentChanged();
}
HBITMAP SelectionModel::CopyBitmap()
@ -442,12 +454,11 @@ void SelectionModel::ClearColor()
void SelectionModel::HideSelection()
{
m_bShow = FALSE;
m_bShow = m_bContentChanged = FALSE;
ClearColor();
ClearMask();
::SetRectEmpty(&m_rc);
::SetRectEmpty(&m_rcOld);
imageModel.NotifyImageChanged();
}
@ -457,12 +468,39 @@ void SelectionModel::DeleteSelection()
return;
TakeOff();
imageModel.PushImageForUndo();
if (toolsModel.GetActiveTool() == TOOL_FREESEL)
DrawBackgroundPoly(imageModel.GetDC(), paletteModel.GetBgColor());
else
DrawBackgroundRect(imageModel.GetDC(), paletteModel.GetBgColor());
DrawBackground(imageModel.GetDC());
HideSelection();
}
void SelectionModel::InvertSelection()
{
TakeOff();
BITMAP bm;
::GetObject(m_hbmColor, sizeof(bm), &bm);
HDC hdc = ::CreateCompatibleDC(NULL);
HGDIOBJ hbmOld = ::SelectObject(hdc, m_hbmColor);
RECT rc = { 0, 0, bm.bmWidth, bm.bmHeight };
::InvertRect(hdc, &rc);
::SelectObject(hdc, hbmOld);
::DeleteDC(hdc);
NotifyContentChanged();
}
void SelectionModel::NotifyContentChanged()
{
m_bContentChanged = TRUE;
imageModel.NotifyImageChanged();
}
void SelectionModel::SwapWidthAndHeight()
{
INT cx = m_rc.Width();
INT cy = m_rc.Height();
m_rc.right = m_rc.left + cy;
m_rc.bottom = m_rc.top + cx;
}