1 ///////////////////////////////////////////////////////////////////////////////
2 // Name:        checklst.cpp
3 // Purpose:     wxCheckListBox sample
4 // Author:      Vadim Zeitlin
5 // Modified by:
6 // Created:     13.11.97
7 // RCS-ID:      $Id: checklst.cpp 43080 2006-11-05 00:45:27Z VZ $
8 // Copyright:   (c) 1998 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr>
9 // Licence:     wxWindows license
10 ///////////////////////////////////////////////////////////////////////////////
11 
12 // For compilers that support precompilation, includes "wx.h".
13 #include "wx/wxprec.h"
14 
15 #ifdef __BORLANDC__
16     #pragma hdrstop
17 #endif
18 
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22 
23 #ifdef __WXMSW__
24     #include  "wx/ownerdrw.h"
25 #endif
26 
27 #include  "wx/log.h"
28 
29 #include  "wx/sizer.h"
30 #include  "wx/menuitem.h"
31 #include  "wx/checklst.h"
32 
33 #if !wxUSE_CHECKLISTBOX
34     #error "This sample can't be built without wxUSE_CHECKLISTBOX"
35 #endif // wxUSE_CHECKLISTBOX
36 
37 // Define a new application type
38 class CheckListBoxApp: public wxApp
39 {
40 public:
41     bool OnInit();
42 };
43 
44 // Define a new frame type
45 class CheckListBoxFrame : public wxFrame
46 {
47 public:
48     // ctor & dtor
49     CheckListBoxFrame(wxFrame *frame, const wxChar *title);
~CheckListBoxFrame()50     virtual ~CheckListBoxFrame(){};
51 
52     // notifications
53     void OnQuit(wxCommandEvent& event);
54     void OnAbout(wxCommandEvent& event);
55 
56     void OnCheckFirstItem(wxCommandEvent& event);
57     void OnUncheckFirstItem(wxCommandEvent& event);
58     void OnToggleFirstItem(wxCommandEvent& event);
59     void OnToggleSelection(wxCommandEvent& event);
60     void OnToggleSorting(wxCommandEvent& event);
61     void OnToggleExtended(wxCommandEvent& event);
62 
63     void OnInsertItemsStart(wxCommandEvent& event);
64     void OnInsertItemsMiddle(wxCommandEvent& event);
65     void OnInsertItemsEnd(wxCommandEvent& event);
66     void OnAppendItems(wxCommandEvent& event);
67     void OnRemoveItems(wxCommandEvent& event);
68 
69     void OnGetBestSize(wxCommandEvent& event);
70 
71     void OnMakeItemFirst(wxCommandEvent& event);
72 
73     void OnListboxSelect(wxCommandEvent& event);
74     void OnCheckboxToggle(wxCommandEvent& event);
75     void OnListboxDblClick(wxCommandEvent& event);
76 
77     void OnButtonUp(wxCommandEvent& event);
78     void OnButtonDown(wxCommandEvent& event);
79 
80 private:
81     void CreateCheckListbox(long flags = 0);
82 
83     void OnButtonMove(bool up);
84 
85     void AdjustColour(size_t index);
86 
87     wxPanel *m_panel;
88 
89     wxCheckListBox *m_pListBox;
90 
91     DECLARE_EVENT_TABLE()
92 };
93 
94 enum
95 {
96     Menu_About = wxID_ABOUT,
97     Menu_Quit = wxID_EXIT,
98 
99     Menu_CheckFirst = wxID_HIGHEST,
100     Menu_UncheckFirst,
101     Menu_ToggleFirst,
102     Menu_Selection,
103     Menu_Extended,
104     Menu_Sorting,
105     Menu_InsertItemsStart,
106     Menu_InsertItemsMiddle,
107     Menu_InsertItemsEnd,
108     Menu_AppendItems,
109     Menu_RemoveItems,
110     Menu_GetBestSize,
111     Menu_MakeItemFirst,
112 
113     Control_First,
114     Control_Listbox,
115 
116     Btn_Up = wxID_UP,
117     Btn_Down = wxID_DOWN
118 };
119 
BEGIN_EVENT_TABLE(CheckListBoxFrame,wxFrame)120 BEGIN_EVENT_TABLE(CheckListBoxFrame, wxFrame)
121     EVT_MENU(Menu_About, CheckListBoxFrame::OnAbout)
122     EVT_MENU(Menu_Quit, CheckListBoxFrame::OnQuit)
123 
124     EVT_MENU(Menu_CheckFirst, CheckListBoxFrame::OnCheckFirstItem)
125     EVT_MENU(Menu_UncheckFirst, CheckListBoxFrame::OnUncheckFirstItem)
126     EVT_MENU(Menu_ToggleFirst, CheckListBoxFrame::OnToggleFirstItem)
127     EVT_MENU(Menu_Selection, CheckListBoxFrame::OnToggleSelection)
128     EVT_MENU(Menu_Extended, CheckListBoxFrame::OnToggleExtended)
129     EVT_MENU(Menu_Sorting, CheckListBoxFrame::OnToggleSorting)
130 
131     EVT_MENU(Menu_InsertItemsStart, CheckListBoxFrame::OnInsertItemsStart)
132     EVT_MENU(Menu_InsertItemsMiddle, CheckListBoxFrame::OnInsertItemsMiddle)
133     EVT_MENU(Menu_InsertItemsEnd, CheckListBoxFrame::OnInsertItemsEnd)
134     EVT_MENU(Menu_AppendItems, CheckListBoxFrame::OnAppendItems)
135     EVT_MENU(Menu_RemoveItems, CheckListBoxFrame::OnRemoveItems)
136 
137     EVT_MENU(Menu_GetBestSize, CheckListBoxFrame::OnGetBestSize)
138 
139     EVT_MENU(Menu_MakeItemFirst, CheckListBoxFrame::OnMakeItemFirst)
140 
141     EVT_LISTBOX(Control_Listbox, CheckListBoxFrame::OnListboxSelect)
142     EVT_CHECKLISTBOX(Control_Listbox, CheckListBoxFrame::OnCheckboxToggle)
143     EVT_LISTBOX_DCLICK(Control_Listbox, CheckListBoxFrame::OnListboxDblClick)
144 
145     EVT_BUTTON(Btn_Up, CheckListBoxFrame::OnButtonUp)
146     EVT_BUTTON(Btn_Down, CheckListBoxFrame::OnButtonDown)
147 END_EVENT_TABLE()
148 
149 IMPLEMENT_APP(CheckListBoxApp)
150 
151 // init our app: create windows
152 bool CheckListBoxApp::OnInit(void)
153 {
154     CheckListBoxFrame *pFrame = new CheckListBoxFrame
155                                     (
156                                      NULL,
157                                      _T("wxWidgets Checklistbox Sample")
158                                     );
159     SetTopWindow(pFrame);
160 
161     return true;
162 }
163 
164 // main frame constructor
CheckListBoxFrame(wxFrame * frame,const wxChar * title)165 CheckListBoxFrame::CheckListBoxFrame(wxFrame *frame,
166                                      const wxChar *title)
167                  : wxFrame(frame, wxID_ANY, title)
168 {
169 #if wxUSE_STATUSBAR
170     // create the status line
171     const int widths[] = { -1, 60 };
172     CreateStatusBar(2);
173     SetStatusWidths(2, widths);
174 #endif // wxUSE_STATUSBAR
175 
176     // Make a menubar
177     // --------------
178 
179     // file submenu
180     wxMenu *menuFile = new wxMenu;
181     menuFile->Append(Menu_About, _T("&About...\tF1"));
182     menuFile->AppendSeparator();
183     menuFile->Append(Menu_Quit, _T("E&xit\tAlt-X"));
184 
185     // listbox submenu
186     wxMenu *menuList = new wxMenu;
187     menuList->Append(Menu_CheckFirst, _T("Check the first item\tCtrl-C"));
188     menuList->Append(Menu_UncheckFirst, _T("Uncheck the first item\tCtrl-U"));
189     menuList->Append(Menu_ToggleFirst, _T("Toggle the first item\tCtrl-T"));
190     menuList->AppendSeparator();
191     menuList->Append(Menu_InsertItemsStart, _T("Insert some item at the beginning"));
192     menuList->Append(Menu_InsertItemsMiddle, _T("Insert some item at the middle"));
193     menuList->Append(Menu_InsertItemsEnd, _T("Insert some item at the end"));
194     menuList->Append(Menu_AppendItems, _T("Append some items\tCtrl-A"));
195     menuList->Append(Menu_RemoveItems, _T("Remove some items"));
196     menuList->AppendSeparator();
197     menuList->AppendCheckItem(Menu_Selection, _T("Multiple selection\tCtrl-M"));
198     menuList->AppendCheckItem(Menu_Extended, _T("Extended selection"));
199     menuList->AppendCheckItem(Menu_Sorting, _T("Sorting"));
200     menuList->AppendSeparator();
201     menuList->Append(Menu_GetBestSize, _T("Get the best size of the checklistbox control"));
202     menuList->AppendSeparator();
203     menuList->Append(Menu_MakeItemFirst, _T("Make selected item the first item"));
204 
205 
206     // put it all together
207     wxMenuBar *menu_bar = new wxMenuBar;
208     menu_bar->Append(menuFile, _T("&File"));
209     menu_bar->Append(menuList, _T("&List"));
210     SetMenuBar(menu_bar);
211 
212     // make a panel with some controls
213     m_panel = new wxPanel(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL);
214 
215     CreateCheckListbox();
216 
217     // create buttons for moving the items around
218     wxButton *button1 = new wxButton(m_panel, Btn_Up);
219     wxButton *button2 = new wxButton(m_panel, Btn_Down);
220 
221 
222     wxBoxSizer *mainsizer = new wxBoxSizer( wxVERTICAL );
223 
224     mainsizer->Add( m_pListBox, 1, wxGROW|wxALL, 10 );
225 
226     wxBoxSizer *bottomsizer = new wxBoxSizer( wxHORIZONTAL );
227 
228     bottomsizer->Add( button1, 0, wxALL, 10 );
229     bottomsizer->Add( button2, 0, wxALL, 10 );
230 
231     mainsizer->Add( bottomsizer, 0, wxCENTER );
232 
233     // tell frame to make use of sizer (or constraints, if any)
234     m_panel->SetAutoLayout( true );
235     m_panel->SetSizer( mainsizer );
236 
237 #ifndef __WXWINCE__
238     // don't allow frame to get smaller than what the sizers tell ye
239     mainsizer->SetSizeHints( this );
240 #endif
241 
242     Show(true);
243 }
244 
CreateCheckListbox(long flags)245 void CheckListBoxFrame::CreateCheckListbox(long flags)
246 {
247     // check list box
248     static const wxChar *aszChoices[] =
249     {
250         _T("Zeroth"),
251         _T("First"), _T("Second"), _T("Third"),
252         _T("Fourth"), _T("Fifth"), _T("Sixth"),
253         _T("Seventh"), _T("Eighth"), _T("Nineth")
254     };
255 
256     wxString *astrChoices = new wxString[WXSIZEOF(aszChoices)];
257     unsigned int ui;
258     for ( ui = 0; ui < WXSIZEOF(aszChoices); ui++ )
259         astrChoices[ui] = aszChoices[ui];
260 
261     m_pListBox = new wxCheckListBox
262         (
263          m_panel,               // parent
264          Control_Listbox,       // control id
265          wxPoint(10, 10),       // listbox poistion
266          wxSize(400, 100),      // listbox size
267          WXSIZEOF(aszChoices),  // number of strings
268          astrChoices,           // array of strings
269          flags
270         );
271 
272     delete [] astrChoices;
273 
274     // set grey background for every second entry
275     for ( ui = 0; ui < WXSIZEOF(aszChoices); ui += 2 ) {
276         AdjustColour(ui);
277     }
278 
279     m_pListBox->Check(2);
280     m_pListBox->Select(3);
281 }
282 
OnQuit(wxCommandEvent & WXUNUSED (event))283 void CheckListBoxFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
284 {
285     Close(true);
286 }
287 
OnAbout(wxCommandEvent & WXUNUSED (event))288 void CheckListBoxFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
289 {
290     wxMessageBox(wxT("Demo of wxCheckListBox control\n(c) Vadim Zeitlin 1998-2002"),
291                  wxT("About wxCheckListBox"),
292                  wxICON_INFORMATION, this);
293 }
294 
OnCheckFirstItem(wxCommandEvent & WXUNUSED (event))295 void CheckListBoxFrame::OnCheckFirstItem(wxCommandEvent& WXUNUSED(event))
296 {
297     if ( !m_pListBox->IsEmpty() )
298         m_pListBox->Check(0);
299 }
300 
OnUncheckFirstItem(wxCommandEvent & WXUNUSED (event))301 void CheckListBoxFrame::OnUncheckFirstItem(wxCommandEvent& WXUNUSED(event))
302 {
303     if ( !m_pListBox->IsEmpty() )
304         m_pListBox->Check(0, false);
305 }
306 
OnToggleFirstItem(wxCommandEvent & WXUNUSED (event))307 void CheckListBoxFrame::OnToggleFirstItem(wxCommandEvent& WXUNUSED(event))
308 {
309     if ( !m_pListBox->IsEmpty() )
310         m_pListBox->Check(0, !m_pListBox->IsChecked(0));
311 }
312 
OnInsertItemsStart(wxCommandEvent & WXUNUSED (event))313 void CheckListBoxFrame::OnInsertItemsStart(wxCommandEvent& WXUNUSED(event))
314 {
315     static size_t s_nItem = 0;
316     wxArrayString items;
317     items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
318     items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
319     items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
320 
321     m_pListBox->InsertItems(items, 0);//m_pListBox->GetCount());
322 }
323 
OnInsertItemsMiddle(wxCommandEvent & WXUNUSED (event))324 void CheckListBoxFrame::OnInsertItemsMiddle(wxCommandEvent& WXUNUSED(event))
325 {
326     static size_t s_nItem = 0;
327     wxArrayString items;
328     items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
329     items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
330     items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
331 
332     m_pListBox->InsertItems(items, m_pListBox->GetCount() ? 1 : 0);
333 }
334 
OnInsertItemsEnd(wxCommandEvent & WXUNUSED (event))335 void CheckListBoxFrame::OnInsertItemsEnd(wxCommandEvent& WXUNUSED(event))
336 {
337     static size_t s_nItem = 0;
338     wxArrayString items;
339     items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
340     items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
341     items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
342 
343     m_pListBox->InsertItems(items, m_pListBox->GetCount() );
344 }
345 
OnAppendItems(wxCommandEvent & WXUNUSED (event))346 void CheckListBoxFrame::OnAppendItems(wxCommandEvent& WXUNUSED(event))
347 {
348     static size_t s_nItem = 0;
349     m_pListBox->Append(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
350     m_pListBox->Append(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
351     m_pListBox->Append(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
352 }
353 
OnRemoveItems(wxCommandEvent & WXUNUSED (event))354 void CheckListBoxFrame::OnRemoveItems(wxCommandEvent& WXUNUSED(event))
355 {
356     if(m_pListBox->GetCount())
357         m_pListBox->Delete(0);
358     if(m_pListBox->GetCount())
359         m_pListBox->Delete(0);
360     if(m_pListBox->GetCount())
361         m_pListBox->Delete(0);
362 }
363 
OnGetBestSize(wxCommandEvent & WXUNUSED (event))364 void CheckListBoxFrame::OnGetBestSize(wxCommandEvent& WXUNUSED(event))
365 {
366     wxSize bestSize = m_pListBox->GetBestSize();
367 
368     wxMessageBox(wxString::Format(wxT("Best size of the checklistbox is:[%i,%i]"),
369                                   bestSize.x, bestSize.y
370                                  )
371                 );
372 }
373 
OnMakeItemFirst(wxCommandEvent & WXUNUSED (event))374 void CheckListBoxFrame::OnMakeItemFirst(wxCommandEvent& WXUNUSED(event))
375 {
376     if(m_pListBox->GetSelection() != -1)
377         m_pListBox->SetFirstItem(m_pListBox->GetSelection());
378     else
379         wxMessageBox(wxT("Nothing selected!"));
380 }
381 
OnToggleSelection(wxCommandEvent & event)382 void CheckListBoxFrame::OnToggleSelection(wxCommandEvent& event)
383 {
384     wxSizer *sizer = m_panel->GetSizer();
385 
386     sizer->Detach( m_pListBox );
387     delete m_pListBox;
388 
389     CreateCheckListbox(event.IsChecked() ? wxLB_EXTENDED : 0);
390 
391     sizer->Insert(0, m_pListBox, 1, wxGROW | wxALL, 10);
392 
393     m_panel->Layout();
394 }
395 
OnToggleExtended(wxCommandEvent & event)396 void CheckListBoxFrame::OnToggleExtended(wxCommandEvent& event)
397 {
398     wxSizer *sizer = m_panel->GetSizer();
399 
400     sizer->Detach( m_pListBox );
401     delete m_pListBox;
402 
403     CreateCheckListbox(event.IsChecked() ? wxLB_EXTENDED : 0);
404 
405     sizer->Insert(0, m_pListBox, 1, wxGROW | wxALL, 10);
406 
407     m_panel->Layout();
408 }
409 
OnToggleSorting(wxCommandEvent & event)410 void CheckListBoxFrame::OnToggleSorting(wxCommandEvent& event)
411 {
412     wxSizer *sizer = m_panel->GetSizer();
413 
414     sizer->Detach( m_pListBox );
415     delete m_pListBox;
416 
417     CreateCheckListbox(event.IsChecked() ? wxLB_SORT : 0);
418 
419     sizer->Insert(0, m_pListBox, 1, wxGROW | wxALL, 10);
420 
421     m_panel->Layout();
422 }
423 
OnListboxSelect(wxCommandEvent & event)424 void CheckListBoxFrame::OnListboxSelect(wxCommandEvent& event)
425 {
426     int nSel = event.GetSelection();
427     wxLogStatus(this, wxT("Item %d selected (%schecked)"), nSel,
428                       m_pListBox->IsChecked(nSel) ? wxT("") : wxT("not "));
429 }
430 
OnListboxDblClick(wxCommandEvent & WXUNUSED (event))431 void CheckListBoxFrame::OnListboxDblClick(wxCommandEvent& WXUNUSED(event))
432 {
433     int selection = -1;
434     if(m_pListBox->GetWindowStyle() & wxLB_EXTENDED)
435     {
436         wxArrayInt list;
437         m_pListBox->GetSelections(list);
438         if(list.Count()==1)
439         {
440             selection = list.Item(0);
441         }
442     }
443     else
444     {
445         selection = m_pListBox->GetSelection();
446     }
447 
448     wxString strSelection;
449     if ( selection != -1 )
450     {
451         strSelection.Printf(wxT("Item %d double clicked"), selection);
452     }
453     else
454     {
455         strSelection = wxT("List double clicked in multiple selection mode");
456     }
457     wxMessageDialog dialog(this, strSelection, wxT("wxCheckListBox message"), wxICON_INFORMATION);
458     dialog.ShowModal();
459 }
460 
OnCheckboxToggle(wxCommandEvent & event)461 void CheckListBoxFrame::OnCheckboxToggle(wxCommandEvent& event)
462 {
463     unsigned int nItem = event.GetInt();
464 
465     wxLogStatus(this, wxT("item %d was %schecked"), nItem,
466                       m_pListBox->IsChecked(nItem) ? wxT("") : wxT("un"));
467 }
468 
OnButtonUp(wxCommandEvent & WXUNUSED (event))469 void CheckListBoxFrame::OnButtonUp(wxCommandEvent& WXUNUSED(event))
470 {
471     OnButtonMove(true);
472 }
473 
OnButtonDown(wxCommandEvent & WXUNUSED (event))474 void CheckListBoxFrame::OnButtonDown(wxCommandEvent& WXUNUSED(event))
475 {
476     OnButtonMove(false);
477 }
478 
OnButtonMove(bool up)479 void CheckListBoxFrame::OnButtonMove(bool up)
480 {
481     int selection = -1;
482     if(m_pListBox->GetWindowStyle() & wxLB_EXTENDED)
483     {
484         wxArrayInt list;
485         m_pListBox->GetSelections(list);
486         if(list.Count()==1)
487         {
488             selection = list.Item(0);
489         }
490     }
491     else
492     {
493         selection = m_pListBox->GetSelection();
494     }
495     if ( selection != wxNOT_FOUND )
496     {
497         wxString label = m_pListBox->GetString(selection);
498 
499         int positionNew = up ? selection - 1 : selection + 2;
500         if ( positionNew < 0 || positionNew > (int)m_pListBox->GetCount() )
501         {
502             wxLogStatus(this, wxT("Can't move this item %s"), up ? wxT("up") : wxT("down"));
503         }
504         else
505         {
506             bool wasChecked = m_pListBox->IsChecked(selection);
507 
508             int positionOld = up ? selection + 1 : selection;
509 
510             // insert the item
511             m_pListBox->InsertItems(1, &label, positionNew);
512 
513             // and delete the old one
514             m_pListBox->Delete(positionOld);
515 
516             int selectionNew = up ? positionNew : positionNew - 1;
517             m_pListBox->Check(selectionNew, wasChecked);
518             m_pListBox->SetSelection(selectionNew);
519             m_pListBox->SetFocus();
520 
521             AdjustColour(selection);
522             AdjustColour(selectionNew);
523 
524             wxLogStatus(this, wxT("Item moved %s"), up ? wxT("up") : wxT("down"));
525         }
526     }
527     else
528     {
529         wxLogStatus(this, wxT("Please select single item"));
530     }
531 }
532 
533 // not implemented in ports other than (native) MSW yet
534 #if defined(__WXMSW__) && !defined(__WXUNIVERSAL__) && !defined(__WXWINCE__)
AdjustColour(size_t index)535 void CheckListBoxFrame::AdjustColour(size_t index)
536 {
537     // even items have grey backround, odd ones - white
538     unsigned char c = index % 2 ? 255 : 200;
539     m_pListBox->GetItem(index)->SetBackgroundColour(wxColor(c, c, c));
540 }
541 #else
AdjustColour(size_t WXUNUSED (index))542 void CheckListBoxFrame::AdjustColour(size_t WXUNUSED(index))
543 {
544 }
545 #endif // wxMSW
546