922c3e67f4f4d122a86da030b122eb6c39a8e21e
[reactos.git] / reactos / base / applications / mspaint_new / imgarea.cpp
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/mspaint_new/imgarea.cpp
5 * PURPOSE: Window procedure of the main window and all children apart from
6 * hPalWin, hToolSettings and hSelection
7 * PROGRAMMERS: Benedikt Freisen
8 */
9
10 /* INCLUDES *********************************************************/
11
12 #include "precomp.h"
13
14 #include "dialogs.h"
15 #include "registry.h"
16
17 /* FUNCTIONS ********************************************************/
18
19 extern void
20 zoomTo(int newZoom, int mouseX, int mouseY);
21
22 void CImgAreaWindow::drawZoomFrame(int mouseX, int mouseY)
23 {
24 HDC hdc;
25 HPEN oldPen;
26 HBRUSH oldBrush;
27 LOGBRUSH logbrush;
28 int rop;
29
30 RECT clientRectScrollbox;
31 RECT clientRectImageArea;
32 int x, y, w, h;
33 scrollboxWindow.GetClientRect(&clientRectScrollbox);
34 GetClientRect(&clientRectImageArea);
35 w = clientRectImageArea.right * clientRectScrollbox.right / (clientRectImageArea.right * 2);
36 h = clientRectImageArea.bottom * clientRectScrollbox.bottom / (clientRectImageArea.bottom * 2);
37 x = max(0, min(clientRectImageArea.right - w, mouseX - w / 2));
38 y = max(0, min(clientRectImageArea.bottom - h, mouseY - h / 2));
39
40 hdc = GetDC();
41 oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 0, 0));
42 logbrush.lbStyle = BS_HOLLOW;
43 oldBrush = (HBRUSH) SelectObject(hdc, CreateBrushIndirect(&logbrush));
44 rop = SetROP2(hdc, R2_NOT);
45 Rectangle(hdc, x, y, x + w, y + h);
46 SetROP2(hdc, rop);
47 DeleteObject(SelectObject(hdc, oldBrush));
48 DeleteObject(SelectObject(hdc, oldPen));
49 ReleaseDC(hdc);
50 }
51
52 LRESULT CImgAreaWindow::OnSize(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
53 {
54 sizeboxLeftTop.MoveWindow(
55 0,
56 0, 3, 3, TRUE);
57 sizeboxCenterTop.MoveWindow(
58 imgXRes * toolsModel.GetZoom() / 2000 + 3 * 3 / 4,
59 0, 3, 3, TRUE);
60 sizeboxRightTop.MoveWindow(
61 imgXRes * toolsModel.GetZoom() / 1000 + 3,
62 0, 3, 3, TRUE);
63 sizeboxLeftCenter.MoveWindow(
64 0,
65 imgYRes * toolsModel.GetZoom() / 2000 + 3 * 3 / 4, 3, 3, TRUE);
66 sizeboxRightCenter.MoveWindow(
67 imgXRes * toolsModel.GetZoom() / 1000 + 3,
68 imgYRes * toolsModel.GetZoom() / 2000 + 3 * 3 / 4, 3, 3, TRUE);
69 sizeboxLeftBottom.MoveWindow(
70 0,
71 imgYRes * toolsModel.GetZoom() / 1000 + 3, 3, 3, TRUE);
72 sizeboxCenterBottom.MoveWindow(
73 imgXRes * toolsModel.GetZoom() / 2000 + 3 * 3 / 4,
74 imgYRes * toolsModel.GetZoom() / 1000 + 3, 3, 3, TRUE);
75 sizeboxRightBottom.MoveWindow(
76 imgXRes * toolsModel.GetZoom() / 1000 + 3,
77 imgYRes * toolsModel.GetZoom() / 1000 + 3, 3, 3, TRUE);
78 UpdateScrollbox();
79 return 0;
80 }
81
82 LRESULT CImgAreaWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
83 {
84 DefWindowProc(WM_PAINT, wParam, lParam);
85 HDC hdc = imageArea.GetDC();
86 StretchBlt(hdc, 0, 0, imgXRes * toolsModel.GetZoom() / 1000, imgYRes * toolsModel.GetZoom() / 1000, hDrawingDC, 0, 0, imgXRes,
87 imgYRes, SRCCOPY);
88 if (showGrid && (toolsModel.GetZoom() >= 4000))
89 {
90 HPEN oldPen = (HPEN) SelectObject(hdc, CreatePen(PS_SOLID, 1, 0x00a0a0a0));
91 int counter;
92 for(counter = 0; counter <= imgYRes; counter++)
93 {
94 MoveToEx(hdc, 0, counter * toolsModel.GetZoom() / 1000, NULL);
95 LineTo(hdc, imgXRes * toolsModel.GetZoom() / 1000, counter * toolsModel.GetZoom() / 1000);
96 }
97 for(counter = 0; counter <= imgXRes; counter++)
98 {
99 MoveToEx(hdc, counter * toolsModel.GetZoom() / 1000, 0, NULL);
100 LineTo(hdc, counter * toolsModel.GetZoom() / 1000, imgYRes * toolsModel.GetZoom() / 1000);
101 }
102 DeleteObject(SelectObject(hdc, oldPen));
103 }
104 imageArea.ReleaseDC(hdc);
105 selectionWindow.Invalidate(FALSE);
106 miniature.Invalidate(FALSE);
107 return 0;
108 }
109
110 LRESULT CImgAreaWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
111 {
112 switch (toolsModel.GetActiveTool())
113 {
114 case TOOL_FILL:
115 SetCursor(hCurFill);
116 break;
117 case TOOL_COLOR:
118 SetCursor(hCurColor);
119 break;
120 case TOOL_ZOOM:
121 SetCursor(hCurZoom);
122 break;
123 case TOOL_PEN:
124 SetCursor(hCurPen);
125 break;
126 case TOOL_AIRBRUSH:
127 SetCursor(hCurAirbrush);
128 break;
129 default:
130 SetCursor(LoadCursor(NULL, IDC_CROSS));
131 }
132 return 0;
133 }
134
135 LRESULT CImgAreaWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
136 {
137 if ((!drawing) || (toolsModel.GetActiveTool() == TOOL_COLOR))
138 {
139 SetCapture();
140 drawing = TRUE;
141 startPaintingL(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / toolsModel.GetZoom(), GET_Y_LPARAM(lParam) * 1000 / toolsModel.GetZoom(),
142 paletteModel.GetFgColor(), paletteModel.GetBgColor());
143 }
144 else
145 {
146 SendMessage(WM_LBUTTONUP, wParam, lParam);
147 undo();
148 }
149 Invalidate(FALSE);
150 if ((toolsModel.GetActiveTool() == TOOL_ZOOM) && (toolsModel.GetZoom() < 8000))
151 zoomTo(toolsModel.GetZoom() * 2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
152 return 0;
153 }
154
155 LRESULT CImgAreaWindow::OnRButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
156 {
157 if ((!drawing) || (toolsModel.GetActiveTool() == TOOL_COLOR))
158 {
159 SetCapture();
160 drawing = TRUE;
161 startPaintingR(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / toolsModel.GetZoom(), GET_Y_LPARAM(lParam) * 1000 / toolsModel.GetZoom(),
162 paletteModel.GetFgColor(), paletteModel.GetBgColor());
163 }
164 else
165 {
166 SendMessage(WM_RBUTTONUP, wParam, lParam);
167 undo();
168 }
169 Invalidate(FALSE);
170 if ((toolsModel.GetActiveTool() == TOOL_ZOOM) && (toolsModel.GetZoom() > 125))
171 zoomTo(toolsModel.GetZoom() / 2, GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
172 return 0;
173 }
174
175 LRESULT CImgAreaWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
176 {
177 if (drawing)
178 {
179 ReleaseCapture();
180 drawing = FALSE;
181 endPaintingL(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / toolsModel.GetZoom(), GET_Y_LPARAM(lParam) * 1000 / toolsModel.GetZoom(), paletteModel.GetFgColor(),
182 paletteModel.GetBgColor());
183 Invalidate(FALSE);
184 if (toolsModel.GetActiveTool() == TOOL_COLOR)
185 {
186 COLORREF tempColor =
187 GetPixel(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / toolsModel.GetZoom(), GET_Y_LPARAM(lParam) * 1000 / toolsModel.GetZoom());
188 if (tempColor != CLR_INVALID)
189 paletteModel.SetFgColor(tempColor);
190 }
191 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
192 }
193 return 0;
194 }
195
196 LRESULT CImgAreaWindow::OnRButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
197 {
198 if (drawing)
199 {
200 ReleaseCapture();
201 drawing = FALSE;
202 endPaintingR(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / toolsModel.GetZoom(), GET_Y_LPARAM(lParam) * 1000 / toolsModel.GetZoom(), paletteModel.GetFgColor(),
203 paletteModel.GetBgColor());
204 Invalidate(FALSE);
205 if (toolsModel.GetActiveTool() == TOOL_COLOR)
206 {
207 COLORREF tempColor =
208 GetPixel(hDrawingDC, GET_X_LPARAM(lParam) * 1000 / toolsModel.GetZoom(), GET_Y_LPARAM(lParam) * 1000 / toolsModel.GetZoom());
209 if (tempColor != CLR_INVALID)
210 paletteModel.SetBgColor(tempColor);
211 }
212 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) "");
213 }
214 return 0;
215 }
216
217 LRESULT CImgAreaWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
218 {
219 LONG xNow = GET_X_LPARAM(lParam) * 1000 / toolsModel.GetZoom();
220 LONG yNow = GET_Y_LPARAM(lParam) * 1000 / toolsModel.GetZoom();
221 if ((!drawing) || (toolsModel.GetActiveTool() <= TOOL_AIRBRUSH))
222 {
223 TRACKMOUSEEVENT tme;
224
225 if (toolsModel.GetActiveTool() == TOOL_ZOOM)
226 {
227 Invalidate(FALSE);
228 UpdateWindow();
229 drawZoomFrame(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam));
230 }
231
232 tme.cbSize = sizeof(TRACKMOUSEEVENT);
233 tme.dwFlags = TME_LEAVE;
234 tme.hwndTrack = imageArea.m_hWnd;
235 tme.dwHoverTime = 0;
236 TrackMouseEvent(&tme);
237
238 if (!drawing)
239 {
240 TCHAR coordStr[100];
241 _stprintf(coordStr, _T("%ld, %ld"), xNow, yNow);
242 SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr);
243 }
244 }
245 if (drawing)
246 {
247 /* values displayed in statusbar */
248 LONG xRel = xNow - start.x;
249 LONG yRel = yNow - start.y;
250 /* freesel, rectsel and text tools always show numbers limited to fit into image area */
251 if ((toolsModel.GetActiveTool() == TOOL_FREESEL) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_TEXT))
252 {
253 if (xRel < 0)
254 xRel = (xNow < 0) ? -start.x : xRel;
255 else if (xNow > imgXRes)
256 xRel = imgXRes-start.x;
257 if (yRel < 0)
258 yRel = (yNow < 0) ? -start.y : yRel;
259 else if (yNow > imgYRes)
260 yRel = imgYRes-start.y;
261 }
262 /* rectsel and shape tools always show non-negative numbers when drawing */
263 if ((toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_SHAPE))
264 {
265 if (xRel < 0)
266 xRel = -xRel;
267 if (yRel < 0)
268 yRel = -yRel;
269 }
270 /* while drawing, update cursor coordinates only for tools 3, 7, 8, 9, 14 */
271 switch(toolsModel.GetActiveTool())
272 {
273 case TOOL_RUBBER:
274 case TOOL_PEN:
275 case TOOL_BRUSH:
276 case TOOL_AIRBRUSH:
277 case TOOL_SHAPE:
278 {
279 TCHAR coordStr[100];
280 _stprintf(coordStr, _T("%ld, %ld"), xNow, yNow);
281 SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) coordStr);
282 break;
283 }
284 }
285 if ((wParam & MK_LBUTTON) != 0)
286 {
287 whilePaintingL(hDrawingDC, xNow, yNow, paletteModel.GetFgColor(), paletteModel.GetBgColor());
288 Invalidate(FALSE);
289 if ((toolsModel.GetActiveTool() >= TOOL_TEXT) || (toolsModel.GetActiveTool() == TOOL_RECTSEL) || (toolsModel.GetActiveTool() == TOOL_FREESEL))
290 {
291 TCHAR sizeStr[100];
292 if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0))
293 yRel = xRel;
294 _stprintf(sizeStr, _T("%ld x %ld"), xRel, yRel);
295 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr);
296 }
297 }
298 if ((wParam & MK_RBUTTON) != 0)
299 {
300 whilePaintingR(hDrawingDC, xNow, yNow, paletteModel.GetFgColor(), paletteModel.GetBgColor());
301 Invalidate(FALSE);
302 if (toolsModel.GetActiveTool() >= TOOL_TEXT)
303 {
304 TCHAR sizeStr[100];
305 if ((toolsModel.GetActiveTool() >= TOOL_LINE) && (GetAsyncKeyState(VK_SHIFT) < 0))
306 yRel = xRel;
307 _stprintf(sizeStr, _T("%ld x %ld"), xRel, yRel);
308 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) sizeStr);
309 }
310 }
311 }
312 return 0;
313 }
314
315 LRESULT CImgAreaWindow::OnMouseLeave(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
316 {
317 SendMessage(hStatusBar, SB_SETTEXT, 1, (LPARAM) _T(""));
318 if (toolsModel.GetActiveTool() == TOOL_ZOOM)
319 imageArea.Invalidate(FALSE);
320 return 0;
321 }