]> git.saurik.com Git - wxWidgets.git/blame - samples/popup/popup.cpp
corrected crash: need to set m_frame eariler (Wlodek Szafran, closes bug 1636225)
[wxWidgets.git] / samples / popup / popup.cpp
CommitLineData
98d5b42b
RR
1/////////////////////////////////////////////////////////////////////////////
2// Name: minimal.cpp
3// Purpose: Popup wxWidgets sample
43f813d1 4// Author: Robert Roebling
98d5b42b 5// Modified by:
43f813d1 6// Created: 2005-02-04
98d5b42b 7// RCS-ID: $Id$
43f813d1 8// Copyright: (c) 2005 Robert Roebling
98d5b42b
RR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
20// For compilers that support precompilation, includes "wx/wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
24 #pragma hdrstop
25#endif
26
27// for all others, include the necessary headers (this file is usually all you
28// need because it includes almost all "standard" wxWidgets headers)
29#ifndef WX_PRECOMP
30 #include "wx/wx.h"
31#endif
32
33#include "wx/popupwin.h"
b6de8445 34#include "wx/spinctrl.h"
98d5b42b
RR
35
36// ----------------------------------------------------------------------------
37// resources
38// ----------------------------------------------------------------------------
39
40// the application icon (under Windows and OS/2 it is in resources and even
41// though we could still include the XPM here it would be unused)
42#if !defined(__WXMSW__) && !defined(__WXPM__)
43 #include "../sample.xpm"
44#endif
45
b6de8445
RR
46// ----------------------------------------------------------------------------
47// constants
48// ----------------------------------------------------------------------------
49
50// IDs for the controls and the menu commands
51enum
52{
53 Minimal_Quit = wxID_EXIT,
54 Minimal_About = wxID_ABOUT,
55 Minimal_TestDialog,
56 Minimal_StartSimplePopup,
57 Minimal_StartScrolledPopup,
58 Minimal_LogWindow,
59 Minimal_PopupButton,
60 Minimal_PopupSpinctrl
61};
62
34786588
VZ
63//----------------------------------------------------------------------------
64// SimpleTransientPopup
65//----------------------------------------------------------------------------
98d5b42b
RR
66class SimpleTransientPopup: public wxPopupTransientWindow
67{
68public:
69 SimpleTransientPopup( wxWindow *parent );
70 virtual ~SimpleTransientPopup();
34786588
VZ
71
72 // wxPopupTransientWindow virtual methods are all overridden to log them
73 virtual void Popup(wxWindow *focus = NULL);
74 virtual void OnDismiss();
75 virtual bool ProcessLeftDown(wxMouseEvent& event);
76 virtual bool Show( bool show = true );
dd6a7fb4 77
34786588 78 wxScrolledWindow* GetChild() { return m_panel; }
dd6a7fb4 79
98d5b42b 80private:
34786588 81 wxScrolledWindow *m_panel;
b6de8445
RR
82 wxButton *m_button;
83 wxSpinCtrl *m_spinCtrl;
414f2513 84 wxStaticText *m_mouseText;
dd6a7fb4 85
98d5b42b
RR
86private:
87 void OnMouse( wxMouseEvent &event );
88 void OnSize( wxSizeEvent &event );
89 void OnSetFocus( wxFocusEvent &event );
90 void OnKillFocus( wxFocusEvent &event );
b6de8445
RR
91 void OnButton( wxCommandEvent& event );
92 void OnSpinCtrl( wxSpinEvent& event );
98d5b42b
RR
93
94private:
95 DECLARE_CLASS(SimpleTransientPopup)
96 DECLARE_EVENT_TABLE()
97};
98
98d5b42b
RR
99//----------------------------------------------------------------------------
100// SimpleTransientPopup
101//----------------------------------------------------------------------------
98d5b42b
RR
102IMPLEMENT_CLASS(SimpleTransientPopup,wxPopupTransientWindow)
103
104BEGIN_EVENT_TABLE(SimpleTransientPopup,wxPopupTransientWindow)
105 EVT_MOUSE_EVENTS( SimpleTransientPopup::OnMouse )
106 EVT_SIZE( SimpleTransientPopup::OnSize )
107 EVT_SET_FOCUS( SimpleTransientPopup::OnSetFocus )
108 EVT_KILL_FOCUS( SimpleTransientPopup::OnKillFocus )
b6de8445
RR
109 EVT_BUTTON( Minimal_PopupButton, SimpleTransientPopup::OnButton )
110 EVT_SPINCTRL( Minimal_PopupSpinctrl, SimpleTransientPopup::OnSpinCtrl )
98d5b42b
RR
111END_EVENT_TABLE()
112
82ceade7
RD
113SimpleTransientPopup::SimpleTransientPopup( wxWindow *parent )
114 :wxPopupTransientWindow( parent )
98d5b42b 115{
dd6a7fb4 116 m_panel = new wxScrolledWindow( this, wxID_ANY );
98d5b42b 117 m_panel->SetBackgroundColour( *wxLIGHT_GREY );
82ceade7
RD
118
119 // Keep this code to verify if mouse events work, they're required if
120 // you're making a control like a combobox where the items are highlighted
121 // under the cursor, the m_panel is set focus in the Popup() function
414f2513
RD
122 m_panel->Connect(wxEVT_MOTION,
123 wxMouseEventHandler(SimpleTransientPopup::OnMouse),
124 NULL, this);
82ceade7 125
dd6a7fb4 126 wxStaticText *text = new wxStaticText( m_panel, wxID_ANY,
98d5b42b
RR
127 wxT("wx.PopupTransientWindow is a\n")
128 wxT("wx.PopupWindow which disappears\n")
129 wxT("automatically when the user\n")
130 wxT("clicks the mouse outside it or if it\n")
131 wxT("(or its first child) loses focus in \n")
414f2513 132 wxT("any other way.") );
b6de8445 133
414f2513
RD
134 m_button = new wxButton(m_panel, Minimal_PopupButton, wxT("Press Me"));
135 m_spinCtrl = new wxSpinCtrl(m_panel, Minimal_PopupSpinctrl, wxT("Hello"));
136 m_mouseText = new wxStaticText(m_panel, wxID_ANY,
137 wxT("<- Test Mouse ->"));
21fe01e2 138
414f2513
RD
139 wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
140 topSizer->Add( text, 0, wxALL, 5 );
141 topSizer->Add( m_button, 0, wxALL, 5 );
142 topSizer->Add( m_spinCtrl, 0, wxALL, 5 );
143 topSizer->Add( m_mouseText, 0, wxCENTRE|wxALL, 5 );
144
145 m_panel->SetAutoLayout( true );
146 m_panel->SetSizer( topSizer );
147 topSizer->Fit(m_panel);
148 topSizer->Fit(this);
98d5b42b
RR
149}
150
151SimpleTransientPopup::~SimpleTransientPopup()
152{
153}
154
34786588
VZ
155void SimpleTransientPopup::Popup(wxWindow *focus)
156{
5c95f4b2 157 wxLogMessage( wxT("0x%lx SimpleTransientPopup::Popup"), long(this) );
82ceade7 158 wxPopupTransientWindow::Popup(focus ? focus : m_panel);
34786588
VZ
159}
160
98d5b42b
RR
161void SimpleTransientPopup::OnDismiss()
162{
5c95f4b2 163 wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnDismiss"), long(this) );
34786588
VZ
164 wxPopupTransientWindow::OnDismiss();
165}
166
167bool SimpleTransientPopup::ProcessLeftDown(wxMouseEvent& event)
168{
5c95f4b2 169 wxLogMessage( wxT("0x%lx SimpleTransientPopup::ProcessLeftDown pos(%d, %d)"), long(this), event.GetX(), event.GetY());
34786588
VZ
170 return wxPopupTransientWindow::ProcessLeftDown(event);
171}
172bool SimpleTransientPopup::Show( bool show )
173{
5c95f4b2 174 wxLogMessage( wxT("0x%lx SimpleTransientPopup::Show %d"), long(this), int(show));
34786588 175 return wxPopupTransientWindow::Show(show);
98d5b42b
RR
176}
177
178void SimpleTransientPopup::OnSize(wxSizeEvent &event)
179{
5c95f4b2 180 wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSize"), long(this) );
98d5b42b
RR
181 event.Skip();
182}
183
184void SimpleTransientPopup::OnSetFocus(wxFocusEvent &event)
185{
5c95f4b2 186 wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSetFocus"), long(this) );
43f813d1 187 event.Skip();
98d5b42b
RR
188}
189
190void SimpleTransientPopup::OnKillFocus(wxFocusEvent &event)
191{
5c95f4b2 192 wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnKillFocus"), long(this) );
43f813d1 193 event.Skip();
98d5b42b
RR
194}
195
196void SimpleTransientPopup::OnMouse(wxMouseEvent &event)
197{
414f2513
RD
198 wxRect rect(m_mouseText->GetRect());
199 rect.SetX(-100000);
200 rect.SetWidth(1000000);
201 wxColour colour(*wxLIGHT_GREY);
202
50dd4ca9 203 if (rect.Contains(event.GetPosition()))
414f2513
RD
204 {
205 colour = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
82ceade7 206 wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnMouse pos(%d, %d)"), long(event.GetEventObject()), event.GetX(), event.GetY());
414f2513
RD
207 }
208
209 if (colour != m_mouseText->GetBackgroundColour())
210 {
211 m_mouseText->SetBackgroundColour(colour);
212 m_mouseText->Refresh();
213 }
34786588
VZ
214 event.Skip();
215}
216
b6de8445 217void SimpleTransientPopup::OnButton(wxCommandEvent& event)
34786588 218{
5c95f4b2 219 wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnButton ID %d"), long(this), event.GetId());
dd6a7fb4 220
b6de8445
RR
221 wxButton *button = wxDynamicCast(event.GetEventObject(), wxButton);
222 if (button->GetLabel() == wxT("Press Me"))
223 button->SetLabel(wxT("Pressed"));
dd6a7fb4 224 else
b6de8445 225 button->SetLabel(wxT("Press Me"));
34786588 226
34786588
VZ
227 event.Skip();
228}
34786588 229
b6de8445 230void SimpleTransientPopup::OnSpinCtrl(wxSpinEvent& event)
34786588 231{
b143cf70 232 wxLogMessage( wxT("0x%lx SimpleTransientPopup::OnSpinCtrl ID %d Value %d"), long(this), event.GetId(), event.GetInt());
98d5b42b
RR
233 event.Skip();
234}
235
236// ----------------------------------------------------------------------------
237// private classes
238// ----------------------------------------------------------------------------
239
98d5b42b
RR
240class MyDialog : public wxDialog
241{
242public:
243 MyDialog(const wxString& title);
244
245 void OnStartSimplePopup(wxCommandEvent& event);
34786588 246 void OnStartScrolledPopup(wxCommandEvent& event);
98d5b42b
RR
247
248private:
82ceade7
RD
249 SimpleTransientPopup *m_simplePopup;
250 SimpleTransientPopup *m_scrolledPopup;
98d5b42b
RR
251 DECLARE_EVENT_TABLE()
252};
253
254class MyFrame : public wxFrame
255{
256public:
257 MyFrame(const wxString& title);
34786588
VZ
258 virtual ~MyFrame();
259
98d5b42b
RR
260 void OnQuit(wxCommandEvent& event);
261 void OnAbout(wxCommandEvent& event);
262 void OnTestDialog(wxCommandEvent& event);
263 void OnStartSimplePopup(wxCommandEvent& event);
34786588 264 void OnStartScrolledPopup(wxCommandEvent& event);
98d5b42b
RR
265
266private:
82ceade7
RD
267 SimpleTransientPopup *m_simplePopup;
268 SimpleTransientPopup *m_scrolledPopup;
b6de8445 269 wxTextCtrl *m_logWin;
34786588 270 wxLog *m_logOld;
98d5b42b
RR
271 DECLARE_EVENT_TABLE()
272};
273
b6de8445 274class MyApp : public wxApp
98d5b42b 275{
b6de8445
RR
276public:
277 virtual bool OnInit();
278
279 MyFrame *m_frame;
98d5b42b
RR
280};
281
282// ----------------------------------------------------------------------------
283// event tables and other macros for wxWidgets
284// ----------------------------------------------------------------------------
285
286
287IMPLEMENT_APP(MyApp)
288
289// 'Main program' equivalent: the program execution "starts" here
290bool MyApp::OnInit()
291{
292 // create the main application window
b6de8445 293 m_frame = new MyFrame(_T("Popup wxWidgets App"));
98d5b42b
RR
294
295 // and show it (the frames, unlike simple controls, are not shown when
296 // created initially)
b6de8445 297 m_frame->Show(true);
98d5b42b
RR
298
299 // success: wxApp::OnRun() will be called which will enter the main message
300 // loop and the application will run. If we returned false here, the
301 // application would exit immediately.
302 return true;
303}
304
305// ----------------------------------------------------------------------------
306// main frame
307// ----------------------------------------------------------------------------
308
309BEGIN_EVENT_TABLE(MyFrame, wxFrame)
310 EVT_MENU(Minimal_Quit, MyFrame::OnQuit)
311 EVT_MENU(Minimal_About, MyFrame::OnAbout)
312 EVT_MENU(Minimal_TestDialog, MyFrame::OnTestDialog)
313 EVT_BUTTON(Minimal_StartSimplePopup, MyFrame::OnStartSimplePopup)
34786588 314 EVT_BUTTON(Minimal_StartScrolledPopup, MyFrame::OnStartScrolledPopup)
98d5b42b
RR
315END_EVENT_TABLE()
316
317MyFrame::MyFrame(const wxString& title)
318 : wxFrame(NULL, wxID_ANY, title)
319{
82ceade7
RD
320 m_simplePopup = m_scrolledPopup = NULL;
321
98d5b42b
RR
322 SetIcon(wxICON(sample));
323
324#if wxUSE_MENUS
325 wxMenu *menuFile = new wxMenu;
326
327 // the "About" item should be in the help menu
328 wxMenu *helpMenu = new wxMenu;
329 helpMenu->Append(Minimal_About, _T("&About...\tF1"), _T("Show about dialog"));
330
331 menuFile->Append(Minimal_TestDialog, _T("&Test dialog\tAlt-T"), _T("Test dialog"));
332 menuFile->Append(Minimal_Quit, _T("E&xit\tAlt-X"), _T("Quit this program"));
333
334 // now append the freshly created menu to the menu bar...
335 wxMenuBar *menuBar = new wxMenuBar();
336 menuBar->Append(menuFile, _T("&File"));
337 menuBar->Append(helpMenu, _T("&Help"));
338
339 // ... and attach this menu bar to the frame
340 SetMenuBar(menuBar);
341#endif // wxUSE_MENUS
342
414f2513
RD
343#if wxUSE_STATUSBAR
344 // create a status bar just for fun (by default with 1 pane only)
345 CreateStatusBar(2);
346 SetStatusText(_T("Welcome to wxWidgets!"));
347#endif // wxUSE_STATUSBAR
348
82ceade7
RD
349 wxPanel *panel = new wxPanel(this, -1);
350 wxButton *button1 = new wxButton( panel, Minimal_StartSimplePopup, wxT("Show simple popup"), wxPoint(20,20) );
351 wxButton *button2 = new wxButton( panel, Minimal_StartScrolledPopup, wxT("Show scrolled popup"), wxPoint(20,70) );
34786588 352
82ceade7
RD
353 m_logWin = new wxTextCtrl( panel, wxID_ANY, wxEmptyString, wxDefaultPosition,
354 wxDefaultSize, wxTE_MULTILINE );
b6de8445
RR
355 m_logWin->SetEditable(false);
356 wxLogTextCtrl* logger = new wxLogTextCtrl( m_logWin );
34786588
VZ
357 m_logOld = logger->SetActiveTarget( logger );
358 logger->SetTimestamp( NULL );
dd6a7fb4 359
34786588 360 wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
82ceade7
RD
361 topSizer->Add( button1, 0, wxALL, 5 );
362 topSizer->Add( button2, 0, wxALL, 5 );
363 topSizer->Add( m_logWin, 1, wxEXPAND|wxALL, 5 );
98d5b42b 364
82ceade7
RD
365 panel->SetAutoLayout( true );
366 panel->SetSizer( topSizer );
98d5b42b 367
98d5b42b
RR
368}
369
dd6a7fb4
WS
370MyFrame::~MyFrame()
371{
372 delete wxLog::SetActiveTarget(m_logOld);
373}
34786588
VZ
374
375
98d5b42b
RR
376// event handlers
377
378void MyFrame::OnStartSimplePopup(wxCommandEvent& event)
379{
b6de8445 380 wxLogMessage( wxT("================================================") );
82ceade7
RD
381 delete m_simplePopup;
382 m_simplePopup = new SimpleTransientPopup( this );
98d5b42b
RR
383 wxWindow *btn = (wxWindow*) event.GetEventObject();
384 wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
385 wxSize sz = btn->GetSize();
82ceade7
RD
386 m_simplePopup->Position( pos, sz );
387 wxLogMessage( wxT("0x%lx Simple Popup Shown pos(%d, %d) size(%d, %d)"), long(m_simplePopup), pos.x, pos.y, sz.x, sz.y );
388 m_simplePopup->Popup();
98d5b42b
RR
389}
390
34786588 391void MyFrame::OnStartScrolledPopup(wxCommandEvent& event)
98d5b42b 392{
34786588 393 wxLogMessage( wxT("================================================") );
82ceade7
RD
394 delete m_scrolledPopup;
395 m_scrolledPopup = new SimpleTransientPopup( this );
396 m_scrolledPopup->GetChild()->SetScrollbars(1, 1, 1000, 1000);
34786588
VZ
397 wxWindow *btn = (wxWindow*) event.GetEventObject();
398 wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
399 wxSize sz = btn->GetSize();
82ceade7
RD
400 m_scrolledPopup->Position( pos, sz );
401 wxLogMessage( wxT("0x%lx Scrolled Popup Shown pos(%d, %d) size(%d, %d)"), long(m_scrolledPopup), pos.x, pos.y, sz.x, sz.y );
402 m_scrolledPopup->Popup();
98d5b42b
RR
403}
404
405void MyFrame::OnTestDialog(wxCommandEvent& WXUNUSED(event))
406{
407 MyDialog dialog( wxT("Test") );
408 dialog.ShowModal();
409}
410
411void MyFrame::OnQuit(wxCommandEvent& WXUNUSED(event))
412{
413 // true is to force the frame to close
414 Close(true);
415}
416
417void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
418{
419 wxString msg;
420 msg.Printf( _T("This is the About dialog of the popup sample.\n")
421 _T("Welcome to %s"), wxVERSION_STRING);
422
423 wxMessageBox(msg, _T("About Popup"), wxOK | wxICON_INFORMATION, this);
424}
425
426// ----------------------------------------------------------------------------
427// test dialog
428// ----------------------------------------------------------------------------
429
430BEGIN_EVENT_TABLE(MyDialog, wxDialog)
431 EVT_BUTTON(Minimal_StartSimplePopup, MyDialog::OnStartSimplePopup)
34786588 432 EVT_BUTTON(Minimal_StartScrolledPopup, MyDialog::OnStartScrolledPopup)
98d5b42b
RR
433END_EVENT_TABLE()
434
435MyDialog::MyDialog(const wxString& title)
82ceade7 436 :wxDialog(NULL, wxID_ANY, title, wxPoint(50,50), wxSize(400,300))
98d5b42b 437{
82ceade7
RD
438 m_simplePopup = m_scrolledPopup = NULL;
439 wxPanel *panel = new wxPanel(this, -1);
98d5b42b 440
82ceade7
RD
441 wxButton *button1 = new wxButton( panel, Minimal_StartSimplePopup, wxT("Show simple popup"), wxPoint(20,20) );
442 wxButton *button2 = new wxButton( panel, Minimal_StartScrolledPopup, wxT("Show scrolled popup"), wxPoint(20,60) );
98d5b42b 443
82ceade7
RD
444 wxButton *okButton = new wxButton( panel, wxID_OK, wxT("OK"), wxPoint(20,200) );
445
446 wxBoxSizer *topSizer = new wxBoxSizer( wxVERTICAL );
447 topSizer->Add( button1, 0, wxALL, 5 );
448 topSizer->Add( button2, 0, wxALL, 5 );
449 topSizer->AddSpacer(40);
450 topSizer->Add( okButton, 0, wxALL, 5 );
451
452 panel->SetAutoLayout( true );
453 panel->SetSizer( topSizer );
454 topSizer->Fit(this);
98d5b42b
RR
455}
456
457void MyDialog::OnStartSimplePopup(wxCommandEvent& event)
458{
b6de8445 459 wxLogMessage( wxT("================================================") );
82ceade7
RD
460 delete m_simplePopup;
461 m_simplePopup = new SimpleTransientPopup( this );
98d5b42b
RR
462 wxWindow *btn = (wxWindow*) event.GetEventObject();
463 wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
464 wxSize sz = btn->GetSize();
82ceade7
RD
465 m_simplePopup->Position( pos, sz );
466 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 );
467 m_simplePopup->Popup();
98d5b42b
RR
468}
469
34786588 470void MyDialog::OnStartScrolledPopup(wxCommandEvent& event)
98d5b42b 471{
34786588 472 wxLogMessage( wxT("================================================") );
82ceade7
RD
473 delete m_scrolledPopup;
474 m_scrolledPopup = new SimpleTransientPopup( this );
475 m_scrolledPopup->GetChild()->SetScrollbars(1, 1, 1000, 1000);
34786588
VZ
476 wxWindow *btn = (wxWindow*) event.GetEventObject();
477 wxPoint pos = btn->ClientToScreen( wxPoint(0,0) );
478 wxSize sz = btn->GetSize();
82ceade7
RD
479 m_scrolledPopup->Position( pos, sz );
480 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 );
481 m_scrolledPopup->Popup();
98d5b42b 482}