]> git.saurik.com Git - wxWidgets.git/blob - src/univ/checklst.cpp
Fixed a confusion between window and client size that could lead to
[wxWidgets.git] / src / univ / checklst.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/univ/checklst.cpp
3 // Purpose: wxCheckListBox implementation
4 // Author: Vadim Zeitlin
5 // Modified by:
6 // Created: 12.09.00
7 // RCS-ID: $Id$
8 // Copyright: (c) 2000 SciTech Software, Inc. (www.scitechsoft.com)
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 #include "wx/wxprec.h"
21
22 #ifdef __BORLANDC__
23 #pragma hdrstop
24 #endif
25
26 #if wxUSE_CHECKLISTBOX
27
28 #include "wx/checklst.h"
29
30 #ifndef WX_PRECOMP
31 #include "wx/log.h"
32 #include "wx/dcclient.h"
33 #include "wx/validate.h"
34 #endif
35
36 #include "wx/univ/renderer.h"
37 #include "wx/univ/inphand.h"
38 #include "wx/univ/theme.h"
39
40 // ----------------------------------------------------------------------------
41 // wxStdCheckListBoxInputHandler
42 // ----------------------------------------------------------------------------
43
44 class WXDLLEXPORT wxStdCheckListboxInputHandler : public wxStdInputHandler
45 {
46 public:
47 wxStdCheckListboxInputHandler(wxInputHandler *inphand);
48
49 virtual bool HandleKey(wxInputConsumer *consumer,
50 const wxKeyEvent& event,
51 bool pressed);
52 virtual bool HandleMouse(wxInputConsumer *consumer,
53 const wxMouseEvent& event);
54 };
55
56 // ============================================================================
57 // implementation of wxCheckListBox
58 // ============================================================================
59
60 IMPLEMENT_DYNAMIC_CLASS(wxCheckListBox, wxListBox)
61
62 // ----------------------------------------------------------------------------
63 // creation
64 // ----------------------------------------------------------------------------
65
66 void wxCheckListBox::Init()
67 {
68 }
69
70 wxCheckListBox::wxCheckListBox(wxWindow *parent,
71 wxWindowID id,
72 const wxPoint &pos,
73 const wxSize &size,
74 const wxArrayString& choices,
75 long style,
76 const wxValidator& validator,
77 const wxString &name)
78 {
79 Init();
80
81 Create(parent, id, pos, size, choices, style, validator, name);
82 }
83
84 bool wxCheckListBox::Create(wxWindow *parent,
85 wxWindowID id,
86 const wxPoint &pos,
87 const wxSize &size,
88 const wxArrayString& choices,
89 long style,
90 const wxValidator& validator,
91 const wxString &name)
92 {
93 wxCArrayString chs(choices);
94
95 return Create(parent, id, pos, size, chs.GetCount(), chs.GetStrings(),
96 style, validator, name);
97 }
98
99 bool wxCheckListBox::Create(wxWindow *parent,
100 wxWindowID id,
101 const wxPoint &pos,
102 const wxSize &size,
103 int n,
104 const wxString choices[],
105 long style,
106 const wxValidator& validator,
107 const wxString &name)
108 {
109 if ( !wxListBox::Create(parent, id, pos, size,
110 n, choices, style, validator, name) )
111 return false;
112
113 CreateInputHandler(wxINP_HANDLER_CHECKLISTBOX);
114
115 return true;
116 }
117
118 // ----------------------------------------------------------------------------
119 // wxCheckListBox functions
120 // ----------------------------------------------------------------------------
121
122 bool wxCheckListBox::IsChecked(unsigned int item) const
123 {
124 wxCHECK_MSG( IsValid(item), false,
125 _T("invalid index in wxCheckListBox::IsChecked") );
126
127 return m_checks[item] != 0;
128 }
129
130 void wxCheckListBox::Check(unsigned int item, bool check)
131 {
132 wxCHECK_RET( IsValid(item),
133 _T("invalid index in wxCheckListBox::Check") );
134
135 // intermediate var is needed to avoid compiler warning with VC++
136 bool isChecked = m_checks[item] != 0;
137 if ( check != isChecked )
138 {
139 m_checks[item] = check;
140
141 RefreshItem(item);
142 }
143 }
144
145 // ----------------------------------------------------------------------------
146 // methods forwarded to wxListBox
147 // ----------------------------------------------------------------------------
148
149 void wxCheckListBox::Delete(unsigned int n)
150 {
151 wxCHECK_RET( IsValid(n), _T("invalid index in wxListBox::Delete") );
152
153 wxListBox::Delete(n);
154
155 m_checks.RemoveAt(n);
156 }
157
158 int wxCheckListBox::DoAppend(const wxString& item)
159 {
160 int pos = wxListBox::DoAppend(item);
161
162 // the item is initially unchecked
163 m_checks.Insert(false, pos);
164
165 return pos;
166 }
167
168 void wxCheckListBox::DoInsertItems(const wxArrayString& items, unsigned int pos)
169 {
170 wxListBox::DoInsertItems(items, pos);
171
172 unsigned int count = items.GetCount();
173 for ( unsigned int n = 0; n < count; n++ )
174 {
175 m_checks.Insert(false, pos + n);
176 }
177 }
178
179 void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData)
180 {
181 // call it first as it does DoClear()
182 wxListBox::DoSetItems(items, clientData);
183
184 unsigned int count = items.GetCount();
185 for ( unsigned int n = 0; n < count; n++ )
186 {
187 m_checks.Add(false);
188 }
189 }
190
191 void wxCheckListBox::DoClear()
192 {
193 m_checks.Empty();
194 }
195
196 // ----------------------------------------------------------------------------
197 // drawing
198 // ----------------------------------------------------------------------------
199
200 wxSize wxCheckListBox::DoGetBestClientSize() const
201 {
202 wxSize size = wxListBox::DoGetBestClientSize();
203 size.x += GetRenderer()->GetCheckBitmapSize().x;
204
205 return size;
206 }
207
208 void wxCheckListBox::DoDrawRange(wxControlRenderer *renderer,
209 int itemFirst, int itemLast)
210 {
211 renderer->DrawCheckItems(this, itemFirst, itemLast);
212 }
213
214 // ----------------------------------------------------------------------------
215 // actions
216 // ----------------------------------------------------------------------------
217
218 bool wxCheckListBox::PerformAction(const wxControlAction& action,
219 long numArg,
220 const wxString& strArg)
221 {
222 if ( action == wxACTION_CHECKLISTBOX_TOGGLE )
223 {
224 int sel = (int)numArg;
225 if ( sel == -1 )
226 {
227 sel = GetSelection();
228 }
229
230 if ( sel != -1 )
231 {
232 Check(sel, !IsChecked(sel));
233
234 SendEvent(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, sel);
235 }
236 }
237 else
238 {
239 return wxListBox::PerformAction(action, numArg, strArg);
240 }
241
242 return true;
243 }
244
245 /* static */
246 wxInputHandler *wxCheckListBox::GetStdInputHandler(wxInputHandler *handlerDef)
247 {
248 static wxStdCheckListboxInputHandler s_handler(handlerDef);
249
250 return &s_handler;
251 }
252
253 // ----------------------------------------------------------------------------
254 // wxStdCheckListboxInputHandler
255 // ----------------------------------------------------------------------------
256
257 wxStdCheckListboxInputHandler::
258 wxStdCheckListboxInputHandler(wxInputHandler *inphand)
259 : wxStdInputHandler(wxListBox::GetStdInputHandler(inphand))
260 {
261 }
262
263 bool wxStdCheckListboxInputHandler::HandleKey(wxInputConsumer *consumer,
264 const wxKeyEvent& event,
265 bool pressed)
266 {
267 if ( pressed && (event.GetKeyCode() == WXK_SPACE) )
268 consumer->PerformAction(wxACTION_CHECKLISTBOX_TOGGLE);
269
270 return wxStdInputHandler::HandleKey(consumer, event, pressed);
271 }
272
273 bool wxStdCheckListboxInputHandler::HandleMouse(wxInputConsumer *consumer,
274 const wxMouseEvent& event)
275 {
276 if ( event.LeftDown() || event.LeftDClick() )
277 {
278 wxCheckListBox *lbox = wxStaticCast(consumer->GetInputWindow(), wxCheckListBox);
279 int x, y;
280
281 wxPoint pt = event.GetPosition();
282 pt -= consumer->GetInputWindow()->GetClientAreaOrigin();
283 lbox->CalcUnscrolledPosition(pt.x, pt.y, &x, &y);
284
285 wxRenderer *renderer = lbox->GetRenderer();
286 x -= renderer->GetCheckItemMargin();
287
288 int item = y / lbox->GetLineHeight();
289 if ( x >= 0 &&
290 x < renderer->GetCheckBitmapSize().x &&
291 item >= 0 &&
292 (unsigned int)item < lbox->GetCount() )
293 {
294 lbox->PerformAction(wxACTION_CHECKLISTBOX_TOGGLE, item);
295
296 return true;
297 }
298 }
299
300 return wxStdInputHandler::HandleMouse(consumer, event);
301 }
302
303 #endif // wxUSE_CHECKLISTBOX