]> git.saurik.com Git - wxWidgets.git/blob - samples/combo/combo.cpp
Implemended column header mouse clicks.
[wxWidgets.git] / samples / combo / combo.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: combo.cpp
3 // Purpose: wxComboCtrl sample
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: Apr-30-2006
7 // RCS-ID: $Id$
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 // ============================================================================
13 // declarations
14 // ============================================================================
15
16 // ----------------------------------------------------------------------------
17 // headers
18 // ----------------------------------------------------------------------------
19
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers)
29 #ifndef WX_PRECOMP
30 #include "wx/wx.h"
31 #endif
32
33 #if !wxUSE_COMBOCTRL
34 #error "Please set wxUSE_COMBOCTRL to 1 and rebuild the library."
35 #endif
36
37 #include "wx/image.h"
38
39 #include "wx/combo.h"
40 #include "wx/odcombo.h"
41
42 // ----------------------------------------------------------------------------
43 // resources
44 // ----------------------------------------------------------------------------
45
46 // the application icon (under Windows and OS/2 it is in resources and even
47 // though we could still include the XPM here it would be unused)
48 #if !defined(__WXMSW__) && !defined(__WXPM__)
49 #include "../sample.xpm"
50 #endif
51
52 // ----------------------------------------------------------------------------
53 // private classes
54 // ----------------------------------------------------------------------------
55
56 // Define a new application type, each program should derive a class from wxApp
57 class MyApp : public wxApp
58 {
59 public:
60 // override base class virtuals
61 // ----------------------------
62
63 // this one is called on application startup and is a good place for the app
64 // initialization (doing it here and not in the ctor allows to have an error
65 // return: if OnInit() returns false, the application terminates)
66 virtual bool OnInit();
67 };
68
69 // Define a new frame type: this is going to be our main frame
70 class MyFrame : public wxFrame
71 {
72 public:
73 // ctor and dtor
74 MyFrame(const wxString& title);
75 ~MyFrame();
76
77 // event handlers (these functions should _not_ be virtual)
78 void OnQuit(wxCommandEvent& event);
79 void OnAbout(wxCommandEvent& event);
80
81 void OnShowComparison( wxCommandEvent& event );
82
83 // log wxComboCtrl events
84 void OnComboBoxUpdate( wxCommandEvent& event );
85
86 protected:
87 wxTextCtrl* m_logWin;
88 wxLog* m_logOld;
89
90 // Common list of items for all dialogs.
91 wxArrayString m_arrItems;
92
93 private:
94 // any class wishing to process wxWidgets events must use this macro
95 DECLARE_EVENT_TABLE()
96 };
97
98 // ----------------------------------------------------------------------------
99 // constants
100 // ----------------------------------------------------------------------------
101
102 // IDs for the controls and the menu commands
103 enum
104 {
105 ComboControl_Compare = wxID_HIGHEST,
106
107 // menu items
108 ComboControl_Quit = wxID_EXIT,
109
110 // it is important for the id corresponding to the "About" command to have
111 // this standard value as otherwise it won't be handled properly under Mac
112 // (where it is special and put into the "Apple" menu)
113 ComboControl_About = wxID_ABOUT
114 };
115
116 // ----------------------------------------------------------------------------
117 // event tables and other macros for wxWidgets
118 // ----------------------------------------------------------------------------
119
120 // the event tables connect the wxWidgets events with the functions (event
121 // handlers) which process them. It can be also done at run-time, but for the
122 // simple menu events like this the static method is much simpler.
123 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
124 EVT_TEXT(wxID_ANY,MyFrame::OnComboBoxUpdate)
125 EVT_COMBOBOX(wxID_ANY,MyFrame::OnComboBoxUpdate)
126
127 EVT_MENU(ComboControl_Compare, MyFrame::OnShowComparison)
128 EVT_MENU(ComboControl_Quit, MyFrame::OnQuit)
129 EVT_MENU(ComboControl_About, MyFrame::OnAbout)
130 END_EVENT_TABLE()
131
132 // Create a new application object: this macro will allow wxWidgets to create
133 // the application object during program execution (it's better than using a
134 // static object for many reasons) and also implements the accessor function
135 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
136 // not wxApp)
137 IMPLEMENT_APP(MyApp)
138
139 // ============================================================================
140 // implementation
141 // ============================================================================
142
143 // ----------------------------------------------------------------------------
144 // the application class
145 // ----------------------------------------------------------------------------
146
147 // 'Main program' equivalent: the program execution "starts" here
148 bool MyApp::OnInit()
149 {
150 // create the main application window
151 MyFrame *frame = new MyFrame(_T("wxComboCtrl and wxOwnerDrawnComboBox Sample"));
152
153 // and show it (the frames, unlike simple controls, are not shown when
154 // created initially)
155 frame->Show(true);
156
157 // success: wxApp::OnRun() will be called which will enter the main message
158 // loop and the application will run. If we returned false here, the
159 // application would exit immediately.
160 return true;
161 }
162
163
164 // ----------------------------------------------------------------------------
165 // wxOwnerDrawnComboBox with custom paint list items
166 // ----------------------------------------------------------------------------
167
168 class wxPenStyleComboBox : public wxOwnerDrawnComboBox
169 {
170 public:
171 virtual void OnDrawItem( wxDC& dc,
172 const wxRect& rect,
173 int item,
174 int flags ) const
175 {
176 if ( item == wxNOT_FOUND )
177 return;
178
179 wxRect r(rect);
180 r.Deflate(3);
181 r.height -= 2;
182
183 int penStyle = wxSOLID;
184 if ( item == 1 )
185 penStyle = wxTRANSPARENT;
186 else if ( item == 2 )
187 penStyle = wxDOT;
188 else if ( item == 3 )
189 penStyle = wxLONG_DASH;
190 else if ( item == 4 )
191 penStyle = wxSHORT_DASH;
192 else if ( item == 5 )
193 penStyle = wxDOT_DASH;
194 else if ( item == 6 )
195 penStyle = wxBDIAGONAL_HATCH;
196 else if ( item == 7 )
197 penStyle = wxCROSSDIAG_HATCH;
198 else if ( item == 8 )
199 penStyle = wxFDIAGONAL_HATCH;
200 else if ( item == 9 )
201 penStyle = wxCROSS_HATCH;
202 else if ( item == 10 )
203 penStyle = wxHORIZONTAL_HATCH;
204 else if ( item == 11 )
205 penStyle = wxVERTICAL_HATCH;
206
207 wxPen pen( dc.GetTextForeground(), 3, penStyle );
208
209 // Get text colour as pen colour
210 dc.SetPen( pen );
211
212 if ( !(flags & wxODCB_PAINTING_CONTROL) )
213 {
214 dc.DrawText(GetString( item ),
215 r.x + 3,
216 (r.y + 0) + ( (r.height/2) - dc.GetCharHeight() )/2
217 );
218
219 dc.DrawLine( r.x+5, r.y+((r.height/4)*3), r.x+r.width - 5, r.y+((r.height/4)*3) );
220 }
221 else
222 {
223 dc.DrawLine( r.x+5, r.y+r.height/2, r.x+r.width - 5, r.y+r.height/2 );
224 }
225 }
226
227 virtual void OnDrawBackground( wxDC& dc, const wxRect& rect,
228 int item, int flags ) const
229 {
230
231 // If item is selected or even, or we are painting the
232 // combo control itself, use the default rendering.
233 if ( (flags & (wxODCB_PAINTING_CONTROL|wxODCB_PAINTING_SELECTED)) ||
234 (item & 1) == 0 )
235 {
236 wxOwnerDrawnComboBox::OnDrawBackground(dc,rect,item,flags);
237 return;
238 }
239
240 // Otherwise, draw every other background with different colour.
241 wxColour bgCol(240,240,250);
242 dc.SetBrush(wxBrush(bgCol));
243 dc.SetPen(wxPen(bgCol));
244 dc.DrawRectangle(rect);
245 }
246
247 virtual wxCoord OnMeasureItem( size_t item ) const
248 {
249 // Simply demonstrate the ability to have variable-height items
250 if ( item & 1 )
251 return 36;
252 else
253 return 24;
254 }
255
256 virtual wxCoord OnMeasureItemWidth( size_t WXUNUSED(item) ) const
257 {
258 return -1; // default - will be measured from text width
259 }
260
261 };
262
263
264 // ----------------------------------------------------------------------------
265 // wxListView Custom popup interface
266 // ----------------------------------------------------------------------------
267
268 #include <wx/listctrl.h>
269
270 class ListViewComboPopup : public wxListView, public wxComboPopup
271 {
272 public:
273
274 virtual void Init()
275 {
276 m_value = -1;
277 m_itemHere = -1; // hot item in list
278 }
279
280 virtual bool Create( wxWindow* parent )
281 {
282 return wxListView::Create(parent,1,
283 wxPoint(0,0),wxDefaultSize,
284 wxLC_LIST|wxLC_SINGLE_SEL|
285 wxLC_SORT_ASCENDING|wxSIMPLE_BORDER);
286 }
287
288 virtual wxWindow *GetControl() { return this; }
289
290 virtual void SetStringValue( const wxString& s )
291 {
292 int n = wxListView::FindItem(-1,s);
293 if ( n >= 0 && n < GetItemCount() )
294 wxListView::Select(n);
295 }
296
297 virtual wxString GetStringValue() const
298 {
299 if ( m_value >= 0 )
300 return wxListView::GetItemText(m_value);
301 return wxEmptyString;
302 }
303
304 //
305 // Popup event handlers
306 //
307
308 // Mouse hot-tracking
309 void OnMouseMove(wxMouseEvent& event)
310 {
311 // Move selection to cursor if it is inside the popup
312
313 int resFlags;
314 int itemHere = HitTest(event.GetPosition(),resFlags);
315 if ( itemHere >= 0 )
316 {
317 wxListView::Select(itemHere,true);
318 m_itemHere = itemHere;
319 }
320 event.Skip();
321 }
322
323 // On mouse left, set the value and close the popup
324 void OnMouseClick(wxMouseEvent& WXUNUSED(event))
325 {
326 m_value = m_itemHere;
327 // TODO: Send event
328 Dismiss();
329 }
330
331 //
332 // Utilies for item manipulation
333 //
334
335 void AddSelection( const wxString& selstr )
336 {
337 wxListView::InsertItem(GetItemCount(),selstr);
338 }
339
340 protected:
341
342 int m_value; // current item index
343 int m_itemHere; // hot item in popup
344
345 private:
346 DECLARE_EVENT_TABLE()
347 };
348
349 BEGIN_EVENT_TABLE(ListViewComboPopup, wxListView)
350 EVT_MOTION(ListViewComboPopup::OnMouseMove)
351 // NOTE: Left down event is used instead of left up right now
352 // since MSW wxListCtrl doesn't seem to emit left ups
353 // consistently.
354 EVT_LEFT_DOWN(ListViewComboPopup::OnMouseClick)
355 END_EVENT_TABLE()
356
357
358 // ----------------------------------------------------------------------------
359 // wxTreeCtrl Custom popup interface
360 // ----------------------------------------------------------------------------
361
362 #include <wx/treectrl.h>
363
364 class TreeCtrlComboPopup : public wxTreeCtrl, public wxComboPopup
365 {
366 public:
367
368 virtual void Init()
369 {
370 }
371
372 virtual bool Create( wxWindow* parent )
373 {
374 return wxTreeCtrl::Create(parent,1,
375 wxPoint(0,0),wxDefaultSize,
376 wxTR_HIDE_ROOT|wxTR_HAS_BUTTONS|
377 wxTR_SINGLE|wxTR_LINES_AT_ROOT|
378 wxSIMPLE_BORDER);
379 }
380
381 virtual void OnShow()
382 {
383 // make sure selected item is visible
384 if ( m_value.IsOk() )
385 EnsureVisible(m_value);
386 }
387
388 virtual wxSize GetAdjustedSize( int minWidth,
389 int WXUNUSED(prefHeight),
390 int maxHeight )
391 {
392 return wxSize(wxMax(300,minWidth),wxMin(250,maxHeight));
393 }
394
395 virtual wxWindow *GetControl() { return this; }
396
397 // Needed by SetStringValue
398 wxTreeItemId FindItemByText( wxTreeItemId parent, const wxString& text )
399 {
400 wxTreeItemIdValue cookie;
401 wxTreeItemId child = GetFirstChild(parent,cookie);
402 while ( child.IsOk() )
403 {
404 if ( GetItemText(child) == text )
405 {
406 return child;
407 }
408 if ( ItemHasChildren(child) )
409 {
410 wxTreeItemId found = FindItemByText(child,text);
411 if ( found.IsOk() )
412 return found;
413 }
414 child = GetNextChild(parent,cookie);
415 }
416 return wxTreeItemId();
417 }
418
419 virtual void SetStringValue( const wxString& s )
420 {
421 wxTreeItemId root = GetRootItem();
422 if ( !root.IsOk() )
423 return;
424
425 wxTreeItemId found = FindItemByText(root,s);
426 if ( found.IsOk() )
427 {
428 m_value = m_itemHere = found;
429 wxTreeCtrl::SelectItem(found);
430 }
431 }
432
433 virtual wxString GetStringValue() const
434 {
435 if ( m_value.IsOk() )
436 return wxTreeCtrl::GetItemText(m_value);
437 return wxEmptyString;
438 }
439
440 //
441 // Popup event handlers
442 //
443
444 // Mouse hot-tracking
445 void OnMouseMove(wxMouseEvent& event)
446 {
447 int resFlags;
448 wxTreeItemId itemHere = HitTest(event.GetPosition(),resFlags);
449 if ( itemHere.IsOk() && (resFlags & wxTREE_HITTEST_ONITEMLABEL) )
450 {
451 wxTreeCtrl::SelectItem(itemHere,true);
452 m_itemHere = itemHere;
453 }
454 event.Skip();
455 }
456
457 // On mouse left, set the value and close the popup
458 void OnMouseClick(wxMouseEvent& event)
459 {
460 int resFlags;
461 wxTreeItemId itemHere = HitTest(event.GetPosition(),resFlags);
462 if ( itemHere.IsOk() && (resFlags & wxTREE_HITTEST_ONITEMLABEL) )
463 {
464 m_itemHere = itemHere;
465 m_value = itemHere;
466 Dismiss();
467 // TODO: Send event
468 }
469 event.Skip();
470 }
471
472 protected:
473
474 wxTreeItemId m_value; // current item index
475 wxTreeItemId m_itemHere; // hot item in popup
476
477 private:
478 DECLARE_EVENT_TABLE()
479 };
480
481 BEGIN_EVENT_TABLE(TreeCtrlComboPopup, wxTreeCtrl)
482 EVT_MOTION(TreeCtrlComboPopup::OnMouseMove)
483 // NOTE: Left down event is used instead of left up right now
484 // since MSW wxTreeCtrl doesn't seem to emit left ups
485 // consistently.
486 EVT_LEFT_DOWN(TreeCtrlComboPopup::OnMouseClick)
487 END_EVENT_TABLE()
488
489 // ----------------------------------------------------------------------------
490 // wxComboCtrl with entirely custom button action (opens file dialog)
491 // ----------------------------------------------------------------------------
492
493 class wxFileSelectorCombo : public wxComboCtrl
494 {
495 public:
496 wxFileSelectorCombo() : wxComboCtrl() { Init(); }
497
498 wxFileSelectorCombo(wxWindow *parent,
499 wxWindowID id = wxID_ANY,
500 const wxString& value = wxEmptyString,
501 const wxPoint& pos = wxDefaultPosition,
502 const wxSize& size = wxDefaultSize,
503 long style = 0,
504 const wxValidator& validator = wxDefaultValidator,
505 const wxString& name = wxComboBoxNameStr)
506 : wxComboCtrl()
507 {
508 Init();
509 Create(parent,id,value,
510 pos,size,
511 // Style flag wxCC_STD_BUTTON makes the button
512 // behave more like a standard push button.
513 style | wxCC_STD_BUTTON,
514 validator,name);
515
516 //
517 // Prepare custom button bitmap (just '...' text)
518 wxMemoryDC dc;
519 wxBitmap bmp(12,16);
520 dc.SelectObject(bmp);
521
522 // Draw transparent background
523 wxColour magic(255,0,255);
524 wxBrush magicBrush(magic);
525 dc.SetBrush( magicBrush );
526 dc.SetPen( *wxTRANSPARENT_PEN );
527 dc.DrawRectangle(0,0,bmp.GetWidth(),bmp.GetHeight());
528
529 // Draw text
530 wxString str = wxT("...");
531 int w,h;
532 dc.GetTextExtent(str, &w, &h, 0, 0);
533 dc.DrawText(str, (bmp.GetWidth()-w)/2, (bmp.GetHeight()-h)/2);
534
535 dc.SelectObject( wxNullBitmap );
536
537 // Finalize transparency with a mask
538 wxMask *mask = new wxMask( bmp, magic );
539 bmp.SetMask( mask );
540
541 SetButtonBitmaps(bmp,true);
542 }
543
544 virtual void OnButtonClick()
545 {
546 // Show standard wxFileDialog on button click
547
548 wxFileDialog dlg(this,
549 wxT("Choose File"),
550 wxEmptyString,
551 GetValue(),
552 wxT("All files (*.*)|*.*"),
553 wxFD_OPEN);
554
555 if ( dlg.ShowModal() == wxID_OK )
556 {
557 SetValue(dlg.GetPath());
558 }
559 }
560
561 // Implement empty DoSetPopupControl to prevent assertion failure.
562 virtual void DoSetPopupControl(wxComboPopup* WXUNUSED(popup))
563 {
564 }
565
566 private:
567 void Init()
568 {
569 // Initialize member variables here
570 }
571 };
572
573 // ----------------------------------------------------------------------------
574 // main frame
575 // ----------------------------------------------------------------------------
576
577 // frame constructor
578 MyFrame::MyFrame(const wxString& title)
579 : wxFrame(NULL, wxID_ANY, title)
580 {
581 wxBoxSizer* topSizer;
582 wxBoxSizer* topRowSizer;
583 wxBoxSizer* colSizer;
584 wxBoxSizer* rowSizer;
585
586 // set the frame icon
587 SetIcon(wxICON(sample));
588
589 #if wxUSE_MENUS
590 // create a menu bar
591 wxMenu *fileMenu = new wxMenu;
592
593 // the "About" item should be in the help menu
594 wxMenu *helpMenu = new wxMenu;
595 helpMenu->Append(ComboControl_About, _T("&About...\tF1"), _T("Show about dialog"));
596
597 fileMenu->Append(ComboControl_Compare, _T("&Compare against wxComboBox..."),
598 _T("Show some wxOwnerDrawnComboBoxes side-by-side with native wxComboBoxes."));
599 fileMenu->AppendSeparator();
600 fileMenu->Append(ComboControl_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
601
602 // now append the freshly created menu to the menu bar...
603 wxMenuBar *menuBar = new wxMenuBar();
604 menuBar->Append(fileMenu, _T("&File"));
605 menuBar->Append(helpMenu, _T("&Help"));
606
607 // ... and attach this menu bar to the frame
608 SetMenuBar(menuBar);
609 #endif // wxUSE_MENUS
610
611 wxPanel* panel = new wxPanel(this);
612
613 // Prepare log window right away since it shows EVT_TEXTs
614 m_logWin = new wxTextCtrl( panel, 105, wxEmptyString, wxDefaultPosition,
615 wxSize(-1,125), wxTE_MULTILINE|wxFULL_REPAINT_ON_RESIZE );
616 m_logWin->SetEditable(false);
617 wxLogTextCtrl* logger = new wxLogTextCtrl( m_logWin );
618 m_logOld = logger->SetActiveTarget( logger );
619 logger->SetTimestamp( NULL );
620
621
622 topSizer = new wxBoxSizer( wxVERTICAL );
623
624 topRowSizer = new wxBoxSizer( wxHORIZONTAL );
625
626 colSizer = new wxBoxSizer( wxVERTICAL );
627
628
629 wxComboCtrl* cc;
630 wxGenericComboCtrl* gcc;
631 wxOwnerDrawnComboBox* odc;
632
633 // Create common strings array
634 m_arrItems.Add( wxT("Solid") );
635 m_arrItems.Add( wxT("Transparent") );
636 m_arrItems.Add( wxT("Dot") );
637 m_arrItems.Add( wxT("Long Dash") );
638 m_arrItems.Add( wxT("Short Dash") );
639 m_arrItems.Add( wxT("Dot Dash") );
640 m_arrItems.Add( wxT("Backward Diagonal Hatch") );
641 m_arrItems.Add( wxT("Cross-diagonal Hatch") );
642 m_arrItems.Add( wxT("Forward Diagonal Hatch") );
643 m_arrItems.Add( wxT("Cross Hatch") );
644 m_arrItems.Add( wxT("Horizontal Hatch") );
645 m_arrItems.Add( wxT("Vertical Hatch") );
646
647
648 //
649 // Create pen selector ODComboBox with owner-drawn items
650 //
651 rowSizer = new wxBoxSizer( wxHORIZONTAL );
652 rowSizer->Add( new wxStaticText(panel,wxID_ANY,
653 wxT("OwnerDrawnComboBox with owner-drawn items:")), 1,
654 wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
655 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
656
657 rowSizer = new wxBoxSizer( wxHORIZONTAL );
658
659
660 // When defining derivative class for callbacks, we need
661 // to use two-stage creation (or redefine the common wx
662 // constructor).
663 odc = new wxPenStyleComboBox();
664 odc->Create(panel,wxID_ANY,wxEmptyString,
665 wxDefaultPosition, wxDefaultSize,
666 m_arrItems,
667 wxCB_READONLY //wxNO_BORDER | wxCB_READONLY
668 );
669
670
671 odc->SetSelection(0);
672
673 rowSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 );
674 rowSizer->AddStretchSpacer(1);
675 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
676
677
678
679 //
680 // Same but with changed button position
681 //
682 rowSizer = new wxBoxSizer( wxHORIZONTAL );
683 rowSizer->Add( new wxStaticText(panel,wxID_ANY,
684 wxT("OwnerDrawnComboBox with owner-drawn items and button on the left:")), 1,
685 wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
686 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
687
688 rowSizer = new wxBoxSizer( wxHORIZONTAL );
689
690
691 // When defining derivative class for callbacks, we need
692 // to use two-stage creation (or redefine the common wx
693 // constructor).
694 odc = new wxPenStyleComboBox();
695 odc->Create(panel,wxID_ANY,wxEmptyString,
696 wxDefaultPosition, wxDefaultSize,
697 m_arrItems,
698 wxCB_READONLY //wxNO_BORDER | wxCB_READONLY
699 );
700
701
702 odc->SetSelection(0);
703
704 // Use button size that is slightly smaller than the default.
705 wxSize butSize = odc->GetButtonSize();
706 odc->SetButtonPosition(butSize.x - 2, // button width
707 butSize.y - 6, // button height
708 wxLEFT, // side
709 2 // horizontal spacing
710 );
711
712 rowSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 );
713 rowSizer->AddStretchSpacer(1);
714 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
715
716
717 //
718 // List View wxComboCtrl
719 //
720
721 rowSizer = new wxBoxSizer( wxHORIZONTAL );
722 rowSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("List View wxComboCtrl:")), 1,
723 wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
724 rowSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Tree Ctrl wxComboControl:")), 1,
725 wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
726 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
727
728 rowSizer = new wxBoxSizer( wxHORIZONTAL );
729 cc = new wxComboCtrl(panel,2,wxEmptyString,
730 wxDefaultPosition, wxDefaultSize);
731
732 cc->SetPopupMinWidth(300);
733
734 ListViewComboPopup* iface = new ListViewComboPopup();
735 cc->SetPopupControl(iface);
736
737 int i;
738 for ( i=0; i<100; i++ )
739 iface->AddSelection( wxString::Format(wxT("Item %02i"),i));
740
741 rowSizer->Add( cc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
742
743
744 //
745 // Tree Ctrl wxComboCtrl
746 //
747
748 // Note that we test that wxGenericComboCtrl works
749 gcc = new wxGenericComboCtrl(panel,wxID_ANY,wxEmptyString,
750 wxDefaultPosition, wxDefaultSize);
751
752 // Set popup interface right away, otherwise some of the calls
753 // below may fail
754 TreeCtrlComboPopup* tcPopup = new TreeCtrlComboPopup();
755 gcc->SetPopupControl(tcPopup);
756
757 // Add items using wxTreeCtrl methods directly
758 wxTreeItemId rootId = tcPopup->AddRoot(wxT("<hidden_root>"));
759
760 wxTreeItemId groupId;
761
762 for ( i=0; i<4; i++ )
763 {
764 groupId = tcPopup->AppendItem(rootId,
765 wxString::Format(wxT("Branch %02i"),i));
766
767 int n;
768 for ( n=0; n<25; n++ )
769 tcPopup->AppendItem(groupId,
770 wxString::Format(wxT("Subitem %02i"),(i*25)+n));
771 }
772
773 gcc->SetValue(wxT("Subitem 05"));
774
775 // Move button to left - it makes more sense for a tree ctrl
776 gcc->SetButtonPosition(-1, // button width
777 -1, // button height
778 wxLEFT, // side
779 0 // horizontal spacing
780 );
781
782 rowSizer->Add( gcc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 );
783
784 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
785
786 #if wxUSE_IMAGE
787 wxInitAllImageHandlers();
788
789 //
790 // Custom Dropbutton Bitmaps
791 // (second one uses blank button background)
792 //
793 rowSizer = new wxBoxSizer( wxHORIZONTAL );
794 rowSizer->Add( new wxStaticText(panel,wxID_ANY,
795 wxT("OwnerDrawnComboBox with simple dropbutton graphics:")), 1,
796 wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
797
798 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
799
800 rowSizer = new wxBoxSizer( wxHORIZONTAL );
801
802 odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString,
803 wxDefaultPosition, wxDefaultSize,
804 m_arrItems,
805 (long)0 // wxCB_SORT // wxNO_BORDER | wxCB_READONLY
806 );
807
808 wxOwnerDrawnComboBox* odc2;
809 odc2 = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString,
810 wxDefaultPosition, wxDefaultSize,
811 m_arrItems,
812 (long)0 // wxCB_SORT // wxNO_BORDER | wxCB_READONLY
813 );
814
815 // Load images from disk
816 wxImage imgNormal(wxT("dropbutn.png"));
817 wxImage imgPressed(wxT("dropbutp.png"));
818 wxImage imgHover(wxT("dropbuth.png"));
819
820 if ( imgNormal.Ok() && imgPressed.Ok() && imgHover.Ok() )
821 {
822 wxBitmap bmpNormal(imgNormal);
823 wxBitmap bmpPressed(imgPressed);
824 wxBitmap bmpHover(imgHover);
825 odc->SetButtonBitmaps(bmpNormal,false,bmpPressed,bmpHover);
826 odc2->SetButtonBitmaps(bmpNormal,true,bmpPressed,bmpHover);
827 }
828 else
829 wxLogError(wxT("Dropbutton images not found"));
830
831 //odc2->SetButtonPosition(0, // width adjustment
832 // 0, // height adjustment
833 // wxLEFT, // side
834 // 0 // horizontal spacing
835 // );
836
837 rowSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 );
838 rowSizer->Add( odc2, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 );
839 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
840 #endif
841
842
843 //
844 // wxComboCtrl with totally custom button action (open file dialog)
845 //
846 rowSizer = new wxBoxSizer( wxHORIZONTAL );
847 rowSizer->Add( new wxStaticText(panel,wxID_ANY,
848 wxT("wxComboCtrl with custom button action:")), 1,
849 wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
850
851
852 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
853
854 rowSizer = new wxBoxSizer( wxHORIZONTAL );
855 wxFileSelectorCombo* fsc;
856
857 fsc = new wxFileSelectorCombo(panel,wxID_ANY,wxEmptyString,
858 wxDefaultPosition, wxDefaultSize,
859 (long)0
860 );
861
862 rowSizer->Add( fsc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 );
863 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 );
864
865
866 // Make sure GetFeatures is implemented
867 wxComboCtrl::GetFeatures();
868
869
870 topRowSizer->Add( colSizer, 1, wxALL, 2 );
871
872 topRowSizer->Add( m_logWin, 1, wxEXPAND|wxALL, 5 );
873 topSizer->Add( topRowSizer, 1, wxEXPAND );
874
875 panel->SetSizer( topSizer );
876 topSizer->SetSizeHints( panel );
877
878 SetSize(740,400);
879 Centre();
880 }
881
882 // event handlers
883
884 void MyFrame::OnComboBoxUpdate( wxCommandEvent& event )
885 {
886 // Don't show messages for the log output window (it'll crash)
887 if ( !event.GetEventObject()->IsKindOf(CLASSINFO(wxComboCtrl)) )
888 return;
889
890 if ( event.GetEventType() == wxEVT_COMMAND_COMBOBOX_SELECTED )
891 wxLogDebug(wxT("EVT_COMBOBOX(id=%i,selection=%i)"),event.GetId(),event.GetSelection());
892 else if ( event.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED )
893 wxLogDebug(wxT("EVT_TEXT(id=%i,string=\"%s\")"),event.GetId(),event.GetString().c_str());
894 }
895
896 void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) )
897 {
898 //
899 // Show some wxOwnerDrawComboBoxes for comparison
900 //
901
902 wxBoxSizer* colSizer;
903 wxBoxSizer* rowSizer;
904 wxStaticBoxSizer* groupSizer;
905
906 wxComboBox* cb;
907 wxOwnerDrawnComboBox* odc;
908
909 const int border = 4;
910
911 wxDialog* dlg = new wxDialog(this,wxID_ANY,
912 wxT("Compare against wxComboBox"),
913 wxDefaultPosition,wxDefaultSize,
914 wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER);
915
916 colSizer = new wxBoxSizer( wxVERTICAL );
917
918 rowSizer = new wxBoxSizer(wxHORIZONTAL);
919
920 groupSizer = new wxStaticBoxSizer(new wxStaticBox(dlg,wxID_ANY,wxT(" wxOwnerDrawnComboBox ")),
921 wxVERTICAL);
922
923 groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Writable, sorted:")), 0,
924 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border );
925
926 odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString,
927 wxDefaultPosition, wxDefaultSize,
928 m_arrItems,
929 wxCB_SORT // wxNO_BORDER|wxCB_READONLY
930 );
931
932 odc->Append(wxT("H - Appended Item")); // test sorting in append
933
934 odc->SetValue(wxT("Dot Dash"));
935
936 groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
937
938 //
939 // Readonly ODComboBox
940 groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Read-only:")), 0,
941 wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
942
943 odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString,
944 wxDefaultPosition, wxDefaultSize,
945 m_arrItems,
946 wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
947 );
948
949 odc->SetValue(wxT("Dot Dash"));
950 odc->SetText(wxT("Dot Dash (Testing SetText)"));
951
952 groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
953
954 //
955 // Disabled ODComboBox
956 groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Disabled:")), 0,
957 wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
958
959 odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString,
960 wxDefaultPosition, wxDefaultSize,
961 m_arrItems,
962 wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
963 );
964
965 odc->SetValue(wxT("Dot Dash"));
966 odc->Enable(false);
967
968 groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
969
970 rowSizer->Add( groupSizer, 1, wxEXPAND|wxALL, border );
971
972
973 groupSizer = new wxStaticBoxSizer(new wxStaticBox(dlg,wxID_ANY,wxT(" wxComboBox ")),
974 wxVERTICAL);
975
976 //
977 // wxComboBox
978 //
979 groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Writable, sorted:")), 0,
980 wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border );
981
982 cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString,
983 wxDefaultPosition, wxDefaultSize,
984 m_arrItems,
985 wxCB_SORT // wxNO_BORDER|wxCB_READONLY
986 );
987
988 cb->Append(wxT("H - Appended Item")); // test sorting in append
989
990 cb->SetValue(wxT("Dot Dash"));
991
992 groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
993
994 //
995 // Readonly wxComboBox
996 groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Read-only:")), 0,
997 wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
998
999 cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString,
1000 wxDefaultPosition, wxDefaultSize,
1001 m_arrItems,
1002 wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
1003 );
1004
1005 cb->SetValue(wxT("Dot Dash"));
1006
1007 groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
1008
1009 //
1010 // Disabled wxComboBox
1011 groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Disabled:")), 0,
1012 wxALIGN_CENTER_VERTICAL|wxRIGHT, border );
1013
1014 cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString,
1015 wxDefaultPosition, wxDefaultSize,
1016 m_arrItems,
1017 wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY
1018 );
1019
1020 cb->SetValue(wxT("Dot Dash"));
1021 cb->Enable(false);
1022
1023 groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border );
1024
1025 rowSizer->Add( groupSizer, 1, wxEXPAND|wxALL, border );
1026
1027 colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, border );
1028
1029 dlg->SetSizer( colSizer );
1030 colSizer->SetSizeHints( dlg );
1031
1032 dlg->SetSize(60,240);
1033 dlg->Centre();
1034 dlg->ShowModal();
1035 }
1036
1037 MyFrame::~MyFrame()
1038 {
1039 delete wxLog::SetActiveTarget(m_logOld);
1040 }
1041
1042 void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
1043 {
1044 // true is to force the frame to close
1045 Close(true);
1046 }
1047
1048 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
1049 {
1050 wxMessageBox(wxString::Format(
1051 _T("Welcome to %s!\n")
1052 _T("\n")
1053 _T("This is the wxWidgets wxComboCtrl and wxOwnerDrawnComboBox sample\n")
1054 _T("running under %s."),
1055 wxVERSION_STRING,
1056 wxGetOsDescription().c_str()
1057 ),
1058 _T("About wxComboCtrl sample"),
1059 wxOK | wxICON_INFORMATION,
1060 this);
1061 }