921d59cdebd9da2aa8c831a1398833cee4a43c48
[reactos.git] / reactos / lib / 3rdparty / cardlib / cardbutton.cpp
1 //
2 // CardLib - CardButton class
3 //
4 // Freeware
5 // Copyright J Brown 2001
6 //
7 //#include <windows.h>
8 //#include <tchar.h>
9
10 #define WIN32_NO_STATUS
11 #include <windef.h>
12
13 #include "cardlib.h"
14 //#include "cardwindow.h"
15 //#include "cardbutton.h"
16 #include "cardcolor.h"
17
18 HPALETTE UseNicePalette(HDC, HPALETTE);
19 void RestorePalette(HDC, HPALETTE);
20
21 void PaintRect(HDC hdc, RECT *rect, COLORREF colour);
22
23 CardButton::CardButton(CardWindow &parent, int Id, TCHAR *szText, UINT Style, bool visible,
24 int x, int y, int width, int height)
25
26 : parentWnd(parent), id(Id), uStyle(Style), fVisible(visible), ButtonCallback(0)
27 {
28 crText = RGB(255,255,255);
29 crBack = RGB(0, 128, 0);
30
31 xadjust = 0;
32 yadjust = 0;
33 xjustify = 0;
34 yjustify = 0;
35
36 fMouseDown = false;
37 fButtonDown = false;
38
39 hIcon = 0;
40
41 SetText(szText);
42 Move(x, y, width, height);
43
44 mxlock = CreateMutex(0, FALSE, 0);
45
46 hFont = 0;
47 }
48
49 CardButton::~CardButton()
50 {
51 CloseHandle(mxlock);
52 }
53
54 void CardButton::DrawRect(HDC hdc, RECT *rect, bool fNormal)
55 {
56 RECT fill;
57
58 HANDLE hOld;
59
60 HPEN hhi = CreatePen(0, 0, MAKE_PALETTERGB(crHighlight));
61 HPEN hsh = CreatePen(0, 0, MAKE_PALETTERGB(crShadow));
62 HPEN hbl = (HPEN)GetStockObject(BLACK_PEN);
63
64 int x = rect->left;
65 int y = rect->top;
66 int width = rect->right-rect->left - 1;
67 int height = rect->bottom-rect->top - 1;
68
69 SetRect(&fill, x+1, y+1, x+width-1, y+height-1);
70
71 int one = 1;
72
73 if(!fNormal)
74 {
75 x += width;
76 y += height;
77 width = -width;
78 height = -height;
79 one = -1;
80 OffsetRect(&fill, 1, 1);
81 }
82
83 if(fNormal)
84 hOld = SelectObject(hdc, hhi);
85 else
86 hOld = SelectObject(hdc, hhi);
87
88 MoveToEx(hdc, x, y+height, 0);
89 LineTo(hdc, x, y);
90 LineTo(hdc, x+width, y);
91 SelectObject(hdc, hOld);
92
93 hOld = SelectObject(hdc, hbl);
94 LineTo(hdc, x+width, y+height);
95 LineTo(hdc, x-one, y+height);
96 SelectObject(hdc, hOld);
97
98 hOld = SelectObject(hdc, hsh);
99 MoveToEx(hdc, x+one, y+height-one, 0);
100 LineTo(hdc, x+width-one, y+height-one);
101 LineTo(hdc, x+width-one, y);
102 SelectObject(hdc, hOld);
103
104 PaintRect(hdc, &fill, MAKE_PALETTERGB(crBack));
105
106 DeleteObject(hhi);
107 DeleteObject(hsh);
108 }
109
110 void CardButton::Clip(HDC hdc)
111 {
112 if(fVisible == false) return;
113
114 ExcludeClipRect(hdc, rect.left, rect.top, rect.right, rect.bottom);
115 }
116
117 void CardButton::Draw(HDC hdc, bool fNormal)
118 {
119 SIZE textsize;
120 int x, y; //text x, y
121 int ix, iy; //icon x, y
122 int iconwidth = 0;
123
124 RECT cliprect;
125
126 if(fVisible == 0) return;
127
128 if(hFont == 0)
129 SelectObject(hdc, GetStockObject(DEFAULT_GUI_FONT));
130 else
131 SelectObject(hdc, hFont);
132
133 GetTextExtentPoint32(hdc, szText, lstrlen(szText), &textsize);
134
135 if(hIcon)
136 {
137 x = rect.left + 32 + 8;
138 }
139 else
140 {
141 if(uStyle & CB_ALIGN_LEFT)
142 {
143 x = rect.left + iconwidth;
144 }
145 else if(uStyle & CB_ALIGN_RIGHT)
146 {
147 x = rect.left + (rect.right-rect.left-iconwidth-textsize.cx);
148 }
149 else //centered
150 {
151 x = rect.right - rect.left - iconwidth;
152 x = (x - textsize.cx) / 2;
153 x += rect.left + iconwidth;
154 }
155 }
156
157 y = rect.bottom - rect.top;
158 y = (y - textsize.cy) / 2;
159 y += rect.top;
160
161 //calc icon position..
162 ix = rect.left + 4;
163 iy = rect.top + (rect.bottom-rect.top-32) / 2;
164
165 //if button is pressed, then shift text
166 if(fNormal == false && (uStyle & CB_PUSHBUTTON))
167 {
168 x += 1;
169 y += 1;
170 ix += 1;
171 iy += 1;
172 }
173
174 SetRect(&cliprect, x, y, x+textsize.cx, y+textsize.cy);
175 ExcludeClipRect(hdc, x, y, x+textsize.cx, y+textsize.cy);
176
177 //
178 // Calc icon pos
179 //
180
181 if(hIcon)
182 {
183 ExcludeClipRect(hdc, ix, iy, ix + 32, iy + 32);
184 }
185
186 if(uStyle & CB_PUSHBUTTON)
187 {
188 DrawRect(hdc, &rect, fNormal);
189
190 SetBkColor(hdc, MAKE_PALETTERGB(crBack));
191 SetTextColor(hdc, crText);//MAKE_PALETTERGB(crText));
192
193 SelectClipRgn(hdc, 0);
194
195 ExtTextOut(hdc, x, y, ETO_OPAQUE, &cliprect, szText, lstrlen(szText), 0);
196 }
197 else
198 {
199 SetBkColor(hdc, MAKE_PALETTERGB(crBack));
200 SetTextColor(hdc, crText);//MAKE_PALETTERGB(crText));
201
202 SelectClipRgn(hdc, 0);
203
204 ExtTextOut(hdc, x, y, ETO_OPAQUE, &rect, szText, lstrlen(szText), 0);
205 }
206
207 if(hIcon)
208 {
209 HBRUSH hbr = CreateSolidBrush(MAKE_PALETTERGB(crBack));
210 DrawIconEx(hdc, ix, iy, hIcon, 32, 32, 0, hbr, 0);
211 DeleteObject(hbr);
212 }
213
214 }
215
216 void CardButton::AdjustPosition(int winwidth, int winheight)
217 {
218 int width = rect.right-rect.left;
219 int height = rect.bottom-rect.top;
220
221 width = width & ~0x1;
222
223 switch(xjustify)
224 {
225 case CS_XJUST_NONE:
226 break;
227
228 case CS_XJUST_CENTER: //centered
229 rect.left = (winwidth - (width)) / 2;
230 rect.left += xadjust;
231 rect.right = rect.left+width;
232 break;
233
234 case CS_XJUST_RIGHT: //right-aligned
235 rect.left = winwidth - width;
236 rect.left += xadjust;
237 rect.right = rect.left+width;
238 break;
239 }
240
241 switch(yjustify)
242 {
243 case CS_YJUST_NONE:
244 break;
245
246 case CS_YJUST_CENTER: //centered
247 rect.top = (winheight - (height)) / 2;
248 rect.top += yadjust;
249 rect.bottom = rect.top+height;
250 break;
251
252 case CS_YJUST_BOTTOM: //right-aligned
253 rect.top = winheight - height;
254 rect.top += yadjust;
255 rect.bottom = rect.top+height;
256 break;
257 }
258
259 }
260
261 int CardButton::OnLButtonDown(HWND hwnd, int x, int y)
262 {
263 if((uStyle & CB_PUSHBUTTON) == 0)
264 return 0;
265
266 //make sure that the user is allowed to do something
267 if(WaitForSingleObject(mxlock, 0) != WAIT_OBJECT_0)
268 {
269 return 0;
270 }
271 else
272 {
273 ReleaseMutex(mxlock);
274 }
275
276 fMouseDown = true;
277 fButtonDown = true;
278
279 Redraw();
280
281 SetCapture(hwnd);
282
283 return 1;
284 }
285
286 int CardButton::OnMouseMove(HWND hwnd, int x, int y)
287 {
288 if(fMouseDown)
289 {
290 bool fOldButtonDown = fButtonDown;
291
292 POINT pt;
293
294 pt.x = x;
295 pt.y = y;
296
297 if(PtInRect(&rect, pt))
298 fButtonDown = true;
299 else
300 fButtonDown = false;
301
302 if(fButtonDown != fOldButtonDown)
303 Redraw();
304 }
305
306 return 0;
307 }
308
309 int CardButton::OnLButtonUp(HWND hwnd, int x, int y)
310 {
311 if(fMouseDown)
312 {
313 fMouseDown = false;
314 fButtonDown = false;
315
316 if(uStyle & CB_PUSHBUTTON)
317 {
318 Redraw();
319 ReleaseCapture();
320 }
321
322 //if have clicked the button
323 if(parentWnd.CardButtonFromPoint(x, y) == this)
324 {
325 if(ButtonCallback)
326 {
327 ButtonCallback(*this);
328 }
329 else
330 {
331 HWND hwnd = (HWND)parentWnd;
332 SendMessage(GetParent(hwnd), WM_COMMAND, MAKEWPARAM(id, BN_CLICKED), (LONG_PTR)hwnd);
333 }
334 }
335 }
336
337 return 0;
338 }
339
340 //#define _countof(array) (sizeof(array)/sizeof(array[0]))
341
342 CardButton *CardWindow::CreateButton(int id, TCHAR *szText, UINT uStyle, bool fVisible, int x, int y, int width, int height)
343 {
344 CardButton *cb;
345
346 if(nNumButtons == MAXBUTTONS)
347 return 0;
348
349 cb = new CardButton(*this, id, szText, uStyle, fVisible, x, y, width, height);
350 Buttons[nNumButtons++] = cb;
351
352 if(uStyle & CB_PUSHBUTTON)
353 {
354 cb->SetBackColor(CardButton::GetFace(crBackgnd));
355 //cb->SetBackColor(ScaleLumRGB(crBackgnd, 0.1));
356 cb->SetForeColor(RGB(255,255,255));
357 }
358 else
359 {
360 cb->SetBackColor(crBackgnd);
361 cb->SetForeColor(RGB(255,255,255));
362 }
363
364 return cb;
365 }
366
367 void CardButton::SetText(TCHAR *lpszFormat, ...)
368 {
369 int count;
370
371 va_list args;
372 va_start(args, lpszFormat);
373
374 count = wvsprintf(szText, lpszFormat, args);
375 va_end(args);
376 }
377
378 int CardButton::Id()
379 {
380 return id;
381 }
382
383 void CardButton::Show(bool fShow)
384 {
385 fVisible = fShow;
386 }
387
388 void CardButton::Move(int x, int y, int width, int height)
389 {
390 SetRect(&rect, x, y, x+width, y+height);
391 }
392
393 void CardButton::Redraw()
394 {
395 HDC hdc = GetDC((HWND)parentWnd);
396
397 HPALETTE hOldPal = UseNicePalette(hdc, __hPalette);
398
399 Draw(hdc, !fButtonDown);
400
401 RestorePalette(hdc, hOldPal);
402
403 ReleaseDC((HWND)parentWnd, hdc);
404 }
405
406 void CardButton::SetForeColor(COLORREF cr)
407 {
408 crText = cr;
409 }
410
411 void CardButton::SetBackColor(COLORREF cr)
412 {
413 crBack = cr;
414
415 crHighlight = GetHighlight(cr);
416 crShadow = GetShadow(cr);
417
418 //crHighlight = ScaleLumRGB(cr, +0.25);
419 //crShadow = ScaleLumRGB(cr, -0.25);
420 }
421
422 // Static member
423 COLORREF CardButton::GetHighlight(COLORREF crBase)
424 {
425 return ColorScaleRGB(crBase, RGB(255,255,255), 0.25);
426 }
427
428 // Static member
429 COLORREF CardButton::GetShadow(COLORREF crBase)
430 {
431 return ColorScaleRGB(crBase, RGB(0, 0, 0), 0.25);
432 }
433
434 COLORREF CardButton::GetFace(COLORREF crBase)
435 {
436 return ColorScaleRGB(crBase, RGB(255,255,255), 0.1);
437 }
438
439 void CardButton::SetPlacement(UINT xJustify, UINT yJustify, int xAdjust, int yAdjust)
440 {
441 xadjust = xAdjust;
442 yadjust = yAdjust;
443 xjustify = xJustify;
444 yjustify = yJustify;
445 }
446
447 void CardButton::SetIcon(HICON hicon, bool fRedraw)
448 {
449 hIcon = hicon;
450
451 if(fRedraw)
452 Redraw();
453 }
454
455 void CardButton::SetFont(HFONT font)
456 {
457 //don't delete the existing font..
458 hFont = font;
459 }
460
461 void CardButton::SetButtonProc(pButtonProc proc)
462 {
463 ButtonCallback = proc;
464 }
465
466 bool CardButton::Lock()
467 {
468 DWORD dw = WaitForSingleObject(mxlock, 0);
469
470 if(dw == WAIT_OBJECT_0)
471 return true;
472 else
473 return false;
474 }
475
476 bool CardButton::UnLock()
477 {
478 if(ReleaseMutex(mxlock))
479 return true;
480 else
481 return false;
482 }
483
484 void CardButton::SetStyle(UINT style)
485 {
486 uStyle = style;
487 }
488
489 UINT CardButton::GetStyle()
490 {
491 return uStyle;
492 }