1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        src/msw/tglbtn.cpp
3 // Purpose:     Definition of the wxToggleButton class, which implements a
4 //              toggle button under wxMSW.
5 // Author:      John Norris, minor changes by Axel Schlueter
6 //              and William Gallafent.
7 // Modified by:
8 // Created:     08.02.01
9 // Copyright:   (c) 2000 Johnny C. Norris II
10 // Licence:     wxWindows licence
11 /////////////////////////////////////////////////////////////////////////////
12 
13 // ============================================================================
14 // declarations
15 // ============================================================================
16 
17 // ----------------------------------------------------------------------------
18 // headers
19 // ----------------------------------------------------------------------------
20 
21 #include "wx/wxprec.h"
22 
23 #ifdef __BORLANDC__
24     #pragma hdrstop
25 #endif
26 
27 #if wxUSE_TOGGLEBTN
28 
29 #include "wx/tglbtn.h"
30 
31 #ifndef WX_PRECOMP
32     #include "wx/button.h"
33     #include "wx/brush.h"
34     #include "wx/dcscreen.h"
35     #include "wx/settings.h"
36 
37     #include "wx/log.h"
38 #endif // WX_PRECOMP
39 
40 #include "wx/msw/private.h"
41 #include "wx/msw/private/button.h"
42 
43 // ----------------------------------------------------------------------------
44 // macros
45 // ----------------------------------------------------------------------------
46 
47 wxDEFINE_EVENT( wxEVT_TOGGLEBUTTON, wxCommandEvent );
48 
49 // ============================================================================
50 // implementation
51 // ============================================================================
52 
53 //-----------------------------------------------------------------------------
54 // wxBitmapToggleButton
55 //-----------------------------------------------------------------------------
56 
IMPLEMENT_DYNAMIC_CLASS(wxBitmapToggleButton,wxToggleButton)57 IMPLEMENT_DYNAMIC_CLASS(wxBitmapToggleButton, wxToggleButton)
58 
59 bool wxBitmapToggleButton::Create( wxWindow *parent, wxWindowID id,
60                 const wxBitmap& label,const wxPoint& pos, const wxSize& size, long style,
61                 const wxValidator& validator, const wxString& name )
62 {
63     if (!wxToggleButton::Create( parent, id, wxEmptyString, pos, size, style, validator, name ))
64         return false;
65 
66     SetBitmap(label);
67 
68     if (size.x == -1 || size.y == -1)
69     {
70         wxSize new_size = GetBestSize();
71         if (size.x != -1)
72             new_size.x = size.x;
73         if (size.y != -1)
74             new_size.y = size.y;
75         SetSize( new_size );
76     }
77 
78     return true;
79 }
80 
81 
82 // ----------------------------------------------------------------------------
83 // wxToggleButton
84 // ----------------------------------------------------------------------------
85 
IMPLEMENT_DYNAMIC_CLASS(wxToggleButton,wxControl)86 IMPLEMENT_DYNAMIC_CLASS(wxToggleButton, wxControl)
87 
88 void wxToggleButton::Init()
89 {
90     m_state = false;
91 }
92 
93 // Single check box item
Create(wxWindow * parent,wxWindowID id,const wxString & label,const wxPoint & pos,const wxSize & size,long style,const wxValidator & validator,const wxString & name)94 bool wxToggleButton::Create(wxWindow *parent,
95                             wxWindowID id,
96                             const wxString& label,
97                             const wxPoint& pos,
98                             const wxSize& size, long style,
99                             const wxValidator& validator,
100                             const wxString& name)
101 {
102     Init();
103 
104     if ( !CreateControl(parent, id, pos, size, style, validator, name) )
105         return false;
106 
107     // if the label contains several lines we must explicitly tell the button
108     // about it or it wouldn't draw it correctly ("\n"s would just appear as
109     // black boxes)
110     //
111     // NB: we do it here and not in MSWGetStyle() because we need the label
112     //     value and the label is not set yet when MSWGetStyle() is called
113     WXDWORD exstyle;
114     WXDWORD msStyle = MSWGetStyle(style, &exstyle);
115     msStyle |= wxMSWButton::GetMultilineStyle(label);
116 
117     return MSWCreateControl(wxT("BUTTON"), msStyle, pos, size, label, exstyle);
118 }
119 
MSWGetStyle(long style,WXDWORD * exstyle) const120 WXDWORD wxToggleButton::MSWGetStyle(long style, WXDWORD *exstyle) const
121 {
122     WXDWORD msStyle = wxControl::MSWGetStyle(style, exstyle);
123 
124     msStyle |= BS_AUTOCHECKBOX | BS_PUSHLIKE | WS_TABSTOP;
125 
126     if ( style & wxBU_LEFT )
127       msStyle |= BS_LEFT;
128     if ( style & wxBU_RIGHT )
129       msStyle |= BS_RIGHT;
130     if ( style & wxBU_TOP )
131       msStyle |= BS_TOP;
132     if ( style & wxBU_BOTTOM )
133       msStyle |= BS_BOTTOM;
134 
135     return msStyle;
136 }
137 
SetValue(bool val)138 void wxToggleButton::SetValue(bool val)
139 {
140     m_state = val;
141     if ( IsOwnerDrawn() )
142     {
143         Refresh();
144     }
145     else
146     {
147         ::SendMessage(GetHwnd(), BM_SETCHECK, val, 0);
148     }
149 }
150 
GetValue() const151 bool wxToggleButton::GetValue() const
152 {
153     if ( IsOwnerDrawn() )
154     {
155         return m_state;
156     }
157     else
158     {
159         return ::SendMessage(GetHwnd(), BM_GETCHECK, 0, 0) == BST_CHECKED;
160     }
161 }
162 
Command(wxCommandEvent & event)163 void wxToggleButton::Command(wxCommandEvent& event)
164 {
165     SetValue(event.GetInt() != 0);
166     ProcessCommand(event);
167 }
168 
MSWCommand(WXUINT param,WXWORD WXUNUSED (id))169 bool wxToggleButton::MSWCommand(WXUINT param, WXWORD WXUNUSED(id))
170 {
171     if ( param != BN_CLICKED && param != BN_DBLCLK )
172         return false;
173 
174     // first update the value so that user event handler gets the new
175     // toggle button value
176 
177     // ownerdrawn buttons don't manage their state themselves unlike usual
178     // auto checkboxes so do it ourselves in any case
179     m_state = !m_state;
180 
181     wxCommandEvent event(wxEVT_TOGGLEBUTTON, m_windowId);
182     event.SetInt(GetValue());
183     event.SetEventObject(this);
184     ProcessCommand(event);
185     return true;
186 }
187 
GetNormalState() const188 wxAnyButton::State wxToggleButton::GetNormalState() const
189 {
190     if ( GetValue() )
191         return State_Pressed;
192     else
193         return State_Normal;
194 }
195 
196 #endif // wxUSE_TOGGLEBTN
197