]> git.saurik.com Git - wxWidgets.git/blobdiff - docs/latex/wx/tevent.tex
Added font setting and ability to determine AUI notebook height for a given page...
[wxWidgets.git] / docs / latex / wx / tevent.tex
index 598878746fa7600530526a5f5d2a1b240625b62b..e747b0671440123ad5759075b7c1427de0dbca17 100644 (file)
@@ -189,7 +189,7 @@ be the only events you wish to redirect), you may use
 instead of using the slower run-time type system.
 
 As mentioned above, only command events are recursively applied to the parents event
-handler in the libary itself. As this quite often causes confusion for users,
+handler in the library itself. As this quite often causes confusion for users,
 here is a list of system events which will NOT get sent to the parent's event handler:
 
 \begin{twocollist}\itemsep=0pt
@@ -211,7 +211,6 @@ here is a list of system events which will NOT get sent to the parent's event ha
 \twocolitem{\helpref{wxSizeEvent}{wxsizeevent}}{A size event}
 \twocolitem{\helpref{wxScrollWinEvent}{wxscrollwinevent}}{A scroll event sent by a scrolled window (not a scroll bar)}
 \twocolitem{\helpref{wxSysColourChangedEvent}{wxsyscolourchangedevent}}{A system colour change event}
-\twocolitem{\helpref{wxUpdateUIEvent}{wxupdateuievent}}{A user interface update event}
 \end{twocollist}
 
 In some cases, it might be desired by the programmer to get a certain number
@@ -220,6 +219,30 @@ used by, the native controls in a dialog. In this case, a special event handler
 will have to be written that will override ProcessEvent() in order to pass
 all events (or any selection of them) to the parent window.
 
+
+\subsection{Events generated by the user vs programmatically generated events}\label{progevent}
+
+While generically \helpref{wxEvents}{wxevent} can be generated both by user
+actions (e.g. resize of a \helpref{wxWindow}{wxwindow}) and by calls to functions
+(e.g. \helpref{wxWindow::SetSize}{wxwindowsetsize}), wxWidgets controls
+normally send \helpref{wxCommandEvent}{wxcommandevent}-derived events only for
+the user-generated events. The only {\bf exceptions} to this rule are:
+
+\begin{twocollist}\itemsep=0pt
+\twocolitem{\helpref{wxNotebook::AddPage}{wxnotebookaddpage}}{No event-free alternatives}
+\twocolitem{\helpref{wxNotebook::AdvanceSelection}{wxnotebookadvanceselection}}{No event-free alternatives}
+\twocolitem{\helpref{wxNotebook::DeletePage}{wxnotebookdeletepage}}{No event-free alternatives}
+\twocolitem{\helpref{wxNotebook::SetSelection}{wxnotebooksetselection}}{Use \helpref{wxNotebook::ChangeSelection}{wxnotebookchangeselection} instead, as \helpref{wxNotebook::SetSelection}{wxnotebooksetselection} is deprecated}
+\twocolitem{\helpref{wxTreeCtrl::Delete}{wxtreectrldelete}}{No event-free alternatives}
+\twocolitem{\helpref{wxTreeCtrl::DeleteAllItems}{wxtreectrldeleteallitems}}{No event-free alternatives}
+\twocolitem{\helpref{wxTreeCtrl::EditLabel}{wxtreectrleditlabel}}{No event-free alternatives}
+\twocolitem{All \helpref{wxTextCtrl}{wxtextctrl} methods}{\helpref{wxTextCtrl::ChangeValue}{wxtextctrlchangevalue} can be used instead
+of \helpref{wxTextCtrl::SetValue}{wxtextctrlsetvalue} but the other functions,
+such as \helpref{Replace}{wxtextctrlreplace} or \helpref{WriteText}{wxtextctrlwritetext} 
+don't have event-free equivalents}
+\end{twocollist}
+
+
 % VZ: it doesn't work like this, but just in case we ever reenable this
 %     behaviour, I leave it here
 %
@@ -245,7 +268,8 @@ defining the appropriate event table, and then call
 \rtfsp\helpref{wxWindow::SetEventHandler}{wxwindowseteventhandler} (or, preferably,
 \rtfsp\helpref{wxWindow::PushEventHandler}{wxwindowpusheventhandler}) to make this
 event handler the object that responds to events. This way, you can avoid
-a lot of class derivation, and use the same event handler object to
+a lot of class derivation, and use the same event handler class (but different
+objects as the same event handler object shouldn't be used more than once) to
 handle events from instances of different classes. If you ever have to call a window's event handler
 manually, use the GetEventHandler function to retrieve the window's event handler and use that
 to call the member function. By default, GetEventHandler returns a pointer to the window itself
@@ -356,21 +380,6 @@ you can use identifiers below wxID\_LOWEST.
 
 \subsection{Event macros summary}\label{eventmacros}
 
-\wxheading{Generic event table macros}
-
-\twocolwidtha{8cm}%
-\begin{twocollist}\itemsep=0pt
-\twocolitem{\windowstyle{EVT\_CUSTOM(event, id, func)}}{Allows you to add a custom event table
-entry by specifying the event identifier (such as wxEVT\_SIZE), the window identifier,
-and a member function to call.}
-\twocolitem{\windowstyle{EVT\_CUSTOM\_RANGE(event, id1, id2, func)}}{The same as EVT\_CUSTOM,
-but responds to a range of window identifiers.}
-\twocolitem{\windowstyle{EVT\_COMMAND(id, event, func)}}{The same as EVT\_CUSTOM, but
-expects a member function with a wxCommandEvent argument.}
-\twocolitem{\windowstyle{EVT\_COMMAND\_RANGE(id1, id2, event, func)}}{The same as EVT\_CUSTOM\_RANGE, but
-expects a member function with a wxCommandEvent argument.}
-\end{twocollist}
-
 \wxheading{Macros listed by event class}
 
 The documentation for specific event macros is organised by event class. Please refer
@@ -413,3 +422,175 @@ update pseudo-events, which are generated to give the application the chance to
 toolbars and controls.}
 \end{twocollist}
 
+\subsection{Custom event summary}\label{customevents}
+
+\wxheading{General approach}
+
+Since version 2.2.x of wxWidgets, each event type is identified by ID which
+is given to the event type {\it at runtime} which makes it possible to add
+new event types to the library or application without risking ID clashes
+(two different event types mistakingly getting the same event ID). This
+event type ID is stored in a struct of type {\bf const wxEventType}.
+
+In order to define a new event type, there are principally two choices.
+One is to define a entirely new event class (typically deriving from
+\helpref{wxEvent}{wxevent} or \helpref{wxCommandEvent}{wxcommandevent}. 
+The other is to use the existing event classes and give them an new event
+type. You'll have to define and declare a new event type using either way,
+and this is done using the following macros:
+
+\begin{verbatim}
+// in the header of the source file
+BEGIN_DECLARE_EVENT_TYPES()
+DECLARE_EVENT_TYPE(name, value)
+END_DECLARE_EVENT_TYPES()
+
+// in the implementation
+DEFINE_EVENT_TYPE(name)
+\end{verbatim}
+
+You can ignore the {\it value} parameter of the DECLARE\_EVENT\_TYPE macro
+since it is used only for backwards compatibility with wxWidgets 2.0.x based
+applications where you have to give the event type ID an explicit value.
+
+See also the \helpref{event sample}{sampleevent} for an example of code
+defining and working with the custom event types.
+
+\wxheading{Using existing event classes}
+
+If you just want to use a \helpref{wxCommandEvent}{wxcommandevent} with
+a new event type, you can then use one of the generic event table macros
+listed below, without having to define a new macro yourself. This also
+has the advantage that you won't have to define a new \helpref{wxEvent::Clone()}{wxeventclone}
+method for posting events between threads etc. This could look like this
+in your code:
+
+{\small%
+\begin{verbatim}
+DECLARE_EVENT_TYPE(wxEVT_MY_EVENT, -1)
+
+DEFINE_EVENT_TYPE(wxEVT_MY_EVENT)
+
+// user code intercepting the event
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+  EVT_MENU    (wxID_EXIT, MyFrame::OnExit)
+  // ....
+  EVT_COMMAND  (ID_MY_WINDOW, wxEVT_MY_EVENT, MyFrame::OnMyEvent)
+END_EVENT_TABLE()
+
+void MyFrame::OnMyEvent( wxCommandEvent &event )
+{
+    // do something
+    wxString text = event.GetText();
+}
+
+
+// user code sending the event
+
+void MyWindow::SendEvent()
+{
+    wxCommandEvent event( wxEVT_MY_EVENT, GetId() );
+    event.SetEventObject( this );
+    // Give it some contents
+    event.SetText( wxT("Hallo") );
+    // Send it
+    GetEventHandler()->ProcessEvent( event );
+}
+\end{verbatim}
+}%
+
+
+\wxheading{Generic event table macros}
+
+\twocolwidtha{8cm}%
+\begin{twocollist}\itemsep=0pt
+\twocolitem{\windowstyle{EVT\_CUSTOM(event, id, func)}}{Allows you to add a custom event table
+entry by specifying the event identifier (such as wxEVT\_SIZE), the window identifier,
+and a member function to call.}
+\twocolitem{\windowstyle{EVT\_CUSTOM\_RANGE(event, id1, id2, func)}}{The same as EVT\_CUSTOM,
+but responds to a range of window identifiers.}
+\twocolitem{\windowstyle{EVT\_COMMAND(id, event, func)}}{The same as EVT\_CUSTOM, but
+expects a member function with a wxCommandEvent argument.}
+\twocolitem{\windowstyle{EVT\_COMMAND\_RANGE(id1, id2, event, func)}}{The same as EVT\_CUSTOM\_RANGE, but
+expects a member function with a wxCommandEvent argument.}
+\twocolitem{\windowstyle{EVT\_NOTIFY(event, id, func)}}{The same as EVT\_CUSTOM, but
+expects a member function with a wxNotifyEvent argument.}
+\twocolitem{\windowstyle{EVT\_NOTIFY\_RANGE(event, id1, id2, func)}}{The same as EVT\_CUSTOM\_RANGE, but
+expects a member function with a wxNotifyEvent argument.}
+\end{twocollist}
+
+
+\wxheading{Defining your own event class}
+
+Under certain circumstances, it will be required to define your own event
+class e.g. for sending more complex data from one place to another. Apart
+from defining your event class, you will also need to define your own
+event table macro (which is quite long). Watch out to put in enough
+casts to the inherited event function. Here is an example, taken mostly
+from the {\it wxPlot} library, which is in the {\it contrib} section of
+the wxWidgets sources.
+
+{\small%
+\begin{verbatim}
+
+// code defining event
+
+class wxPlotEvent: public wxNotifyEvent
+{
+public:
+    wxPlotEvent( wxEventType commandType = wxEVT_NULL, int id = 0 );
+
+    // accessors
+    wxPlotCurve *GetCurve()
+        { return m_curve; }
+
+    // required for sending with wxPostEvent()
+    wxEvent* Clone();
+
+private:
+    wxPlotCurve   *m_curve;
+};
+
+DECLARE_EVENT_MACRO( wxEVT_PLOT_ACTION, -1 )
+
+typedef void (wxEvtHandler::*wxPlotEventFunction)(wxPlotEvent&);
+
+#define EVT_PLOT(id, fn) \
+    DECLARE_EVENT_TABLE_ENTRY( wxEVT_PLOT_ACTION, id, -1, \
+    (wxObjectEventFunction) (wxEventFunction) (wxCommandEventFunction) (wxNotifyEventFunction) \
+    wxStaticCastEvent( wxPlotEventFunction, & fn ), (wxObject *) NULL ),
+
+
+// code implementing the event type and the event class
+
+DEFINE_EVENT_TYPE( wxEVT_PLOT_ACTION )
+
+wxPlotEvent::wxPlotEvent( ...
+
+
+// user code intercepting the event
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+  EVT_PLOT  (ID_MY_WINDOW,  MyFrame::OnPlot)
+END_EVENT_TABLE()
+
+void MyFrame::OnPlot( wxPlotEvent &event )
+{
+    wxPlotCurve *curve = event.GetCurve();
+}
+
+
+// user code sending the event
+
+void MyWindow::SendEvent()
+{
+    wxPlotEvent event( wxEVT_PLOT_ACTION, GetId() );
+    event.SetEventObject( this );
+    event.SetCurve( m_curve );
+    GetEventHandler()->ProcessEvent( event );
+}
+
+\end{verbatim}
+}%
+