#endif
#include "wx/event.h"
+#include "wx/evtloop.h"
#ifndef WX_PRECOMP
#include "wx/list.h"
#include "wx/module.h"
#if wxUSE_GUI
+ #include "wx/window.h"
#include "wx/control.h"
#include "wx/dc.h"
#include "wx/textctrl.h"
{ 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_KILL_FOCUS)
DEFINE_EVENT_TYPE(wxEVT_CHILD_FOCUS)
DEFINE_EVENT_TYPE(wxEVT_MOUSEWHEEL)
+DEFINE_EVENT_TYPE(wxEVT_AUX1_DOWN)
+DEFINE_EVENT_TYPE(wxEVT_AUX1_UP)
+DEFINE_EVENT_TYPE(wxEVT_AUX1_DCLICK)
+DEFINE_EVENT_TYPE(wxEVT_AUX2_DOWN)
+DEFINE_EVENT_TYPE(wxEVT_AUX2_UP)
+DEFINE_EVENT_TYPE(wxEVT_AUX2_DCLICK)
// Non-client mouse events
DEFINE_EVENT_TYPE(wxEVT_NC_LEFT_DOWN)
DEFINE_EVENT_TYPE(wxEVT_SIZING)
DEFINE_EVENT_TYPE(wxEVT_MOVE)
DEFINE_EVENT_TYPE(wxEVT_MOVING)
+DEFINE_EVENT_TYPE(wxEVT_MOVE_START)
+DEFINE_EVENT_TYPE(wxEVT_MOVE_END)
DEFINE_EVENT_TYPE(wxEVT_CLOSE_WINDOW)
DEFINE_EVENT_TYPE(wxEVT_END_SESSION)
DEFINE_EVENT_TYPE(wxEVT_QUERY_END_SESSION)
DEFINE_EVENT_TYPE(wxEVT_HIBERNATE)
DEFINE_EVENT_TYPE(wxEVT_ACTIVATE_APP)
-DEFINE_EVENT_TYPE(wxEVT_POWER)
DEFINE_EVENT_TYPE(wxEVT_ACTIVATE)
DEFINE_EVENT_TYPE(wxEVT_CREATE)
DEFINE_EVENT_TYPE(wxEVT_DESTROY)
wxMouseEvent::wxMouseEvent(wxEventType commandType)
{
m_eventType = commandType;
- m_metaDown = false;
- m_altDown = false;
- m_controlDown = false;
- m_shiftDown = false;
- m_leftDown = false;
- m_rightDown = false;
- m_middleDown = false;
+
m_x = 0;
m_y = 0;
+
+ m_leftDown = false;
+ m_middleDown = false;
+ m_rightDown = false;
+ m_aux1Down = false;
+ m_aux2Down = false;
+
+ m_controlDown = false;
+ m_shiftDown = false;
+ m_altDown = false;
+ m_metaDown = false;
+
+ m_clickCount = -1;
+
m_wheelRotation = 0;
m_wheelDelta = 0;
m_linesPerAction = 0;
m_leftDown = event.m_leftDown;
m_middleDown = event.m_middleDown;
m_rightDown = event.m_rightDown;
+ m_aux1Down = event.m_aux1Down;
+ m_aux2Down = event.m_aux2Down;
m_controlDown = event.m_controlDown;
m_shiftDown = event.m_shiftDown;
// fall through
case wxMOUSE_BTN_ANY:
- return (LeftDClick() || MiddleDClick() || RightDClick());
+ return (LeftDClick() || MiddleDClick() || RightDClick() ||
+ Aux1DClick() || Aux2DClick());
case wxMOUSE_BTN_LEFT:
return LeftDClick();
case wxMOUSE_BTN_RIGHT:
return RightDClick();
+
+ case wxMOUSE_BTN_AUX1:
+ return Aux1DClick();
+
+ case wxMOUSE_BTN_AUX2:
+ return Aux2DClick();
}
}
// fall through
case wxMOUSE_BTN_ANY:
- return (LeftDown() || MiddleDown() || RightDown());
+ return (LeftDown() || MiddleDown() || RightDown() ||
+ Aux1Down() || Aux2Down());
case wxMOUSE_BTN_LEFT:
return LeftDown();
case wxMOUSE_BTN_RIGHT:
return RightDown();
+
+ case wxMOUSE_BTN_AUX1:
+ return Aux1Down();
+
+ case wxMOUSE_BTN_AUX2:
+ return Aux2Down();
}
}
// fall through
case wxMOUSE_BTN_ANY:
- return (LeftUp() || MiddleUp() || RightUp());
+ return (LeftUp() || MiddleUp() || RightUp() ||
+ Aux1Up() || Aux2Up());
case wxMOUSE_BTN_LEFT:
return LeftUp();
case wxMOUSE_BTN_RIGHT:
return RightUp();
+
+ case wxMOUSE_BTN_AUX1:
+ return Aux1Up();
+
+ case wxMOUSE_BTN_AUX2:
+ return Aux2Up();
}
}
case wxMOUSE_BTN_RIGHT:
return RightDown() || RightUp() || RightDClick();
+
+ case wxMOUSE_BTN_AUX1:
+ return Aux1Down() || Aux1Up() || Aux1DClick();
+
+ case wxMOUSE_BTN_AUX2:
+ return Aux2Down() || Aux2Up() || Aux2DClick();
}
}
// fall through
case wxMOUSE_BTN_ANY:
- return LeftIsDown() || MiddleIsDown() || RightIsDown();
+ return LeftIsDown() || MiddleIsDown() || RightIsDown() || Aux1Down() || Aux2Down();
case wxMOUSE_BTN_LEFT:
return LeftIsDown();
case wxMOUSE_BTN_RIGHT:
return RightIsDown();
+
+ case wxMOUSE_BTN_AUX1:
+ return Aux1IsDown();
+
+ case wxMOUSE_BTN_AUX2:
+ return Aux2IsDown();
}
}
int wxMouseEvent::GetButton() const
{
- for ( int i = 1; i <= 3; i++ )
+ for ( int i = 1; i < wxMOUSE_BTN_MAX; i++ )
{
if ( Button(i) )
{
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 wxUSE_THREADS
-bool wxEvtHandler::ProcessThreadEvent(wxEvent& event)
+bool wxEvtHandler::ProcessThreadEvent(const wxEvent& event)
{
// check that we are really in a child thread
wxASSERT_MSG( !wxThread::IsMain(),
#endif // wxUSE_THREADS
-void wxEvtHandler::AddPendingEvent(wxEvent& event)
+void wxEvtHandler::AddPendingEvent(const wxEvent& event)
{
// 1) Add event to list of pending events of this event handler
// 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
// Try going down the event handler chain
if ( GetNextHandler() )
{
- if ( GetNextHandler()->ProcessEvent(event) )
- return true;
+ // notice that we shouldn't let the parent have the event even if the
+ // next handler does not process it because it will have already passed
+ // it to the parent in this case
+ return GetNextHandler()->ProcessEvent(event);
}
// Finally propagate the event upwards the window chain and/or to the
return TryParent(event);
}
+bool wxEvtHandler::SafelyProcessEvent(wxEvent& event)
+{
+#if wxUSE_EXCEPTIONS
+ try
+ {
+#endif
+ return ProcessEvent(event);
+#if wxUSE_EXCEPTIONS
+ }
+ catch ( ... )
+ {
+ wxEventLoopBase *loop = wxEventLoopBase::GetActive();
+ try
+ {
+ if ( !wxTheApp || !wxTheApp->OnExceptionInMainLoop() )
+ {
+ if ( loop )
+ loop->Exit();
+ }
+ //else: continue running current event loop
+
+ return false;
+ }
+ catch ( ... )
+ {
+ // OnExceptionInMainLoop() threw, possibly rethrowing the same
+ // exception again: very good, but we still need Exit() to
+ // be called
+ if ( loop )
+ loop->Exit();
+ throw;
+ }
+ }
+#endif // wxUSE_EXCEPTIONS
+}
+
bool wxEvtHandler::SearchEventTable(wxEventTable& table, wxEvent& event)
{
wxEventBlocker::~wxEventBlocker()
{
wxEvtHandler *popped = m_window->PopEventHandler(false);
- wxCHECK_RET(popped == this,
+ wxCHECK_RET(popped == this,
wxT("Don't push other event handlers into a window managed by wxEventBlocker!"));
}