]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/popup/popup.cpp
wxAUI: fixed pane saving design thinko
[wxWidgets.git] / samples / popup / popup.cpp
index 973ba33b984bfff26eb517112a8e1377da71a011..0306e91ccf2748c3c72aaf561a0e5cdece5092f3 100644 (file)
@@ -31,6 +31,7 @@
 #endif
 
 #include "wx/popupwin.h"
+#include "wx/spinctrl.h"
 
 // ----------------------------------------------------------------------------
 // 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
 //----------------------------------------------------------------------------
@@ -61,12 +79,17 @@ public:
 
 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 );
+    void OnButton( wxCommandEvent& event );
+    void OnSpinCtrl( wxSpinEvent& event );
 
 private:
     DECLARE_CLASS(SimpleTransientPopup)
@@ -83,23 +106,46 @@ 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 )
+                     :wxPopupTransientWindow( parent )
 {
     m_panel = new wxScrolledWindow( this, wxID_ANY );
     m_panel->SetBackgroundColour( *wxLIGHT_GREY );
+
+    // 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("wx.PopupTransientWindow is a\n")
                           wxT("wx.PopupWindow 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 );
+
+    m_panel->SetAutoLayout( true );
+    m_panel->SetSizer( topSizer );
+    topSizer->Fit(m_panel);
+    topSizer->Fit(this);
 }
 
 SimpleTransientPopup::~SimpleTransientPopup()
@@ -108,301 +154,89 @@ SimpleTransientPopup::~SimpleTransientPopup()
 
 void SimpleTransientPopup::Popup(wxWindow *focus)
 {
-    wxLogMessage( wxT("SimpleTransientPopup::Popup"));
-    wxPopupTransientWindow::Popup(focus);
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::Popup"), long(this) );
+    wxPopupTransientWindow::Popup(focus ? focus : m_panel);
 }
 
 void SimpleTransientPopup::OnDismiss()
 {
-    wxLogMessage( wxT("SimpleTransientPopup::OnDismiss"));
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnDismiss"), long(this) );
     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 )
 {
-    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)
 {
-    wxLogMessage( wxT("SimpleTransientPopup::OnSize"));
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSize"), long(this) );
     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)
 {
-    wxLogMessage( wxT("SimpleTransientPopup::OnKillFocus"));
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnKillFocus"), long(this) );
     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)
-    {
-        Init();
+    if (rect.Inside(event.GetPosition()))
+    {       
+        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)
+    if (colour != m_mouseText->GetBackgroundColour())
     {
-        m_popped_handler = true;
-
-        if (child->GetEventHandler() == (wxEvtHandler*)m_handlerPopup)
-            child->PopEventHandler(false);
-        if (child->HasCapture())
-            child->ReleaseMouse();
-
-        child->SetFocus();
+        m_mouseText->SetBackgroundColour(colour);
+        m_mouseText->Refresh();
     }
+    event.Skip();
 }
 
-#if USE_TIMER_TO_PUSHPOP
-void ComplexTransientPopup::OnTimer( wxTimerEvent &WXUNUSED(event) )
+void SimpleTransientPopup::OnButton(wxCommandEvent& event)
 {
-    if (!IsShown()) return;
-
-    m_mouse = ScreenToClient(wxGetMousePosition());
-
-    wxWindow *child = GetChild();
-    if (!child) return; // nothing to do
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnButton ID %d"), long(this), event.GetId());
 
-    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);
+    wxButton *button = wxDynamicCast(event.GetEventObject(), wxButton);
+    if (button->GetLabel() == wxT("Press Me"))
+        button->SetLabel(wxT("Pressed"));
     else
-        PushPopupHandler(child);
-}
-
-void ComplexTransientPopup::StartTimer()
-{
-    if (!m_timer)
-        m_timer = new wxTimer(this, wxID_ANY);
-
-    m_timer->Start(200, false);
-}
+        button->SetLabel(wxT("Press Me"));
 
-void ComplexTransientPopup::StopTimer()
-{
-    if (m_timer)
-    {
-        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(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);
-    }
     event.Skip();
 }
-#endif // USE_TIMER_TO_PUSHPOP
 
-void ComplexTransientPopup::OnMouse( wxMouseEvent& event )
+void SimpleTransientPopup::OnSpinCtrl(wxSpinEvent& event)
 {
-    m_mouse = event.GetPosition();
+    wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSpinCtrl ID %d Value %ld"), long(this), event.GetId(), event.GetInt());
     event.Skip();
 }
 
-void ComplexTransientPopup::OnKeyDown( wxKeyEvent &event )
-{
-    if (GetChild() && GetChild()->ProcessEvent(event))
-        event.Skip(false);
-    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
-}
-
-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();
-}
-
-bool ComplexTransientPopup::ProcessLeftDown( wxMouseEvent &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;
-}
-
 // ----------------------------------------------------------------------------
 // private classes
 // ----------------------------------------------------------------------------
 
-class MyApp : public wxApp
-{
-public:
-    virtual bool OnInit();
-};
-
 class MyDialog : public wxDialog
 {
 public:
@@ -410,9 +244,10 @@ public:
 
     void OnStartSimplePopup(wxCommandEvent& event);
     void OnStartScrolledPopup(wxCommandEvent& event);
-    void OnStartComplexPopup(wxCommandEvent& event);
 
 private:
+    SimpleTransientPopup *m_simplePopup;
+    SimpleTransientPopup *m_scrolledPopup;
     DECLARE_EVENT_TABLE()
 };
 
@@ -422,34 +257,26 @@ public:
     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 OnStartComplexPopup(wxCommandEvent& 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_StartScrolledPopup,
-    Minimal_StartComplexPopup,
-    Minimal_LogWindow
+public:
+    virtual bool OnInit();
+
+    MyFrame *m_frame;
 };
 
 // ----------------------------------------------------------------------------
@@ -463,11 +290,11 @@ IMPLEMENT_APP(MyApp)
 bool MyApp::OnInit()
 {
     // create the main application window
-    MyFrame *frame = new MyFrame(_T("Popup wxWidgets App"));
+    m_frame = new MyFrame(_T("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
@@ -485,12 +312,13 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(Minimal_TestDialog, MyFrame::OnTestDialog)
     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)
        : wxFrame(NULL, wxID_ANY, title)
 {
+    m_simplePopup = m_scrolledPopup = NULL;
+
     SetIcon(wxICON(sample));
 
 #if wxUSE_MENUS
@@ -512,30 +340,31 @@ MyFrame::MyFrame(const wxString& title)
     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(_T("Welcome to wxWidgets!"));
+#endif // wxUSE_STATUSBAR
 
-    wxTextCtrl* logWin = new wxTextCtrl( this, wxID_ANY, 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 );
     logger->SetTimestamp( NULL );
 
     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->SetAutoLayout( true );
+    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()
@@ -548,40 +377,29 @@ MyFrame::~MyFrame()
 
 void MyFrame::OnStartSimplePopup(wxCommandEvent& event)
 {
-    SimpleTransientPopup* popup = new SimpleTransientPopup( this );
+    wxLogMessage( wxT("================================================") );
+    delete m_simplePopup;
+    m_simplePopup = 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();
+    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::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("Scrolled Popup Shown pos(%d, %d) size(%d, %d)"), pos.x, pos.y, sz.x, sz.y );
-    popup->Popup();
-}
-
-void MyFrame::OnStartComplexPopup(wxCommandEvent& event)
-{
-    ComplexTransientPopup* popup = new ComplexTransientPopup( this );
-    popup->GetChild()->SetScrollbars(1, 1, 1000, 1000);
+    delete m_scrolledPopup;
+    m_scrolledPopup = new SimpleTransientPopup( this );
+    m_scrolledPopup->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("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))
@@ -612,55 +430,53 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
 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)
-       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_StartScrolledPopup, wxT("Show scrolled popup"), wxPoint(20,60) );
-    new wxButton( this, Minimal_StartComplexPopup, wxT("Show complex popup"), wxPoint(20,100) );
+    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->SetAutoLayout( true );
+    panel->SetSizer( topSizer );
+    topSizer->Fit(this);
 }
 
 void MyDialog::OnStartSimplePopup(wxCommandEvent& event)
 {
-    SimpleTransientPopup* popup = new SimpleTransientPopup( this );
+    wxLogMessage( wxT("================================================") );
+    delete m_simplePopup;
+    m_simplePopup = 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("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)
 {
-    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("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 );
+    m_scrolledPopup->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("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();
 }
-