1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxComboCtrl sample
4 // Author: Jaakko Salli
6 // Created: Apr-30-2006
7 // Copyright: (c) Jaakko Salli
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx/wx.h".
20 #include "wx/wxprec.h"
26 // for all others, include the necessary headers (this file is usually all you
27 // need because it includes almost all "standard" wxWidgets headers)
33 #error "Please set wxUSE_COMBOCTRL to 1 and rebuild the library."
39 #include "wx/odcombo.h"
41 // ----------------------------------------------------------------------------
43 // ----------------------------------------------------------------------------
45 // the application icon (under Windows and OS/2 it is in resources and even
46 // though we could still include the XPM here it would be unused)
47 #ifndef wxHAS_IMAGES_IN_RESOURCES
48 #include "../sample.xpm"
51 // ----------------------------------------------------------------------------
53 // ----------------------------------------------------------------------------
55 // Define a new application type, each program should derive a class from wxApp
56 class MyApp
: public wxApp
59 // override base class virtuals
60 // ----------------------------
62 // this one is called on application startup and is a good place for the app
63 // initialization (doing it here and not in the ctor allows to have an error
64 // return: if OnInit() returns false, the application terminates)
65 virtual bool OnInit();
68 // Define a new frame type: this is going to be our main frame
69 class MyFrame
: public wxFrame
73 MyFrame(const wxString
& title
);
76 // event handlers (these functions should _not_ be virtual)
77 void OnQuit(wxCommandEvent
& event
);
78 void OnAbout(wxCommandEvent
& event
);
80 void OnShowComparison( wxCommandEvent
& event
);
82 // log wxComboCtrl events
83 void OnComboBoxUpdate( wxCommandEvent
& event
);
85 void OnIdle( wxIdleEvent
& event
);
92 // Common list of items for all dialogs.
93 wxArrayString m_arrItems
;
96 // any class wishing to process wxWidgets events must use this macro
100 // ----------------------------------------------------------------------------
102 // ----------------------------------------------------------------------------
104 // IDs for the controls and the menu commands
107 ComboCtrl_Compare
= wxID_HIGHEST
,
110 ComboCtrl_Quit
= wxID_EXIT
,
112 // it is important for the id corresponding to the "About" command to have
113 // this standard value as otherwise it won't be handled properly under Mac
114 // (where it is special and put into the "Apple" menu)
115 ComboCtrl_About
= wxID_ABOUT
118 // ----------------------------------------------------------------------------
119 // event tables and other macros for wxWidgets
120 // ----------------------------------------------------------------------------
122 // the event tables connect the wxWidgets events with the functions (event
123 // handlers) which process them. It can be also done at run-time, but for the
124 // simple menu events like this the static method is much simpler.
125 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
126 EVT_TEXT(wxID_ANY
,MyFrame::OnComboBoxUpdate
)
127 EVT_TEXT_ENTER(wxID_ANY
,MyFrame::OnComboBoxUpdate
)
128 EVT_COMBOBOX(wxID_ANY
,MyFrame::OnComboBoxUpdate
)
130 EVT_MENU(ComboCtrl_Compare
, MyFrame::OnShowComparison
)
131 EVT_MENU(ComboCtrl_Quit
, MyFrame::OnQuit
)
132 EVT_MENU(ComboCtrl_About
, MyFrame::OnAbout
)
134 EVT_IDLE(MyFrame::OnIdle
)
137 // Create a new application object: this macro will allow wxWidgets to create
138 // the application object during program execution (it's better than using a
139 // static object for many reasons) and also implements the accessor function
140 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
144 // ============================================================================
146 // ============================================================================
148 // ----------------------------------------------------------------------------
149 // the application class
150 // ----------------------------------------------------------------------------
152 // 'Main program' equivalent: the program execution "starts" here
155 if ( !wxApp::OnInit() )
158 // create the main application window
159 MyFrame
*frame
= new MyFrame(wxT("wxComboCtrl and wxOwnerDrawnComboBox Sample"));
161 // and show it (the frames, unlike simple controls, are not shown when
162 // created initially)
165 // success: wxApp::OnRun() will be called which will enter the main message
166 // loop and the application will run. If we returned false here, the
167 // application would exit immediately.
172 // ----------------------------------------------------------------------------
173 // wxOwnerDrawnComboBox with custom paint list items
174 // ----------------------------------------------------------------------------
176 class wxPenStyleComboBox
: public wxOwnerDrawnComboBox
179 virtual void OnDrawItem( wxDC
& dc
,
184 if ( item
== wxNOT_FOUND
)
191 wxPenStyle penStyle
= wxPENSTYLE_SOLID
;
193 penStyle
= wxPENSTYLE_TRANSPARENT
;
194 else if ( item
== 2 )
195 penStyle
= wxPENSTYLE_DOT
;
196 else if ( item
== 3 )
197 penStyle
= wxPENSTYLE_LONG_DASH
;
198 else if ( item
== 4 )
199 penStyle
= wxPENSTYLE_SHORT_DASH
;
200 else if ( item
== 5 )
201 penStyle
= wxPENSTYLE_DOT_DASH
;
202 else if ( item
== 6 )
203 penStyle
= wxPENSTYLE_BDIAGONAL_HATCH
;
204 else if ( item
== 7 )
205 penStyle
= wxPENSTYLE_CROSSDIAG_HATCH
;
206 else if ( item
== 8 )
207 penStyle
= wxPENSTYLE_FDIAGONAL_HATCH
;
208 else if ( item
== 9 )
209 penStyle
= wxPENSTYLE_CROSS_HATCH
;
210 else if ( item
== 10 )
211 penStyle
= wxPENSTYLE_HORIZONTAL_HATCH
;
212 else if ( item
== 11 )
213 penStyle
= wxPENSTYLE_VERTICAL_HATCH
;
215 wxPen
pen( dc
.GetTextForeground(), 3, penStyle
);
217 // Get text colour as pen colour
220 if ( !(flags
& wxODCB_PAINTING_CONTROL
) )
222 dc
.DrawText(GetString( item
),
224 (r
.y
+ 0) + ( (r
.height
/2) - dc
.GetCharHeight() )/2
227 dc
.DrawLine( r
.x
+5, r
.y
+((r
.height
/4)*3), r
.x
+r
.width
- 5, r
.y
+((r
.height
/4)*3) );
231 dc
.DrawLine( r
.x
+5, r
.y
+r
.height
/2, r
.x
+r
.width
- 5, r
.y
+r
.height
/2 );
235 virtual void OnDrawBackground( wxDC
& dc
, const wxRect
& rect
,
236 int item
, int flags
) const
239 // If item is selected or even, or we are painting the
240 // combo control itself, use the default rendering.
241 if ( (flags
& (wxODCB_PAINTING_CONTROL
|wxODCB_PAINTING_SELECTED
)) ||
244 wxOwnerDrawnComboBox::OnDrawBackground(dc
,rect
,item
,flags
);
248 // Otherwise, draw every other background with different colour.
249 wxColour
bgCol(240,240,250);
250 dc
.SetBrush(wxBrush(bgCol
));
251 dc
.SetPen(wxPen(bgCol
));
252 dc
.DrawRectangle(rect
);
255 virtual wxCoord
OnMeasureItem( size_t item
) const
257 // Simply demonstrate the ability to have variable-height items
264 virtual wxCoord
OnMeasureItemWidth( size_t WXUNUSED(item
) ) const
266 return -1; // default - will be measured from text width
272 // ----------------------------------------------------------------------------
273 // wxListView Custom popup interface
274 // ----------------------------------------------------------------------------
276 #include <wx/listctrl.h>
278 class ListViewComboPopup
: public wxListView
, public wxComboPopup
285 m_itemHere
= -1; // hot item in list
288 virtual bool Create( wxWindow
* parent
)
290 return wxListView::Create(parent
,1,
291 wxPoint(0,0),wxDefaultSize
,
292 wxLC_LIST
|wxLC_SINGLE_SEL
|
293 wxLC_SORT_ASCENDING
|wxSIMPLE_BORDER
);
296 virtual wxWindow
*GetControl() { return this; }
298 virtual void SetStringValue( const wxString
& s
)
300 int n
= wxListView::FindItem(-1,s
);
301 if ( n
>= 0 && n
< GetItemCount() )
302 wxListView::Select(n
);
305 virtual wxString
GetStringValue() const
308 return wxListView::GetItemText(m_value
);
309 return wxEmptyString
;
313 // Popup event handlers
316 // Mouse hot-tracking
317 void OnMouseMove(wxMouseEvent
& event
)
319 // Move selection to cursor if it is inside the popup
322 int itemHere
= HitTest(event
.GetPosition(),resFlags
);
325 wxListView::Select(itemHere
,true);
326 m_itemHere
= itemHere
;
331 // On mouse left, set the value and close the popup
332 void OnMouseClick(wxMouseEvent
& WXUNUSED(event
))
334 m_value
= m_itemHere
;
340 // Utilies for item manipulation
343 void AddSelection( const wxString
& selstr
)
345 wxListView::InsertItem(GetItemCount(),selstr
);
350 int m_value
; // current item index
351 int m_itemHere
; // hot item in popup
354 DECLARE_EVENT_TABLE()
357 BEGIN_EVENT_TABLE(ListViewComboPopup
, wxListView
)
358 EVT_MOTION(ListViewComboPopup::OnMouseMove
)
359 // NOTE: Left down event is used instead of left up right now
360 // since MSW wxListCtrl doesn't seem to emit left ups
362 EVT_LEFT_DOWN(ListViewComboPopup::OnMouseClick
)
366 // ----------------------------------------------------------------------------
367 // wxTreeCtrl Custom popup interface
368 // ----------------------------------------------------------------------------
370 #include <wx/treectrl.h>
372 class TreeCtrlComboPopup
: public wxTreeCtrl
, public wxComboPopup
379 virtual ~TreeCtrlComboPopup()
381 if (!m_isBeingDeleted
)
383 wxMessageBox("error wxTreeCtrl::Destroy() was not called");
388 virtual bool Create( wxWindow
* parent
)
390 return wxTreeCtrl::Create(parent
,1,
391 wxPoint(0,0),wxDefaultSize
,
392 wxTR_DEFAULT_STYLE
| wxTR_HIDE_ROOT
| wxSIMPLE_BORDER
);
395 virtual void OnShow()
397 // make sure selected item is visible
398 if ( m_value
.IsOk() )
399 EnsureVisible(m_value
);
402 virtual wxSize
GetAdjustedSize( int minWidth
,
403 int WXUNUSED(prefHeight
),
406 return wxSize(wxMax(300,minWidth
),wxMin(250,maxHeight
));
409 virtual wxWindow
*GetControl() { return this; }
411 // Needed by SetStringValue
412 wxTreeItemId
FindItemByText( wxTreeItemId parent
, const wxString
& text
)
414 wxTreeItemIdValue cookie
;
415 wxTreeItemId child
= GetFirstChild(parent
,cookie
);
416 while ( child
.IsOk() )
418 if ( GetItemText(child
) == text
)
422 if ( ItemHasChildren(child
) )
424 wxTreeItemId found
= FindItemByText(child
,text
);
428 child
= GetNextChild(parent
,cookie
);
430 return wxTreeItemId();
433 virtual void SetStringValue( const wxString
& s
)
435 wxTreeItemId root
= GetRootItem();
439 wxTreeItemId found
= FindItemByText(root
,s
);
442 m_value
= m_itemHere
= found
;
443 wxTreeCtrl::SelectItem(found
);
447 virtual wxString
GetStringValue() const
449 if ( m_value
.IsOk() )
450 return wxTreeCtrl::GetItemText(m_value
);
451 return wxEmptyString
;
455 // Popup event handlers
458 // Mouse hot-tracking
459 void OnMouseMove(wxMouseEvent
& event
)
462 wxTreeItemId itemHere
= HitTest(event
.GetPosition(),resFlags
);
463 if ( itemHere
.IsOk() && (resFlags
& wxTREE_HITTEST_ONITEMLABEL
) )
465 wxTreeCtrl::SelectItem(itemHere
,true);
466 m_itemHere
= itemHere
;
471 // On mouse left, set the value and close the popup
472 void OnMouseClick(wxMouseEvent
& event
)
475 wxTreeItemId itemHere
= HitTest(event
.GetPosition(),resFlags
);
476 if ( itemHere
.IsOk() && (resFlags
& wxTREE_HITTEST_ONITEMLABEL
) )
478 m_itemHere
= itemHere
;
488 wxTreeItemId m_value
; // current item index
489 wxTreeItemId m_itemHere
; // hot item in popup
492 DECLARE_EVENT_TABLE()
495 BEGIN_EVENT_TABLE(TreeCtrlComboPopup
, wxTreeCtrl
)
496 EVT_MOTION(TreeCtrlComboPopup::OnMouseMove
)
497 // NOTE: Left down event is used instead of left up right now
498 // since MSW wxTreeCtrl doesn't seem to emit left ups
500 EVT_LEFT_DOWN(TreeCtrlComboPopup::OnMouseClick
)
503 // ----------------------------------------------------------------------------
504 // wxComboCtrl with custom popup animation, using wxWindow::ShowWithEffect().
505 // ----------------------------------------------------------------------------
507 class wxComboCtrlWithCustomPopupAnim
: public wxComboCtrl
510 virtual bool AnimateShow( const wxRect
& rect
, int WXUNUSED(flags
) )
512 wxWindow
* win
= GetPopupWindow();
514 win
->Raise(); // This is needed
515 win
->ShowWithEffect(wxSHOW_EFFECT_BLEND
);
520 // ----------------------------------------------------------------------------
521 // wxComboCtrl with entirely custom button action (opens file dialog)
522 // ----------------------------------------------------------------------------
524 class wxFileSelectorCombo
: public wxComboCtrl
527 wxFileSelectorCombo() : wxComboCtrl() { Init(); }
529 wxFileSelectorCombo(wxWindow
*parent
,
530 wxWindowID id
= wxID_ANY
,
531 const wxString
& value
= wxEmptyString
,
532 const wxPoint
& pos
= wxDefaultPosition
,
533 const wxSize
& size
= wxDefaultSize
,
535 const wxValidator
& validator
= wxDefaultValidator
,
536 const wxString
& name
= wxComboBoxNameStr
)
540 Create(parent
,id
,value
,
542 // Style flag wxCC_STD_BUTTON makes the button
543 // behave more like a standard push button.
544 style
| wxCC_STD_BUTTON
,
548 // Prepare custom button bitmap (just '...' text)
551 dc
.SelectObject(bmp
);
553 // Draw transparent background
554 wxColour
magic(255,0,255);
555 wxBrush
magicBrush(magic
);
556 dc
.SetBrush( magicBrush
);
557 dc
.SetPen( *wxTRANSPARENT_PEN
);
558 dc
.DrawRectangle(0,0,bmp
.GetWidth(),bmp
.GetHeight());
561 wxString str
= wxT("...");
563 dc
.GetTextExtent(str
, &w
, &h
, 0, 0);
564 dc
.DrawText(str
, (bmp
.GetWidth()-w
)/2, (bmp
.GetHeight()-h
)/2);
566 dc
.SelectObject( wxNullBitmap
);
568 // Finalize transparency with a mask
569 wxMask
*mask
= new wxMask( bmp
, magic
);
572 SetButtonBitmaps(bmp
,true);
575 virtual void OnButtonClick()
577 // Show standard wxFileDialog on button click
579 wxFileDialog
dlg(this,
583 wxT("All files (*.*)|*.*"),
586 if ( dlg
.ShowModal() == wxID_OK
)
588 SetValue(dlg
.GetPath());
592 // Implement empty DoSetPopupControl to prevent assertion failure.
593 virtual void DoSetPopupControl(wxComboPopup
* WXUNUSED(popup
))
600 // Initialize member variables here
604 // ----------------------------------------------------------------------------
606 // ----------------------------------------------------------------------------
609 MyFrame::MyFrame(const wxString
& title
)
610 : wxFrame(NULL
, wxID_ANY
, title
)
612 wxBoxSizer
* topSizer
;
613 wxBoxSizer
* topRowSizer
;
614 wxBoxSizer
* colSizer
;
615 wxBoxSizer
* rowSizer
;
617 // set the frame icon
618 SetIcon(wxICON(sample
));
622 wxMenu
*fileMenu
= new wxMenu
;
624 // the "About" item should be in the help menu
625 wxMenu
*helpMenu
= new wxMenu
;
626 helpMenu
->Append(ComboCtrl_About
, wxT("&About\tF1"), wxT("Show about dialog"));
628 fileMenu
->Append(ComboCtrl_Compare
, wxT("&Compare against wxComboBox..."),
629 wxT("Show some wxOwnerDrawnComboBoxes side-by-side with native wxComboBoxes."));
630 fileMenu
->AppendSeparator();
631 fileMenu
->Append(ComboCtrl_Quit
, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
633 // now append the freshly created menu to the menu bar...
634 wxMenuBar
*menuBar
= new wxMenuBar();
635 menuBar
->Append(fileMenu
, wxT("&File"));
636 menuBar
->Append(helpMenu
, wxT("&Help"));
638 // ... and attach this menu bar to the frame
640 #endif // wxUSE_MENUS
642 wxPanel
* panel
= new wxPanel(this);
644 // Prepare log window right away since it shows EVT_TEXTs
645 m_logWin
= new wxTextCtrl(panel
, 105, wxEmptyString
,
649 wxLogTextCtrl
* logger
= new wxLogTextCtrl(m_logWin
);
650 m_logOld
= logger
->SetActiveTarget(logger
);
651 logger
->DisableTimestamp();
654 topSizer
= new wxBoxSizer( wxVERTICAL
);
656 topRowSizer
= new wxBoxSizer( wxHORIZONTAL
);
658 colSizer
= new wxBoxSizer( wxVERTICAL
);
662 wxGenericComboCtrl
* gcc
;
663 wxOwnerDrawnComboBox
* odc
;
665 // Create common strings array
666 m_arrItems
.Add( wxT("Solid") );
667 m_arrItems
.Add( wxT("Transparent") );
668 m_arrItems
.Add( wxT("Dot") );
669 m_arrItems
.Add( wxT("Long Dash") );
670 m_arrItems
.Add( wxT("Short Dash") );
671 m_arrItems
.Add( wxT("Dot Dash") );
672 m_arrItems
.Add( wxT("Backward Diagonal Hatch") );
673 m_arrItems
.Add( wxT("Cross-diagonal Hatch") );
674 m_arrItems
.Add( wxT("Forward Diagonal Hatch") );
675 m_arrItems
.Add( wxT("Cross Hatch") );
676 m_arrItems
.Add( wxT("Horizontal Hatch") );
677 m_arrItems
.Add( wxT("Vertical Hatch") );
681 // Create pen selector ODComboBox with owner-drawn items
683 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
684 rowSizer
->Add( new wxStaticText(panel
,wxID_ANY
,
685 wxT("OwnerDrawnComboBox with owner-drawn items:")), 1,
686 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
687 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
689 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
692 // When defining derivative class for callbacks, we need
693 // to use two-stage creation (or redefine the common wx
695 odc
= new wxPenStyleComboBox();
696 odc
->Create(panel
,wxID_ANY
,wxEmptyString
,
697 wxDefaultPosition
, wxDefaultSize
,
699 wxCB_READONLY
//wxNO_BORDER | wxCB_READONLY
703 odc
->SetSelection(0);
705 rowSizer
->Add( odc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 4 );
706 rowSizer
->AddStretchSpacer(1);
707 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
712 // Same but with changed button position
714 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
715 rowSizer
->Add( new wxStaticText(panel
,wxID_ANY
,
716 wxT("OwnerDrawnComboBox with owner-drawn items and button on the left:")), 1,
717 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
718 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
720 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
723 // When defining derivative class for callbacks, we need
724 // to use two-stage creation (or redefine the common wx
726 odc
= new wxPenStyleComboBox();
727 odc
->Create(panel
,wxID_ANY
,wxEmptyString
,
728 wxDefaultPosition
, wxDefaultSize
,
730 wxCB_READONLY
//wxNO_BORDER | wxCB_READONLY
734 odc
->SetSelection(0);
736 // Use button size that is slightly smaller than the default.
737 wxSize butSize
= odc
->GetButtonSize();
738 odc
->SetButtonPosition(butSize
.x
- 2, // button width
739 butSize
.y
- 6, // button height
741 2 // horizontal spacing
744 rowSizer
->Add( odc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 4 );
745 rowSizer
->AddStretchSpacer(1);
746 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
750 // List View wxComboCtrl
753 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
754 rowSizer
->Add( new wxStaticText(panel
,
756 "List View wxComboCtrl (custom animation):"),
757 1, wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
758 rowSizer
->Add( new wxStaticText(panel
,wxID_ANY
,wxT("Tree Ctrl wxComboCtrl:")), 1,
759 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
760 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
762 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
763 cc
= new wxComboCtrlWithCustomPopupAnim();
765 // Let's set a custom style for the contained wxTextCtrl. We need to
766 // use two-step creation for it to work properly.
767 cc
->SetTextCtrlStyle(wxTE_RIGHT
);
769 cc
->Create(panel
, wxID_ANY
, wxEmptyString
);
771 // Make sure we use popup that allows focusing the listview.
772 cc
->UseAltPopupWindow();
774 cc
->SetPopupMinWidth(300);
776 ListViewComboPopup
* iface
= new ListViewComboPopup();
777 cc
->SetPopupControl(iface
);
780 for ( i
=0; i
<100; i
++ )
781 iface
->AddSelection( wxString::Format(wxT("Item %02i"),i
));
783 rowSizer
->Add( cc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5 );
787 // Tree Ctrl wxComboCtrl
790 // Note that we test that wxGenericComboCtrl works
791 gcc
= new wxGenericComboCtrl(panel
,wxID_ANY
,wxEmptyString
,
792 wxDefaultPosition
, wxDefaultSize
);
794 // Make sure we use popup that allows focusing the treectrl.
795 gcc
->UseAltPopupWindow();
797 // Set popup interface right away, otherwise some of the calls
799 TreeCtrlComboPopup
* tcPopup
= new TreeCtrlComboPopup();
800 gcc
->SetPopupControl(tcPopup
);
802 // Add items using wxTreeCtrl methods directly
803 wxTreeItemId rootId
= tcPopup
->AddRoot(wxT("<hidden_root>"));
805 wxTreeItemId groupId
;
807 for ( i
=0; i
<4; i
++ )
809 groupId
= tcPopup
->AppendItem(rootId
,
810 wxString::Format(wxT("Branch %02i"),i
));
813 for ( n
=0; n
<25; n
++ )
814 tcPopup
->AppendItem(groupId
,
815 wxString::Format(wxT("Subitem %02i"),(i
*25)+n
));
818 gcc
->SetValue(wxT("Subitem 05"));
820 // Move button to left - it makes more sense for a tree ctrl
821 gcc
->SetButtonPosition(-1, // button width
824 0 // horizontal spacing
827 rowSizer
->Add( gcc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5 );
829 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
832 wxInitAllImageHandlers();
835 // Custom Dropbutton Bitmaps
836 // (second one uses blank button background)
838 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
839 rowSizer
->Add( new wxStaticText(panel
,wxID_ANY
,
840 wxT("OwnerDrawnComboBox with simple dropbutton graphics:")), 1,
841 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
843 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
845 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
847 odc
= new wxOwnerDrawnComboBox(panel
,wxID_ANY
,wxEmptyString
,
848 wxDefaultPosition
, wxDefaultSize
,
850 (long)0 // wxCB_SORT // wxNO_BORDER | wxCB_READONLY
853 wxOwnerDrawnComboBox
* odc2
;
854 odc2
= new wxOwnerDrawnComboBox(panel
,wxID_ANY
,wxEmptyString
,
855 wxDefaultPosition
, wxDefaultSize
,
857 (long)0 // wxCB_SORT // wxNO_BORDER | wxCB_READONLY
860 // Load images from disk
861 wxImage
imgNormal(wxT("dropbutn.png"));
862 wxImage
imgPressed(wxT("dropbutp.png"));
863 wxImage
imgHover(wxT("dropbuth.png"));
865 if ( imgNormal
.IsOk() && imgPressed
.IsOk() && imgHover
.IsOk() )
867 wxBitmap
bmpNormal(imgNormal
);
868 wxBitmap
bmpPressed(imgPressed
);
869 wxBitmap
bmpHover(imgHover
);
870 odc
->SetButtonBitmaps(bmpNormal
,false,bmpPressed
,bmpHover
);
871 odc2
->SetButtonBitmaps(bmpNormal
,true,bmpPressed
,bmpHover
);
874 wxLogError(wxT("Dropbutton images not found"));
876 //odc2->SetButtonPosition(0, // width adjustment
877 // 0, // height adjustment
879 // 0 // horizontal spacing
882 rowSizer
->Add( odc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 4 );
883 rowSizer
->Add( odc2
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 4 );
884 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
889 // wxComboCtrl with totally custom button action (open file dialog)
891 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
892 rowSizer
->Add( new wxStaticText(panel
,wxID_ANY
,
893 wxT("wxComboCtrl with custom button action:")), 1,
894 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
897 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
899 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
900 wxFileSelectorCombo
* fsc
;
902 fsc
= new wxFileSelectorCombo(panel
,wxID_ANY
,wxEmptyString
,
903 wxDefaultPosition
, wxDefaultSize
,
907 rowSizer
->Add( fsc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 4 );
908 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
911 // Make sure GetFeatures is implemented
912 wxComboCtrl::GetFeatures();
915 topRowSizer
->Add( colSizer
, 1, wxALL
, 2 );
917 colSizer
= new wxBoxSizer( wxVERTICAL
);
919 colSizer
->AddSpacer(8);
920 colSizer
->Add( new wxStaticText(panel
, wxID_ANY
, wxT("Log Messages:")), 0, wxTOP
|wxLEFT
, 3 );
921 colSizer
->Add( m_logWin
, 1, wxEXPAND
|wxALL
, 3 );
923 topRowSizer
->Add( colSizer
, 1, wxEXPAND
|wxALL
, 2 );
924 topSizer
->Add( topRowSizer
, 1, wxEXPAND
);
926 panel
->SetSizer( topSizer
);
927 topSizer
->SetSizeHints( panel
);
935 void MyFrame::OnComboBoxUpdate( wxCommandEvent
& event
)
937 // Don't show messages for the log output window (it'll crash)
938 if ( !event
.GetEventObject()->IsKindOf(CLASSINFO(wxComboCtrl
)) )
941 if ( event
.GetEventType() == wxEVT_COMBOBOX
)
943 wxLogDebug(wxT("EVT_COMBOBOX(id=%i,selection=%i)"),event
.GetId(),event
.GetSelection());
945 else if ( event
.GetEventType() == wxEVT_TEXT
)
947 wxLogDebug(wxT("EVT_TEXT(id=%i,string=\"%s\")"),event
.GetId(),event
.GetString().c_str());
949 else if ( event
.GetEventType() == wxEVT_TEXT_ENTER
)
951 wxLogDebug("EVT_TEXT_ENTER(id=%i,string=\"%s\")",
952 event
.GetId(), event
.GetString().c_str());
956 void MyFrame::OnShowComparison( wxCommandEvent
& WXUNUSED(event
) )
959 // Show some wxOwnerDrawComboBoxes for comparison
962 wxBoxSizer
* colSizer
;
963 wxBoxSizer
* rowSizer
;
964 wxStaticBoxSizer
* groupSizer
;
967 wxOwnerDrawnComboBox
* odc
;
969 const int border
= 4;
971 wxDialog
* dlg
= new wxDialog(this,wxID_ANY
,
972 wxT("Compare against wxComboBox"),
973 wxDefaultPosition
,wxDefaultSize
,
974 wxDEFAULT_DIALOG_STYLE
|wxRESIZE_BORDER
);
976 colSizer
= new wxBoxSizer( wxVERTICAL
);
978 rowSizer
= new wxBoxSizer(wxHORIZONTAL
);
980 groupSizer
= new wxStaticBoxSizer(new wxStaticBox(dlg
,wxID_ANY
,wxT(" wxOwnerDrawnComboBox ")),
983 groupSizer
->Add( new wxStaticText(dlg
, wxID_ANY
,
984 wxT("Writable, with margins, sorted:")), 0,
985 wxALIGN_CENTER_VERTICAL
|wxRIGHT
|wxEXPAND
, border
);
987 odc
= new wxOwnerDrawnComboBox(dlg
,wxID_ANY
,wxEmptyString
,
988 wxDefaultPosition
, wxDefaultSize
,
990 wxCB_SORT
// wxNO_BORDER|wxCB_READONLY
993 odc
->Append(wxT("H - Appended Item")); // test sorting in append
995 odc
->SetValue(wxT("Dot Dash"));
996 odc
->SetMargins(15, 10);
997 groupSizer
->Add( odc
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, border
);
998 groupSizer
->AddStretchSpacer();
1001 // Readonly ODComboBox
1002 groupSizer
->Add( new wxStaticText(dlg
, wxID_ANY
,
1003 wxT("Read-only, big font:")), 0,
1004 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, border
);
1006 odc
= new wxOwnerDrawnComboBox(dlg
,wxID_ANY
,wxEmptyString
,
1007 wxDefaultPosition
, wxDefaultSize
,
1009 wxCB_SORT
|wxCB_READONLY
// wxNO_BORDER|wxCB_READONLY
1012 odc
->SetFont(odc
->GetFont().Scale(1.5));
1013 odc
->SetValue(wxT("Dot Dash"));
1014 odc
->SetText(wxT("Dot Dash (Testing SetText)"));
1016 groupSizer
->Add( odc
, 0, wxALL
, border
);
1017 groupSizer
->AddStretchSpacer();
1020 // Disabled ODComboBox
1021 groupSizer
->Add( new wxStaticText(dlg
,wxID_ANY
,wxT("Disabled:")), 0,
1022 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, border
);
1024 odc
= new wxOwnerDrawnComboBox(dlg
,wxID_ANY
,wxEmptyString
,
1025 wxDefaultPosition
, wxDefaultSize
,
1027 wxCB_SORT
|wxCB_READONLY
// wxNO_BORDER|wxCB_READONLY
1030 odc
->SetValue(wxT("Dot Dash"));
1033 groupSizer
->Add( odc
, 3, wxALIGN_CENTER_VERTICAL
|wxEXPAND
|wxALL
, border
);
1035 rowSizer
->Add( groupSizer
, 1, wxEXPAND
|wxALL
, border
);
1038 groupSizer
= new wxStaticBoxSizer(new wxStaticBox(dlg
,wxID_ANY
,wxT(" wxComboBox ")),
1044 groupSizer
->Add( new wxStaticText(dlg
,wxID_ANY
,
1045 wxT("Writable, with margins, sorted:")), 0,
1046 wxALIGN_CENTER_VERTICAL
|wxRIGHT
|wxEXPAND
, border
);
1048 cb
= new wxComboBox(dlg
,wxID_ANY
,wxEmptyString
,
1049 wxDefaultPosition
, wxDefaultSize
,
1051 wxCB_SORT
// wxNO_BORDER|wxCB_READONLY
1054 cb
->Append(wxT("H - Appended Item")); // test sorting in append
1056 cb
->SetValue(wxT("Dot Dash"));
1057 cb
->SetMargins(15, 10);
1058 groupSizer
->Add( cb
, 0, wxALIGN_CENTER_VERTICAL
|wxALL
, border
);
1059 groupSizer
->AddStretchSpacer();
1062 // Readonly wxComboBox
1063 groupSizer
->Add( new wxStaticText(dlg
, wxID_ANY
,
1064 wxT("Read-only, big font:")), 0,
1065 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, border
);
1067 cb
= new wxComboBox(dlg
,wxID_ANY
,wxEmptyString
,
1068 wxDefaultPosition
, wxDefaultSize
,
1070 wxCB_SORT
|wxCB_READONLY
// wxNO_BORDER|wxCB_READONLY
1073 cb
->SetFont(cb
->GetFont().Scale(1.5));
1074 cb
->SetValue(wxT("Dot Dash"));
1076 groupSizer
->Add( cb
, 0, wxALL
, border
);
1077 groupSizer
->AddStretchSpacer();
1080 // Disabled wxComboBox
1081 groupSizer
->Add( new wxStaticText(dlg
,wxID_ANY
,wxT("Disabled:")), 0,
1082 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, border
);
1084 cb
= new wxComboBox(dlg
,wxID_ANY
,wxEmptyString
,
1085 wxDefaultPosition
, wxDefaultSize
,
1087 wxCB_SORT
|wxCB_READONLY
// wxNO_BORDER|wxCB_READONLY
1090 cb
->SetValue(wxT("Dot Dash"));
1093 groupSizer
->Add( cb
, 3, wxALIGN_CENTER_VERTICAL
|wxEXPAND
|wxALL
, border
);
1095 rowSizer
->Add( groupSizer
, 1, wxEXPAND
|wxALL
, border
);
1097 colSizer
->Add( rowSizer
, 1, wxEXPAND
|wxALL
, border
);
1099 dlg
->SetSizer( colSizer
);
1100 colSizer
->SetSizeHints( dlg
);
1102 dlg
->SetSize(60,240);
1109 delete wxLog::SetActiveTarget(m_logOld
);
1112 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1114 // true is to force the frame to close
1118 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1120 wxMessageBox(wxString::Format(
1121 wxT("Welcome to %s!\n")
1123 wxT("This is the wxWidgets wxComboCtrl and wxOwnerDrawnComboBox sample\n")
1124 wxT("running under %s."),
1126 wxGetOsDescription().c_str()
1128 wxT("About wxComboCtrl sample"),
1129 wxOK
| wxICON_INFORMATION
,
1133 void MyFrame::OnIdle(wxIdleEvent
& event
)
1135 // This code is useful for debugging focus problems
1136 // (which are plentiful when dealing with popup windows).
1138 static wxWindow
* lastFocus
= (wxWindow
*) NULL
;
1140 wxWindow
* curFocus
= ::wxWindow::FindFocus();
1142 if ( curFocus
!= lastFocus
)
1144 const wxChar
* className
= wxT("<none>");
1146 className
= curFocus
->GetClassInfo()->GetClassName();
1147 lastFocus
= curFocus
;
1148 wxLogDebug( wxT("FOCUSED: %s %X"),
1150 (unsigned int)curFocus
);