mirror of
https://github.com/reactos/reactos.git
synced 2025-04-27 09:00:27 +00:00
[MSPAINT_NEW] refactoring: move selection management to a dedicated SelectionModel (WIP)
svn path=/trunk/; revision=68382
This commit is contained in:
parent
b0451457d7
commit
3116acb259
10 changed files with 528 additions and 335 deletions
|
@ -18,6 +18,7 @@ list(APPEND SOURCE
|
|||
registry.cpp
|
||||
scrollbox.cpp
|
||||
selection.cpp
|
||||
selectionmodel.cpp
|
||||
sizebox.cpp
|
||||
textedit.cpp
|
||||
toolbox.cpp
|
||||
|
|
|
@ -21,7 +21,6 @@ typedef struct tagSTRETCHSKEW {
|
|||
/* VARIABLES declared in main.c *************************************/
|
||||
|
||||
extern HDC hDrawingDC;
|
||||
extern HDC hSelDC;
|
||||
extern int *bmAddress;
|
||||
extern BITMAPINFO bitmapinfo;
|
||||
|
||||
|
@ -39,10 +38,9 @@ extern POINT last;
|
|||
class ToolsModel;
|
||||
extern ToolsModel toolsModel;
|
||||
|
||||
extern RECT rectSel_src;
|
||||
extern RECT rectSel_dest;
|
||||
extern HBITMAP hSelBm;
|
||||
extern HBITMAP hSelMask;
|
||||
class SelectionModel;
|
||||
extern SelectionModel selectionModel;
|
||||
|
||||
extern HWND hwndEditCtl;
|
||||
extern LOGFONT lfTextFont;
|
||||
extern HFONT hfontTextFont;
|
||||
|
@ -114,5 +112,3 @@ extern CTextEditWindow textEditWindow;
|
|||
|
||||
extern POINT pointStack[256];
|
||||
extern short pointSP;
|
||||
extern POINT *ptStack;
|
||||
extern int ptSP;
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
HDC hDrawingDC;
|
||||
HDC hSelDC;
|
||||
int *bmAddress;
|
||||
BITMAPINFO bitmapinfo;
|
||||
int imgXRes = 400;
|
||||
|
@ -31,10 +30,8 @@ POINT last;
|
|||
|
||||
ToolsModel toolsModel;
|
||||
|
||||
RECT rectSel_src;
|
||||
RECT rectSel_dest;
|
||||
HBITMAP hSelBm;
|
||||
HBITMAP hSelMask;
|
||||
SelectionModel selectionModel;
|
||||
|
||||
LOGFONT lfTextFont;
|
||||
HFONT hfontTextFont;
|
||||
HWND hwndEditCtl;
|
||||
|
@ -205,7 +202,7 @@ _tWinMain (HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPTSTR lpszArgument
|
|||
|
||||
hDC = imageArea.GetDC();
|
||||
hDrawingDC = CreateCompatibleDC(hDC);
|
||||
hSelDC = CreateCompatibleDC(hDC);
|
||||
selectionModel.SetDC(CreateCompatibleDC(hDC));
|
||||
imageArea.ReleaseDC(hDC);
|
||||
SelectObject(hDrawingDC, CreatePen(PS_SOLID, 0, paletteModel.GetFgColor()));
|
||||
SelectObject(hDrawingDC, CreateSolidBrush(paletteModel.GetBgColor()));
|
||||
|
|
|
@ -15,44 +15,42 @@
|
|||
void
|
||||
placeSelWin()
|
||||
{
|
||||
selectionWindow.MoveWindow(rectSel_dest.left * toolsModel.GetZoom() / 1000, rectSel_dest.top * toolsModel.GetZoom() / 1000,
|
||||
RECT_WIDTH(rectSel_dest) * toolsModel.GetZoom() / 1000 + 6, RECT_HEIGHT(rectSel_dest) * toolsModel.GetZoom() / 1000 + 6, TRUE);
|
||||
selectionWindow.MoveWindow(selectionModel.GetDestRectLeft() * toolsModel.GetZoom() / 1000, selectionModel.GetDestRectTop() * toolsModel.GetZoom() / 1000,
|
||||
selectionModel.GetDestRectWidth() * toolsModel.GetZoom() / 1000 + 6, selectionModel.GetDestRectHeight() * toolsModel.GetZoom() / 1000 + 6, TRUE);
|
||||
selectionWindow.BringWindowToTop();
|
||||
imageArea.InvalidateRect(NULL, FALSE);
|
||||
}
|
||||
|
||||
void
|
||||
regularize(LONG x0, LONG y0, LONG *x1, LONG *y1)
|
||||
regularize(LONG x0, LONG y0, LONG& x1, LONG& y1)
|
||||
{
|
||||
if (abs(*x1 - x0) >= abs(*y1 - y0))
|
||||
*y1 = y0 + (*y1 > y0 ? abs(*x1 - x0) : -abs(*x1 - x0));
|
||||
if (abs(x1 - x0) >= abs(y1 - y0))
|
||||
y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0));
|
||||
else
|
||||
*x1 = x0 + (*x1 > x0 ? abs(*y1 - y0) : -abs(*y1 - y0));
|
||||
x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0));
|
||||
}
|
||||
|
||||
void
|
||||
roundTo8Directions(LONG x0, LONG y0, LONG *x1, LONG *y1)
|
||||
roundTo8Directions(LONG x0, LONG y0, LONG& x1, LONG& y1)
|
||||
{
|
||||
if (abs(*x1 - x0) >= abs(*y1 - y0))
|
||||
if (abs(x1 - x0) >= abs(y1 - y0))
|
||||
{
|
||||
if (abs(*y1 - y0) * 5 < abs(*x1 - x0) * 2)
|
||||
*y1 = y0;
|
||||
if (abs(y1 - y0) * 5 < abs(x1 - x0) * 2)
|
||||
y1 = y0;
|
||||
else
|
||||
*y1 = y0 + (*y1 > y0 ? abs(*x1 - x0) : -abs(*x1 - x0));
|
||||
y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (abs(*x1 - x0) * 5 < abs(*y1 - y0) * 2)
|
||||
*x1 = x0;
|
||||
if (abs(x1 - x0) * 5 < abs(y1 - y0) * 2)
|
||||
x1 = x0;
|
||||
else
|
||||
*x1 = x0 + (*x1 > x0 ? abs(*y1 - y0) : -abs(*y1 - y0));
|
||||
x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0));
|
||||
}
|
||||
}
|
||||
|
||||
POINT pointStack[256];
|
||||
short pointSP;
|
||||
POINT *ptStack = NULL;
|
||||
int ptSP = 0;
|
||||
|
||||
void
|
||||
startPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
||||
|
@ -65,12 +63,8 @@ startPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
{
|
||||
case TOOL_FREESEL:
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
if (ptStack != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, ptStack);
|
||||
ptStack = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * 1024);
|
||||
ptSP = 0;
|
||||
ptStack[0].x = x;
|
||||
ptStack[0].y = y;
|
||||
selectionModel.ResetPtStack();
|
||||
selectionModel.PushToPtStack(x, y);
|
||||
break;
|
||||
case TOOL_LINE:
|
||||
case TOOL_RECT:
|
||||
|
@ -82,8 +76,7 @@ startPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_TEXT:
|
||||
imageModel.CopyPrevious();
|
||||
selectionWindow.ShowWindow(SW_HIDE);
|
||||
rectSel_src.right = rectSel_src.left;
|
||||
rectSel_src.bottom = rectSel_src.top;
|
||||
selectionModel.SetSrcRectSizeToZero();
|
||||
break;
|
||||
case TOOL_RUBBER:
|
||||
imageModel.CopyPrevious();
|
||||
|
@ -134,15 +127,11 @@ whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
switch (toolsModel.GetActiveTool())
|
||||
{
|
||||
case TOOL_FREESEL:
|
||||
if (ptSP == 0)
|
||||
if (selectionModel.PtStackSize() == 1)
|
||||
imageModel.CopyPrevious();
|
||||
ptSP++;
|
||||
if (ptSP % 1024 == 0)
|
||||
ptStack = (POINT*) HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, ptStack, sizeof(POINT) * (ptSP + 1024));
|
||||
ptStack[ptSP].x = max(0, min(x, imageModel.GetWidth()));
|
||||
ptStack[ptSP].y = max(0, min(y, imageModel.GetHeight()));
|
||||
selectionModel.PushToPtStack(max(0, min(x, imageModel.GetWidth())), max(0, min(y, imageModel.GetHeight())));
|
||||
imageModel.ResetToPrevious();
|
||||
Poly(hdc, ptStack, ptSP + 1, 0, 0, 2, 0, FALSE, TRUE); /* draw the freehand selection inverted/xored */
|
||||
selectionModel.DrawFramePoly(hdc);
|
||||
break;
|
||||
case TOOL_RECTSEL:
|
||||
case TOOL_TEXT:
|
||||
|
@ -151,10 +140,7 @@ whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
imageModel.ResetToPrevious();
|
||||
temp.x = max(0, min(x, imageModel.GetWidth()));
|
||||
temp.y = max(0, min(y, imageModel.GetHeight()));
|
||||
rectSel_dest.left = rectSel_src.left = min(start.x, temp.x);
|
||||
rectSel_dest.top = rectSel_src.top = min(start.y, temp.y);
|
||||
rectSel_dest.right = rectSel_src.right = max(start.x, temp.x);
|
||||
rectSel_dest.bottom = rectSel_src.bottom = max(start.y, temp.y);
|
||||
selectionModel.SetSrcAndDestRectFromPoints(start, temp);
|
||||
RectSel(hdc, start.x, start.y, temp.x, temp.y);
|
||||
break;
|
||||
}
|
||||
|
@ -173,7 +159,7 @@ whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_LINE:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
roundTo8Directions(start.x, start.y, &x, &y);
|
||||
roundTo8Directions(start.x, start.y, x, y);
|
||||
Line(hdc, start.x, start.y, x, y, fg, toolsModel.GetLineWidth());
|
||||
break;
|
||||
case TOOL_BEZIER:
|
||||
|
@ -197,7 +183,7 @@ whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_RECT:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
Rect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
case TOOL_SHAPE:
|
||||
|
@ -206,20 +192,20 @@ whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
pointStack[pointSP].y = y;
|
||||
if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
|
||||
roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
|
||||
&pointStack[pointSP].x, &pointStack[pointSP].y);
|
||||
pointStack[pointSP].x, pointStack[pointSP].y);
|
||||
if (pointSP + 1 >= 2)
|
||||
Poly(hdc, pointStack, pointSP + 1, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE);
|
||||
break;
|
||||
case TOOL_ELLIPSE:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
Ellp(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
case TOOL_RRECT:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
RRect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
}
|
||||
|
@ -235,79 +221,30 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
{
|
||||
case TOOL_FREESEL:
|
||||
{
|
||||
POINT *ptStackCopy;
|
||||
int i;
|
||||
rectSel_src.left = rectSel_src.top = MAXLONG;
|
||||
rectSel_src.right = rectSel_src.bottom = 0;
|
||||
for (i = 0; i <= ptSP; i++)
|
||||
selectionModel.CalculateBoundingBoxAndContents(hdc);
|
||||
if (selectionModel.PtStackSize() > 1)
|
||||
{
|
||||
if (ptStack[i].x < rectSel_src.left)
|
||||
rectSel_src.left = ptStack[i].x;
|
||||
if (ptStack[i].y < rectSel_src.top)
|
||||
rectSel_src.top = ptStack[i].y;
|
||||
if (ptStack[i].x > rectSel_src.right)
|
||||
rectSel_src.right = ptStack[i].x;
|
||||
if (ptStack[i].y > rectSel_src.bottom)
|
||||
rectSel_src.bottom = ptStack[i].y;
|
||||
}
|
||||
rectSel_src.right += 1;
|
||||
rectSel_src.bottom += 1;
|
||||
rectSel_dest.left = rectSel_src.left;
|
||||
rectSel_dest.top = rectSel_src.top;
|
||||
rectSel_dest.right = rectSel_src.right;
|
||||
rectSel_dest.bottom = rectSel_src.bottom;
|
||||
if (ptSP != 0)
|
||||
{
|
||||
DeleteObject(hSelMask);
|
||||
hSelMask = CreateBitmap(RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), 1, 1, NULL);
|
||||
DeleteObject(SelectObject(hSelDC, hSelMask));
|
||||
ptStackCopy = (POINT*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, sizeof(POINT) * (ptSP + 1));
|
||||
for (i = 0; i <= ptSP; i++)
|
||||
{
|
||||
ptStackCopy[i].x = ptStack[i].x - rectSel_src.left;
|
||||
ptStackCopy[i].y = ptStack[i].y - rectSel_src.top;
|
||||
}
|
||||
Poly(hSelDC, ptStackCopy, ptSP + 1, 0x00ffffff, 0x00ffffff, 1, 2, TRUE, FALSE);
|
||||
HeapFree(GetProcessHeap(), 0, ptStackCopy);
|
||||
SelectObject(hSelDC, hSelBm = CreateDIBWithProperties(RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src)));
|
||||
imageModel.ResetToPrevious();
|
||||
MaskBlt(hSelDC, 0, 0, RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), hDrawingDC, rectSel_src.left,
|
||||
rectSel_src.top, hSelMask, 0, 0, MAKEROP4(SRCCOPY, WHITENESS));
|
||||
Poly(hdc, ptStack, ptSP + 1, bg, bg, 1, 2, TRUE, FALSE);
|
||||
selectionModel.DrawBackgroundPoly(hdc, bg);
|
||||
imageModel.CopyPrevious();
|
||||
|
||||
MaskBlt(hDrawingDC, rectSel_src.left, rectSel_src.top, RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), hSelDC, 0,
|
||||
0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
|
||||
selectionModel.DrawSelection(hdc);
|
||||
|
||||
placeSelWin();
|
||||
selectionWindow.ShowWindow(SW_SHOW);
|
||||
/* force refresh of selection contents */
|
||||
selectionWindow.SendMessage(WM_LBUTTONDOWN, 0, 0);
|
||||
selectionWindow.SendMessage(WM_MOUSEMOVE, 0, 0);
|
||||
selectionWindow.SendMessage(WM_LBUTTONUP, 0, 0);
|
||||
ForceRefreshSelectionContents();
|
||||
}
|
||||
HeapFree(GetProcessHeap(), 0, ptStack);
|
||||
ptStack = NULL;
|
||||
selectionModel.ResetPtStack();
|
||||
break;
|
||||
}
|
||||
case TOOL_RECTSEL:
|
||||
imageModel.ResetToPrevious();
|
||||
if ((RECT_WIDTH(rectSel_src) != 0) && (RECT_HEIGHT(rectSel_src) != 0))
|
||||
if (selectionModel.IsSrcRectSizeNonzero())
|
||||
{
|
||||
DeleteObject(hSelMask);
|
||||
hSelMask = CreateBitmap(RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), 1, 1, NULL);
|
||||
DeleteObject(SelectObject(hSelDC, hSelMask));
|
||||
Rect(hSelDC, 0, 0, RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), 0x00ffffff, 0x00ffffff, 1, 2);
|
||||
SelectObject(hSelDC, hSelBm = CreateDIBWithProperties(RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src)));
|
||||
imageModel.ResetToPrevious();
|
||||
BitBlt(hSelDC, 0, 0, RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), hDrawingDC, rectSel_src.left,
|
||||
rectSel_src.top, SRCCOPY);
|
||||
Rect(hdc, rectSel_src.left, rectSel_src.top, rectSel_src.right,
|
||||
rectSel_src.bottom, bg, bg, 0, TRUE);
|
||||
selectionModel.CalculateContents(hdc);
|
||||
selectionModel.DrawBackgroundRect(hdc, bg);
|
||||
imageModel.CopyPrevious();
|
||||
|
||||
BitBlt(hDrawingDC, rectSel_src.left, rectSel_src.top, RECT_WIDTH(rectSel_src), RECT_HEIGHT(rectSel_src), hSelDC, 0,
|
||||
0, SRCCOPY);
|
||||
selectionModel.DrawSelection(hdc);
|
||||
|
||||
placeSelWin();
|
||||
selectionWindow.ShowWindow(SW_SHOW);
|
||||
|
@ -316,7 +253,7 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
break;
|
||||
case TOOL_TEXT:
|
||||
imageModel.ResetToPrevious();
|
||||
if ((RECT_WIDTH(rectSel_src) != 0) && (RECT_HEIGHT(rectSel_src) != 0))
|
||||
if (selectionModel.IsSrcRectSizeNonzero())
|
||||
{
|
||||
imageModel.CopyPrevious();
|
||||
|
||||
|
@ -335,7 +272,7 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_LINE:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
roundTo8Directions(start.x, start.y, &x, &y);
|
||||
roundTo8Directions(start.x, start.y, x, y);
|
||||
Line(hdc, start.x, start.y, x, y, fg, toolsModel.GetLineWidth());
|
||||
break;
|
||||
case TOOL_BEZIER:
|
||||
|
@ -346,7 +283,7 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_RECT:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
Rect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
case TOOL_SHAPE:
|
||||
|
@ -355,7 +292,7 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
pointStack[pointSP].y = y;
|
||||
if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
|
||||
roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
|
||||
&pointStack[pointSP].x, &pointStack[pointSP].y);
|
||||
pointStack[pointSP].x, pointStack[pointSP].y);
|
||||
pointSP++;
|
||||
if (pointSP >= 2)
|
||||
{
|
||||
|
@ -376,13 +313,13 @@ endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_ELLIPSE:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
Ellp(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
case TOOL_RRECT:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
RRect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
}
|
||||
|
@ -468,7 +405,7 @@ whilePaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_LINE:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
roundTo8Directions(start.x, start.y, &x, &y);
|
||||
roundTo8Directions(start.x, start.y, x, y);
|
||||
Line(hdc, start.x, start.y, x, y, bg, toolsModel.GetLineWidth());
|
||||
break;
|
||||
case TOOL_BEZIER:
|
||||
|
@ -492,7 +429,7 @@ whilePaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_RECT:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
Rect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
case TOOL_SHAPE:
|
||||
|
@ -501,20 +438,20 @@ whilePaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
pointStack[pointSP].y = y;
|
||||
if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
|
||||
roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
|
||||
&pointStack[pointSP].x, &pointStack[pointSP].y);
|
||||
pointStack[pointSP].x, pointStack[pointSP].y);
|
||||
if (pointSP + 1 >= 2)
|
||||
Poly(hdc, pointStack, pointSP + 1, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE);
|
||||
break;
|
||||
case TOOL_ELLIPSE:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
Ellp(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
case TOOL_RRECT:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
RRect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
}
|
||||
|
@ -538,7 +475,7 @@ endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_LINE:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
roundTo8Directions(start.x, start.y, &x, &y);
|
||||
roundTo8Directions(start.x, start.y, x, y);
|
||||
Line(hdc, start.x, start.y, x, y, bg, toolsModel.GetLineWidth());
|
||||
break;
|
||||
case TOOL_BEZIER:
|
||||
|
@ -549,7 +486,7 @@ endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_RECT:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
Rect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
case TOOL_SHAPE:
|
||||
|
@ -558,7 +495,7 @@ endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
pointStack[pointSP].y = y;
|
||||
if ((pointSP > 0) && (GetAsyncKeyState(VK_SHIFT) < 0))
|
||||
roundTo8Directions(pointStack[pointSP - 1].x, pointStack[pointSP - 1].y,
|
||||
&pointStack[pointSP].x, &pointStack[pointSP].y);
|
||||
pointStack[pointSP].x, pointStack[pointSP].y);
|
||||
pointSP++;
|
||||
if (pointSP >= 2)
|
||||
{
|
||||
|
@ -579,13 +516,13 @@ endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg)
|
|||
case TOOL_ELLIPSE:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
Ellp(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
case TOOL_RRECT:
|
||||
imageModel.ResetToPrevious();
|
||||
if (GetAsyncKeyState(VK_SHIFT) < 0)
|
||||
regularize(start.x, start.y, &x, &y);
|
||||
regularize(start.x, start.y, x, y);
|
||||
RRect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle());
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "palettemodel.h"
|
||||
#include "scrollbox.h"
|
||||
#include "selection.h"
|
||||
#include "selectionmodel.h"
|
||||
#include "sizebox.h"
|
||||
#include "textedit.h"
|
||||
#include "toolbox.h"
|
||||
|
|
|
@ -10,21 +10,9 @@
|
|||
|
||||
#include "precomp.h"
|
||||
|
||||
/* 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
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
LPCTSTR cursors[9] = { /* action to mouse cursor lookup table */
|
||||
const LPCTSTR CSelectionWindow::m_lpszCursorLUT[9] = { /* action to mouse cursor lookup table */
|
||||
IDC_SIZEALL,
|
||||
|
||||
IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW,
|
||||
|
@ -32,13 +20,6 @@ LPCTSTR cursors[9] = { /* action to mouse cursor lookup table */
|
|||
IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE
|
||||
};
|
||||
|
||||
BOOL moving = FALSE;
|
||||
int action = ACTION_MOVE;
|
||||
POINTS pos;
|
||||
POINTS frac;
|
||||
POINT delta;
|
||||
DWORD system_selection_color;
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -81,32 +62,31 @@ ForceRefreshSelectionContents()
|
|||
}
|
||||
}
|
||||
|
||||
int
|
||||
identifyCorner(short x, short y, short w, short h)
|
||||
int CSelectionWindow::IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight)
|
||||
{
|
||||
if (y < 3)
|
||||
if (iYPos < 3)
|
||||
{
|
||||
if (x < 3)
|
||||
if (iXPos < 3)
|
||||
return ACTION_RESIZE_TOP_LEFT;
|
||||
if ((x < w / 2 + 2) && (x >= w / 2 - 1))
|
||||
if ((iXPos < iWidth / 2 + 2) && (iXPos >= iWidth / 2 - 1))
|
||||
return ACTION_RESIZE_TOP;
|
||||
if (x >= w - 3)
|
||||
if (iXPos >= iWidth - 3)
|
||||
return ACTION_RESIZE_TOP_RIGHT;
|
||||
}
|
||||
if ((y < h / 2 + 2) && (y >= h / 2 - 1))
|
||||
if ((iYPos < iHeight / 2 + 2) && (iYPos >= iHeight / 2 - 1))
|
||||
{
|
||||
if (x < 3)
|
||||
if (iXPos < 3)
|
||||
return ACTION_RESIZE_LEFT;
|
||||
if (x >= w - 3)
|
||||
if (iXPos >= iWidth - 3)
|
||||
return ACTION_RESIZE_RIGHT;
|
||||
}
|
||||
if (y >= h - 3)
|
||||
if (iYPos >= iHeight - 3)
|
||||
{
|
||||
if (x < 3)
|
||||
if (iXPos < 3)
|
||||
return ACTION_RESIZE_BOTTOM_LEFT;
|
||||
if ((x < w / 2 + 2) && (x >= w / 2 - 1))
|
||||
if ((iXPos < iWidth / 2 + 2) && (iXPos >= iWidth / 2 - 1))
|
||||
return ACTION_RESIZE_BOTTOM;
|
||||
if (x >= w - 3)
|
||||
if (iXPos >= iWidth - 3)
|
||||
return ACTION_RESIZE_BOTTOM_RIGHT;
|
||||
}
|
||||
return 0;
|
||||
|
@ -114,13 +94,13 @@ identifyCorner(short x, short y, short w, short h)
|
|||
|
||||
LRESULT CSelectionWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (!moving)
|
||||
if (!m_bMoving)
|
||||
{
|
||||
HDC hDC = GetDC();
|
||||
DefWindowProc(WM_PAINT, wParam, lParam);
|
||||
SelectionFrame(hDC, 1, 1, RECT_WIDTH(rectSel_dest) * toolsModel.GetZoom() / 1000 + 5,
|
||||
RECT_HEIGHT(rectSel_dest) * toolsModel.GetZoom() / 1000 + 5,
|
||||
system_selection_color);
|
||||
SelectionFrame(hDC, 1, 1, selectionModel.GetDestRectWidth() * toolsModel.GetZoom() / 1000 + 5,
|
||||
selectionModel.GetDestRectHeight() * toolsModel.GetZoom() / 1000 + 5,
|
||||
m_dwSystemSelectionColor);
|
||||
ReleaseDC(hDC);
|
||||
}
|
||||
return 0;
|
||||
|
@ -134,8 +114,10 @@ LRESULT CSelectionWindow::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam,
|
|||
|
||||
LRESULT CSelectionWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
m_bMoving = FALSE;
|
||||
m_iAction = ACTION_MOVE;
|
||||
/* update the system selection color */
|
||||
system_selection_color = GetSysColor(COLOR_HIGHLIGHT);
|
||||
m_dwSystemSelectionColor = GetSysColor(COLOR_HIGHLIGHT);
|
||||
SendMessage(WM_PAINT, 0, MAKELPARAM(0, 0));
|
||||
return 0;
|
||||
}
|
||||
|
@ -143,7 +125,7 @@ LRESULT CSelectionWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL
|
|||
LRESULT CSelectionWindow::OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
/* update the system selection color */
|
||||
system_selection_color = GetSysColor(COLOR_HIGHLIGHT);
|
||||
m_dwSystemSelectionColor = GetSysColor(COLOR_HIGHLIGHT);
|
||||
SendMessage(WM_PAINT, 0, MAKELPARAM(0, 0));
|
||||
return 0;
|
||||
}
|
||||
|
@ -156,14 +138,14 @@ LRESULT CSelectionWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, B
|
|||
|
||||
LRESULT CSelectionWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
pos.x = GET_X_LPARAM(lParam);
|
||||
pos.y = GET_Y_LPARAM(lParam);
|
||||
delta.x = 0;
|
||||
delta.y = 0;
|
||||
m_ptPos.x = GET_X_LPARAM(lParam);
|
||||
m_ptPos.y = GET_Y_LPARAM(lParam);
|
||||
m_ptDelta.x = 0;
|
||||
m_ptDelta.y = 0;
|
||||
SetCapture();
|
||||
if (action != ACTION_MOVE)
|
||||
SetCursor(LoadCursor(NULL, cursors[action]));
|
||||
moving = TRUE;
|
||||
if (m_iAction != ACTION_MOVE)
|
||||
SetCursor(LoadCursor(NULL, m_lpszCursorLUT[m_iAction]));
|
||||
m_bMoving = TRUE;
|
||||
scrlClientWindow.InvalidateRect(NULL, TRUE);
|
||||
imageArea.SendMessage(WM_PAINT, 0, 0);
|
||||
return 0;
|
||||
|
@ -171,127 +153,66 @@ LRESULT CSelectionWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam,
|
|||
|
||||
LRESULT CSelectionWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (moving)
|
||||
if (m_bMoving)
|
||||
{
|
||||
TCHAR sizeStr[100];
|
||||
POINT deltaUsed;
|
||||
imageModel.ResetToPrevious();
|
||||
frac.x += GET_X_LPARAM(lParam) - pos.x;
|
||||
frac.y += GET_Y_LPARAM(lParam) - pos.y;
|
||||
delta.x += frac.x * 1000 / toolsModel.GetZoom();
|
||||
delta.y += frac.y * 1000 / toolsModel.GetZoom();
|
||||
m_ptFrac.x += GET_X_LPARAM(lParam) - m_ptPos.x;
|
||||
m_ptFrac.y += GET_Y_LPARAM(lParam) - m_ptPos.y;
|
||||
m_ptDelta.x += m_ptFrac.x * 1000 / toolsModel.GetZoom();
|
||||
m_ptDelta.y += m_ptFrac.y * 1000 / toolsModel.GetZoom();
|
||||
if (toolsModel.GetZoom() < 1000)
|
||||
{
|
||||
frac.x = 0;
|
||||
frac.y = 0;
|
||||
m_ptFrac.x = 0;
|
||||
m_ptFrac.y = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
frac.x -= (frac.x * 1000 / toolsModel.GetZoom()) * toolsModel.GetZoom() / 1000;
|
||||
frac.y -= (frac.y * 1000 / toolsModel.GetZoom()) * toolsModel.GetZoom() / 1000;
|
||||
m_ptFrac.x -= (m_ptFrac.x * 1000 / toolsModel.GetZoom()) * toolsModel.GetZoom() / 1000;
|
||||
m_ptFrac.y -= (m_ptFrac.y * 1000 / toolsModel.GetZoom()) * toolsModel.GetZoom() / 1000;
|
||||
}
|
||||
switch (action)
|
||||
{
|
||||
case ACTION_MOVE: /* move selection */
|
||||
deltaUsed.x = delta.x;
|
||||
deltaUsed.y = delta.y;
|
||||
OffsetRect(&rectSel_dest, deltaUsed.x, deltaUsed.y);
|
||||
break;
|
||||
case ACTION_RESIZE_TOP_LEFT: /* resize at upper left corner */
|
||||
deltaUsed.x = min(delta.x, RECT_WIDTH(rectSel_dest) - 1);
|
||||
deltaUsed.y = min(delta.y, RECT_HEIGHT(rectSel_dest) - 1);
|
||||
rectSel_dest.left += deltaUsed.x;
|
||||
rectSel_dest.top += deltaUsed.y;
|
||||
break;
|
||||
case ACTION_RESIZE_TOP: /* resize at top edge */
|
||||
deltaUsed.x = delta.x;
|
||||
deltaUsed.y = min(delta.y, RECT_HEIGHT(rectSel_dest) - 1);
|
||||
rectSel_dest.top += deltaUsed.y;
|
||||
break;
|
||||
case ACTION_RESIZE_TOP_RIGHT: /* resize at upper right corner */
|
||||
deltaUsed.x = max(delta.x, -(RECT_WIDTH(rectSel_dest) - 1));
|
||||
deltaUsed.y = min(delta.y, RECT_HEIGHT(rectSel_dest) - 1);
|
||||
rectSel_dest.top += deltaUsed.y;
|
||||
rectSel_dest.right += deltaUsed.x;
|
||||
break;
|
||||
case ACTION_RESIZE_LEFT: /* resize at left edge */
|
||||
deltaUsed.x = min(delta.x, RECT_WIDTH(rectSel_dest) - 1);
|
||||
deltaUsed.y = delta.y;
|
||||
rectSel_dest.left += deltaUsed.x;
|
||||
break;
|
||||
case ACTION_RESIZE_RIGHT: /* resize at right edge */
|
||||
deltaUsed.x = max(delta.x, -(RECT_WIDTH(rectSel_dest) - 1));
|
||||
deltaUsed.y = delta.y;
|
||||
rectSel_dest.right += deltaUsed.x;
|
||||
break;
|
||||
case ACTION_RESIZE_BOTTOM_LEFT: /* resize at lower left corner */
|
||||
deltaUsed.x = min(delta.x, RECT_WIDTH(rectSel_dest) - 1);
|
||||
deltaUsed.y = max(delta.y, -(RECT_HEIGHT(rectSel_dest) - 1));
|
||||
rectSel_dest.left += deltaUsed.x;
|
||||
rectSel_dest.bottom += deltaUsed.y;
|
||||
break;
|
||||
case ACTION_RESIZE_BOTTOM: /* resize at bottom edge */
|
||||
deltaUsed.x = delta.x;
|
||||
deltaUsed.y = max(delta.y, -(RECT_HEIGHT(rectSel_dest) - 1));
|
||||
rectSel_dest.bottom += deltaUsed.y;
|
||||
break;
|
||||
case ACTION_RESIZE_BOTTOM_RIGHT: /* resize at lower right corner */
|
||||
deltaUsed.x = max(delta.x, -(RECT_WIDTH(rectSel_dest) - 1));
|
||||
deltaUsed.y = max(delta.y, -(RECT_HEIGHT(rectSel_dest) - 1));
|
||||
rectSel_dest.right += deltaUsed.x;
|
||||
rectSel_dest.bottom += deltaUsed.y;
|
||||
break;
|
||||
}
|
||||
delta.x -= deltaUsed.x;
|
||||
delta.y -= deltaUsed.y;
|
||||
selectionModel.ModifyDestRect(m_ptDelta, m_iAction);
|
||||
|
||||
_stprintf(sizeStr, _T("%d x %d"), RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest));
|
||||
_stprintf(sizeStr, _T("%d x %d"), selectionModel.GetDestRectWidth(), selectionModel.GetDestRectHeight());
|
||||
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr);
|
||||
|
||||
if (toolsModel.GetActiveTool() == TOOL_TEXT)
|
||||
{
|
||||
Text(hDrawingDC, rectSel_dest.left, rectSel_dest.top, rectSel_dest.right, rectSel_dest.bottom, paletteModel.GetFgColor(), paletteModel.GetBgColor(), textToolText, hfontTextFont, toolsModel.IsBackgroundTransparent());
|
||||
selectionModel.DrawTextToolText(hDrawingDC, paletteModel.GetFgColor(), paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
|
||||
}
|
||||
else
|
||||
{
|
||||
if (action != ACTION_MOVE)
|
||||
StretchBlt(hDrawingDC, rectSel_dest.left, rectSel_dest.top, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), hSelDC, 0, 0, GetDIBWidth(hSelBm), GetDIBHeight(hSelBm), SRCCOPY);
|
||||
if (m_iAction != ACTION_MOVE)
|
||||
selectionModel.DrawSelectionStretched(hDrawingDC);
|
||||
else
|
||||
if (toolsModel.IsBackgroundTransparent() == 0)
|
||||
MaskBlt(hDrawingDC, rectSel_dest.left, rectSel_dest.top, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest),
|
||||
hSelDC, 0, 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
|
||||
else
|
||||
{
|
||||
ColorKeyedMaskBlt(hDrawingDC, rectSel_dest.left, rectSel_dest.top, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest),
|
||||
hSelDC, 0, 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND), paletteModel.GetBgColor());
|
||||
}
|
||||
selectionModel.DrawSelection(hDrawingDC, paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
|
||||
}
|
||||
imageArea.InvalidateRect(NULL, FALSE);
|
||||
imageArea.SendMessage(WM_PAINT, 0, 0);
|
||||
pos.x = GET_X_LPARAM(lParam);
|
||||
pos.y = GET_Y_LPARAM(lParam);
|
||||
m_ptPos.x = GET_X_LPARAM(lParam);
|
||||
m_ptPos.y = GET_Y_LPARAM(lParam);
|
||||
}
|
||||
else
|
||||
{
|
||||
int w = RECT_WIDTH(rectSel_dest) * toolsModel.GetZoom() / 1000 + 6;
|
||||
int h = RECT_HEIGHT(rectSel_dest) * toolsModel.GetZoom() / 1000 + 6;
|
||||
pos.x = GET_X_LPARAM(lParam);
|
||||
pos.y = GET_Y_LPARAM(lParam);
|
||||
int w = selectionModel.GetDestRectWidth() * toolsModel.GetZoom() / 1000 + 6;
|
||||
int h = selectionModel.GetDestRectHeight() * toolsModel.GetZoom() / 1000 + 6;
|
||||
m_ptPos.x = GET_X_LPARAM(lParam);
|
||||
m_ptPos.y = GET_Y_LPARAM(lParam);
|
||||
SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) NULL);
|
||||
action = identifyCorner(pos.x, pos.y, w, h);
|
||||
if (action != ACTION_MOVE)
|
||||
SetCursor(LoadCursor(NULL, cursors[action]));
|
||||
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::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
|
||||
{
|
||||
if (moving)
|
||||
if (m_bMoving)
|
||||
{
|
||||
moving = FALSE;
|
||||
m_bMoving = FALSE;
|
||||
ReleaseCapture();
|
||||
if (action != ACTION_MOVE)
|
||||
if (m_iAction != ACTION_MOVE)
|
||||
{
|
||||
if (toolsModel.GetActiveTool() == TOOL_TEXT)
|
||||
{
|
||||
|
@ -299,25 +220,7 @@ LRESULT CSelectionWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, B
|
|||
}
|
||||
else
|
||||
{
|
||||
HDC hTempDC;
|
||||
HBITMAP hTempBm;
|
||||
hTempDC = CreateCompatibleDC(hSelDC);
|
||||
hTempBm = CreateDIBWithProperties(RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest));
|
||||
SelectObject(hTempDC, hTempBm);
|
||||
SelectObject(hSelDC, hSelBm);
|
||||
StretchBlt(hTempDC, 0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), hSelDC, 0, 0,
|
||||
GetDIBWidth(hSelBm), GetDIBHeight(hSelBm), SRCCOPY);
|
||||
DeleteObject(hSelBm);
|
||||
hSelBm = hTempBm;
|
||||
hTempBm = CreateBitmap(RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), 1, 1, NULL);
|
||||
SelectObject(hTempDC, hTempBm);
|
||||
SelectObject(hSelDC, hSelMask);
|
||||
StretchBlt(hTempDC, 0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), hSelDC, 0, 0,
|
||||
GetDIBWidth(hSelMask), GetDIBHeight(hSelMask), SRCCOPY);
|
||||
DeleteObject(hSelMask);
|
||||
hSelMask = hTempBm;
|
||||
SelectObject(hSelDC, hSelBm);
|
||||
DeleteDC(hTempDC);
|
||||
selectionModel.ScaleContentsToFit();
|
||||
}
|
||||
}
|
||||
placeSelWin();
|
||||
|
|
|
@ -30,6 +30,17 @@ public:
|
|||
LRESULT OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
LRESULT OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
|
||||
|
||||
private:
|
||||
static const LPCTSTR m_lpszCursorLUT[9];
|
||||
BOOL m_bMoving;
|
||||
int m_iAction;
|
||||
POINT m_ptPos;
|
||||
POINT m_ptFrac;
|
||||
POINT m_ptDelta;
|
||||
DWORD m_dwSystemSelectionColor;
|
||||
|
||||
int IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight);
|
||||
};
|
||||
|
||||
void ForceRefreshSelectionContents();
|
||||
|
|
328
reactos/base/applications/mspaint_new/selectionmodel.cpp
Normal file
328
reactos/base/applications/mspaint_new/selectionmodel.cpp
Normal file
|
@ -0,0 +1,328 @@
|
|||
/*
|
||||
* PROJECT: PAINT for ReactOS
|
||||
* LICENSE: LGPL
|
||||
* FILE: base/applications/mspaint_new/selectionmodel.cpp
|
||||
* PURPOSE: Keep track of selection parameters, notify listeners
|
||||
* PROGRAMMERS: Benedikt Freisen
|
||||
*/
|
||||
|
||||
/* INCLUDES *********************************************************/
|
||||
|
||||
#include "precomp.h"
|
||||
|
||||
/* FUNCTIONS ********************************************************/
|
||||
|
||||
SelectionModel::SelectionModel()
|
||||
{
|
||||
m_ptStack = NULL;
|
||||
m_iPtSP = 0;
|
||||
}
|
||||
|
||||
void SelectionModel::SetDC(HDC hDC)
|
||||
{
|
||||
m_hDC = hDC;
|
||||
}
|
||||
|
||||
void SelectionModel::ResetPtStack()
|
||||
{
|
||||
if (m_ptStack != NULL)
|
||||
HeapFree(GetProcessHeap(), 0, m_ptStack);
|
||||
m_ptStack = NULL;
|
||||
m_iPtSP = 0;
|
||||
}
|
||||
|
||||
void SelectionModel::PushToPtStack(LONG x, LONG y)
|
||||
{
|
||||
if (m_iPtSP % 1024 == 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);
|
||||
}
|
||||
m_ptStack[m_iPtSP].x = x;
|
||||
m_ptStack[m_iPtSP].y = y;
|
||||
m_iPtSP++;
|
||||
}
|
||||
|
||||
void SelectionModel::CalculateBoundingBoxAndContents(HDC hDCImage)
|
||||
{
|
||||
int i;
|
||||
m_rcSrc.left = m_rcSrc.top = MAXLONG;
|
||||
m_rcSrc.right = m_rcSrc.bottom = 0;
|
||||
for (i = 0; i < m_iPtSP; i++)
|
||||
{
|
||||
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++)
|
||||
{
|
||||
m_ptStackCopy[i].x = m_ptStack[i].x - m_rcSrc.left;
|
||||
m_ptStackCopy[i].y = m_ptStack[i].y - m_rcSrc.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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
void SelectionModel::DrawBackgroundPoly(HDC hDCImage, COLORREF crBg)
|
||||
{
|
||||
Poly(hDCImage, m_ptStack, m_iPtSP, crBg, crBg, 1, 2, TRUE, 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, TRUE);
|
||||
}
|
||||
|
||||
extern 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);
|
||||
|
||||
void SelectionModel::DrawSelection(HDC hDCImage, COLORREF crBg, BOOL bBgTransparent)
|
||||
{
|
||||
MaskBlt(hDCImage, m_rcSrc.left, m_rcSrc.top, RECT_WIDTH(m_rcSrc), RECT_HEIGHT(m_rcSrc), m_hDC, 0,
|
||||
0, m_hMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
|
||||
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));
|
||||
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);
|
||||
}
|
||||
|
||||
void SelectionModel::DrawSelectionStretched(HDC hDCImage)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void SelectionModel::InsertFromHBITMAP(HBITMAP hBm)
|
||||
{
|
||||
HDC hTempDC;
|
||||
HBITMAP hTempMask;
|
||||
|
||||
DeleteObject(SelectObject(m_hDC, m_hBm = (HBITMAP) CopyImage(hBm,
|
||||
IMAGE_BITMAP, 0, 0,
|
||||
LR_COPYRETURNORG)));
|
||||
|
||||
SetRectEmpty(&m_rcSrc);
|
||||
m_rcDest.left = m_rcDest.top = 0;
|
||||
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, m_rcDest.left, m_rcDest.top, m_rcDest.right, m_rcDest.bottom, 0x00ffffff, 0x00ffffff, 1, 1);
|
||||
DeleteObject(m_hMask);
|
||||
m_hMask = hTempMask;
|
||||
DeleteDC(hTempDC);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void SelectionModel::RotateNTimes90Degrees(int iN)
|
||||
{
|
||||
if (iN == 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);
|
||||
}
|
||||
}
|
||||
|
||||
HBITMAP SelectionModel::GetBitmap()
|
||||
{
|
||||
return m_hBm;
|
||||
}
|
||||
|
||||
int SelectionModel::PtStackSize()
|
||||
{
|
||||
return m_iPtSP;
|
||||
}
|
||||
|
||||
void SelectionModel::DrawFramePoly(HDC hDCImage)
|
||||
{
|
||||
Poly(hDCImage, m_ptStack, m_iPtSP, 0, 0, 2, 0, FALSE, TRUE); /* draw the freehand selection inverted/xored */
|
||||
}
|
||||
|
||||
void SelectionModel::SetSrcAndDestRectFromPoints(POINT& ptFrom, 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);
|
||||
}
|
||||
|
||||
void SelectionModel::SetSrcRectSizeToZero()
|
||||
{
|
||||
m_rcSrc.right = m_rcSrc.left;
|
||||
m_rcSrc.bottom = m_rcSrc.top;
|
||||
}
|
||||
|
||||
BOOL SelectionModel::IsSrcRectSizeNonzero()
|
||||
{
|
||||
return (RECT_WIDTH(m_rcSrc) != 0) && (RECT_HEIGHT(m_rcSrc) != 0);
|
||||
}
|
||||
|
||||
void SelectionModel::ModifyDestRect(POINT& ptDelta, int iAction)
|
||||
{
|
||||
POINT ptDeltaUsed;
|
||||
|
||||
switch (iAction)
|
||||
{
|
||||
case ACTION_MOVE: /* move selection */
|
||||
ptDeltaUsed.x = ptDelta.x;
|
||||
ptDeltaUsed.y = ptDelta.y;
|
||||
OffsetRect(&m_rcDest, ptDeltaUsed.x, ptDeltaUsed.y);
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
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;
|
||||
break;
|
||||
}
|
||||
ptDelta.x -= ptDeltaUsed.x;
|
||||
ptDelta.y -= ptDeltaUsed.y;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectWidth()
|
||||
{
|
||||
return m_rcDest.right - m_rcDest.left;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectHeight()
|
||||
{
|
||||
return m_rcDest.bottom - m_rcDest.top;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectLeft()
|
||||
{
|
||||
return m_rcDest.left;
|
||||
}
|
||||
|
||||
LONG SelectionModel::GetDestRectTop()
|
||||
{
|
||||
return m_rcDest.top;
|
||||
}
|
||||
|
||||
void SelectionModel::DrawTextToolText(HDC hDCImage, COLORREF crFg, COLORREF crBg, BOOL bBgTransparent)
|
||||
{
|
||||
Text(hDCImage, m_rcDest.left, m_rcDest.top, m_rcDest.right, m_rcDest.bottom, crFg, crBg, textToolText, hfontTextFont, bBgTransparent);
|
||||
}
|
65
reactos/base/applications/mspaint_new/selectionmodel.h
Normal file
65
reactos/base/applications/mspaint_new/selectionmodel.h
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* PROJECT: PAINT for ReactOS
|
||||
* LICENSE: LGPL
|
||||
* FILE: base/applications/mspaint_new/selectionmodel.h
|
||||
* PURPOSE: Keep track of selection parameters, notify listeners
|
||||
* PROGRAMMERS: Benedikt Freisen
|
||||
*/
|
||||
|
||||
/* 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;
|
||||
POINT *m_ptStack;
|
||||
int m_iPtSP;
|
||||
|
||||
// void NotifySelectionChanging();
|
||||
// void NotifySelectionChanged();
|
||||
|
||||
public:
|
||||
SelectionModel();
|
||||
void SetDC(HDC hDC);
|
||||
void ResetPtStack();
|
||||
void PushToPtStack(LONG x, LONG y);
|
||||
void CalculateBoundingBoxAndContents(HDC hDCImage);
|
||||
void CalculateContents(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 InsertFromHBITMAP(HBITMAP hBm);
|
||||
void FlipHorizontally();
|
||||
void FlipVertically();
|
||||
void RotateNTimes90Degrees(int iN);
|
||||
HBITMAP GetBitmap();
|
||||
int PtStackSize();
|
||||
void DrawFramePoly(HDC hDCImage);
|
||||
void SetSrcAndDestRectFromPoints(POINT& ptFrom, POINT& ptTo);
|
||||
void SetSrcRectSizeToZero();
|
||||
BOOL IsSrcRectSizeNonzero();
|
||||
void ModifyDestRect(POINT& ptDelta, int iAction);
|
||||
LONG GetDestRectWidth();
|
||||
LONG GetDestRectHeight();
|
||||
LONG GetDestRectLeft();
|
||||
LONG GetDestRectTop();
|
||||
void DrawTextToolText(HDC hDCImage, COLORREF crFg, COLORREF crBg, BOOL bBgTransparent = FALSE);
|
||||
};
|
|
@ -107,29 +107,12 @@ void CMainWindow::UpdateApplicationProperties(HBITMAP bitmap, LPTSTR newfilename
|
|||
|
||||
void CMainWindow::InsertSelectionFromHBITMAP(HBITMAP bitmap, HWND window)
|
||||
{
|
||||
HDC hTempDC;
|
||||
HBITMAP hTempMask;
|
||||
|
||||
HWND hToolbar = FindWindowEx(toolBoxContainer.m_hWnd, NULL, TOOLBARCLASSNAME, NULL);
|
||||
SendMessage(hToolbar, TB_CHECKBUTTON, ID_RECTSEL, MAKELPARAM(TRUE, 0));
|
||||
toolBoxContainer.SendMessage(WM_COMMAND, ID_RECTSEL);
|
||||
|
||||
DeleteObject(SelectObject(hSelDC, hSelBm = (HBITMAP) CopyImage(bitmap,
|
||||
IMAGE_BITMAP, 0, 0,
|
||||
LR_COPYRETURNORG)));
|
||||
imageModel.CopyPrevious();
|
||||
SetRectEmpty(&rectSel_src);
|
||||
rectSel_dest.left = rectSel_dest.top = 0;
|
||||
rectSel_dest.right = rectSel_dest.left + GetDIBWidth(hSelBm);
|
||||
rectSel_dest.bottom = rectSel_dest.top + GetDIBHeight(hSelBm);
|
||||
|
||||
hTempDC = CreateCompatibleDC(hSelDC);
|
||||
hTempMask = CreateBitmap(RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), 1, 1, NULL);
|
||||
SelectObject(hTempDC, hTempMask);
|
||||
Rect(hTempDC, rectSel_dest.left, rectSel_dest.top, rectSel_dest.right, rectSel_dest.bottom, 0x00ffffff, 0x00ffffff, 1, 1);
|
||||
DeleteObject(hSelMask);
|
||||
hSelMask = hTempMask;
|
||||
DeleteDC(hTempDC);
|
||||
selectionModel.InsertFromHBITMAP(bitmap);
|
||||
|
||||
placeSelWin();
|
||||
selectionWindow.ShowWindow(SW_SHOW);
|
||||
|
@ -159,8 +142,6 @@ LRESULT CMainWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHa
|
|||
{
|
||||
SendMessage(WM_SETICON, ICON_BIG, (LPARAM) LoadIcon(hProgInstance, MAKEINTRESOURCE(IDI_APPICON)));
|
||||
SendMessage(WM_SETICON, ICON_SMALL, (LPARAM) LoadIcon(hProgInstance, MAKEINTRESOURCE(IDI_APPICON)));
|
||||
ptStack = NULL;
|
||||
ptSP = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -392,7 +373,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
case IDM_EDITCOPY:
|
||||
OpenClipboard();
|
||||
EmptyClipboard();
|
||||
SetClipboardData(CF_BITMAP, CopyImage(hSelBm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG));
|
||||
SetClipboardData(CF_BITMAP, CopyImage(selectionModel.GetBitmap(), IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG));
|
||||
CloseClipboard();
|
||||
break;
|
||||
case IDM_EDITCUT:
|
||||
|
@ -411,20 +392,8 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
break;
|
||||
case IDM_EDITDELETESELECTION:
|
||||
{
|
||||
/* remove selection window and already painted content using undo(),
|
||||
paint Rect for rectangular selections and Poly for freeform selections */
|
||||
/* remove selection window and already painted content using undo */
|
||||
imageModel.Undo();
|
||||
if (toolsModel.GetActiveTool() == TOOL_RECTSEL)
|
||||
{
|
||||
imageModel.CopyPrevious();
|
||||
Rect(hDrawingDC, rectSel_dest.left, rectSel_dest.top, rectSel_dest.right,
|
||||
rectSel_dest.bottom, paletteModel.GetBgColor(), paletteModel.GetBgColor(), 0, TRUE);
|
||||
}
|
||||
if (toolsModel.GetActiveTool() == TOOL_FREESEL)
|
||||
{
|
||||
imageModel.CopyPrevious();
|
||||
Poly(hDrawingDC, ptStack, ptSP + 1, 0, 0, 2, 0, FALSE, TRUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case IDM_EDITSELECTALL:
|
||||
|
@ -440,7 +409,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
}
|
||||
case IDM_EDITCOPYTO:
|
||||
if (GetSaveFileName(&ofn) != 0)
|
||||
SaveDIBToFile(hSelBm, ofn.lpstrFile, hDrawingDC, NULL, NULL, fileHPPM, fileVPPM);
|
||||
SaveDIBToFile(selectionModel.GetBitmap(), ofn.lpstrFile, hDrawingDC, NULL, NULL, fileHPPM, fileVPPM);
|
||||
break;
|
||||
case IDM_EDITPASTEFROM:
|
||||
if (GetOpenFileName(&ofn) != 0)
|
||||
|
@ -480,12 +449,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
case 1: /* flip horizontally */
|
||||
if (selectionWindow.IsWindowVisible())
|
||||
{
|
||||
SelectObject(hSelDC, hSelMask);
|
||||
StretchBlt(hSelDC, RECT_WIDTH(rectSel_dest) - 1, 0, -RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), hSelDC,
|
||||
0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY);
|
||||
SelectObject(hSelDC, hSelBm);
|
||||
StretchBlt(hSelDC, RECT_WIDTH(rectSel_dest) - 1, 0, -RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), hSelDC,
|
||||
0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY);
|
||||
selectionModel.FlipHorizontally();
|
||||
ForceRefreshSelectionContents();
|
||||
}
|
||||
else
|
||||
|
@ -499,12 +463,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
case 2: /* flip vertically */
|
||||
if (selectionWindow.IsWindowVisible())
|
||||
{
|
||||
SelectObject(hSelDC, hSelMask);
|
||||
StretchBlt(hSelDC, 0, RECT_HEIGHT(rectSel_dest) - 1, RECT_WIDTH(rectSel_dest), -RECT_HEIGHT(rectSel_dest), hSelDC,
|
||||
0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY);
|
||||
SelectObject(hSelDC, hSelBm);
|
||||
StretchBlt(hSelDC, 0, RECT_HEIGHT(rectSel_dest) - 1, RECT_WIDTH(rectSel_dest), -RECT_HEIGHT(rectSel_dest), hSelDC,
|
||||
0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY);
|
||||
selectionModel.FlipVertically();
|
||||
ForceRefreshSelectionContents();
|
||||
}
|
||||
else
|
||||
|
@ -520,12 +479,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
case 4: /* rotate 180 degrees */
|
||||
if (selectionWindow.IsWindowVisible())
|
||||
{
|
||||
SelectObject(hSelDC, hSelMask);
|
||||
StretchBlt(hSelDC, RECT_WIDTH(rectSel_dest) - 1, RECT_HEIGHT(rectSel_dest) - 1, -RECT_WIDTH(rectSel_dest), -RECT_HEIGHT(rectSel_dest), hSelDC,
|
||||
0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY);
|
||||
SelectObject(hSelDC, hSelBm);
|
||||
StretchBlt(hSelDC, RECT_WIDTH(rectSel_dest) - 1, RECT_HEIGHT(rectSel_dest) - 1, -RECT_WIDTH(rectSel_dest), -RECT_HEIGHT(rectSel_dest), hSelDC,
|
||||
0, 0, RECT_WIDTH(rectSel_dest), RECT_HEIGHT(rectSel_dest), SRCCOPY);
|
||||
selectionModel.RotateNTimes90Degrees(2);
|
||||
ForceRefreshSelectionContents();
|
||||
}
|
||||
else
|
||||
|
@ -561,7 +515,7 @@ LRESULT CMainWindow::OnCommand(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bH
|
|||
toolsModel.SetBackgroundTransparent(!toolsModel.IsBackgroundTransparent());
|
||||
break;
|
||||
case IDM_IMAGECROP:
|
||||
imageModel.Insert((HBITMAP) CopyImage(hSelBm, IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG));
|
||||
imageModel.Insert((HBITMAP) CopyImage(selectionModel.GetBitmap(), IMAGE_BITMAP, 0, 0, LR_COPYRETURNORG));
|
||||
break;
|
||||
|
||||
case IDM_VIEWTOOLBOX:
|
||||
|
|
Loading…
Reference in a new issue