mirror of
https://github.com/reactos/reactos.git
synced 2025-04-26 16:40:27 +00:00
[MSPAINT] Make selection window-less (#5208)
- Delete selection.cpp and selection.h and selectionWindow. - Extend ColorKeyedMaskBlt function. - Implement selection resizing. CORE-18867
This commit is contained in:
parent
3f5bcf5775
commit
aac89519ec
23 changed files with 702 additions and 829 deletions
|
@ -20,7 +20,6 @@ list(APPEND SOURCE
|
|||
palette.cpp
|
||||
palettemodel.cpp
|
||||
registry.cpp
|
||||
selection.cpp
|
||||
selectionmodel.cpp
|
||||
sizebox.cpp
|
||||
textedit.cpp
|
||||
|
|
|
@ -150,14 +150,25 @@ LRESULT CCanvasWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BO
|
|||
|
||||
if (hit == HIT_NONE || hit == HIT_BORDER)
|
||||
{
|
||||
if (toolsModel.GetActiveTool() == TOOL_BEZIER ||
|
||||
toolsModel.GetActiveTool() == TOOL_SHAPE)
|
||||
switch (toolsModel.GetActiveTool())
|
||||
{
|
||||
if (ToolBase::pointSP != 0)
|
||||
{
|
||||
toolsModel.OnCancelDraw();
|
||||
case TOOL_BEZIER:
|
||||
case TOOL_SHAPE:
|
||||
if (ToolBase::pointSP != 0)
|
||||
{
|
||||
toolsModel.OnCancelDraw();
|
||||
imageArea.Invalidate();
|
||||
}
|
||||
break;
|
||||
|
||||
case TOOL_FREESEL:
|
||||
case TOOL_RECTSEL:
|
||||
toolsModel.OnFinishDraw();
|
||||
imageArea.Invalidate();
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions
|
||||
|
|
|
@ -56,6 +56,5 @@ enum CANVAS_HITTEST // hit
|
|||
|
||||
BOOL zoomTo(int newZoom, int mouseX, int mouseY);
|
||||
BOOL nearlyEqualPoints(INT x0, INT y0, INT x1, INT y1);
|
||||
void placeSelWin(void);
|
||||
void updateStartAndLast(LONG x, LONG y);
|
||||
void updateLast(LONG x, LONG y);
|
||||
|
|
|
@ -220,9 +220,13 @@ HBITMAP DoLoadImageFile(HWND hwnd, LPCTSTR name, BOOL fIsMainFile)
|
|||
return hBitmap;
|
||||
}
|
||||
|
||||
HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight)
|
||||
HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono)
|
||||
{
|
||||
HBITMAP hbm2 = CreateDIBWithProperties(cy, cx);
|
||||
HBITMAP hbm2;
|
||||
if (bMono)
|
||||
hbm2 = ::CreateBitmap(cy, cx, 1, 1, NULL);
|
||||
else
|
||||
hbm2 = CreateDIBWithProperties(cy, cx);
|
||||
if (!hbm2)
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@ void ShowFileLoadError(LPCTSTR name);
|
|||
|
||||
HBITMAP SetBitmapAndInfo(HBITMAP hBitmap, LPCTSTR name, DWORD dwFileSize, BOOL isFile);
|
||||
|
||||
HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight);
|
||||
HBITMAP Rotate90DegreeBlt(HDC hDC1, INT cx, INT cy, BOOL bRight, BOOL bMono);
|
||||
|
||||
HBITMAP SkewDIB(HDC hDC1, HBITMAP hbm, INT nDegree, BOOL bVertical);
|
||||
|
||||
|
|
|
@ -290,33 +290,76 @@ Text(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LPCT
|
|||
|
||||
BOOL
|
||||
ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
|
||||
HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask,
|
||||
DWORD dwRop, COLORREF keyColor)
|
||||
HDC hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight,
|
||||
HBITMAP hbmMask, COLORREF keyColor)
|
||||
{
|
||||
HDC hTempDC;
|
||||
HDC hTempDC2;
|
||||
HBITMAP hTempBm;
|
||||
HBRUSH hTempBrush;
|
||||
HBITMAP hTempMask;
|
||||
HDC hTempDC1, hTempDC2;
|
||||
HBITMAP hbmTempColor, hbmTempMask;
|
||||
HGDIOBJ hbmOld1, hbmOld2;
|
||||
|
||||
if (hbmMask == NULL)
|
||||
{
|
||||
if (keyColor == CLR_INVALID)
|
||||
{
|
||||
::StretchBlt(hdcDest, nXDest, nYDest, nWidth, nHeight,
|
||||
hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, SRCCOPY);
|
||||
}
|
||||
else
|
||||
{
|
||||
::GdiTransparentBlt(hdcDest, nXDest, nYDest, nWidth, nHeight,
|
||||
hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, keyColor);
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
else if (nWidth == nSrcWidth && nHeight == nSrcHeight && keyColor == CLR_INVALID)
|
||||
{
|
||||
::MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight,
|
||||
hdcSrc, nXSrc, nYSrc, hbmMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0029));
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
hTempDC1 = ::CreateCompatibleDC(hdcDest);
|
||||
hTempDC2 = ::CreateCompatibleDC(hdcDest);
|
||||
hbmTempMask = ::CreateBitmap(nWidth, nHeight, 1, 1, NULL);
|
||||
hbmTempColor = CreateColorDIB(nWidth, nHeight, RGB(255, 255, 255));
|
||||
|
||||
// hbmTempMask <-- hbmMask (stretched)
|
||||
hbmOld1 = ::SelectObject(hTempDC1, hbmMask);
|
||||
hbmOld2 = ::SelectObject(hTempDC2, hbmTempMask);
|
||||
::StretchBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC1, 0, 0, nSrcWidth, nSrcHeight, SRCCOPY);
|
||||
::SelectObject(hTempDC2, hbmOld2);
|
||||
::SelectObject(hTempDC1, hbmOld1);
|
||||
|
||||
hbmOld1 = ::SelectObject(hTempDC1, hbmTempColor);
|
||||
if (keyColor == CLR_INVALID)
|
||||
{
|
||||
// hbmTempColor <-- hdcSrc (stretched)
|
||||
::StretchBlt(hTempDC1, 0, 0, nWidth, nHeight,
|
||||
hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, SRCCOPY);
|
||||
|
||||
// hdcDest <-- hbmTempColor (masked)
|
||||
::MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hTempDC1, 0, 0,
|
||||
hbmTempMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0029));
|
||||
}
|
||||
else
|
||||
{
|
||||
// hbmTempColor <-- hdcDest
|
||||
::BitBlt(hTempDC1, 0, 0, nWidth, nHeight, hdcDest, nXDest, nYDest, SRCCOPY);
|
||||
|
||||
// hbmTempColor <-- hdcSrc (color key)
|
||||
::GdiTransparentBlt(hTempDC1, 0, 0, nWidth, nHeight,
|
||||
hdcSrc, nXSrc, nYSrc, nSrcWidth, nSrcHeight, keyColor);
|
||||
|
||||
// hdcDest <-- hbmTempColor (masked)
|
||||
::MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hTempDC1, 0, 0,
|
||||
hbmTempMask, 0, 0, MAKEROP4(SRCCOPY, 0xAA0029));
|
||||
}
|
||||
::SelectObject(hTempDC1, hbmOld1);
|
||||
|
||||
::DeleteObject(hbmTempColor);
|
||||
::DeleteObject(hbmTempMask);
|
||||
::DeleteDC(hTempDC2);
|
||||
::DeleteDC(hTempDC1);
|
||||
|
||||
hTempDC = CreateCompatibleDC(hdcSrc);
|
||||
hTempDC2 = CreateCompatibleDC(hdcSrc);
|
||||
hTempBm = CreateCompatibleBitmap(hTempDC, nWidth, nHeight);
|
||||
SelectObject(hTempDC, hTempBm);
|
||||
hTempBrush = CreateSolidBrush(keyColor);
|
||||
SelectObject(hTempDC, hTempBrush);
|
||||
BitBlt(hTempDC, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY);
|
||||
PatBlt(hTempDC, 0, 0, nWidth, nHeight, PATINVERT);
|
||||
hTempMask = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
|
||||
SelectObject(hTempDC2, hTempMask);
|
||||
BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, 0, 0, SRCCOPY);
|
||||
SelectObject(hTempDC, hbmMask);
|
||||
BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, xMask, yMask, SRCAND);
|
||||
MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, hTempMask, xMask, yMask, dwRop);
|
||||
DeleteDC(hTempDC);
|
||||
DeleteDC(hTempDC2);
|
||||
DeleteObject(hTempBm);
|
||||
DeleteObject(hTempBrush);
|
||||
DeleteObject(hTempMask);
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ void RectSel(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2);
|
|||
|
||||
void Text(HDC hdc, LONG x1, LONG y1, LONG x2, LONG y2, COLORREF fg, COLORREF bg, LPCTSTR lpchText, HFONT font, LONG style);
|
||||
|
||||
extern BOOL
|
||||
BOOL
|
||||
ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight,
|
||||
HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask,
|
||||
DWORD dwRop, COLORREF keyColor);
|
||||
HDC hdcSrc, int nXSrc, int nYSrc, int nSrcWidth, int nSrcHeight,
|
||||
HBITMAP hbmMask, COLORREF keyColor);
|
||||
|
|
|
@ -52,6 +52,5 @@ extern CToolBox toolBoxContainer;
|
|||
extern CToolSettingsWindow toolSettingsWindow;
|
||||
extern CPaletteWindow paletteWindow;
|
||||
extern CCanvasWindow canvasWindow;
|
||||
extern CSelectionWindow selectionWindow;
|
||||
extern CImgAreaWindow imageArea;
|
||||
extern CTextEditWindow textEditWindow;
|
||||
|
|
|
@ -64,7 +64,7 @@ void ImageModel::Undo(BOOL bClearRedo)
|
|||
{
|
||||
int oldWidth = GetWidth();
|
||||
int oldHeight = GetHeight();
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
selectionModel.m_bShow = FALSE;
|
||||
currInd = (currInd + HISTORYSIZE - 1) % HISTORYSIZE;
|
||||
SelectObject(hDrawingDC, hBms[currInd]);
|
||||
undoSteps--;
|
||||
|
@ -85,7 +85,7 @@ void ImageModel::Redo()
|
|||
{
|
||||
int oldWidth = GetWidth();
|
||||
int oldHeight = GetHeight();
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
selectionModel.m_bShow = FALSE;
|
||||
currInd = (currInd + 1) % HISTORYSIZE;
|
||||
SelectObject(hDrawingDC, hBms[currInd]);
|
||||
redoSteps--;
|
||||
|
@ -264,7 +264,7 @@ void ImageModel::RotateNTimes90Degrees(int iN)
|
|||
case 1:
|
||||
case 3:
|
||||
DeleteObject(hBms[(currInd + 1) % HISTORYSIZE]);
|
||||
hBms[(currInd + 1) % HISTORYSIZE] = Rotate90DegreeBlt(hDrawingDC, GetWidth(), GetHeight(), iN == 1);
|
||||
hBms[(currInd + 1) % HISTORYSIZE] = Rotate90DegreeBlt(hDrawingDC, GetWidth(), GetHeight(), iN == 1, FALSE);
|
||||
currInd = (currInd + 1) % HISTORYSIZE;
|
||||
if (undoSteps < HISTORYSIZE - 1)
|
||||
undoSteps++;
|
||||
|
@ -282,23 +282,15 @@ void ImageModel::RotateNTimes90Degrees(int iN)
|
|||
NotifyImageChanged();
|
||||
}
|
||||
|
||||
void ImageModel::DrawSelectionBackground(COLORREF rgbBG)
|
||||
{
|
||||
if (toolsModel.GetActiveTool() == TOOL_FREESEL)
|
||||
selectionModel.DrawBackgroundPoly(hDrawingDC, rgbBG);
|
||||
else
|
||||
selectionModel.DrawBackgroundRect(hDrawingDC, rgbBG);
|
||||
}
|
||||
|
||||
void ImageModel::DeleteSelection()
|
||||
{
|
||||
if (selectionWindow.IsWindowVisible())
|
||||
ResetToPrevious();
|
||||
CopyPrevious();
|
||||
if (selectionWindow.IsWindowVisible())
|
||||
Undo(TRUE);
|
||||
DrawSelectionBackground(paletteModel.GetBgColor());
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
if (!selectionModel.m_bShow)
|
||||
return;
|
||||
|
||||
selectionModel.TakeOff();
|
||||
selectionModel.m_bShow = FALSE;
|
||||
selectionModel.ClearColor();
|
||||
selectionModel.ClearMask();
|
||||
NotifyImageChanged();
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,6 @@ public:
|
|||
void FlipHorizontally();
|
||||
void FlipVertically();
|
||||
void RotateNTimes90Degrees(int iN);
|
||||
void DrawSelectionBackground(COLORREF rgbBG);
|
||||
void DeleteSelection();
|
||||
void Bound(POINT& pt);
|
||||
};
|
||||
|
|
|
@ -21,7 +21,6 @@ LRESULT CImgAreaWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
|
|||
m_hCurZoom = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_ZOOM));
|
||||
m_hCurPen = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_PEN));
|
||||
m_hCurAirbrush = LoadIcon(hProgInstance, MAKEINTRESOURCE(IDC_AIRBRUSH));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -71,49 +70,61 @@ LRESULT CImgAreaWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
|
||||
LRESULT CImgAreaWindow::OnEraseBkGnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
HDC hdc = (HDC)wParam;
|
||||
|
||||
if (toolsModel.GetActiveTool() == TOOL_TEXT && !toolsModel.IsBackgroundTransparent() &&
|
||||
::IsWindowVisible(textEditWindow))
|
||||
{
|
||||
// Do clipping
|
||||
HWND hChild = textEditWindow;
|
||||
RECT rcChild;
|
||||
::GetWindowRect(hChild, &rcChild);
|
||||
::MapWindowPoints(NULL, m_hWnd, (LPPOINT)&rcChild, 2);
|
||||
ExcludeClipRect(hdc, rcChild.left, rcChild.top, rcChild.right, rcChild.bottom);
|
||||
}
|
||||
|
||||
return DefWindowProc(nMsg, wParam, lParam);
|
||||
return TRUE; // Don't fill background
|
||||
}
|
||||
|
||||
LRESULT CImgAreaWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
RECT rcClient;
|
||||
GetClientRect(&rcClient);
|
||||
|
||||
PAINTSTRUCT ps;
|
||||
HDC hdc = BeginPaint(&ps);
|
||||
int imgXRes = imageModel.GetWidth();
|
||||
int imgYRes = imageModel.GetHeight();
|
||||
StretchBlt(hdc, 0, 0, Zoomed(imgXRes), Zoomed(imgYRes), imageModel.GetDC(), 0, 0, imgXRes,
|
||||
imgYRes, SRCCOPY);
|
||||
|
||||
// We use a memory bitmap to reduce flickering
|
||||
HDC hdcMem = ::CreateCompatibleDC(hdc);
|
||||
HBITMAP hbm = ::CreateCompatibleBitmap(hdc, rcClient.right, rcClient.bottom);
|
||||
HGDIOBJ hbmOld = ::SelectObject(hdcMem, hbm);
|
||||
|
||||
// Draw the image
|
||||
SIZE size = { imageModel.GetWidth(), imageModel.GetHeight() };
|
||||
StretchBlt(hdcMem, 0, 0, ::Zoomed(size.cx), ::Zoomed(size.cy),
|
||||
imageModel.GetDC(), 0, 0, size.cx, size.cy, SRCCOPY);
|
||||
|
||||
// Draw the grid
|
||||
if (showGrid && (toolsModel.GetZoom() >= 4000))
|
||||
{
|
||||
HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 1, 0x00a0a0a0));
|
||||
int counter;
|
||||
for(counter = 0; counter <= imgYRes; counter++)
|
||||
HPEN oldPen = (HPEN) SelectObject(hdcMem, CreatePen(PS_SOLID, 1, 0x00a0a0a0));
|
||||
for (int counter = 0; counter <= size.cy; counter++)
|
||||
{
|
||||
MoveToEx(hdc, 0, Zoomed(counter), NULL);
|
||||
LineTo(hdc, Zoomed(imgXRes), Zoomed(counter));
|
||||
::MoveToEx(hdcMem, 0, ::Zoomed(counter), NULL);
|
||||
::LineTo(hdcMem, ::Zoomed(size.cx), ::Zoomed(counter));
|
||||
}
|
||||
for(counter = 0; counter <= imgXRes; counter++)
|
||||
for (int counter = 0; counter <= size.cx; counter++)
|
||||
{
|
||||
MoveToEx(hdc, Zoomed(counter), 0, NULL);
|
||||
LineTo(hdc, Zoomed(counter), Zoomed(imgYRes));
|
||||
::MoveToEx(hdcMem, ::Zoomed(counter), 0, NULL);
|
||||
::LineTo(hdcMem, ::Zoomed(counter), ::Zoomed(size.cy));
|
||||
}
|
||||
DeleteObject(SelectObject(hdc, oldPen));
|
||||
::DeleteObject(::SelectObject(hdcMem, oldPen));
|
||||
}
|
||||
|
||||
// Draw selection
|
||||
if (selectionModel.m_bShow)
|
||||
{
|
||||
RECT rc = selectionModel.m_rc;
|
||||
Zoomed(rc);
|
||||
::InflateRect(&rc, GRIP_SIZE, GRIP_SIZE);
|
||||
drawSizeBoxes(hdcMem, &rc, TRUE, &ps.rcPaint);
|
||||
::InflateRect(&rc, -GRIP_SIZE, -GRIP_SIZE);
|
||||
selectionModel.DrawSelection(hdcMem, &rc, paletteModel.GetBgColor(),
|
||||
toolsModel.IsBackgroundTransparent());
|
||||
}
|
||||
|
||||
// Transfer bits
|
||||
::BitBlt(hdc, 0, 0, rcClient.right, rcClient.bottom, hdcMem, 0, 0, SRCCOPY);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
EndPaint(&ps);
|
||||
if (selectionWindow.IsWindow())
|
||||
selectionWindow.Invalidate(FALSE);
|
||||
|
||||
if (miniature.IsWindow())
|
||||
miniature.Invalidate(FALSE);
|
||||
if (textEditWindow.IsWindow())
|
||||
|
@ -121,8 +132,57 @@ LRESULT CImgAreaWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& b
|
|||
return 0;
|
||||
}
|
||||
|
||||
CANVAS_HITTEST CImgAreaWindow::SelectionHitTest(POINT ptZoomed)
|
||||
{
|
||||
if (!selectionModel.m_bShow)
|
||||
return HIT_NONE;
|
||||
|
||||
RECT rcSelection = selectionModel.m_rc;
|
||||
Zoomed(rcSelection);
|
||||
::InflateRect(&rcSelection, GRIP_SIZE, GRIP_SIZE);
|
||||
|
||||
return getSizeBoxHitTest(ptZoomed, &rcSelection);
|
||||
}
|
||||
|
||||
void CImgAreaWindow::StartSelectionDrag(CANVAS_HITTEST hit, POINT ptUnZoomed)
|
||||
{
|
||||
m_hitSelection = hit;
|
||||
selectionModel.m_ptHit = ptUnZoomed;
|
||||
selectionModel.TakeOff();
|
||||
|
||||
SetCapture();
|
||||
Invalidate(FALSE);
|
||||
}
|
||||
|
||||
void CImgAreaWindow::SelectionDragging(POINT ptUnZoomed)
|
||||
{
|
||||
selectionModel.Dragging(m_hitSelection, ptUnZoomed);
|
||||
Invalidate(FALSE);
|
||||
}
|
||||
|
||||
void CImgAreaWindow::EndSelectionDrag(POINT ptUnZoomed)
|
||||
{
|
||||
selectionModel.Dragging(m_hitSelection, ptUnZoomed);
|
||||
m_hitSelection = HIT_NONE;
|
||||
Invalidate(FALSE);
|
||||
}
|
||||
|
||||
LRESULT CImgAreaWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
POINT pt;
|
||||
::GetCursorPos(&pt);
|
||||
ScreenToClient(&pt);
|
||||
|
||||
CANVAS_HITTEST hit = SelectionHitTest(pt);
|
||||
if (hit != HIT_NONE)
|
||||
{
|
||||
if (!setCursorOnSizeBox(hit))
|
||||
::SetCursor(::LoadCursor(NULL, IDC_SIZEALL));
|
||||
return 0;
|
||||
}
|
||||
|
||||
UnZoomed(pt);
|
||||
|
||||
switch (toolsModel.GetActiveTool())
|
||||
{
|
||||
case TOOL_FILL:
|
||||
|
@ -148,20 +208,31 @@ LRESULT CImgAreaWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
|
|||
|
||||
LRESULT CImgAreaWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
|
||||
CANVAS_HITTEST hit = SelectionHitTest(pt);
|
||||
if (hit != HIT_NONE)
|
||||
{
|
||||
UnZoomed(pt);
|
||||
StartSelectionDrag(hit, pt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
UnZoomed(pt);
|
||||
drawing = TRUE;
|
||||
SetCapture();
|
||||
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
|
||||
toolsModel.OnButtonDown(TRUE, UnZoomed(x), UnZoomed(y), FALSE);
|
||||
toolsModel.OnButtonDown(TRUE, pt.x, pt.y, FALSE);
|
||||
Invalidate(FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CImgAreaWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
UnZoomed(pt);
|
||||
drawing = FALSE;
|
||||
ReleaseCapture();
|
||||
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
|
||||
toolsModel.OnButtonDown(TRUE, UnZoomed(x), UnZoomed(y), TRUE);
|
||||
toolsModel.OnButtonDown(TRUE, pt.x, pt.y, TRUE);
|
||||
toolsModel.resetTool();
|
||||
Invalidate(FALSE);
|
||||
return 0;
|
||||
|
@ -169,20 +240,22 @@ LRESULT CImgAreaWindow::OnLButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam,
|
|||
|
||||
LRESULT CImgAreaWindow::OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
UnZoomed(pt);
|
||||
drawing = TRUE;
|
||||
SetCapture();
|
||||
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
|
||||
toolsModel.OnButtonDown(FALSE, UnZoomed(x), UnZoomed(y), FALSE);
|
||||
toolsModel.OnButtonDown(FALSE, pt.x, pt.y, FALSE);
|
||||
Invalidate(FALSE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CImgAreaWindow::OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
UnZoomed(pt);
|
||||
drawing = FALSE;
|
||||
ReleaseCapture();
|
||||
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
|
||||
toolsModel.OnButtonDown(FALSE, UnZoomed(x), UnZoomed(y), TRUE);
|
||||
toolsModel.OnButtonDown(FALSE, pt.x, pt.y, TRUE);
|
||||
toolsModel.resetTool();
|
||||
Invalidate(FALSE);
|
||||
return 0;
|
||||
|
@ -190,20 +263,28 @@ LRESULT CImgAreaWindow::OnRButtonDblClk(UINT nMsg, WPARAM wParam, LPARAM lParam,
|
|||
|
||||
LRESULT CImgAreaWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
UnZoomed(pt);
|
||||
if (drawing)
|
||||
{
|
||||
drawing = FALSE;
|
||||
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
|
||||
toolsModel.OnButtonUp(TRUE, UnZoomed(x), UnZoomed(y));
|
||||
toolsModel.OnButtonUp(TRUE, pt.x, pt.y);
|
||||
Invalidate(FALSE);
|
||||
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
|
||||
}
|
||||
else if (m_hitSelection != HIT_NONE)
|
||||
{
|
||||
EndSelectionDrag(pt);
|
||||
}
|
||||
ReleaseCapture();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CImgAreaWindow::cancelDrawing()
|
||||
{
|
||||
selectionModel.ClearColor();
|
||||
selectionModel.ClearMask();
|
||||
m_hitSelection = HIT_NONE;
|
||||
drawing = FALSE;
|
||||
toolsModel.OnCancelDraw();
|
||||
Invalidate(FALSE);
|
||||
|
@ -226,7 +307,7 @@ LRESULT CImgAreaWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
|
|||
}
|
||||
else
|
||||
{
|
||||
if (drawing || ToolBase::pointSP != 0 || selectionWindow.IsWindowVisible())
|
||||
if (drawing || ToolBase::pointSP != 0 || selectionModel.m_bShow)
|
||||
cancelDrawing();
|
||||
}
|
||||
}
|
||||
|
@ -235,22 +316,34 @@ LRESULT CImgAreaWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL&
|
|||
|
||||
LRESULT CImgAreaWindow::OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
UnZoomed(pt);
|
||||
if (drawing)
|
||||
{
|
||||
drawing = FALSE;
|
||||
INT x = GET_X_LPARAM(lParam), y = GET_Y_LPARAM(lParam);
|
||||
toolsModel.OnButtonUp(FALSE, UnZoomed(x), UnZoomed(y));
|
||||
toolsModel.OnButtonUp(FALSE, pt.x, pt.y);
|
||||
Invalidate(FALSE);
|
||||
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
|
||||
}
|
||||
else if (m_hitSelection != HIT_NONE)
|
||||
{
|
||||
EndSelectionDrag(pt);
|
||||
}
|
||||
ReleaseCapture();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
LONG xNow = UnZoomed(GET_X_LPARAM(lParam));
|
||||
LONG yNow = UnZoomed(GET_Y_LPARAM(lParam));
|
||||
POINT pt = { GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam) };
|
||||
UnZoomed(pt);
|
||||
|
||||
if (m_hitSelection != HIT_NONE)
|
||||
{
|
||||
SelectionDragging(pt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((!drawing) || (toolsModel.GetActiveTool() <= TOOL_AIRBRUSH))
|
||||
{
|
||||
TRACKMOUSEEVENT tme;
|
||||
|
@ -271,26 +364,26 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
|
|||
if (!drawing)
|
||||
{
|
||||
CString strCoord;
|
||||
strCoord.Format(_T("%ld, %ld"), xNow, yNow);
|
||||
strCoord.Format(_T("%ld, %ld"), pt.x, pt.y);
|
||||
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord);
|
||||
}
|
||||
}
|
||||
if (drawing)
|
||||
{
|
||||
/* values displayed in statusbar */
|
||||
LONG xRel = xNow - start.x;
|
||||
LONG yRel = yNow - start.y;
|
||||
LONG xRel = pt.x - start.x;
|
||||
LONG yRel = pt.y - start.y;
|
||||
/* freesel, rectsel and text tools always show numbers limited to fit into image area */
|
||||
if ((toolsModel.GetActiveTool() == TOOL_FREESEL) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_TEXT))
|
||||
{
|
||||
if (xRel < 0)
|
||||
xRel = (xNow < 0) ? -start.x : xRel;
|
||||
else if (xNow > imageModel.GetWidth())
|
||||
xRel = (pt.x < 0) ? -start.x : xRel;
|
||||
else if (pt.x > imageModel.GetWidth())
|
||||
xRel = imageModel.GetWidth() - start.x;
|
||||
if (yRel < 0)
|
||||
yRel = (yNow < 0) ? -start.y : yRel;
|
||||
else if (yNow > imageModel.GetHeight())
|
||||
yRel = imageModel.GetHeight() - start.y;
|
||||
yRel = (pt.y < 0) ? -start.y : yRel;
|
||||
else if (pt.y > imageModel.GetHeight())
|
||||
yRel = imageModel.GetHeight() - start.y;
|
||||
}
|
||||
/* rectsel and shape tools always show non-negative numbers when drawing */
|
||||
if ((toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_SHAPE))
|
||||
|
@ -310,7 +403,7 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
|
|||
case TOOL_SHAPE:
|
||||
{
|
||||
CString strCoord;
|
||||
strCoord.Format(_T("%ld, %ld"), xNow, yNow);
|
||||
strCoord.Format(_T("%ld, %ld"), pt.x, pt.y);
|
||||
SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) (LPCTSTR) strCoord);
|
||||
break;
|
||||
}
|
||||
|
@ -319,7 +412,7 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
|
|||
}
|
||||
if (wParam & MK_LBUTTON)
|
||||
{
|
||||
toolsModel.OnMouseMove(TRUE, xNow, yNow);
|
||||
toolsModel.OnMouseMove(TRUE, pt.x, pt.y);
|
||||
Invalidate(FALSE);
|
||||
if ((toolsModel.GetActiveTool() >= TOOL_TEXT) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_FREESEL))
|
||||
{
|
||||
|
@ -332,7 +425,7 @@ LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOO
|
|||
}
|
||||
if (wParam & MK_RBUTTON)
|
||||
{
|
||||
toolsModel.OnMouseMove(FALSE, xNow, yNow);
|
||||
toolsModel.OnMouseMove(FALSE, pt.x, pt.y);
|
||||
Invalidate(FALSE);
|
||||
if (toolsModel.GetActiveTool() >= TOOL_TEXT)
|
||||
{
|
||||
|
|
|
@ -13,9 +13,15 @@
|
|||
class CImgAreaWindow : public CWindowImpl<CImgAreaWindow>
|
||||
{
|
||||
public:
|
||||
CImgAreaWindow() : drawing(FALSE) { }
|
||||
CImgAreaWindow()
|
||||
: drawing(FALSE)
|
||||
, m_hitSelection(HIT_NONE)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL drawing;
|
||||
CANVAS_HITTEST m_hitSelection;
|
||||
|
||||
void cancelDrawing();
|
||||
void finishDrawing();
|
||||
|
||||
|
@ -71,4 +77,8 @@ private:
|
|||
LRESULT OnCtlColorEdit(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
||||
void drawZoomFrame(int mouseX, int mouseY);
|
||||
CANVAS_HITTEST SelectionHitTest(POINT ptZoomed);
|
||||
void StartSelectionDrag(CANVAS_HITTEST hit, POINT ptUnZoomed);
|
||||
void SelectionDragging(POINT ptUnZoomed);
|
||||
void EndSelectionDrag(POINT ptUnZoomed);
|
||||
};
|
||||
|
|
|
@ -16,20 +16,6 @@ POINT ToolBase::pointStack[256] = { { 0 } };
|
|||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
void
|
||||
placeSelWin()
|
||||
{
|
||||
CRect rc;
|
||||
rc.left = Zoomed(selectionModel.GetDestRectLeft());
|
||||
rc.top = Zoomed(selectionModel.GetDestRectTop());
|
||||
rc.right = rc.left + Zoomed(selectionModel.GetDestRectWidth());
|
||||
rc.bottom = rc.top + Zoomed(selectionModel.GetDestRectHeight());
|
||||
::InflateRect(&rc, GRIP_SIZE, GRIP_SIZE);
|
||||
selectionWindow.MoveWindow(rc.left, rc.top, rc.Width(), rc.Height(), TRUE);
|
||||
selectionWindow.BringWindowToTop();
|
||||
imageArea.InvalidateRect(NULL, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
regularize(LONG x0, LONG y0, LONG& x1, LONG& y1)
|
||||
{
|
||||
|
@ -82,8 +68,11 @@ void ToolBase::reset()
|
|||
pointSP = 0;
|
||||
start.x = start.y = last.x = last.y = -1;
|
||||
selectionModel.ResetPtStack();
|
||||
if (selectionWindow.IsWindow())
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
if (selectionModel.m_bShow)
|
||||
{
|
||||
selectionModel.Landing();
|
||||
selectionModel.m_bShow = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
void ToolBase::OnCancelDraw()
|
||||
|
@ -121,12 +110,14 @@ struct FreeSelTool : ToolBase
|
|||
|
||||
void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
|
||||
{
|
||||
selectionModel.Landing();
|
||||
if (bLeftButton)
|
||||
{
|
||||
imageModel.CopyPrevious();
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
selectionModel.m_bShow = FALSE;
|
||||
selectionModel.ResetPtStack();
|
||||
selectionModel.PushToPtStack(x, y);
|
||||
POINT pt = { x, y };
|
||||
selectionModel.PushToPtStack(pt);
|
||||
}
|
||||
m_bLeftButton = bLeftButton;
|
||||
}
|
||||
|
@ -137,7 +128,7 @@ struct FreeSelTool : ToolBase
|
|||
{
|
||||
POINT pt = { x, y };
|
||||
imageModel.Bound(pt);
|
||||
selectionModel.PushToPtStack(pt.x, pt.y);
|
||||
selectionModel.PushToPtStack(pt);
|
||||
imageModel.ResetToPrevious();
|
||||
selectionModel.DrawFramePoly(m_hdc);
|
||||
}
|
||||
|
@ -150,28 +141,25 @@ struct FreeSelTool : ToolBase
|
|||
imageModel.ResetToPrevious();
|
||||
if (selectionModel.PtStackSize() > 2)
|
||||
{
|
||||
selectionModel.CalculateBoundingBoxAndContents(m_hdc);
|
||||
placeSelWin();
|
||||
selectionWindow.IsMoved(FALSE);
|
||||
selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
selectionModel.BuildMaskFromPtStack();
|
||||
selectionModel.TakeOff();
|
||||
selectionModel.m_bShow = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
imageModel.Undo(TRUE);
|
||||
selectionWindow.IsMoved(FALSE);
|
||||
selectionModel.ResetPtStack();
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
selectionModel.m_bShow = FALSE;
|
||||
}
|
||||
imageArea.Invalidate(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void OnFinishDraw()
|
||||
{
|
||||
if (m_bLeftButton)
|
||||
{
|
||||
selectionWindow.IsMoved(FALSE);
|
||||
selectionWindow.ForceRefreshSelectionContents();
|
||||
}
|
||||
imageArea.Invalidate(FALSE);
|
||||
|
||||
m_bLeftButton = FALSE;
|
||||
ToolBase::OnFinishDraw();
|
||||
}
|
||||
|
@ -181,7 +169,6 @@ struct FreeSelTool : ToolBase
|
|||
if (m_bLeftButton)
|
||||
imageModel.Undo(TRUE);
|
||||
m_bLeftButton = FALSE;
|
||||
selectionWindow.IsMoved(FALSE);
|
||||
ToolBase::OnCancelDraw();
|
||||
}
|
||||
};
|
||||
|
@ -197,11 +184,12 @@ struct RectSelTool : ToolBase
|
|||
|
||||
void OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
|
||||
{
|
||||
selectionModel.Landing();
|
||||
if (bLeftButton)
|
||||
{
|
||||
imageModel.CopyPrevious();
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
selectionModel.SetSrcRectSizeToZero();
|
||||
selectionModel.m_bShow = FALSE;
|
||||
::SetRectEmpty(&selectionModel.m_rc);
|
||||
}
|
||||
m_bLeftButton = bLeftButton;
|
||||
}
|
||||
|
@ -213,7 +201,7 @@ struct RectSelTool : ToolBase
|
|||
imageModel.ResetToPrevious();
|
||||
POINT pt = { x, y };
|
||||
imageModel.Bound(pt);
|
||||
selectionModel.SetSrcAndDestRectFromPoints(start, pt);
|
||||
selectionModel.SetRectFromPoints(start, pt);
|
||||
RectSel(m_hdc, start.x, start.y, pt.x, pt.y);
|
||||
}
|
||||
}
|
||||
|
@ -225,23 +213,16 @@ struct RectSelTool : ToolBase
|
|||
imageModel.ResetToPrevious();
|
||||
if (start.x == x && start.y == y)
|
||||
imageModel.Undo(TRUE);
|
||||
selectionModel.CalculateContents(m_hdc);
|
||||
placeSelWin();
|
||||
selectionWindow.IsMoved(FALSE);
|
||||
if (selectionModel.IsSrcRectSizeNonzero())
|
||||
selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
else
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
selectionModel.m_bShow = !selectionModel.m_rc.IsRectEmpty();
|
||||
imageArea.Invalidate(FALSE);
|
||||
}
|
||||
}
|
||||
|
||||
void OnFinishDraw()
|
||||
{
|
||||
if (m_bLeftButton)
|
||||
{
|
||||
selectionWindow.IsMoved(FALSE);
|
||||
selectionWindow.ForceRefreshSelectionContents();
|
||||
}
|
||||
imageArea.Invalidate(FALSE);
|
||||
|
||||
m_bLeftButton = FALSE;
|
||||
ToolBase::OnFinishDraw();
|
||||
}
|
||||
|
@ -251,7 +232,6 @@ struct RectSelTool : ToolBase
|
|||
if (m_bLeftButton)
|
||||
imageModel.Undo(TRUE);
|
||||
m_bLeftButton = FALSE;
|
||||
selectionWindow.IsMoved(FALSE);
|
||||
ToolBase::OnCancelDraw();
|
||||
}
|
||||
};
|
||||
|
@ -430,7 +410,7 @@ struct TextTool : ToolBase
|
|||
imageModel.ResetToPrevious();
|
||||
POINT pt = { x, y };
|
||||
imageModel.Bound(pt);
|
||||
selectionModel.SetSrcAndDestRectFromPoints(start, pt);
|
||||
selectionModel.SetRectFromPoints(start, pt);
|
||||
RectSel(m_hdc, start.x, start.y, pt.x, pt.y);
|
||||
}
|
||||
|
||||
|
@ -452,6 +432,10 @@ struct TextTool : ToolBase
|
|||
{
|
||||
imageModel.Undo(TRUE);
|
||||
|
||||
POINT pt = { x, y };
|
||||
imageModel.Bound(pt);
|
||||
selectionModel.SetRectFromPoints(start, pt);
|
||||
|
||||
BOOL bTextBoxShown = ::IsWindowVisible(textEditWindow);
|
||||
if (bTextBoxShown && textEditWindow.GetWindowTextLength() > 0)
|
||||
{
|
||||
|
@ -466,6 +450,13 @@ struct TextTool : ToolBase
|
|||
imageModel.CopyPrevious();
|
||||
Text(m_hdc, rc.left, rc.top, rc.right, rc.bottom, m_fg, m_bg, szText,
|
||||
textEditWindow.GetFont(), style);
|
||||
|
||||
if (selectionModel.m_rc.IsRectEmpty())
|
||||
{
|
||||
textEditWindow.ShowWindow(SW_HIDE);
|
||||
textEditWindow.SetWindowText(NULL);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (registrySettings.ShowTextTool)
|
||||
|
@ -476,45 +467,35 @@ struct TextTool : ToolBase
|
|||
fontsDialog.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
}
|
||||
|
||||
if (!bTextBoxShown || selectionModel.IsSrcRectSizeNonzero())
|
||||
RECT rc = selectionModel.m_rc;
|
||||
|
||||
// Enlarge if tool small
|
||||
INT cxMin = CX_MINTEXTEDIT, cyMin = CY_MINTEXTEDIT;
|
||||
if (selectionModel.m_rc.IsRectEmpty())
|
||||
{
|
||||
RECT rc;
|
||||
selectionModel.GetRect(&rc);
|
||||
|
||||
// Enlarge if tool small
|
||||
INT cxMin = CX_MINTEXTEDIT, cyMin = CY_MINTEXTEDIT;
|
||||
if (selectionModel.IsSrcRectSizeNonzero())
|
||||
{
|
||||
if (rc.right - rc.left < cxMin)
|
||||
rc.right = rc.left + cxMin;
|
||||
if (rc.bottom - rc.top < cyMin)
|
||||
rc.bottom = rc.top + cyMin;
|
||||
}
|
||||
else
|
||||
{
|
||||
SetRect(&rc, x, y, x + cxMin, y + cyMin);
|
||||
}
|
||||
|
||||
if (!textEditWindow.IsWindow())
|
||||
textEditWindow.Create(imageArea);
|
||||
|
||||
textEditWindow.SetWindowText(NULL);
|
||||
textEditWindow.ValidateEditRect(&rc);
|
||||
textEditWindow.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
textEditWindow.SetFocus();
|
||||
SetRect(&rc, x, y, x + cxMin, y + cyMin);
|
||||
}
|
||||
else
|
||||
{
|
||||
textEditWindow.ShowWindow(SW_HIDE);
|
||||
textEditWindow.SetWindowText(NULL);
|
||||
if (rc.right - rc.left < cxMin)
|
||||
rc.right = rc.left + cxMin;
|
||||
if (rc.bottom - rc.top < cyMin)
|
||||
rc.bottom = rc.top + cyMin;
|
||||
}
|
||||
|
||||
if (!textEditWindow.IsWindow())
|
||||
textEditWindow.Create(imageArea);
|
||||
|
||||
textEditWindow.SetWindowText(NULL);
|
||||
textEditWindow.ValidateEditRect(&rc);
|
||||
textEditWindow.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
textEditWindow.SetFocus();
|
||||
}
|
||||
|
||||
void OnFinishDraw()
|
||||
{
|
||||
toolsModel.OnButtonDown(TRUE, -1, -1, TRUE);
|
||||
toolsModel.OnButtonUp(TRUE, -1, -1);
|
||||
selectionWindow.IsMoved(FALSE);
|
||||
ToolBase::OnFinishDraw();
|
||||
}
|
||||
};
|
||||
|
|
|
@ -97,8 +97,8 @@ void PaletteModel::NotifyColorChanged()
|
|||
{
|
||||
if (paletteWindow.IsWindow())
|
||||
paletteWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED);
|
||||
if (selectionWindow.IsWindow())
|
||||
selectionWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED);
|
||||
if (imageArea.IsWindow())
|
||||
imageArea.SendMessage(WM_PALETTEMODELCOLORCHANGED);
|
||||
if (textEditWindow.IsWindow())
|
||||
textEditWindow.SendMessage(WM_PALETTEMODELCOLORCHANGED);
|
||||
}
|
||||
|
|
|
@ -43,7 +43,6 @@
|
|||
#include "palette.h"
|
||||
#include "palettemodel.h"
|
||||
#include "registry.h"
|
||||
#include "selection.h"
|
||||
#include "selectionmodel.h"
|
||||
#include "sizebox.h"
|
||||
#include "canvas.h"
|
||||
|
|
|
@ -1,237 +0,0 @@
|
|||
/*
|
||||
* PROJECT: PAINT for ReactOS
|
||||
* LICENSE: LGPL
|
||||
* FILE: base/applications/mspaint/selection.cpp
|
||||
* PURPOSE: Window procedure of the selection window
|
||||
* PROGRAMMERS: Benedikt Freisen
|
||||
* Katayama Hirofumi MZ
|
||||
*/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
CSelectionWindow selectionWindow;
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
const LPCTSTR CSelectionWindow::m_lpszCursorLUT[9] = { /* action to mouse cursor lookup table */
|
||||
IDC_SIZEALL,
|
||||
|
||||
IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW,
|
||||
IDC_SIZEWE, IDC_SIZEWE,
|
||||
IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE
|
||||
};
|
||||
|
||||
void CSelectionWindow::ForceRefreshSelectionContents()
|
||||
{
|
||||
if (::IsWindowVisible(selectionWindow))
|
||||
{
|
||||
imageModel.ResetToPrevious();
|
||||
imageModel.DrawSelectionBackground(m_rgbBack);
|
||||
selectionModel.DrawSelection(imageModel.GetDC(), paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
|
||||
}
|
||||
}
|
||||
|
||||
int CSelectionWindow::IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
PAINTSTRUCT ps;
|
||||
HDC hDC = BeginPaint(&ps);
|
||||
if (!m_bMoving)
|
||||
{
|
||||
RECT rcClient;
|
||||
GetClientRect(&rcClient);
|
||||
drawSizeBoxes(hDC, &rcClient, TRUE, &ps.rcPaint);
|
||||
}
|
||||
EndPaint(&ps);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
// do nothing => transparent background
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
m_bMoving = FALSE;
|
||||
m_iAction = ACTION_MOVE;
|
||||
/* update the system selection color */
|
||||
Invalidate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
/* update the system selection color */
|
||||
Invalidate();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
RECT rcClient;
|
||||
GetClientRect(&rcClient);
|
||||
|
||||
POINT pt;
|
||||
::GetCursorPos(&pt);
|
||||
ScreenToClient(&pt);
|
||||
|
||||
if (!setCursorOnSizeBox(getSizeBoxHitTest(pt, &rcClient)))
|
||||
::SetCursor(::LoadCursor(NULL, IDC_SIZEALL));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
m_ptPos.x = GET_X_LPARAM(lParam);
|
||||
m_ptPos.y = GET_Y_LPARAM(lParam);
|
||||
m_ptDelta.x = 0;
|
||||
m_ptDelta.y = 0;
|
||||
SetCapture();
|
||||
if (m_iAction != ACTION_MOVE)
|
||||
SetCursor(LoadCursor(NULL, m_lpszCursorLUT[m_iAction]));
|
||||
m_bMoving = TRUE;
|
||||
imageArea.InvalidateRect(NULL, FALSE);
|
||||
imageArea.SendMessage(WM_PAINT, 0, 0);
|
||||
m_rgbBack = paletteModel.GetBgColor();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (m_bMoving)
|
||||
{
|
||||
imageModel.ResetToPrevious();
|
||||
imageModel.DrawSelectionBackground(m_rgbBack);
|
||||
m_ptFrac.x += GET_X_LPARAM(lParam) - m_ptPos.x;
|
||||
m_ptFrac.y += GET_Y_LPARAM(lParam) - m_ptPos.y;
|
||||
m_ptDelta.x += UnZoomed(m_ptFrac.x);
|
||||
m_ptDelta.y += UnZoomed(m_ptFrac.y);
|
||||
if (toolsModel.GetZoom() < 1000)
|
||||
{
|
||||
m_ptFrac.x = 0;
|
||||
m_ptFrac.y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_ptFrac.x -= Zoomed(UnZoomed(m_ptFrac.x));
|
||||
m_ptFrac.y -= Zoomed(UnZoomed(m_ptFrac.y));
|
||||
}
|
||||
selectionModel.ModifyDestRect(m_ptDelta, m_iAction);
|
||||
|
||||
CString strSize;
|
||||
strSize.Format(_T("%ld x %ld"), selectionModel.GetDestRectWidth(), selectionModel.GetDestRectHeight());
|
||||
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize);
|
||||
|
||||
if (m_iAction != ACTION_MOVE)
|
||||
selectionModel.DrawSelectionStretched(imageModel.GetDC());
|
||||
else
|
||||
selectionModel.DrawSelection(imageModel.GetDC(), paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
|
||||
imageArea.InvalidateRect(NULL, FALSE);
|
||||
imageArea.SendMessage(WM_PAINT, 0, 0);
|
||||
m_ptPos.x = GET_X_LPARAM(lParam);
|
||||
m_ptPos.y = GET_Y_LPARAM(lParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
int w = Zoomed(selectionModel.GetDestRectWidth()) + 2 * GRIP_SIZE;
|
||||
int h = Zoomed(selectionModel.GetDestRectHeight()) + 2 * GRIP_SIZE;
|
||||
m_ptPos.x = GET_X_LPARAM(lParam);
|
||||
m_ptPos.y = GET_Y_LPARAM(lParam);
|
||||
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) NULL);
|
||||
m_iAction = IdentifyCorner(m_ptPos.x, m_ptPos.y, w, h);
|
||||
if (m_iAction != ACTION_MOVE)
|
||||
SetCursor(LoadCursor(NULL, m_lpszCursorLUT[m_iAction]));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
m_bMoved = TRUE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (m_bMoving)
|
||||
{
|
||||
m_bMoving = FALSE;
|
||||
ReleaseCapture();
|
||||
if (m_iAction != ACTION_MOVE && toolsModel.GetActiveTool() != TOOL_TEXT)
|
||||
{
|
||||
imageModel.Undo();
|
||||
imageModel.DrawSelectionBackground(m_rgbBack);
|
||||
selectionModel.ScaleContentsToFit();
|
||||
imageModel.CopyPrevious();
|
||||
}
|
||||
placeSelWin();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (m_bMoving)
|
||||
{
|
||||
m_bMoving = FALSE;
|
||||
if (m_iAction == ACTION_MOVE)
|
||||
{
|
||||
if (toolsModel.GetActiveTool() == TOOL_RECTSEL)
|
||||
imageArea.cancelDrawing();
|
||||
else
|
||||
placeSelWin();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_iAction = ACTION_MOVE;
|
||||
}
|
||||
ShowWindow(SW_HIDE);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (wParam == VK_ESCAPE)
|
||||
{
|
||||
if (GetCapture() == m_hWnd)
|
||||
{
|
||||
ReleaseCapture();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnPaletteModelColorChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnToolsModelSettingsChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnSelectionModelRefreshNeeded(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
ForceRefreshSelectionContents();
|
||||
return 0;
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
return ::SendMessage(GetParent(), nMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
LRESULT CSelectionWindow::OnToolsModelZoomChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
placeSelWin();
|
||||
return 0;
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
/*
|
||||
* PROJECT: PAINT for ReactOS
|
||||
* LICENSE: LGPL
|
||||
* FILE: base/applications/mspaint/selection.h
|
||||
* PURPOSE: Window procedure of the selection window
|
||||
* PROGRAMMERS: Benedikt Freisen
|
||||
* Katayama Hirofumi MZ
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
class CSelectionWindow : public CWindowImpl<CSelectionWindow>
|
||||
{
|
||||
public:
|
||||
CSelectionWindow() : m_bMoved(FALSE)
|
||||
{
|
||||
}
|
||||
|
||||
BOOL IsMoved() const { return m_bMoved; }
|
||||
void IsMoved(BOOL bMoved) { m_bMoved = bMoved; }
|
||||
|
||||
void ForceRefreshSelectionContents();
|
||||
|
||||
DECLARE_WND_CLASS_EX(_T("Selection"), CS_DBLCLKS, COLOR_BTNFACE)
|
||||
|
||||
BEGIN_MSG_MAP(CSelectionWindow)
|
||||
MESSAGE_HANDLER(WM_PAINT, OnPaint)
|
||||
MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
|
||||
MESSAGE_HANDLER(WM_CREATE, OnCreate)
|
||||
MESSAGE_HANDLER(WM_SYSCOLORCHANGE, OnSysColorChange)
|
||||
MESSAGE_HANDLER(WM_SETCURSOR, OnSetCursor)
|
||||
MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
|
||||
MESSAGE_HANDLER(WM_MOUSEMOVE, OnMouseMove)
|
||||
MESSAGE_HANDLER(WM_MOUSEWHEEL, OnMouseWheel)
|
||||
MESSAGE_HANDLER(WM_LBUTTONUP, OnLButtonUp)
|
||||
MESSAGE_HANDLER(WM_MOVE, OnMove)
|
||||
MESSAGE_HANDLER(WM_PALETTEMODELCOLORCHANGED, OnPaletteModelColorChanged)
|
||||
MESSAGE_HANDLER(WM_TOOLSMODELSETTINGSCHANGED, OnToolsModelSettingsChanged)
|
||||
MESSAGE_HANDLER(WM_TOOLSMODELZOOMCHANGED, OnToolsModelZoomChanged)
|
||||
MESSAGE_HANDLER(WM_SELECTIONMODELREFRESHNEEDED, OnSelectionModelRefreshNeeded)
|
||||
MESSAGE_HANDLER(WM_CAPTURECHANGED, OnCaptureChanged)
|
||||
MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
|
||||
END_MSG_MAP()
|
||||
|
||||
LRESULT OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnPaletteModelColorChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnToolsModelSettingsChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnToolsModelZoomChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnSelectionModelRefreshNeeded(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
||||
private:
|
||||
static const LPCTSTR m_lpszCursorLUT[9];
|
||||
BOOL m_bMoved;
|
||||
BOOL m_bMoving;
|
||||
int m_iAction;
|
||||
POINT m_ptPos;
|
||||
POINT m_ptFrac;
|
||||
POINT m_ptDelta;
|
||||
COLORREF m_rgbBack;
|
||||
|
||||
int IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight);
|
||||
};
|
||||
|
||||
void ForceRefreshSelectionContents();
|
|
@ -14,225 +14,295 @@ SelectionModel selectionModel;
|
|||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
SelectionModel::SelectionModel()
|
||||
: m_hDC(CreateCompatibleDC(NULL))
|
||||
, m_hBm(NULL)
|
||||
, m_hMask(NULL)
|
||||
: m_hbmColor(NULL)
|
||||
, m_hbmMask(NULL)
|
||||
, m_ptStack(NULL)
|
||||
, m_iPtSP(0)
|
||||
, m_bShow(FALSE)
|
||||
{
|
||||
SetRectEmpty(&m_rcSrc);
|
||||
SetRectEmpty(&m_rcDest);
|
||||
::SetRectEmpty(&m_rc);
|
||||
m_ptHit.x = m_ptHit.y = -1;
|
||||
}
|
||||
|
||||
SelectionModel::~SelectionModel()
|
||||
{
|
||||
DeleteDC(m_hDC);
|
||||
ClearColor();
|
||||
ClearMask();
|
||||
ResetPtStack();
|
||||
if (m_hBm)
|
||||
{
|
||||
DeleteObject(m_hBm);
|
||||
}
|
||||
if (m_hMask)
|
||||
{
|
||||
DeleteObject(m_hMask);
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionModel::ResetPtStack()
|
||||
{
|
||||
if (m_ptStack != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, m_ptStack);
|
||||
m_ptStack = NULL;
|
||||
if (m_ptStack)
|
||||
{
|
||||
free(m_ptStack);
|
||||
m_ptStack = NULL;
|
||||
}
|
||||
m_iPtSP = 0;
|
||||
}
|
||||
|
||||
void SelectionModel::PushToPtStack(LONG x, LONG y)
|
||||
void SelectionModel::PushToPtStack(POINT pt)
|
||||
{
|
||||
if (m_iPtSP % 1024 == 0)
|
||||
#define GROW_COUNT 256
|
||||
if (m_iPtSP % GROW_COUNT == 0)
|
||||
{
|
||||
if (m_ptStack)
|
||||
m_ptStack = (POINT*) HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, m_ptStack, sizeof(POINT) * (m_iPtSP + 1024));
|
||||
else
|
||||
m_ptStack = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * 1024);
|
||||
INT nNewCount = m_iPtSP + GROW_COUNT;
|
||||
LPPOINT pptNew = (LPPOINT)realloc(m_ptStack, sizeof(POINT) * nNewCount);
|
||||
if (pptNew == NULL)
|
||||
return;
|
||||
m_ptStack = pptNew;
|
||||
}
|
||||
m_ptStack[m_iPtSP].x = x;
|
||||
m_ptStack[m_iPtSP].y = y;
|
||||
m_ptStack[m_iPtSP] = pt;
|
||||
m_iPtSP++;
|
||||
#undef GROW_COUNT
|
||||
}
|
||||
|
||||
void SelectionModel::CalculateBoundingBoxAndContents(HDC hDCImage)
|
||||
void SelectionModel::ShiftPtStack(BOOL bPlus)
|
||||
{
|
||||
int i;
|
||||
m_rcSrc.left = m_rcSrc.top = MAXLONG;
|
||||
m_rcSrc.right = m_rcSrc.bottom = 0;
|
||||
for (i = 0; i < m_iPtSP; i++)
|
||||
if (bPlus)
|
||||
{
|
||||
if (m_ptStack[i].x < m_rcSrc.left)
|
||||
m_rcSrc.left = m_ptStack[i].x;
|
||||
if (m_ptStack[i].y < m_rcSrc.top)
|
||||
m_rcSrc.top = m_ptStack[i].y;
|
||||
if (m_ptStack[i].x > m_rcSrc.right)
|
||||
m_rcSrc.right = m_ptStack[i].x;
|
||||
if (m_ptStack[i].y > m_rcSrc.bottom)
|
||||
m_rcSrc.bottom = m_ptStack[i].y;
|
||||
}
|
||||
m_rcSrc.right += 1;
|
||||
m_rcSrc.bottom += 1;
|
||||
m_rcDest.left = m_rcSrc.left;
|
||||
m_rcDest.top = m_rcSrc.top;
|
||||
m_rcDest.right = m_rcSrc.right;
|
||||
m_rcDest.bottom = m_rcSrc.bottom;
|
||||
|
||||
if (m_iPtSP > 1)
|
||||
{
|
||||
DeleteObject(m_hMask);
|
||||
m_hMask = CreateBitmap(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 1, 1, NULL);
|
||||
DeleteObject(SelectObject(m_hDC, m_hMask));
|
||||
POINT *m_ptStackCopy = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * m_iPtSP);
|
||||
for (i = 0; i < m_iPtSP; i++)
|
||||
for (INT i = 0; i < m_iPtSP; ++i)
|
||||
{
|
||||
m_ptStackCopy[i].x = m_ptStack[i].x - m_rcSrc.left;
|
||||
m_ptStackCopy[i].y = m_ptStack[i].y - m_rcSrc.top;
|
||||
POINT& pt = m_ptStack[i];
|
||||
pt.x += m_rc.left;
|
||||
pt.y += m_rc.top;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (INT i = 0; i < m_iPtSP; ++i)
|
||||
{
|
||||
POINT& pt = m_ptStack[i];
|
||||
pt.x -= m_rc.left;
|
||||
pt.y -= m_rc.top;
|
||||
}
|
||||
Poly(m_hDC, m_ptStackCopy, m_iPtSP, 0x00ffffff, 0x00ffffff, 1, 2, TRUE, FALSE);
|
||||
HeapFree(GetProcessHeap(), 0, m_ptStackCopy);
|
||||
SelectObject(m_hDC, m_hBm = CreateDIBWithProperties(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc)));
|
||||
imageModel.ResetToPrevious();
|
||||
MaskBlt(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), hDCImage, m_rcSrc.left,
|
||||
m_rcSrc.top, m_hMask, 0, 0, MAKEROP4(SRCCOPY, WHITENESS));
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionModel::CalculateContents(HDC hDCImage)
|
||||
void SelectionModel::BuildMaskFromPtStack()
|
||||
{
|
||||
DeleteObject(m_hMask);
|
||||
m_hMask = CreateBitmap(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 1, 1, NULL);
|
||||
DeleteObject(SelectObject(m_hDC, m_hMask));
|
||||
Rect(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), 0x00ffffff, 0x00ffffff, 1, 2);
|
||||
SelectObject(m_hDC, m_hBm = CreateDIBWithProperties(RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc)));
|
||||
BitBlt(m_hDC, 0, 0, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), hDCImage, m_rcSrc.left,
|
||||
m_rcSrc.top, SRCCOPY);
|
||||
CRect rc = { MAXLONG, MAXLONG, 0, 0 };
|
||||
for (INT i = 0; i < m_iPtSP; ++i)
|
||||
{
|
||||
POINT& pt = m_ptStack[i];
|
||||
rc.left = min(pt.x, rc.left);
|
||||
rc.top = min(pt.y, rc.top);
|
||||
rc.right = max(pt.x, rc.right);
|
||||
rc.bottom = max(pt.y, rc.bottom);
|
||||
}
|
||||
rc.right += 1;
|
||||
rc.bottom += 1;
|
||||
|
||||
m_rc = rc;
|
||||
|
||||
ShiftPtStack(FALSE);
|
||||
|
||||
ClearMask();
|
||||
|
||||
HDC hdcMem = ::CreateCompatibleDC(NULL);
|
||||
m_hbmMask = ::CreateBitmap(rc.Width(), rc.Height(), 1, 1, NULL);
|
||||
HGDIOBJ hbmOld = ::SelectObject(hdcMem, m_hbmMask);
|
||||
FillRect(hdcMem, &rc, (HBRUSH)::GetStockObject(BLACK_BRUSH));
|
||||
HGDIOBJ hPenOld = ::SelectObject(hdcMem, GetStockObject(NULL_PEN));
|
||||
HGDIOBJ hbrOld = ::SelectObject(hdcMem, GetStockObject(WHITE_BRUSH));
|
||||
::Polygon(hdcMem, m_ptStack, m_iPtSP);
|
||||
::SelectObject(hdcMem, hbrOld);
|
||||
::SelectObject(hdcMem, hPenOld);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
::DeleteDC(hdcMem);
|
||||
}
|
||||
|
||||
void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg)
|
||||
{
|
||||
Poly(hDCImage, m_ptStack, m_iPtSP, crBg, crBg, 1, 2, TRUE, FALSE);
|
||||
ShiftPtStack(TRUE);
|
||||
|
||||
HGDIOBJ hPenOld = ::SelectObject(hDCImage, ::GetStockObject(NULL_PEN));
|
||||
HGDIOBJ hbrOld = ::SelectObject(hDCImage, ::CreateSolidBrush(crBg));
|
||||
::Polygon(hDCImage, m_ptStack, m_iPtSP);
|
||||
::DeleteObject(::SelectObject(hDCImage, hbrOld));
|
||||
::SelectObject(hDCImage, hPenOld);
|
||||
|
||||
ShiftPtStack(FALSE);
|
||||
}
|
||||
|
||||
void SelectionModel::DrawBackgroundRect(HDC hDCImage, COLORREF crBg)
|
||||
{
|
||||
Rect(hDCImage, m_rcSrc.left, m_rcSrc.top, m_rcSrc.right, m_rcSrc.bottom, crBg, crBg, 0, 1);
|
||||
Rect(hDCImage, m_rc.left, m_rc.top, m_rc.right, m_rc.bottom, crBg, crBg, 0, 1);
|
||||
}
|
||||
|
||||
void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent)
|
||||
void SelectionModel::DrawSelection(HDC hDCImage, LPCRECT prc, COLORREF crBg, BOOL bBgTransparent)
|
||||
{
|
||||
if (!bBgTransparent)
|
||||
MaskBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest),
|
||||
m_hDC, 0, 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
|
||||
CRect rc = *prc;
|
||||
if (::IsRectEmpty(&rc))
|
||||
return;
|
||||
|
||||
BITMAP bm;
|
||||
GetObject(m_hbmColor, sizeof(BITMAP), &bm);
|
||||
|
||||
COLORREF keyColor = (bBgTransparent ? crBg : CLR_INVALID);
|
||||
|
||||
HDC hMemDC = CreateCompatibleDC(hDCImage);
|
||||
HGDIOBJ hbmOld = SelectObject(hMemDC, m_hbmColor);
|
||||
ColorKeyedMaskBlt(hDCImage, rc.left, rc.top, rc.Width(), rc.Height(),
|
||||
hMemDC, 0, 0, bm.bmWidth, bm.bmHeight, m_hbmMask, keyColor);
|
||||
SelectObject(hMemDC, hbmOld);
|
||||
DeleteDC(hMemDC);
|
||||
}
|
||||
|
||||
void SelectionModel::GetSelectionContents(HDC hDCImage)
|
||||
{
|
||||
ClearColor();
|
||||
|
||||
HDC hMemDC = ::CreateCompatibleDC(NULL);
|
||||
m_hbmColor = CreateColorDIB(m_rc.Width(), m_rc.Height(), RGB(255, 255, 255));
|
||||
HGDIOBJ hbmOld = ::SelectObject(hMemDC, m_hbmColor);
|
||||
::BitBlt(hMemDC, 0, 0, m_rc.Width(), m_rc.Height(), hDCImage, m_rc.left, m_rc.top, SRCCOPY);
|
||||
::SelectObject(hMemDC, hbmOld);
|
||||
::DeleteDC(hMemDC);
|
||||
}
|
||||
|
||||
BOOL SelectionModel::TakeOff()
|
||||
{
|
||||
if (m_hbmColor || ::IsRectEmpty(&m_rc))
|
||||
return FALSE;
|
||||
|
||||
HDC hDCImage = imageModel.GetDC();
|
||||
GetSelectionContents(hDCImage);
|
||||
|
||||
if (toolsModel.GetActiveTool() == TOOL_FREESEL)
|
||||
{
|
||||
DrawBackgroundPoly(hDCImage, paletteModel.GetBgColor());
|
||||
}
|
||||
else
|
||||
ColorKeyedMaskBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest),
|
||||
m_hDC, 0, 0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND), crBg);
|
||||
{
|
||||
ClearMask();
|
||||
DrawBackgroundRect(hDCImage, paletteModel.GetBgColor());
|
||||
}
|
||||
|
||||
imageArea.Invalidate(FALSE);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void SelectionModel::DrawSelectionStretched(HDC hDCImage)
|
||||
void SelectionModel::Landing()
|
||||
{
|
||||
StretchBlt(hDCImage, m_rcDest.left, m_rcDest.top, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0, GetDIBWidth(m_hBm), GetDIBHeight(m_hBm), SRCCOPY);
|
||||
}
|
||||
if (!m_hbmColor)
|
||||
return;
|
||||
|
||||
void SelectionModel::ScaleContentsToFit()
|
||||
{
|
||||
HDC hTempDC;
|
||||
HBITMAP hTempBm;
|
||||
hTempDC = CreateCompatibleDC(m_hDC);
|
||||
hTempBm = CreateDIBWithProperties(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest));
|
||||
SelectObject(hTempDC, hTempBm);
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
StretchBlt(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0,
|
||||
GetDIBWidth(m_hBm), GetDIBHeight(m_hBm), SRCCOPY);
|
||||
DeleteObject(m_hBm);
|
||||
m_hBm = hTempBm;
|
||||
hTempBm = CreateBitmap(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 1, 1, NULL);
|
||||
SelectObject(hTempDC, hTempBm);
|
||||
SelectObject(m_hDC, m_hMask);
|
||||
StretchBlt(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC, 0, 0,
|
||||
GetDIBWidth(m_hMask), GetDIBHeight(m_hMask), SRCCOPY);
|
||||
DeleteObject(m_hMask);
|
||||
m_hMask = hTempBm;
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
DeleteDC(hTempDC);
|
||||
DrawSelection(imageModel.GetDC(), &m_rc, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
|
||||
|
||||
::SetRectEmpty(&m_rc);
|
||||
ClearMask();
|
||||
ClearColor();
|
||||
|
||||
imageModel.CopyPrevious();
|
||||
}
|
||||
|
||||
void SelectionModel::InsertFromHBITMAP(HBITMAP hBm, INT x, INT y)
|
||||
{
|
||||
HDC hTempDC;
|
||||
HBITMAP hTempMask;
|
||||
m_hbmColor = CopyDIBImage(hBm);
|
||||
::DeleteObject(m_hbmColor);
|
||||
|
||||
m_hBm = CopyDIBImage(hBm);
|
||||
DeleteObject(SelectObject(m_hDC, m_hBm));
|
||||
m_rc.left = x;
|
||||
m_rc.top = y;
|
||||
m_rc.right = m_rc.left + GetDIBWidth(hBm);
|
||||
m_rc.bottom = m_rc.top + GetDIBHeight(hBm);
|
||||
|
||||
SetRectEmpty(&m_rcSrc);
|
||||
m_rcDest.left = x;
|
||||
m_rcDest.top = y;
|
||||
m_rcDest.right = m_rcDest.left + GetDIBWidth(m_hBm);
|
||||
m_rcDest.bottom = m_rcDest.top + GetDIBHeight(m_hBm);
|
||||
|
||||
hTempDC = CreateCompatibleDC(m_hDC);
|
||||
hTempMask = CreateBitmap(RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 1, 1, NULL);
|
||||
SelectObject(hTempDC, hTempMask);
|
||||
Rect(hTempDC, 0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), 0x00ffffff, 0x00ffffff, 1, 1);
|
||||
DeleteObject(m_hMask);
|
||||
m_hMask = hTempMask;
|
||||
DeleteDC(hTempDC);
|
||||
ClearMask();
|
||||
}
|
||||
|
||||
void SelectionModel::FlipHorizontally()
|
||||
{
|
||||
SelectObject(m_hDC, m_hMask);
|
||||
StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, 0, -RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC,
|
||||
0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, 0, -RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), m_hDC,
|
||||
0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
|
||||
TakeOff();
|
||||
|
||||
HDC hdcMem = ::CreateCompatibleDC(NULL);
|
||||
if (m_hbmMask)
|
||||
{
|
||||
::SelectObject(hdcMem, m_hbmMask);
|
||||
::StretchBlt(hdcMem, m_rc.Width() - 1, 0, -m_rc.Width(), m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
}
|
||||
if (m_hbmColor)
|
||||
{
|
||||
::SelectObject(hdcMem, m_hbmColor);
|
||||
::StretchBlt(hdcMem, m_rc.Width() - 1, 0, -m_rc.Width(), m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
}
|
||||
::DeleteDC(hdcMem);
|
||||
|
||||
NotifyRefreshNeeded();
|
||||
}
|
||||
|
||||
void SelectionModel::FlipVertically()
|
||||
{
|
||||
SelectObject(m_hDC, m_hMask);
|
||||
StretchBlt(m_hDC, 0, RECT_HEIGHT(m_rcDest) - 1, RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC,
|
||||
0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
StretchBlt(m_hDC, 0, RECT_HEIGHT(m_rcDest) - 1, RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC,
|
||||
0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
|
||||
TakeOff();
|
||||
|
||||
HDC hdcMem = ::CreateCompatibleDC(NULL);
|
||||
if (m_hbmMask)
|
||||
{
|
||||
::SelectObject(hdcMem, m_hbmMask);
|
||||
::StretchBlt(hdcMem, 0, m_rc.Height() - 1, m_rc.Width(), -m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
}
|
||||
if (m_hbmColor)
|
||||
{
|
||||
::SelectObject(hdcMem, m_hbmColor);
|
||||
::StretchBlt(hdcMem, 0, m_rc.Height() - 1, m_rc.Width(), -m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
}
|
||||
::DeleteDC(hdcMem);
|
||||
|
||||
NotifyRefreshNeeded();
|
||||
}
|
||||
|
||||
void SelectionModel::RotateNTimes90Degrees(int iN)
|
||||
{
|
||||
HBITMAP hbm;
|
||||
HGDIOBJ hbmOld;
|
||||
HDC hdcMem = ::CreateCompatibleDC(NULL);
|
||||
|
||||
switch (iN)
|
||||
{
|
||||
case 1:
|
||||
case 3:
|
||||
imageModel.DeleteSelection();
|
||||
imageModel.CopyPrevious();
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
hbm = Rotate90DegreeBlt(m_hDC, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), iN == 1);
|
||||
InsertFromHBITMAP(hbm, m_rcDest.left, m_rcDest.top);
|
||||
DeleteObject(hbm);
|
||||
selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
selectionWindow.ForceRefreshSelectionContents();
|
||||
placeSelWin();
|
||||
break;
|
||||
case 2:
|
||||
SelectObject(m_hDC, m_hMask);
|
||||
StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, RECT_HEIGHT(m_rcDest) - 1, -RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC,
|
||||
0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
StretchBlt(m_hDC, RECT_WIDTH(m_rcDest) - 1, RECT_HEIGHT(m_rcDest) - 1, -RECT_WIDTH(m_rcDest), -RECT_HEIGHT(m_rcDest), m_hDC,
|
||||
0, 0, RECT_WIDTH(m_rcDest), RECT_HEIGHT(m_rcDest), SRCCOPY);
|
||||
break;
|
||||
case 1:
|
||||
case 3:
|
||||
TakeOff();
|
||||
if (m_hbmColor)
|
||||
{
|
||||
hbmOld = ::SelectObject(hdcMem, m_hbmColor);
|
||||
hbm = Rotate90DegreeBlt(hdcMem, m_rc.Width(), m_rc.Height(), iN == 1, FALSE);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
::DeleteObject(m_hbmColor);
|
||||
m_hbmColor = hbm;
|
||||
}
|
||||
if (m_hbmMask)
|
||||
{
|
||||
hbmOld = ::SelectObject(hdcMem, m_hbmMask);
|
||||
hbm = Rotate90DegreeBlt(hdcMem, m_rc.Width(), m_rc.Height(), iN == 1, TRUE);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
::DeleteObject(m_hbmMask);
|
||||
m_hbmMask = hbm;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
TakeOff();
|
||||
if (m_hbmColor)
|
||||
{
|
||||
hbmOld = ::SelectObject(hdcMem, m_hbmColor);
|
||||
::StretchBlt(hdcMem, m_rc.Width() - 1, m_rc.Height() - 1, -m_rc.Width(), -m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
}
|
||||
if (m_hbmMask)
|
||||
{
|
||||
hbmOld = ::SelectObject(hdcMem, m_hbmMask);
|
||||
::StretchBlt(hdcMem, m_rc.Width() - 1, m_rc.Height() - 1, -m_rc.Width(), -m_rc.Height(),
|
||||
hdcMem, 0, 0, m_rc.Width(), m_rc.Height(), SRCCOPY);
|
||||
::SelectObject(hdcMem, hbmOld);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
::DeleteDC(hdcMem);
|
||||
NotifyRefreshNeeded();
|
||||
}
|
||||
|
||||
|
@ -241,47 +311,47 @@ void SelectionModel::StretchSkew(int nStretchPercentX, int nStretchPercentY, int
|
|||
if (nStretchPercentX == 100 && nStretchPercentY == 100 && nSkewDegX == 0 && nSkewDegY == 0)
|
||||
return;
|
||||
|
||||
imageModel.DeleteSelection();
|
||||
imageModel.CopyPrevious();
|
||||
TakeOff();
|
||||
|
||||
INT oldWidth = RECT_WIDTH(m_rcDest);
|
||||
INT oldHeight = RECT_HEIGHT(m_rcDest);
|
||||
INT oldWidth = m_rc.Width();
|
||||
INT oldHeight = m_rc.Height();
|
||||
INT newWidth = oldWidth * nStretchPercentX / 100;
|
||||
INT newHeight = oldHeight * nStretchPercentY / 100;
|
||||
|
||||
if (oldWidth != newWidth || oldHeight != newHeight)
|
||||
{
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
HBITMAP hbm0 = CopyDIBImage(m_hBm, newWidth, newHeight);
|
||||
InsertFromHBITMAP(hbm0, m_rcDest.left, m_rcDest.top);
|
||||
DeleteObject(hbm0);
|
||||
HBITMAP hbm0 = CopyDIBImage(m_hbmColor, newWidth, newHeight);
|
||||
InsertFromHBITMAP(hbm0, m_rc.left, m_rc.top);
|
||||
::DeleteObject(hbm0);
|
||||
}
|
||||
|
||||
HDC hDC = ::CreateCompatibleDC(NULL);
|
||||
|
||||
if (nSkewDegX)
|
||||
{
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
HBITMAP hbm1 = SkewDIB(m_hDC, m_hBm, nSkewDegX, FALSE);
|
||||
InsertFromHBITMAP(hbm1, m_rcDest.left, m_rcDest.top);
|
||||
DeleteObject(hbm1);
|
||||
::SelectObject(hDC, m_hbmColor);
|
||||
HBITMAP hbm1 = SkewDIB(hDC, m_hbmColor, nSkewDegX, FALSE);
|
||||
InsertFromHBITMAP(hbm1, m_rc.left, m_rc.top);
|
||||
::DeleteObject(hbm1);
|
||||
}
|
||||
|
||||
if (nSkewDegY)
|
||||
{
|
||||
SelectObject(m_hDC, m_hBm);
|
||||
HBITMAP hbm2 = SkewDIB(m_hDC, m_hBm, nSkewDegY, TRUE);
|
||||
InsertFromHBITMAP(hbm2, m_rcDest.left, m_rcDest.top);
|
||||
DeleteObject(hbm2);
|
||||
::SelectObject(hDC, m_hbmColor);
|
||||
HBITMAP hbm2 = SkewDIB(hDC, m_hbmColor, nSkewDegY, TRUE);
|
||||
InsertFromHBITMAP(hbm2, m_rc.left, m_rc.top);
|
||||
::DeleteObject(hbm2);
|
||||
}
|
||||
|
||||
selectionWindow.ShowWindow(SW_SHOWNOACTIVATE);
|
||||
selectionWindow.ForceRefreshSelectionContents();
|
||||
placeSelWin();
|
||||
::DeleteDC(hDC);
|
||||
|
||||
m_bShow = TRUE;
|
||||
NotifyRefreshNeeded();
|
||||
}
|
||||
|
||||
HBITMAP SelectionModel::GetBitmap() const
|
||||
{
|
||||
return m_hBm;
|
||||
return m_hbmColor;
|
||||
}
|
||||
|
||||
int SelectionModel::PtStackSize() const
|
||||
|
@ -291,114 +361,92 @@ int SelectionModel::PtStackSize() const
|
|||
|
||||
void SelectionModel::DrawFramePoly(HDC hDCImage)
|
||||
{
|
||||
Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE); /* draw the freehand selection inverted/xored */
|
||||
/* draw the freehand selection inverted/xored */
|
||||
Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE);
|
||||
}
|
||||
|
||||
void SelectionModel::SetSrcAndDestRectFromPoints(const POINT& ptFrom, const POINT& ptTo)
|
||||
void SelectionModel::SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo)
|
||||
{
|
||||
m_rcDest.left = m_rcSrc.left = min(ptFrom.x, ptTo.x);
|
||||
m_rcDest.top = m_rcSrc.top = min(ptFrom.y, ptTo.y);
|
||||
m_rcDest.right = m_rcSrc.right = max(ptFrom.x, ptTo.x);
|
||||
m_rcDest.bottom = m_rcSrc.bottom = max(ptFrom.y, ptTo.y);
|
||||
m_rc.left = min(ptFrom.x, ptTo.x);
|
||||
m_rc.top = min(ptFrom.y, ptTo.y);
|
||||
m_rc.right = max(ptFrom.x, ptTo.x);
|
||||
m_rc.bottom = max(ptFrom.y, ptTo.y);
|
||||
}
|
||||
|
||||
void SelectionModel::SetSrcRectSizeToZero()
|
||||
void SelectionModel::Dragging(CANVAS_HITTEST hit, POINT pt)
|
||||
{
|
||||
m_rcSrc.right = m_rcSrc.left;
|
||||
m_rcSrc.bottom = m_rcSrc.top;
|
||||
}
|
||||
|
||||
BOOL SelectionModel::IsSrcRectSizeNonzero() const
|
||||
{
|
||||
return (RECT_WIDTH(m_rcSrc) != 0) && (RECT_HEIGHT(m_rcSrc) != 0);
|
||||
}
|
||||
|
||||
void SelectionModel::ModifyDestRect(POINT& ptDelta, int iAction)
|
||||
{
|
||||
POINT ptDeltaUsed;
|
||||
|
||||
switch (iAction)
|
||||
switch (hit)
|
||||
{
|
||||
case ACTION_MOVE: /* move selection */
|
||||
ptDeltaUsed.x = ptDelta.x;
|
||||
ptDeltaUsed.y = ptDelta.y;
|
||||
OffsetRect(&m_rcDest, ptDeltaUsed.x, ptDeltaUsed.y);
|
||||
case HIT_NONE:
|
||||
break;
|
||||
case ACTION_RESIZE_TOP_LEFT: /* resize at upper left corner */
|
||||
ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
|
||||
ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
|
||||
m_rcDest.left += ptDeltaUsed.x;
|
||||
m_rcDest.top += ptDeltaUsed.y;
|
||||
case HIT_UPPER_LEFT:
|
||||
m_rc.left += pt.x - m_ptHit.x;
|
||||
m_rc.top += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case ACTION_RESIZE_TOP: /* resize at top edge */
|
||||
ptDeltaUsed.x = ptDelta.x;
|
||||
ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
|
||||
m_rcDest.top += ptDeltaUsed.y;
|
||||
case HIT_UPPER_CENTER:
|
||||
m_rc.top += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case ACTION_RESIZE_TOP_RIGHT: /* resize at upper right corner */
|
||||
ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
|
||||
ptDeltaUsed.y = min(ptDelta.y, RECT_HEIGHT(m_rcDest) - 1);
|
||||
m_rcDest.top += ptDeltaUsed.y;
|
||||
m_rcDest.right += ptDeltaUsed.x;
|
||||
case HIT_UPPER_RIGHT:
|
||||
m_rc.right += pt.x - m_ptHit.x;
|
||||
m_rc.top += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case ACTION_RESIZE_LEFT: /* resize at left edge */
|
||||
ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
|
||||
ptDeltaUsed.y = ptDelta.y;
|
||||
m_rcDest.left += ptDeltaUsed.x;
|
||||
case HIT_MIDDLE_LEFT:
|
||||
m_rc.left += pt.x - m_ptHit.x;
|
||||
break;
|
||||
case ACTION_RESIZE_RIGHT: /* resize at right edge */
|
||||
ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
|
||||
ptDeltaUsed.y = ptDelta.y;
|
||||
m_rcDest.right += ptDeltaUsed.x;
|
||||
case HIT_MIDDLE_RIGHT:
|
||||
m_rc.right += pt.x - m_ptHit.x;
|
||||
break;
|
||||
case ACTION_RESIZE_BOTTOM_LEFT: /* resize at lower left corner */
|
||||
ptDeltaUsed.x = min(ptDelta.x, RECT_WIDTH(m_rcDest) - 1);
|
||||
ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
|
||||
m_rcDest.left += ptDeltaUsed.x;
|
||||
m_rcDest.bottom += ptDeltaUsed.y;
|
||||
case HIT_LOWER_LEFT:
|
||||
m_rc.left += pt.x - m_ptHit.x;
|
||||
m_rc.bottom += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case ACTION_RESIZE_BOTTOM: /* resize at bottom edge */
|
||||
ptDeltaUsed.x = ptDelta.x;
|
||||
ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
|
||||
m_rcDest.bottom += ptDeltaUsed.y;
|
||||
case HIT_LOWER_CENTER:
|
||||
m_rc.bottom += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case ACTION_RESIZE_BOTTOM_RIGHT: /* resize at lower right corner */
|
||||
ptDeltaUsed.x = max(ptDelta.x, -(RECT_WIDTH(m_rcDest) - 1));
|
||||
ptDeltaUsed.y = max(ptDelta.y, -(RECT_HEIGHT(m_rcDest) - 1));
|
||||
m_rcDest.right += ptDeltaUsed.x;
|
||||
m_rcDest.bottom += ptDeltaUsed.y;
|
||||
case HIT_LOWER_RIGHT:
|
||||
m_rc.right += pt.x - m_ptHit.x;
|
||||
m_rc.bottom += pt.y - m_ptHit.y;
|
||||
break;
|
||||
case HIT_BORDER:
|
||||
case HIT_INNER:
|
||||
OffsetRect(&m_rc, pt.x - m_ptHit.x, pt.y - m_ptHit.y);
|
||||
break;
|
||||
}
|
||||
ptDelta.x -= ptDeltaUsed.x;
|
||||
ptDelta.y -= ptDeltaUsed.y;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectWidth() const
|
||||
{
|
||||
return m_rcDest.right - m_rcDest.left;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectHeight() const
|
||||
{
|
||||
return m_rcDest.bottom - m_rcDest.top;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectLeft() const
|
||||
{
|
||||
return m_rcDest.left;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectTop() const
|
||||
{
|
||||
return m_rcDest.top;
|
||||
m_ptHit = pt;
|
||||
}
|
||||
|
||||
void SelectionModel::NotifyRefreshNeeded()
|
||||
{
|
||||
selectionWindow.SendMessage(WM_SELECTIONMODELREFRESHNEEDED);
|
||||
imageArea.Invalidate(FALSE);
|
||||
}
|
||||
|
||||
void SelectionModel::GetRect(LPRECT prc) const
|
||||
void SelectionModel::ClearMask()
|
||||
{
|
||||
*prc = m_rcDest;
|
||||
if (m_hbmMask)
|
||||
{
|
||||
::DeleteObject(m_hbmMask);
|
||||
m_hbmMask = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionModel::ClearColor()
|
||||
{
|
||||
if (m_hbmColor)
|
||||
{
|
||||
::DeleteObject(m_hbmColor);
|
||||
m_hbmColor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void SelectionModel::CancelSelection()
|
||||
{
|
||||
if (!m_bShow)
|
||||
return;
|
||||
|
||||
imageModel.CopyPrevious();
|
||||
if (m_bShow)
|
||||
imageModel.Undo(TRUE);
|
||||
|
||||
m_bShow = FALSE;
|
||||
imageArea.Invalidate(FALSE);
|
||||
}
|
||||
|
|
|
@ -9,66 +9,54 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
/* DEFINES **********************************************************/
|
||||
|
||||
#define ACTION_MOVE 0
|
||||
#define ACTION_RESIZE_TOP_LEFT 1
|
||||
#define ACTION_RESIZE_TOP 2
|
||||
#define ACTION_RESIZE_TOP_RIGHT 3
|
||||
#define ACTION_RESIZE_LEFT 4
|
||||
#define ACTION_RESIZE_RIGHT 5
|
||||
#define ACTION_RESIZE_BOTTOM_LEFT 6
|
||||
#define ACTION_RESIZE_BOTTOM 7
|
||||
#define ACTION_RESIZE_BOTTOM_RIGHT 8
|
||||
|
||||
/* CLASSES **********************************************************/
|
||||
|
||||
class SelectionModel
|
||||
{
|
||||
private:
|
||||
HDC m_hDC;
|
||||
RECT m_rcSrc;
|
||||
RECT m_rcDest;
|
||||
HBITMAP m_hBm;
|
||||
HBITMAP m_hMask;
|
||||
HBITMAP m_hbmColor;
|
||||
HBITMAP m_hbmMask;
|
||||
POINT *m_ptStack;
|
||||
int m_iPtSP;
|
||||
|
||||
// void NotifySelectionChanging();
|
||||
// void NotifySelectionChanged();
|
||||
void NotifyRefreshNeeded();
|
||||
|
||||
public:
|
||||
BOOL m_bShow;
|
||||
CRect m_rc; // in image pixel coordinates
|
||||
POINT m_ptHit; // in image pixel coordinates
|
||||
|
||||
SelectionModel();
|
||||
~SelectionModel();
|
||||
|
||||
void ResetPtStack();
|
||||
void PushToPtStack(LONG x, LONG y);
|
||||
void CalculateBoundingBoxAndContents(HDC hDCImage);
|
||||
void CalculateContents(HDC hDCImage);
|
||||
void PushToPtStack(POINT pt);
|
||||
int PtStackSize() const;
|
||||
void SetRectFromPoints(const POINT& ptFrom, const POINT& ptTo);
|
||||
void BuildMaskFromPtStack();
|
||||
|
||||
BOOL TakeOff();
|
||||
void Landing();
|
||||
|
||||
HBITMAP GetBitmap() const;
|
||||
void GetSelectionContents(HDC hDCImage);
|
||||
void DrawFramePoly(HDC hDCImage);
|
||||
void DrawBackgroundPoly(HDC hDCImage, COLORREF crBg);
|
||||
void DrawBackgroundRect(HDC hDCImage, COLORREF crBg);
|
||||
void DrawSelection(HDC hDCImage, COLORREF crBg = 0, BOOL bBgTransparent = FALSE);
|
||||
void DrawSelectionStretched(HDC hDCImage);
|
||||
void ScaleContentsToFit();
|
||||
void DrawSelection(HDC hDCImage, LPCRECT prc, COLORREF crBg = 0, BOOL bBgTransparent = FALSE);
|
||||
void InsertFromHBITMAP(HBITMAP hBm, INT x = 0, INT y = 0);
|
||||
|
||||
// operation
|
||||
void FlipHorizontally();
|
||||
void FlipVertically();
|
||||
void RotateNTimes90Degrees(int iN);
|
||||
void StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX = 0, int nSkewDegY = 0);
|
||||
HBITMAP GetBitmap() const;
|
||||
int PtStackSize() const;
|
||||
void DrawFramePoly(HDC hDCImage);
|
||||
void SetSrcAndDestRectFromPoints(const POINT& ptFrom, const POINT& ptTo);
|
||||
void SetSrcRectSizeToZero();
|
||||
BOOL IsSrcRectSizeNonzero() const;
|
||||
void ModifyDestRect(POINT& ptDelta, int iAction);
|
||||
LONG GetDestRectWidth() const;
|
||||
LONG GetDestRectHeight() const;
|
||||
LONG GetDestRectLeft() const;
|
||||
LONG GetDestRectTop() const;
|
||||
void GetRect(LPRECT prc) const;
|
||||
void StretchSkew(int nStretchPercentX, int nStretchPercentY, int nSkewDegX, int nSkewDegY);
|
||||
|
||||
void CancelSelection();
|
||||
void NotifyRefreshNeeded();
|
||||
void Dragging(CANVAS_HITTEST hit, POINT pt);
|
||||
void ClearMask();
|
||||
void ClearColor();
|
||||
|
||||
private:
|
||||
SelectionModel(const SelectionModel&);
|
||||
SelectionModel& operator=(const SelectionModel&);
|
||||
|
||||
void ShiftPtStack(BOOL bPlus);
|
||||
};
|
||||
|
|
|
@ -114,7 +114,7 @@ LRESULT CToolBox::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHand
|
|||
|
||||
LRESULT CToolBox::OnToolsModelToolChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
selectionModel.m_bShow = FALSE;
|
||||
toolsModel.resetTool(); // resets the point-buffer of the polygon and bezier functions
|
||||
|
||||
// Check the toolbar button
|
||||
|
|
|
@ -141,8 +141,8 @@ void ToolsModel::SetBackgroundTransparent(BOOL bTransparent)
|
|||
{
|
||||
m_transpBg = bTransparent;
|
||||
NotifyToolSettingsChanged();
|
||||
if (selectionWindow.IsWindow())
|
||||
selectionWindow.ForceRefreshSelectionContents();
|
||||
if (imageArea.IsWindow())
|
||||
imageArea.Invalidate(FALSE);
|
||||
}
|
||||
|
||||
int ToolsModel::GetZoom() const
|
||||
|
@ -172,8 +172,6 @@ void ToolsModel::NotifyToolSettingsChanged()
|
|||
{
|
||||
if (toolSettingsWindow.IsWindow())
|
||||
toolSettingsWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
|
||||
if (selectionWindow.IsWindow())
|
||||
selectionWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
|
||||
if (textEditWindow.IsWindow())
|
||||
textEditWindow.SendMessage(WM_TOOLSMODELSETTINGSCHANGED);
|
||||
}
|
||||
|
@ -184,8 +182,8 @@ void ToolsModel::NotifyZoomChanged()
|
|||
toolSettingsWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
|
||||
if (textEditWindow.IsWindow())
|
||||
textEditWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
|
||||
if (selectionWindow.IsWindow())
|
||||
selectionWindow.SendMessage(WM_TOOLSMODELZOOMCHANGED);
|
||||
if (imageArea.IsWindow())
|
||||
imageArea.SendMessage(WM_TOOLSMODELZOOMCHANGED);
|
||||
}
|
||||
|
||||
void ToolsModel::OnButtonDown(BOOL bLeftButton, LONG x, LONG y, BOOL bDoubleClick)
|
||||
|
|
|
@ -132,3 +132,31 @@ static inline int UnZoomed(int xy)
|
|||
{
|
||||
return xy * 1000 / toolsModel.GetZoom();
|
||||
}
|
||||
|
||||
static inline void Zoomed(POINT& pt)
|
||||
{
|
||||
pt.x = Zoomed(pt.x);
|
||||
pt.y = Zoomed(pt.y);
|
||||
}
|
||||
|
||||
static inline void Zoomed(RECT& rc)
|
||||
{
|
||||
rc.left = Zoomed(rc.left);
|
||||
rc.top = Zoomed(rc.top);
|
||||
rc.right = Zoomed(rc.right);
|
||||
rc.bottom = Zoomed(rc.bottom);
|
||||
}
|
||||
|
||||
static inline void UnZoomed(POINT& pt)
|
||||
{
|
||||
pt.x = UnZoomed(pt.x);
|
||||
pt.y = UnZoomed(pt.y);
|
||||
}
|
||||
|
||||
static inline void UnZoomed(RECT& rc)
|
||||
{
|
||||
rc.left = UnZoomed(rc.left);
|
||||
rc.top = UnZoomed(rc.top);
|
||||
rc.right = UnZoomed(rc.right);
|
||||
rc.bottom = UnZoomed(rc.bottom);
|
||||
}
|
||||
|
|
|
@ -182,11 +182,9 @@ void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND window)
|
|||
toolBoxContainer.SendMessage(WM_COMMAND, ID_RECTSEL);
|
||||
|
||||
imageModel.CopyPrevious();
|
||||
selectionModel.InsertFromHBITMAP(bitmap);
|
||||
|
||||
placeSelWin();
|
||||
selectionWindow.ShowWindow(SW_SHOW);
|
||||
selectionWindow.ForceRefreshSelectionContents();
|
||||
selectionModel.InsertFromHBITMAP(bitmap, 0, 0);
|
||||
selectionModel.m_bShow = TRUE;
|
||||
imageArea.Invalidate(FALSE);
|
||||
}
|
||||
|
||||
LRESULT CMainWindow::OnMouseWheel(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
|
@ -279,9 +277,6 @@ LRESULT CMainWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHa
|
|||
// Creating the window inside the canvas
|
||||
imageArea.Create(canvasWindow, rcEmpty, NULL, WS_CHILD | WS_VISIBLE);
|
||||
|
||||
// Create selection window (initially hidden)
|
||||
selectionWindow.Create(imageArea, rcEmpty, NULL, WS_CHILD | BS_OWNERDRAW);
|
||||
|
||||
// Create and show the miniature if necessary
|
||||
if (registrySettings.ShowThumbnail)
|
||||
{
|
||||
|
@ -407,7 +402,7 @@ LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam, LPARAM lParam, BO
|
|||
{
|
||||
HMENU menu = (HMENU)wParam;
|
||||
BOOL trueSelection =
|
||||
(::IsWindowVisible(selectionWindow) &&
|
||||
(selectionModel.m_bShow &&
|
||||
((toolsModel.GetActiveTool() == TOOL_FREESEL) || (toolsModel.GetActiveTool() == TOOL_RECTSEL)));
|
||||
|
||||
switch (lParam)
|
||||
|
@ -438,7 +433,7 @@ LRESULT CMainWindow::OnInitMenuPopup(UINT nMsg, WPARAM wParam, LPARAM lParam, BO
|
|||
CheckMenuItem(menu, IDM_VIEWSHOWMINIATURE, CHECKED_IF(registrySettings.ShowThumbnail));
|
||||
break;
|
||||
case 3: /* Image menu */
|
||||
EnableMenuItem(menu, IDM_IMAGECROP, ENABLED_IF(::IsWindowVisible(selectionWindow)));
|
||||
EnableMenuItem(menu, IDM_IMAGECROP, ENABLED_IF(selectionModel.m_bShow));
|
||||
CheckMenuItem(menu, IDM_IMAGEDRAWOPAQUE, CHECKED_IF(!toolsModel.IsBackgroundTransparent()));
|
||||
break;
|
||||
}
|
||||
|
@ -484,7 +479,6 @@ LRESULT CMainWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
if (hwndCapture)
|
||||
{
|
||||
if (canvasWindow.m_hWnd == hwndCapture ||
|
||||
selectionWindow.m_hWnd == hwndCapture ||
|
||||
imageArea.m_hWnd == hwndCapture ||
|
||||
fullscreenWindow.m_hWnd == hwndCapture)
|
||||
{
|
||||
|
@ -610,7 +604,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
case IDM_EDITUNDO:
|
||||
if (toolsModel.GetActiveTool() == TOOL_TEXT && ::IsWindowVisible(textEditWindow))
|
||||
break;
|
||||
if (selectionWindow.IsWindowVisible())
|
||||
if (selectionModel.m_bShow)
|
||||
{
|
||||
if (toolsModel.GetActiveTool() == TOOL_RECTSEL ||
|
||||
toolsModel.GetActiveTool() == TOOL_FREESEL)
|
||||
|
@ -736,31 +730,31 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
switch (mirrorRotateDialog.DoModal(mainWindow.m_hWnd))
|
||||
{
|
||||
case 1: /* flip horizontally */
|
||||
if (::IsWindowVisible(selectionWindow))
|
||||
if (selectionModel.m_bShow)
|
||||
selectionModel.FlipHorizontally();
|
||||
else
|
||||
imageModel.FlipHorizontally();
|
||||
break;
|
||||
case 2: /* flip vertically */
|
||||
if (::IsWindowVisible(selectionWindow))
|
||||
if (selectionModel.m_bShow)
|
||||
selectionModel.FlipVertically();
|
||||
else
|
||||
imageModel.FlipVertically();
|
||||
break;
|
||||
case 3: /* rotate 90 degrees */
|
||||
if (::IsWindowVisible(selectionWindow))
|
||||
if (selectionModel.m_bShow)
|
||||
selectionModel.RotateNTimes90Degrees(1);
|
||||
else
|
||||
imageModel.RotateNTimes90Degrees(1);
|
||||
break;
|
||||
case 4: /* rotate 180 degrees */
|
||||
if (::IsWindowVisible(selectionWindow))
|
||||
if (selectionModel.m_bShow)
|
||||
selectionModel.RotateNTimes90Degrees(2);
|
||||
else
|
||||
imageModel.RotateNTimes90Degrees(2);
|
||||
break;
|
||||
case 5: /* rotate 270 degrees */
|
||||
if (::IsWindowVisible(selectionWindow))
|
||||
if (selectionModel.m_bShow)
|
||||
selectionModel.RotateNTimes90Degrees(3);
|
||||
else
|
||||
imageModel.RotateNTimes90Degrees(3);
|
||||
|
@ -779,7 +773,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
{
|
||||
if (stretchSkewDialog.DoModal(mainWindow.m_hWnd))
|
||||
{
|
||||
if (::IsWindowVisible(selectionWindow))
|
||||
if (selectionModel.m_bShow)
|
||||
{
|
||||
selectionModel.StretchSkew(stretchSkewDialog.percentage.x, stretchSkewDialog.percentage.y,
|
||||
stretchSkewDialog.angle.x, stretchSkewDialog.angle.y);
|
||||
|
|
Loading…
Reference in a new issue