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: bmpbuttn.cpp 40141 2006-07-16 20:35:29Z SN $
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
25IMPLEMENT_DYNAMIC_CLASS(wxBitmapButton, wxButton)
26
27#define BUTTON_HEIGHT_FACTOR (EDIT_CONTROL_FACTOR * 1.1)
28
29bool 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
102bool 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
170void 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
221void 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
258void 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
295void wxBitmapButton::SetDefault()
296{
297    wxButton::SetDefault();
298}
299
300#endif // ndef for wxUSE_BMPBUTTON
301