X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/956b1c8553bc14c60db7c40f7ae9b7405fb30bcb..ef3f06797d8410b1dffe6244e2cc7597f5727adb:/src/common/event.cpp?ds=sidebyside diff --git a/src/common/event.cpp b/src/common/event.cpp index 59f6bc004a..c7d1d33bde 100644 --- a/src/common/event.cpp +++ b/src/common/event.cpp @@ -156,33 +156,34 @@ const wxEventType wxEVT_NULL = wxNewEventType(); wxDEFINE_EVENT( wxEVT_IDLE, wxIdleEvent ); -// Thread event +// Thread and asynchronous call events wxDEFINE_EVENT( wxEVT_THREAD, wxThreadEvent ); +wxDEFINE_EVENT( wxEVT_ASYNC_METHOD_CALL, wxAsyncMethodCallEvent ); #endif // wxUSE_BASE #if wxUSE_GUI -wxDEFINE_EVENT( wxEVT_COMMAND_BUTTON_CLICKED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_CHECKBOX_CLICKED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_CHOICE_SELECTED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_LISTBOX_SELECTED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_MENU_SELECTED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_SLIDER_UPDATED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_RADIOBOX_SELECTED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_RADIOBUTTON_SELECTED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_SCROLLBAR_UPDATED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_VLBOX_SELECTED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_COMBOBOX_SELECTED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_TOOL_RCLICKED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_TOOL_ENTER, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_SPINCTRL_UPDATED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_SPINCTRLDOUBLE_UPDATED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_TOOL_DROPDOWN_CLICKED, wxCommandEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_COMBOBOX_DROPDOWN, wxCommandEvent); -wxDEFINE_EVENT( wxEVT_COMMAND_COMBOBOX_CLOSEUP, wxCommandEvent); +wxDEFINE_EVENT( wxEVT_BUTTON, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_CHECKBOX, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_CHOICE, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_LISTBOX, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_LISTBOX_DCLICK, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_CHECKLISTBOX, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_MENU, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_SLIDER, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_RADIOBOX, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_RADIOBUTTON, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_SCROLLBAR, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_VLBOX, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_COMBOBOX, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_TOOL_RCLICKED, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_TOOL_ENTER, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_SPINCTRL, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_SPINCTRLDOUBLE, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_TOOL_DROPDOWN, wxCommandEvent ); +wxDEFINE_EVENT( wxEVT_COMBOBOX_DROPDOWN, wxCommandEvent); +wxDEFINE_EVENT( wxEVT_COMBOBOX_CLOSEUP, wxCommandEvent); // Mouse event types wxDEFINE_EVENT( wxEVT_LEFT_DOWN, wxMouseEvent ); @@ -298,9 +299,9 @@ wxDEFINE_EVENT( wxEVT_INIT_DIALOG, wxInitDialogEvent ); wxDEFINE_EVENT( wxEVT_UPDATE_UI, wxUpdateUIEvent ); // Clipboard events -wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_COPY, wxClipboardTextEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_CUT, wxClipboardTextEvent ); -wxDEFINE_EVENT( wxEVT_COMMAND_TEXT_PASTE, wxClipboardTextEvent ); +wxDEFINE_EVENT( wxEVT_TEXT_COPY, wxClipboardTextEvent ); +wxDEFINE_EVENT( wxEVT_TEXT_CUT, wxClipboardTextEvent ); +wxDEFINE_EVENT( wxEVT_TEXT_PASTE, wxClipboardTextEvent ); // Generic command events // Note: a click is a higher-level event than button down/up @@ -369,6 +370,7 @@ wxEvent::wxEvent(int theId, wxEventType commandType) m_isCommandEvent = false; m_propagationLevel = wxEVENT_PROPAGATE_NONE; m_wasProcessed = false; + m_willBeProcessedAgain = false; } wxEvent::wxEvent(const wxEvent& src) @@ -383,6 +385,7 @@ wxEvent::wxEvent(const wxEvent& src) , m_skipped(src.m_skipped) , m_isCommandEvent(src.m_isCommandEvent) , m_wasProcessed(false) + , m_willBeProcessedAgain(false) { } @@ -402,6 +405,10 @@ wxEvent& wxEvent::operator=(const wxEvent& src) // don't change m_wasProcessed + // While the original again could be passed to another handler, this one + // isn't going to be processed anywhere else by default. + m_willBeProcessedAgain = false; + return *this; } @@ -426,7 +433,7 @@ wxCommandEvent::wxCommandEvent(wxEventType commandType, int theId) wxString wxCommandEvent::GetString() const { - if (m_eventType != wxEVT_COMMAND_TEXT_UPDATED || !m_eventObject) + if (m_eventType != wxEVT_TEXT || !m_eventObject) { return m_cmdString; } @@ -736,6 +743,10 @@ wxKeyEvent::wxKeyEvent(wxEventType type) m_uniChar = WXK_NONE; #endif + m_x = + m_y = wxDefaultCoord; + m_hasPosition = false; + InitPropagation(); } @@ -759,6 +770,42 @@ wxKeyEvent::wxKeyEvent(wxEventType eventType, const wxKeyEvent& evt) InitPropagation(); } +void wxKeyEvent::InitPositionIfNecessary() const +{ + if ( m_hasPosition ) + return; + + // We're const because we're called from const Get[XY]() methods but we + // need to update the "cached" values. + wxKeyEvent& self = const_cast(*this); + self.m_hasPosition = true; + + // The only position we can possibly associate with the keyboard event on + // the platforms where it doesn't carry it already is the mouse position. + wxGetMousePosition(&self.m_x, &self.m_y); + + // If this event is associated with a window, the position should be in its + // client coordinates, but otherwise leave it in screen coordinates as what + // else can we use? + wxWindow* const win = wxDynamicCast(GetEventObject(), wxWindow); + if ( win ) + win->ScreenToClient(&self.m_x, &self.m_y); +} + +wxCoord wxKeyEvent::GetX() const +{ + InitPositionIfNecessary(); + + return m_x; +} + +wxCoord wxKeyEvent::GetY() const +{ + InitPositionIfNecessary(); + + return m_y; +} + bool wxKeyEvent::IsKeyInCategory(int category) const { switch ( GetKeyCode() ) @@ -1387,6 +1434,12 @@ bool wxEvtHandler::TryAfter(wxEvent& event) if ( GetNextHandler() ) return GetNextHandler()->TryAfter(event); + // If this event is going to be processed in another handler next, don't + // pass it to wxTheApp now, it will be done from TryAfter() of this other + // handler. + if ( event.WillBeProcessedAgain() ) + return false; + #if WXWIN_COMPATIBILITY_2_8 // as above, call the old virtual function for compatibility return TryParent(event); @@ -1524,6 +1577,17 @@ bool wxEvtHandler::TryHereOnly(wxEvent& event) if ( GetEventHashTable().HandleEvent(event, this) ) return true; +#ifdef wxHAS_CALL_AFTER + // There is an implicit entry for async method calls processing in every + // event handler: + if ( event.GetEventType() == wxEVT_ASYNC_METHOD_CALL && + event.GetEventObject() == this ) + { + static_cast(event).Execute(); + return true; + } +#endif // wxHAS_CALL_AFTER + // We don't have a handler for this event. return false; } @@ -1623,15 +1687,6 @@ wxEvtHandler::DoUnbind(int id, if (!m_dynamicEvents) return false; - // Remove connection from tracker node (wxEventConnectionRef) - wxEvtHandler *eventSink = func.GetEvtHandler(); - if ( eventSink && eventSink != this ) - { - wxEventConnectionRef *evtConnRef = FindRefInTrackerList(eventSink); - if ( evtConnRef ) - evtConnRef->DecRef(); - } - wxList::compatibility_iterator node = m_dynamicEvents->GetFirst(); while (node) { @@ -1643,6 +1698,15 @@ wxEvtHandler::DoUnbind(int id, entry->m_fn->IsMatching(func) && ((entry->m_callbackUserData == userData) || !userData)) { + // Remove connection from tracker node (wxEventConnectionRef) + wxEvtHandler *eventSink = entry->m_fn->GetEvtHandler(); + if ( eventSink && eventSink != this ) + { + wxEventConnectionRef *evtConnRef = FindRefInTrackerList(eventSink); + if ( evtConnRef ) + evtConnRef->DecRef(); + } + delete entry->m_callbackUserData; m_dynamicEvents->Erase( node ); delete entry;