ffa0bc7083db50833e238f0fc565c41a64332268
2 * PROJECT: PAINT for ReactOS
4 * FILE: base/applications/mspaint_new/mouse.cpp
5 * PURPOSE: Things which should not be in the mouse event handler itself
6 * PROGRAMMERS: Benedikt Freisen
9 /* INCLUDES *********************************************************/
13 /* FUNCTIONS ********************************************************/
18 selectionWindow
.MoveWindow(rectSel_dest
.left
* toolsModel
.GetZoom() / 1000, rectSel_dest
.top
* toolsModel
.GetZoom() / 1000,
19 RECT_WIDTH(rectSel_dest
) * toolsModel
.GetZoom() / 1000 + 6, RECT_HEIGHT(rectSel_dest
) * toolsModel
.GetZoom() / 1000 + 6, TRUE
);
20 selectionWindow
.BringWindowToTop();
21 imageArea
.InvalidateRect(NULL
, FALSE
);
25 regularize(LONG x0
, LONG y0
, LONG
*x1
, LONG
*y1
)
27 if (abs(*x1
- x0
) >= abs(*y1
- y0
))
28 *y1
= y0
+ (*y1
> y0
? abs(*x1
- x0
) : -abs(*x1
- x0
));
30 *x1
= x0
+ (*x1
> x0
? abs(*y1
- y0
) : -abs(*y1
- y0
));
34 roundTo8Directions(LONG x0
, LONG y0
, LONG
*x1
, LONG
*y1
)
36 if (abs(*x1
- x0
) >= abs(*y1
- y0
))
38 if (abs(*y1
- y0
) * 5 < abs(*x1
- x0
) * 2)
41 *y1
= y0
+ (*y1
> y0
? abs(*x1
- x0
) : -abs(*x1
- x0
));
45 if (abs(*x1
- x0
) * 5 < abs(*y1
- y0
) * 2)
48 *x1
= x0
+ (*x1
> x0
? abs(*y1
- y0
) : -abs(*y1
- y0
));
52 POINT pointStack
[256];
54 POINT
*ptStack
= NULL
;
58 startPaintingL(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
64 switch (toolsModel
.GetActiveTool())
67 selectionWindow
.ShowWindow(SW_HIDE
);
69 HeapFree(GetProcessHeap(), 0, ptStack
);
70 ptStack
= (POINT
*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, sizeof(POINT
) * 1024);
84 selectionWindow
.ShowWindow(SW_HIDE
);
85 rectSel_src
.right
= rectSel_src
.left
;
86 rectSel_src
.bottom
= rectSel_src
.top
;
90 Erase(hdc
, x
, y
, x
, y
, bg
, toolsModel
.GetRubberRadius());
98 SetPixel(hdc
, x
, y
, fg
);
102 Brush(hdc
, x
, y
, x
, y
, fg
, toolsModel
.GetBrushStyle());
106 Airbrush(hdc
, x
, y
, fg
, toolsModel
.GetAirBrushWidth());
109 pointStack
[pointSP
].x
= x
;
110 pointStack
[pointSP
].y
= y
;
118 pointStack
[pointSP
].x
= x
;
119 pointStack
[pointSP
].y
= y
;
120 if (pointSP
+ 1 >= 2)
121 Poly(hdc
, pointStack
, pointSP
+ 1, fg
, bg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle(), FALSE
, FALSE
);
132 whilePaintingL(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
134 switch (toolsModel
.GetActiveTool())
140 if (ptSP
% 1024 == 0)
141 ptStack
= (POINT
*) HeapReAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, ptStack
, sizeof(POINT
) * (ptSP
+ 1024));
142 ptStack
[ptSP
].x
= max(0, min(x
, imgXRes
));
143 ptStack
[ptSP
].y
= max(0, min(y
, imgYRes
));
145 Poly(hdc
, ptStack
, ptSP
+ 1, 0, 0, 2, 0, FALSE
, TRUE
); /* draw the freehand selection inverted/xored */
152 temp
.x
= max(0, min(x
, imgXRes
));
153 temp
.y
= max(0, min(y
, imgYRes
));
154 rectSel_dest
.left
= rectSel_src
.left
= min(start
.x
, temp
.x
);
155 rectSel_dest
.top
= rectSel_src
.top
= min(start
.y
, temp
.y
);
156 rectSel_dest
.right
= rectSel_src
.right
= max(start
.x
, temp
.x
);
157 rectSel_dest
.bottom
= rectSel_src
.bottom
= max(start
.y
, temp
.y
);
158 RectSel(hdc
, start
.x
, start
.y
, temp
.x
, temp
.y
);
162 Erase(hdc
, last
.x
, last
.y
, x
, y
, bg
, toolsModel
.GetRubberRadius());
165 Line(hdc
, last
.x
, last
.y
, x
, y
, fg
, 1);
168 Brush(hdc
, last
.x
, last
.y
, x
, y
, fg
, toolsModel
.GetBrushStyle());
171 Airbrush(hdc
, x
, y
, fg
, toolsModel
.GetAirBrushWidth());
175 if (GetAsyncKeyState(VK_SHIFT
) < 0)
176 roundTo8Directions(start
.x
, start
.y
, &x
, &y
);
177 Line(hdc
, start
.x
, start
.y
, x
, y
, fg
, toolsModel
.GetLineWidth());
181 pointStack
[pointSP
].x
= x
;
182 pointStack
[pointSP
].y
= y
;
186 Line(hdc
, pointStack
[0].x
, pointStack
[0].y
, pointStack
[1].x
, pointStack
[1].y
, fg
,
187 toolsModel
.GetLineWidth());
190 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[2], pointStack
[1], fg
, toolsModel
.GetLineWidth());
193 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[3], pointStack
[1], fg
, toolsModel
.GetLineWidth());
199 if (GetAsyncKeyState(VK_SHIFT
) < 0)
200 regularize(start
.x
, start
.y
, &x
, &y
);
201 Rect(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
205 pointStack
[pointSP
].x
= x
;
206 pointStack
[pointSP
].y
= y
;
207 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
208 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
209 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
210 if (pointSP
+ 1 >= 2)
211 Poly(hdc
, pointStack
, pointSP
+ 1, fg
, bg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle(), FALSE
, FALSE
);
215 if (GetAsyncKeyState(VK_SHIFT
) < 0)
216 regularize(start
.x
, start
.y
, &x
, &y
);
217 Ellp(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
221 if (GetAsyncKeyState(VK_SHIFT
) < 0)
222 regularize(start
.x
, start
.y
, &x
, &y
);
223 RRect(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
232 endPaintingL(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
234 switch (toolsModel
.GetActiveTool())
240 rectSel_src
.left
= rectSel_src
.top
= MAXLONG
;
241 rectSel_src
.right
= rectSel_src
.bottom
= 0;
242 for (i
= 0; i
<= ptSP
; i
++)
244 if (ptStack
[i
].x
< rectSel_src
.left
)
245 rectSel_src
.left
= ptStack
[i
].x
;
246 if (ptStack
[i
].y
< rectSel_src
.top
)
247 rectSel_src
.top
= ptStack
[i
].y
;
248 if (ptStack
[i
].x
> rectSel_src
.right
)
249 rectSel_src
.right
= ptStack
[i
].x
;
250 if (ptStack
[i
].y
> rectSel_src
.bottom
)
251 rectSel_src
.bottom
= ptStack
[i
].y
;
253 rectSel_src
.right
+= 1;
254 rectSel_src
.bottom
+= 1;
255 rectSel_dest
.left
= rectSel_src
.left
;
256 rectSel_dest
.top
= rectSel_src
.top
;
257 rectSel_dest
.right
= rectSel_src
.right
;
258 rectSel_dest
.bottom
= rectSel_src
.bottom
;
261 DeleteObject(hSelMask
);
262 hSelMask
= CreateBitmap(RECT_WIDTH(rectSel_src
), RECT_HEIGHT(rectSel_src
), 1, 1, NULL
);
263 DeleteObject(SelectObject(hSelDC
, hSelMask
));
264 ptStackCopy
= (POINT
*) HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS
, sizeof(POINT
) * (ptSP
+ 1));
265 for (i
= 0; i
<= ptSP
; i
++)
267 ptStackCopy
[i
].x
= ptStack
[i
].x
- rectSel_src
.left
;
268 ptStackCopy
[i
].y
= ptStack
[i
].y
- rectSel_src
.top
;
270 Poly(hSelDC
, ptStackCopy
, ptSP
+ 1, 0x00ffffff, 0x00ffffff, 1, 2, TRUE
, FALSE
);
271 HeapFree(GetProcessHeap(), 0, ptStackCopy
);
272 SelectObject(hSelDC
, hSelBm
= CreateDIBWithProperties(RECT_WIDTH(rectSel_src
), RECT_HEIGHT(rectSel_src
)));
274 MaskBlt(hSelDC
, 0, 0, RECT_WIDTH(rectSel_src
), RECT_HEIGHT(rectSel_src
), hDrawingDC
, rectSel_src
.left
,
275 rectSel_src
.top
, hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, WHITENESS
));
276 Poly(hdc
, ptStack
, ptSP
+ 1, bg
, bg
, 1, 2, TRUE
, FALSE
);
279 MaskBlt(hDrawingDC
, rectSel_src
.left
, rectSel_src
.top
, RECT_WIDTH(rectSel_src
), RECT_HEIGHT(rectSel_src
), hSelDC
, 0,
280 0, hSelMask
, 0, 0, MAKEROP4(SRCCOPY
, SRCAND
));
283 selectionWindow
.ShowWindow(SW_SHOW
);
284 /* force refresh of selection contents */
285 selectionWindow
.SendMessage(WM_LBUTTONDOWN
, 0, 0);
286 selectionWindow
.SendMessage(WM_MOUSEMOVE
, 0, 0);
287 selectionWindow
.SendMessage(WM_LBUTTONUP
, 0, 0);
289 HeapFree(GetProcessHeap(), 0, ptStack
);
295 if ((RECT_WIDTH(rectSel_src
) != 0) && (RECT_HEIGHT(rectSel_src
) != 0))
297 DeleteObject(hSelMask
);
298 hSelMask
= CreateBitmap(RECT_WIDTH(rectSel_src
), RECT_HEIGHT(rectSel_src
), 1, 1, NULL
);
299 DeleteObject(SelectObject(hSelDC
, hSelMask
));
300 Rect(hSelDC
, 0, 0, RECT_WIDTH(rectSel_src
), RECT_HEIGHT(rectSel_src
), 0x00ffffff, 0x00ffffff, 1, 2);
301 SelectObject(hSelDC
, hSelBm
= CreateDIBWithProperties(RECT_WIDTH(rectSel_src
), RECT_HEIGHT(rectSel_src
)));
303 BitBlt(hSelDC
, 0, 0, RECT_WIDTH(rectSel_src
), RECT_HEIGHT(rectSel_src
), hDrawingDC
, rectSel_src
.left
,
304 rectSel_src
.top
, SRCCOPY
);
305 Rect(hdc
, rectSel_src
.left
, rectSel_src
.top
, rectSel_src
.right
,
306 rectSel_src
.bottom
, bg
, bg
, 0, TRUE
);
309 BitBlt(hDrawingDC
, rectSel_src
.left
, rectSel_src
.top
, RECT_WIDTH(rectSel_src
), RECT_HEIGHT(rectSel_src
), hSelDC
, 0,
313 selectionWindow
.ShowWindow(SW_SHOW
);
314 ForceRefreshSelectionContents();
319 if ((RECT_WIDTH(rectSel_src
) != 0) && (RECT_HEIGHT(rectSel_src
) != 0))
324 selectionWindow
.ShowWindow(SW_SHOW
);
325 ForceRefreshSelectionContents();
329 Erase(hdc
, last
.x
, last
.y
, x
, y
, bg
, toolsModel
.GetRubberRadius());
332 Line(hdc
, last
.x
, last
.y
, x
, y
, fg
, 1);
333 SetPixel(hdc
, x
, y
, fg
);
337 if (GetAsyncKeyState(VK_SHIFT
) < 0)
338 roundTo8Directions(start
.x
, start
.y
, &x
, &y
);
339 Line(hdc
, start
.x
, start
.y
, x
, y
, fg
, toolsModel
.GetLineWidth());
348 if (GetAsyncKeyState(VK_SHIFT
) < 0)
349 regularize(start
.x
, start
.y
, &x
, &y
);
350 Rect(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
354 pointStack
[pointSP
].x
= x
;
355 pointStack
[pointSP
].y
= y
;
356 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
357 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
358 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
362 if ((pointStack
[0].x
- x
) * (pointStack
[0].x
- x
) +
363 (pointStack
[0].y
- y
) * (pointStack
[0].y
- y
) <= toolsModel
.GetLineWidth() * toolsModel
.GetLineWidth() + 1)
365 Poly(hdc
, pointStack
, pointSP
, fg
, bg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle(), TRUE
, FALSE
);
370 Poly(hdc
, pointStack
, pointSP
, fg
, bg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle(), FALSE
, FALSE
);
378 if (GetAsyncKeyState(VK_SHIFT
) < 0)
379 regularize(start
.x
, start
.y
, &x
, &y
);
380 Ellp(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
384 if (GetAsyncKeyState(VK_SHIFT
) < 0)
385 regularize(start
.x
, start
.y
, &x
, &y
);
386 RRect(hdc
, start
.x
, start
.y
, x
, y
, fg
, bg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
392 startPaintingR(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
398 switch (toolsModel
.GetActiveTool())
410 Replace(hdc
, x
, y
, x
, y
, fg
, bg
, toolsModel
.GetRubberRadius());
418 SetPixel(hdc
, x
, y
, bg
);
422 Brush(hdc
, x
, y
, x
, y
, bg
, toolsModel
.GetBrushStyle());
426 Airbrush(hdc
, x
, y
, bg
, toolsModel
.GetAirBrushWidth());
429 pointStack
[pointSP
].x
= x
;
430 pointStack
[pointSP
].y
= y
;
438 pointStack
[pointSP
].x
= x
;
439 pointStack
[pointSP
].y
= y
;
440 if (pointSP
+ 1 >= 2)
441 Poly(hdc
, pointStack
, pointSP
+ 1, bg
, fg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle(), FALSE
, FALSE
);
452 whilePaintingR(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
454 switch (toolsModel
.GetActiveTool())
457 Replace(hdc
, last
.x
, last
.y
, x
, y
, fg
, bg
, toolsModel
.GetRubberRadius());
460 Line(hdc
, last
.x
, last
.y
, x
, y
, bg
, 1);
463 Brush(hdc
, last
.x
, last
.y
, x
, y
, bg
, toolsModel
.GetBrushStyle());
466 Airbrush(hdc
, x
, y
, bg
, toolsModel
.GetAirBrushWidth());
470 if (GetAsyncKeyState(VK_SHIFT
) < 0)
471 roundTo8Directions(start
.x
, start
.y
, &x
, &y
);
472 Line(hdc
, start
.x
, start
.y
, x
, y
, bg
, toolsModel
.GetLineWidth());
476 pointStack
[pointSP
].x
= x
;
477 pointStack
[pointSP
].y
= y
;
481 Line(hdc
, pointStack
[0].x
, pointStack
[0].y
, pointStack
[1].x
, pointStack
[1].y
, bg
,
482 toolsModel
.GetLineWidth());
485 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[2], pointStack
[1], bg
, toolsModel
.GetLineWidth());
488 Bezier(hdc
, pointStack
[0], pointStack
[2], pointStack
[3], pointStack
[1], bg
, toolsModel
.GetLineWidth());
494 if (GetAsyncKeyState(VK_SHIFT
) < 0)
495 regularize(start
.x
, start
.y
, &x
, &y
);
496 Rect(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
500 pointStack
[pointSP
].x
= x
;
501 pointStack
[pointSP
].y
= y
;
502 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
503 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
504 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
505 if (pointSP
+ 1 >= 2)
506 Poly(hdc
, pointStack
, pointSP
+ 1, bg
, fg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle(), FALSE
, FALSE
);
510 if (GetAsyncKeyState(VK_SHIFT
) < 0)
511 regularize(start
.x
, start
.y
, &x
, &y
);
512 Ellp(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
516 if (GetAsyncKeyState(VK_SHIFT
) < 0)
517 regularize(start
.x
, start
.y
, &x
, &y
);
518 RRect(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
527 endPaintingR(HDC hdc
, LONG x
, LONG y
, COLORREF fg
, COLORREF bg
)
529 switch (toolsModel
.GetActiveTool())
532 Replace(hdc
, last
.x
, last
.y
, x
, y
, fg
, bg
, toolsModel
.GetRubberRadius());
535 Line(hdc
, last
.x
, last
.y
, x
, y
, bg
, 1);
536 SetPixel(hdc
, x
, y
, bg
);
540 if (GetAsyncKeyState(VK_SHIFT
) < 0)
541 roundTo8Directions(start
.x
, start
.y
, &x
, &y
);
542 Line(hdc
, start
.x
, start
.y
, x
, y
, bg
, toolsModel
.GetLineWidth());
551 if (GetAsyncKeyState(VK_SHIFT
) < 0)
552 regularize(start
.x
, start
.y
, &x
, &y
);
553 Rect(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
557 pointStack
[pointSP
].x
= x
;
558 pointStack
[pointSP
].y
= y
;
559 if ((pointSP
> 0) && (GetAsyncKeyState(VK_SHIFT
) < 0))
560 roundTo8Directions(pointStack
[pointSP
- 1].x
, pointStack
[pointSP
- 1].y
,
561 &pointStack
[pointSP
].x
, &pointStack
[pointSP
].y
);
565 if ((pointStack
[0].x
- x
) * (pointStack
[0].x
- x
) +
566 (pointStack
[0].y
- y
) * (pointStack
[0].y
- y
) <= toolsModel
.GetLineWidth() * toolsModel
.GetLineWidth() + 1)
568 Poly(hdc
, pointStack
, pointSP
, bg
, fg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle(), TRUE
, FALSE
);
573 Poly(hdc
, pointStack
, pointSP
, bg
, fg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle(), FALSE
, FALSE
);
581 if (GetAsyncKeyState(VK_SHIFT
) < 0)
582 regularize(start
.x
, start
.y
, &x
, &y
);
583 Ellp(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());
587 if (GetAsyncKeyState(VK_SHIFT
) < 0)
588 regularize(start
.x
, start
.y
, &x
, &y
);
589 RRect(hdc
, start
.x
, start
.y
, x
, y
, bg
, fg
, toolsModel
.GetLineWidth(), toolsModel
.GetShapeStyle());