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