[MSPAINT] Make imageArea window-less (#5215)

- Move imageArea code into canvasWindow.
- Delete imgarea.cpp, imgarea.h, and imageArea.
- Add CCanvasWindow::ImageToCanvas and CCanvasWindow::CanvasToImage to convert the coordinates.
- Realize drawing of resizing image area.
CORE-18867
This commit is contained in:
Katayama Hirofumi MZ 2023-04-08 22:25:27 +09:00 committed by GitHub
parent fa322c2e14
commit efe7368c46
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 544 additions and 666 deletions

View file

@ -13,7 +13,6 @@ list(APPEND SOURCE
drawing.cpp drawing.cpp
fullscreen.cpp fullscreen.cpp
history.cpp history.cpp
imgarea.cpp
main.cpp main.cpp
miniature.cpp miniature.cpp
mouse.cpp mouse.cpp

View file

@ -13,20 +13,79 @@ CCanvasWindow canvasWindow;
/* FUNCTIONS ********************************************************/ /* FUNCTIONS ********************************************************/
CCanvasWindow::CCanvasWindow() CCanvasWindow::CCanvasWindow()
: m_whereHit(HIT_NONE) : m_drawing(FALSE)
, m_ptOrig { 0, 0 } , m_hitSelection(HIT_NONE)
, m_whereHit(HIT_NONE)
, m_ptOrig { -1, -1 }
{ {
::SetRectEmpty(&m_rcNew);
}
VOID CCanvasWindow::drawZoomFrame(INT mouseX, INT mouseY)
{
// FIXME: Draw the border of the area that is to be zoomed in
CRect rc;
GetImageRect(rc);
ImageToCanvas(rc);
HDC hdc = GetDC();
DrawXorRect(hdc, &rc);
ReleaseDC(hdc);
} }
RECT CCanvasWindow::GetBaseRect() RECT CCanvasWindow::GetBaseRect()
{ {
CRect rcBase = { 0, 0, Zoomed(imageModel.GetWidth()), Zoomed(imageModel.GetHeight()) }; CRect rcBase;
GetImageRect(rcBase);
ImageToCanvas(rcBase);
::InflateRect(&rcBase, GRIP_SIZE, GRIP_SIZE); ::InflateRect(&rcBase, GRIP_SIZE, GRIP_SIZE);
::OffsetRect(&rcBase, GRIP_SIZE - GetScrollPos(SB_HORZ), GRIP_SIZE - GetScrollPos(SB_VERT));
return rcBase; return rcBase;
} }
CANVAS_HITTEST CCanvasWindow::HitTest(POINT pt) VOID CCanvasWindow::ImageToCanvas(POINT& pt)
{
pt.x = Zoomed(pt.x);
pt.y = Zoomed(pt.y);
pt.x += GRIP_SIZE - GetScrollPos(SB_HORZ);
pt.y += GRIP_SIZE - GetScrollPos(SB_VERT);
}
VOID CCanvasWindow::ImageToCanvas(RECT& rc)
{
rc.left = Zoomed(rc.left);
rc.top = Zoomed(rc.top);
rc.right = Zoomed(rc.right);
rc.bottom = Zoomed(rc.bottom);
::OffsetRect(&rc, GRIP_SIZE - GetScrollPos(SB_HORZ), GRIP_SIZE - GetScrollPos(SB_VERT));
}
VOID CCanvasWindow::CanvasToImage(POINT& pt, BOOL bZoomed)
{
pt.x -= GRIP_SIZE - GetScrollPos(SB_HORZ);
pt.y -= GRIP_SIZE - GetScrollPos(SB_VERT);
if (bZoomed)
return;
pt.x = UnZoomed(pt.x);
pt.y = UnZoomed(pt.y);
}
VOID CCanvasWindow::CanvasToImage(RECT& rc, BOOL bZoomed)
{
::OffsetRect(&rc, GetScrollPos(SB_HORZ) - GRIP_SIZE, GetScrollPos(SB_VERT) - GRIP_SIZE);
if (bZoomed)
return;
rc.left = UnZoomed(rc.left);
rc.top = UnZoomed(rc.top);
rc.right = UnZoomed(rc.right);
rc.bottom = UnZoomed(rc.bottom);
}
VOID CCanvasWindow::GetImageRect(RECT& rc)
{
::SetRect(&rc, 0, 0, imageModel.GetWidth(), imageModel.GetHeight());
}
CANVAS_HITTEST CCanvasWindow::CanvasHitTest(POINT pt)
{ {
RECT rcBase = GetBaseRect(); RECT rcBase = GetBaseRect();
return getSizeBoxHitTest(pt, &rcBase); return getSizeBoxHitTest(pt, &rcBase);
@ -42,9 +101,62 @@ VOID CCanvasWindow::DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint)
// Fill the background // Fill the background
::FillRect(hdcMem, &rcPaint, (HBRUSH)(COLOR_APPWORKSPACE + 1)); ::FillRect(hdcMem, &rcPaint, (HBRUSH)(COLOR_APPWORKSPACE + 1));
// Draw the sizeboxes // Draw the sizeboxes if necessary
RECT rcBase = GetBaseRect(); RECT rcBase = GetBaseRect();
drawSizeBoxes(hdcMem, &rcBase, FALSE, &rcPaint); if (!selectionModel.m_bShow)
drawSizeBoxes(hdcMem, &rcBase, FALSE, &rcPaint);
// Draw the image
CRect rcImage;
GetImageRect(rcImage);
ImageToCanvas(rcImage);
SIZE sizeImage = { imageModel.GetWidth(), imageModel.GetHeight() };
StretchBlt(hdcMem, rcImage.left, rcImage.top, rcImage.Width(), rcImage.Height(),
imageModel.GetDC(), 0, 0, sizeImage.cx, sizeImage.cy, SRCCOPY);
// Draw the grid
if (showGrid && toolsModel.GetZoom() >= 4000)
{
HPEN oldPen = (HPEN) SelectObject(hdcMem, CreatePen(PS_SOLID, 1, RGB(160, 160, 160)));
for (INT counter = 0; counter < sizeImage.cy; counter++)
{
POINT pt0 = { 0, counter }, pt1 = { sizeImage.cx, counter };
ImageToCanvas(pt0);
ImageToCanvas(pt1);
::MoveToEx(hdcMem, pt0.x, pt0.y, NULL);
::LineTo(hdcMem, pt1.x, pt1.y);
}
for (INT counter = 0; counter < sizeImage.cx; counter++)
{
POINT pt0 = { counter, 0 }, pt1 = { counter, sizeImage.cy };
ImageToCanvas(pt0);
ImageToCanvas(pt1);
::MoveToEx(hdcMem, pt0.x, pt0.y, NULL);
::LineTo(hdcMem, pt1.x, pt1.y);
}
::DeleteObject(::SelectObject(hdcMem, oldPen));
}
// Draw selection
if (selectionModel.m_bShow)
{
RECT rcSelection = selectionModel.m_rc;
ImageToCanvas(rcSelection);
::InflateRect(&rcSelection, GRIP_SIZE, GRIP_SIZE);
drawSizeBoxes(hdcMem, &rcSelection, TRUE, &rcPaint);
::InflateRect(&rcSelection, -GRIP_SIZE, -GRIP_SIZE);
INT iSaveDC = ::SaveDC(hdcMem);
::IntersectClipRect(hdcMem, rcImage.left, rcImage.top, rcImage.right, rcImage.bottom);
selectionModel.DrawSelection(hdcMem, &rcSelection, paletteModel.GetBgColor(),
toolsModel.IsBackgroundTransparent());
::RestoreDC(hdcMem, iSaveDC);
}
// Draw new frame if any
if (!::IsRectEmpty(&m_rcNew))
DrawXorRect(hdcMem, &m_rcNew);
// Transfer the bits // Transfer the bits
::BitBlt(hDC, ::BitBlt(hDC,
@ -65,7 +177,7 @@ VOID CCanvasWindow::Update(HWND hwndFrom)
CSize sizeZoomed = { Zoomed(imageModel.GetWidth()), Zoomed(imageModel.GetHeight()) }; CSize sizeZoomed = { Zoomed(imageModel.GetWidth()), Zoomed(imageModel.GetHeight()) };
CSize sizeWhole = { sizeZoomed.cx + (GRIP_SIZE * 2), sizeZoomed.cy + (GRIP_SIZE * 2) }; CSize sizeWhole = { sizeZoomed.cx + (GRIP_SIZE * 2), sizeZoomed.cy + (GRIP_SIZE * 2) };
/* show/hide the scrollbars */ // show/hide the scrollbars
ShowScrollBar(SB_HORZ, sizePage.cx < sizeWhole.cx); ShowScrollBar(SB_HORZ, sizePage.cx < sizeWhole.cx);
ShowScrollBar(SB_VERT, sizePage.cy < sizeWhole.cy); ShowScrollBar(SB_VERT, sizePage.cy < sizeWhole.cy);
@ -85,12 +197,6 @@ VOID CCanvasWindow::Update(HWND hwndFrom)
si.nMax = sizeWhole.cy; si.nMax = sizeWhole.cy;
si.nPage = sizePage.cy; si.nPage = sizePage.cy;
SetScrollInfo(SB_VERT, &si); SetScrollInfo(SB_VERT, &si);
if (imageArea.IsWindow() && hwndFrom != imageArea.m_hWnd)
{
INT dx = -GetScrollPos(SB_HORZ), dy = -GetScrollPos(SB_VERT);
imageArea.MoveWindow(dx + GRIP_SIZE, dy + GRIP_SIZE, sizeZoomed.cx, sizeZoomed.cy, TRUE);
}
} }
LRESULT CCanvasWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) LRESULT CCanvasWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
@ -143,60 +249,221 @@ LRESULT CCanvasWindow::OnVScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
return 0; return 0;
} }
LRESULT CCanvasWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) LRESULT CCanvasWindow::OnLRButtonDown(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ {
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) }; POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
CANVAS_HITTEST hit = HitTest(pt);
CANVAS_HITTEST hitSelection = SelectionHitTest(pt);
if (hitSelection != HIT_NONE)
{
if (bLeftButton)
{
UnZoomed(pt);
StartSelectionDrag(hitSelection, pt);
}
return 0;
}
CANVAS_HITTEST hit = CanvasHitTest(pt);
if (hit == HIT_NONE || hit == HIT_BORDER) if (hit == HIT_NONE || hit == HIT_BORDER)
{ {
switch (toolsModel.GetActiveTool()) switch (toolsModel.GetActiveTool())
{ {
case TOOL_BEZIER: case TOOL_BEZIER:
case TOOL_SHAPE: case TOOL_SHAPE:
if (ToolBase::pointSP != 0) toolsModel.OnCancelDraw();
{ canvasWindow.Invalidate();
toolsModel.OnCancelDraw();
imageArea.Invalidate();
}
break; break;
case TOOL_FREESEL: case TOOL_FREESEL:
case TOOL_RECTSEL: case TOOL_RECTSEL:
toolsModel.OnFinishDraw(); toolsModel.OnFinishDraw();
imageArea.Invalidate(); canvasWindow.Invalidate();
break; break;
default: default:
break; break;
} }
toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions
return 0; return 0;
} }
CanvasToImage(pt, TRUE);
if (hit == HIT_INNER) if (hit == HIT_INNER)
{ {
// TODO: In the future, we handle the events of the window-less image area. m_drawing = TRUE;
UnZoomed(pt);
SetCapture();
toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, FALSE);
Invalidate(FALSE);
return 0; return 0;
} }
// Start dragging if (bLeftButton)
m_whereHit = hit; {
m_ptOrig = pt; m_whereHit = hit;
SetCapture(); UnZoomed(pt);
m_ptOrig = pt;
SetCapture();
}
return 0; return 0;
} }
LRESULT CCanvasWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return OnLRButtonDown(TRUE, nMsg, wParam, lParam, bHandled);
}
LRESULT CCanvasWindow::OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return OnLRButtonDown(FALSE, nMsg, wParam, lParam, bHandled);
}
LRESULT CCanvasWindow::OnLRButtonDblClk(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
CanvasToImage(pt);
m_drawing = FALSE;
ReleaseCapture();
toolsModel.OnButtonDown(bLeftButton, pt.x, pt.y, TRUE);
toolsModel.resetTool();
Invalidate(FALSE);
return 0;
}
LRESULT CCanvasWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return OnLRButtonDblClk(TRUE, nMsg, wParam, lParam, bHandled);
}
LRESULT CCanvasWindow::OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return OnLRButtonDblClk(FALSE, nMsg, wParam, lParam, bHandled);
}
LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ {
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
CanvasToImage(pt);
if (m_hitSelection != HIT_NONE)
{
SelectionDragging(pt);
return 0;
}
if (!m_drawing || toolsModel.GetActiveTool() <= TOOL_AIRBRUSH)
{
if (toolsModel.GetActiveTool() == TOOL_ZOOM)
{
Invalidate(FALSE);
UpdateWindow();
CanvasToImage(pt);
drawZoomFrame(pt.x, pt.y);
}
TRACKMOUSEEVENT tme = { sizeof(tme) };
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = m_hWnd;
tme.dwHoverTime = 0;
::TrackMouseEvent(&tme);
if (!m_drawing)
{
CString strCoord;
strCoord.Format(_T("%ld, %ld"), pt.x, pt.y);
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord);
}
}
if (m_drawing)
{
// values displayed in statusbar
LONG xRel = pt.x - start.x;
LONG yRel = pt.y - start.y;
switch (toolsModel.GetActiveTool())
{
// freesel, rectsel and text tools always show numbers limited to fit into image area
case TOOL_FREESEL:
case TOOL_RECTSEL:
case TOOL_TEXT:
if (xRel < 0)
xRel = (pt.x < 0) ? -start.x : xRel;
else if (pt.x > imageModel.GetWidth())
xRel = imageModel.GetWidth() - start.x;
if (yRel < 0)
yRel = (pt.y < 0) ? -start.y : yRel;
else if (pt.y > imageModel.GetHeight())
yRel = imageModel.GetHeight() - start.y;
break;
// while drawing, update cursor coordinates only for tools 3, 7, 8, 9, 14
case TOOL_RUBBER:
case TOOL_PEN:
case TOOL_BRUSH:
case TOOL_AIRBRUSH:
case TOOL_SHAPE:
{
CString strCoord;
strCoord.Format(_T("%ld, %ld"), pt.x, pt.y);
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord);
break;
}
default:
break;
}
// rectsel and shape tools always show non-negative numbers when drawing
if (toolsModel.GetActiveTool() == TOOL_RECTSEL || toolsModel.GetActiveTool() == TOOL_SHAPE)
{
if (xRel < 0)
xRel = -xRel;
if (yRel < 0)
yRel = -yRel;
}
if (wParam & MK_LBUTTON)
{
toolsModel.OnMouseMove(TRUE, pt.x, pt.y);
Invalidate(FALSE);
if ((toolsModel.GetActiveTool() >= TOOL_TEXT) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_FREESEL))
{
CString strSize;
if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0))
yRel = xRel;
strSize.Format(_T("%ld x %ld"), xRel, yRel);
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize);
}
}
if (wParam & MK_RBUTTON)
{
toolsModel.OnMouseMove(FALSE, pt.x, pt.y);
Invalidate(FALSE);
if (toolsModel.GetActiveTool() >= TOOL_TEXT)
{
CString strSize;
if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0))
yRel = xRel;
strSize.Format(_T("%ld x %ld"), xRel, yRel);
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize);
}
}
return 0;
}
if (m_whereHit == HIT_NONE || ::GetCapture() != m_hWnd) if (m_whereHit == HIT_NONE || ::GetCapture() != m_hWnd)
return 0; return 0;
// Dragging now... Calculate the new size // Dragging now... Calculate the new size
INT cxImage = imageModel.GetWidth(), cyImage = imageModel.GetHeight(); INT cxImage = imageModel.GetWidth(), cyImage = imageModel.GetHeight();
INT cxDelta = UnZoomed(GET_X_LPARAM(lParam) - m_ptOrig.x); INT cxDelta = pt.x - m_ptOrig.x;
INT cyDelta = UnZoomed(GET_Y_LPARAM(lParam) - m_ptOrig.y); INT cyDelta = pt.y - m_ptOrig.y;
switch (m_whereHit) switch (m_whereHit)
{ {
case HIT_UPPER_LEFT: case HIT_UPPER_LEFT:
@ -242,20 +509,62 @@ LRESULT CCanvasWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL
strSize.Format(_T("%d x %d"), cxImage, cyImage); strSize.Format(_T("%d x %d"), cxImage, cyImage);
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize); SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize);
CRect rc = { 0, 0, cxImage, cyImage };
switch (m_whereHit)
{
case HIT_UPPER_LEFT:
::OffsetRect(&rc, cxDelta, cyDelta);
break;
case HIT_UPPER_CENTER:
::OffsetRect(&rc, 0, cyDelta);
break;
case HIT_UPPER_RIGHT:
::OffsetRect(&rc, 0, cyDelta);
break;
case HIT_MIDDLE_LEFT:
::OffsetRect(&rc, cxDelta, 0);
break;
case HIT_LOWER_LEFT:
::OffsetRect(&rc, cxDelta, 0);
break;
default:
break;
}
ImageToCanvas(rc);
m_rcNew = rc;
Invalidate(TRUE);
return 0; return 0;
} }
LRESULT CCanvasWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) LRESULT CCanvasWindow::OnLRButtonUp(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ {
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
CanvasToImage(pt);
::ReleaseCapture(); ::ReleaseCapture();
if (m_whereHit == HIT_NONE) if (m_drawing)
{
m_drawing = FALSE;
toolsModel.OnButtonUp(bLeftButton, pt.x, pt.y);
Invalidate(FALSE);
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
return 0;
}
else if (m_hitSelection != HIT_NONE && bLeftButton)
{
EndSelectionDrag(pt);
return 0;
}
if (m_whereHit == HIT_NONE || !bLeftButton)
return 0; return 0;
// Resize the image // Resize the image
INT cxImage = imageModel.GetWidth(), cyImage = imageModel.GetHeight(); INT cxImage = imageModel.GetWidth(), cyImage = imageModel.GetHeight();
INT cxDelta = UnZoomed(GET_X_LPARAM(lParam) - m_ptOrig.x); INT cxDelta = pt.x - m_ptOrig.x;
INT cyDelta = UnZoomed(GET_Y_LPARAM(lParam) - m_ptOrig.y); INT cyDelta = pt.y - m_ptOrig.y;
switch (m_whereHit) switch (m_whereHit)
{ {
case HIT_UPPER_LEFT: case HIT_UPPER_LEFT:
@ -285,23 +594,68 @@ LRESULT CCanvasWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL
default: default:
break; break;
} }
::SetRectEmpty(&m_rcNew);
// Finish dragging
m_whereHit = HIT_NONE; m_whereHit = HIT_NONE;
toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions
Update(NULL); Update(NULL);
Invalidate(TRUE); Invalidate(TRUE);
return 0; return 0;
} }
LRESULT CCanvasWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return OnLRButtonUp(TRUE, nMsg, wParam, lParam, bHandled);
}
LRESULT CCanvasWindow::OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return OnLRButtonUp(FALSE, nMsg, wParam, lParam, bHandled);
}
LRESULT CCanvasWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) LRESULT CCanvasWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ {
POINT pt; POINT pt;
::GetCursorPos(&pt); ::GetCursorPos(&pt);
ScreenToClient(&pt); ScreenToClient(&pt);
if (!setCursorOnSizeBox(HitTest(pt))) CANVAS_HITTEST hitSelection = SelectionHitTest(pt);
if (hitSelection != HIT_NONE)
{
if (!setCursorOnSizeBox(hitSelection))
::SetCursor(::LoadCursor(NULL, IDC_SIZEALL));
return 0;
}
CRect rcImage;
GetImageRect(rcImage);
ImageToCanvas(rcImage);
if (::PtInRect(&rcImage, pt))
{
switch (toolsModel.GetActiveTool())
{
case TOOL_FILL:
::SetCursor(::LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_FILL)));
break;
case TOOL_COLOR:
::SetCursor(::LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_COLOR)));
break;
case TOOL_ZOOM:
::SetCursor(::LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_ZOOM)));
break;
case TOOL_PEN:
::SetCursor(::LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_PEN)));
break;
case TOOL_AIRBRUSH:
::SetCursor(::LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_AIRBRUSH)));
break;
default:
::SetCursor(::LoadCursor(NULL, IDC_CROSS));
}
return 0;
}
if (selectionModel.m_bShow || !setCursorOnSizeBox(CanvasHitTest(pt)))
::SetCursor(::LoadCursor(NULL, IDC_ARROW)); ::SetCursor(::LoadCursor(NULL, IDC_ARROW));
return 0; return 0;
@ -354,3 +708,56 @@ LRESULT CCanvasWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
EndPaint(&ps); EndPaint(&ps);
return 0; return 0;
} }
VOID CCanvasWindow::cancelDrawing()
{
selectionModel.ClearColor();
selectionModel.ClearMask();
m_hitSelection = HIT_NONE;
m_drawing = FALSE;
toolsModel.OnCancelDraw();
Invalidate(FALSE);
}
VOID CCanvasWindow::finishDrawing()
{
toolsModel.OnFinishDraw();
m_drawing = FALSE;
Invalidate(FALSE);
}
CANVAS_HITTEST CCanvasWindow::SelectionHitTest(POINT ptZoomed)
{
if (!selectionModel.m_bShow)
return HIT_NONE;
RECT rcSelection = selectionModel.m_rc;
Zoomed(rcSelection);
::OffsetRect(&rcSelection, GRIP_SIZE - GetScrollPos(SB_HORZ), GRIP_SIZE - GetScrollPos(SB_VERT));
::InflateRect(&rcSelection, GRIP_SIZE, GRIP_SIZE);
return getSizeBoxHitTest(ptZoomed, &rcSelection);
}
VOID CCanvasWindow::StartSelectionDrag(CANVAS_HITTEST hit, POINT ptUnZoomed)
{
m_hitSelection = hit;
selectionModel.m_ptHit = ptUnZoomed;
selectionModel.TakeOff();
SetCapture();
Invalidate(FALSE);
}
VOID CCanvasWindow::SelectionDragging(POINT ptUnZoomed)
{
selectionModel.Dragging(m_hitSelection, ptUnZoomed);
Invalidate(FALSE);
}
VOID CCanvasWindow::EndSelectionDrag(POINT ptUnZoomed)
{
selectionModel.Dragging(m_hitSelection, ptUnZoomed);
m_hitSelection = HIT_NONE;
Invalidate(FALSE);
}

View file

@ -11,7 +11,7 @@
class CCanvasWindow : public CWindowImpl<CCanvasWindow> class CCanvasWindow : public CWindowImpl<CCanvasWindow>
{ {
public: public:
DECLARE_WND_CLASS_EX(_T("ReactOSPaintCanvas"), 0, COLOR_APPWORKSPACE) DECLARE_WND_CLASS_EX(_T("ReactOSPaintCanvas"), CS_DBLCLKS, COLOR_APPWORKSPACE)
BEGIN_MSG_MAP(CCanvasWindow) BEGIN_MSG_MAP(CCanvasWindow)
MESSAGE_HANDLER(WM_SIZE, OnSize) MESSAGE_HANDLER(WM_SIZE, OnSize)
@ -21,8 +21,12 @@ public:
MESSAGE_HANDLER(WM_VSCROLL, OnVScroll) MESSAGE_HANDLER(WM_VSCROLL, OnVScroll)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd) MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown) MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_RBUTTONDOWN, OnRButtonDown)
MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk)
MESSAGE_HANDLER(WM_RBUTTONDBLCLK, OnRButtonDblClk)
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown) MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp) MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
MESSAGE_HANDLER(WM_RBUTTONUP, OnRButtonUp)
MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor) MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel) MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
MESSAGE_HANDLER(WM_CANCELMODE, OnCancelMode) MESSAGE_HANDLER(WM_CANCELMODE, OnCancelMode)
@ -31,16 +35,34 @@ public:
CCanvasWindow(); CCanvasWindow();
BOOL m_drawing;
VOID cancelDrawing();
VOID finishDrawing();
VOID Update(HWND hwndFrom); VOID Update(HWND hwndFrom);
VOID ImageToCanvas(POINT& pt);
VOID ImageToCanvas(RECT& rc);
VOID CanvasToImage(POINT& pt, BOOL bZoomed = FALSE);
VOID CanvasToImage(RECT& rc, BOOL bZoomed = FALSE);
VOID GetImageRect(RECT& rc);
protected: protected:
CANVAS_HITTEST m_hitSelection;
CANVAS_HITTEST m_whereHit; CANVAS_HITTEST m_whereHit;
POINT m_ptOrig; // The origin of drag start POINT m_ptOrig; // The origin of drag start
CRect m_rcNew;
CANVAS_HITTEST HitTest(POINT pt); CANVAS_HITTEST CanvasHitTest(POINT pt);
RECT GetBaseRect(); RECT GetBaseRect();
VOID DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint); VOID DoDraw(HDC hDC, RECT& rcClient, RECT& rcPaint);
VOID OnHVScroll(WPARAM wParam, INT fnBar); VOID OnHVScroll(WPARAM wParam, INT fnBar);
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);
LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnHScroll(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
@ -48,11 +70,19 @@ protected:
LRESULT OnEraseBkgnd(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 OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnCancelMode(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnCancelMode(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled); LRESULT OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLRButtonDown(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLRButtonDblClk(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLRButtonUp(BOOL bLeftButton, UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
}; };

View file

@ -363,3 +363,14 @@ ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
return TRUE; return TRUE;
} }
void DrawXorRect(HDC hdc, const RECT *prc)
{
HGDIOBJ oldPen = ::SelectObject(hdc, ::CreatePen(PS_SOLID, 0, RGB(255, 255, 255)));
HGDIOBJ oldBrush = ::SelectObject(hdc, ::GetStockObject(NULL_BRUSH));
INT oldRop2 = SetROP2(hdc, R2_XORPEN);
::Rectangle(hdc, prc->left, prc->top, prc->right, prc->bottom);
::SetROP2(hdc, oldRop2);
::SelectObject(hdc, oldBrush);
::DeleteObject(::SelectObject(hdc, oldPen));
}

View file

@ -38,3 +38,5 @@ BOOL
ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
HDC hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight, HDC hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight,
HBITMAP hbmMask, COLORREF keyColor); HBITMAP hbmMask, COLORREF keyColor);
void DrawXorRect(HDC hdc, const RECT *prc);

View file

@ -52,5 +52,4 @@ extern CToolBox toolBoxContainer;
extern CToolSettingsWindow toolSettingsWindow; extern CToolSettingsWindow toolSettingsWindow;
extern CPaletteWindow paletteWindow; extern CPaletteWindow paletteWindow;
extern CCanvasWindow canvasWindow; extern CCanvasWindow canvasWindow;
extern CImgAreaWindow imageArea;
extern CTextEditWindow textEditWindow; extern CTextEditWindow textEditWindow;

View file

@ -14,14 +14,14 @@ ImageModel imageModel;
void ImageModel::NotifyDimensionsChanged() void ImageModel::NotifyDimensionsChanged()
{ {
if (imageArea.IsWindow()) if (canvasWindow.IsWindow())
imageArea.SendMessage(WM_IMAGEMODELDIMENSIONSCHANGED); canvasWindow.SendMessage(WM_IMAGEMODELDIMENSIONSCHANGED);
} }
void ImageModel::NotifyImageChanged() void ImageModel::NotifyImageChanged()
{ {
if (imageArea.IsWindow()) if (canvasWindow.IsWindow())
imageArea.SendMessage(WM_IMAGEMODELIMAGECHANGED); canvasWindow.SendMessage(WM_IMAGEMODELIMAGECHANGED);
} }
ImageModel::ImageModel() ImageModel::ImageModel()

View file

@ -1,480 +0,0 @@
/*
* PROJECT: PAINT for ReactOS
* LICENSE: LGPL
* FILE: base/applications/mspaint/imgarea.cpp
* 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"
CImgAreaWindow imageArea;
/* FUNCTIONS ********************************************************/
LRESULT CImgAreaWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
m_hCurFill = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_FILL));
m_hCurColor = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_COLOR));
m_hCurZoom = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_ZOOM));
m_hCurPen = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_PEN));
m_hCurAirbrush = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_AIRBRUSH));
return 0;
}
void CImgAreaWindow::drawZoomFrame(int mouseX, int mouseY)
{
HDC hdc;
HPEN oldPen;
HBRUSH oldBrush;
LOGBRUSH logbrush;
int rop;
RECT clientRectCanvas;
RECT clientRectImageArea;
int x, y, w, h;
canvasWindow.GetClientRect(&clientRectCanvas);
GetClientRect(&clientRectImageArea);
w = clientRectImageArea.right * 2;
h = clientRectImageArea.bottom * 2;
if (!w || !h)
{
return;
}
w = clientRectImageArea.right * clientRectCanvas.right / w;
h = clientRectImageArea.bottom * clientRectCanvas.bottom / h;
x = max(0, min(clientRectImageArea.right - w, mouseX - w / 2));
y = max(0, min(clientRectImageArea.bottom - h, mouseY - h / 2));
hdc = GetDC();
oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 0, 0));
logbrush.lbStyle = BS_HOLLOW;
oldBrush = (HBRUSH) SelectObject(hdc, CreateBrushIndirect(&logbrush));
rop = SetROP2(hdc, R2_NOT);
Rectangle(hdc, x, y, x + w, y + h);
SetROP2(hdc, rop);
DeleteObject(SelectObject(hdc, oldBrush));
DeleteObject(SelectObject(hdc, oldPen));
ReleaseDC(hdc);
}
LRESULT CImgAreaWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (!IsWindow())
return 0;
canvasWindow.Update(NULL);
return 0;
}
LRESULT CImgAreaWindow::OnEraseBkGnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
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);
// 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(hdcMem, CreatePen(PS_SOLID, 1, 0x00a0a0a0));
for (int counter = 0; counter <= size.cy; counter++)
{
::MoveToEx(hdcMem, 0, ::Zoomed(counter), NULL);
::LineTo(hdcMem, ::Zoomed(size.cx), ::Zoomed(counter));
}
for (int counter = 0; counter <= size.cx; counter++)
{
::MoveToEx(hdcMem, ::Zoomed(counter), 0, NULL);
::LineTo(hdcMem, ::Zoomed(counter), ::Zoomed(size.cy));
}
::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 (miniature.IsWindow())
miniature.Invalidate(FALSE);
if (textEditWindow.IsWindow())
textEditWindow.Invalidate(FALSE);
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:
::SetCursor(m_hCurFill);
break;
case TOOL_COLOR:
::SetCursor(m_hCurColor);
break;
case TOOL_ZOOM:
::SetCursor(m_hCurZoom);
break;
case TOOL_PEN:
::SetCursor(m_hCurPen);
break;
case TOOL_AIRBRUSH:
::SetCursor(m_hCurAirbrush);
break;
default:
::SetCursor(::LoadCursor(NULL, IDC_CROSS));
}
return 0;
}
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();
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();
toolsModel.OnButtonDown(TRUE, pt.x, pt.y, TRUE);
toolsModel.resetTool();
Invalidate(FALSE);
return 0;
}
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();
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();
toolsModel.OnButtonDown(FALSE, pt.x, pt.y, TRUE);
toolsModel.resetTool();
Invalidate(FALSE);
return 0;
}
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;
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);
}
LRESULT CImgAreaWindow::OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (drawing)
cancelDrawing();
return 0;
}
LRESULT CImgAreaWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
if (wParam == VK_ESCAPE)
{
if (GetCapture() == m_hWnd)
{
ReleaseCapture();
}
else
{
if (drawing || ToolBase::pointSP != 0 || selectionModel.m_bShow)
cancelDrawing();
}
}
return 0;
}
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;
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)
{
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;
if (toolsModel.GetActiveTool() == TOOL_ZOOM)
{
Invalidate(FALSE);
UpdateWindow();
drawZoomFrame(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
}
tme.cbSize = sizeof(TRACKMOUSEEVENT);
tme.dwFlags = TME_LEAVE;
tme.hwndTrack = m_hWnd;
tme.dwHoverTime = 0;
TrackMouseEvent(&tme);
if (!drawing)
{
CString strCoord;
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 = 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 = (pt.x < 0) ? -start.x : xRel;
else if (pt.x > imageModel.GetWidth())
xRel = imageModel.GetWidth() - start.x;
if (yRel < 0)
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))
{
if (xRel < 0)
xRel = -xRel;
if (yRel < 0)
yRel = -yRel;
}
/* while drawing, update cursor coordinates only for tools 3, 7, 8, 9, 14 */
switch(toolsModel.GetActiveTool())
{
case TOOL_RUBBER:
case TOOL_PEN:
case TOOL_BRUSH:
case TOOL_AIRBRUSH:
case TOOL_SHAPE:
{
CString strCoord;
strCoord.Format(_T("%ld, %ld"), pt.x, pt.y);
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord);
break;
}
default:
break;
}
if (wParam & MK_LBUTTON)
{
toolsModel.OnMouseMove(TRUE, pt.x, pt.y);
Invalidate(FALSE);
if ((toolsModel.GetActiveTool() >= TOOL_TEXT) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_FREESEL))
{
CString strSize;
if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0))
yRel = xRel;
strSize.Format(_T("%ld x %ld"), xRel, yRel);
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize);
}
}
if (wParam & MK_RBUTTON)
{
toolsModel.OnMouseMove(FALSE, pt.x, pt.y);
Invalidate(FALSE);
if (toolsModel.GetActiveTool() >= TOOL_TEXT)
{
CString strSize;
if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0))
yRel = xRel;
strSize.Format(_T("%ld x %ld"), xRel, yRel);
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize);
}
}
}
return 0;
}
LRESULT CImgAreaWindow::OnMouseLeave(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) _T(""));
if (toolsModel.GetActiveTool() == TOOL_ZOOM)
Invalidate(FALSE);
return 0;
}
LRESULT CImgAreaWindow::OnImageModelDimensionsChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
canvasWindow.Update(NULL);
return 0;
}
LRESULT CImgAreaWindow::OnImageModelImageChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
Invalidate(FALSE);
return 0;
}
LRESULT CImgAreaWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
return ::SendMessage(GetParent(), nMsg, wParam, lParam);
}
LRESULT CImgAreaWindow::OnCtlColorEdit(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
HDC hdc = (HDC)wParam;
SetBkMode(hdc, TRANSPARENT);
return (LRESULT)GetStockObject(NULL_BRUSH);
}
void CImgAreaWindow::finishDrawing()
{
toolsModel.OnFinishDraw();
drawing = FALSE;
Invalidate(FALSE);
}

View file

@ -1,84 +0,0 @@
/*
* PROJECT: PAINT for ReactOS
* LICENSE: LGPL
* FILE: base/applications/mspaint/imgarea.h
* PURPOSE: Window procedure of the main window and all children apart from
* hPalWin, hToolSettings and hSelection
* PROGRAMMERS: Benedikt Freisen
* Katayama Hirofumi MZ
*/
#pragma once
class CImgAreaWindow : public CWindowImpl<CImgAreaWindow>
{
public:
CImgAreaWindow()
: drawing(FALSE)
, m_hitSelection(HIT_NONE)
{
}
BOOL drawing;
CANVAS_HITTEST m_hitSelection;
void cancelDrawing();
void finishDrawing();
DECLARE_WND_CLASS_EX(_T("ImgAreaWindow"), CS_DBLCLKS, COLOR_BTNFACE)
BEGIN_MSG_MAP(CImgAreaWindow)
MESSAGE_HANDLER(WM_SIZE, OnSize)
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkGnd)
MESSAGE_HANDLER(WM_PAINT, OnPaint)
MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
MESSAGE_HANDLER(WM_LBUTTONDBLCLK, OnLButtonDblClk)
MESSAGE_HANDLER(WM_RBUTTONDOWN, OnRButtonDown)
MESSAGE_HANDLER(WM_RBUTTONDBLCLK, OnRButtonDblClk)
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
MESSAGE_HANDLER(WM_RBUTTONUP, OnRButtonUp)
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
MESSAGE_HANDLER(WM_MOUSELEAVE, OnMouseLeave)
MESSAGE_HANDLER(WM_IMAGEMODELDIMENSIONSCHANGED, OnImageModelDimensionsChanged)
MESSAGE_HANDLER(WM_IMAGEMODELIMAGECHANGED, OnImageModelImageChanged)
MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
MESSAGE_HANDLER(WM_CTLCOLOREDIT, OnCtlColorEdit)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
END_MSG_MAP()
private:
HCURSOR m_hCurFill;
HCURSOR m_hCurColor;
HCURSOR m_hCurZoom;
HCURSOR m_hCurPen;
HCURSOR m_hCurAirbrush;
LRESULT OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnSize(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);
LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnRButtonUp(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 OnMouseLeave(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnImageModelDimensionsChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
LRESULT OnImageModelImageChanged(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 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);
};

View file

@ -151,14 +151,14 @@ struct FreeSelTool : ToolBase
selectionModel.ResetPtStack(); selectionModel.ResetPtStack();
selectionModel.m_bShow = FALSE; selectionModel.m_bShow = FALSE;
} }
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
} }
} }
void OnFinishDraw() void OnFinishDraw()
{ {
if (m_bLeftButton) if (m_bLeftButton)
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
m_bLeftButton = FALSE; m_bLeftButton = FALSE;
ToolBase::OnFinishDraw(); ToolBase::OnFinishDraw();
@ -214,14 +214,14 @@ struct RectSelTool : ToolBase
if (start.x == x && start.y == y) if (start.x == x && start.y == y)
imageModel.Undo(TRUE); imageModel.Undo(TRUE);
selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty(); selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty();
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
} }
} }
void OnFinishDraw() void OnFinishDraw()
{ {
if (m_bLeftButton) if (m_bLeftButton)
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
m_bLeftButton = FALSE; m_bLeftButton = FALSE;
ToolBase::OnFinishDraw(); ToolBase::OnFinishDraw();
@ -417,7 +417,7 @@ struct TextTool : ToolBase
void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
{ {
if (!textEditWindow.IsWindow()) if (!textEditWindow.IsWindow())
textEditWindow.Create(imageArea); textEditWindow.Create(canvasWindow);
imageModel.CopyPrevious(); imageModel.CopyPrevious();
UpdatePoint(x, y); UpdatePoint(x, y);
@ -484,7 +484,7 @@ struct TextTool : ToolBase
} }
if (!textEditWindow.IsWindow()) if (!textEditWindow.IsWindow())
textEditWindow.Create(imageArea); textEditWindow.Create(canvasWindow);
textEditWindow.SetWindowText(NULL); textEditWindow.SetWindowText(NULL);
textEditWindow.ValidateEditRect(&rc); textEditWindow.ValidateEditRect(&rc);

View file

@ -97,8 +97,8 @@ void PaletteModel::NotifyColorChanged()
{ {
if (paletteWindow.IsWindow()) if (paletteWindow.IsWindow())
paletteWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED); paletteWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED);
if (imageArea.IsWindow()) if (canvasWindow.IsWindow())
imageArea.SendMessage(WM_PALETTEMODELCOLORCHANGED); canvasWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED);
if (textEditWindow.IsWindow()) if (textEditWindow.IsWindow())
textEditWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED); textEditWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED);
} }

View file

@ -38,7 +38,6 @@
#include "dib.h" #include "dib.h"
#include "fullscreen.h" #include "fullscreen.h"
#include "history.h" #include "history.h"
#include "imgarea.h"
#include "miniature.h" #include "miniature.h"
#include "palette.h" #include "palette.h"
#include "palettemodel.h" #include "palettemodel.h"

View file

@ -179,7 +179,7 @@ BOOL SelectionModel::TakeOff()
DrawBackgroundRect(hDCImage, paletteModel.GetBgColor()); DrawBackgroundRect(hDCImage, paletteModel.GetBgColor());
} }
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
return TRUE; return TRUE;
} }
@ -417,7 +417,7 @@ void SelectionModel::Dragging(CANVAS_HITTEST hit, POINT pt)
void SelectionModel::NotifyRefreshNeeded() void SelectionModel::NotifyRefreshNeeded()
{ {
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
} }
void SelectionModel::ClearMask() void SelectionModel::ClearMask()
@ -448,5 +448,5 @@ void SelectionModel::CancelSelection()
imageModel.Undo(TRUE); imageModel.Undo(TRUE);
m_bShow = FALSE; m_bShow = FALSE;
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
} }

View file

@ -293,11 +293,8 @@ void CTextEditWindow::InvalidateEditRect()
::InvalidateRect(m_hwndParent, &rc, TRUE); ::InvalidateRect(m_hwndParent, &rc, TRUE);
GetClientRect(&rc); GetClientRect(&rc);
MapWindowPoints(imageArea, (LPPOINT)&rc, 2); MapWindowPoints(canvasWindow, (LPPOINT)&rc, 2);
rc.left = UnZoomed(rc.left); canvasWindow.CanvasToImage(rc);
rc.top = UnZoomed(rc.top);
rc.right = UnZoomed(rc.right);
rc.bottom = UnZoomed(rc.bottom);
m_rc = rc; m_rc = rc;
} }
@ -394,27 +391,30 @@ void CTextEditWindow::ValidateEditRect(LPCRECT prc OPTIONAL)
{ {
if (prc) if (prc)
m_rc = *prc; m_rc = *prc;
INT x0 = Zoomed(m_rc.left), y0 = Zoomed(m_rc.top);
INT x1 = Zoomed(m_rc.right), y1 = Zoomed(m_rc.bottom); CRect rc = m_rc;
canvasWindow.ImageToCanvas(rc);
++m_nAppIsMovingOrSizing; ++m_nAppIsMovingOrSizing;
MoveWindow(x0, y0, x1 - x0, y1 - y0, TRUE); MoveWindow(rc.left, rc.top, rc.Width(), rc.Height(), TRUE);
--m_nAppIsMovingOrSizing; --m_nAppIsMovingOrSizing;
} }
void CTextEditWindow::Reposition() void CTextEditWindow::Reposition()
{ {
RECT rc, rcImage; CRect rc;
GetWindowRect(&rc); GetWindowRect(&rc);
::MapWindowPoints(NULL, canvasWindow, (LPPOINT)&rc, 2);
canvasWindow.CanvasToImage(rc);
::MapWindowPoints(NULL, imageArea, (LPPOINT)&rc, 2); CRect rcImage;
imageArea.GetClientRect(&rcImage); canvasWindow.GetImageRect(rcImage);
if (rc.bottom > rcImage.bottom) if (rc.bottom > rcImage.bottom)
::OffsetRect(&rc, 0, rcImage.bottom - rc.bottom); ::OffsetRect(&rc, 0, rcImage.Height());
if (rc.right > rcImage.right) if (rc.right > rcImage.right)
::OffsetRect(&rc, rcImage.right - rc.right, 0); ::OffsetRect(&rc, rcImage.Width(), 0);
if (rc.left < 0) if (rc.left < 0)
::OffsetRect(&rc, -rc.left, 0); ::OffsetRect(&rc, -rc.left, 0);
@ -422,8 +422,10 @@ void CTextEditWindow::Reposition()
if (rc.top < 0) if (rc.top < 0)
::OffsetRect(&rc, 0, -rc.top); ::OffsetRect(&rc, 0, -rc.top);
canvasWindow.ImageToCanvas(rc);
++m_nAppIsMovingOrSizing; ++m_nAppIsMovingOrSizing;
MoveWindow(rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, TRUE); MoveWindow(rc.left, rc.top, rc.Width(), rc.Height(), TRUE);
--m_nAppIsMovingOrSizing; --m_nAppIsMovingOrSizing;
} }

View file

@ -141,8 +141,8 @@ void ToolsModel::SetBackgroundTransparent(BOOL bTransparent)
{ {
m_transpBg = bTransparent; m_transpBg = bTransparent;
NotifyToolSettingsChanged(); NotifyToolSettingsChanged();
if (imageArea.IsWindow()) if (canvasWindow.IsWindow())
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
} }
int ToolsModel::GetZoom() const int ToolsModel::GetZoom() const
@ -182,8 +182,8 @@ void ToolsModel::NotifyZoomChanged()
toolSettingsWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED); toolSettingsWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
if (textEditWindow.IsWindow()) if (textEditWindow.IsWindow())
textEditWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED); textEditWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
if (imageArea.IsWindow()) if (canvasWindow.IsWindow())
imageArea.SendMessage(WM_TOOLSMODELZOOMCHANGED); canvasWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
} }
void ToolsModel::OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick) void ToolsModel::OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)

View file

@ -45,11 +45,14 @@ static HWND DoHtmlHelpW(HWND hwndCaller, LPCWSTR pszFile, UINT uCommand, DWORD_P
BOOL BOOL
zoomTo(int newZoom, int mouseX, int mouseY) zoomTo(int newZoom, int mouseX, int mouseY)
{ {
RECT clientRectScrollbox;
RECT clientRectImageArea;
int x, y, w, h; int x, y, w, h;
RECT clientRectScrollbox;
canvasWindow.GetClientRect(&clientRectScrollbox); canvasWindow.GetClientRect(&clientRectScrollbox);
imageArea.GetClientRect(&clientRectImageArea);
RECT clientRectImageArea;
::SetRect(&clientRectImageArea, 0, 0, imageModel.GetWidth(), imageModel.GetHeight());
Zoomed(clientRectImageArea);
w = clientRectImageArea.right * newZoom / toolsModel.GetZoom(); w = clientRectImageArea.right * newZoom / toolsModel.GetZoom();
h = clientRectImageArea.bottom * newZoom / toolsModel.GetZoom(); h = clientRectImageArea.bottom * newZoom / toolsModel.GetZoom();
if (!w || !h) if (!w || !h)
@ -63,9 +66,7 @@ zoomTo(int newZoom, int mouseX, int mouseY)
toolsModel.SetZoom(newZoom); toolsModel.SetZoom(newZoom);
imageArea.MoveWindow(GRIP_SIZE, GRIP_SIZE, Zoomed(imageModel.GetWidth()), Zoomed(imageModel.GetHeight()), FALSE);
canvasWindow.Invalidate(TRUE); canvasWindow.Invalidate(TRUE);
imageArea.Invalidate(FALSE);
canvasWindow.SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, x), 0); canvasWindow.SendMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, x), 0);
canvasWindow.SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, y), 0); canvasWindow.SendMessage(WM_VSCROLL, MAKEWPARAM(SB_THUMBPOSITION, y), 0);
@ -139,7 +140,7 @@ void CMainWindow::alignChildrenToMainWindow()
void CMainWindow::saveImage(BOOL overwrite) void CMainWindow::saveImage(BOOL overwrite)
{ {
imageArea.finishDrawing(); canvasWindow.finishDrawing();
if (isAFile && overwrite) if (isAFile && overwrite)
{ {
@ -206,7 +207,7 @@ void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND window)
imageModel.CopyPrevious(); imageModel.CopyPrevious();
selectionModel.InsertFromHBITMAP(bitmap, 0, 0); selectionModel.InsertFromHBITMAP(bitmap, 0, 0);
selectionModel.m_bShow = TRUE; selectionModel.m_bShow = TRUE;
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
} }
LRESULT CMainWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) LRESULT CMainWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
@ -296,9 +297,6 @@ LRESULT CMainWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHa
style = WS_CHILD | WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE; style = WS_CHILD | WS_GROUP | WS_HSCROLL | WS_VSCROLL | WS_VISIBLE;
canvasWindow.Create(m_hWnd, rcEmpty, NULL, style, WS_EX_CLIENTEDGE); canvasWindow.Create(m_hWnd, rcEmpty, NULL, style, WS_EX_CLIENTEDGE);
// Creating the window inside the canvas
imageArea.Create(canvasWindow, rcEmpty, NULL, WS_CHILD | WS_VISIBLE);
// Create and show the miniature if necessary // Create and show the miniature if necessary
if (registrySettings.ShowThumbnail) if (registrySettings.ShowThumbnail)
{ {
@ -340,7 +338,7 @@ LRESULT CMainWindow::OnDestroy(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
BOOL CMainWindow::ConfirmSave() BOOL CMainWindow::ConfirmSave()
{ {
imageArea.finishDrawing(); canvasWindow.finishDrawing();
if (imageModel.IsImageSaved()) if (imageModel.IsImageSaved())
return TRUE; return TRUE;
@ -501,16 +499,11 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
if (hwndCapture) if (hwndCapture)
{ {
if (canvasWindow.m_hWnd == hwndCapture || if (canvasWindow.m_hWnd == hwndCapture ||
imageArea.m_hWnd == hwndCapture ||
fullscreenWindow.m_hWnd == hwndCapture) fullscreenWindow.m_hWnd == hwndCapture)
{ {
SendMessage(hwndCapture, nMsg, wParam, lParam); SendMessage(hwndCapture, nMsg, wParam, lParam);
} }
} }
else
{
imageArea.SendMessage(nMsg, wParam, lParam);
}
} }
return 0; return 0;
} }
@ -526,7 +519,7 @@ LRESULT CMainWindow::OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam, B
LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled) LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{ {
// Disable commands while dragging mouse // Disable commands while dragging mouse
if (imageArea.drawing && ::GetCapture()) if (canvasWindow.m_drawing && ::GetCapture())
{ {
ATLTRACE("locking!\n"); ATLTRACE("locking!\n");
return 0; return 0;
@ -631,28 +624,28 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
if (toolsModel.GetActiveTool() == TOOL_RECTSEL || if (toolsModel.GetActiveTool() == TOOL_RECTSEL ||
toolsModel.GetActiveTool() == TOOL_FREESEL) toolsModel.GetActiveTool() == TOOL_FREESEL)
{ {
imageArea.cancelDrawing(); canvasWindow.cancelDrawing();
break; break;
} }
} }
if (ToolBase::pointSP != 0) // drawing something? if (ToolBase::pointSP != 0) // drawing something?
{ {
imageArea.cancelDrawing(); canvasWindow.cancelDrawing();
break; break;
} }
imageModel.Undo(); imageModel.Undo();
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
break; break;
case IDM_EDITREDO: case IDM_EDITREDO:
if (toolsModel.GetActiveTool() == TOOL_TEXT && ::IsWindowVisible(textEditWindow)) if (toolsModel.GetActiveTool() == TOOL_TEXT && ::IsWindowVisible(textEditWindow))
break; break;
if (ToolBase::pointSP != 0) // drawing something? if (ToolBase::pointSP != 0) // drawing something?
{ {
imageArea.finishDrawing(); canvasWindow.finishDrawing();
break; break;
} }
imageModel.Redo(); imageModel.Redo();
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
break; break;
case IDM_EDITCOPY: case IDM_EDITCOPY:
OpenClipboard(); OpenClipboard();
@ -684,7 +677,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
break; break;
case TOOL_TEXT: case TOOL_TEXT:
imageArea.cancelDrawing(); canvasWindow.cancelDrawing();
break; break;
default: default:
break; break;
@ -701,7 +694,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
HWND hToolbar = FindWindowEx(toolBoxContainer.m_hWnd, NULL, TOOLBARCLASSNAME, NULL); HWND hToolbar = FindWindowEx(toolBoxContainer.m_hWnd, NULL, TOOLBARCLASSNAME, NULL);
SendMessage(hToolbar, TB_CHECKBUTTON, ID_RECTSEL, MAKELPARAM(TRUE, 0)); SendMessage(hToolbar, TB_CHECKBUTTON, ID_RECTSEL, MAKELPARAM(TRUE, 0));
toolsModel.selectAll(); toolsModel.selectAll();
imageArea.Invalidate(TRUE); canvasWindow.Invalidate(TRUE);
break; break;
} }
case IDM_EDITCOPYTO: case IDM_EDITCOPYTO:
@ -746,7 +739,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
case IDM_IMAGEDELETEIMAGE: case IDM_IMAGEDELETEIMAGE:
imageModel.CopyPrevious(); imageModel.CopyPrevious();
Rect(imageModel.GetDC(), 0, 0, imageModel.GetWidth(), imageModel.GetHeight(), paletteModel.GetBgColor(), paletteModel.GetBgColor(), 0, TRUE); Rect(imageModel.GetDC(), 0, 0, imageModel.GetWidth(), imageModel.GetHeight(), paletteModel.GetBgColor(), paletteModel.GetBgColor(), 0, TRUE);
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
break; break;
case IDM_IMAGEROTATEMIRROR: case IDM_IMAGEROTATEMIRROR:
switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd)) switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd))
@ -844,7 +837,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
break; break;
case IDM_VIEWSHOWGRID: case IDM_VIEWSHOWGRID:
showGrid = !showGrid; showGrid = !showGrid;
imageArea.Invalidate(FALSE); canvasWindow.Invalidate(FALSE);
break; break;
case IDM_VIEWSHOWMINIATURE: case IDM_VIEWSHOWMINIATURE:
registrySettings.ShowThumbnail = !::IsWindowVisible(miniature); registrySettings.ShowThumbnail = !::IsWindowVisible(miniature);