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