/* * PROJECT: PAINT for ReactOS * LICENSE: LGPL * FILE: base/applications/mspaint/mouse.cpp * PURPOSE: Things which should not be in the mouse event handler itself * PROGRAMMERS: Benedikt Freisen */ /* INCLUDES *********************************************************/ #include "precomp.h" /* FUNCTIONS ********************************************************/ void placeSelWin() { 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) { 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)); } void roundTo8Directions(LONG x0, LONG y0, LONG& x1, LONG& y1) { if (abs(x1 - x0) >= abs(y1 - y0)) { if (abs(y1 - y0) * 5 < abs(x1 - x0) * 2) y1 = y0; else y1 = y0 + (y1 > y0 ? abs(x1 - x0) : -abs(x1 - x0)); } else { if (abs(x1 - x0) * 5 < abs(y1 - y0) * 2) x1 = x0; else x1 = x0 + (x1 > x0 ? abs(y1 - y0) : -abs(y1 - y0)); } } POINT pointStack[256]; short pointSP; void startPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) { start.x = x; start.y = y; last.x = x; last.y = y; switch (toolsModel.GetActiveTool()) { case TOOL_FREESEL: selectionWindow.ShowWindow(SW_HIDE); selectionModel.ResetPtStack(); selectionModel.PushToPtStack(x, y); break; case TOOL_LINE: case TOOL_RECT: case TOOL_ELLIPSE: case TOOL_RRECT: imageModel.CopyPrevious(); break; case TOOL_RECTSEL: case TOOL_TEXT: imageModel.CopyPrevious(); selectionWindow.ShowWindow(SW_HIDE); selectionModel.SetSrcRectSizeToZero(); break; case TOOL_RUBBER: imageModel.CopyPrevious(); Erase(hdc, x, y, x, y, bg, toolsModel.GetRubberRadius()); break; case TOOL_FILL: imageModel.CopyPrevious(); Fill(hdc, x, y, fg); break; case TOOL_PEN: imageModel.CopyPrevious(); SetPixel(hdc, x, y, fg); break; case TOOL_BRUSH: imageModel.CopyPrevious(); Brush(hdc, x, y, x, y, fg, toolsModel.GetBrushStyle()); break; case TOOL_AIRBRUSH: imageModel.CopyPrevious(); Airbrush(hdc, x, y, fg, toolsModel.GetAirBrushWidth()); break; case TOOL_BEZIER: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP == 0) { imageModel.CopyPrevious(); pointSP++; } break; case TOOL_SHAPE: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP + 1 >= 2) Poly(hdc, pointStack, pointSP + 1, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE); if (pointSP == 0) { imageModel.CopyPrevious(); pointSP++; } break; } } void whilePaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) { switch (toolsModel.GetActiveTool()) { case TOOL_FREESEL: if (selectionModel.PtStackSize() == 1) imageModel.CopyPrevious(); selectionModel.PushToPtStack(max(0, min(x, imageModel.GetWidth())), max(0, min(y, imageModel.GetHeight()))); imageModel.ResetToPrevious(); selectionModel.DrawFramePoly(hdc); break; case TOOL_RECTSEL: case TOOL_TEXT: { POINT temp; imageModel.ResetToPrevious(); temp.x = max(0, min(x, imageModel.GetWidth())); temp.y = max(0, min(y, imageModel.GetHeight())); selectionModel.SetSrcAndDestRectFromPoints(start, temp); RectSel(hdc, start.x, start.y, temp.x, temp.y); break; } case TOOL_RUBBER: Erase(hdc, last.x, last.y, x, y, bg, toolsModel.GetRubberRadius()); break; case TOOL_PEN: Line(hdc, last.x, last.y, x, y, fg, 1); break; case TOOL_BRUSH: Brush(hdc, last.x, last.y, x, y, fg, toolsModel.GetBrushStyle()); break; case TOOL_AIRBRUSH: Airbrush(hdc, x, y, fg, toolsModel.GetAirBrushWidth()); break; case TOOL_LINE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(start.x, start.y, x, y); Line(hdc, start.x, start.y, x, y, fg, toolsModel.GetLineWidth()); break; case TOOL_BEZIER: imageModel.ResetToPrevious(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; switch (pointSP) { case 1: Line(hdc, pointStack[0].x, pointStack[0].y, pointStack[1].x, pointStack[1].y, fg, toolsModel.GetLineWidth()); break; case 2: Bezier(hdc, pointStack[0], pointStack[2], pointStack[2], pointStack[1], fg, toolsModel.GetLineWidth()); break; case 3: Bezier(hdc, pointStack[0], pointStack[2], pointStack[3], pointStack[1], fg, toolsModel.GetLineWidth()); break; } break; case TOOL_RECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) 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: imageModel.ResetToPrevious(); pointStack[pointSP].x = x; 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); 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); 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); RRect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; } last.x = x; last.y = y; } void endPaintingL(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) { switch (toolsModel.GetActiveTool()) { case TOOL_FREESEL: { selectionModel.CalculateBoundingBoxAndContents(hdc); if (selectionModel.PtStackSize() > 1) { selectionModel.DrawBackgroundPoly(hdc, bg); imageModel.CopyPrevious(); selectionModel.DrawSelection(hdc); placeSelWin(); selectionWindow.ShowWindow(SW_SHOW); ForceRefreshSelectionContents(); } selectionModel.ResetPtStack(); break; } case TOOL_RECTSEL: imageModel.ResetToPrevious(); if (selectionModel.IsSrcRectSizeNonzero()) { selectionModel.CalculateContents(hdc); selectionModel.DrawBackgroundRect(hdc, bg); imageModel.CopyPrevious(); selectionModel.DrawSelection(hdc); placeSelWin(); selectionWindow.ShowWindow(SW_SHOW); ForceRefreshSelectionContents(); } break; case TOOL_TEXT: imageModel.ResetToPrevious(); if (selectionModel.IsSrcRectSizeNonzero()) { imageModel.CopyPrevious(); placeSelWin(); selectionWindow.ShowWindow(SW_SHOW); ForceRefreshSelectionContents(); } break; case TOOL_RUBBER: Erase(hdc, last.x, last.y, x, y, bg, toolsModel.GetRubberRadius()); break; case TOOL_PEN: Line(hdc, last.x, last.y, x, y, fg, 1); SetPixel(hdc, x, y, fg); break; case TOOL_LINE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(start.x, start.y, x, y); Line(hdc, start.x, start.y, x, y, fg, toolsModel.GetLineWidth()); break; case TOOL_BEZIER: pointSP++; if (pointSP == 4) pointSP = 0; break; case TOOL_RECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) 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: imageModel.ResetToPrevious(); pointStack[pointSP].x = x; 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); pointSP++; if (pointSP >= 2) { if ((pointStack[0].x - x) * (pointStack[0].x - x) + (pointStack[0].y - y) * (pointStack[0].y - y) <= toolsModel.GetLineWidth() * toolsModel.GetLineWidth() + 1) { Poly(hdc, pointStack, pointSP, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), TRUE, FALSE); pointSP = 0; } else { Poly(hdc, pointStack, pointSP, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE); } } if (pointSP == 255) pointSP--; break; case TOOL_ELLIPSE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) 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); RRect(hdc, start.x, start.y, x, y, fg, bg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; } } void startPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) { start.x = x; start.y = y; last.x = x; last.y = y; switch (toolsModel.GetActiveTool()) { case TOOL_FREESEL: case TOOL_TEXT: case TOOL_LINE: case TOOL_RECT: case TOOL_ELLIPSE: case TOOL_RRECT: imageModel.CopyPrevious(); break; case TOOL_RUBBER: imageModel.CopyPrevious(); Replace(hdc, x, y, x, y, fg, bg, toolsModel.GetRubberRadius()); break; case TOOL_FILL: imageModel.CopyPrevious(); Fill(hdc, x, y, bg); break; case TOOL_PEN: imageModel.CopyPrevious(); SetPixel(hdc, x, y, bg); break; case TOOL_BRUSH: imageModel.CopyPrevious(); Brush(hdc, x, y, x, y, bg, toolsModel.GetBrushStyle()); break; case TOOL_AIRBRUSH: imageModel.CopyPrevious(); Airbrush(hdc, x, y, bg, toolsModel.GetAirBrushWidth()); break; case TOOL_BEZIER: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP == 0) { imageModel.CopyPrevious(); pointSP++; } break; case TOOL_SHAPE: pointStack[pointSP].x = x; pointStack[pointSP].y = y; if (pointSP + 1 >= 2) Poly(hdc, pointStack, pointSP + 1, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE); if (pointSP == 0) { imageModel.CopyPrevious(); pointSP++; } break; } } void whilePaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) { switch (toolsModel.GetActiveTool()) { case TOOL_RUBBER: Replace(hdc, last.x, last.y, x, y, fg, bg, toolsModel.GetRubberRadius()); break; case TOOL_PEN: Line(hdc, last.x, last.y, x, y, bg, 1); break; case TOOL_BRUSH: Brush(hdc, last.x, last.y, x, y, bg, toolsModel.GetBrushStyle()); break; case TOOL_AIRBRUSH: Airbrush(hdc, x, y, bg, toolsModel.GetAirBrushWidth()); break; case TOOL_LINE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(start.x, start.y, x, y); Line(hdc, start.x, start.y, x, y, bg, toolsModel.GetLineWidth()); break; case TOOL_BEZIER: imageModel.ResetToPrevious(); pointStack[pointSP].x = x; pointStack[pointSP].y = y; switch (pointSP) { case 1: Line(hdc, pointStack[0].x, pointStack[0].y, pointStack[1].x, pointStack[1].y, bg, toolsModel.GetLineWidth()); break; case 2: Bezier(hdc, pointStack[0], pointStack[2], pointStack[2], pointStack[1], bg, toolsModel.GetLineWidth()); break; case 3: Bezier(hdc, pointStack[0], pointStack[2], pointStack[3], pointStack[1], bg, toolsModel.GetLineWidth()); break; } break; case TOOL_RECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) 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: imageModel.ResetToPrevious(); pointStack[pointSP].x = x; 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); 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); 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); RRect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; } last.x = x; last.y = y; } void endPaintingR(HDC hdc, LONG x, LONG y, COLORREF fg, COLORREF bg) { switch (toolsModel.GetActiveTool()) { case TOOL_RUBBER: Replace(hdc, last.x, last.y, x, y, fg, bg, toolsModel.GetRubberRadius()); break; case TOOL_PEN: Line(hdc, last.x, last.y, x, y, bg, 1); SetPixel(hdc, x, y, bg); break; case TOOL_LINE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) roundTo8Directions(start.x, start.y, x, y); Line(hdc, start.x, start.y, x, y, bg, toolsModel.GetLineWidth()); break; case TOOL_BEZIER: pointSP++; if (pointSP == 4) pointSP = 0; break; case TOOL_RECT: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) 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: imageModel.ResetToPrevious(); pointStack[pointSP].x = x; 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); pointSP++; if (pointSP >= 2) { if ((pointStack[0].x - x) * (pointStack[0].x - x) + (pointStack[0].y - y) * (pointStack[0].y - y) <= toolsModel.GetLineWidth() * toolsModel.GetLineWidth() + 1) { Poly(hdc, pointStack, pointSP, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), TRUE, FALSE); pointSP = 0; } else { Poly(hdc, pointStack, pointSP, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle(), FALSE, FALSE); } } if (pointSP == 255) pointSP--; break; case TOOL_ELLIPSE: imageModel.ResetToPrevious(); if (GetAsyncKeyState(VK_SHIFT) < 0) 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); RRect(hdc, start.x, start.y, x, y, bg, fg, toolsModel.GetLineWidth(), toolsModel.GetShapeStyle()); break; } }