// 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"
#include "wx/thread.h"
+#include "wx/dynarray.h"
+
// ----------------------------------------------------------------------------
// forward declarations
// ----------------------------------------------------------------------------
#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) \
#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)
#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.).
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
};
// 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:
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
// ----------------------------------------------------------------------------
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;
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 ) };
#endif // wxUSE_GUI
-#endif
- // _WX_EVENTH__
+#endif // _WX_EVENT_H__
+