#include "wx/list.h"
#include "wx/app.h"
#include "wx/utils.h"
+ #include "wx/stopwatch.h"
+ #include "wx/module.h"
#if wxUSE_GUI
#include "wx/control.h"
#include "wx/dc.h"
#include "wx/textctrl.h"
+ #include "wx/validate.h"
#endif // wxUSE_GUI
#endif
-#include "wx/module.h"
-
-#if wxUSE_GUI
- #include "wx/validate.h"
-#if wxUSE_STOPWATCH
- #include "wx/stopwatch.h"
-#endif
-#endif // wxUSE_GUI
-
// ----------------------------------------------------------------------------
// wxWin macros
// ----------------------------------------------------------------------------
#if wxUSE_BASE
IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler, wxObject)
IMPLEMENT_ABSTRACT_CLASS(wxEvent, wxObject)
+ IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent)
#endif // wxUSE_BASE
#if wxUSE_GUI
- IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent, wxEvent)
IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent, wxEvent)
IMPLEMENT_DYNAMIC_CLASS(wxNotifyEvent, wxCommandEvent)
IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent, wxCommandEvent)
IMPLEMENT_DYNAMIC_CLASS(wxHelpEvent, wxCommandEvent)
IMPLEMENT_DYNAMIC_CLASS(wxContextMenuEvent, wxCommandEvent)
IMPLEMENT_DYNAMIC_CLASS(wxMouseCaptureChangedEvent, wxEvent)
+ IMPLEMENT_DYNAMIC_CLASS(wxMouseCaptureLostEvent, wxEvent)
IMPLEMENT_DYNAMIC_CLASS(wxClipboardTextEvent, wxCommandEvent)
#endif // wxUSE_GUI
{ DECLARE_EVENT_TABLE_ENTRY(wxEVT_NULL, 0, 0, (wxObjectEventFunction)NULL, NULL) };
-#ifdef __WXDEBUG__
-// Clear up event hash table contents or we can get problems
-// when C++ is cleaning up the static object
+// wxUSE_MEMORY_TRACING considers memory freed from the static objects dtors
+// leaked, so we need to manually clean up all event tables before checking for
+// the memory leaks when using it, however this breaks re-initializing the
+// library (i.e. repeated calls to wxInitialize/wxUninitialize) because the
+// event tables won't be rebuilt the next time, so disable this by default
+#if defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING
+
class wxEventTableEntryModule: public wxModule
{
-DECLARE_DYNAMIC_CLASS(wxEventTableEntryModule)
public:
- wxEventTableEntryModule() {}
- bool OnInit() { return true; }
- void OnExit()
- {
- wxEventHashTable::ClearAll();
- }
+ wxEventTableEntryModule() { }
+ virtual bool OnInit() { return true; }
+ virtual void OnExit() { wxEventHashTable::ClearAll(); }
+
+ DECLARE_DYNAMIC_CLASS(wxEventTableEntryModule)
};
+
IMPLEMENT_DYNAMIC_CLASS(wxEventTableEntryModule, wxModule)
-#endif
+
+#endif // __WXDEBUG__ && wxUSE_MEMORY_TRACING
// ----------------------------------------------------------------------------
// global variables
DEFINE_EVENT_TYPE(wxEVT_NULL)
DEFINE_EVENT_TYPE(wxEVT_IDLE)
DEFINE_EVENT_TYPE(wxEVT_SOCKET)
+DEFINE_EVENT_TYPE(wxEVT_TIMER)
#endif // !WXWIN_COMPATIBILITY_EVENT_TYPES
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_RCLICKED)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_ENTER)
DEFINE_EVENT_TYPE(wxEVT_COMMAND_SPINCTRL_UPDATED)
-
-// Sockets and timers send events, too
-DEFINE_EVENT_TYPE(wxEVT_TIMER)
+DEFINE_EVENT_TYPE(wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED)
// Mouse event types
DEFINE_EVENT_TYPE(wxEVT_LEFT_DOWN)
DEFINE_EVENT_TYPE(wxEVT_ICONIZE)
DEFINE_EVENT_TYPE(wxEVT_MAXIMIZE)
DEFINE_EVENT_TYPE(wxEVT_MOUSE_CAPTURE_CHANGED)
+DEFINE_EVENT_TYPE(wxEVT_MOUSE_CAPTURE_LOST)
DEFINE_EVENT_TYPE(wxEVT_PAINT)
DEFINE_EVENT_TYPE(wxEVT_ERASE_BACKGROUND)
DEFINE_EVENT_TYPE(wxEVT_NC_PAINT)
#if wxUSE_BASE
+wxIdleMode wxIdleEvent::sm_idleMode = wxIDLE_PROCESS_ALL;
+
// ============================================================================
// implementation
// ============================================================================
}
wxEvent::wxEvent(const wxEvent &src)
- : wxObject()
+ : wxObject(src)
, m_eventObject(src.m_eventObject)
, m_eventType(src.m_eventType)
, m_timeStamp(src.m_timeStamp)
wxCommandEvent::wxCommandEvent(wxEventType commandType, int theId)
: wxEvent(theId, commandType)
-#if WXWIN_COMPATIBILITY_2_4
- , m_commandString(this)
-#endif
{
m_clientData = (char *) NULL;
m_clientObject = (wxClientData *) NULL;
#endif
}
-/*
- * Idle events
- */
-
-wxIdleMode wxIdleEvent::sm_idleMode = wxIDLE_PROCESS_ALL;
-
-// Can we send an idle event?
-bool wxIdleEvent::CanSend(wxWindow* win)
-{
- // Don't update if we've switched global updating off
- // and this window doesn't support updates.
- if (win &&
- (GetMode() == wxIDLE_PROCESS_SPECIFIED &&
- ((win->GetExtraStyle() & wxWS_EX_PROCESS_IDLE) == 0)))
- return false;
-
- return true;
-}
-
/*
* Scroll events
*/
m_wheelRotation = 0;
m_wheelDelta = 0;
m_linesPerAction = 0;
+ m_wheelAxis = 0;
}
void wxMouseEvent::Assign(const wxMouseEvent& event)
m_wheelRotation = event.m_wheelRotation;
m_wheelDelta = event.m_wheelDelta;
m_linesPerAction = event.m_linesPerAction;
+ m_wheelAxis = event.m_wheelAxis;
}
// return true if was a button dclick event
void wxEventHashTable::Clear()
{
- size_t i;
- for(i = 0; i < m_size; i++)
+ for ( size_t i = 0; i < m_size; i++ )
{
EventTypeTablePointer eTTnode = m_eventTypeTable[i];
- if (eTTnode)
- {
- delete eTTnode;
- }
+ delete eTTnode;
}
- // Necessary in order to not invoke the
- // overloaded delete operator when statics are cleaned up
- if (m_eventTypeTable)
- delete[] m_eventTypeTable;
-
+ delete[] m_eventTypeTable;
m_eventTypeTable = NULL;
+
m_size = 0;
}
+#if defined(__WXDEBUG__) && wxUSE_MEMORY_TRACING
+
// Clear all tables
void wxEventHashTable::ClearAll()
{
}
}
+#endif // __WXDEBUG__ && wxUSE_MEMORY_TRACING
+
bool wxEventHashTable::HandleEvent(wxEvent &event, wxEvtHandler *self)
{
if (m_rebuildHash)
m_eventsLocker = new wxCriticalSection;
# endif
#endif
+
// no client data (yet)
m_clientData = NULL;
m_clientDataType = wxClientData_None;
if (m_dynamicEvents)
{
- wxList::iterator it = m_dynamicEvents->begin(),
- en = m_dynamicEvents->end();
- for (;it != en; ++it)
+ for ( wxList::iterator it = m_dynamicEvents->begin(),
+ end = m_dynamicEvents->end();
+ it != end;
+ ++it )
{
#if WXWIN_COMPATIBILITY_EVENT_TYPES
wxEventTableEntry *entry = (wxEventTableEntry*)*it;
void wxEvtHandler::ProcessPendingEvents()
{
- // this method is only called by wxApp if this handler does have pending
- // events
+ // this method is only called by wxApp if this handler does have
+ // pending events
wxCHECK_RET( m_pendingEvents,
wxT("Please call wxApp::ProcessPendingEvents() instead") );
-
+
wxENTER_CRIT_SECT( Lock() );
// we leave the loop once we have processed all events that were present at
// It's importan we remove event from list before processing it.
// Else a nested event loop, for example from a modal dialog, might
// process the same event again.
+
m_pendingEvents->Erase(node);
wxLEAVE_CRIT_SECT( Lock() );
ProcessEvent(*event);
+
delete event;
wxENTER_CRIT_SECT( Lock() );
return focusWin;
}
+// ----------------------------------------------------------------------------
+// wxEventBlocker
+// ----------------------------------------------------------------------------
+
+wxEventBlocker::wxEventBlocker(wxWindow *win, wxEventType type)
+{
+ wxCHECK_RET(win, wxT("Null window given to wxEventBlocker"));
+
+ m_window = win;
+
+ Block(type);
+ m_window->PushEventHandler(this);
+}
+
+wxEventBlocker::~wxEventBlocker()
+{
+ wxEvtHandler *popped = m_window->PopEventHandler(false);
+ wxCHECK_RET(popped == this,
+ wxT("Don't push other event handlers into a window managed by wxEventBlocker!"));
+}
+
+bool wxEventBlocker::ProcessEvent(wxEvent& event)
+{
+ // should this event be blocked?
+ for ( size_t i = 0; i < m_eventsToBlock.size(); i++ )
+ {
+ wxEventType t = (wxEventType)m_eventsToBlock[i];
+ if ( t == wxEVT_ANY || t == event.GetEventType() )
+ return true; // yes, it should: mark this event as processed
+ }
+
+ return false;
+}
+
#endif // wxUSE_GUI