1 /////////////////////////////////////////////////////////////////////////////
3 // Purpose: wxComboCtrl sample
4 // Author: Jaakko Salli
6 // Created: Apr-30-2006
8 // Copyright: (c) Jaakko Salli
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 // ============================================================================
14 // ============================================================================
16 // ----------------------------------------------------------------------------
18 // ----------------------------------------------------------------------------
20 // For compilers that support precompilation, includes "wx/wx.h".
21 #include "wx/wxprec.h"
27 // for all others, include the necessary headers (this file is usually all you
28 // need because it includes almost all "standard" wxWidgets headers)
34 #error "Please set wxUSE_COMBOCTRL to 1 and rebuild the library."
40 #include "wx/odcombo.h"
42 // ----------------------------------------------------------------------------
44 // ----------------------------------------------------------------------------
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 #ifndef wxHAS_IMAGES_IN_RESOURCES
49 #include "../sample.xpm"
52 // ----------------------------------------------------------------------------
54 // ----------------------------------------------------------------------------
56 // Define a new application type, each program should derive a class from wxApp
57 class MyApp
: public wxApp
60 // override base class virtuals
61 // ----------------------------
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();
69 // Define a new frame type: this is going to be our main frame
70 class MyFrame
: public wxFrame
74 MyFrame(const wxString
& title
);
77 // event handlers (these functions should _not_ be virtual)
78 void OnQuit(wxCommandEvent
& event
);
79 void OnAbout(wxCommandEvent
& event
);
81 void OnShowComparison( wxCommandEvent
& event
);
83 // log wxComboCtrl events
84 void OnComboBoxUpdate( wxCommandEvent
& event
);
86 void OnIdle( wxIdleEvent
& event
);
93 // Common list of items for all dialogs.
94 wxArrayString m_arrItems
;
97 // any class wishing to process wxWidgets events must use this macro
101 // ----------------------------------------------------------------------------
103 // ----------------------------------------------------------------------------
105 // IDs for the controls and the menu commands
108 ComboCtrl_Compare
= wxID_HIGHEST
,
111 ComboCtrl_Quit
= wxID_EXIT
,
113 // it is important for the id corresponding to the "About" command to have
114 // this standard value as otherwise it won't be handled properly under Mac
115 // (where it is special and put into the "Apple" menu)
116 ComboCtrl_About
= wxID_ABOUT
119 // ----------------------------------------------------------------------------
120 // event tables and other macros for wxWidgets
121 // ----------------------------------------------------------------------------
123 // the event tables connect the wxWidgets events with the functions (event
124 // handlers) which process them. It can be also done at run-time, but for the
125 // simple menu events like this the static method is much simpler.
126 BEGIN_EVENT_TABLE(MyFrame
, wxFrame
)
127 EVT_TEXT(wxID_ANY
,MyFrame::OnComboBoxUpdate
)
128 EVT_TEXT_ENTER(wxID_ANY
,MyFrame::OnComboBoxUpdate
)
129 EVT_COMBOBOX(wxID_ANY
,MyFrame::OnComboBoxUpdate
)
131 EVT_MENU(ComboCtrl_Compare
, MyFrame::OnShowComparison
)
132 EVT_MENU(ComboCtrl_Quit
, MyFrame::OnQuit
)
133 EVT_MENU(ComboCtrl_About
, MyFrame::OnAbout
)
135 EVT_IDLE(MyFrame::OnIdle
)
138 // Create a new application object: this macro will allow wxWidgets to create
139 // the application object during program execution (it's better than using a
140 // static object for many reasons) and also implements the accessor function
141 // wxGetApp() which will return the reference of the right type (i.e. MyApp and
145 // ============================================================================
147 // ============================================================================
149 // ----------------------------------------------------------------------------
150 // the application class
151 // ----------------------------------------------------------------------------
153 // 'Main program' equivalent: the program execution "starts" here
156 if ( !wxApp::OnInit() )
159 // create the main application window
160 MyFrame
*frame
= new MyFrame(wxT("wxComboCtrl and wxOwnerDrawnComboBox Sample"));
162 // and show it (the frames, unlike simple controls, are not shown when
163 // created initially)
166 // success: wxApp::OnRun() will be called which will enter the main message
167 // loop and the application will run. If we returned false here, the
168 // application would exit immediately.
173 // ----------------------------------------------------------------------------
174 // wxOwnerDrawnComboBox with custom paint list items
175 // ----------------------------------------------------------------------------
177 class wxPenStyleComboBox
: public wxOwnerDrawnComboBox
180 virtual void OnDrawItem( wxDC
& dc
,
185 if ( item
== wxNOT_FOUND
)
192 int penStyle
= wxSOLID
;
194 penStyle
= wxTRANSPARENT
;
195 else if ( item
== 2 )
197 else if ( item
== 3 )
198 penStyle
= wxLONG_DASH
;
199 else if ( item
== 4 )
200 penStyle
= wxSHORT_DASH
;
201 else if ( item
== 5 )
202 penStyle
= wxDOT_DASH
;
203 else if ( item
== 6 )
204 penStyle
= wxBDIAGONAL_HATCH
;
205 else if ( item
== 7 )
206 penStyle
= wxCROSSDIAG_HATCH
;
207 else if ( item
== 8 )
208 penStyle
= wxFDIAGONAL_HATCH
;
209 else if ( item
== 9 )
210 penStyle
= wxCROSS_HATCH
;
211 else if ( item
== 10 )
212 penStyle
= wxHORIZONTAL_HATCH
;
213 else if ( item
== 11 )
214 penStyle
= wxVERTICAL_HATCH
;
216 wxPen
pen( dc
.GetTextForeground(), 3, penStyle
);
218 // Get text colour as pen colour
221 if ( !(flags
& wxODCB_PAINTING_CONTROL
) )
223 dc
.DrawText(GetString( item
),
225 (r
.y
+ 0) + ( (r
.height
/2) - dc
.GetCharHeight() )/2
228 dc
.DrawLine( r
.x
+5, r
.y
+((r
.height
/4)*3), r
.x
+r
.width
- 5, r
.y
+((r
.height
/4)*3) );
232 dc
.DrawLine( r
.x
+5, r
.y
+r
.height
/2, r
.x
+r
.width
- 5, r
.y
+r
.height
/2 );
236 virtual void OnDrawBackground( wxDC
& dc
, const wxRect
& rect
,
237 int item
, int flags
) const
240 // If item is selected or even, or we are painting the
241 // combo control itself, use the default rendering.
242 if ( (flags
& (wxODCB_PAINTING_CONTROL
|wxODCB_PAINTING_SELECTED
)) ||
245 wxOwnerDrawnComboBox::OnDrawBackground(dc
,rect
,item
,flags
);
249 // Otherwise, draw every other background with different colour.
250 wxColour
bgCol(240,240,250);
251 dc
.SetBrush(wxBrush(bgCol
));
252 dc
.SetPen(wxPen(bgCol
));
253 dc
.DrawRectangle(rect
);
256 virtual wxCoord
OnMeasureItem( size_t item
) const
258 // Simply demonstrate the ability to have variable-height items
265 virtual wxCoord
OnMeasureItemWidth( size_t WXUNUSED(item
) ) const
267 return -1; // default - will be measured from text width
273 // ----------------------------------------------------------------------------
274 // wxListView Custom popup interface
275 // ----------------------------------------------------------------------------
277 #include <wx/listctrl.h>
279 class ListViewComboPopup
: public wxListView
, public wxComboPopup
286 m_itemHere
= -1; // hot item in list
289 virtual bool Create( wxWindow
* parent
)
291 return wxListView::Create(parent
,1,
292 wxPoint(0,0),wxDefaultSize
,
293 wxLC_LIST
|wxLC_SINGLE_SEL
|
294 wxLC_SORT_ASCENDING
|wxSIMPLE_BORDER
);
297 virtual wxWindow
*GetControl() { return this; }
299 virtual void SetStringValue( const wxString
& s
)
301 int n
= wxListView::FindItem(-1,s
);
302 if ( n
>= 0 && n
< GetItemCount() )
303 wxListView::Select(n
);
306 virtual wxString
GetStringValue() const
309 return wxListView::GetItemText(m_value
);
310 return wxEmptyString
;
314 // Popup event handlers
317 // Mouse hot-tracking
318 void OnMouseMove(wxMouseEvent
& event
)
320 // Move selection to cursor if it is inside the popup
323 int itemHere
= HitTest(event
.GetPosition(),resFlags
);
326 wxListView::Select(itemHere
,true);
327 m_itemHere
= itemHere
;
332 // On mouse left, set the value and close the popup
333 void OnMouseClick(wxMouseEvent
& WXUNUSED(event
))
335 m_value
= m_itemHere
;
341 // Utilies for item manipulation
344 void AddSelection( const wxString
& selstr
)
346 wxListView::InsertItem(GetItemCount(),selstr
);
351 int m_value
; // current item index
352 int m_itemHere
; // hot item in popup
355 DECLARE_EVENT_TABLE()
358 BEGIN_EVENT_TABLE(ListViewComboPopup
, wxListView
)
359 EVT_MOTION(ListViewComboPopup::OnMouseMove
)
360 // NOTE: Left down event is used instead of left up right now
361 // since MSW wxListCtrl doesn't seem to emit left ups
363 EVT_LEFT_DOWN(ListViewComboPopup::OnMouseClick
)
367 // ----------------------------------------------------------------------------
368 // wxTreeCtrl Custom popup interface
369 // ----------------------------------------------------------------------------
371 #include <wx/treectrl.h>
373 class TreeCtrlComboPopup
: public wxTreeCtrl
, public wxComboPopup
380 virtual ~TreeCtrlComboPopup()
382 if (!m_isBeingDeleted
)
384 wxMessageBox("error wxTreeCtrl::Destroy() was not called");
389 virtual bool Create( wxWindow
* parent
)
391 return wxTreeCtrl::Create(parent
,1,
392 wxPoint(0,0),wxDefaultSize
,
393 wxTR_DEFAULT_STYLE
| wxTR_HIDE_ROOT
| wxSIMPLE_BORDER
);
396 virtual void OnShow()
398 // make sure selected item is visible
399 if ( m_value
.IsOk() )
400 EnsureVisible(m_value
);
403 virtual wxSize
GetAdjustedSize( int minWidth
,
404 int WXUNUSED(prefHeight
),
407 return wxSize(wxMax(300,minWidth
),wxMin(250,maxHeight
));
410 virtual wxWindow
*GetControl() { return this; }
412 // Needed by SetStringValue
413 wxTreeItemId
FindItemByText( wxTreeItemId parent
, const wxString
& text
)
415 wxTreeItemIdValue cookie
;
416 wxTreeItemId child
= GetFirstChild(parent
,cookie
);
417 while ( child
.IsOk() )
419 if ( GetItemText(child
) == text
)
423 if ( ItemHasChildren(child
) )
425 wxTreeItemId found
= FindItemByText(child
,text
);
429 child
= GetNextChild(parent
,cookie
);
431 return wxTreeItemId();
434 virtual void SetStringValue( const wxString
& s
)
436 wxTreeItemId root
= GetRootItem();
440 wxTreeItemId found
= FindItemByText(root
,s
);
443 m_value
= m_itemHere
= found
;
444 wxTreeCtrl::SelectItem(found
);
448 virtual wxString
GetStringValue() const
450 if ( m_value
.IsOk() )
451 return wxTreeCtrl::GetItemText(m_value
);
452 return wxEmptyString
;
456 // Popup event handlers
459 // Mouse hot-tracking
460 void OnMouseMove(wxMouseEvent
& event
)
463 wxTreeItemId itemHere
= HitTest(event
.GetPosition(),resFlags
);
464 if ( itemHere
.IsOk() && (resFlags
& wxTREE_HITTEST_ONITEMLABEL
) )
466 wxTreeCtrl::SelectItem(itemHere
,true);
467 m_itemHere
= itemHere
;
472 // On mouse left, set the value and close the popup
473 void OnMouseClick(wxMouseEvent
& event
)
476 wxTreeItemId itemHere
= HitTest(event
.GetPosition(),resFlags
);
477 if ( itemHere
.IsOk() && (resFlags
& wxTREE_HITTEST_ONITEMLABEL
) )
479 m_itemHere
= itemHere
;
489 wxTreeItemId m_value
; // current item index
490 wxTreeItemId m_itemHere
; // hot item in popup
493 DECLARE_EVENT_TABLE()
496 BEGIN_EVENT_TABLE(TreeCtrlComboPopup
, wxTreeCtrl
)
497 EVT_MOTION(TreeCtrlComboPopup::OnMouseMove
)
498 // NOTE: Left down event is used instead of left up right now
499 // since MSW wxTreeCtrl doesn't seem to emit left ups
501 EVT_LEFT_DOWN(TreeCtrlComboPopup::OnMouseClick
)
504 // ----------------------------------------------------------------------------
505 // wxComboCtrl with custom popup animation, using wxWindow::ShowWithEffect().
506 // ----------------------------------------------------------------------------
508 class wxComboCtrlWithCustomPopupAnim
: public wxComboCtrl
511 virtual bool AnimateShow( const wxRect
& rect
, int WXUNUSED(flags
) )
513 wxWindow
* win
= GetPopupWindow();
515 win
->Raise(); // This is needed
516 win
->ShowWithEffect(wxSHOW_EFFECT_BLEND
);
521 // ----------------------------------------------------------------------------
522 // wxComboCtrl with entirely custom button action (opens file dialog)
523 // ----------------------------------------------------------------------------
525 class wxFileSelectorCombo
: public wxComboCtrl
528 wxFileSelectorCombo() : wxComboCtrl() { Init(); }
530 wxFileSelectorCombo(wxWindow
*parent
,
531 wxWindowID id
= wxID_ANY
,
532 const wxString
& value
= wxEmptyString
,
533 const wxPoint
& pos
= wxDefaultPosition
,
534 const wxSize
& size
= wxDefaultSize
,
536 const wxValidator
& validator
= wxDefaultValidator
,
537 const wxString
& name
= wxComboBoxNameStr
)
541 Create(parent
,id
,value
,
543 // Style flag wxCC_STD_BUTTON makes the button
544 // behave more like a standard push button.
545 style
| wxCC_STD_BUTTON
,
549 // Prepare custom button bitmap (just '...' text)
552 dc
.SelectObject(bmp
);
554 // Draw transparent background
555 wxColour
magic(255,0,255);
556 wxBrush
magicBrush(magic
);
557 dc
.SetBrush( magicBrush
);
558 dc
.SetPen( *wxTRANSPARENT_PEN
);
559 dc
.DrawRectangle(0,0,bmp
.GetWidth(),bmp
.GetHeight());
562 wxString str
= wxT("...");
564 dc
.GetTextExtent(str
, &w
, &h
, 0, 0);
565 dc
.DrawText(str
, (bmp
.GetWidth()-w
)/2, (bmp
.GetHeight()-h
)/2);
567 dc
.SelectObject( wxNullBitmap
);
569 // Finalize transparency with a mask
570 wxMask
*mask
= new wxMask( bmp
, magic
);
573 SetButtonBitmaps(bmp
,true);
576 virtual void OnButtonClick()
578 // Show standard wxFileDialog on button click
580 wxFileDialog
dlg(this,
584 wxT("All files (*.*)|*.*"),
587 if ( dlg
.ShowModal() == wxID_OK
)
589 SetValue(dlg
.GetPath());
593 // Implement empty DoSetPopupControl to prevent assertion failure.
594 virtual void DoSetPopupControl(wxComboPopup
* WXUNUSED(popup
))
601 // Initialize member variables here
605 // ----------------------------------------------------------------------------
607 // ----------------------------------------------------------------------------
610 MyFrame::MyFrame(const wxString
& title
)
611 : wxFrame(NULL
, wxID_ANY
, title
)
613 wxBoxSizer
* topSizer
;
614 wxBoxSizer
* topRowSizer
;
615 wxBoxSizer
* colSizer
;
616 wxBoxSizer
* rowSizer
;
618 // set the frame icon
619 SetIcon(wxICON(sample
));
623 wxMenu
*fileMenu
= new wxMenu
;
625 // the "About" item should be in the help menu
626 wxMenu
*helpMenu
= new wxMenu
;
627 helpMenu
->Append(ComboCtrl_About
, wxT("&About\tF1"), wxT("Show about dialog"));
629 fileMenu
->Append(ComboCtrl_Compare
, wxT("&Compare against wxComboBox..."),
630 wxT("Show some wxOwnerDrawnComboBoxes side-by-side with native wxComboBoxes."));
631 fileMenu
->AppendSeparator();
632 fileMenu
->Append(ComboCtrl_Quit
, wxT("E&xit\tAlt-X"), wxT("Quit this program"));
634 // now append the freshly created menu to the menu bar...
635 wxMenuBar
*menuBar
= new wxMenuBar();
636 menuBar
->Append(fileMenu
, wxT("&File"));
637 menuBar
->Append(helpMenu
, wxT("&Help"));
639 // ... and attach this menu bar to the frame
641 #endif // wxUSE_MENUS
643 wxPanel
* panel
= new wxPanel(this);
645 // Prepare log window right away since it shows EVT_TEXTs
646 m_logWin
= new wxTextCtrl(panel
, 105, wxEmptyString
,
650 wxLogTextCtrl
* logger
= new wxLogTextCtrl(m_logWin
);
651 m_logOld
= logger
->SetActiveTarget(logger
);
652 logger
->DisableTimestamp();
655 topSizer
= new wxBoxSizer( wxVERTICAL
);
657 topRowSizer
= new wxBoxSizer( wxHORIZONTAL
);
659 colSizer
= new wxBoxSizer( wxVERTICAL
);
663 wxGenericComboCtrl
* gcc
;
664 wxOwnerDrawnComboBox
* odc
;
666 // Create common strings array
667 m_arrItems
.Add( wxT("Solid") );
668 m_arrItems
.Add( wxT("Transparent") );
669 m_arrItems
.Add( wxT("Dot") );
670 m_arrItems
.Add( wxT("Long Dash") );
671 m_arrItems
.Add( wxT("Short Dash") );
672 m_arrItems
.Add( wxT("Dot Dash") );
673 m_arrItems
.Add( wxT("Backward Diagonal Hatch") );
674 m_arrItems
.Add( wxT("Cross-diagonal Hatch") );
675 m_arrItems
.Add( wxT("Forward Diagonal Hatch") );
676 m_arrItems
.Add( wxT("Cross Hatch") );
677 m_arrItems
.Add( wxT("Horizontal Hatch") );
678 m_arrItems
.Add( wxT("Vertical Hatch") );
682 // Create pen selector ODComboBox with owner-drawn items
684 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
685 rowSizer
->Add( new wxStaticText(panel
,wxID_ANY
,
686 wxT("OwnerDrawnComboBox with owner-drawn items:")), 1,
687 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
688 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
690 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
693 // When defining derivative class for callbacks, we need
694 // to use two-stage creation (or redefine the common wx
696 odc
= new wxPenStyleComboBox();
697 odc
->Create(panel
,wxID_ANY
,wxEmptyString
,
698 wxDefaultPosition
, wxDefaultSize
,
700 wxCB_READONLY
//wxNO_BORDER | wxCB_READONLY
704 odc
->SetSelection(0);
706 rowSizer
->Add( odc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 4 );
707 rowSizer
->AddStretchSpacer(1);
708 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
713 // Same but with changed button position
715 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
716 rowSizer
->Add( new wxStaticText(panel
,wxID_ANY
,
717 wxT("OwnerDrawnComboBox with owner-drawn items and button on the left:")), 1,
718 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
719 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
721 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
724 // When defining derivative class for callbacks, we need
725 // to use two-stage creation (or redefine the common wx
727 odc
= new wxPenStyleComboBox();
728 odc
->Create(panel
,wxID_ANY
,wxEmptyString
,
729 wxDefaultPosition
, wxDefaultSize
,
731 wxCB_READONLY
//wxNO_BORDER | wxCB_READONLY
735 odc
->SetSelection(0);
737 // Use button size that is slightly smaller than the default.
738 wxSize butSize
= odc
->GetButtonSize();
739 odc
->SetButtonPosition(butSize
.x
- 2, // button width
740 butSize
.y
- 6, // button height
742 2 // horizontal spacing
745 rowSizer
->Add( odc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 4 );
746 rowSizer
->AddStretchSpacer(1);
747 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
751 // List View wxComboCtrl
754 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
755 rowSizer
->Add( new wxStaticText(panel
,
757 "List View wxComboCtrl (custom animation):"),
758 1, wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
759 rowSizer
->Add( new wxStaticText(panel
,wxID_ANY
,wxT("Tree Ctrl wxComboCtrl:")), 1,
760 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
761 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
763 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
764 cc
= new wxComboCtrlWithCustomPopupAnim();
766 // Let's set a custom style for the contained wxTextCtrl. We need to
767 // use two-step creation for it to work properly.
768 cc
->SetTextCtrlStyle(wxTE_RIGHT
);
770 cc
->Create(panel
, wxID_ANY
, wxEmptyString
);
772 // Make sure we use popup that allows focusing the listview.
773 cc
->UseAltPopupWindow();
775 cc
->SetPopupMinWidth(300);
777 ListViewComboPopup
* iface
= new ListViewComboPopup();
778 cc
->SetPopupControl(iface
);
781 for ( i
=0; i
<100; i
++ )
782 iface
->AddSelection( wxString::Format(wxT("Item %02i"),i
));
784 rowSizer
->Add( cc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5 );
788 // Tree Ctrl wxComboCtrl
791 // Note that we test that wxGenericComboCtrl works
792 gcc
= new wxGenericComboCtrl(panel
,wxID_ANY
,wxEmptyString
,
793 wxDefaultPosition
, wxDefaultSize
);
795 // Make sure we use popup that allows focusing the treectrl.
796 gcc
->UseAltPopupWindow();
798 // Set popup interface right away, otherwise some of the calls
800 TreeCtrlComboPopup
* tcPopup
= new TreeCtrlComboPopup();
801 gcc
->SetPopupControl(tcPopup
);
803 // Add items using wxTreeCtrl methods directly
804 wxTreeItemId rootId
= tcPopup
->AddRoot(wxT("<hidden_root>"));
806 wxTreeItemId groupId
;
808 for ( i
=0; i
<4; i
++ )
810 groupId
= tcPopup
->AppendItem(rootId
,
811 wxString::Format(wxT("Branch %02i"),i
));
814 for ( n
=0; n
<25; n
++ )
815 tcPopup
->AppendItem(groupId
,
816 wxString::Format(wxT("Subitem %02i"),(i
*25)+n
));
819 gcc
->SetValue(wxT("Subitem 05"));
821 // Move button to left - it makes more sense for a tree ctrl
822 gcc
->SetButtonPosition(-1, // button width
825 0 // horizontal spacing
828 rowSizer
->Add( gcc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 5 );
830 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
833 wxInitAllImageHandlers();
836 // Custom Dropbutton Bitmaps
837 // (second one uses blank button background)
839 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
840 rowSizer
->Add( new wxStaticText(panel
,wxID_ANY
,
841 wxT("OwnerDrawnComboBox with simple dropbutton graphics:")), 1,
842 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
844 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
846 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
848 odc
= new wxOwnerDrawnComboBox(panel
,wxID_ANY
,wxEmptyString
,
849 wxDefaultPosition
, wxDefaultSize
,
851 (long)0 // wxCB_SORT // wxNO_BORDER | wxCB_READONLY
854 wxOwnerDrawnComboBox
* odc2
;
855 odc2
= new wxOwnerDrawnComboBox(panel
,wxID_ANY
,wxEmptyString
,
856 wxDefaultPosition
, wxDefaultSize
,
858 (long)0 // wxCB_SORT // wxNO_BORDER | wxCB_READONLY
861 // Load images from disk
862 wxImage
imgNormal(wxT("dropbutn.png"));
863 wxImage
imgPressed(wxT("dropbutp.png"));
864 wxImage
imgHover(wxT("dropbuth.png"));
866 if ( imgNormal
.IsOk() && imgPressed
.IsOk() && imgHover
.IsOk() )
868 wxBitmap
bmpNormal(imgNormal
);
869 wxBitmap
bmpPressed(imgPressed
);
870 wxBitmap
bmpHover(imgHover
);
871 odc
->SetButtonBitmaps(bmpNormal
,false,bmpPressed
,bmpHover
);
872 odc2
->SetButtonBitmaps(bmpNormal
,true,bmpPressed
,bmpHover
);
875 wxLogError(wxT("Dropbutton images not found"));
877 //odc2->SetButtonPosition(0, // width adjustment
878 // 0, // height adjustment
880 // 0 // horizontal spacing
883 rowSizer
->Add( odc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 4 );
884 rowSizer
->Add( odc2
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 4 );
885 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
890 // wxComboCtrl with totally custom button action (open file dialog)
892 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
893 rowSizer
->Add( new wxStaticText(panel
,wxID_ANY
,
894 wxT("wxComboCtrl with custom button action:")), 1,
895 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, 4 );
898 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
900 rowSizer
= new wxBoxSizer( wxHORIZONTAL
);
901 wxFileSelectorCombo
* fsc
;
903 fsc
= new wxFileSelectorCombo(panel
,wxID_ANY
,wxEmptyString
,
904 wxDefaultPosition
, wxDefaultSize
,
908 rowSizer
->Add( fsc
, 1, wxALIGN_CENTER_VERTICAL
|wxALL
, 4 );
909 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, 5 );
912 // Make sure GetFeatures is implemented
913 wxComboCtrl::GetFeatures();
916 topRowSizer
->Add( colSizer
, 1, wxALL
, 2 );
918 colSizer
= new wxBoxSizer( wxVERTICAL
);
920 colSizer
->AddSpacer(8);
921 colSizer
->Add( new wxStaticText(panel
, wxID_ANY
, wxT("Log Messages:")), 0, wxTOP
|wxLEFT
, 3 );
922 colSizer
->Add( m_logWin
, 1, wxEXPAND
|wxALL
, 3 );
924 topRowSizer
->Add( colSizer
, 1, wxEXPAND
|wxALL
, 2 );
925 topSizer
->Add( topRowSizer
, 1, wxEXPAND
);
927 panel
->SetSizer( topSizer
);
928 topSizer
->SetSizeHints( panel
);
936 void MyFrame::OnComboBoxUpdate( wxCommandEvent
& event
)
938 // Don't show messages for the log output window (it'll crash)
939 if ( !event
.GetEventObject()->IsKindOf(CLASSINFO(wxComboCtrl
)) )
942 if ( event
.GetEventType() == wxEVT_COMMAND_COMBOBOX_SELECTED
)
944 wxLogDebug(wxT("EVT_COMBOBOX(id=%i,selection=%i)"),event
.GetId(),event
.GetSelection());
946 else if ( event
.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED
)
948 wxLogDebug(wxT("EVT_TEXT(id=%i,string=\"%s\")"),event
.GetId(),event
.GetString().c_str());
950 else if ( event
.GetEventType() == wxEVT_COMMAND_TEXT_ENTER
)
952 wxLogDebug("EVT_TEXT_ENTER(id=%i,string=\"%s\")",
953 event
.GetId(), event
.GetString().c_str());
957 void MyFrame::OnShowComparison( wxCommandEvent
& WXUNUSED(event
) )
960 // Show some wxOwnerDrawComboBoxes for comparison
963 wxBoxSizer
* colSizer
;
964 wxBoxSizer
* rowSizer
;
965 wxStaticBoxSizer
* groupSizer
;
968 wxOwnerDrawnComboBox
* odc
;
970 const int border
= 4;
972 wxDialog
* dlg
= new wxDialog(this,wxID_ANY
,
973 wxT("Compare against wxComboBox"),
974 wxDefaultPosition
,wxDefaultSize
,
975 wxDEFAULT_DIALOG_STYLE
|wxRESIZE_BORDER
);
977 colSizer
= new wxBoxSizer( wxVERTICAL
);
979 rowSizer
= new wxBoxSizer(wxHORIZONTAL
);
981 groupSizer
= new wxStaticBoxSizer(new wxStaticBox(dlg
,wxID_ANY
,wxT(" wxOwnerDrawnComboBox ")),
984 groupSizer
->Add( new wxStaticText(dlg
,wxID_ANY
,wxT("Writable, 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"));
997 groupSizer
->Add( odc
, 1, wxALIGN_CENTER_VERTICAL
|wxEXPAND
|wxALL
, border
);
1000 // Readonly ODComboBox
1001 groupSizer
->Add( new wxStaticText(dlg
,wxID_ANY
,wxT("Read-only:")), 0,
1002 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, border
);
1004 odc
= new wxOwnerDrawnComboBox(dlg
,wxID_ANY
,wxEmptyString
,
1005 wxDefaultPosition
, wxDefaultSize
,
1007 wxCB_SORT
|wxCB_READONLY
// wxNO_BORDER|wxCB_READONLY
1010 odc
->SetValue(wxT("Dot Dash"));
1011 odc
->SetText(wxT("Dot Dash (Testing SetText)"));
1013 groupSizer
->Add( odc
, 1, wxALIGN_CENTER_VERTICAL
|wxEXPAND
|wxALL
, border
);
1016 // Disabled ODComboBox
1017 groupSizer
->Add( new wxStaticText(dlg
,wxID_ANY
,wxT("Disabled:")), 0,
1018 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, border
);
1020 odc
= new wxOwnerDrawnComboBox(dlg
,wxID_ANY
,wxEmptyString
,
1021 wxDefaultPosition
, wxDefaultSize
,
1023 wxCB_SORT
|wxCB_READONLY
// wxNO_BORDER|wxCB_READONLY
1026 odc
->SetValue(wxT("Dot Dash"));
1029 groupSizer
->Add( odc
, 1, wxALIGN_CENTER_VERTICAL
|wxEXPAND
|wxALL
, border
);
1031 rowSizer
->Add( groupSizer
, 1, wxEXPAND
|wxALL
, border
);
1034 groupSizer
= new wxStaticBoxSizer(new wxStaticBox(dlg
,wxID_ANY
,wxT(" wxComboBox ")),
1040 groupSizer
->Add( new wxStaticText(dlg
,wxID_ANY
,wxT("Writable, sorted:")), 0,
1041 wxALIGN_CENTER_VERTICAL
|wxRIGHT
|wxEXPAND
, border
);
1043 cb
= new wxComboBox(dlg
,wxID_ANY
,wxEmptyString
,
1044 wxDefaultPosition
, wxDefaultSize
,
1046 wxCB_SORT
// wxNO_BORDER|wxCB_READONLY
1049 cb
->Append(wxT("H - Appended Item")); // test sorting in append
1051 cb
->SetValue(wxT("Dot Dash"));
1053 groupSizer
->Add( cb
, 1, wxALIGN_CENTER_VERTICAL
|wxEXPAND
|wxALL
, border
);
1056 // Readonly wxComboBox
1057 groupSizer
->Add( new wxStaticText(dlg
,wxID_ANY
,wxT("Read-only:")), 0,
1058 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, border
);
1060 cb
= new wxComboBox(dlg
,wxID_ANY
,wxEmptyString
,
1061 wxDefaultPosition
, wxDefaultSize
,
1063 wxCB_SORT
|wxCB_READONLY
// wxNO_BORDER|wxCB_READONLY
1066 cb
->SetValue(wxT("Dot Dash"));
1068 groupSizer
->Add( cb
, 1, wxALIGN_CENTER_VERTICAL
|wxEXPAND
|wxALL
, border
);
1071 // Disabled wxComboBox
1072 groupSizer
->Add( new wxStaticText(dlg
,wxID_ANY
,wxT("Disabled:")), 0,
1073 wxALIGN_CENTER_VERTICAL
|wxRIGHT
, border
);
1075 cb
= new wxComboBox(dlg
,wxID_ANY
,wxEmptyString
,
1076 wxDefaultPosition
, wxDefaultSize
,
1078 wxCB_SORT
|wxCB_READONLY
// wxNO_BORDER|wxCB_READONLY
1081 cb
->SetValue(wxT("Dot Dash"));
1084 groupSizer
->Add( cb
, 1, wxALIGN_CENTER_VERTICAL
|wxEXPAND
|wxALL
, border
);
1086 rowSizer
->Add( groupSizer
, 1, wxEXPAND
|wxALL
, border
);
1088 colSizer
->Add( rowSizer
, 0, wxEXPAND
|wxALL
, border
);
1090 dlg
->SetSizer( colSizer
);
1091 colSizer
->SetSizeHints( dlg
);
1093 dlg
->SetSize(60,240);
1100 delete wxLog::SetActiveTarget(m_logOld
);
1103 void MyFrame::OnQuit(wxCommandEvent
& WXUNUSED(event
))
1105 // true is to force the frame to close
1109 void MyFrame::OnAbout(wxCommandEvent
& WXUNUSED(event
))
1111 wxMessageBox(wxString::Format(
1112 wxT("Welcome to %s!\n")
1114 wxT("This is the wxWidgets wxComboCtrl and wxOwnerDrawnComboBox sample\n")
1115 wxT("running under %s."),
1117 wxGetOsDescription().c_str()
1119 wxT("About wxComboCtrl sample"),
1120 wxOK
| wxICON_INFORMATION
,
1124 void MyFrame::OnIdle(wxIdleEvent
& event
)
1126 // This code is useful for debugging focus problems
1127 // (which are plentiful when dealing with popup windows).
1129 static wxWindow
* lastFocus
= (wxWindow
*) NULL
;
1131 wxWindow
* curFocus
= ::wxWindow::FindFocus();
1133 if ( curFocus
!= lastFocus
)
1135 const wxChar
* className
= wxT("<none>");
1137 className
= curFocus
->GetClassInfo()->GetClassName();
1138 lastFocus
= curFocus
;
1139 wxLogDebug( wxT("FOCUSED: %s %X"),
1141 (unsigned int)curFocus
);