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