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(wxNotifyEvent
, wxCommandEvent
) 
  39 IMPLEMENT_DYNAMIC_CLASS(wxScrollEvent
, wxCommandEvent
) 
  40 IMPLEMENT_DYNAMIC_CLASS(wxMouseEvent
, wxEvent
) 
  41 IMPLEMENT_DYNAMIC_CLASS(wxKeyEvent
, wxEvent
) 
  42 IMPLEMENT_DYNAMIC_CLASS(wxSizeEvent
, wxEvent
) 
  43 IMPLEMENT_DYNAMIC_CLASS(wxPaintEvent
, wxEvent
) 
  44 IMPLEMENT_DYNAMIC_CLASS(wxEraseEvent
, wxEvent
) 
  45 IMPLEMENT_DYNAMIC_CLASS(wxMoveEvent
, wxEvent
) 
  46 IMPLEMENT_DYNAMIC_CLASS(wxFocusEvent
, wxEvent
) 
  47 IMPLEMENT_DYNAMIC_CLASS(wxCloseEvent
, wxEvent
) 
  48 IMPLEMENT_DYNAMIC_CLASS(wxShowEvent
, wxEvent
) 
  49 IMPLEMENT_DYNAMIC_CLASS(wxMaximizeEvent
, wxEvent
) 
  50 IMPLEMENT_DYNAMIC_CLASS(wxIconizeEvent
, wxEvent
) 
  51 IMPLEMENT_DYNAMIC_CLASS(wxMenuEvent
, wxEvent
) 
  52 IMPLEMENT_DYNAMIC_CLASS(wxJoystickEvent
, wxEvent
) 
  53 IMPLEMENT_DYNAMIC_CLASS(wxDropFilesEvent
, wxEvent
) 
  54 IMPLEMENT_DYNAMIC_CLASS(wxActivateEvent
, wxEvent
) 
  55 IMPLEMENT_DYNAMIC_CLASS(wxInitDialogEvent
, wxEvent
) 
  56 IMPLEMENT_DYNAMIC_CLASS(wxSysColourChangedEvent
, wxEvent
) 
  57 IMPLEMENT_DYNAMIC_CLASS(wxIdleEvent
, wxEvent
) 
  58 IMPLEMENT_DYNAMIC_CLASS(wxUpdateUIEvent
, wxCommandEvent
) 
  59 IMPLEMENT_DYNAMIC_CLASS(wxNavigationKeyEvent
, wxCommandEvent
) 
  60 IMPLEMENT_DYNAMIC_CLASS(wxPaletteChangedEvent
, wxEvent
) 
  61 IMPLEMENT_DYNAMIC_CLASS(wxQueryNewPaletteEvent
, wxEvent
) 
  63 const wxEventTable 
*wxEvtHandler::GetEventTable() const { return &wxEvtHandler::sm_eventTable
; } 
  65 const wxEventTable 
wxEvtHandler::sm_eventTable 
= 
  66         { (const wxEventTable 
*) NULL
, &wxEvtHandler::sm_eventTableEntries
[0] }; 
  68 const wxEventTableEntry 
wxEvtHandler::sm_eventTableEntries
[] = { { 0, 0, 0, 
  70 // stupid SGI compiler --- offer aug 98 
  80  * General wxWindows events, covering 
  81  * all interesting things that might happen (button clicking, resizing, 
  82  * setting text in widgets, etc.). 
  84  * For each completely new event type, derive a new event class. 
  88 wxEvent::wxEvent(int theId
) 
  90   m_eventType 
= wxEVT_NULL
; 
  91   m_eventObject 
= (wxObject 
*) NULL
; 
  92   m_eventHandle 
= (char *) NULL
; 
  96   m_callbackUserData 
= (wxObject 
*) NULL
; 
 104 wxCommandEvent::wxCommandEvent(wxEventType commandType
, int theId
) 
 106   m_eventType 
= commandType
; 
 107   m_clientData 
= (char *) NULL
; 
 108   m_clientObject 
= (wxClientData 
*) NULL
; 
 112   m_commandString 
= (char *) NULL
; 
 119 wxScrollEvent::wxScrollEvent(wxEventType commandType
, int id
, int pos
, int orient
): 
 120   wxCommandEvent(commandType
, id
) 
 122   m_extraLong 
= orient
; 
 132 wxMouseEvent::wxMouseEvent(wxEventType commandType
) 
 134   m_eventType 
= commandType
; 
 137   m_controlDown 
= FALSE
; 
 141   m_middleDown 
= FALSE
; 
 146 // True if was a button dclick event (1 = left, 2 = middle, 3 = right) 
 147 // or any button dclick event (but = -1) 
 148 bool wxMouseEvent::ButtonDClick(int but
) const 
 152       return (LeftDClick() || MiddleDClick() || RightDClick()); 
 156       return MiddleDClick(); 
 158       return RightDClick(); 
 165 // True if was a button down event (1 = left, 2 = middle, 3 = right) 
 166 // or any button down event (but = -1) 
 167 bool wxMouseEvent::ButtonDown(int but
) const 
 171       return (LeftDown() || MiddleDown() || RightDown()); 
 184 // True if was a button up event (1 = left, 2 = middle, 3 = right) 
 185 // or any button up event (but = -1) 
 186 bool wxMouseEvent::ButtonUp(int but
) const 
 190       return (LeftUp() || MiddleUp() || RightUp()); 
 203 // True if the given button is currently changing state 
 204 bool wxMouseEvent::Button(int but
) const 
 208       return (ButtonUp(-1) || ButtonDown(-1) || ButtonDClick(-1)) ; 
 210       return (LeftDown() || LeftUp() || LeftDClick()); 
 212       return (MiddleDown() || MiddleUp() || MiddleDClick()); 
 214       return (RightDown() || RightUp() || RightDClick()); 
 221 bool wxMouseEvent::ButtonIsDown(int but
) const 
 225       return (LeftIsDown() || MiddleIsDown() || RightIsDown()); 
 229       return MiddleIsDown(); 
 231       return RightIsDown(); 
 238 // Find the logical position of the event given the DC 
 239 wxPoint 
wxMouseEvent::GetLogicalPosition(const wxDC
& dc
) const 
 241     wxPoint 
pt(dc
.DeviceToLogicalX(m_x
), dc
.DeviceToLogicalY(m_y
)); 
 251 wxKeyEvent::wxKeyEvent(wxEventType type
) 
 255   m_controlDown 
= FALSE
; 
 265 wxEvtHandler::wxEvtHandler(void) 
 267   m_nextHandler 
= (wxEvtHandler 
*) NULL
; 
 268   m_previousHandler 
= (wxEvtHandler 
*) NULL
; 
 270   m_dynamicEvents 
= (wxList 
*) NULL
; 
 273 wxEvtHandler::~wxEvtHandler(void) 
 275   // Takes itself out of the list of handlers 
 276   if (m_previousHandler
) 
 277     m_previousHandler
->m_nextHandler 
= m_nextHandler
; 
 280     m_nextHandler
->m_previousHandler 
= m_previousHandler
; 
 284     wxNode 
*node 
= m_dynamicEvents
->First(); 
 287       wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->Data(); 
 288       if (entry
->m_callbackUserData
) delete entry
->m_callbackUserData
; 
 292     delete m_dynamicEvents
; 
 300 bool wxEvtHandler::ProcessEvent(wxEvent
& event
) 
 302   // An event handler can be enabled or disabled 
 303   if ( GetEvtHandlerEnabled() ) 
 305     // Handle per-instance dynamic event tables first 
 307     if (SearchDynamicEventTable( event 
)) return TRUE
; 
 309     // Then static per-class event tables   
 311     const wxEventTable 
*table 
= GetEventTable(); 
 313     // Try the associated validator first, if this is a window. 
 314     // Problem: if the event handler of the window has been replaced, 
 315     // this wxEvtHandler may no longer be a window. 
 316     // Therefore validators won't be processed if the handler 
 317     // has been replaced with SetEventHandler. 
 318     // THIS CAN BE CURED if PushEventHandler is used instead of 
 319     // SetEventHandler, and then processing will be passed down the 
 320     // chain of event handlers. 
 321     if (IsKindOf(CLASSINFO(wxWindow
))) 
 323         wxWindow 
*win 
= (wxWindow 
*)this; 
 325       // Can only use the validator of the window which 
 326       // is receiving the event 
 327       if ( (win 
== event
.GetEventObject()) && 
 328           win
->GetValidator() && 
 329           win
->GetValidator()->ProcessEvent(event
)) 
 333     // Search upwards through the inheritance hierarchy 
 336       if (SearchEventTable((wxEventTable
&)*table
, event
)) 
 338       table 
= table
->baseTable
; 
 342   // Try going down the event handler chain 
 343   if ( GetNextHandler() ) 
 345         if ( GetNextHandler()->ProcessEvent(event
) ) 
 349   // Carry on up the parent-child hierarchy, 
 350   // but only if event is a command event: it wouldn't 
 351   // make sense for a parent to receive a child's size event, for example 
 352   if (IsKindOf(CLASSINFO(wxWindow
)) && event
.IsKindOf(CLASSINFO(wxCommandEvent
))) 
 354     wxWindow 
*win 
= (wxWindow 
*)this; 
 355     wxWindow 
*parent 
= win
->GetParent(); 
 356     if (parent 
&& !parent
->IsBeingDeleted()) 
 357       return win
->GetParent()->GetEventHandler()->ProcessEvent(event
); 
 360   // Last try - application object. 
 361   // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always swallow it. 
 362   // wxEVT_IDLE is sent explicitly to wxApp so it will be processed appropriately 
 363   // via SearchEventTable. 
 364   if (wxTheApp 
&& this != wxTheApp 
&& (event
.GetEventType() != wxEVT_IDLE
) && wxTheApp
->ProcessEvent(event
)) 
 370 bool wxEvtHandler::SearchEventTable(wxEventTable
& table
, wxEvent
& event
) 
 373   int commandId 
= event
.GetId(); 
 375   // BC++ doesn't like while (table.entries[i].m_fn) 
 377   while (table
.entries
[i
].m_fn 
!= 0L) 
 379     if ((event
.GetEventType() == table
.entries
[i
].m_eventType
) && 
 380         (table
.entries
[i
].m_id 
== -1 || // Match, if event spec says any id will do (id == -1) 
 381           (table
.entries
[i
].m_lastId 
== -1 && commandId 
== table
.entries
[i
].m_id
) || 
 382           (table
.entries
[i
].m_lastId 
!= -1 && 
 383             (commandId 
>= table
.entries
[i
].m_id 
&& commandId 
<= table
.entries
[i
].m_lastId
)))) 
 386                 event
.m_callbackUserData 
= table
.entries
[i
].m_callbackUserData
; 
 388         (this->*((wxEventFunction
) (table
.entries
[i
].m_fn
)))(event
); 
 390         if ( event
.GetSkipped() ) 
 400 void wxEvtHandler::Connect( int id
, int lastId
, 
 401                             wxEventType eventType
, 
 402                     wxObjectEventFunction func
, 
 405   wxEventTableEntry 
*entry 
= new wxEventTableEntry
; 
 407   entry
->m_lastId 
= lastId
; 
 408   entry
->m_eventType 
= eventType
; 
 410   entry
->m_callbackUserData 
= userData
; 
 412   if (!m_dynamicEvents
)  
 413     m_dynamicEvents 
= new wxList
; 
 415   m_dynamicEvents
->Append( (wxObject
*) entry 
); 
 418 bool wxEvtHandler::SearchDynamicEventTable( wxEvent
& event 
) 
 420   if (!m_dynamicEvents
) return FALSE
; 
 422   int commandId 
= event
.GetId(); 
 424   wxNode 
*node 
= m_dynamicEvents
->First(); 
 427     wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->Data(); 
 431     if ((event
.GetEventType() == entry
->m_eventType
) && 
 432         (entry
->m_id 
== -1 ||     // Match, if event spec says any id will do (id == -1) 
 433         (entry
->m_lastId 
== -1 && commandId 
== entry
->m_id
) || 
 434         (entry
->m_lastId 
!= -1 && 
 435         (commandId 
>= entry
->m_id 
&& commandId 
<= entry
->m_lastId
)))) 
 438           event
.m_callbackUserData 
= entry
->m_callbackUserData
; 
 440           (this->*((wxEventFunction
) (entry
->m_fn
)))(event
); 
 442       if (event
.GetSkipped())  
 453 bool wxEvtHandler::OnClose(void) 
 455     if (GetNextHandler()) return GetNextHandler()->OnClose();