Added "metal" theme.
[wxWidgets.git] / src / univ / checkbox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: univ/checkbox.cpp
3 // Purpose: wxCheckBox implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 25.08.00
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows license
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #ifdef __GNUG__
21 #pragma implementation "univcheckbox.h"
22 #endif
23
24 #include "wx/wxprec.h"
25
26 #ifdef __BORLANDC__
27 #pragma hdrstop
28 #endif
29
30 #if wxUSE_CHECKBOX
31
32 #ifndef WX_PRECOMP
33 #include "wx/dcclient.h"
34 #include "wx/checkbox.h"
35 #include "wx/validate.h"
36
37 #include "wx/button.h" // for wxACTION_BUTTON_XXX
38 #endif
39
40 #include "wx/univ/theme.h"
41 #include "wx/univ/renderer.h"
42 #include "wx/univ/inphand.h"
43 #include "wx/univ/colschem.h"
44
45 // ============================================================================
46 // implementation
47 // ============================================================================
48
49 IMPLEMENT_DYNAMIC_CLASS(wxCheckBox, wxControl)
50
51 // ----------------------------------------------------------------------------
52 // wxCheckBox
53 // ----------------------------------------------------------------------------
54
55 void wxCheckBox::Init()
56 {
57 m_isPressed = FALSE;
58 m_status = Status_Unchecked;
59 }
60
61 bool wxCheckBox::Create(wxWindow *parent,
62 wxWindowID id,
63 const wxString &label,
64 const wxPoint &pos,
65 const wxSize &size,
66 long style,
67 const wxValidator& validator,
68 const wxString &name)
69 {
70 if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) )
71 return FALSE;
72
73 m_hasDialogBackground = TRUE;
74
75 SetLabel(label);
76 SetBestSize(size);
77
78 CreateInputHandler(wxINP_HANDLER_CHECKBOX);
79
80 return TRUE;
81 }
82
83 // ----------------------------------------------------------------------------
84 // checkbox interface
85 // ----------------------------------------------------------------------------
86
87 bool wxCheckBox::GetValue() const
88 {
89 return m_status == Status_Checked;
90 }
91
92 void wxCheckBox::SetValue(bool value)
93 {
94 Status status = value ? Status_Checked : Status_Unchecked;
95 if ( status != m_status )
96 {
97 m_status = status;
98
99 if ( m_status == Status_Checked )
100 {
101 // invoke the hook
102 OnCheck();
103 }
104
105 Refresh();
106 }
107 }
108
109 void wxCheckBox::OnCheck()
110 {
111 // we do nothing here
112 }
113
114 // ----------------------------------------------------------------------------
115 // indicator bitmaps
116 // ----------------------------------------------------------------------------
117
118 wxBitmap wxCheckBox::GetBitmap(State state, Status status) const
119 {
120 wxBitmap bmp = m_bitmaps[state][status];
121 if ( !bmp.Ok() )
122 bmp = m_bitmaps[State_Normal][status];
123
124 return bmp;
125 }
126
127 void wxCheckBox::SetBitmap(const wxBitmap& bmp, State state, Status status)
128 {
129 m_bitmaps[state][status] = bmp;
130 }
131
132 // ----------------------------------------------------------------------------
133 // drawing
134 // ----------------------------------------------------------------------------
135
136 wxCheckBox::State wxCheckBox::GetState(int flags) const
137 {
138 if ( flags & wxCONTROL_DISABLED )
139 return State_Disabled;
140 else if ( flags & wxCONTROL_PRESSED )
141 return State_Pressed;
142 else if ( flags & wxCONTROL_CURRENT )
143 return State_Current;
144 else
145 return State_Normal;
146 }
147
148 void wxCheckBox::DoDraw(wxControlRenderer *renderer)
149 {
150 int flags = GetStateFlags();
151
152 wxDC& dc = renderer->GetDC();
153 dc.SetFont(GetFont());
154 dc.SetTextForeground(GetForegroundColour());
155
156 if ( m_status == Status_Checked )
157 flags |= wxCONTROL_CHECKED;
158
159 wxBitmap bitmap(GetBitmap(GetState(flags), m_status));
160
161 renderer->GetRenderer()->
162 DrawCheckButton(dc,
163 GetLabel(),
164 bitmap,
165 renderer->GetRect(),
166 flags,
167 GetWindowStyle() & wxALIGN_RIGHT ? wxALIGN_RIGHT
168 : wxALIGN_LEFT,
169 GetAccelIndex());
170 }
171
172 // ----------------------------------------------------------------------------
173 // geometry calculations
174 // ----------------------------------------------------------------------------
175
176 wxSize wxCheckBox::GetBitmapSize() const
177 {
178 wxBitmap bmp = GetBitmap(State_Normal, Status_Checked);
179 return bmp.Ok() ? wxSize(bmp.GetWidth(), bmp.GetHeight())
180 : GetRenderer()->GetCheckBitmapSize();
181 }
182
183 wxSize wxCheckBox::DoGetBestClientSize() const
184 {
185 wxClientDC dc(wxConstCast(this, wxCheckBox));
186 dc.SetFont(GetFont());
187 wxCoord width, height;
188 dc.GetMultiLineTextExtent(GetLabel(), &width, &height);
189
190 wxSize sizeBmp = GetBitmapSize();
191 if ( height < sizeBmp.y )
192 height = sizeBmp.y;
193
194 #if wxUNIV_COMPATIBLE_MSW
195 // this looks better but is different from what wxMSW does
196 height += GetCharHeight()/2;
197 #endif // wxUNIV_COMPATIBLE_MSW
198
199 width += sizeBmp.x + 2*GetCharWidth();
200
201 return wxSize(width, height);
202 }
203
204 // ----------------------------------------------------------------------------
205 // checkbox actions
206 // ----------------------------------------------------------------------------
207
208 void wxCheckBox::Press()
209 {
210 if ( !m_isPressed )
211 {
212 m_isPressed = TRUE;
213
214 Refresh();
215 }
216 }
217
218 void wxCheckBox::Release()
219 {
220 if ( m_isPressed )
221 {
222 m_isPressed = FALSE;
223
224 Refresh();
225 }
226 }
227
228 void wxCheckBox::Toggle()
229 {
230 m_isPressed = FALSE;
231
232 ChangeValue(!GetValue());
233 }
234
235 void wxCheckBox::ChangeValue(bool value)
236 {
237 SetValue(value);
238
239 SendEvent();
240 }
241
242 void wxCheckBox::SendEvent()
243 {
244 wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, GetId());
245 InitCommandEvent(event);
246 event.SetInt(IsChecked());
247 Command(event);
248 }
249
250 // ----------------------------------------------------------------------------
251 // input handling
252 // ----------------------------------------------------------------------------
253
254 bool wxCheckBox::PerformAction(const wxControlAction& action,
255 long numArg,
256 const wxString& strArg)
257 {
258 if ( action == wxACTION_BUTTON_PRESS )
259 Press();
260 else if ( action == wxACTION_BUTTON_RELEASE )
261 Release();
262 if ( action == wxACTION_CHECKBOX_CHECK )
263 ChangeValue(TRUE);
264 else if ( action == wxACTION_CHECKBOX_CLEAR )
265 ChangeValue(FALSE);
266 else if ( action == wxACTION_CHECKBOX_TOGGLE )
267 Toggle();
268 else
269 return wxControl::PerformAction(action, numArg, strArg);
270
271 return TRUE;
272 }
273
274 // ----------------------------------------------------------------------------
275 // wxStdCheckboxInputHandler
276 // ----------------------------------------------------------------------------
277
278 wxStdCheckboxInputHandler::wxStdCheckboxInputHandler(wxInputHandler *inphand)
279 : wxStdButtonInputHandler(inphand)
280 {
281 }
282
283 bool wxStdCheckboxInputHandler::HandleActivation(wxInputConsumer *consumer,
284 bool activated)
285 {
286 // only the focused checkbox appearance changes when the app gains/loses
287 // activation
288 return consumer->GetInputWindow()->IsFocused();
289 }
290
291 #endif // wxUSE_CHECKBOX