1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     Event classes 
   4 // Author:      Julian Smart 
   8 // Copyright:   (c) Julian Smart and Markus Holzem 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "event.h" 
  16 // For compilers that support precompilation, includes "wx.h". 
  17 #include "wx/wxprec.h" 
  25 #include "wx/control.h" 
  32 #include "wx/validate.h" 
  34 #if !USE_SHARED_LIBRARY 
  35 IMPLEMENT_DYNAMIC_CLASS(wxEvtHandler
, wxObject
) 
  36 IMPLEMENT_ABSTRACT_CLASS(wxEvent
, wxObject
) 
  37 IMPLEMENT_DYNAMIC_CLASS(wxCommandEvent
, wxEvent
) 
  38 IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent
, wxCommandEvent
) 
  39 IMPLEMENT_DYNAMIC_CLASS(wxMouseEvent
, wxEvent
) 
  40 IMPLEMENT_DYNAMIC_CLASS(wxKeyEvent
, wxEvent
) 
  41 IMPLEMENT_DYNAMIC_CLASS(wxSizeEvent
, wxEvent
) 
  42 IMPLEMENT_DYNAMIC_CLASS(wxPaintEvent
, wxEvent
) 
  43 IMPLEMENT_DYNAMIC_CLASS(wxEraseEvent
, wxEvent
) 
  44 IMPLEMENT_DYNAMIC_CLASS(wxMoveEvent
, wxEvent
) 
  45 IMPLEMENT_DYNAMIC_CLASS(wxFocusEvent
, wxEvent
) 
  46 IMPLEMENT_DYNAMIC_CLASS(wxCloseEvent
, wxEvent
) 
  47 IMPLEMENT_DYNAMIC_CLASS(wxShowEvent
, wxEvent
) 
  48 IMPLEMENT_DYNAMIC_CLASS(wxMaximizeEvent
, wxEvent
) 
  49 IMPLEMENT_DYNAMIC_CLASS(wxIconizeEvent
, wxEvent
) 
  50 IMPLEMENT_DYNAMIC_CLASS(wxMenuEvent
, wxEvent
) 
  51 IMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent
, wxEvent
) 
  52 IMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent
, wxEvent
) 
  53 IMPLEMENT_DYNAMIC_CLASS(wxActivateEvent
, wxEvent
) 
  54 IMPLEMENT_DYNAMIC_CLASS(wxInitDialogEvent
, wxEvent
) 
  55 IMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent
, wxEvent
) 
  56 IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent
, wxEvent
) 
  57 IMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent
, wxCommandEvent
) 
  58 IMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent
, wxCommandEvent
) 
  59 IMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent
, wxEvent
) 
  60 IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent
, wxEvent
) 
  62 const wxEventTable 
*wxEvtHandler::GetEventTable() const { return &wxEvtHandler::sm_eventTable
; } 
  64 const wxEventTable 
wxEvtHandler::sm_eventTable 
= 
  65         { (const wxEventTable 
*) NULL
, &wxEvtHandler::sm_eventTableEntries
[0] }; 
  67 const wxEventTableEntry 
wxEvtHandler::sm_eventTableEntries
[] = { { 0, 0, 0, 
  69 // stupid SGI compiler --- offer aug 98 
  79  * General wxWindows events, covering 
  80  * all interesting things that might happen (button clicking, resizing, 
  81  * setting text in widgets, etc.). 
  83  * For each completely new event type, derive a new event class. 
  87 wxEvent::wxEvent(int theId
) 
  89   m_eventType 
= wxEVT_NULL
; 
  90   m_eventObject 
= (wxObject 
*) NULL
; 
  91   m_eventHandle 
= (char *) NULL
; 
  95   m_callbackUserData 
= (wxObject 
*) NULL
; 
 103 wxCommandEvent::wxCommandEvent(wxEventType commandType
, int theId
) 
 105   m_eventType 
= commandType
; 
 106   m_clientData 
= (char *) NULL
; 
 110   m_commandString 
= (char *) NULL
; 
 117 wxScrollEvent::wxScrollEvent(wxEventType commandType
, int id
, int pos
, int orient
): 
 118   wxCommandEvent(commandType
, id
) 
 120   m_extraLong 
= orient
; 
 130 wxMouseEvent::wxMouseEvent(wxEventType commandType
) 
 132   m_eventType 
= commandType
; 
 135   m_controlDown 
= FALSE
; 
 139   m_middleDown 
= FALSE
; 
 144 // True if was a button dclick event (1 = left, 2 = middle, 3 = right) 
 145 // or any button dclick event (but = -1) 
 146 bool wxMouseEvent::ButtonDClick(int but
) const 
 150       return (LeftDClick() || MiddleDClick() || RightDClick()); 
 154       return MiddleDClick(); 
 156       return RightDClick(); 
 163 // True if was a button down event (1 = left, 2 = middle, 3 = right) 
 164 // or any button down event (but = -1) 
 165 bool wxMouseEvent::ButtonDown(int but
) const 
 169       return (LeftDown() || MiddleDown() || RightDown()); 
 182 // True if was a button up event (1 = left, 2 = middle, 3 = right) 
 183 // or any button up event (but = -1) 
 184 bool wxMouseEvent::ButtonUp(int but
) const 
 188       return (LeftUp() || MiddleUp() || RightUp()); 
 201 // True if the given button is currently changing state 
 202 bool wxMouseEvent::Button(int but
) const 
 206       return (ButtonUp(-1) || ButtonDown(-1) || ButtonDClick(-1)) ; 
 208       return (LeftDown() || LeftUp() || LeftDClick()); 
 210       return (MiddleDown() || MiddleUp() || MiddleDClick()); 
 212       return (RightDown() || RightUp() || RightDClick()); 
 219 bool wxMouseEvent::ButtonIsDown(int but
) const 
 223       return (LeftIsDown() || MiddleIsDown() || RightIsDown()); 
 227       return MiddleIsDown(); 
 229       return RightIsDown(); 
 236 // Find the logical position of the event given the DC 
 237 wxPoint 
wxMouseEvent::GetLogicalPosition(const wxDC
& dc
) const 
 239     wxPoint 
pt(dc
.DeviceToLogicalX(m_x
), dc
.DeviceToLogicalY(m_y
)); 
 249 wxKeyEvent::wxKeyEvent(wxEventType type
) 
 253   m_controlDown 
= FALSE
; 
 263 wxEvtHandler::wxEvtHandler(void) 
 265   m_clientData 
= (char *) NULL
; 
 266   m_nextHandler 
= (wxEvtHandler 
*) NULL
; 
 267   m_previousHandler 
= (wxEvtHandler 
*) NULL
; 
 269   m_dynamicEvents 
= (wxList 
*) NULL
; 
 272 wxEvtHandler::~wxEvtHandler(void) 
 274   // Takes itself out of the list of handlers 
 275   if (m_previousHandler
) 
 276     m_previousHandler
->m_nextHandler 
= m_nextHandler
; 
 279     m_nextHandler
->m_previousHandler 
= m_previousHandler
; 
 283     wxNode 
*node 
= m_dynamicEvents
->First(); 
 286       wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->Data(); 
 287       if (entry
->m_callbackUserData
) delete entry
->m_callbackUserData
; 
 291     delete m_dynamicEvents
; 
 299 bool wxEvtHandler::ProcessEvent(wxEvent
& event
) 
 301   // An event handler can be enabled or disabled 
 302   if ( GetEvtHandlerEnabled() ) 
 304     // Handle per-instance dynamic event tables first 
 306     if (SearchDynamicEventTable( event 
)) return TRUE
; 
 308     // Then static per-class event tables   
 310     const wxEventTable 
*table 
= GetEventTable(); 
 312     // Try the associated validator first, if this is a window. 
 313     // Problem: if the event handler of the window has been replaced, 
 314     // this wxEvtHandler may no longer be a window. 
 315     // Therefore validators won't be processed if the handler 
 316     // has been replaced with SetEventHandler. 
 317     // THIS CAN BE CURED if PushEventHandler is used instead of 
 318     // SetEventHandler, and then processing will be passed down the 
 319     // chain of event handlers. 
 320     if (IsKindOf(CLASSINFO(wxWindow
))) 
 322         wxWindow 
*win 
= (wxWindow 
*)this; 
 324       // Can only use the validator of the window which 
 325       // is receiving the event 
 326       if ( (win 
== event
.GetEventObject()) && 
 327           win
->GetValidator() && 
 328           win
->GetValidator()->ProcessEvent(event
)) 
 332     // Search upwards through the inheritance hierarchy 
 335       if (SearchEventTable((wxEventTable
&)*table
, event
)) 
 337       table 
= table
->baseTable
; 
 341   // Try going down the event handler chain 
 342   if ( GetNextHandler() ) 
 344         if ( GetNextHandler()->ProcessEvent(event
) ) 
 348   // Carry on up the parent-child hierarchy, 
 349   // but only if event is a command event: it wouldn't 
 350   // make sense for a parent to receive a child's size event, for example 
 351   if (IsKindOf(CLASSINFO(wxWindow
)) && event
.IsKindOf(CLASSINFO(wxCommandEvent
))) 
 353     wxWindow 
*win 
= (wxWindow 
*)this; 
 354     wxWindow 
*parent 
= win
->GetParent(); 
 355     if (parent 
&& !parent
->IsBeingDeleted()) 
 356       return win
->GetParent()->GetEventHandler()->ProcessEvent(event
); 
 359   // Last try - application object. 
 360   // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always swallow it. 
 361   // wxEVT_IDLE is sent explicitly to wxApp so it will be processed appropriately 
 362   // via SearchEventTable. 
 363   if (wxTheApp 
&& this != wxTheApp 
&& (event
.GetEventType() != wxEVT_IDLE
) && wxTheApp
->ProcessEvent(event
)) 
 369 bool wxEvtHandler::SearchEventTable(wxEventTable
& table
, wxEvent
& event
) 
 372   int commandId 
= event
.GetId(); 
 374   while (table
.entries
[i
].m_fn 
!=  
 382 //    wxEventType eventType = (wxEventType) table.entries[i].m_eventType; 
 384     if ((event
.GetEventType() == table
.entries
[i
].m_eventType
) && 
 385         (table
.entries
[i
].m_id 
== -1 || // Match, if event spec says any id will do (id == -1) 
 386           (table
.entries
[i
].m_lastId 
== -1 && commandId 
== table
.entries
[i
].m_id
) || 
 387           (table
.entries
[i
].m_lastId 
!= -1 && 
 388             (commandId 
>= table
.entries
[i
].m_id 
&& commandId 
<= table
.entries
[i
].m_lastId
)))) 
 391                 event
.m_callbackUserData 
= table
.entries
[i
].m_callbackUserData
; 
 393         (this->*((wxEventFunction
) (table
.entries
[i
].m_fn
)))(event
); 
 395         if ( event
.GetSkipped() ) 
 405 void wxEvtHandler::Connect( int id
, int lastId
, 
 407                     wxObjectEventFunction func
, 
 410   wxEventTableEntry 
*entry 
= new wxEventTableEntry
; 
 412   entry
->m_lastId 
= lastId
; 
 413   entry
->m_eventType 
= eventType
; 
 415   entry
->m_callbackUserData 
= userData
; 
 417   if (!m_dynamicEvents
)  
 418     m_dynamicEvents 
= new wxList
; 
 420   m_dynamicEvents
->Append( (wxObject
*) entry 
); 
 423 bool wxEvtHandler::SearchDynamicEventTable( wxEvent
& event 
) 
 425   if (!m_dynamicEvents
) return FALSE
; 
 427   int commandId 
= event
.GetId(); 
 429   wxNode 
*node 
= m_dynamicEvents
->First(); 
 432     wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->Data(); 
 434 //    wxEventType eventType = (wxEventType) entry->m_eventType; 
 438     if ((event
.GetEventType() == entry
->m_eventType
) && 
 439         (entry
->m_id 
== -1 ||     // Match, if event spec says any id will do (id == -1) 
 440         (entry
->m_lastId 
== -1 && commandId 
== entry
->m_id
) || 
 441         (entry
->m_lastId 
!= -1 && 
 442         (commandId 
>= entry
->m_id 
&& commandId 
<= entry
->m_lastId
)))) 
 445           event
.m_callbackUserData 
= entry
->m_callbackUserData
; 
 447           (this->*((wxEventFunction
) (entry
->m_fn
)))(event
); 
 449       if (event
.GetSkipped())  
 460 bool wxEvtHandler::OnClose(void) 
 462     if (GetNextHandler()) return GetNextHandler()->OnClose();