]> 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 1f62803ab79df07c70a6372c8c4167a30b265713..ed0097e955edd87c6f4f0a463cda8b023b948366 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        minimal.cpp
+// Name:        popup.cpp
 // Purpose:     Popup wxWidgets sample
 // Author:      Robert Roebling
 // Modified by:
 // Purpose:     Popup wxWidgets sample
 // Author:      Robert Roebling
 // Modified by:
@@ -31,6 +31,7 @@
 #endif
 
 #include "wx/popupwin.h"
 #endif
 
 #include "wx/popupwin.h"
+#include "wx/spinctrl.h"
 
 // ----------------------------------------------------------------------------
 // resources
 
 // ----------------------------------------------------------------------------
 // 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)
 
 // 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
 
     #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
 //----------------------------------------------------------------------------
 class SimpleTransientPopup: public wxPopupTransientWindow
 {
 public:
-    SimpleTransientPopup( wxWindow *parent );
+    SimpleTransientPopup( wxWindow *parent, bool scrolled );
     virtual ~SimpleTransientPopup();
 
     // wxPopupTransientWindow virtual methods are all overridden to log them
     virtual ~SimpleTransientPopup();
 
     // wxPopupTransientWindow virtual methods are all overridden to log them
@@ -56,17 +74,20 @@ public:
     virtual void OnDismiss();
     virtual bool ProcessLeftDown(wxMouseEvent& event);
     virtual bool Show( bool show = true );
     virtual void OnDismiss();
     virtual bool ProcessLeftDown(wxMouseEvent& event);
     virtual bool Show( bool show = true );
-    
-    wxScrolledWindow* GetChild() { return m_panel; }
-    
+
 private:
     wxScrolledWindow *m_panel;
 private:
     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 );
 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)
 
 private:
     DECLARE_CLASS(SimpleTransientPopup)
@@ -83,326 +104,159 @@ BEGIN_EVENT_TABLE(SimpleTransientPopup,wxPopupTransientWindow)
     EVT_SIZE( SimpleTransientPopup::OnSize )
     EVT_SET_FOCUS( SimpleTransientPopup::OnSetFocus )
     EVT_KILL_FOCUS( SimpleTransientPopup::OnKillFocus )
     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()
 
 END_EVENT_TABLE()
 
-SimpleTransientPopup::SimpleTransientPopup( wxWindow *parent ) :
-    wxPopupTransientWindow( parent )
+SimpleTransientPopup::SimpleTransientPopup( wxWindow *parent, bool scrolled )
+                     :wxPopupTransientWindow( parent )
 {
 {
-    m_panel = new wxScrolledWindow( this, -1 );
+    m_panel = new wxScrolledWindow( this, wxID_ANY );
     m_panel->SetBackgroundColour( *wxLIGHT_GREY );
     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("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()
 {
 }
 
 }
 
 SimpleTransientPopup::~SimpleTransientPopup()
 {
 }
 
-void SimpleTransientPopup::Popup(wxWindow *focus)
+void SimpleTransientPopup::Popup(wxWindow* WXUNUSED(focus))
 {
 {
-    wxLogMessage( wxT("SimpleTransientPopup::Popup"));
-    wxPopupTransientWindow::Popup(focus);
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::Popup"), long(this) );
+    wxPopupTransientWindow::Popup();
 }
 
 void SimpleTransientPopup::OnDismiss()
 {
 }
 
 void SimpleTransientPopup::OnDismiss()
 {
-    wxLogMessage( wxT("SimpleTransientPopup::OnDismiss"));
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnDismiss"), long(this) );
     wxPopupTransientWindow::OnDismiss();
 }
 
 bool SimpleTransientPopup::ProcessLeftDown(wxMouseEvent& event)
 {
     wxPopupTransientWindow::OnDismiss();
 }
 
 bool SimpleTransientPopup::ProcessLeftDown(wxMouseEvent& event)
 {
-    wxLogMessage( wxT("SimpleTransientPopup::ProcessLeftDown pos(%d, %d)"), event.GetX(), event.GetY());
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::ProcessLeftDown pos(%d, %d)"), long(this), event.GetX(), event.GetY());
     return wxPopupTransientWindow::ProcessLeftDown(event);
 }
 bool SimpleTransientPopup::Show( bool show )
 {
     return wxPopupTransientWindow::ProcessLeftDown(event);
 }
 bool SimpleTransientPopup::Show( bool show )
 {
-    wxLogMessage( wxT("SimpleTransientPopup::Show %d"), int(show));
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::Show %d"), long(this), int(show));
     return wxPopupTransientWindow::Show(show);
 }
 
 void SimpleTransientPopup::OnSize(wxSizeEvent &event)
 {
     return wxPopupTransientWindow::Show(show);
 }
 
 void SimpleTransientPopup::OnSize(wxSizeEvent &event)
 {
-    wxLogMessage( wxT("SimpleTransientPopup::OnSize"));
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSize"), long(this) );
     event.Skip();
 }
 
 void SimpleTransientPopup::OnSetFocus(wxFocusEvent &event)
 {
     event.Skip();
 }
 
 void SimpleTransientPopup::OnSetFocus(wxFocusEvent &event)
 {
-    wxLogMessage( wxT("SimpleTransientPopup::OnSetFocus"));
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSetFocus"), long(this) );
     event.Skip();
 }
 
 void SimpleTransientPopup::OnKillFocus(wxFocusEvent &event)
 {
     event.Skip();
 }
 
 void SimpleTransientPopup::OnKillFocus(wxFocusEvent &event)
 {
-    wxLogMessage( wxT("SimpleTransientPopup::OnKillFocus"));
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnKillFocus"), long(this) );
     event.Skip();
 }
 
 void SimpleTransientPopup::OnMouse(wxMouseEvent &event)
 {
     event.Skip();
 }
 
 void SimpleTransientPopup::OnMouse(wxMouseEvent &event)
 {
-    wxLogMessage( wxT("SimpleTransientPopup::OnMouse pos(%d, %d)"), event.GetX(), event.GetY());
-    event.Skip();
-}
-
-// ----------------------------------------------------------------------------
-// ComplexTransientPopup
-//   we push the event handler when the mouse isn't in the popup and
-//   and pop the event handler when it is so that the child gets the events.
-// ----------------------------------------------------------------------------
+    wxRect rect(m_mouseText->GetRect());
+    rect.SetX(-100000);
+    rect.SetWidth(1000000);
+    wxColour colour(*wxLIGHT_GREY);
 
 
-// Use EVT_IDLE to push and pop the handler, else use a wxTimer
-#define USE_TIMER_TO_PUSHPOP 0
-
-class ComplexTransientPopup : public SimpleTransientPopup
-{
-public:    
-    ComplexTransientPopup(wxWindow *parent) : SimpleTransientPopup(parent)
+    if (rect.Contains(event.GetPosition()))
     {
     {
-        Init();
+        colour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
+        wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnMouse pos(%d, %d)"),
+                      long(event.GetEventObject()), event.GetX(), event.GetY());
     }
     }
-    virtual ~ComplexTransientPopup();
-    
-    virtual void Popup(wxWindow *focus = NULL);
-    virtual void Dismiss();
-    virtual bool ProcessLeftDown(wxMouseEvent& event);
-    
-protected:    
-
-    // safely push and pop the event handler of the child
-    void PushPopupHandler(wxWindow* child);
-    void PopPopupHandler(wxWindow* child);
-
-    void OnMouse( wxMouseEvent& event );
-    void OnKeyDown( wxKeyEvent &event );
-    
-#if USE_TIMER_TO_PUSHPOP
-    // start/stop timer that pushes and pops handler when the mouse goes over
-    //  the scrollbars (if any) of the child window
-    void StartTimer();
-    void StopTimer();
-    void OnTimer( wxTimerEvent& event );
-    wxTimer      *m_timer;           // timer for tracking mouse position
-#else // !USE_TIMER_TO_PUSHPOP
-    void OnIdle( wxIdleEvent& event );
-#endif // USE_TIMER_TO_PUSHPOP
-    
-    wxPoint       m_mouse;           // last/current mouse position
-    bool          m_popped_handler;  // state of the event handler
-
-private:
-    void Init();
-    DECLARE_EVENT_TABLE()
-};
-
-//----------------------------------------------------------------------------
-// ComplexTransientPopup
-//----------------------------------------------------------------------------
-BEGIN_EVENT_TABLE(ComplexTransientPopup, SimpleTransientPopup)
-    EVT_KEY_DOWN(ComplexTransientPopup::OnKeyDown)
-    EVT_MOUSE_EVENTS(ComplexTransientPopup::OnMouse)
-#if USE_TIMER_TO_PUSHPOP
-    EVT_TIMER( wxID_ANY, ComplexTransientPopup::OnTimer )
-#endif // USE_TIMER_TO_PUSHPOP
-END_EVENT_TABLE()
-
-void ComplexTransientPopup::Init()
-{
-#if USE_TIMER_TO_PUSHPOP
-    m_timer          = NULL;
-#endif // USE_TIMER_TO_PUSHPOP
-    m_popped_handler = false;
-}
-
-ComplexTransientPopup::~ComplexTransientPopup()
-{
-#if USE_TIMER_TO_PUSHPOP
-    StopTimer();
-#endif // USE_TIMER_TO_PUSHPOP
-}
 
 
-void ComplexTransientPopup::PushPopupHandler(wxWindow* child)
-{
-    if (child && m_handlerPopup && m_popped_handler)
-    {
-        m_popped_handler = false;
-        
-        if (child->GetEventHandler() != (wxEvtHandler*)m_handlerPopup)
-            child->PushEventHandler((wxEvtHandler*)m_handlerPopup);
-        if (!child->HasCapture())
-            child->CaptureMouse();
-        
-        child->SetFocus();
-    }        
-}
-void ComplexTransientPopup::PopPopupHandler(wxWindow* child)
-{
-    if (child && m_handlerPopup && !m_popped_handler)
-    {
-        m_popped_handler = true;
-        
-        if (child->GetEventHandler() == (wxEvtHandler*)m_handlerPopup)
-            child->PopEventHandler(false);         
-        if (child->HasCapture())
-            child->ReleaseMouse();
-            
-        child->SetFocus();            
-    }    
-}
-
-#if USE_TIMER_TO_PUSHPOP
-void ComplexTransientPopup::OnTimer( wxTimerEvent &WXUNUSED(event) )
-{   
-    if (!IsShown()) return;
-   
-    m_mouse = ScreenToClient(wxGetMousePosition());
-
-    wxWindow *child = GetChild();
-    if (!child) return; // nothing to do
-    
-    wxRect clientRect(wxPoint(0,0), GetClientSize());
-    wxLogMessage(wxT("CTW::OnTimer mouse(%d, %d), popped %d, m_handlerPopup %d"), m_mouse.x, m_mouse.y, m_popped_handler, m_handlerPopup);
-    // pop the event handler if inside the child window or 
-    // restore the event handler if not in the child window
-    if (clientRect.Inside(m_mouse))
-        PopPopupHandler(child);
-    else 
-        PushPopupHandler(child);
-}
-
-void ComplexTransientPopup::StartTimer()
-{
-    if (!m_timer)
-        m_timer = new wxTimer(this, wxID_ANY);
-    
-    m_timer->Start(200, false);    
-}
-
-void ComplexTransientPopup::StopTimer()
-{
-    if (m_timer) 
+    if (colour != m_mouseText->GetBackgroundColour())
     {
     {
-        if (m_timer->IsRunning()) 
-            m_timer->Stop();
-        delete m_timer;
-        m_timer = NULL;
-    }        
-}
-
-#else // USE_TIMER_TO_PUSHPOP
-void ComplexTransientPopup::OnIdle( wxIdleEvent& event )
-{
-    if (IsShown())
-    {
-        m_mouse = ScreenToClient(wxGetMousePosition());
-        wxLogMessage(wxT("CTW::OnIdle mouse(%d, %d), popped %d, m_handlerPopup %d"), m_mouse.x, m_mouse.y, m_popped_handler, m_handlerPopup);
-        
-        wxWindow *child = GetChild();
-        if (!child) return; // nothing to do
-    
-        wxRect clientRect(wxPoint(0,0), GetClientSize());
-        //wxPrintf(wxT("**DropDownPopup::OnIdle mouse %d %d -- %d %d %d\n"), m_mouse.x, m_mouse.y, m_popped_handler, m_child, m_handlerPopup); fflush(stdout);
-        // pop the event handler if inside the child window or 
-        // restore the event handler if not in the child window
-        if (clientRect.Inside(m_mouse))
-            PopPopupHandler(child);
-        else 
-            PushPopupHandler(child);
+        m_mouseText->SetBackgroundColour(colour);
+        m_mouseText->Refresh();
     }
     event.Skip();
 }
     }
     event.Skip();
 }
-#endif // USE_TIMER_TO_PUSHPOP
 
 
-void ComplexTransientPopup::OnMouse( wxMouseEvent& event )
+void SimpleTransientPopup::OnButton(wxCommandEvent& event)
 {
 {
-    m_mouse = event.GetPosition();
-    event.Skip();
-}
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnButton ID %d"), long(this), event.GetId());
 
 
-void ComplexTransientPopup::OnKeyDown( wxKeyEvent &event )
-{    
-    if (GetChild() && GetChild()->ProcessEvent(event))
-        event.Skip(false);
+    wxButton *button = wxDynamicCast(event.GetEventObject(), wxButton);
+    if (button->GetLabel() == wxT("Press Me"))
+        button->SetLabel(wxT("Pressed"));
     else
     else
-        event.Skip(true);
-}
-
-void ComplexTransientPopup::Popup(wxWindow *focus)
-{
-    SimpleTransientPopup::Popup(focus);
-    
-#if USE_TIMER_TO_PUSHPOP
-    // start the timer to track the mouse position
-    // note: idle function not used in this case
-    StartTimer();
-#else              
-    // note: all timer related functions aren't used in this case
-    Connect(wxID_ANY, wxEVT_IDLE,
-           (wxObjectEventFunction)(wxEventFunction)(wxIdleEventFunction)
-            &ComplexTransientPopup::OnIdle, 0, this);
-#endif // USE_TIMER_TO_PUSHPOP
-}
+        button->SetLabel(wxT("Press Me"));
 
 
-void ComplexTransientPopup::Dismiss()
-{
-#if USE_TIMER_TO_PUSHPOP
-    StopTimer();    
-#else // USE_TIMER_TO_PUSHPOP
-    Disconnect(wxID_ANY, wxEVT_IDLE, 
-               (wxObjectEventFunction)(wxEventFunction)(wxIdleEventFunction)
-               &ComplexTransientPopup::OnIdle, 0, this);
-#endif // USE_TIMER_TO_PUSHPOP
-    
-    // restore the event handler if necessary for the base class Dismiss
-    wxWindow *child = GetChild();
-    if (child) PushPopupHandler(child);
-
-    m_popped_handler = false;
-
-    SimpleTransientPopup::Dismiss();
+    event.Skip();
 }
 
 }
 
-bool ComplexTransientPopup::ProcessLeftDown( wxMouseEvent &event )
+void SimpleTransientPopup::OnSpinCtrl(wxSpinEvent& event)
 {
 {
-    m_mouse = event.GetPosition();
-    //wxPrintf(wxT("DropDownPopup::ProcessLeftDown %d %d\n"), m_mouse.x, m_mouse.y); fflush(stdout);
-    
-    if (m_popped_handler) return true; // shouldn't ever get here, but just in case
-
-#if USE_TIMER_TO_PUSHPOP
-    StopTimer();    
-#endif // USE_TIMER_TO_PUSHPOP
-    
-    // don't let the click on the dropdown button actually press it
-    // *** Here's where we stick code to ensure that if we click on a combobox
-    //     dropdown box we don't try to reshow this dialog because they intend 
-    //     hide it.
-    
-    if (wxRect(wxPoint(0,0), GetSize()).Inside(m_mouse))
-        return false;
-
-    Dismiss();
-    return true;
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSpinCtrl ID %d Value %d"),
+                  long(this), event.GetId(), event.GetInt());
+    event.Skip();
 }
 
 // ----------------------------------------------------------------------------
 // private classes
 // ----------------------------------------------------------------------------
 
 }
 
 // ----------------------------------------------------------------------------
 // private classes
 // ----------------------------------------------------------------------------
 
-class MyApp : public wxApp
-{
-public:
-    virtual bool OnInit();
-};
-
 class MyDialog : public wxDialog
 {
 public:
 class MyDialog : public wxDialog
 {
 public:
@@ -410,9 +264,10 @@ public:
 
     void OnStartSimplePopup(wxCommandEvent& event);
     void OnStartScrolledPopup(wxCommandEvent& event);
 
     void OnStartSimplePopup(wxCommandEvent& event);
     void OnStartScrolledPopup(wxCommandEvent& event);
-    void OnStartComplexPopup(wxCommandEvent& event);
 
 private:
 
 private:
+    SimpleTransientPopup *m_simplePopup;
+    SimpleTransientPopup *m_scrolledPopup;
     DECLARE_EVENT_TABLE()
 };
 
     DECLARE_EVENT_TABLE()
 };
 
@@ -422,34 +277,27 @@ public:
     MyFrame(const wxString& title);
     virtual ~MyFrame();
 
     MyFrame(const wxString& title);
     virtual ~MyFrame();
 
-    void CreatePanel(wxWindow* parent);
-
     void OnQuit(wxCommandEvent& event);
     void OnAbout(wxCommandEvent& event);
     void OnTestDialog(wxCommandEvent& event);
     void OnStartSimplePopup(wxCommandEvent& event);
     void OnStartScrolledPopup(wxCommandEvent& event);
     void OnQuit(wxCommandEvent& event);
     void OnAbout(wxCommandEvent& event);
     void OnTestDialog(wxCommandEvent& event);
     void OnStartSimplePopup(wxCommandEvent& event);
     void OnStartScrolledPopup(wxCommandEvent& event);
-    void OnStartComplexPopup(wxCommandEvent& event);
+    void OnActivate(wxActivateEvent& event);
 
 private:
 
 private:
+    SimpleTransientPopup *m_simplePopup;
+    SimpleTransientPopup *m_scrolledPopup;
+    wxTextCtrl *m_logWin;
     wxLog *m_logOld;
     DECLARE_EVENT_TABLE()
 };
 
     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_StartScrolledPopup,
-    Minimal_StartComplexPopup,
-    Minimal_LogWindow
+public:
+    virtual bool OnInit();
+
+    MyFrame *m_frame;
 };
 
 // ----------------------------------------------------------------------------
 };
 
 // ----------------------------------------------------------------------------
@@ -462,12 +310,15 @@ IMPLEMENT_APP(MyApp)
 // 'Main program' equivalent: the program execution "starts" here
 bool MyApp::OnInit()
 {
 // 'Main program' equivalent: the program execution "starts" here
 bool MyApp::OnInit()
 {
+    if ( !wxApp::OnInit() )
+        return false;
+
     // create the main application window
     // 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)
 
     // 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
 
     // success: wxApp::OnRun() will be called which will enter the main message
     // loop and the application will run. If we returned false here, the
@@ -483,14 +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_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_StartScrolledPopup, MyFrame::OnStartScrolledPopup)
     EVT_BUTTON(Minimal_StartSimplePopup, MyFrame::OnStartSimplePopup)
     EVT_BUTTON(Minimal_StartScrolledPopup, MyFrame::OnStartScrolledPopup)
-    EVT_BUTTON(Minimal_StartComplexPopup, MyFrame::OnStartComplexPopup)
 END_EVENT_TABLE()
 
 MyFrame::MyFrame(const wxString& title)
 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
     SetIcon(wxICON(sample));
 
 #if wxUSE_MENUS
@@ -498,90 +351,83 @@ MyFrame::MyFrame(const wxString& title)
 
     // the "About" item should be in the help menu
     wxMenu *helpMenu = new wxMenu;
 
     // 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();
 
     // 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
 
 
     // ... and attach this menu bar to the frame
     SetMenuBar(menuBar);
 #endif // wxUSE_MENUS
 
-    wxButton *button1 = new wxButton( this, Minimal_StartSimplePopup, wxT("Show simple popup"), wxPoint(20,20) );
-    wxButton *button2 = new wxButton( this, Minimal_StartScrolledPopup, wxT("Show scrolled popup"), wxPoint(20,70) );
-    wxButton *button3 = 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(wxT("Welcome to wxWidgets!"));
+#endif // wxUSE_STATUSBAR
 
 
-    wxTextCtrl* logWin = new wxTextCtrl( this, -1, wxEmptyString, wxDefaultPosition,
-                             wxDefaultSize, wxTE_MULTILINE );
-    wxLogTextCtrl* logger = new wxLogTextCtrl( logWin );
+    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 );
     m_logOld = logger->SetActiveTarget( logger );
-    logger->SetTimestamp( NULL );
-    
+    logger->DisableTimestamp();
+
     wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
     wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
-    topSizer->Add( button1, 0 );
-    topSizer->Add( button2, 0 );
-    topSizer->Add( button3, 0 );
-    topSizer->Add( logWin, 1, wxEXPAND );
+    topSizer->Add( button1, 0, wxALL, 5 );
+    topSizer->Add( button2, 0, wxALL, 5 );
+    topSizer->Add( m_logWin, 1, wxEXPAND|wxALL, 5 );
 
 
-    SetAutoLayout( true );
-    SetSizer( topSizer );
+    panel->SetSizer( topSizer );
 
 
-#if wxUSE_STATUSBAR
-    // create a status bar just for fun (by default with 1 pane only)
-    CreateStatusBar(2);
-    SetStatusText(_T("Welcome to wxWidgets!"));
-#endif // wxUSE_STATUSBAR
 }
 
 }
 
-MyFrame::~MyFrame() 
-{ 
-    delete wxLog::SetActiveTarget(m_logOld); 
-} 
+MyFrame::~MyFrame()
+{
+    delete wxLog::SetActiveTarget(m_logOld);
+}
 
 
 // event handlers
 
 
 
 // event handlers
 
-void MyFrame::OnStartSimplePopup(wxCommandEvent& event)
+void MyFrame::OnActivate(wxActivateEvent& WXUNUSED(event))
 {
 {
-    SimpleTransientPopup* popup = new SimpleTransientPopup( this );
-    wxWindow *btn = (wxWindow*) event.GetEventObject();
-    wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
-    wxSize sz = btn->GetSize();
-    popup->Position( pos, sz );
-    wxLogMessage( wxT("================================================") );
-    wxLogMessage( wxT("Simple Popup Shown pos(%d, %d) size(%d, %d)"), pos.x, pos.y, sz.x, sz.y );
-    popup->Popup();
+    wxLogMessage( wxT("In activate...") );
 }
 
 }
 
-void MyFrame::OnStartScrolledPopup(wxCommandEvent& event)
+void MyFrame::OnStartSimplePopup(wxCommandEvent& event)
 {
 {
-    SimpleTransientPopup* popup = new SimpleTransientPopup( this );
-    popup->GetChild()->SetScrollbars(1, 1, 1000, 1000);
+    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();
     wxWindow *btn = (wxWindow*) event.GetEventObject();
     wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
     wxSize sz = btn->GetSize();
-    popup->Position( pos, sz );
-    wxLogMessage( wxT("================================================") );
-    wxLogMessage( wxT("Scrolled Popup Shown pos(%d, %d) size(%d, %d)"), pos.x, pos.y, sz.x, sz.y );
-    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& event)
+void MyFrame::OnStartScrolledPopup(wxCommandEvent& event)
 {
 {
-    ComplexTransientPopup* popup = new ComplexTransientPopup( this );
-    popup->GetChild()->SetScrollbars(1, 1, 1000, 1000);
+    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();
     wxWindow *btn = (wxWindow*) event.GetEventObject();
     wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
     wxSize sz = btn->GetSize();
-    popup->Position( pos, sz );
-    wxLogMessage( wxT("================================================") );
-    wxLogMessage( wxT("Complex Popup Shown pos(%d, %d) size(%d, %d)"), pos.x, pos.y, sz.x, sz.y );
-    popup->Popup();
+    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))
 }
 
 void MyFrame::OnTestDialog(wxCommandEvent& WXUNUSED(event))
@@ -599,10 +445,10 @@ void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
 void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 {
     wxString msg;
 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);
 }
 
 // ----------------------------------------------------------------------------
 }
 
 // ----------------------------------------------------------------------------
@@ -612,55 +458,50 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 BEGIN_EVENT_TABLE(MyDialog, wxDialog)
     EVT_BUTTON(Minimal_StartSimplePopup, MyDialog::OnStartSimplePopup)
     EVT_BUTTON(Minimal_StartScrolledPopup, MyDialog::OnStartScrolledPopup)
 BEGIN_EVENT_TABLE(MyDialog, wxDialog)
     EVT_BUTTON(Minimal_StartSimplePopup, MyDialog::OnStartSimplePopup)
     EVT_BUTTON(Minimal_StartScrolledPopup, MyDialog::OnStartScrolledPopup)
-    EVT_BUTTON(Minimal_StartComplexPopup, MyDialog::OnStartComplexPopup)
 END_EVENT_TABLE()
 
 MyDialog::MyDialog(const wxString& title)
 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);
 
 
-    new wxButton( this, Minimal_StartSimplePopup, wxT("Show simple popup"), wxPoint(20,20) );
-    new wxButton( this, Minimal_StartScrolledPopup, wxT("Show scrolled popup"), wxPoint(20,60) );
-    new wxButton( this, Minimal_StartComplexPopup, wxT("Show complex popup"), wxPoint(20,100) );
+    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, wxID_OK, wxT("OK"), wxPoint(20,200) );
+    wxButton *okButton = new wxButton( panel, 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)
 {
 }
 
 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();
     wxWindow *btn = (wxWindow*) event.GetEventObject();
     wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
     wxSize sz = btn->GetSize();
-    popup->Position( pos, sz );
-    wxLogMessage( wxT("================================================") );
-    wxLogMessage( wxT("Dialog Simple Popup Shown pos(%d, %d) size(%d, %d)"), pos.x, pos.y, sz.x, sz.y );
-    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::OnStartScrolledPopup(wxCommandEvent& event)
 {
 }
 
 void MyDialog::OnStartScrolledPopup(wxCommandEvent& event)
 {
-    SimpleTransientPopup* popup = new SimpleTransientPopup( this );
-    popup->GetChild()->SetScrollbars(1, 1, 1000, 1000);
-    wxWindow *btn = (wxWindow*) event.GetEventObject();
-    wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
-    wxSize sz = btn->GetSize();
-    popup->Position( pos, sz );
     wxLogMessage( wxT("================================================") );
     wxLogMessage( wxT("================================================") );
-    wxLogMessage( wxT("Dialog Scrolled Popup Shown pos(%d, %d) size(%d, %d)"), pos.x, pos.y, sz.x, sz.y );
-    popup->Popup();
-}
-
-void MyDialog::OnStartComplexPopup(wxCommandEvent& event)
-{
-    ComplexTransientPopup* popup = new ComplexTransientPopup( this );
-    popup->GetChild()->SetScrollbars(1, 1, 1000, 1000);
+    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();
     wxWindow *btn = (wxWindow*) event.GetEventObject();
     wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
     wxSize sz = btn->GetSize();
-    popup->Position( pos, sz );
-    wxLogMessage( wxT("================================================") );
-    wxLogMessage( wxT("Dialog Complex Popup Shown pos(%d, %d) size(%d, %d)"), pos.x, pos.y, sz.x, sz.y );
-    popup->Popup();
+    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();
 }
 }
-