X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/5048c832bb3c2f41ecd29ac079d74e39e304aec8..5b36366c59ea68056ba07a3ca1c2cd6022a59735:/include/wx/event.h?ds=sidebyside diff --git a/include/wx/event.h b/include/wx/event.h index c881a924f2..a4d7b5685a 100644 --- a/include/wx/event.h +++ b/include/wx/event.h @@ -9,8 +9,8 @@ // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifndef _WX_EVENTH__ -#define _WX_EVENTH__ +#ifndef _WX_EVENT_H__ +#define _WX_EVENT_H__ #if defined(__GNUG__) && !defined(__APPLE__) #pragma interface "event.h" @@ -27,6 +27,8 @@ #include "wx/thread.h" +#include "wx/dynarray.h" + // ---------------------------------------------------------------------------- // forward declarations // ---------------------------------------------------------------------------- @@ -86,6 +88,8 @@ typedef int wxEventType; #define DECLARE_EVENT_TABLE_ENTRY(type, winid, idLast, fn, obj) \ wxEventTableEntry(type, winid, idLast, fn, obj) +#define EMPTY_PARAMETER_VALUE /* Fake macro parameter value */ + #define BEGIN_DECLARE_EVENT_TYPES() #define END_DECLARE_EVENT_TYPES() #define DECLARE_EXPORTED_EVENT_TYPE(expdecl, name, value) \ @@ -93,7 +97,7 @@ typedef int wxEventType; #define DECLARE_EVENT_TYPE(name, value) \ DECLARE_EXPORTED_EVENT_TYPE(WXDLLIMPEXP_CORE, name, value) #define DECLARE_LOCAL_EVENT_TYPE(name, value) \ - DECLARE_EXPORTED_EVENT_TYPE(/* */, name, value) + DECLARE_EXPORTED_EVENT_TYPE(EMPTY_PARAMETER_VALUE, name, value) #define DEFINE_EVENT_TYPE(name) const wxEventType name = wxNewEventType(); #define DEFINE_LOCAL_EVENT_TYPE(name) DEFINE_EVENT_TYPE(name) @@ -331,6 +335,17 @@ END_DECLARE_EVENT_TYPES() #endif // WXWIN_COMPATIBILITY +// the predefined constants for the number of times we propagate event +// upwards window child-parent chain +enum Propagation_state +{ + // don't propagate it at all + wxEVENT_PROPAGATE_NONE = 0, + + // propagate it until it is processed + wxEVENT_PROPAGATE_MAX = INT_MAX +}; + /* * wxWindows events, covering all interesting things that might happen * (button clicking, resizing, setting text in widgets, etc.). @@ -370,30 +385,108 @@ public: void Skip(bool skip = TRUE) { m_skipped = skip; } bool GetSkipped() const { return m_skipped; }; - // Implementation only: this test is explicitlty anti OO and this functions - // exists only for optimization purposes. - bool IsCommandEvent() const { return m_isCommandEvent; } - // this function is used to create a copy of the event polymorphically and // all derived classes must implement it because otherwise wxPostEvent() // for them wouldn't work (it needs to do a copy of the event) virtual wxEvent *Clone() const = 0; + // Implementation only: this test is explicitlty anti OO and this functions + // exists only for optimization purposes. + bool IsCommandEvent() const { return m_isCommandEvent; } + + // Determine if this event should be propagating to the parent window. + bool ShouldPropagate() const + { return m_propagationLevel != wxEVENT_PROPAGATE_NONE; } + + // Stop an event from propagating to its parent window, returns the old + // propagation level value + int StopPropagation() + { + int propagationLevel = m_propagationLevel; + m_propagationLevel = wxEVENT_PROPAGATE_NONE; + return propagationLevel; + } + + // Resume the event propagation by restoring the propagation level + // (returned by StopPropagation()) + void ResumePropagation(int propagationLevel) + { + m_propagationLevel = propagationLevel; + } + public: wxObject* m_eventObject; wxEventType m_eventType; long m_timeStamp; int m_id; wxObject* m_callbackUserData; + +protected: + // the propagation level: while it is positive, we propagate the event to + // the parent window (if any) + // + // this one doesn't have to be public, we don't have to worry about + // backwards compatibility as it is new + int m_propagationLevel; + +public: bool m_skipped; bool m_isCommandEvent; - + private: + // it needs to access our m_propagationLevel + friend class WXDLLIMPEXP_BASE wxPropagateOnce; + DECLARE_ABSTRACT_CLASS(wxEvent) }; +/* + * Helper class to temporarily change an event not to propagate. + */ +class WXDLLIMPEXP_BASE wxPropagationDisabler +{ +public: + wxPropagationDisabler(wxEvent& event) : m_event(event) + { + m_propagationLevelOld = m_event.StopPropagation(); + } + + ~wxPropagationDisabler() + { + m_event.ResumePropagation(m_propagationLevelOld); + } + +private: + wxEvent& m_event; + int m_propagationLevelOld; +}; + +/* + * Another one to temporarily lower propagation level. + */ +class WXDLLIMPEXP_BASE wxPropagateOnce +{ +public: + wxPropagateOnce(wxEvent& event) : m_event(event) + { + wxASSERT_MSG( m_event.m_propagationLevel > 0, + _T("shouldn't be used unless ShouldPropagate()!") ); + + m_event.m_propagationLevel--; + } + + ~wxPropagateOnce() + { + m_event.m_propagationLevel++; + } + +private: + wxEvent& m_event; +}; + #if wxUSE_GUI + // Item or menu event class /* wxEVT_COMMAND_BUTTON_CLICKED @@ -1115,7 +1208,7 @@ private: }; // wxChildFocusEvent notifies the parent that a child has got the focus: unlike -// wxFocusEvent it is propgated upwards the window chain +// wxFocusEvent it is propagated upwards the window chain class WXDLLIMPEXP_CORE wxChildFocusEvent : public wxCommandEvent { public: @@ -1184,12 +1277,12 @@ private: class WXDLLIMPEXP_CORE wxMenuEvent : public wxEvent { public: - wxMenuEvent(wxEventType type = wxEVT_NULL, int winid = 0) + wxMenuEvent(wxEventType type = wxEVT_NULL, int winid = 0, wxMenu* menu = NULL) : wxEvent(winid, type) - { m_menuId = winid; } + { m_menuId = winid; m_menu = NULL; } wxMenuEvent(const wxMenuEvent & event) : wxEvent(event) - { m_menuId = event.m_menuId; } + { m_menuId = event.m_menuId; m_menu = event.m_menu; } // only for wxEVT_MENU_HIGHLIGHT int GetMenuId() const { return m_menuId; } @@ -1197,10 +1290,14 @@ public: // only for wxEVT_MENU_OPEN/CLOSE bool IsPopup() const { return m_menuId == -1; } + // only for wxEVT_MENU_OPEN/CLOSE + wxMenu* GetMenu() const { return m_menu; } + virtual wxEvent *Clone() const { return new wxMenuEvent(*this); } private: - int m_menuId; + int m_menuId; + wxMenu* m_menu; DECLARE_DYNAMIC_CLASS(wxMenuEvent) }; @@ -2078,6 +2175,56 @@ struct WXDLLIMPEXP_BASE wxEventTable const wxEventTableEntry *entries; // bottom of entry array }; +// ---------------------------------------------------------------------------- +// wxEventHashTable: a helper of wxEvtHandler to speed up wxEventTable lookups. +// ---------------------------------------------------------------------------- + +WX_DEFINE_ARRAY_NO_PTR(const wxEventTableEntry*, wxEventTableEntryPointerArray); +class WXDLLIMPEXP_BASE wxEvtHandler; + +class WXDLLIMPEXP_BASE wxEventHashTable +{ +private: + // Internal data structs + struct EventTypeTable + { + wxEventType eventType; + wxEventTableEntryPointerArray eventEntryTable; + }; + typedef EventTypeTable* EventTypeTablePointer; + +public: + // Constructor, needs the event table it needs to hash later on. + // Note: hashing of the event table is not done in the constructor as it + // can be that the event table is not yet full initialize, the hash + // will gets initialized when handling the first event look-up request. + wxEventHashTable(const wxEventTable &table); + // Destructor. + ~wxEventHashTable(); + + // Handle the given event, in other words search the event table hash + // and call self->ProcessEvent() if a match was found. + bool HandleEvent(wxEvent &event, wxEvtHandler *self); + +protected: + // Init the hash table with the entries of the static event table. + void InitHashTable(); + // Helper funtion of InitHashTable() to insert 1 entry into the hash table. + void AddEntry(const wxEventTableEntry &entry); + // Allocate and init with null pointers the base hash table. + void AllocEventTypeTable(size_t size); + // Grow the hash table in size and transfer all items currently + // in the table to the correct location in the new table. + void GrowEventTypeTable(); + +protected: + const wxEventTable &m_table; + bool m_rebuildHash; + + size_t m_size; + EventTypeTablePointer *m_eventTypeTable; +}; + // ---------------------------------------------------------------------------- // wxEvtHandler: the base class for all objects handling wxWindows events // ---------------------------------------------------------------------------- @@ -2197,10 +2344,12 @@ protected: virtual bool TryParent(wxEvent& event); - static const wxEventTable sm_eventTable; - + static const wxEventTable sm_eventTable; virtual const wxEventTable *GetEventTable() const; + static wxEventHashTable sm_eventHashTable; + virtual wxEventHashTable& GetEventHashTable() const; + wxEvtHandler* m_nextHandler; wxEvtHandler* m_previousHandler; wxList* m_dynamicEvents; @@ -2299,16 +2448,22 @@ typedef void (wxEvtHandler::*wxMouseCaptureChangedEventFunction)(wxMouseCaptureC static const wxEventTableEntry sm_eventTableEntries[]; \ protected: \ static const wxEventTable sm_eventTable; \ - virtual const wxEventTable* GetEventTable() const; + virtual const wxEventTable* GetEventTable() const; \ + static wxEventHashTable sm_eventHashTable; \ + virtual wxEventHashTable& GetEventHashTable() const; // N.B.: when building DLL with Borland C++ 5.5 compiler, you must initialize // sm_eventTable before using it in GetEventTable() or the compiler gives // E2233 (see http://groups.google.com/groups?selm=397dcc8a%241_2%40dnews) + #define BEGIN_EVENT_TABLE(theClass, baseClass) \ const wxEventTable theClass::sm_eventTable = \ { &baseClass::sm_eventTable, &theClass::sm_eventTableEntries[0] }; \ const wxEventTable *theClass::GetEventTable() const \ { return &theClass::sm_eventTable; } \ + wxEventHashTable theClass::sm_eventHashTable(theClass::sm_eventTable); \ + wxEventHashTable &theClass::GetEventHashTable() const \ + { return theClass::sm_eventHashTable; } \ const wxEventTableEntry theClass::sm_eventTableEntries[] = { \ #define END_EVENT_TABLE() DECLARE_EVENT_TABLE_ENTRY( wxEVT_NULL, 0, 0, 0, 0 ) }; @@ -2569,5 +2724,5 @@ wxWindow* wxFindFocusDescendant(wxWindow* ancestor); #endif // wxUSE_GUI -#endif - // _WX_EVENTH__ +#endif // _WX_EVENT_H__ +