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