]> git.saurik.com Git - wxWidgets.git/blob - src/univ/checkbox.cpp
patch from Dimitri fixing crashes when decoding the invalid GIFs
[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 SetLabel(label);
74 SetBestSize(size);
75
76 CreateInputHandler(wxINP_HANDLER_CHECKBOX);
77
78 return TRUE;
79 }
80
81 // ----------------------------------------------------------------------------
82 // checkbox interface
83 // ----------------------------------------------------------------------------
84
85 bool wxCheckBox::GetValue() const
86 {
87 return m_status == Status_Checked;
88 }
89
90 void wxCheckBox::SetValue(bool value)
91 {
92 Status status = value ? Status_Checked : Status_Unchecked;
93 if ( status != m_status )
94 {
95 m_status = status;
96
97 if ( m_status == Status_Checked )
98 {
99 // invoke the hook
100 OnCheck();
101 }
102
103 Refresh();
104 }
105 }
106
107 void wxCheckBox::OnCheck()
108 {
109 // we do nothing here
110 }
111
112 // ----------------------------------------------------------------------------
113 // indicator bitmaps
114 // ----------------------------------------------------------------------------
115
116 wxBitmap wxCheckBox::GetBitmap(State state, Status status) const
117 {
118 wxBitmap bmp = m_bitmaps[state][status];
119 if ( !bmp.Ok() )
120 bmp = m_bitmaps[State_Normal][status];
121
122 return bmp;
123 }
124
125 void wxCheckBox::SetBitmap(const wxBitmap& bmp, State state, Status status)
126 {
127 m_bitmaps[state][status] = bmp;
128 }
129
130 // ----------------------------------------------------------------------------
131 // drawing
132 // ----------------------------------------------------------------------------
133
134 wxCheckBox::State wxCheckBox::GetState(int flags) const
135 {
136 if ( flags & wxCONTROL_DISABLED )
137 return State_Disabled;
138 else if ( flags & wxCONTROL_PRESSED )
139 return State_Pressed;
140 else if ( flags & wxCONTROL_CURRENT )
141 return State_Current;
142 else
143 return State_Normal;
144 }
145
146 void wxCheckBox::DoDraw(wxControlRenderer *renderer)
147 {
148 int flags = GetStateFlags();
149
150 wxDC& dc = renderer->GetDC();
151 dc.SetFont(GetFont());
152 dc.SetTextForeground(GetForegroundColour());
153
154 if ( m_status == Status_Checked )
155 flags |= wxCONTROL_CHECKED;
156
157 wxBitmap bitmap(GetBitmap(GetState(flags), m_status));
158
159 renderer->GetRenderer()->
160 DrawCheckButton(dc,
161 GetLabel(),
162 bitmap,
163 renderer->GetRect(),
164 flags,
165 GetWindowStyle() & wxALIGN_RIGHT ? wxALIGN_RIGHT
166 : wxALIGN_LEFT,
167 GetAccelIndex());
168 }
169
170 // ----------------------------------------------------------------------------
171 // geometry calculations
172 // ----------------------------------------------------------------------------
173
174 wxSize wxCheckBox::GetBitmapSize() const
175 {
176 wxBitmap bmp = GetBitmap(State_Normal, Status_Checked);
177 return bmp.Ok() ? wxSize(bmp.GetWidth(), bmp.GetHeight())
178 : GetRenderer()->GetCheckBitmapSize();
179 }
180
181 wxSize wxCheckBox::DoGetBestClientSize() const
182 {
183 wxClientDC dc(wxConstCast(this, wxCheckBox));
184 dc.SetFont(GetFont());
185 wxCoord width, height;
186 dc.GetMultiLineTextExtent(GetLabel(), &width, &height);
187
188 wxSize sizeBmp = GetBitmapSize();
189 if ( height < sizeBmp.y )
190 height = sizeBmp.y;
191
192 #if wxUNIV_COMPATIBLE_MSW
193 // this looks better but is different from what wxMSW does
194 height += GetCharHeight()/2;
195 #endif // wxUNIV_COMPATIBLE_MSW
196
197 width += sizeBmp.x + 2*GetCharWidth();
198
199 return wxSize(width, height);
200 }
201
202 // ----------------------------------------------------------------------------
203 // checkbox actions
204 // ----------------------------------------------------------------------------
205
206 void wxCheckBox::Press()
207 {
208 if ( !m_isPressed )
209 {
210 m_isPressed = TRUE;
211
212 Refresh();
213 }
214 }
215
216 void wxCheckBox::Release()
217 {
218 if ( m_isPressed )
219 {
220 m_isPressed = FALSE;
221
222 Refresh();
223 }
224 }
225
226 void wxCheckBox::Toggle()
227 {
228 m_isPressed = FALSE;
229
230 ChangeValue(!GetValue());
231 }
232
233 void wxCheckBox::ChangeValue(bool value)
234 {
235 SetValue(value);
236
237 SendEvent();
238 }
239
240 void wxCheckBox::SendEvent()
241 {
242 wxCommandEvent event(wxEVT_COMMAND_CHECKBOX_CLICKED, GetId());
243 InitCommandEvent(event);
244 event.SetInt(IsChecked());
245 Command(event);
246 }
247
248 // ----------------------------------------------------------------------------
249 // input handling
250 // ----------------------------------------------------------------------------
251
252 bool wxCheckBox::PerformAction(const wxControlAction& action,
253 long numArg,
254 const wxString& strArg)
255 {
256 if ( action == wxACTION_BUTTON_PRESS )
257 Press();
258 else if ( action == wxACTION_BUTTON_RELEASE )
259 Release();
260 if ( action == wxACTION_CHECKBOX_CHECK )
261 ChangeValue(TRUE);
262 else if ( action == wxACTION_CHECKBOX_CLEAR )
263 ChangeValue(FALSE);
264 else if ( action == wxACTION_CHECKBOX_TOGGLE )
265 Toggle();
266 else
267 return wxControl::PerformAction(action, numArg, strArg);
268
269 return TRUE;
270 }
271
272 // ----------------------------------------------------------------------------
273 // wxStdCheckboxInputHandler
274 // ----------------------------------------------------------------------------
275
276 wxStdCheckboxInputHandler::wxStdCheckboxInputHandler(wxInputHandler *inphand)
277 : wxStdButtonInputHandler(inphand)
278 {
279 }
280
281 bool wxStdCheckboxInputHandler::HandleActivation(wxInputConsumer *consumer,
282 bool activated)
283 {
284 // only the focused checkbox appearance changes when the app gains/loses
285 // activation
286 return consumer->GetInputWindow()->IsFocused();
287 }
288
289 #endif // wxUSE_CHECKBOX