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