Create a branch for header work.
[reactos.git] / base / applications / paint / selection.c
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/paint/selection.c
5 * PURPOSE: Window procedure of the selection window
6 * PROGRAMMERS: Benedikt Freisen
7 */
8
9 /* INCLUDES *********************************************************/
10
11 #include <windows.h>
12 #include "globalvar.h"
13 #include "drawing.h"
14 #include "history.h"
15 #include "mouse.h"
16 #include "dib.h"
17
18 /* FUNCTIONS ********************************************************/
19
20 LPCTSTR cursors[9] = { IDC_SIZEALL, IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW,
21 IDC_SIZEWE, IDC_SIZEWE, IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE
22 };
23
24 BOOL moving = FALSE;
25 int action = 0;
26 short xPos;
27 short yPos;
28 short xFrac;
29 short yFrac;
30
31 int
32 identifyCorner(short x, short y, short w, short h)
33 {
34 if (y < 3)
35 {
36 if (x < 3)
37 return 1;
38 if ((x < w / 2 + 2) && (x >= w / 2 - 1))
39 return 2;
40 if (x >= w - 3)
41 return 3;
42 }
43 if ((y < h / 2 + 2) && (y >= h / 2 - 1))
44 {
45 if (x < 3)
46 return 4;
47 if (x >= w - 3)
48 return 5;
49 }
50 if (y >= h - 3)
51 {
52 if (x < 3)
53 return 6;
54 if ((x < w / 2 + 2) && (x >= w / 2 - 1))
55 return 7;
56 if (x >= w - 3)
57 return 8;
58 }
59 return 0;
60 }
61
62 LRESULT CALLBACK
63 SelectionWinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
64 {
65 switch (message)
66 {
67 case WM_PAINT:
68 {
69 if (!moving)
70 {
71 HDC hDC = GetDC(hwnd);
72 DefWindowProc(hwnd, message, wParam, lParam);
73 SelectionFrame(hDC, 1, 1, rectSel_dest[2] * zoom / 1000 + 5,
74 rectSel_dest[3] * zoom / 1000 + 5);
75 ReleaseDC(hwnd, hDC);
76 }
77 break;
78 }
79 case WM_LBUTTONDOWN:
80 xPos = LOWORD(lParam);
81 yPos = HIWORD(lParam);
82 SetCapture(hwnd);
83 if (action != 0)
84 SetCursor(LoadCursor(NULL, cursors[action]));
85 moving = TRUE;
86 break;
87 case WM_MOUSEMOVE:
88 if (moving)
89 {
90 int xDelta;
91 int yDelta;
92 resetToU1();
93 xFrac += (short)LOWORD(lParam) - xPos;
94 yFrac += (short)HIWORD(lParam) - yPos;
95 if (zoom < 1000)
96 {
97 xDelta = xFrac * 1000 / zoom;
98 xFrac = 0;
99 yDelta = yFrac * 1000 / zoom;
100 yFrac = 0;
101 }
102 else
103 {
104 xDelta = xFrac * 1000 / zoom;
105 xFrac -= (xFrac * 1000 / zoom) * zoom / 1000;
106 yDelta = yFrac * 1000 / zoom;
107 yFrac -= (yFrac * 1000 / zoom) * zoom / 1000;
108 }
109 switch (action)
110 {
111 case 0:
112 rectSel_dest[0] += xDelta;
113 rectSel_dest[1] += yDelta;
114 break;
115 case 1:
116 rectSel_dest[0] += xDelta;
117 rectSel_dest[1] += yDelta;
118 rectSel_dest[2] -= xDelta;
119 rectSel_dest[3] -= yDelta;
120 break;
121 case 2:
122 rectSel_dest[1] += yDelta;
123 rectSel_dest[3] -= yDelta;
124 break;
125 case 3:
126 rectSel_dest[2] += xDelta;
127 rectSel_dest[1] += yDelta;
128 break;
129 case 4:
130 rectSel_dest[0] += xDelta;
131 rectSel_dest[2] -= xDelta;
132 break;
133 case 5:
134 rectSel_dest[2] += xDelta;
135 break;
136 case 6:
137 rectSel_dest[0] += xDelta;
138 rectSel_dest[2] -= xDelta;
139 rectSel_dest[3] += yDelta;
140 break;
141 case 7:
142 rectSel_dest[3] += yDelta;
143 break;
144 case 8:
145 rectSel_dest[2] += xDelta;
146 rectSel_dest[3] += yDelta;
147 break;
148 }
149
150 if (action != 0)
151 StretchBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2], rectSel_dest[3], hSelDC, 0, 0, GetDIBWidth(hSelBm), GetDIBHeight(hSelBm), SRCCOPY);
152 else
153 if (transpBg == 0)
154 MaskBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2], rectSel_dest[3],
155 hSelDC, 0, 0, hSelMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
156 else
157 {
158 HBITMAP tempMask;
159 HBRUSH oldBrush;
160 HDC tempDC;
161 tempMask = CreateBitmap(rectSel_dest[2], rectSel_dest[3], 1, 1, NULL);
162 oldBrush = SelectObject(hSelDC, CreateSolidBrush(bgColor));
163 tempDC = CreateCompatibleDC(hSelDC);
164 SelectObject(tempDC, tempMask);
165 MaskBlt(tempDC, 0, 0, rectSel_dest[2], rectSel_dest[3], hSelDC, 0, 0, hSelMask, 0, 0,
166 MAKEROP4(NOTSRCCOPY, BLACKNESS));
167 DeleteDC(tempDC);
168 DeleteObject(SelectObject(hSelDC, oldBrush));
169
170 MaskBlt(hDrawingDC, rectSel_dest[0], rectSel_dest[1], rectSel_dest[2], rectSel_dest[3],
171 hSelDC, 0, 0, tempMask, 0, 0, MAKEROP4(SRCCOPY, SRCAND));
172 DeleteObject(tempMask);
173 }
174 SendMessage(hImageArea, WM_PAINT, 0, 0);
175 xPos = LOWORD(lParam);
176 yPos = HIWORD(lParam);
177 //SendMessage(hwnd, WM_PAINT, 0, 0);
178 }
179 else
180 {
181 int w = rectSel_dest[2] * zoom / 1000 + 6;
182 int h = rectSel_dest[3] * zoom / 1000 + 6;
183 xPos = LOWORD(lParam);
184 yPos = HIWORD(lParam);
185 action = identifyCorner(xPos, yPos, w, h);
186 if (action != 0)
187 SetCursor(LoadCursor(NULL, cursors[action]));
188 }
189 break;
190 case WM_LBUTTONUP:
191 if (moving)
192 {
193 moving = FALSE;
194 ReleaseCapture();
195 if (action != 0)
196 {
197 HDC hTempDC;
198 HBITMAP hTempBm;
199 hTempDC = CreateCompatibleDC(hSelDC);
200 hTempBm = CreateDIBWithProperties(rectSel_dest[2], rectSel_dest[3]);
201 SelectObject(hTempDC, hTempBm);
202 SelectObject(hSelDC, hSelBm);
203 StretchBlt(hTempDC, 0, 0, rectSel_dest[2], rectSel_dest[3], hSelDC, 0, 0,
204 GetDIBWidth(hSelBm), GetDIBHeight(hSelBm), SRCCOPY);
205 DeleteObject(hSelBm);
206 hSelBm = hTempBm;
207 hTempBm = CreateBitmap(rectSel_dest[2], rectSel_dest[3], 1, 1, NULL);
208 SelectObject(hTempDC, hTempBm);
209 SelectObject(hSelDC, hSelMask);
210 StretchBlt(hTempDC, 0, 0, rectSel_dest[2], rectSel_dest[3], hSelDC, 0, 0,
211 GetDIBWidth(hSelMask), GetDIBHeight(hSelMask), SRCCOPY);
212 DeleteObject(hSelMask);
213 hSelMask = hTempBm;
214 SelectObject(hSelDC, hSelBm);
215 DeleteDC(hTempDC);
216 }
217 placeSelWin();
218 ShowWindow(hSelection, SW_HIDE);
219 ShowWindow(hSelection, SW_SHOW);
220 }
221 break;
222 default:
223 return DefWindowProc(hwnd, message, wParam, lParam);
224 }
225
226 return 0;
227 }