]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/combo/combo.cpp
Make a couple virtuals protected so they can be overridden.
[wxWidgets.git] / samples / combo / combo.cpp
index 51e8a869ce8fc6604b0b307e6eb49217299c7d79..7710587b7379612cb7d625f26a3b9a33d47b3ba7 100644 (file)
@@ -45,7 +45,7 @@
 
 // the application icon (under Windows and OS/2 it is in resources and even
 // though we could still include the XPM here it would be unused)
-#if !defined(__WXMSW__) && !defined(__WXPM__)
+#ifndef wxHAS_IMAGES_IN_RESOURCES
     #include "../sample.xpm"
 #endif
 
@@ -83,6 +83,9 @@ public:
     // log wxComboCtrl events
     void OnComboBoxUpdate( wxCommandEvent& event );
 
+    void OnIdle( wxIdleEvent& event );
+
+
 protected:
     wxTextCtrl*     m_logWin;
     wxLog*          m_logOld;
@@ -102,15 +105,15 @@ private:
 // IDs for the controls and the menu commands
 enum
 {
-    ComboControl_Compare = wxID_HIGHEST,
+    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
 };
 
 // ----------------------------------------------------------------------------
@@ -122,11 +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_Compare,  MyFrame::OnShowComparison)
-    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
@@ -147,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("wxComboCtrl and wxOwnerDrawnComboBox Sample"));
+    MyFrame *frame = new MyFrame(wxT("wxComboCtrl and wxOwnerDrawnComboBox Sample"));
 
     // and show it (the frames, unlike simple controls, are not shown when
     // created initially)
@@ -228,8 +237,9 @@ public:
                                    int item, int flags ) const
     {
 
-        // If item is selected or even, use the default rendering.
-        if ( GetVListBoxComboPopup()->IsCurrent((size_t)item) ||
+        // 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);
@@ -367,14 +377,20 @@ public:
     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()
@@ -485,6 +501,23 @@ BEGIN_EVENT_TABLE(TreeCtrlComboPopup, wxTreeCtrl)
     EVT_LEFT_DOWN(TreeCtrlComboPopup::OnMouseClick)
 END_EVENT_TABLE()
 
+// ----------------------------------------------------------------------------
+// wxComboCtrl with custom popup animation, using wxWindow::ShowWithEffect().
+// ----------------------------------------------------------------------------
+
+class wxComboCtrlWithCustomPopupAnim : public wxComboCtrl
+{
+protected:
+    virtual bool AnimateShow( const wxRect& rect, int WXUNUSED(flags) )
+    {
+        wxWindow* win = GetPopupWindow();
+        win->SetSize(rect);
+        win->Raise();  // This is needed
+        win->ShowWithEffect(wxSHOW_EFFECT_BLEND);
+        return true;
+    }
+};
+
 // ----------------------------------------------------------------------------
 // wxComboCtrl with entirely custom button action (opens file dialog)
 // ----------------------------------------------------------------------------
@@ -591,17 +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_Compare, _T("&Compare against wxComboBox..."),
-        _T("Show some wxOwnerDrawnComboBoxes side-by-side with native wxComboBoxes."));
+    fileMenu->Append(ComboCtrl_Compare, wxT("&Compare against wxComboBox..."),
+        wxT("Show some wxOwnerDrawnComboBoxes side-by-side with native wxComboBoxes."));
     fileMenu->AppendSeparator();
-    fileMenu->Append(ComboControl_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
+    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);
@@ -610,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 );
@@ -626,7 +660,7 @@ MyFrame::MyFrame(const wxString& title)
 
 
     wxComboCtrl* cc;
-    wxGenericComboControl* gcc;
+    wxGenericComboCtrl* gcc;
     wxOwnerDrawnComboBox* odc;
 
     // Create common strings array
@@ -699,8 +733,11 @@ MyFrame::MyFrame(const wxString& title)
 
 
     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
                           );
@@ -715,15 +752,25 @@ MyFrame::MyFrame(const wxString& title)
     //
 
     rowSizer = new wxBoxSizer( wxHORIZONTAL );
-    rowSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("List View wxComboCtrl:")), 1,
-                   wxALIGN_CENTER_VERTICAL|wxRIGHT, 4 );
-    rowSizer->Add( new wxStaticText(panel,wxID_ANY,wxT("Tree Ctrl wxComboControl:")), 1,
+    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 wxComboCtrl(panel,2,wxEmptyString,
-                         wxDefaultPosition, wxDefaultSize);
+    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);
 
@@ -741,9 +788,12 @@ MyFrame::MyFrame(const wxString& title)
     // 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
@@ -769,8 +819,8 @@ MyFrame::MyFrame(const wxString& title)
     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
                           );
@@ -813,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);
@@ -865,13 +915,19 @@ MyFrame::MyFrame(const wxString& title)
 
     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,400);
+    Fit();
     Centre();
 }
 
@@ -884,9 +940,18 @@ void MyFrame::OnComboBoxUpdate( wxCommandEvent& event )
         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) )
@@ -1044,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 wxComboCtrl and wxOwnerDrawnComboBox 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 wxComboCtrl 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();
+}