]> git.saurik.com Git - wxWidgets.git/commitdiff
Show the order in which different event handlers are called.
authorVadim Zeitlin <vadim@wxwidgets.org>
Mon, 7 Sep 2009 23:00:21 +0000 (23:00 +0000)
committerVadim Zeitlin <vadim@wxwidgets.org>
Mon, 7 Sep 2009 23:00:21 +0000 (23:00 +0000)
Update the event sample to define (as) many (as possible) event handlers for a
test button and log messages in all of the handlers to leave a trace of the
order in which they were executed.

Add a pointer to this feature of the event sample to the events overview.

Closes #11156.

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61852 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

docs/doxygen/overviews/eventhandling.h
samples/event/event.cpp

index e671bb84d080b2457a63cfd739245deaff769d06..05ad03f49ad1a75de4714f4db07359eae8831459 100644 (file)
@@ -428,7 +428,10 @@ in simple situations where this extra flexibility is not needed.
 
 The previous sections explain how to define event handlers but don't address
 the question of how exactly wxWidgets finds the handler to call for the
-given event. This section describes the algorithm used in detail.
+given event. This section describes the algorithm used in detail. Notice that
+you may want to run the @ref page_samples_event while reading this section and
+look at its code and the output when the button which can be used to test the
+event handlers execution order is clicked to understand it better.
 
 When an event is received from the windowing system, wxWidgets calls
 wxEvtHandler::ProcessEvent() on the first event handler object belonging to the
@@ -454,7 +457,7 @@ doesn't count as having handled the event and the search continues):
     </li>
 
     <li value="3">
-    The list of dynamically bind event handlers, i.e., those for which
+    The list of dynamically bound event handlers, i.e., those for which
     Bind<>() was called, is consulted. Notice that this is done before
     checking the static event table entries, so if both a dynamic and a static
     event handler match the same event, the static one is never going to be
index d2b7679af15a20def4c5d51fddb015f5194d5159..1ddacb0430f95c1f73a107465a6fdfdcf74fd608 100644 (file)
@@ -34,6 +34,9 @@
     #include "../sample.xpm"
 #endif
 
+#include <wx/statline.h>
+#include <wx/log.h>
+
 // ----------------------------------------------------------------------------
 // event constants
 // ----------------------------------------------------------------------------
@@ -65,8 +68,56 @@ public:
     // initialization (doing it here and not in the ctor allows to have an error
     // return: if OnInit() returns false, the application terminates)
     virtual bool OnInit();
+
+    // these are regular event handlers used to highlight the events handling
+    // order
+    void OnClickDynamicHandlerApp(wxCommandEvent& event);
+    void OnClickStaticHandlerApp(wxCommandEvent& event);
+
+    // we override wxConsoleApp::FilterEvent used to highlight the events
+    // handling order
+    virtual int FilterEvent(wxEvent& event);
+
+private:
+    DECLARE_EVENT_TABLE()
 };
 
+// Define a custom button used to highlight the events handling order
+class MyEvtTestButton : public wxButton
+{
+public:
+    static long BUTTON_ID;
+
+    MyEvtTestButton(wxWindow *parent, const wxString& label)
+        : wxButton(parent, BUTTON_ID, label)
+    {
+        // Add a dynamic handler for this button event to button itself
+        Connect(wxEVT_COMMAND_BUTTON_CLICKED,
+                wxCommandEventHandler(MyEvtTestButton::OnClickDynamicHandler));
+    }
+
+private:
+    void OnClickDynamicHandler(wxCommandEvent& event)
+    {
+        wxLogMessage("Step 3 in \"How Events are Processed\":\n"
+                     "Button::ownDynamicHandler");
+
+        event.Skip();
+    }
+
+    void OnClickStaticHandler(wxCommandEvent& event)
+    {
+        wxLogMessage("Step 4 in \"How Events are Processed\":\n"
+                     "Button::ownStaticHandler");
+
+        event.Skip();
+    }
+
+    DECLARE_EVENT_TABLE()
+};
+
+long MyEvtTestButton::BUTTON_ID = wxNewId();
+
 // Define a new frame type: this is going to be our main frame
 class MyFrame : public wxFrame
 {
@@ -91,6 +142,11 @@ public:
 
     void OnUpdateUIPop(wxUpdateUIEvent& event);
 
+    // regular event handlers used to highlight the events handling order
+    void OnClickDynamicHandlerFrame(wxCommandEvent& event);
+    void OnClickDynamicHandlerButton(wxCommandEvent& event);
+    void OnClickStaticHandlerFrame(wxCommandEvent& event);
+
 private:
     // symbolic names for the status bar fields
     enum
@@ -122,6 +178,10 @@ private:
     // the button to whose event we connect dynamically
     wxButton *m_btnDynamic;
 
+    // the button used to highlight the event handlers execution order
+    MyEvtTestButton *m_testBtn;
+
+
     // any class wishing to process wxWidgets events must use this macro
     DECLARE_EVENT_TABLE()
 };
@@ -170,8 +230,19 @@ enum
 // event tables and other macros for wxWidgets
 // ----------------------------------------------------------------------------
 
-// the event tables connect the wxWidgets events with the functions (event
-// handlers) which process them. It can be also done at run-time, but for the
+// The event tables connect the wxWidgets events with the functions (event
+// handlers) which process them.
+BEGIN_EVENT_TABLE(MyApp, wxApp)
+    // Add a static handler for button Click event in the app
+    EVT_BUTTON(MyEvtTestButton::BUTTON_ID, MyApp::OnClickStaticHandlerApp)
+END_EVENT_TABLE()
+
+BEGIN_EVENT_TABLE(MyEvtTestButton, wxButton)
+    // Add a static handler to this button itself for its own event
+    EVT_BUTTON(BUTTON_ID, MyEvtTestButton::OnClickStaticHandler)
+END_EVENT_TABLE()
+
+// This can be also done at run-time, but for the
 // simple menu events like this the static method is much simpler.
 BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     EVT_MENU(Event_Quit,  MyFrame::OnQuit)
@@ -194,6 +265,9 @@ BEGIN_EVENT_TABLE(MyFrame, wxFrame)
     // the line below would also work if OnProcessCustom() were defined as
     // taking a wxEvent (as required by EVT_CUSTOM) and not wxCommandEvent
     //EVT_CUSTOM(wxEVT_MY_CUSTOM_COMMAND, wxID_ANY, MyFrame::OnProcessCustom)
+
+    // Add a static handler in the parent frame for button event
+    EVT_BUTTON(MyEvtTestButton::BUTTON_ID, MyFrame::OnClickStaticHandlerFrame)
 END_EVENT_TABLE()
 
 BEGIN_EVENT_TABLE(MyEvtHandler, wxEvtHandler)
@@ -229,12 +303,51 @@ bool MyApp::OnInit()
     // created initially)
     frame->Show(true);
 
+    // Add a dynamic handler at the application level for the test button
+    Connect(MyEvtTestButton::BUTTON_ID, wxEVT_COMMAND_BUTTON_CLICKED,
+            wxCommandEventHandler(MyApp::OnClickDynamicHandlerApp));
+
     // success: wxApp::OnRun() will be called which will enter the main message
     // loop and the application will run. If we returned false here, the
     // application would exit immediately.
     return true;
 }
 
+// This is always the first to handle an event !
+int MyApp::FilterEvent(wxEvent& event)
+{
+    if ( event.GetEventType() == wxEVT_COMMAND_BUTTON_CLICKED &&
+            event.GetId() == MyEvtTestButton::BUTTON_ID )
+    {
+        wxLogMessage("Step 0 in \"How Events are Processed\":\n"
+                     "App::FilterEvent");
+    }
+
+    return wxApp::FilterEvent(event);
+}
+
+void MyApp::OnClickDynamicHandlerApp(wxCommandEvent& event)
+{
+    wxLogMessage("Step 7, 3 in \"How Events are Processed\":\n"
+                 "App::DynamicHandler_InAppTable");
+
+    event.Skip();
+}
+
+void MyApp::OnClickStaticHandlerApp(wxCommandEvent& event)
+{
+    wxLogMessage("Step 7, 4 in \"How Events are Processed\":\n"
+                 "App::StaticHandler_InAppTable");
+
+    wxLogMessage("Button click processed, there should be no more messages "
+                 "about handling events from the button.\n\n"
+                 "The log below shows the order in which the handlers "
+                 "were executed.");
+    wxLog::FlushActive();
+
+    event.Skip();
+}
+
 // ----------------------------------------------------------------------------
 // main frame
 // ----------------------------------------------------------------------------
@@ -292,6 +405,7 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
 #endif // wxUSE_STATUSBAR
 
     wxPanel * const panel = new wxPanel(this);
+    wxSizer * const mainSizer = new wxBoxSizer(wxVERTICAL);
     wxSizer * const sizer = new wxBoxSizer(wxHORIZONTAL);
     const wxSizerFlags centreY(wxSizerFlags().Centre().Border());
     sizer->Add(new wxStaticText(panel, wxID_ANY,
@@ -299,7 +413,29 @@ MyFrame::MyFrame(const wxString& title, const wxPoint& pos, const wxSize& size)
         centreY);
     m_btnDynamic = new wxButton(panel, Event_Dynamic, "&Dynamic button");
     sizer->Add(m_btnDynamic, centreY);
-    panel->SetSizer(sizer);
+
+    mainSizer->Add(sizer, 1, wxEXPAND);
+    mainSizer->Add(new wxStaticLine(panel), 0, wxEXPAND);
+    mainSizer->Add(new wxStaticLine(panel), 0, wxEXPAND);
+
+    m_testBtn = new MyEvtTestButton(panel, "Test Event Handlers Execution Order");
+
+    // After being created, an instance of MyEvtTestButton already has its own
+    // event handlers (see class definition);
+
+    // Add a dynamic handler for this button event in the parent frame
+    Connect(m_testBtn->GetId(), wxEVT_COMMAND_BUTTON_CLICKED,
+            wxCommandEventHandler(MyFrame::OnClickDynamicHandlerFrame));
+
+    // Bind a method of this frame (notice "this" argument!) to the button
+    // itself
+    m_testBtn->Connect(wxEVT_COMMAND_BUTTON_CLICKED,
+                       wxCommandEventHandler(MyFrame::OnClickDynamicHandlerButton),
+                       NULL,
+                       this);
+
+    mainSizer->Add(m_testBtn);
+    panel->SetSizer(mainSizer);
 }
 
 MyFrame::~MyFrame()
@@ -330,10 +466,34 @@ void MyFrame::OnAbout(wxCommandEvent& WXUNUSED(event))
                  wxOK | wxICON_INFORMATION, this);
 }
 
+void MyFrame::OnClickStaticHandlerFrame(wxCommandEvent& event)
+{
+    wxLogMessage("Step 6, 4 in \"How Events are Processed\":\n"
+                 "parentWin::StaticHandler_InFrameTable");
+
+    event.Skip();
+}
+
 // ----------------------------------------------------------------------------
 // dynamic event handling stuff
 // ----------------------------------------------------------------------------
 
+void MyFrame::OnClickDynamicHandlerFrame(wxCommandEvent& event)
+{
+    wxLogMessage("Step 6, 3 in \"How Events are Processed\":\n"
+                 "parentWin::DynamicHandler_InFrameTable");
+
+    event.Skip();
+}
+
+void MyFrame::OnClickDynamicHandlerButton(wxCommandEvent& event)
+{
+    wxLogMessage("Step 3 in \"How Events are Processed\":\n"
+                 "parentWin::DynamicHandler_InButtonTable");
+
+    event.Skip();
+}
+
 void MyFrame::OnDynamic(wxCommandEvent& event)
 {
     wxString origin;