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