]> git.saurik.com Git - wxWidgets.git/blob - src/os2/bmpbuttn.cpp
fix crash which happened if you called SetAttr(NULL) followed by SetAttr(attr) (...
[wxWidgets.git] / src / os2 / bmpbuttn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/os2/bmpbuttn.cpp
3 // Purpose: wxBitmapButton
4 // Author: David Webster
5 // Modified by:
6 // Created: 10/13/99
7 // RCS-ID: $Id$
8 // Copyright: (c) David Webster
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14
15 #if wxUSE_BMPBUTTON
16
17 #include "wx/bmpbuttn.h"
18
19 #ifndef WX_PRECOMP
20 #endif
21
22 #include "wx/os2/dcclient.h"
23 #include "wx/os2/private.h"
24
25
26 IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton, wxButton)
27
28 #define BUTTON_HEIGHT_FACTOR (EDIT_CONTROL_FACTOR * 1.1)
29
30 bool wxBitmapButton::Create( wxWindow* pParent,
31 wxWindowID vId,
32 const wxBitmap& rBitmap,
33 const wxPoint& rPos,
34 const wxSize& rSize,
35 long lStyle,
36 const wxValidator& rValidator,
37 const wxString& rsName )
38 {
39 m_bmpNormal = rBitmap;
40 SetName(rsName);
41 #if wxUSE_VALIDATORS
42 SetValidator(rValidator);
43 #endif
44
45 pParent->AddChild(this);
46
47 m_backgroundColour = pParent->GetBackgroundColour() ;
48 m_foregroundColour = pParent->GetForegroundColour() ;
49 m_windowStyle = lStyle;
50
51 if (lStyle & wxBU_AUTODRAW)
52 {
53 m_marginX = wxDEFAULT_BUTTON_MARGIN;
54 m_marginY = wxDEFAULT_BUTTON_MARGIN;
55 }
56
57 int nX = rPos.x;
58 int nY = rPos.y;
59 int nWidth = rSize.x;
60 int nHeight = rSize.y;
61
62 if (vId == wxID_ANY)
63 m_windowId = NewControlId();
64 else
65 m_windowId = vId;
66
67 if (nWidth == wxDefaultCoord && rBitmap.Ok())
68 nWidth = rBitmap.GetWidth() + 4 * m_marginX;
69
70 if (nHeight == wxDefaultCoord && rBitmap.Ok())
71 nHeight = rBitmap.GetHeight() + 4 * m_marginY;
72
73 ULONG ulOS2Style = WS_VISIBLE | WS_TABSTOP | BS_USERBUTTON;
74
75 if (m_windowStyle & wxCLIP_SIBLINGS)
76 ulOS2Style |= WS_CLIPSIBLINGS;
77
78 m_hWnd = (WXHWND)::WinCreateWindow( GetHwndOf(pParent)
79 ,WC_BUTTON
80 ,(PSZ)wxEmptyString
81 ,ulOS2Style
82 ,0, 0, 0, 0
83 ,GetHwndOf(pParent)
84 ,HWND_TOP
85 ,m_windowId
86 ,NULL
87 ,NULL
88 );
89
90 //
91 //Subclass again for purposes of dialog editing mode
92 //
93 SubclassWin(m_hWnd);
94 SetFont(*wxSMALL_FONT);
95 SetSize( nX
96 ,nY
97 ,nWidth
98 ,nHeight
99 );
100 return true;
101 } // end of wxBitmapButton::Create
102
103 bool wxBitmapButton::OS2OnDraw( WXDRAWITEMSTRUCT* pItem)
104 {
105 PUSERBUTTON pUser = (PUSERBUTTON)pItem;
106 bool bAutoDraw = (GetWindowStyleFlag() & wxBU_AUTODRAW) != 0;
107
108 if (!pUser)
109 return false;
110
111 wxBitmap* pBitmap;
112 bool bIsSelected = pUser->fsState & BDS_HILITED;
113 wxClientDC vDc(this);
114
115 if (bIsSelected && m_bmpSelected.Ok())
116 pBitmap = &m_bmpSelected;
117 else if ((pUser->fsState & BDS_DEFAULT) && m_bmpFocus.Ok())
118 pBitmap = &m_bmpFocus;
119 else if ((pUser->fsState & BDS_DISABLED) && m_bmpDisabled.Ok())
120 pBitmap = &m_bmpDisabled;
121 else
122 pBitmap = &m_bmpNormal;
123
124 if (!pBitmap->Ok() )
125 return false;
126
127
128 //
129 // Centre the bitmap in the control area
130 //
131 int nX1 = 0;
132 int nY1 = 0;
133 wxPMDCImpl *impl = (wxPMDCImpl*) vDc.GetImpl();
134 int nWidth = impl->m_vRclPaint.xRight - impl->m_vRclPaint.xLeft;
135 int nHeight = impl->m_vRclPaint.yTop - impl->m_vRclPaint.yBottom;
136 int nBmpWidth = pBitmap->GetWidth();
137 int nBmpHeight = pBitmap->GetHeight();
138
139 nX1 = (nWidth - nBmpWidth) / 2;
140 nY1 = (nHeight - nBmpHeight) / 2;
141
142 if (bIsSelected && bAutoDraw)
143 {
144 nX1++;
145 nY1++;
146 }
147
148 //
149 // Draw the button face
150 //
151 DrawFace( vDc, bIsSelected );
152
153 //
154 // Draw the bitmap
155 //
156 vDc.DrawBitmap( *pBitmap, nX1, nY1, true );
157
158 //
159 // Draw focus / disabled state, if auto-drawing
160 //
161 if ((pUser->fsState == BDS_DISABLED) && bAutoDraw)
162 {
163 DrawButtonDisable( vDc, *pBitmap );
164 }
165 else if ((pUser->fsState == BDS_DEFAULT) && bAutoDraw)
166 {
167 DrawButtonFocus(vDc);
168 }
169 return true;
170 } // end of wxBitmapButton::OS2OnDraw
171
172 void wxBitmapButton::DrawFace (wxClientDC& rDC, bool bSel)
173 {
174 //
175 // Set up drawing colors
176 //
177 wxPen vHiLitePen(*wxWHITE, 2, wxSOLID); // White
178 wxColour gray85(85, 85, 85);
179 wxPen vDarkShadowPen(gray85, 2, wxSOLID);
180 wxColour vFaceColor(204, 204, 204); // Light Grey
181
182 //
183 // Draw the main button face
184 //
185 // This triggers a redraw and destroys the bottom & left focus border and
186 // doesn't seem to do anything useful.
187 // ::WinFillRect(rDC.GetHPS(), &rDC.m_vRclPaint, vFaceColor.GetPixel());
188
189 //
190 // Draw the border
191 // Note: DrawLine expects wxWidgets coordinate system so swap
192 //
193 rDC.SetPen(bSel ? vDarkShadowPen : vHiLitePen);
194 wxPMDCImpl *impl = (wxPMDCImpl*) rDC.GetImpl();
195 // top
196 rDC.DrawLine( impl->m_vRclPaint.xLeft + 1
197 ,impl->m_vRclPaint.yBottom + 1
198 ,impl->m_vRclPaint.xRight - 1
199 ,impl->m_vRclPaint.yBottom + 1
200 );
201 // left
202 rDC.DrawLine( impl->m_vRclPaint.xLeft + 1
203 ,impl->m_vRclPaint.yBottom + 1
204 ,impl->m_vRclPaint.xLeft + 1
205 ,impl->m_vRclPaint.yTop - 1
206 );
207
208 rDC.SetPen(bSel ? vHiLitePen : vDarkShadowPen);
209 // bottom
210 rDC.DrawLine( impl->m_vRclPaint.xLeft + 1
211 ,impl->m_vRclPaint.yTop - 1
212 ,impl->m_vRclPaint.xRight - 1
213 ,impl->m_vRclPaint.yTop - 1
214 );
215 // right
216 rDC.DrawLine( impl->m_vRclPaint.xRight - 1
217 ,impl->m_vRclPaint.yBottom + 1
218 ,impl->m_vRclPaint.xRight - 1
219 ,impl->m_vRclPaint.yTop - 1
220 );
221
222 } // end of wxBitmapButton::DrawFace
223
224 void wxBitmapButton::DrawButtonFocus (
225 wxClientDC& rDC
226 )
227 {
228 wxPen vBlackPen(*wxBLACK, 2, wxSOLID);
229
230 //
231 // Draw a thick black line around the outside of the button
232 // Note: DrawLine expects wxWidgets coordinate system so swap
233 //
234 rDC.SetPen(vBlackPen);
235 wxPMDCImpl *impl = (wxPMDCImpl*) rDC.GetImpl();
236 // top
237 rDC.DrawLine( impl->m_vRclPaint.xLeft
238 ,impl->m_vRclPaint.yBottom
239 ,impl->m_vRclPaint.xRight
240 ,impl->m_vRclPaint.yBottom
241 );
242 // right
243 rDC.DrawLine( impl->m_vRclPaint.xRight
244 ,impl->m_vRclPaint.yBottom
245 ,impl->m_vRclPaint.xRight
246 ,impl->m_vRclPaint.yTop
247 );
248 // bottom
249 rDC.DrawLine( impl->m_vRclPaint.xRight
250 ,impl->m_vRclPaint.yTop
251 ,impl->m_vRclPaint.xLeft
252 ,impl->m_vRclPaint.yTop
253 );
254 // left
255 rDC.DrawLine( impl->m_vRclPaint.xLeft
256 ,impl->m_vRclPaint.yTop
257 ,impl->m_vRclPaint.xLeft
258 ,impl->m_vRclPaint.yBottom
259 );
260 } // end of wxBitmapButton::DrawButtonFocus
261
262 void wxBitmapButton::DrawButtonDisable( wxClientDC& rDC,
263 wxBitmap& rBmp )
264 {
265 wxPen vGreyPen(wxT("GREY"), 2, wxSOLID);
266
267 //
268 // Draw a thick black line around the outside of the button
269 // Note: DrawLine expects wxWidgets coordinate system so swap
270 //
271 rDC.SetPen(vGreyPen);
272 wxPMDCImpl *impl = (wxPMDCImpl*) rDC.GetImpl();
273 // top
274 rDC.DrawLine( impl->m_vRclPaint.xLeft
275 ,impl->m_vRclPaint.yBottom
276 ,impl->m_vRclPaint.xRight
277 ,impl->m_vRclPaint.yBottom
278 );
279 // right
280 rDC.DrawLine( impl->m_vRclPaint.xRight
281 ,impl->m_vRclPaint.yBottom
282 ,impl->m_vRclPaint.xRight
283 ,impl->m_vRclPaint.yTop
284 );
285 // bottom
286 rDC.DrawLine( impl->m_vRclPaint.xRight
287 ,impl->m_vRclPaint.yTop
288 ,impl->m_vRclPaint.xLeft
289 ,impl->m_vRclPaint.yTop
290 );
291 // left
292 rDC.DrawLine( impl->m_vRclPaint.xLeft
293 ,impl->m_vRclPaint.yTop
294 ,impl->m_vRclPaint.xLeft
295 ,impl->m_vRclPaint.yBottom
296 );
297 wxDisableBitmap(rBmp, vGreyPen.GetColour().GetPixel());
298 } // end of wxBitmapButton::DrawButtonDisable
299
300 #endif // ndef for wxUSE_BMPBUTTON