wxInputConsumer
[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 #ifdef __GNUG__
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 bool wxCheckListBox::Create(wxWindow *parent,
59 wxWindowID id,
60 const wxPoint &pos,
61 const wxSize &size,
62 int n,
63 const wxString choices[],
64 long style,
65 const wxValidator& validator,
66 const wxString &name)
67 {
68 if ( !wxListBox::Create(parent, id, pos, size,
69 n, choices, style, validator, name) )
70 return FALSE;
71
72 CreateInputHandler(wxINP_HANDLER_CHECKLISTBOX);
73
74 return TRUE;
75 }
76
77 // ----------------------------------------------------------------------------
78 // wxCheckListBox functions
79 // ----------------------------------------------------------------------------
80
81 bool wxCheckListBox::IsChecked(size_t item) const
82 {
83 wxCHECK_MSG( item < m_checks.GetCount(), FALSE,
84 _T("invalid index in wxCheckListBox::IsChecked") );
85
86 return m_checks[item] != 0;
87 }
88
89 void wxCheckListBox::Check(size_t item, bool check)
90 {
91 wxCHECK_RET( item < m_checks.GetCount(),
92 _T("invalid index in wxCheckListBox::Check") );
93
94 // intermediate var is needed to avoid compiler warning with VC++
95 bool isChecked = m_checks[item] != 0;
96 if ( check != isChecked )
97 {
98 m_checks[item] = check;
99
100 RefreshItem(item);
101 }
102 }
103
104 // ----------------------------------------------------------------------------
105 // methods forwarded to wxListBox
106 // ----------------------------------------------------------------------------
107
108 void wxCheckListBox::Delete(int n)
109 {
110 wxCHECK_RET( n < GetCount(), _T("invalid index in wxListBox::Delete") );
111
112 wxListBox::Delete(n);
113
114 m_checks.RemoveAt(n);
115 }
116
117 int wxCheckListBox::DoAppend(const wxString& item)
118 {
119 int pos = wxListBox::DoAppend(item);
120
121 // the item is initially unchecked
122 m_checks.Insert(FALSE, pos);
123
124 return pos;
125 }
126
127 void wxCheckListBox::DoInsertItems(const wxArrayString& items, int pos)
128 {
129 wxListBox::DoInsertItems(items, pos);
130
131 size_t count = items.GetCount();
132 for ( size_t n = 0; n < count; n++ )
133 {
134 m_checks.Insert(FALSE, pos + n);
135 }
136 }
137
138 void wxCheckListBox::DoSetItems(const wxArrayString& items, void **clientData)
139 {
140 // call it first as it does DoClear()
141 wxListBox::DoSetItems(items, clientData);
142
143 size_t count = items.GetCount();
144 for ( size_t n = 0; n < count; n++ )
145 {
146 m_checks.Add(FALSE);
147 }
148 }
149
150 void wxCheckListBox::DoClear()
151 {
152 m_checks.Empty();
153 }
154
155 // ----------------------------------------------------------------------------
156 // drawing
157 // ----------------------------------------------------------------------------
158
159 wxSize wxCheckListBox::DoGetBestClientSize() const
160 {
161 wxSize size = wxListBox::DoGetBestClientSize();
162 size.x += GetRenderer()->GetCheckBitmapSize().x;
163
164 return size;
165 }
166
167 void wxCheckListBox::DoDrawRange(wxControlRenderer *renderer,
168 int itemFirst, int itemLast)
169 {
170 renderer->DrawCheckItems(this, itemFirst, itemLast);
171 }
172
173 // ----------------------------------------------------------------------------
174 // actions
175 // ----------------------------------------------------------------------------
176
177 bool wxCheckListBox::PerformAction(const wxControlAction& action,
178 long numArg,
179 const wxString& strArg)
180 {
181 if ( action == wxACTION_CHECKLISTBOX_TOGGLE )
182 {
183 int sel = (int)numArg;
184 if ( sel == -1 )
185 {
186 sel = GetSelection();
187 }
188
189 if ( sel != -1 )
190 {
191 Check(sel, !IsChecked(sel));
192
193 SendEvent(wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, sel);
194 }
195 }
196 else
197 {
198 return wxListBox::PerformAction(action, numArg, strArg);
199 }
200
201 return TRUE;
202 }
203
204 // ----------------------------------------------------------------------------
205 // wxStdCheckListboxInputHandler
206 // ----------------------------------------------------------------------------
207
208 wxStdCheckListboxInputHandler::
209 wxStdCheckListboxInputHandler(wxInputHandler *inphand)
210 : wxStdListboxInputHandler(inphand)
211 {
212 }
213
214 bool wxStdCheckListboxInputHandler::HandleKey(wxInputConsumer *consumer,
215 const wxKeyEvent& event,
216 bool pressed)
217 {
218 if ( pressed && (event.GetKeyCode() == WXK_SPACE) )
219 consumer->PerformAction(wxACTION_CHECKLISTBOX_TOGGLE);
220
221 return wxStdListboxInputHandler::HandleKey(consumer, event, pressed);
222 }
223
224 bool wxStdCheckListboxInputHandler::HandleMouse(wxInputConsumer *consumer,
225 const wxMouseEvent& event)
226 {
227 if ( event.LeftDown() || event.LeftDClick() )
228 {
229 wxCheckListBox *lbox = wxStaticCast(consumer->GetInputWindow(), wxCheckListBox);
230 int x, y;
231
232 wxPoint pt = event.GetPosition();
233 pt -= consumer->GetInputWindow()->GetClientAreaOrigin();
234 lbox->CalcUnscrolledPosition(pt.x, pt.y, &x, &y);
235
236 wxRenderer *renderer = lbox->GetRenderer();
237 x -= renderer->GetCheckItemMargin();
238
239 int item = y / lbox->GetLineHeight();
240 if ( x >= 0 &&
241 x < renderer->GetCheckBitmapSize().x &&
242 item >= 0 &&
243 item < lbox->GetCount() )
244 {
245 lbox->PerformAction(wxACTION_CHECKLISTBOX_TOGGLE, item);
246
247 return TRUE;
248 }
249 }
250
251 return wxStdListboxInputHandler::HandleMouse(consumer, event);
252 }
253
254 #endif // wxUSE_CHECKLISTBOX