]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/popup/popup.cpp
Support using GetTextExtent() with empty string to get descent in wxOSX.
[wxWidgets.git] / samples / popup / popup.cpp
index f3a8ce329756bec0b37c44805edce56fca0eab99..ed0097e955edd87c6f4f0a463cda8b023b948366 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
-// Name:        minimal.cpp
+// Name:        popup.cpp
 // Purpose:     Popup wxWidgets sample
 // Author:      Robert Roebling
 // Modified by:
@@ -31,6 +31,7 @@
 #endif
 
 #include "wx/popupwin.h"
+#include "wx/spinctrl.h"
 
 // ----------------------------------------------------------------------------
 // resources
 
 // 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
 
+// ----------------------------------------------------------------------------
+// constants
+// ----------------------------------------------------------------------------
+
+// IDs for the controls and the menu commands
+enum
+{
+    Minimal_Quit = wxID_EXIT,
+    Minimal_About = wxID_ABOUT,
+    Minimal_TestDialog,
+    Minimal_StartSimplePopup,
+    Minimal_StartScrolledPopup,
+    Minimal_LogWindow,
+    Minimal_PopupButton,
+    Minimal_PopupSpinctrl
+};
+
+//----------------------------------------------------------------------------
+// SimpleTransientPopup
+//----------------------------------------------------------------------------
 class SimpleTransientPopup: public wxPopupTransientWindow
 {
 public:
-    SimpleTransientPopup( wxWindow *parent );
+    SimpleTransientPopup( wxWindow *parent, bool scrolled );
     virtual ~SimpleTransientPopup();
-    
-    void OnDismiss();
-    
+
+    // wxPopupTransientWindow virtual methods are all overridden to log them
+    virtual void Popup(wxWindow *focus = NULL);
+    virtual void OnDismiss();
+    virtual bool ProcessLeftDown(wxMouseEvent& event);
+    virtual bool Show( bool show = true );
+
 private:
-    wxPanel *m_panel;
-    
+    wxScrolledWindow *m_panel;
+    wxButton *m_button;
+    wxSpinCtrl *m_spinCtrl;
+    wxStaticText *m_mouseText;
+
 private:
     void OnMouse( wxMouseEvent &event );
     void OnSize( wxSizeEvent &event );
     void OnSetFocus( wxFocusEvent &event );
     void OnKillFocus( wxFocusEvent &event );
+    void OnButton( wxCommandEvent& event );
+    void OnSpinCtrl( wxSpinEvent& event );
 
 private:
     DECLARE_CLASS(SimpleTransientPopup)
     DECLARE_EVENT_TABLE()
 };
 
-
 //----------------------------------------------------------------------------
 // SimpleTransientPopup
 //----------------------------------------------------------------------------
-
 IMPLEMENT_CLASS(SimpleTransientPopup,wxPopupTransientWindow)
 
 BEGIN_EVENT_TABLE(SimpleTransientPopup,wxPopupTransientWindow)
@@ -76,50 +104,152 @@ BEGIN_EVENT_TABLE(SimpleTransientPopup,wxPopupTransientWindow)
     EVT_SIZE( SimpleTransientPopup::OnSize )
     EVT_SET_FOCUS( SimpleTransientPopup::OnSetFocus )
     EVT_KILL_FOCUS( SimpleTransientPopup::OnKillFocus )
+    EVT_BUTTON( Minimal_PopupButton, SimpleTransientPopup::OnButton )
+    EVT_SPINCTRL( Minimal_PopupSpinctrl, SimpleTransientPopup::OnSpinCtrl )
 END_EVENT_TABLE()
 
-SimpleTransientPopup::SimpleTransientPopup( wxWindow *parent ) :
-    wxPopupTransientWindow( parent )
+SimpleTransientPopup::SimpleTransientPopup( wxWindow *parent, bool scrolled )
+                     :wxPopupTransientWindow( parent )
 {
-    m_panel = new wxPanel( this, -1 );
+    m_panel = new wxScrolledWindow( this, wxID_ANY );
     m_panel->SetBackgroundColour( *wxLIGHT_GREY );
-    wxStaticText *text = new wxStaticText( m_panel, -1, 
-                          wxT("wx.PopupTransientWindow is a\n")
-                          wxT("wx.PopupWindow which disappears\n")
+
+    // Keep this code to verify if mouse events work, they're required if
+    // you're making a control like a combobox where the items are highlighted
+    // under the cursor, the m_panel is set focus in the Popup() function
+    m_panel->Connect(wxEVT_MOTION,
+                     wxMouseEventHandler(SimpleTransientPopup::OnMouse),
+                     NULL, this);
+
+    wxStaticText *text = new wxStaticText( m_panel, wxID_ANY,
+                          wxT("wxPopupTransientWindow is a\n")
+                          wxT("wxPopupWindow which disappears\n")
                           wxT("automatically when the user\n")
                           wxT("clicks the mouse outside it or if it\n")
                           wxT("(or its first child) loses focus in \n")
-                          wxT("any other way."), wxPoint( 10,10) );
-    wxSize size = text->GetBestSize();
-    m_panel->SetSize( size.x+20, size.y+20 );
-    SetClientSize( size.x+20, size.y+20 );
+                          wxT("any other way.") );
+
+    m_button = new wxButton(m_panel, Minimal_PopupButton, wxT("Press Me"));
+    m_spinCtrl = new wxSpinCtrl(m_panel, Minimal_PopupSpinctrl, wxT("Hello"));
+    m_mouseText = new wxStaticText(m_panel, wxID_ANY,
+                                   wxT("<- Test Mouse ->"));
+
+    wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
+    topSizer->Add( text, 0, wxALL, 5 );
+    topSizer->Add( m_button, 0, wxALL, 5 );
+    topSizer->Add( m_spinCtrl, 0, wxALL, 5 );
+    topSizer->Add( m_mouseText, 0, wxCENTRE|wxALL, 5 );
+
+    if ( scrolled )
+    {
+        // Add a big window to ensure that scrollbars are shown when we set the
+        // panel size to a lesser size below.
+        topSizer->Add(new wxPanel(m_panel, wxID_ANY, wxDefaultPosition,
+                                  wxSize(600, 900)));
+    }
+
+    m_panel->SetSizer( topSizer );
+    if ( scrolled )
+    {
+        // Set the fixed size to ensure that the scrollbars are shown.
+        m_panel->SetSize(300, 300);
+
+        // And also actually enable them.
+        m_panel->SetScrollRate(10, 10);
+    }
+    else
+    {
+        // Use the fitting size for the panel if we don't need scrollbars.
+        topSizer->Fit(m_panel);
+    }
+
+    SetClientSize(m_panel->GetSize());
 }
 
 SimpleTransientPopup::~SimpleTransientPopup()
 {
 }
 
+void SimpleTransientPopup::Popup(wxWindow* WXUNUSED(focus))
+{
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::Popup"), long(this) );
+    wxPopupTransientWindow::Popup();
+}
+
 void SimpleTransientPopup::OnDismiss()
 {
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnDismiss"), long(this) );
+    wxPopupTransientWindow::OnDismiss();
+}
+
+bool SimpleTransientPopup::ProcessLeftDown(wxMouseEvent& event)
+{
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::ProcessLeftDown pos(%d, %d)"), long(this), event.GetX(), event.GetY());
+    return wxPopupTransientWindow::ProcessLeftDown(event);
+}
+bool SimpleTransientPopup::Show( bool show )
+{
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::Show %d"), long(this), int(show));
+    return wxPopupTransientWindow::Show(show);
 }
 
 void SimpleTransientPopup::OnSize(wxSizeEvent &event)
 {
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSize"), long(this) );
     event.Skip();
 }
 
 void SimpleTransientPopup::OnSetFocus(wxFocusEvent &event)
 {
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSetFocus"), long(this) );
     event.Skip();
 }
 
 void SimpleTransientPopup::OnKillFocus(wxFocusEvent &event)
 {
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnKillFocus"), long(this) );
     event.Skip();
 }
 
 void SimpleTransientPopup::OnMouse(wxMouseEvent &event)
 {
+    wxRect rect(m_mouseText->GetRect());
+    rect.SetX(-100000);
+    rect.SetWidth(1000000);
+    wxColour colour(*wxLIGHT_GREY);
+
+    if (rect.Contains(event.GetPosition()))
+    {
+        colour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
+        wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnMouse pos(%d, %d)"),
+                      long(event.GetEventObject()), event.GetX(), event.GetY());
+    }
+
+    if (colour != m_mouseText->GetBackgroundColour())
+    {
+        m_mouseText->SetBackgroundColour(colour);
+        m_mouseText->Refresh();
+    }
+    event.Skip();
+}
+
+void SimpleTransientPopup::OnButton(wxCommandEvent& event)
+{
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnButton ID %d"), long(this), event.GetId());
+
+    wxButton *button = wxDynamicCast(event.GetEventObject(), wxButton);
+    if (button->GetLabel() == wxT("Press Me"))
+        button->SetLabel(wxT("Pressed"));
+    else
+        button->SetLabel(wxT("Press Me"));
+
+    event.Skip();
+}
+
+void SimpleTransientPopup::OnSpinCtrl(wxSpinEvent& event)
+{
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSpinCtrl ID %d Value %d"),
+                  long(this), event.GetId(), event.GetInt());
     event.Skip();
 }
 
@@ -127,21 +257,17 @@ void SimpleTransientPopup::OnMouse(wxMouseEvent &event)
 // private classes
 // ----------------------------------------------------------------------------
 
-class MyApp : public wxApp
-{
-public:
-    virtual bool OnInit();
-};
-
 class MyDialog : public wxDialog
 {
 public:
     MyDialog(const wxString& title);
 
     void OnStartSimplePopup(wxCommandEvent& event);
-    void OnStartComplexPopup(wxCommandEvent& event);
+    void OnStartScrolledPopup(wxCommandEvent& event);
 
 private:
+    SimpleTransientPopup *m_simplePopup;
+    SimpleTransientPopup *m_scrolledPopup;
     DECLARE_EVENT_TABLE()
 };
 
@@ -149,29 +275,29 @@ class MyFrame : public wxFrame
 {
 public:
     MyFrame(const wxString& title);
+    virtual ~MyFrame();
 
     void OnQuit(wxCommandEvent& event);
     void OnAbout(wxCommandEvent& event);
     void OnTestDialog(wxCommandEvent& event);
     void OnStartSimplePopup(wxCommandEvent& event);
-    void OnStartComplexPopup(wxCommandEvent& event);
+    void OnStartScrolledPopup(wxCommandEvent& event);
+    void OnActivate(wxActivateEvent& event);
 
 private:
+    SimpleTransientPopup *m_simplePopup;
+    SimpleTransientPopup *m_scrolledPopup;
+    wxTextCtrl *m_logWin;
+    wxLog *m_logOld;
     DECLARE_EVENT_TABLE()
 };
 
-// ----------------------------------------------------------------------------
-// constants
-// ----------------------------------------------------------------------------
-
-// IDs for the controls and the menu commands
-enum
+class MyApp : public wxApp
 {
-    Minimal_Quit = wxID_EXIT,
-    Minimal_About = wxID_ABOUT,
-    Minimal_TestDialog,
-    Minimal_StartSimplePopup,
-    Minimal_StartComplexPopup,
+public:
+    virtual bool OnInit();
+
+    MyFrame *m_frame;
 };
 
 // ----------------------------------------------------------------------------
@@ -184,12 +310,15 @@ 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("Popup wxWidgets App"));
+    m_frame = new MyFrame(wxT("Popup wxWidgets App"));
 
     // and show it (the frames, unlike simple controls, are not shown when
     // created initially)
-    frame->Show(true);
+    m_frame->Show(true);
 
     // success: wxApp::OnRun() will be called which will enter the main message
     // loop and the application will run. If we returned false here, the
@@ -205,13 +334,16 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(Minimal_Quit,  MyFrame::OnQuit)
     EVT_MENU(Minimal_About, MyFrame::OnAbout)
     EVT_MENU(Minimal_TestDialog, MyFrame::OnTestDialog)
+    EVT_ACTIVATE(MyFrame::OnActivate)
     EVT_BUTTON(Minimal_StartSimplePopup, MyFrame::OnStartSimplePopup)
-    EVT_BUTTON(Minimal_StartComplexPopup, MyFrame::OnStartComplexPopup)
+    EVT_BUTTON(Minimal_StartScrolledPopup, MyFrame::OnStartScrolledPopup)
 END_EVENT_TABLE()
 
 MyFrame::MyFrame(const wxString& title)
-       : wxFrame(NULL, wxID_ANY, title)
+: wxFrame(NULL, wxID_ANY, title, wxDefaultPosition, wxSize(500,300))
 {
+    m_simplePopup = m_scrolledPopup = NULL;
+
     SetIcon(wxICON(sample));
 
 #if wxUSE_MENUS
@@ -219,45 +351,83 @@ MyFrame::MyFrame(const wxString& title)
 
     // the "About" item should be in the help menu
     wxMenu *helpMenu = new wxMenu;
-    helpMenu->Append(Minimal_About, _T("&About...\tF1"), _T("Show about dialog"));
+    helpMenu->Append(Minimal_About, wxT("&About\tF1"), wxT("Show about dialog"));
 
-    menuFile->Append(Minimal_TestDialog, _T("&Test dialog\tAlt-T"), _T("Test dialog"));
-    menuFile->Append(Minimal_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
+    menuFile->Append(Minimal_TestDialog, wxT("&Test dialog\tAlt-T"), wxT("Test dialog"));
+    menuFile->Append(Minimal_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(menuFile, _T("&File"));
-    menuBar->Append(helpMenu, _T("&Help"));
+    menuBar->Append(menuFile, wxT("&File"));
+    menuBar->Append(helpMenu, wxT("&Help"));
 
     // ... and attach this menu bar to the frame
     SetMenuBar(menuBar);
 #endif // wxUSE_MENUS
 
-    new wxButton( this, Minimal_StartSimplePopup, wxT("Show simple popup"), wxPoint(20,20) );
-    new wxButton( this, Minimal_StartComplexPopup, wxT("Show complex popup"), wxPoint(20,120) );
-
-
 #if wxUSE_STATUSBAR
     // create a status bar just for fun (by default with 1 pane only)
     CreateStatusBar(2);
-    SetStatusText(_T("Welcome to wxWidgets!"));
+    SetStatusText(wxT("Welcome to wxWidgets!"));
 #endif // wxUSE_STATUSBAR
+
+    wxPanel *panel = new wxPanel(this, -1);
+    wxButton *button1 = new wxButton( panel, Minimal_StartSimplePopup, wxT("Show simple popup"), wxPoint(20,20) );
+    wxButton *button2 = new wxButton( panel, Minimal_StartScrolledPopup, wxT("Show scrolled popup"), wxPoint(20,70) );
+
+    m_logWin = new wxTextCtrl( panel, wxID_ANY, wxEmptyString, wxDefaultPosition,
+                               wxDefaultSize, wxTE_MULTILINE );
+    m_logWin->SetEditable(false);
+    wxLogTextCtrl* logger = new wxLogTextCtrl( m_logWin );
+    m_logOld = logger->SetActiveTarget( logger );
+    logger->DisableTimestamp();
+
+    wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
+    topSizer->Add( button1, 0, wxALL, 5 );
+    topSizer->Add( button2, 0, wxALL, 5 );
+    topSizer->Add( m_logWin, 1, wxEXPAND|wxALL, 5 );
+
+    panel->SetSizer( topSizer );
+
 }
 
+MyFrame::~MyFrame()
+{
+    delete wxLog::SetActiveTarget(m_logOld);
+}
+
+
 // event handlers
 
+void MyFrame::OnActivate(wxActivateEvent& WXUNUSED(event))
+{
+    wxLogMessage( wxT("In activate...") );
+}
+
 void MyFrame::OnStartSimplePopup(wxCommandEvent& event)
 {
-    SimpleTransientPopup* popup = new SimpleTransientPopup( this );
+    wxLogMessage( wxT("================================================") );
+    delete m_simplePopup;
+    m_simplePopup = new SimpleTransientPopup( this, false );
     wxWindow *btn = (wxWindow*) event.GetEventObject();
     wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
     wxSize sz = btn->GetSize();
-    popup->Position( pos, sz );
-    popup->Popup();
+    m_simplePopup->Position( pos, sz );
+    wxLogMessage( wxT("0x%lx Simple Popup Shown pos(%d, %d) size(%d, %d)"), long(m_simplePopup), pos.x, pos.y, sz.x, sz.y );
+    m_simplePopup->Popup();
 }
 
-void MyFrame::OnStartComplexPopup(wxCommandEvent& WXUNUSED(event))
+void MyFrame::OnStartScrolledPopup(wxCommandEvent& event)
 {
+    wxLogMessage( wxT("================================================") );
+    delete m_scrolledPopup;
+    m_scrolledPopup = new SimpleTransientPopup( this, true );
+    wxWindow *btn = (wxWindow*) event.GetEventObject();
+    wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
+    wxSize sz = btn->GetSize();
+    m_scrolledPopup->Position( pos, sz );
+    wxLogMessage( wxT("0x%lx Scrolled Popup Shown pos(%d, %d) size(%d, %d)"), long(m_scrolledPopup), pos.x, pos.y, sz.x, sz.y );
+    m_scrolledPopup->Popup();
 }
 
 void MyFrame::OnTestDialog(wxCommandEvent& WXUNUSED(event))
@@ -275,10 +445,10 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 {
     wxString msg;
-    msg.Printf( _T("This is the About dialog of the popup sample.\n")
-                _T("Welcome to %s"), wxVERSION_STRING);
+    msg.Printf( wxT("This is the About dialog of the popup sample.\n")
+                wxT("Welcome to %s"), wxVERSION_STRING);
 
-    wxMessageBox(msg, _T("About Popup"), wxOK | wxICON_INFORMATION, this);
+    wxMessageBox(msg, wxT("About Popup"), wxOK | wxICON_INFORMATION, this);
 }
 
 // ----------------------------------------------------------------------------
@@ -287,30 +457,51 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 
 BEGIN_EVENT_TABLE(MyDialog, wxDialog)
     EVT_BUTTON(Minimal_StartSimplePopup, MyDialog::OnStartSimplePopup)
-    EVT_BUTTON(Minimal_StartComplexPopup, MyDialog::OnStartComplexPopup)
+    EVT_BUTTON(Minimal_StartScrolledPopup, MyDialog::OnStartScrolledPopup)
 END_EVENT_TABLE()
 
 MyDialog::MyDialog(const wxString& title)
-       wxDialog(NULL, wxID_ANY, title, wxPoint(50,50), wxSize(400,300))
+         :wxDialog(NULL, wxID_ANY, title, wxPoint(50,50), wxSize(400,300))
 {
+    m_simplePopup = m_scrolledPopup = NULL;
+    wxPanel *panel = new wxPanel(this, -1);
+
+    wxButton *button1 = new wxButton( panel, Minimal_StartSimplePopup, wxT("Show simple popup"), wxPoint(20,20) );
+    wxButton *button2 = new wxButton( panel, Minimal_StartScrolledPopup, wxT("Show scrolled popup"), wxPoint(20,60) );
 
-    new wxButton( this, Minimal_StartSimplePopup, wxT("Show simple popup"), wxPoint(20,20) );
-    new wxButton( this, Minimal_StartComplexPopup, wxT("Show complex popup"), wxPoint(20,80) );
+    wxButton *okButton = new wxButton( panel, wxID_OK, wxT("OK"), wxPoint(20,200) );
 
-    new wxButton( this, wxID_OK, wxT("OK"), wxPoint(20,200) );
+    wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
+    topSizer->Add( button1, 0, wxALL, 5 );
+    topSizer->Add( button2, 0, wxALL, 5 );
+    topSizer->AddSpacer(40);
+    topSizer->Add( okButton, 0, wxALL, 5 );
+
+    panel->SetSizerAndFit( topSizer );
 }
 
 void MyDialog::OnStartSimplePopup(wxCommandEvent& event)
 {
-    SimpleTransientPopup* popup = new SimpleTransientPopup( this );
+    wxLogMessage( wxT("================================================") );
+    delete m_simplePopup;
+    m_simplePopup = new SimpleTransientPopup( this, false );
     wxWindow *btn = (wxWindow*) event.GetEventObject();
     wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
     wxSize sz = btn->GetSize();
-    popup->Position( pos, sz );
-    popup->Popup();
+    m_simplePopup->Position( pos, sz );
+    wxLogMessage( wxT("0x%lx Dialog Simple Popup Shown pos(%d, %d) size(%d, %d)"), long(m_simplePopup), pos.x, pos.y, sz.x, sz.y );
+    m_simplePopup->Popup();
 }
 
-void MyDialog::OnStartComplexPopup(wxCommandEvent& WXUNUSED(event))
+void MyDialog::OnStartScrolledPopup(wxCommandEvent& event)
 {
+    wxLogMessage( wxT("================================================") );
+    delete m_scrolledPopup;
+    m_scrolledPopup = new SimpleTransientPopup( this, true );
+    wxWindow *btn = (wxWindow*) event.GetEventObject();
+    wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
+    wxSize sz = btn->GetSize();
+    m_scrolledPopup->Position( pos, sz );
+    wxLogMessage( wxT("0x%lx Dialog Scrolled Popup Shown pos(%d, %d) size(%d, %d)"), long(m_scrolledPopup), pos.x, pos.y, sz.x, sz.y );
+    m_scrolledPopup->Popup();
 }
-