[CRT] Massively improve performance of rand_s
[reactos.git] / base / applications / mspaint / selection.cpp
1 /*
2 * PROJECT: PAINT for ReactOS
3 * LICENSE: LGPL
4 * FILE: base/applications/mspaint/selection.cpp
5 * PURPOSE: Window procedure of the selection window
6 * PROGRAMMERS: Benedikt Freisen
7 * Katayama Hirofumi MZ
8 */
9
10 /* INCLUDES *********************************************************/
11
12 #include "precomp.h"
13
14 /* FUNCTIONS ********************************************************/
15
16 const LPCTSTR CSelectionWindow::m_lpszCursorLUT[9] = { /* action to mouse cursor lookup table */
17 IDC_SIZEALL,
18
19 IDC_SIZENWSE, IDC_SIZENS, IDC_SIZENESW,
20 IDC_SIZEWE, IDC_SIZEWE,
21 IDC_SIZENESW, IDC_SIZENS, IDC_SIZENWSE
22 };
23
24 BOOL
25 ColorKeyedMaskBlt(HDC hdcDest, int nXDest, int nYDest, int nWidth, int nHeight, HDC hdcSrc, int nXSrc, int nYSrc, HBITMAP hbmMask, int xMask, int yMask, DWORD dwRop, COLORREF keyColor)
26 {
27 HDC hTempDC;
28 HDC hTempDC2;
29 HBITMAP hTempBm;
30 HBRUSH hTempBrush;
31 HBITMAP hTempMask;
32
33 hTempDC = CreateCompatibleDC(hdcSrc);
34 hTempDC2 = CreateCompatibleDC(hdcSrc);
35 hTempBm = CreateCompatibleBitmap(hTempDC, nWidth, nHeight);
36 SelectObject(hTempDC, hTempBm);
37 hTempBrush = CreateSolidBrush(keyColor);
38 SelectObject(hTempDC, hTempBrush);
39 BitBlt(hTempDC, 0, 0, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, SRCCOPY);
40 PatBlt(hTempDC, 0, 0, nWidth, nHeight, PATINVERT);
41 hTempMask = CreateBitmap(nWidth, nHeight, 1, 1, NULL);
42 SelectObject(hTempDC2, hTempMask);
43 BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, 0, 0, SRCCOPY);
44 SelectObject(hTempDC, hbmMask);
45 BitBlt(hTempDC2, 0, 0, nWidth, nHeight, hTempDC, xMask, yMask, SRCAND);
46 MaskBlt(hdcDest, nXDest, nYDest, nWidth, nHeight, hdcSrc, nXSrc, nYSrc, hTempMask, xMask, yMask, dwRop);
47 DeleteDC(hTempDC);
48 DeleteDC(hTempDC2);
49 DeleteObject(hTempBm);
50 DeleteObject(hTempBrush);
51 DeleteObject(hTempMask);
52 return TRUE;
53 }
54
55 void
56 ForceRefreshSelectionContents()
57 {
58 if (selectionWindow.IsWindowVisible())
59 {
60 selectionWindow.SendMessage(WM_LBUTTONDOWN, 0, MAKELPARAM(0, 0));
61 selectionWindow.SendMessage(WM_MOUSEMOVE, 0, MAKELPARAM(0, 0));
62 selectionWindow.SendMessage(WM_LBUTTONUP, 0, MAKELPARAM(0, 0));
63 }
64 }
65
66 int CSelectionWindow::IdentifyCorner(int iXPos, int iYPos, int iWidth, int iHeight)
67 {
68 if (iYPos < 3)
69 {
70 if (iXPos < 3)
71 return ACTION_RESIZE_TOP_LEFT;
72 if ((iXPos < iWidth / 2 + 2) && (iXPos >= iWidth / 2 - 1))
73 return ACTION_RESIZE_TOP;
74 if (iXPos >= iWidth - 3)
75 return ACTION_RESIZE_TOP_RIGHT;
76 }
77 if ((iYPos < iHeight / 2 + 2) && (iYPos >= iHeight / 2 - 1))
78 {
79 if (iXPos < 3)
80 return ACTION_RESIZE_LEFT;
81 if (iXPos >= iWidth - 3)
82 return ACTION_RESIZE_RIGHT;
83 }
84 if (iYPos >= iHeight - 3)
85 {
86 if (iXPos < 3)
87 return ACTION_RESIZE_BOTTOM_LEFT;
88 if ((iXPos < iWidth / 2 + 2) && (iXPos >= iWidth / 2 - 1))
89 return ACTION_RESIZE_BOTTOM;
90 if (iXPos >= iWidth - 3)
91 return ACTION_RESIZE_BOTTOM_RIGHT;
92 }
93 return 0;
94 }
95
96 LRESULT CSelectionWindow::OnPaint(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
97 {
98 if (!m_bMoving)
99 {
100 HDC hDC = GetDC();
101 DefWindowProc(WM_PAINT, wParam, lParam);
102 SelectionFrame(hDC, 1, 1, selectionModel.GetDestRectWidth() * toolsModel.GetZoom() / 1000 + 5,
103 selectionModel.GetDestRectHeight() * toolsModel.GetZoom() / 1000 + 5,
104 m_dwSystemSelectionColor);
105 ReleaseDC(hDC);
106 }
107 return 0;
108 }
109
110 LRESULT CSelectionWindow::OnEraseBkgnd(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
111 {
112 // do nothing => transparent background
113 return 0;
114 }
115
116 LRESULT CSelectionWindow::OnCreate(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
117 {
118 m_bMoving = FALSE;
119 m_iAction = ACTION_MOVE;
120 /* update the system selection color */
121 m_dwSystemSelectionColor = GetSysColor(COLOR_HIGHLIGHT);
122 SendMessage(WM_PAINT, 0, MAKELPARAM(0, 0));
123 return 0;
124 }
125
126 LRESULT CSelectionWindow::OnSysColorChange(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
127 {
128 /* update the system selection color */
129 m_dwSystemSelectionColor = GetSysColor(COLOR_HIGHLIGHT);
130 SendMessage(WM_PAINT, 0, MAKELPARAM(0, 0));
131 return 0;
132 }
133
134 LRESULT CSelectionWindow::OnSetCursor(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
135 {
136 SetCursor(LoadCursor(NULL, IDC_SIZEALL));
137 return 0;
138 }
139
140 LRESULT CSelectionWindow::OnLButtonDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
141 {
142 m_ptPos.x = GET_X_LPARAM(lParam);
143 m_ptPos.y = GET_Y_LPARAM(lParam);
144 m_ptDelta.x = 0;
145 m_ptDelta.y = 0;
146 SetCapture();
147 if (m_iAction != ACTION_MOVE)
148 SetCursor(LoadCursor(NULL, m_lpszCursorLUT[m_iAction]));
149 m_bMoving = TRUE;
150 scrlClientWindow.InvalidateRect(NULL, TRUE);
151 scrlClientWindow.SendMessage(WM_PAINT, 0, 0);
152 imageArea.InvalidateRect(NULL, FALSE);
153 imageArea.SendMessage(WM_PAINT, 0, 0);
154 return 0;
155 }
156
157 LRESULT CSelectionWindow::OnMouseMove(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
158 {
159 if (m_bMoving)
160 {
161 imageModel.ResetToPrevious();
162 m_ptFrac.x += GET_X_LPARAM(lParam) - m_ptPos.x;
163 m_ptFrac.y += GET_Y_LPARAM(lParam) - m_ptPos.y;
164 m_ptDelta.x += m_ptFrac.x * 1000 / toolsModel.GetZoom();
165 m_ptDelta.y += m_ptFrac.y * 1000 / toolsModel.GetZoom();
166 if (toolsModel.GetZoom() < 1000)
167 {
168 m_ptFrac.x = 0;
169 m_ptFrac.y = 0;
170 }
171 else
172 {
173 m_ptFrac.x -= (m_ptFrac.x * 1000 / toolsModel.GetZoom()) * toolsModel.GetZoom() / 1000;
174 m_ptFrac.y -= (m_ptFrac.y * 1000 / toolsModel.GetZoom()) * toolsModel.GetZoom() / 1000;
175 }
176 selectionModel.ModifyDestRect(m_ptDelta, m_iAction);
177
178 CString strSize;
179 strSize.Format(_T("%d x %d"), selectionModel.GetDestRectWidth(), selectionModel.GetDestRectHeight());
180 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) (LPCTSTR) strSize);
181
182 if (toolsModel.GetActiveTool() == TOOL_TEXT)
183 {
184 selectionModel.DrawTextToolText(imageModel.GetDC(), paletteModel.GetFgColor(), paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
185 }
186 else
187 {
188 if (m_iAction != ACTION_MOVE)
189 selectionModel.DrawSelectionStretched(imageModel.GetDC());
190 else
191 selectionModel.DrawSelection(imageModel.GetDC(), paletteModel.GetBgColor(), toolsModel.IsBackgroundTransparent());
192 }
193 imageArea.InvalidateRect(NULL, FALSE);
194 imageArea.SendMessage(WM_PAINT, 0, 0);
195 m_ptPos.x = GET_X_LPARAM(lParam);
196 m_ptPos.y = GET_Y_LPARAM(lParam);
197 }
198 else
199 {
200 int w = selectionModel.GetDestRectWidth() * toolsModel.GetZoom() / 1000 + 6;
201 int h = selectionModel.GetDestRectHeight() * toolsModel.GetZoom() / 1000 + 6;
202 m_ptPos.x = GET_X_LPARAM(lParam);
203 m_ptPos.y = GET_Y_LPARAM(lParam);
204 SendMessage(hStatusBar, SB_SETTEXT, 2, (LPARAM) NULL);
205 m_iAction = IdentifyCorner(m_ptPos.x, m_ptPos.y, w, h);
206 if (m_iAction != ACTION_MOVE)
207 SetCursor(LoadCursor(NULL, m_lpszCursorLUT[m_iAction]));
208 }
209 return 0;
210 }
211
212 LRESULT CSelectionWindow::OnLButtonUp(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
213 {
214 if (m_bMoving)
215 {
216 m_bMoving = FALSE;
217 ReleaseCapture();
218 if (m_iAction != ACTION_MOVE)
219 {
220 if (toolsModel.GetActiveTool() == TOOL_TEXT)
221 {
222 // FIXME: What to do?
223 }
224 else
225 {
226 selectionModel.ScaleContentsToFit();
227 }
228 }
229 placeSelWin();
230 ShowWindow(SW_HIDE);
231 ShowWindow(SW_SHOW);
232 }
233 return 0;
234 }
235
236 LRESULT CSelectionWindow::OnCaptureChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
237 {
238 if (m_bMoving)
239 {
240 m_bMoving = FALSE;
241 if (m_iAction == ACTION_MOVE)
242 {
243 // FIXME: dirty hack
244 placeSelWin();
245 imageModel.Undo();
246 imageModel.Undo();
247 }
248 else
249 {
250 m_iAction = ACTION_MOVE;
251 }
252 ShowWindow(SW_HIDE);
253 }
254 return 0;
255 }
256
257 LRESULT CSelectionWindow::OnKeyDown(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
258 {
259 if (wParam == VK_ESCAPE)
260 {
261 if (GetCapture() == m_hWnd)
262 {
263 ReleaseCapture();
264 }
265 }
266 return 0;
267 }
268
269 LRESULT CSelectionWindow::OnPaletteModelColorChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
270 {
271 if (toolsModel.GetActiveTool() == TOOL_TEXT)
272 ForceRefreshSelectionContents();
273 return 0;
274 }
275
276 LRESULT CSelectionWindow::OnToolsModelSettingsChanged(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
277 {
278 if (toolsModel.GetActiveTool() == TOOL_FREESEL ||
279 toolsModel.GetActiveTool() == TOOL_RECTSEL ||
280 toolsModel.GetActiveTool() == TOOL_TEXT)
281 ForceRefreshSelectionContents();
282 return 0;
283 }
284
285 LRESULT CSelectionWindow::OnSelectionModelRefreshNeeded(UINT nMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
286 {
287 ForceRefreshSelectionContents();
288 return 0;
289 }