1 /////////////////////////////////////////////////////////////////////////////
2 // Name:        lboxtest.cpp
3 // Purpose:     wxListBox sample
4 // Author:      Vadim Zeitlin
5 // Id:          $Id: lboxtest.cpp 41547 2006-10-02 05:36:31Z PC $
6 // Copyright:   (c) 2000 Vadim Zeitlin
7 // Licence:     wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9 
10 /*
11    Current bugs:
12 
13   +1. horz scrollbar doesn't appear in listbox
14   +2. truncating text ctrl doesn't update display
15   +3. deleting last listbox item doesn't update display
16    4. text ctrl background corrupted after resize
17  */
18 
19 // ============================================================================
20 // declarations
21 // ============================================================================
22 
23 // ----------------------------------------------------------------------------
24 // headers
25 // ----------------------------------------------------------------------------
26 
27 // for compilers that support precompilation, includes "wx/wx.h".
28 #include "wx/wxprec.h"
29 
30 #ifdef __BORLANDC__
31     #pragma hdrstop
32 #endif
33 
34 // for all others, include the necessary headers
35 #ifndef WX_PRECOMP
36     #include "wx/wx.h"
37     #include "wx/app.h"
38     #include "wx/frame.h"
39     #include "wx/dcclient.h"
40 
41     #include "wx/button.h"
42     #include "wx/checkbox.h"
43     #include "wx/checklst.h"
44     #include "wx/listbox.h"
45     #include "wx/radiobox.h"
46     #include "wx/radiobut.h"
47     #include "wx/statbox.h"
48     #include "wx/stattext.h"
49     #include "wx/textctrl.h"
50 #endif
51 
52 #include "wx/sizer.h"
53 
54 #ifdef __WXUNIVERSAL__
55     #include "wx/univ/theme.h"
56 #endif // __WXUNIVERSAL__
57 
58 // ----------------------------------------------------------------------------
59 // constants
60 // ----------------------------------------------------------------------------
61 
62 // control ids
63 enum
64 {
65     LboxTest_Reset = 100,
66     LboxTest_Create,
67     LboxTest_Add,
68     LboxTest_AddText,
69     LboxTest_AddSeveral,
70     LboxTest_AddMany,
71     LboxTest_Clear,
72 #if wxUSE_LOG
73     LboxTest_ClearLog,
74 #endif // wxUSE_LOG
75     LboxTest_Change,
76     LboxTest_ChangeText,
77     LboxTest_Delete,
78     LboxTest_DeleteText,
79     LboxTest_DeleteSel,
80     LboxTest_DeselectAll,
81     LboxTest_Listbox,
82     LboxTest_Quit
83 };
84 
85 // ----------------------------------------------------------------------------
86 // our classes
87 // ----------------------------------------------------------------------------
88 
89 // Define a new application type, each program should derive a class from wxApp
90 class LboxTestApp : public wxApp
91 {
92 public:
93     // override base class virtuals
94     // ----------------------------
95 
96     // this one is called on application startup and is a good place for the app
97     // initialization (doing it here and not in the ctor allows to have an error
98     // return: if OnInit() returns false, the application terminates)
99     virtual bool OnInit();
100 };
101 
102 // Define a new frame type: this is going to be our main frame
103 class LboxTestFrame : public wxFrame
104 {
105 public:
106     // ctor(s) and dtor
107     LboxTestFrame(const wxString& title);
108     virtual ~LboxTestFrame();
109 
110 protected:
111     // event handlers
112     void OnButtonReset(wxCommandEvent& event);
113     void OnButtonCreate(wxCommandEvent& event);
114     void OnButtonChange(wxCommandEvent& event);
115     void OnButtonDelete(wxCommandEvent& event);
116     void OnButtonDeleteSel(wxCommandEvent& event);
117     void OnButtonDeselectAll(wxCommandEvent& event);
118     void OnButtonClear(wxCommandEvent& event);
119 
120 #if wxUSE_LOG
121     void OnButtonClearLog(wxCommandEvent& event);
122 #endif // wxUSE_LOG
123     void OnButtonAdd(wxCommandEvent& event);
124     void OnButtonAddSeveral(wxCommandEvent& event);
125     void OnButtonAddMany(wxCommandEvent& event);
126     void OnButtonQuit(wxCommandEvent& event);
127 
128     void OnListbox(wxCommandEvent& event);
129     void OnListboxDClick(wxCommandEvent& event);
130     void OnListboxRDown(wxMouseEvent& event);
131 
132     void OnCheckOrRadioBox(wxCommandEvent& event);
133 
134     void OnUpdateUIAddSeveral(wxUpdateUIEvent& event);
135     void OnUpdateUICreateButton(wxUpdateUIEvent& event);
136     void OnUpdateUIClearButton(wxUpdateUIEvent& event);
137     void OnUpdateUIDeleteButton(wxUpdateUIEvent& event);
138     void OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event);
139     void OnUpdateUIDeselectAllButton(wxUpdateUIEvent& event);
140 
141     // reset the listbox parameters
142     void Reset();
143 
144     // (re)create the listbox
145     void CreateLbox();
146 
147     // listbox parameters
148     // ------------------
149 
150     // the selection mode
151     enum LboxSelection
152     {
153         LboxSel_Single,
154         LboxSel_Extended,
155         LboxSel_Multiple
156     } m_lboxSelMode;
157 
158     // should it be sorted?
159     bool m_sorted;
160 
161     // should it have horz scroll/vert scrollbar permanently shown?
162     bool m_horzScroll,
163          m_vertScrollAlways;
164 
165     // should the recreate button be enabled?
166     bool m_dirty;
167 
168     // the controls
169     // ------------
170 
171     // the sel mode radiobox
172     wxRadioBox *m_radioSelMode;
173 
174     // the checkboxes
175     wxCheckBox *m_chkSort,
176                *m_chkHScroll,
177                *m_chkVScroll;
178 
179     // the listbox itself and the sizer it is in
180     wxListBox *m_lbox;
181     wxSizer *m_sizerLbox;
182 
183     // panel the controls such as the listbox are in
184     wxPanel* m_panel;
185 
186 #if wxUSE_LOG
187     // the listbox for logging messages
188     wxListBox *m_lboxLog;
189 #endif // wxUSE_LOG
190 
191     // the text entries for "Add/change string" and "Delete" buttons
192     wxTextCtrl *m_textAdd,
193                *m_textChange,
194                *m_textDelete;
195 
196 private:
197 #if wxUSE_LOG
198     // the log target we use to redirect messages to the listbox
199     wxLog *m_logTarget;
200 #endif // wxUSE_LOG
201 
202     // any class wishing to process wxWidgets events must use this macro
203     DECLARE_EVENT_TABLE()
204 };
205 
206 #if wxUSE_LOG
207 // A log target which just redirects the messages to a listbox
208 class LboxLogger : public wxLog
209 {
210 public:
LboxLogger(wxListBox * lbox,wxLog * logOld)211     LboxLogger(wxListBox *lbox, wxLog *logOld)
212     {
213         m_lbox = lbox;
214         //m_lbox->Disable(); -- looks ugly under MSW
215         m_logOld = logOld;
216     }
217 
~LboxLogger()218     virtual ~LboxLogger()
219     {
220         wxLog::SetActiveTarget(m_logOld);
221     }
222 
223 private:
224     // implement sink functions
DoLog(wxLogLevel level,const wxChar * szString,time_t t)225     virtual void DoLog(wxLogLevel level, const wxChar *szString, time_t t)
226     {
227         // don't put trace messages into listbox or we can get into infinite
228         // recursion
229         if ( level == wxLOG_Trace )
230         {
231             if ( m_logOld )
232             {
233                 // cast is needed to call protected method
234                 ((LboxLogger *)m_logOld)->DoLog(level, szString, t);
235             }
236         }
237         else
238         {
239             wxLog::DoLog(level, szString, t);
240         }
241     }
242 
DoLogString(const wxChar * szString,time_t WXUNUSED (t))243     virtual void DoLogString(const wxChar *szString, time_t WXUNUSED(t))
244     {
245         wxString msg;
246         TimeStamp(&msg);
247         msg += szString;
248         #ifdef __WXUNIVERSAL__
249             m_lbox->AppendAndEnsureVisible(msg);
250         #else // other ports don't have this method yet
251             m_lbox->Append(msg);
252 
253             // SetFirstItem() isn't implemented in wxGTK
254             #ifndef __WXGTK__
255                 m_lbox->SetFirstItem(m_lbox->GetCount() - 1);
256             #endif
257         #endif
258     }
259 
260     // the control we use
261     wxListBox *m_lbox;
262 
263     // the old log target
264     wxLog *m_logOld;
265 };
266 #endif // wxUSE_LOG
267 
268 // ----------------------------------------------------------------------------
269 // misc macros
270 // ----------------------------------------------------------------------------
271 
272 IMPLEMENT_APP(LboxTestApp)
273 
274 // ----------------------------------------------------------------------------
275 // event tables
276 // ----------------------------------------------------------------------------
277 
BEGIN_EVENT_TABLE(LboxTestFrame,wxFrame)278 BEGIN_EVENT_TABLE(LboxTestFrame, wxFrame)
279     EVT_BUTTON(LboxTest_Reset, LboxTestFrame::OnButtonReset)
280     EVT_BUTTON(LboxTest_Create, LboxTestFrame::OnButtonCreate)
281     EVT_BUTTON(LboxTest_Change, LboxTestFrame::OnButtonChange)
282     EVT_BUTTON(LboxTest_Delete, LboxTestFrame::OnButtonDelete)
283     EVT_BUTTON(LboxTest_DeleteSel, LboxTestFrame::OnButtonDeleteSel)
284     EVT_BUTTON(LboxTest_DeselectAll, LboxTestFrame::OnButtonDeselectAll)
285     EVT_BUTTON(LboxTest_Clear, LboxTestFrame::OnButtonClear)
286 #if wxUSE_LOG
287     EVT_BUTTON(LboxTest_ClearLog, LboxTestFrame::OnButtonClearLog)
288 #endif // wxUSE_LOG
289     EVT_BUTTON(LboxTest_Add, LboxTestFrame::OnButtonAdd)
290     EVT_BUTTON(LboxTest_AddSeveral, LboxTestFrame::OnButtonAddSeveral)
291     EVT_BUTTON(LboxTest_AddMany, LboxTestFrame::OnButtonAddMany)
292     EVT_BUTTON(LboxTest_Quit, LboxTestFrame::OnButtonQuit)
293 
294     EVT_TEXT_ENTER(LboxTest_AddText, LboxTestFrame::OnButtonAdd)
295     EVT_TEXT_ENTER(LboxTest_DeleteText, LboxTestFrame::OnButtonDelete)
296 
297     EVT_UPDATE_UI_RANGE(LboxTest_Reset, LboxTest_Create,
298                         LboxTestFrame::OnUpdateUICreateButton)
299 
300     EVT_UPDATE_UI(LboxTest_AddSeveral, LboxTestFrame::OnUpdateUIAddSeveral)
301     EVT_UPDATE_UI(LboxTest_Clear, LboxTestFrame::OnUpdateUIClearButton)
302     EVT_UPDATE_UI(LboxTest_DeleteText, LboxTestFrame::OnUpdateUIClearButton)
303     EVT_UPDATE_UI(LboxTest_Delete, LboxTestFrame::OnUpdateUIDeleteButton)
304     EVT_UPDATE_UI(LboxTest_Change, LboxTestFrame::OnUpdateUIDeleteSelButton)
305     EVT_UPDATE_UI(LboxTest_ChangeText, LboxTestFrame::OnUpdateUIDeleteSelButton)
306     EVT_UPDATE_UI(LboxTest_DeleteSel, LboxTestFrame::OnUpdateUIDeleteSelButton)
307     EVT_UPDATE_UI(LboxTest_DeselectAll, LboxTestFrame::OnUpdateUIDeselectAllButton)
308 
309     EVT_LISTBOX(LboxTest_Listbox, LboxTestFrame::OnListbox)
310     EVT_LISTBOX_DCLICK(wxID_ANY, LboxTestFrame::OnListboxDClick)
311     EVT_CHECKBOX(wxID_ANY, LboxTestFrame::OnCheckOrRadioBox)
312     EVT_RADIOBOX(wxID_ANY, LboxTestFrame::OnCheckOrRadioBox)
313 END_EVENT_TABLE()
314 
315 // ============================================================================
316 // implementation
317 // ============================================================================
318 
319 // ----------------------------------------------------------------------------
320 // app class
321 // ----------------------------------------------------------------------------
322 
323 bool LboxTestApp::OnInit()
324 {
325     wxFrame *frame = new LboxTestFrame(_T("wxListBox sample"));
326     frame->Show();
327 
328 #if wxUSE_LOG
329     //wxLog::AddTraceMask(_T("listbox"));
330     wxLog::AddTraceMask(_T("scrollbar"));
331 #endif // wxUSE_LOG
332 
333     return true;
334 }
335 
336 // ----------------------------------------------------------------------------
337 // top level frame class
338 // ----------------------------------------------------------------------------
339 
LboxTestFrame(const wxString & title)340 LboxTestFrame::LboxTestFrame(const wxString& title)
341              : wxFrame(NULL, wxID_ANY, title, wxPoint(100, 100))
342 {
343     // init everything
344     m_dirty = false;
345     m_radioSelMode = (wxRadioBox *)NULL;
346 
347     m_chkVScroll =
348     m_chkHScroll =
349     m_chkSort = (wxCheckBox *)NULL;
350 
351     m_lbox = (wxListBox *)NULL;
352 #if wxUSE_LOG
353     m_lboxLog = (wxListBox *)NULL;
354 #endif // wxUSE_LOG
355     m_sizerLbox = (wxSizer *)NULL;
356 
357 #if wxUSE_LOG
358     m_logTarget = (wxLog *)NULL;
359 #endif // wxUSE_LOG
360 
361     m_panel = new wxPanel(this, wxID_ANY);
362 
363     /*
364        What we create here is a frame having 3 panes: the explanatory pane to
365        the left allowing to set the listbox styles and recreate the control,
366        the pane containing the listbox itself and the lower pane containing
367        the buttons which allow to add/change/delete strings to/from it.
368     */
369     wxSizer *sizerTop = new wxBoxSizer(wxVERTICAL),
370             *sizerUp = new wxBoxSizer(wxHORIZONTAL),
371             *sizerLeft,
372             *sizerRight = new wxBoxSizer(wxVERTICAL);
373 
374     // upper left pane
375     static const wxString modes[] =
376     {
377         _T("single"),
378         _T("extended"),
379         _T("multiple"),
380     };
381 
382     wxStaticBox *box = new wxStaticBox(m_panel, wxID_ANY, _T("&Set listbox parameters"));
383     m_radioSelMode = new wxRadioBox(m_panel, wxID_ANY, _T("Selection &mode:"),
384                                     wxDefaultPosition, wxDefaultSize,
385                                     WXSIZEOF(modes), modes,
386                                     1, wxRA_SPECIFY_COLS);
387 
388     m_chkVScroll = new wxCheckBox(m_panel, wxID_ANY, _T("Always show &vertical scrollbar"));
389     m_chkHScroll = new wxCheckBox(m_panel, wxID_ANY, _T("Show &horizontal scrollbar"));
390     m_chkSort = new wxCheckBox(m_panel, wxID_ANY, _T("&Sort items"));
391 
392     sizerLeft = new wxStaticBoxSizer(box, wxVERTICAL);
393 
394     sizerLeft->Add(m_chkVScroll, 0, wxLEFT | wxRIGHT, 5);
395     sizerLeft->Add(m_chkHScroll, 0, wxLEFT | wxRIGHT, 5);
396     sizerLeft->Add(m_chkSort, 0, wxLEFT | wxRIGHT, 5);
397     sizerLeft->Add(5, 5, 0, wxGROW | wxALL, 5); // spacer
398     sizerLeft->Add(m_radioSelMode, 0, wxGROW | wxALL, 5);
399 
400     wxSizer *sizerBtn = new wxBoxSizer(wxHORIZONTAL);
401     wxButton *btn = new wxButton(m_panel, LboxTest_Reset, _T("&Reset"));
402     sizerBtn->Add(btn, 0, wxLEFT | wxRIGHT, 5);
403     btn = new wxButton(m_panel, LboxTest_Create, _T("&Create"));
404     sizerBtn->Add(btn, 0, wxLEFT | wxRIGHT, 5);
405     sizerLeft->Add(sizerBtn, 0, wxALIGN_CENTRE_HORIZONTAL | wxALL, 15);
406 
407     // middle pane
408     wxStaticBox *box2 = new wxStaticBox(m_panel, wxID_ANY, _T("&Change listbox contents"));
409     wxSizer *sizerMiddle = new wxStaticBoxSizer(box2, wxVERTICAL);
410 
411     wxSizer *sizerRow = new wxBoxSizer(wxHORIZONTAL);
412     btn = new wxButton(m_panel, LboxTest_Add, _T("&Add this string"));
413     m_textAdd = new wxTextCtrl(m_panel, LboxTest_AddText, _T("test item 0"));
414     sizerRow->Add(btn, 0, wxRIGHT, 5);
415     sizerRow->Add(m_textAdd, 1, wxLEFT, 5);
416     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
417 
418     btn = new wxButton(m_panel, LboxTest_AddSeveral, _T("&Insert a few strings"));
419     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
420 
421     btn = new wxButton(m_panel, LboxTest_AddMany, _T("Add &many strings"));
422     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
423 
424     sizerRow = new wxBoxSizer(wxHORIZONTAL);
425     btn = new wxButton(m_panel, LboxTest_Change, _T("C&hange current"));
426     m_textChange = new wxTextCtrl(m_panel, LboxTest_ChangeText, wxEmptyString);
427     sizerRow->Add(btn, 0, wxRIGHT, 5);
428     sizerRow->Add(m_textChange, 1, wxLEFT, 5);
429     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
430 
431     sizerRow = new wxBoxSizer(wxHORIZONTAL);
432     btn = new wxButton(m_panel, LboxTest_Delete, _T("&Delete this item"));
433     m_textDelete = new wxTextCtrl(m_panel, LboxTest_DeleteText, wxEmptyString);
434     sizerRow->Add(btn, 0, wxRIGHT, 5);
435     sizerRow->Add(m_textDelete, 1, wxLEFT, 5);
436     sizerMiddle->Add(sizerRow, 0, wxALL | wxGROW, 5);
437 
438     btn = new wxButton(m_panel, LboxTest_DeleteSel, _T("Delete &selection"));
439     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
440 
441     btn = new wxButton(m_panel, LboxTest_DeselectAll, _T("Deselect All"));
442     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
443 
444     btn = new wxButton(m_panel, LboxTest_Clear, _T("&Clear"));
445     sizerMiddle->Add(btn, 0, wxALL | wxGROW, 5);
446 
447     // right pane
448     sizerRight->SetMinSize(250, 0);
449     m_sizerLbox = sizerRight; // save it to modify it later
450 
451     // the 3 panes panes compose the upper part of the window
452     sizerUp->Add(sizerLeft, 0, wxGROW | (wxALL & ~wxLEFT), 10);
453     sizerUp->Add(sizerMiddle, 1, wxGROW | wxALL, 10);
454     sizerUp->Add(sizerRight, 1, wxGROW | (wxALL & ~wxRIGHT), 10);
455 
456     // the lower one only has the log listbox and a button to clear it
457 #if wxUSE_LOG
458     wxSizer *sizerDown = new wxStaticBoxSizer
459                              (
460                                new wxStaticBox(m_panel, wxID_ANY, _T("&Log window")),
461                                wxVERTICAL
462                              );
463     m_lboxLog = new wxListBox(m_panel, wxID_ANY);
464     sizerDown->Add(m_lboxLog, 1, wxGROW | wxALL, 5);
465 #else
466     wxSizer *sizerDown = new wxBoxSizer(wxVERTICAL);
467 #endif // wxUSE_LOG
468     wxBoxSizer *sizerBtns = new wxBoxSizer(wxHORIZONTAL);
469 #if wxUSE_LOG
470     btn = new wxButton(m_panel, LboxTest_ClearLog, _T("Clear &log"));
471     sizerBtns->Add(btn);
472     sizerBtns->Add(10, 0); // spacer
473 #endif // wxUSE_LOG
474     btn = new wxButton(m_panel, LboxTest_Quit, _T("E&xit"));
475     sizerBtns->Add(btn);
476     sizerDown->Add(sizerBtns, 0, wxALL | wxALIGN_RIGHT, 5);
477 
478     // put everything together
479     sizerTop->Add(sizerUp, 1, wxGROW | (wxALL & ~wxBOTTOM), 10);
480     sizerTop->Add(0, 5, 0, wxGROW); // spacer in between
481     sizerTop->Add(sizerDown, 0,  wxGROW | (wxALL & ~wxTOP), 10);
482 
483     // final initialization and create the listbox
484     Reset();
485     CreateLbox();
486 
487     m_panel->SetSizer(sizerTop);
488 
489     sizerTop->Fit(this);
490     sizerTop->SetSizeHints(this);
491 
492 #if wxUSE_LOG
493     // now that everything is created we can redirect the log messages to the
494     // listbox
495     m_logTarget = new LboxLogger(m_lboxLog, wxLog::GetActiveTarget());
496     wxLog::SetActiveTarget(m_logTarget);
497 #endif // wxUSE_LOG
498 }
499 
~LboxTestFrame()500 LboxTestFrame::~LboxTestFrame()
501 {
502 #if wxUSE_LOG
503     delete m_logTarget;
504 #endif // wxUSE_LOG
505 }
506 
507 // ----------------------------------------------------------------------------
508 // operations
509 // ----------------------------------------------------------------------------
510 
Reset()511 void LboxTestFrame::Reset()
512 {
513     if ( m_radioSelMode->GetSelection() == LboxSel_Single &&
514          !m_chkSort->GetValue() &&
515          m_chkHScroll->GetValue() &&
516          !m_chkVScroll->GetValue() )
517     {
518         // nothing to do
519         return;
520     }
521 
522     m_radioSelMode->SetSelection(LboxSel_Single);
523     m_chkSort->SetValue(false);
524     m_chkHScroll->SetValue(true);
525     m_chkVScroll->SetValue(false);
526 
527     m_dirty = true;
528 }
529 
CreateLbox()530 void LboxTestFrame::CreateLbox()
531 {
532     int flags = 0;
533     switch ( m_radioSelMode->GetSelection() )
534     {
535         default:
536             wxFAIL_MSG( _T("unexpected radio box selection") );
537 
538         case LboxSel_Single:    flags |= wxLB_SINGLE; break;
539         case LboxSel_Extended:  flags |= wxLB_EXTENDED; break;
540         case LboxSel_Multiple:  flags |= wxLB_MULTIPLE; break;
541     }
542 
543     if ( m_chkVScroll->GetValue() )
544         flags |= wxLB_ALWAYS_SB;
545     if ( m_chkHScroll->GetValue() )
546         flags |= wxLB_HSCROLL;
547     if ( m_chkSort->GetValue() )
548         flags |= wxLB_SORT;
549 
550     wxArrayString items;
551 
552     if ( m_lbox ) // cache old items to restore later if listbox existed
553     {
554     int count = m_lbox->GetCount();
555     for ( int n = 0; n < count; n++ )
556     {
557         items.Add(m_lbox->GetString(n));
558     }
559 
560     m_sizerLbox->Detach(m_lbox);
561     delete m_lbox;
562     }
563 
564     m_lbox = new wxListBox(m_panel, LboxTest_Listbox,
565                            wxDefaultPosition, wxDefaultSize,
566                            0, NULL,
567                            flags);
568 
569     m_lbox->Set(items);
570     m_sizerLbox->Add(m_lbox, 1, wxGROW | wxALL, 5);
571     m_sizerLbox->Layout();
572 
573     m_dirty = false;
574 
575     m_lbox->Connect(wxEVT_RIGHT_DOWN,
576         wxMouseEventHandler(LboxTestFrame::OnListboxRDown), NULL, this);
577 }
578 
579 // ----------------------------------------------------------------------------
580 // event handlers
581 // ----------------------------------------------------------------------------
582 
OnButtonQuit(wxCommandEvent & WXUNUSED (event))583 void LboxTestFrame::OnButtonQuit(wxCommandEvent& WXUNUSED(event))
584 {
585     Close();
586 }
587 
OnButtonReset(wxCommandEvent & WXUNUSED (event))588 void LboxTestFrame::OnButtonReset(wxCommandEvent& WXUNUSED(event))
589 {
590     Reset();
591 }
592 
OnButtonCreate(wxCommandEvent & WXUNUSED (event))593 void LboxTestFrame::OnButtonCreate(wxCommandEvent& WXUNUSED(event))
594 {
595     CreateLbox();
596 }
597 
OnButtonChange(wxCommandEvent & WXUNUSED (event))598 void LboxTestFrame::OnButtonChange(wxCommandEvent& WXUNUSED(event))
599 {
600     wxArrayInt selections;
601     int count = m_lbox->GetSelections(selections);
602     wxString s = m_textChange->GetValue();
603     for ( int n = 0; n < count; n++ )
604     {
605         m_lbox->SetString(selections[n], s);
606     }
607 }
608 
OnButtonDelete(wxCommandEvent & WXUNUSED (event))609 void LboxTestFrame::OnButtonDelete(wxCommandEvent& WXUNUSED(event))
610 {
611     unsigned long n;
612     if ( !m_textDelete->GetValue().ToULong(&n) ||
613             (n >= (unsigned)m_lbox->GetCount()) )
614     {
615         return;
616     }
617 
618     m_lbox->Delete(n);
619 }
620 
OnButtonDeleteSel(wxCommandEvent & WXUNUSED (event))621 void LboxTestFrame::OnButtonDeleteSel(wxCommandEvent& WXUNUSED(event))
622 {
623     wxArrayInt selections;
624     int n = m_lbox->GetSelections(selections);
625     while ( n > 0 )
626     {
627         m_lbox->Delete(selections[--n]);
628     }
629 }
630 
OnButtonDeselectAll(wxCommandEvent & WXUNUSED (event))631 void LboxTestFrame::OnButtonDeselectAll(wxCommandEvent& WXUNUSED(event))
632 {
633     m_lbox->SetSelection(-1);
634 }
635 
OnButtonClear(wxCommandEvent & WXUNUSED (event))636 void LboxTestFrame::OnButtonClear(wxCommandEvent& WXUNUSED(event))
637 {
638     m_lbox->Clear();
639 }
640 
641 #if wxUSE_LOG
OnButtonClearLog(wxCommandEvent & WXUNUSED (event))642 void LboxTestFrame::OnButtonClearLog(wxCommandEvent& WXUNUSED(event))
643 {
644     m_lboxLog->Clear();
645 }
646 #endif // wxUSE_LOG
647 
OnButtonAdd(wxCommandEvent & WXUNUSED (event))648 void LboxTestFrame::OnButtonAdd(wxCommandEvent& WXUNUSED(event))
649 {
650     static unsigned s_item = 0;
651 
652     wxString s = m_textAdd->GetValue();
653     if ( !m_textAdd->IsModified() )
654     {
655         // update the default string
656         m_textAdd->SetValue(wxString::Format(_T("test item %u"), ++s_item));
657     }
658 
659     m_lbox->Append(s);
660 }
661 
OnButtonAddMany(wxCommandEvent & WXUNUSED (event))662 void LboxTestFrame::OnButtonAddMany(wxCommandEvent& WXUNUSED(event))
663 {
664     // "many" means 1000 here
665     for ( unsigned n = 0; n < 1000; n++ )
666     {
667         m_lbox->Append(wxString::Format(_T("item #%u"), n));
668     }
669 }
670 
OnButtonAddSeveral(wxCommandEvent & WXUNUSED (event))671 void LboxTestFrame::OnButtonAddSeveral(wxCommandEvent& WXUNUSED(event))
672 {
673     wxArrayString items;
674     items.Add(_T("First"));
675     items.Add(_T("another one"));
676     items.Add(_T("and the last (very very very very very very very very very very long) one"));
677     m_lbox->InsertItems(items, 0);
678 }
679 
OnUpdateUICreateButton(wxUpdateUIEvent & event)680 void LboxTestFrame::OnUpdateUICreateButton(wxUpdateUIEvent& event)
681 {
682     event.Enable(m_dirty);
683 }
684 
OnUpdateUIDeleteButton(wxUpdateUIEvent & event)685 void LboxTestFrame::OnUpdateUIDeleteButton(wxUpdateUIEvent& event)
686 {
687     unsigned long n;
688     event.Enable(m_textDelete->GetValue().ToULong(&n) &&
689                     (n < (unsigned)m_lbox->GetCount()));
690 }
691 
OnUpdateUIDeleteSelButton(wxUpdateUIEvent & event)692 void LboxTestFrame::OnUpdateUIDeleteSelButton(wxUpdateUIEvent& event)
693 {
694     wxArrayInt selections;
695     event.Enable(m_lbox->GetSelections(selections) != 0);
696 }
697 
OnUpdateUIDeselectAllButton(wxUpdateUIEvent & event)698 void LboxTestFrame::OnUpdateUIDeselectAllButton(wxUpdateUIEvent& event)
699 {
700     wxArrayInt selections;
701     event.Enable(m_lbox->GetSelections(selections) != 0);
702 }
703 
OnUpdateUIClearButton(wxUpdateUIEvent & event)704 void LboxTestFrame::OnUpdateUIClearButton(wxUpdateUIEvent& event)
705 {
706     event.Enable(m_lbox->GetCount() != 0);
707 }
708 
OnUpdateUIAddSeveral(wxUpdateUIEvent & event)709 void LboxTestFrame::OnUpdateUIAddSeveral(wxUpdateUIEvent& event)
710 {
711     event.Enable(!(m_lbox->GetWindowStyle() & wxLB_SORT));
712 }
713 
OnListbox(wxCommandEvent & event)714 void LboxTestFrame::OnListbox(wxCommandEvent& event)
715 {
716     int sel = event.GetInt();
717     m_textDelete->SetValue(wxString::Format(_T("%d"), sel));
718 
719     wxLogMessage(_T("Listbox item %d selected"), sel);
720 }
721 
OnListboxDClick(wxCommandEvent & event)722 void LboxTestFrame::OnListboxDClick(wxCommandEvent& event)
723 {
724     int sel = event.GetInt();
725     wxLogMessage(_T("Listbox item %d double clicked"), sel);
726 }
727 
OnListboxRDown(wxMouseEvent & event)728 void LboxTestFrame::OnListboxRDown(wxMouseEvent& event)
729 {
730     int item = m_lbox->HitTest(event.GetPosition());
731 
732     if ( item != wxNOT_FOUND )
733         wxLogMessage(_T("Listbox item %d right clicked"), item);
734     else
735         wxLogMessage(_T("Listbox right clicked but no item clicked upon"));
736 
737     event.Skip();
738 }
739 
OnCheckOrRadioBox(wxCommandEvent & WXUNUSED (event))740 void LboxTestFrame::OnCheckOrRadioBox(wxCommandEvent& WXUNUSED(event))
741 {
742     m_dirty = true;
743 }
744 
745