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 
  64         { return &wxEvtHandler::sm_eventTable
; } 
  66     const wxEventTable 
wxEvtHandler::sm_eventTable 
= 
  67         { (const wxEventTable 
*)NULL
, &wxEvtHandler::sm_eventTableEntries
[0] }; 
  69     const wxEventTableEntry 
wxEvtHandler::sm_eventTableEntries
[] = 
  72         // stupid SGI compiler --- offer aug 98 
  79 #endif // !USE_SHARED_LIBRARY 
  82  * General wxWindows events, covering 
  83  * all interesting things that might happen (button clicking, resizing, 
  84  * setting text in widgets, etc.). 
  86  * For each completely new event type, derive a new event class. 
  90 wxEvent::wxEvent(int theId
) 
  92     m_eventType 
= wxEVT_NULL
; 
  93     m_eventObject 
= (wxObject 
*) NULL
; 
  94     m_eventHandle 
= (char *) NULL
; 
  98     m_callbackUserData 
= (wxObject 
*) NULL
; 
 106 wxCommandEvent::wxCommandEvent(wxEventType commandType
, int theId
) 
 108     m_eventType 
= commandType
; 
 109     m_clientData 
= (char *) NULL
; 
 110     m_clientObject 
= (wxClientData 
*) NULL
; 
 114     m_commandString 
= (char *) NULL
; 
 121 wxScrollEvent::wxScrollEvent(wxEventType commandType
, 
 125              : wxCommandEvent(commandType
, id
) 
 127     m_extraLong 
= orient
; 
 137 wxMouseEvent::wxMouseEvent(wxEventType commandType
) 
 139     m_eventType 
= commandType
; 
 142     m_controlDown 
= FALSE
; 
 146     m_middleDown 
= FALSE
; 
 151 // True if was a button dclick event (1 = left, 2 = middle, 3 = right) 
 152 // or any button dclick event (but = -1) 
 153 bool wxMouseEvent::ButtonDClick(int but
) const 
 158             return (LeftDClick() || MiddleDClick() || RightDClick()); 
 162             return MiddleDClick(); 
 164             return RightDClick(); 
 166             wxFAIL_MSG("invalid parameter in wxMouseEvent::ButtonDClick"); 
 172 // True if was a button down event (1 = left, 2 = middle, 3 = right) 
 173 // or any button down event (but = -1) 
 174 bool wxMouseEvent::ButtonDown(int but
) const 
 179             return (LeftDown() || MiddleDown() || RightDown()); 
 187             wxFAIL_MSG("invalid parameter in wxMouseEvent::ButtonDown"); 
 193 // True if was a button up event (1 = left, 2 = middle, 3 = right) 
 194 // or any button up event (but = -1) 
 195 bool wxMouseEvent::ButtonUp(int but
) const 
 199             return (LeftUp() || MiddleUp() || RightUp()); 
 207             wxFAIL_MSG("invalid parameter in wxMouseEvent::ButtonUp"); 
 213 // True if the given button is currently changing state 
 214 bool wxMouseEvent::Button(int but
) const 
 218             return (ButtonUp(-1) || ButtonDown(-1) || ButtonDClick(-1)) ; 
 220             return (LeftDown() || LeftUp() || LeftDClick()); 
 222             return (MiddleDown() || MiddleUp() || MiddleDClick()); 
 224             return (RightDown() || RightUp() || RightDClick()); 
 226             wxFAIL_MSG("invalid parameter in wxMouseEvent::Button"); 
 232 bool wxMouseEvent::ButtonIsDown(int but
) const 
 236             return (LeftIsDown() || MiddleIsDown() || RightIsDown()); 
 240             return MiddleIsDown(); 
 242             return RightIsDown(); 
 244             wxFAIL_MSG("invalid parameter in wxMouseEvent::ButtonIsDown"); 
 250 // Find the logical position of the event given the DC 
 251 wxPoint 
wxMouseEvent::GetLogicalPosition(const wxDC
& dc
) const 
 253     wxPoint 
pt(dc
.DeviceToLogicalX(m_x
), dc
.DeviceToLogicalY(m_y
)); 
 263 wxKeyEvent::wxKeyEvent(wxEventType type
) 
 267     m_controlDown 
= FALSE
; 
 277 wxEvtHandler::wxEvtHandler() 
 279     m_nextHandler 
= (wxEvtHandler 
*) NULL
; 
 280     m_previousHandler 
= (wxEvtHandler 
*) NULL
; 
 282     m_dynamicEvents 
= (wxList 
*) NULL
; 
 285 wxEvtHandler::~wxEvtHandler() 
 287     // Takes itself out of the list of handlers 
 288     if (m_previousHandler
) 
 289         m_previousHandler
->m_nextHandler 
= m_nextHandler
; 
 292         m_nextHandler
->m_previousHandler 
= m_previousHandler
; 
 296         wxNode 
*node 
= m_dynamicEvents
->First(); 
 299             wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->Data(); 
 300             if (entry
->m_callbackUserData
) delete entry
->m_callbackUserData
; 
 304         delete m_dynamicEvents
; 
 312 bool wxEvtHandler::ProcessEvent(wxEvent
& event
) 
 314     bool isWindow 
= IsKindOf(CLASSINFO(wxWindow
)); 
 316     // An event handler can be enabled or disabled 
 317     if ( GetEvtHandlerEnabled() ) 
 319         // Handle per-instance dynamic event tables first 
 321         if (SearchDynamicEventTable( event 
)) 
 324         // Then static per-class event tables 
 326         const wxEventTable 
*table 
= GetEventTable(); 
 328         // Try the associated validator first, if this is a window. 
 329         // Problem: if the event handler of the window has been replaced, 
 330         // this wxEvtHandler may no longer be a window. 
 331         // Therefore validators won't be processed if the handler 
 332         // has been replaced with SetEventHandler. 
 333         // THIS CAN BE CURED if PushEventHandler is used instead of 
 334         // SetEventHandler, and then processing will be passed down the 
 335         // chain of event handlers. 
 338             wxWindow 
*win 
= (wxWindow 
*)this; 
 340             // Can only use the validator of the window which 
 341             // is receiving the event 
 342             if ( (win 
== event
.GetEventObject()) && 
 343                     win
->GetValidator() && 
 344                     win
->GetValidator()->ProcessEvent(event
)) 
 350         // Search upwards through the inheritance hierarchy 
 353             if (SearchEventTable((wxEventTable
&)*table
, event
)) 
 355             table 
= table
->baseTable
; 
 359     // Try going down the event handler chain 
 360     if ( GetNextHandler() ) 
 362         if ( GetNextHandler()->ProcessEvent(event
) ) 
 366     // Carry on up the parent-child hierarchy, 
 367     // but only if event is a command event: it wouldn't 
 368     // make sense for a parent to receive a child's size event, for example 
 369     if ( isWindow 
&& event
.IsKindOf(CLASSINFO(wxCommandEvent
)) ) 
 371         wxWindow 
*win 
= (wxWindow 
*)this; 
 372         wxWindow 
*parent 
= win
->GetParent(); 
 373         if (parent 
&& !parent
->IsBeingDeleted()) 
 374             return win
->GetParent()->GetEventHandler()->ProcessEvent(event
); 
 377     // Last try - application object. 
 378     // Special case: don't pass wxEVT_IDLE to wxApp, since it'll always swallow 
 379     // it. wxEVT_IDLE is sent explicitly to wxApp so it will be processed 
 380     // appropriately via SearchEventTable. 
 381     if ( wxTheApp 
&& (this != wxTheApp
) && (event
.GetEventType() != wxEVT_IDLE
) 
 384         if ( wxTheApp
->ProcessEvent(event
) ) 
 391 bool wxEvtHandler::SearchEventTable(wxEventTable
& table
, wxEvent
& event
) 
 394     int commandId 
= event
.GetId(); 
 396     // BC++ doesn't like while (table.entries[i].m_fn) 
 399     while (table
.entries
[i
].m_fn 
!= 0) 
 401     while (table
.entries
[i
].m_fn 
!= 0L) 
 404         if ((event
.GetEventType() == table
.entries
[i
].m_eventType
) && 
 405                 (table
.entries
[i
].m_id 
== -1 || // Match, if event spec says any id will do (id == -1) 
 406                  (table
.entries
[i
].m_lastId 
== -1 && commandId 
== table
.entries
[i
].m_id
) || 
 407                  (table
.entries
[i
].m_lastId 
!= -1 && 
 408                   (commandId 
>= table
.entries
[i
].m_id 
&& commandId 
<= table
.entries
[i
].m_lastId
)))) 
 411             event
.m_callbackUserData 
= table
.entries
[i
].m_callbackUserData
; 
 413             (this->*((wxEventFunction
) (table
.entries
[i
].m_fn
)))(event
); 
 415             if ( event
.GetSkipped() ) 
 425 void wxEvtHandler::Connect( int id
, int lastId
, 
 426                             wxEventType eventType
, 
 427                             wxObjectEventFunction func
, 
 430     wxEventTableEntry 
*entry 
= new wxEventTableEntry
; 
 432     entry
->m_lastId 
= lastId
; 
 433     entry
->m_eventType 
= eventType
; 
 435     entry
->m_callbackUserData 
= userData
; 
 437     if (!m_dynamicEvents
) 
 438         m_dynamicEvents 
= new wxList
; 
 440     m_dynamicEvents
->Append( (wxObject
*) entry 
); 
 443 bool wxEvtHandler::SearchDynamicEventTable( wxEvent
& event 
) 
 445     if (!m_dynamicEvents
) return FALSE
; 
 447     int commandId 
= event
.GetId(); 
 449     wxNode 
*node 
= m_dynamicEvents
->First(); 
 452         wxEventTableEntry 
*entry 
= (wxEventTableEntry
*)node
->Data(); 
 456             // Match, if event spec says any id will do (id == -1) 
 457             if ( (event
.GetEventType() == entry
->m_eventType
) && 
 458                  (entry
->m_id 
== -1 || 
 459                   (entry
->m_lastId 
== -1 && commandId 
== entry
->m_id
) || 
 460                   (entry
->m_lastId 
!= -1 && 
 461                   (commandId 
>= entry
->m_id 
&& commandId 
<= entry
->m_lastId
))) ) 
 464                 event
.m_callbackUserData 
= entry
->m_callbackUserData
; 
 466                 (this->*((wxEventFunction
) (entry
->m_fn
)))(event
); 
 468                 if (event
.GetSkipped()) 
 479 #if WXWIN_COMPATIBILITY 
 480 bool wxEvtHandler::OnClose() 
 482     if (GetNextHandler()) 
 483         return GetNextHandler()->OnClose();