]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/combo/combo.cpp
Implement missing wxTextBoxAttr::IsDefault function
[wxWidgets.git] / samples / combo / combo.cpp
index 89b115bdaf527247fb36a7b217ad9639a2ef06c1..28660519d0760fec48f53278bbd93b6921f9d480 100644 (file)
@@ -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);
+    Fit();
     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("<none>");
+        if ( curFocus )
+            className = curFocus->GetClassInfo()->GetClassName();
+        lastFocus = curFocus;
+        wxLogDebug( wxT("FOCUSED: %s %X"),
+            className,
+            (unsigned int)curFocus);
+    }
+#endif
+
+    event.Skip();
+}