]> git.saurik.com Git - wxWidgets.git/blame - src/msw/bmpbuttn.cpp
xti additions / changes, trying to reduce dependencies
[wxWidgets.git] / src / msw / bmpbuttn.cpp
CommitLineData
2bda0e17 1/////////////////////////////////////////////////////////////////////////////
1e6feb95 2// Name: src/msw/bmpbuttn.cpp
2bda0e17
KB
3// Purpose: wxBitmapButton
4// Author: Julian Smart
5// Modified by:
6// Created: 04/01/98
7// RCS-ID: $Id$
6c9a19aa
JS
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
2bda0e17
KB
10/////////////////////////////////////////////////////////////////////////////
11
14f355c2 12#if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
2bda0e17
KB
13#pragma implementation "bmpbuttn.h"
14#endif
15
16// For compilers that support precompilation, includes "wx.h".
17#include "wx/wxprec.h"
18
19#ifdef __BORLANDC__
1e6feb95 20 #pragma hdrstop
2bda0e17
KB
21#endif
22
1e6feb95
VZ
23#if wxUSE_BMPBUTTON
24
2bda0e17 25#ifndef WX_PRECOMP
10a0bdb1 26 #include "wx/bmpbuttn.h"
84f19880 27 #include "wx/log.h"
47e92c41 28 #include "wx/dcmemory.h"
2bda0e17
KB
29#endif
30
31#include "wx/msw/private.h"
32
2bda0e17 33IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton, wxButton)
2bda0e17 34
066f1b7a
SC
35/*
36TODO PROPERTIES :
37
38long "style" , wxBU_AUTODRAW
39bool "default" , 0
40bitmap "selected" ,
41bitmap "focus" ,
42bitmap "disabled" ,
43*/
44
2bda0e17
KB
45#define BUTTON_HEIGHT_FACTOR (EDIT_CONTROL_FACTOR * 1.1)
46
debe6624 47bool wxBitmapButton::Create(wxWindow *parent, wxWindowID id, const wxBitmap& bitmap,
2bda0e17 48 const wxPoint& pos,
debe6624 49 const wxSize& size, long style,
2bda0e17
KB
50 const wxValidator& validator,
51 const wxString& name)
52{
1e6feb95 53 m_bmpNormal = bitmap;
2bda0e17 54 SetName(name);
11b6a93b
VZ
55
56#if wxUSE_VALIDATORS
2bda0e17 57 SetValidator(validator);
11b6a93b 58#endif // wxUSE_VALIDATORS
2bda0e17
KB
59
60 parent->AddChild(this);
61
5ab1fa8e
GRG
62 m_backgroundColour = parent->GetBackgroundColour();
63 m_foregroundColour = parent->GetForegroundColour();
2bda0e17 64 m_windowStyle = style;
2bda0e17
KB
65
66 if ( style & wxBU_AUTODRAW )
67 {
fd3f686c
VZ
68 m_marginX = wxDEFAULT_BUTTON_MARGIN;
69 m_marginY = wxDEFAULT_BUTTON_MARGIN;
2bda0e17
KB
70 }
71
72 int x = pos.x;
73 int y = pos.y;
74 int width = size.x;
75 int height = size.y;
76
77 if (id == -1)
78 m_windowId = NewControlId();
79 else
80 m_windowId = id;
81
82 if ( width == -1 && bitmap.Ok())
fd3f686c 83 width = bitmap.GetWidth() + 2*m_marginX;
2bda0e17
KB
84
85 if ( height == -1 && bitmap.Ok())
fd3f686c 86 height = bitmap.GetHeight() + 2*m_marginY;
2bda0e17 87
f6bcfd97
BP
88 long msStyle = WS_VISIBLE | WS_TABSTOP | WS_CHILD | BS_OWNERDRAW ;
89
b0766406
JS
90 if ( m_windowStyle & wxCLIP_SIBLINGS )
91 msStyle |= WS_CLIPSIBLINGS;
92
f6bcfd97
BP
93#ifdef __WIN32__
94 if(m_windowStyle & wxBU_LEFT)
95 msStyle |= BS_LEFT;
96 if(m_windowStyle & wxBU_RIGHT)
97 msStyle |= BS_RIGHT;
98 if(m_windowStyle & wxBU_TOP)
99 msStyle |= BS_TOP;
100 if(m_windowStyle & wxBU_BOTTOM)
101 msStyle |= BS_BOTTOM;
102#endif
103
42e69d6b
VZ
104 m_hWnd = (WXHWND)CreateWindowEx
105 (
106 0,
223d09f6 107 wxT("BUTTON"),
fda7962d 108 wxEmptyString,
f6bcfd97 109 msStyle,
33ac7e6f 110 0, 0, 0, 0,
42e69d6b
VZ
111 GetWinHwnd(parent),
112 (HMENU)m_windowId,
113 wxGetInstance(),
114 NULL
115 );
2bda0e17
KB
116
117 // Subclass again for purposes of dialog editing mode
42e69d6b 118 SubclassWin(m_hWnd);
2bda0e17 119
5ab1fa8e 120 SetFont(parent->GetFont());
2bda0e17
KB
121
122 SetSize(x, y, width, height);
2bda0e17
KB
123
124 return TRUE;
125}
126
f6bcfd97
BP
127// VZ: should be at the very least less than wxDEFAULT_BUTTON_MARGIN
128#define FOCUS_MARGIN 3
129
2bda0e17
KB
130bool wxBitmapButton::MSWOnDraw(WXDRAWITEMSTRUCT *item)
131{
4676948b 132#ifndef __WXWINCE__
ba681060 133 long style = GetWindowLong((HWND) GetHWND(), GWL_STYLE);
fd3f686c
VZ
134 if (style & BS_BITMAP)
135 {
fd3f686c
VZ
136 // Let default procedure draw the bitmap, which is defined
137 // in the Windows resource.
138 return FALSE;
139 }
2bda0e17
KB
140#endif
141
142 LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT) item;
47e92c41
GRG
143 HDC hDC = lpDIS->hDC;
144 UINT state = lpDIS->itemState;
145 bool isSelected = (state & ODS_SELECTED) != 0;
146 bool autoDraw = (GetWindowStyleFlag() & wxBU_AUTODRAW) != 0;
2bda0e17 147
47e92c41
GRG
148
149 // choose the bitmap to use depending on the button state
d9c8e68e 150 wxBitmap* bitmap;
2bda0e17 151
1e6feb95
VZ
152 if ( isSelected && m_bmpSelected.Ok() )
153 bitmap = &m_bmpSelected;
154 else if ((state & ODS_FOCUS) && m_bmpFocus.Ok())
155 bitmap = &m_bmpFocus;
156 else if ((state & ODS_DISABLED) && m_bmpDisabled.Ok())
157 bitmap = &m_bmpDisabled;
d9c8e68e 158 else
1e6feb95 159 bitmap = &m_bmpNormal;
2bda0e17 160
42e69d6b
VZ
161 if ( !bitmap->Ok() )
162 return FALSE;
2bda0e17 163
47e92c41
GRG
164 // centre the bitmap in the control area
165 int x = lpDIS->rcItem.left;
166 int y = lpDIS->rcItem.top;
167 int width = lpDIS->rcItem.right - x;
168 int height = lpDIS->rcItem.bottom - y;
169 int wBmp = bitmap->GetWidth();
170 int hBmp = bitmap->GetHeight();
f6bcfd97
BP
171
172 int x1,y1;
173
174 if(m_windowStyle & wxBU_LEFT)
175 x1 = x + (FOCUS_MARGIN+1);
176 else if(m_windowStyle & wxBU_RIGHT)
177 x1 = x + (width - wBmp) - (FOCUS_MARGIN+1);
178 else
179 x1 = x + (width - wBmp) / 2;
180
181 if(m_windowStyle & wxBU_TOP)
182 y1 = y + (FOCUS_MARGIN+1);
183 else if(m_windowStyle & wxBU_BOTTOM)
184 y1 = y + (height - hBmp) - (FOCUS_MARGIN+1);
185 else
186 y1 = y + (height - hBmp) / 2;
2bda0e17 187
47e92c41 188 if ( isSelected && autoDraw )
d9c8e68e 189 {
47e92c41
GRG
190 x1++;
191 y1++;
d9c8e68e 192 }
2bda0e17 193
47e92c41 194 // draw the face, if auto-drawing
d9c8e68e
VZ
195 if ( autoDraw )
196 {
197 DrawFace((WXHDC) hDC,
198 lpDIS->rcItem.left, lpDIS->rcItem.top,
199 lpDIS->rcItem.right, lpDIS->rcItem.bottom,
200 isSelected);
201 }
2bda0e17 202
47e92c41
GRG
203 // draw the bitmap
204 wxDC dst;
205 dst.SetHDC((WXHDC) hDC, FALSE);
206 dst.DrawBitmap(*bitmap, x1, y1, TRUE);
33ac7e6f 207
47e92c41 208 // draw focus / disabled state, if auto-drawing
d9c8e68e
VZ
209 if ( (state & ODS_DISABLED) && autoDraw )
210 {
211 DrawButtonDisable((WXHDC) hDC,
212 lpDIS->rcItem.left, lpDIS->rcItem.top,
213 lpDIS->rcItem.right, lpDIS->rcItem.bottom,
214 TRUE);
215 }
216 else if ( (state & ODS_FOCUS) && autoDraw )
217 {
218 DrawButtonFocus((WXHDC) hDC,
219 lpDIS->rcItem.left,
220 lpDIS->rcItem.top,
221 lpDIS->rcItem.right,
222 lpDIS->rcItem.bottom,
223 isSelected);
224 }
2bda0e17 225
2bda0e17
KB
226 return TRUE;
227}
228
5ab1fa8e
GRG
229// GRG Feb/2000, support for bmp buttons with Win95/98 standard LNF
230
231#if defined(__WIN95__)
232
2bda0e17
KB
233void wxBitmapButton::DrawFace( WXHDC dc, int left, int top, int right, int bottom, bool sel )
234{
d9c8e68e 235 HPEN oldp;
5ab1fa8e 236 HPEN penHiLight;
d9c8e68e
VZ
237 HPEN penLight;
238 HPEN penShadow;
5ab1fa8e 239 HPEN penDkShadow;
d9c8e68e 240 HBRUSH brushFace;
2bda0e17 241
5ab1fa8e
GRG
242 // create needed pens and brush
243 penHiLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DHILIGHT));
244 penLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DLIGHT));
245 penShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DSHADOW));
246 penDkShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_3DDKSHADOW));
85b43fbf
JS
247 // brushFace = CreateSolidBrush(GetSysColor(COLOR_BTNFACE));
248 // Taking the background colour fits in better with
249 // Windows XP themes.
250 brushFace = CreateSolidBrush(m_backgroundColour.m_pixel);
5ab1fa8e
GRG
251
252 // draw the rectangle
253 RECT rect;
254 rect.left = left;
255 rect.right = right;
256 rect.top = top;
257 rect.bottom = bottom;
258 FillRect((HDC) dc, &rect, brushFace);
259
260 // draw the border
261 oldp = (HPEN) SelectObject( (HDC) dc, sel? penDkShadow : penHiLight);
4676948b
JS
262
263 wxDrawLine((HDC) dc, left, top, right-1, top);
264 wxDrawLine((HDC) dc, left, top+1, left, bottom-1);
5ab1fa8e
GRG
265
266 SelectObject( (HDC) dc, sel? penShadow : penLight);
4676948b
JS
267 wxDrawLine((HDC) dc, left+1, top+1, right-2, top+1);
268 wxDrawLine((HDC) dc, left+1, top+2, left+1, bottom-2);
5ab1fa8e
GRG
269
270 SelectObject( (HDC) dc, sel? penLight : penShadow);
4676948b
JS
271 wxDrawLine((HDC) dc, left+1, bottom-2, right-1, bottom-2);
272 wxDrawLine((HDC) dc, right-2, bottom-3, right-2, top);
5ab1fa8e
GRG
273
274 SelectObject( (HDC) dc, sel? penHiLight : penDkShadow);
4676948b
JS
275 wxDrawLine((HDC) dc, left, bottom-1, right+2, bottom-1);
276 wxDrawLine((HDC) dc, right-1, bottom-2, right-1, top-1);
5ab1fa8e
GRG
277
278 // delete allocated resources
279 SelectObject((HDC) dc,oldp);
280 DeleteObject(penHiLight);
281 DeleteObject(penLight);
282 DeleteObject(penShadow);
283 DeleteObject(penDkShadow);
284 DeleteObject(brushFace);
285}
286
287#else
2bda0e17 288
5ab1fa8e
GRG
289void wxBitmapButton::DrawFace( WXHDC dc, int left, int top, int right, int bottom, bool sel )
290{
291 HPEN oldp;
292 HPEN penBorder;
293 HPEN penLight;
294 HPEN penShadow;
295 HBRUSH brushFace;
2bda0e17 296
5ab1fa8e
GRG
297 // create needed pens and brush
298 penBorder = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_WINDOWFRAME));
299 penShadow = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNSHADOW));
300 penLight = CreatePen(PS_SOLID, 0, GetSysColor(COLOR_BTNHIGHLIGHT));
301 brushFace = CreateSolidBrush(COLOR_BTNFACE);
2bda0e17 302
5ab1fa8e
GRG
303 // draw the rectangle
304 RECT rect;
305 rect.left = left;
306 rect.right = right;
307 rect.top = top;
308 rect.bottom = bottom;
309 FillRect((HDC) dc, &rect, brushFace);
2bda0e17 310
5ab1fa8e
GRG
311 // draw the border
312 oldp = (HPEN) SelectObject( (HDC) dc, penBorder);
d9c8e68e
VZ
313 MoveToEx((HDC) dc,left+1,top,NULL);LineTo((HDC) dc,right-1,top);
314 MoveToEx((HDC) dc,left,top+1,NULL);LineTo((HDC) dc,left,bottom-1);
315 MoveToEx((HDC) dc,left+1,bottom-1,NULL);LineTo((HDC) dc,right-1,bottom-1);
316 MoveToEx((HDC) dc,right-1,top+1,NULL);LineTo((HDC) dc,right-1,bottom-1);
2bda0e17 317
5ab1fa8e 318 SelectObject( (HDC) dc, penShadow);
fd3f686c
VZ
319 if (sel)
320 {
5ab1fa8e
GRG
321 MoveToEx((HDC) dc,left+1 ,bottom-2 ,NULL);
322 LineTo((HDC) dc, left+1 ,top+1);
323 LineTo((HDC) dc, right-2 ,top+1);
fd3f686c
VZ
324 }
325 else
326 {
5ab1fa8e
GRG
327 MoveToEx((HDC) dc,left+1 ,bottom-2 ,NULL);
328 LineTo((HDC) dc, right-2 ,bottom-2);
329 LineTo((HDC) dc, right-2 ,top);
330
331 MoveToEx((HDC) dc,left+2 ,bottom-3 ,NULL);
332 LineTo((HDC) dc, right-3 ,bottom-3);
333 LineTo((HDC) dc, right-3 ,top+1);
334
335 SelectObject( (HDC) dc, penLight);
336
337 MoveToEx((HDC) dc,left+1 ,bottom-2 ,NULL);
338 LineTo((HDC) dc, left+1 ,top+1);
339 LineTo((HDC) dc, right-2 ,top+1);
fd3f686c 340 }
2bda0e17 341
5ab1fa8e
GRG
342 // delete allocated resources
343 SelectObject((HDC) dc,oldp);
d9c8e68e
VZ
344 DeleteObject(penBorder);
345 DeleteObject(penLight);
346 DeleteObject(penShadow);
347 DeleteObject(brushFace);
2bda0e17
KB
348}
349
5ab1fa8e
GRG
350#endif // defined(__WIN95__)
351
352
2bda0e17
KB
353void wxBitmapButton::DrawButtonFocus( WXHDC dc, int left, int top, int right, int bottom, bool sel )
354{
fd3f686c
VZ
355 RECT rect;
356 rect.left = left;
357 rect.top = top;
358 rect.right = right;
359 rect.bottom = bottom;
5ab1fa8e
GRG
360 InflateRect( &rect, - FOCUS_MARGIN, - FOCUS_MARGIN );
361
362 // GRG: the focus rectangle should not move when the button is pushed!
363/*
fd3f686c 364 if ( sel )
5ab1fa8e
GRG
365 OffsetRect( &rect, 1, 1 );
366*/
33ac7e6f 367 (void)sel;
5ab1fa8e 368 DrawFocusRect( (HDC) dc, &rect );
2bda0e17
KB
369}
370
371extern HBRUSH wxDisableButtonBrush;
372void wxBitmapButton::DrawButtonDisable( WXHDC dc, int left, int top, int right, int bottom, bool with_marg )
373{
5ab1fa8e 374 HBRUSH old = (HBRUSH) SelectObject( (HDC) dc, wxDisableButtonBrush );
2bda0e17 375
d9c8e68e 376 // VZ: what's this?? there is no such ROP AFAIK
ce3ed50d 377#ifdef __SALFORDC__
d9c8e68e 378 DWORD dwRop = 0xFA0089L;
ce3ed50d 379#else
d9c8e68e 380 DWORD dwRop = 0xFA0089UL;
ce3ed50d 381#endif
d9c8e68e
VZ
382
383 if ( with_marg )
384 {
385 left += m_marginX;
386 top += m_marginY;
387 right -= 2 * m_marginX;
388 bottom -= 2 * m_marginY;
389 }
390
391 ::PatBlt( (HDC) dc, left, top, right, bottom, dwRop);
392
5ab1fa8e 393 ::SelectObject( (HDC) dc, old );
2bda0e17
KB
394}
395
0655ad29
VZ
396void wxBitmapButton::SetDefault()
397{
398 wxButton::SetDefault();
399}
1e6feb95
VZ
400
401#endif // wxUSE_BMPBUTTON