X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/6d0ce565ff6a0db2e7c6e3240ef4cf6fe7950a35..c29c95fe24973b94fd724db767193171ca7c513d:/samples/combo/combo.cpp diff --git a/samples/combo/combo.cpp b/samples/combo/combo.cpp index 89b115bdaf..e31bcee2e0 100644 --- a/samples/combo/combo.cpp +++ b/samples/combo/combo.cpp @@ -1,6 +1,6 @@ ///////////////////////////////////////////////////////////////////////////// // Name: combo.cpp -// Purpose: wxComboControl sample +// Purpose: wxComboCtrl sample // Author: Jaakko Salli // Modified by: // Created: Apr-30-2006 @@ -30,8 +30,8 @@ #include "wx/wx.h" #endif -#if !wxUSE_COMBOCONTROL - #error "Please set wxUSE_COMBOCONTROL to 1 and rebuild the library." +#if !wxUSE_COMBOCTRL + #error "Please set wxUSE_COMBOCTRL to 1 and rebuild the library." #endif #include "wx/image.h" @@ -78,13 +78,21 @@ public: void OnQuit(wxCommandEvent& event); void OnAbout(wxCommandEvent& event); - // log wxComboControl events + void OnShowComparison( wxCommandEvent& event ); + + // log wxComboCtrl events void OnComboBoxUpdate( wxCommandEvent& event ); + void OnIdle( wxIdleEvent& event ); + + protected: wxTextCtrl* m_logWin; wxLog* m_logOld; + // Common list of items for all dialogs. + wxArrayString m_arrItems; + private: // any class wishing to process wxWidgets events must use this macro DECLARE_EVENT_TABLE() @@ -97,13 +105,15 @@ private: // IDs for the controls and the menu commands enum { + ComboCtrl_Compare = wxID_HIGHEST, + // menu items - ComboControl_Quit = wxID_EXIT, + ComboCtrl_Quit = wxID_EXIT, // it is important for the id corresponding to the "About" command to have // this standard value as otherwise it won't be handled properly under Mac // (where it is special and put into the "Apple" menu) - ComboControl_About = wxID_ABOUT + ComboCtrl_About = wxID_ABOUT }; // ---------------------------------------------------------------------------- @@ -115,10 +125,14 @@ enum // simple menu events like this the static method is much simpler. BEGIN_EVENT_TABLE(MyFrame, wxFrame) EVT_TEXT(wxID_ANY,MyFrame::OnComboBoxUpdate) + EVT_TEXT_ENTER(wxID_ANY,MyFrame::OnComboBoxUpdate) EVT_COMBOBOX(wxID_ANY,MyFrame::OnComboBoxUpdate) - EVT_MENU(ComboControl_Quit, MyFrame::OnQuit) - EVT_MENU(ComboControl_About, MyFrame::OnAbout) + EVT_MENU(ComboCtrl_Compare, MyFrame::OnShowComparison) + EVT_MENU(ComboCtrl_Quit, MyFrame::OnQuit) + EVT_MENU(ComboCtrl_About, MyFrame::OnAbout) + + EVT_IDLE(MyFrame::OnIdle) END_EVENT_TABLE() // Create a new application object: this macro will allow wxWidgets to create @@ -139,8 +153,11 @@ IMPLEMENT_APP(MyApp) // 'Main program' equivalent: the program execution "starts" here bool MyApp::OnInit() { + if ( !wxApp::OnInit() ) + return false; + // create the main application window - MyFrame *frame = new MyFrame(_T("wxComboControl Sample")); + MyFrame *frame = new MyFrame(wxT("wxComboCtrl and wxOwnerDrawnComboBox Sample")); // and show it (the frames, unlike simple controls, are not shown when // created initially) @@ -153,6 +170,106 @@ bool MyApp::OnInit() } +// ---------------------------------------------------------------------------- +// wxOwnerDrawnComboBox with custom paint list items +// ---------------------------------------------------------------------------- + +class wxPenStyleComboBox : public wxOwnerDrawnComboBox +{ +public: + virtual void OnDrawItem( wxDC& dc, + const wxRect& rect, + int item, + int flags ) const + { + if ( item == wxNOT_FOUND ) + return; + + wxRect r(rect); + r.Deflate(3); + r.height -= 2; + + int penStyle = wxSOLID; + if ( item == 1 ) + penStyle = wxTRANSPARENT; + else if ( item == 2 ) + penStyle = wxDOT; + else if ( item == 3 ) + penStyle = wxLONG_DASH; + else if ( item == 4 ) + penStyle = wxSHORT_DASH; + else if ( item == 5 ) + penStyle = wxDOT_DASH; + else if ( item == 6 ) + penStyle = wxBDIAGONAL_HATCH; + else if ( item == 7 ) + penStyle = wxCROSSDIAG_HATCH; + else if ( item == 8 ) + penStyle = wxFDIAGONAL_HATCH; + else if ( item == 9 ) + penStyle = wxCROSS_HATCH; + else if ( item == 10 ) + penStyle = wxHORIZONTAL_HATCH; + else if ( item == 11 ) + penStyle = wxVERTICAL_HATCH; + + wxPen pen( dc.GetTextForeground(), 3, penStyle ); + + // Get text colour as pen colour + dc.SetPen( pen ); + + if ( !(flags & wxODCB_PAINTING_CONTROL) ) + { + dc.DrawText(GetString( item ), + r.x + 3, + (r.y + 0) + ( (r.height/2) - dc.GetCharHeight() )/2 + ); + + dc.DrawLine( r.x+5, r.y+((r.height/4)*3), r.x+r.width - 5, r.y+((r.height/4)*3) ); + } + else + { + dc.DrawLine( r.x+5, r.y+r.height/2, r.x+r.width - 5, r.y+r.height/2 ); + } + } + + virtual void OnDrawBackground( wxDC& dc, const wxRect& rect, + int item, int flags ) const + { + + // If item is selected or even, or we are painting the + // combo control itself, use the default rendering. + if ( (flags & (wxODCB_PAINTING_CONTROL|wxODCB_PAINTING_SELECTED)) || + (item & 1) == 0 ) + { + wxOwnerDrawnComboBox::OnDrawBackground(dc,rect,item,flags); + return; + } + + // Otherwise, draw every other background with different colour. + wxColour bgCol(240,240,250); + dc.SetBrush(wxBrush(bgCol)); + dc.SetPen(wxPen(bgCol)); + dc.DrawRectangle(rect); + } + + virtual wxCoord OnMeasureItem( size_t item ) const + { + // Simply demonstrate the ability to have variable-height items + if ( item & 1 ) + return 36; + else + return 24; + } + + virtual wxCoord OnMeasureItemWidth( size_t WXUNUSED(item) ) const + { + return -1; // default - will be measured from text width + } + +}; + + // ---------------------------------------------------------------------------- // wxListView Custom popup interface // ---------------------------------------------------------------------------- @@ -163,14 +280,6 @@ class ListViewComboPopup : public wxListView, public wxComboPopup { public: -/* - ListViewComboPopup(wxComboControlBase* combo) - : wxListView(), wxComboPopup(combo) - { - m_value = -1; - m_itemHere = -1; // hot item in list - } -*/ virtual void Init() { m_value = -1; @@ -265,24 +374,23 @@ class TreeCtrlComboPopup : public wxTreeCtrl, public wxComboPopup { public: -/* - TreeCtrlComboPopup(wxComboControlBase* combo) - : wxTreeCtrl(), wxComboPopup(combo) + virtual void Init() { } -*/ - - virtual void Init() + virtual ~TreeCtrlComboPopup() { + if (!m_isBeingDeleted) + { + wxMessageBox("error wxTreeCtrl::Destroy() was not called"); + } + SendDestroyEvent(); } virtual bool Create( wxWindow* parent ) { return wxTreeCtrl::Create(parent,1, wxPoint(0,0),wxDefaultSize, - wxTR_HIDE_ROOT|wxTR_HAS_BUTTONS| - wxTR_SINGLE|wxTR_LINES_AT_ROOT| - wxSIMPLE_BORDER); + wxTR_DEFAULT_STYLE | wxTR_HIDE_ROOT | wxSIMPLE_BORDER ); } virtual void OnShow() @@ -394,153 +502,30 @@ BEGIN_EVENT_TABLE(TreeCtrlComboPopup, wxTreeCtrl) END_EVENT_TABLE() // ---------------------------------------------------------------------------- -// wxOwnerDrawnComboBox with custom paint list items +// wxComboCtrl with custom popup animation, using wxWindow::ShowWithEffect(). // ---------------------------------------------------------------------------- -/* -class wxPenStyleComboBox : public wxOwnerDrawnComboBox -{ -public: - virtual bool OnDrawListItem( wxDC& dc, const wxRect& rect, int item, int flags ) - { - wxRect r(rect); - r.Deflate(3); - r.height -= 2; - - int pen_style = wxSOLID; - if ( item == 1 ) - pen_style = wxTRANSPARENT; - else if ( item == 2 ) - pen_style = wxDOT; - else if ( item == 3 ) - pen_style = wxLONG_DASH; - else if ( item == 4 ) - pen_style = wxSHORT_DASH; - else if ( item == 5 ) - pen_style = wxDOT_DASH; - else if ( item == 6 ) - pen_style = wxBDIAGONAL_HATCH; - else if ( item == 7 ) - pen_style = wxCROSSDIAG_HATCH; - else if ( item == 8 ) - pen_style = wxFDIAGONAL_HATCH; - else if ( item == 9 ) - pen_style = wxCROSS_HATCH; - else if ( item == 10 ) - pen_style = wxHORIZONTAL_HATCH; - else if ( item == 11 ) - pen_style = wxVERTICAL_HATCH; - - wxPen pen( dc.GetTextForeground(), 3, pen_style ); - - // Get text colour as pen colour - dc.SetPen ( pen ); - - if ( !(flags & wxCP_PAINTING_CONTROL) ) - { - dc.DrawText(GetString( item ), - r.x + 3, - (r.y + 0) + ( (r.height/2) - dc.GetCharHeight() )/2 - ); - - dc.DrawLine( r.x+5, r.y+((r.height/4)*3), r.x+r.width - 5, r.y+((r.height/4)*3) ); - } - else - { - dc.DrawLine( r.x+5, r.y+r.height/2, r.x+r.width - 5, r.y+r.height/2 ); - } - - return true; - } - - virtual wxCoord OnMeasureListItem( int WXUNUSED(item) ) - { - return 24; - } - virtual wxCoord OnMeasureListItemWidth( int WXUNUSED(item) ) - { - return -1; // default - will be measured from text width - } - -}; -*/ - -class wxPenStylePopup : public wxVListBoxComboPopup +class wxComboCtrlWithCustomPopupAnim : public wxComboCtrl { -public: - virtual void OnDrawItem( wxDC& dc, const wxRect& rect, int item, int flags ) const - { - if ( item == wxNOT_FOUND ) - return; - - wxRect r(rect); - r.Deflate(3); - r.height -= 2; - - int pen_style = wxSOLID; - if ( item == 1 ) - pen_style = wxTRANSPARENT; - else if ( item == 2 ) - pen_style = wxDOT; - else if ( item == 3 ) - pen_style = wxLONG_DASH; - else if ( item == 4 ) - pen_style = wxSHORT_DASH; - else if ( item == 5 ) - pen_style = wxDOT_DASH; - else if ( item == 6 ) - pen_style = wxBDIAGONAL_HATCH; - else if ( item == 7 ) - pen_style = wxCROSSDIAG_HATCH; - else if ( item == 8 ) - pen_style = wxFDIAGONAL_HATCH; - else if ( item == 9 ) - pen_style = wxCROSS_HATCH; - else if ( item == 10 ) - pen_style = wxHORIZONTAL_HATCH; - else if ( item == 11 ) - pen_style = wxVERTICAL_HATCH; - - wxPen pen( dc.GetTextForeground(), 3, pen_style ); - - // Get text colour as pen colour - dc.SetPen ( pen ); - - if ( !(flags & wxCP_PAINTING_CONTROL) ) - { - dc.DrawText(GetString( item ), - r.x + 3, - (r.y + 0) + ( (r.height/2) - dc.GetCharHeight() )/2 - ); - - dc.DrawLine( r.x+5, r.y+((r.height/4)*3), r.x+r.width - 5, r.y+((r.height/4)*3) ); - } - else - { - dc.DrawLine( r.x+5, r.y+r.height/2, r.x+r.width - 5, r.y+r.height/2 ); - } - } - - virtual wxCoord OnMeasureItem( size_t WXUNUSED(item) ) const - { - return 24; - } - - virtual wxCoord OnMeasureItemWidth( size_t WXUNUSED(item) ) const +protected: + virtual bool AnimateShow( const wxRect& rect, int WXUNUSED(flags) ) { - return -1; // default - will be measured from text width + wxWindow* win = GetPopupWindow(); + win->SetSize(rect); + win->Raise(); // This is needed + win->ShowWithEffect(wxSHOW_EFFECT_BLEND); + return true; } - }; // ---------------------------------------------------------------------------- -// wxComboControl with entirely custom button action (opens file dialog) +// wxComboCtrl with entirely custom button action (opens file dialog) // ---------------------------------------------------------------------------- -class wxFileSelectorCombo : public wxComboControl +class wxFileSelectorCombo : public wxComboCtrl { public: - wxFileSelectorCombo() : wxComboControl() { Init(); } + wxFileSelectorCombo() : wxComboCtrl() { Init(); } wxFileSelectorCombo(wxWindow *parent, wxWindowID id = wxID_ANY, @@ -550,7 +535,7 @@ public: long style = 0, const wxValidator& validator = wxDefaultValidator, const wxString& name = wxComboBoxNameStr) - : wxComboControl() + : wxComboCtrl() { Init(); Create(parent,id,value, @@ -597,7 +582,7 @@ public: wxEmptyString, GetValue(), wxT("All files (*.*)|*.*"), - wxOPEN); + wxFD_OPEN); if ( dlg.ShowModal() == wxID_OK ) { @@ -605,6 +590,11 @@ public: } } + // Implement empty DoSetPopupControl to prevent assertion failure. + virtual void DoSetPopupControl(wxComboPopup* WXUNUSED(popup)) + { + } + private: void Init() { @@ -624,7 +614,6 @@ MyFrame::MyFrame(const wxString& title) wxBoxSizer* topRowSizer; wxBoxSizer* colSizer; wxBoxSizer* rowSizer; - wxStaticBoxSizer* groupSizer; // set the frame icon SetIcon(wxICON(sample)); @@ -635,14 +624,17 @@ MyFrame::MyFrame(const wxString& title) // the "About" item should be in the help menu wxMenu *helpMenu = new wxMenu; - helpMenu->Append(ComboControl_About, _T("&About...\tF1"), _T("Show about dialog")); + helpMenu->Append(ComboCtrl_About, wxT("&About...\tF1"), wxT("Show about dialog")); - fileMenu->Append(ComboControl_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); + fileMenu->Append(ComboCtrl_Compare, wxT("&Compare against wxComboBox..."), + wxT("Show some wxOwnerDrawnComboBoxes side-by-side with native wxComboBoxes.")); + fileMenu->AppendSeparator(); + fileMenu->Append(ComboCtrl_Quit, wxT("E&xit\tAlt-X"), wxT("Quit this program")); // now append the freshly created menu to the menu bar... wxMenuBar *menuBar = new wxMenuBar(); - menuBar->Append(fileMenu, _T("&File")); - menuBar->Append(helpMenu, _T("&Help")); + menuBar->Append(fileMenu, wxT("&File")); + menuBar->Append(helpMenu, wxT("&Help")); // ... and attach this menu bar to the frame SetMenuBar(menuBar); @@ -651,12 +643,13 @@ MyFrame::MyFrame(const wxString& title) wxPanel* panel = new wxPanel(this); // Prepare log window right away since it shows EVT_TEXTs - m_logWin = new wxTextCtrl( panel, 105, wxEmptyString, wxDefaultPosition, - wxSize(-1,125), wxTE_MULTILINE|wxFULL_REPAINT_ON_RESIZE ); - m_logWin->SetEditable(false); - wxLogTextCtrl* logger = new wxLogTextCtrl( m_logWin ); - m_logOld = logger->SetActiveTarget( logger ); - logger->SetTimestamp( NULL ); + m_logWin = new wxTextCtrl(panel, 105, wxEmptyString, + wxDefaultPosition, + wxSize(-1, 125), + wxTE_MULTILINE); + wxLogTextCtrl* logger = new wxLogTextCtrl(m_logWin); + m_logOld = logger->SetActiveTarget(logger); + logger->DisableTimestamp(); topSizer = new wxBoxSizer( wxVERTICAL ); @@ -666,176 +659,85 @@ MyFrame::MyFrame(const wxString& title) colSizer = new wxBoxSizer( wxVERTICAL ); - // Make sure GetFeatures is implemented - int features = wxComboControl::GetFeatures(); - wxLogDebug(wxT("wxComboControl features: 0x%X (all features: 0x%X)"), - features,wxComboControlFeatures::All); - - - wxComboBox* cb; - wxComboControl* cc; - wxGenericComboControl* gcc; + wxComboCtrl* cc; + wxGenericComboCtrl* gcc; wxOwnerDrawnComboBox* odc; // Create common strings array - wxArrayString arrItems; - arrItems.Add( wxT("Solid") ); - arrItems.Add( wxT("Transparent") ); - arrItems.Add( wxT("Dot") ); - arrItems.Add( wxT("Long Dash") ); - arrItems.Add( wxT("Short Dash") ); - arrItems.Add( wxT("Dot Dash") ); - arrItems.Add( wxT("Backward Diagonal Hatch") ); - arrItems.Add( wxT("Cross-diagonal Hatch") ); - arrItems.Add( wxT("Forward Diagonal Hatch") ); - arrItems.Add( wxT("Cross Hatch") ); - arrItems.Add( wxT("Horizontal Hatch") ); - arrItems.Add( wxT("Vertical Hatch") ); - - int border = 4; - - // - // Show some wxOwnerDrawComboBoxes for comparison - // - rowSizer = new wxBoxSizer(wxHORIZONTAL); - - groupSizer = new wxStaticBoxSizer(new wxStaticBox(panel,wxID_ANY,wxT(" wxOwnerDrawnComboBox ")), - wxVERTICAL); - - groupSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Writable, sorted:")), 0, - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border ); - - odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString, - wxDefaultPosition, wxDefaultSize, - arrItems, - wxCB_SORT // wxNO_BORDER|wxCB_READONLY - ); - - odc->Append(wxT("H - Appended Item")); // test sorting in append - - odc->SetValue(wxT("Dot Dash")); - - groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); - - // - // Readonly ODComboBox - groupSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Read-only:")), 0, - wxALIGN_CENTER_VERTICAL|wxRIGHT, border ); - - odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString, - wxDefaultPosition, wxDefaultSize, - arrItems, - wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY - ); - - odc->SetValue(wxT("Dot Dash")); - odc->SetText(wxT("Dot Dash (Testing SetText)")); - - groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); + m_arrItems.Add( wxT("Solid") ); + m_arrItems.Add( wxT("Transparent") ); + m_arrItems.Add( wxT("Dot") ); + m_arrItems.Add( wxT("Long Dash") ); + m_arrItems.Add( wxT("Short Dash") ); + m_arrItems.Add( wxT("Dot Dash") ); + m_arrItems.Add( wxT("Backward Diagonal Hatch") ); + m_arrItems.Add( wxT("Cross-diagonal Hatch") ); + m_arrItems.Add( wxT("Forward Diagonal Hatch") ); + m_arrItems.Add( wxT("Cross Hatch") ); + m_arrItems.Add( wxT("Horizontal Hatch") ); + m_arrItems.Add( wxT("Vertical Hatch") ); - // - // Disabled ODComboBox - groupSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Disabled:")), 0, - wxALIGN_CENTER_VERTICAL|wxRIGHT, border ); - - odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString, - wxDefaultPosition, wxDefaultSize, - arrItems, - wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY - ); - - odc->SetValue(wxT("Dot Dash")); - odc->Enable(false); - - groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); - - rowSizer->Add( groupSizer, 1, wxEXPAND|wxALL, border ); - - - groupSizer = new wxStaticBoxSizer(new wxStaticBox(panel,wxID_ANY,wxT(" wxComboBox ")), - wxVERTICAL); // - // wxComboBox - // - groupSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Writable, sorted:")), 0, - wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border ); - - cb = new wxComboBox(panel,wxID_ANY,wxEmptyString, - wxDefaultPosition, wxDefaultSize, - arrItems, - wxCB_SORT // wxNO_BORDER|wxCB_READONLY - ); - - cb->Append(wxT("H - Appended Item")); // test sorting in append - - cb->SetValue(wxT("Dot Dash")); - - groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); - + // Create pen selector ODComboBox with owner-drawn items // - // Readonly wxComboBox - groupSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Read-only:")), 0, - wxALIGN_CENTER_VERTICAL|wxRIGHT, border ); - - cb = new wxComboBox(panel,wxID_ANY,wxEmptyString, - wxDefaultPosition, wxDefaultSize, - arrItems, - wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY - ); - - cb->SetValue(wxT("Dot Dash")); - - groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); + rowSizer = new wxBoxSizer( wxHORIZONTAL ); + rowSizer->Add( new wxStaticText(panel,wxID_ANY, + wxT("OwnerDrawnComboBox with owner-drawn items:")), 1, + wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 ); + colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 ); - // - // Disabled wxComboBox - groupSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Disabled:")), 0, - wxALIGN_CENTER_VERTICAL|wxRIGHT, border ); + rowSizer = new wxBoxSizer( wxHORIZONTAL ); - cb = new wxComboBox(panel,wxID_ANY,wxEmptyString, - wxDefaultPosition, wxDefaultSize, - arrItems, - wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY - ); - cb->SetValue(wxT("Dot Dash")); - cb->Enable(false); + // When defining derivative class for callbacks, we need + // to use two-stage creation (or redefine the common wx + // constructor). + odc = new wxPenStyleComboBox(); + odc->Create(panel,wxID_ANY,wxEmptyString, + wxDefaultPosition, wxDefaultSize, + m_arrItems, + wxCB_READONLY //wxNO_BORDER | wxCB_READONLY + ); - groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); - rowSizer->Add( groupSizer, 1, wxEXPAND|wxALL, border ); + odc->SetSelection(0); + rowSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 4 ); + rowSizer->AddStretchSpacer(1); + colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 ); - colSizer->Add( rowSizer, 1, wxEXPAND|wxALL, border ); // - // Pen selector ODComboBox with application painted items + // Same but with changed button position // - rowSizer = new wxBoxSizer ( wxHORIZONTAL ); + rowSizer = new wxBoxSizer( wxHORIZONTAL ); rowSizer->Add( new wxStaticText(panel,wxID_ANY, - wxT("OwnerDrawnComboBox with Custom Paint Items and Button Placing:")), 1, + wxT("OwnerDrawnComboBox with owner-drawn items and button on the left:")), 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 ); colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 ); - rowSizer = new wxBoxSizer ( wxHORIZONTAL ); + rowSizer = new wxBoxSizer( wxHORIZONTAL ); + // When defining derivative class for callbacks, we need // to use two-stage creation (or redefine the common wx // constructor). - odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString, - wxDefaultPosition, wxDefaultSize, - arrItems, - wxCB_READONLY //wxNO_BORDER | wxCB_READONLY - ); + odc = new wxPenStyleComboBox(); + odc->Create(panel,wxID_ANY,wxEmptyString, + wxDefaultPosition, wxDefaultSize, + m_arrItems, + wxCB_READONLY //wxNO_BORDER | wxCB_READONLY + ); - odc->SetPopupControl( new wxPenStylePopup() ); - //m_odc->SetCustomPaintWidth( 60 ); odc->SetSelection(0); - odc->SetButtonPosition(-2, // width adjustment - -6, // height adjustment + + // Use button size that is slightly smaller than the default. + wxSize butSize = odc->GetButtonSize(); + odc->SetButtonPosition(butSize.x - 2, // button width + butSize.y - 6, // button height wxLEFT, // side 2 // horizontal spacing ); @@ -846,54 +748,52 @@ MyFrame::MyFrame(const wxString& title) // - // List View wxComboControl + // List View wxComboCtrl // - rowSizer = new wxBoxSizer ( wxHORIZONTAL ); - rowSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("List View wxComboControl:")), 1, - wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 ); - rowSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Tree Ctrl wxGenericComboControl:")), 1, + rowSizer = new wxBoxSizer( wxHORIZONTAL ); + rowSizer->Add( new wxStaticText(panel, + wxID_ANY, + "List View wxComboCtrl (custom animation):"), + 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 ); + rowSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Tree Ctrl wxComboCtrl:")), 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 ); colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 ); - rowSizer = new wxBoxSizer ( wxHORIZONTAL ); - cc = new wxComboControl(panel,2,wxEmptyString, - wxDefaultPosition, wxDefaultSize); + rowSizer = new wxBoxSizer( wxHORIZONTAL ); + cc = new wxComboCtrlWithCustomPopupAnim(); + + // Let's set a custom style for the contained wxTextCtrl. We need to + // use two-step creation for it to work properly. + cc->SetTextCtrlStyle(wxTE_RIGHT); + + cc->Create(panel, wxID_ANY, wxEmptyString); + + // Make sure we use popup that allows focusing the listview. + cc->UseAltPopupWindow(); cc->SetPopupMinWidth(300); ListViewComboPopup* iface = new ListViewComboPopup(); cc->SetPopupControl(iface); - iface->AddSelection( wxT("Cabbage") ); - iface->AddSelection( wxT("Potato") ); - iface->AddSelection( wxT("Onion") ); - iface->AddSelection( wxT("Carrot") ); - iface->AddSelection( wxT("Cauliflower") ); - iface->AddSelection( wxT("Bean") ); - iface->AddSelection( wxT("Raddish") ); - iface->AddSelection( wxT("Banana") ); - iface->AddSelection( wxT("Apple") ); - iface->AddSelection( wxT("Orange") ); - iface->AddSelection( wxT("Kiwi") ); - iface->AddSelection( wxT("Strawberry") ); - iface->AddSelection( wxT("Cucumber") ); - iface->AddSelection( wxT("Blackberry") ); - iface->AddSelection( wxT("Melon") ); - iface->AddSelection( wxT("Cherry") ); - iface->AddSelection( wxT("Pea") ); - iface->AddSelection( wxT("Pear") ); + int i; + for ( i=0; i<100; i++ ) + iface->AddSelection( wxString::Format(wxT("Item %02i"),i)); rowSizer->Add( cc, 1, wxALIGN_CENTER_VERTICAL|wxALL, 5 ); // - // Tree Ctrl wxComboControl + // Tree Ctrl wxComboCtrl // - // Note that we test that wxGenericComboControl works - gcc = new wxGenericComboControl(panel,wxID_ANY,wxEmptyString, - wxDefaultPosition, wxDefaultSize); + // Note that we test that wxGenericComboCtrl works + gcc = new wxGenericComboCtrl(panel,wxID_ANY,wxEmptyString, + wxDefaultPosition, wxDefaultSize); + + // Make sure we use popup that allows focusing the treectrl. + gcc->UseAltPopupWindow(); // Set popup interface right away, otherwise some of the calls // below may fail @@ -905,24 +805,22 @@ MyFrame::MyFrame(const wxString& title) wxTreeItemId groupId; - groupId = tcPopup->AppendItem(rootId,wxT("Controls")); - tcPopup->AppendItem(groupId,wxT("wxButton")); - tcPopup->AppendItem(groupId,wxT("wxCheckBox")); - tcPopup->AppendItem(groupId,wxT("wxListCtrl")); - tcPopup->AppendItem(groupId,wxT("wxStaticBox")); - tcPopup->AppendItem(groupId,wxT("wxStaticText")); - tcPopup->AppendItem(groupId,wxT("wxTextCtrl")); - tcPopup->AppendItem(groupId,wxT("wxTreeCtrl")); - groupId = tcPopup->AppendItem(rootId,wxT("Dialogs")); - tcPopup->AppendItem(groupId,wxT("wxDirDialog")); - tcPopup->AppendItem(groupId,wxT("wxFileDialog")); - tcPopup->AppendItem(groupId,wxT("wxWizard")); - - gcc->SetValue(wxT("wxStaticBox")); + for ( i=0; i<4; i++ ) + { + groupId = tcPopup->AppendItem(rootId, + wxString::Format(wxT("Branch %02i"),i)); + + int n; + for ( n=0; n<25; n++ ) + tcPopup->AppendItem(groupId, + wxString::Format(wxT("Subitem %02i"),(i*25)+n)); + } + + gcc->SetValue(wxT("Subitem 05")); // Move button to left - it makes more sense for a tree ctrl - gcc->SetButtonPosition(0, // width adjustment - 0, // height adjustment + gcc->SetButtonPosition(-1, // button width + -1, // button height wxLEFT, // side 0 // horizontal spacing ); @@ -938,25 +836,25 @@ MyFrame::MyFrame(const wxString& title) // Custom Dropbutton Bitmaps // (second one uses blank button background) // - rowSizer = new wxBoxSizer ( wxHORIZONTAL ); + rowSizer = new wxBoxSizer( wxHORIZONTAL ); rowSizer->Add( new wxStaticText(panel,wxID_ANY, wxT("OwnerDrawnComboBox with simple dropbutton graphics:")), 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 ); colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 ); - rowSizer = new wxBoxSizer ( wxHORIZONTAL ); + rowSizer = new wxBoxSizer( wxHORIZONTAL ); odc = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString, wxDefaultPosition, wxDefaultSize, - arrItems, + m_arrItems, (long)0 // wxCB_SORT // wxNO_BORDER | wxCB_READONLY ); wxOwnerDrawnComboBox* odc2; odc2 = new wxOwnerDrawnComboBox(panel,wxID_ANY,wxEmptyString, wxDefaultPosition, wxDefaultSize, - arrItems, + m_arrItems, (long)0 // wxCB_SORT // wxNO_BORDER | wxCB_READONLY ); @@ -965,7 +863,7 @@ MyFrame::MyFrame(const wxString& title) wxImage imgPressed(wxT("dropbutp.png")); wxImage imgHover(wxT("dropbuth.png")); - if ( imgNormal.Ok() && imgPressed.Ok() && imgHover.Ok() ) + if ( imgNormal.IsOk() && imgPressed.IsOk() && imgHover.IsOk() ) { wxBitmap bmpNormal(imgNormal); wxBitmap bmpPressed(imgPressed); @@ -989,17 +887,17 @@ MyFrame::MyFrame(const wxString& title) // - // wxComboControl with totally custom button action (open file dialog) + // wxComboCtrl with totally custom button action (open file dialog) // - rowSizer = new wxBoxSizer ( wxHORIZONTAL ); + rowSizer = new wxBoxSizer( wxHORIZONTAL ); rowSizer->Add( new wxStaticText(panel,wxID_ANY, - wxT("wxComboControl with custom button action:")), 1, + wxT("wxComboCtrl with custom button action:")), 1, wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 ); colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 ); - rowSizer = new wxBoxSizer ( wxHORIZONTAL ); + rowSizer = new wxBoxSizer( wxHORIZONTAL ); wxFileSelectorCombo* fsc; fsc = new wxFileSelectorCombo(panel,wxID_ANY,wxEmptyString, @@ -1011,35 +909,195 @@ MyFrame::MyFrame(const wxString& title) colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, 5 ); + // Make sure GetFeatures is implemented + wxComboCtrl::GetFeatures(); + + topRowSizer->Add( colSizer, 1, wxALL, 2 ); - topRowSizer->Add( m_logWin, 1, wxEXPAND|wxALL, 5 ); + colSizer = new wxBoxSizer( wxVERTICAL ); + + colSizer->AddSpacer(8); + colSizer->Add( new wxStaticText(panel, wxID_ANY, wxT("Log Messages:")), 0, wxTOP|wxLEFT, 3 ); + colSizer->Add( m_logWin, 1, wxEXPAND|wxALL, 3 ); + + topRowSizer->Add( colSizer, 1, wxEXPAND|wxALL, 2 ); topSizer->Add( topRowSizer, 1, wxEXPAND ); panel->SetSizer( topSizer ); topSizer->SetSizeHints( panel ); - SetSize(740,480); + SetSize(740,400); Centre(); } -MyFrame::~MyFrame() -{ - delete wxLog::SetActiveTarget(m_logOld); -} - // event handlers void MyFrame::OnComboBoxUpdate( wxCommandEvent& event ) { // Don't show messages for the log output window (it'll crash) - if ( event.GetId() == 105 ) + if ( !event.GetEventObject()->IsKindOf(CLASSINFO(wxComboCtrl)) ) return; if ( event.GetEventType() == wxEVT_COMMAND_COMBOBOX_SELECTED ) + { wxLogDebug(wxT("EVT_COMBOBOX(id=%i,selection=%i)"),event.GetId(),event.GetSelection()); + } else if ( event.GetEventType() == wxEVT_COMMAND_TEXT_UPDATED ) + { wxLogDebug(wxT("EVT_TEXT(id=%i,string=\"%s\")"),event.GetId(),event.GetString().c_str()); + } + else if ( event.GetEventType() == wxEVT_COMMAND_TEXT_ENTER ) + { + wxLogDebug("EVT_TEXT_ENTER(id=%i,string=\"%s\")", + event.GetId(), event.GetString().c_str()); + } +} + +void MyFrame::OnShowComparison( wxCommandEvent& WXUNUSED(event) ) +{ + // + // Show some wxOwnerDrawComboBoxes for comparison + // + + wxBoxSizer* colSizer; + wxBoxSizer* rowSizer; + wxStaticBoxSizer* groupSizer; + + wxComboBox* cb; + wxOwnerDrawnComboBox* odc; + + const int border = 4; + + wxDialog* dlg = new wxDialog(this,wxID_ANY, + wxT("Compare against wxComboBox"), + wxDefaultPosition,wxDefaultSize, + wxDEFAULT_DIALOG_STYLE|wxRESIZE_BORDER); + + colSizer = new wxBoxSizer( wxVERTICAL ); + + rowSizer = new wxBoxSizer(wxHORIZONTAL); + + groupSizer = new wxStaticBoxSizer(new wxStaticBox(dlg,wxID_ANY,wxT(" wxOwnerDrawnComboBox ")), + wxVERTICAL); + + groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Writable, sorted:")), 0, + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border ); + + odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString, + wxDefaultPosition, wxDefaultSize, + m_arrItems, + wxCB_SORT // wxNO_BORDER|wxCB_READONLY + ); + + odc->Append(wxT("H - Appended Item")); // test sorting in append + + odc->SetValue(wxT("Dot Dash")); + + groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); + + // + // Readonly ODComboBox + groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Read-only:")), 0, + wxALIGN_CENTER_VERTICAL|wxRIGHT, border ); + + odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString, + wxDefaultPosition, wxDefaultSize, + m_arrItems, + wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY + ); + + odc->SetValue(wxT("Dot Dash")); + odc->SetText(wxT("Dot Dash (Testing SetText)")); + + groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); + + // + // Disabled ODComboBox + groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Disabled:")), 0, + wxALIGN_CENTER_VERTICAL|wxRIGHT, border ); + + odc = new wxOwnerDrawnComboBox(dlg,wxID_ANY,wxEmptyString, + wxDefaultPosition, wxDefaultSize, + m_arrItems, + wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY + ); + + odc->SetValue(wxT("Dot Dash")); + odc->Enable(false); + + groupSizer->Add( odc, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); + + rowSizer->Add( groupSizer, 1, wxEXPAND|wxALL, border ); + + + groupSizer = new wxStaticBoxSizer(new wxStaticBox(dlg,wxID_ANY,wxT(" wxComboBox ")), + wxVERTICAL); + + // + // wxComboBox + // + groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Writable, sorted:")), 0, + wxALIGN_CENTER_VERTICAL|wxRIGHT|wxEXPAND, border ); + + cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString, + wxDefaultPosition, wxDefaultSize, + m_arrItems, + wxCB_SORT // wxNO_BORDER|wxCB_READONLY + ); + + cb->Append(wxT("H - Appended Item")); // test sorting in append + + cb->SetValue(wxT("Dot Dash")); + + groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); + + // + // Readonly wxComboBox + groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Read-only:")), 0, + wxALIGN_CENTER_VERTICAL|wxRIGHT, border ); + + cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString, + wxDefaultPosition, wxDefaultSize, + m_arrItems, + wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY + ); + + cb->SetValue(wxT("Dot Dash")); + + groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); + + // + // Disabled wxComboBox + groupSizer->Add( new wxStaticText(dlg,wxID_ANY,wxT("Disabled:")), 0, + wxALIGN_CENTER_VERTICAL|wxRIGHT, border ); + + cb = new wxComboBox(dlg,wxID_ANY,wxEmptyString, + wxDefaultPosition, wxDefaultSize, + m_arrItems, + wxCB_SORT|wxCB_READONLY // wxNO_BORDER|wxCB_READONLY + ); + + cb->SetValue(wxT("Dot Dash")); + cb->Enable(false); + + groupSizer->Add( cb, 1, wxALIGN_CENTER_VERTICAL|wxEXPAND|wxALL, border ); + + rowSizer->Add( groupSizer, 1, wxEXPAND|wxALL, border ); + + colSizer->Add( rowSizer, 0, wxEXPAND|wxALL, border ); + + dlg->SetSizer( colSizer ); + colSizer->SetSizeHints( dlg ); + + dlg->SetSize(60,240); + dlg->Centre(); + dlg->ShowModal(); +} + +MyFrame::~MyFrame() +{ + delete wxLog::SetActiveTarget(m_logOld); } void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) @@ -1051,14 +1109,38 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event)) void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event)) { wxMessageBox(wxString::Format( - _T("Welcome to %s!\n") - _T("\n") - _T("This is the wxWidgets wxComboControl sample\n") - _T("running under %s."), + wxT("Welcome to %s!\n") + wxT("\n") + wxT("This is the wxWidgets wxComboCtrl and wxOwnerDrawnComboBox sample\n") + wxT("running under %s."), wxVERSION_STRING, wxGetOsDescription().c_str() ), - _T("About wxComboControl sample"), + wxT("About wxComboCtrl sample"), wxOK | wxICON_INFORMATION, this); } + +void MyFrame::OnIdle(wxIdleEvent& event) +{ + // This code is useful for debugging focus problems + // (which are plentiful when dealing with popup windows). +#if 0 + static wxWindow* lastFocus = (wxWindow*) NULL; + + wxWindow* curFocus = ::wxWindow::FindFocus(); + + if ( curFocus != lastFocus ) + { + const wxChar* className = wxT(""); + if ( curFocus ) + className = curFocus->GetClassInfo()->GetClassName(); + lastFocus = curFocus; + wxLogDebug( wxT("FOCUSED: %s %X"), + className, + (unsigned int)curFocus); + } +#endif + + event.Skip(); +}