1 ///////////////////////////////////////////////////////////////////////////// 
   3 // Purpose:     wxControl class 
   8 // Copyright:   (c) AUTHOR 
   9 // Licence:     wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "control.h" 
  16 #include "wx/control.h" 
  17 #include "wx/notebook.h" 
  18 #include "wx/tabctrl.h" 
  19 #include "wx/radiobox.h" 
  20 #include "wx/spinbutt.h" 
  22 #if !USE_SHARED_LIBRARY 
  23 IMPLEMENT_ABSTRACT_CLASS(wxControl
, wxWindow
) 
  25 BEGIN_EVENT_TABLE(wxControl
, wxWindow
) 
  26         EVT_MOUSE_EVENTS( wxControl::OnMouseEvent 
)  
  27         EVT_CHAR( wxControl::OnKeyDown 
)  
  28         EVT_PAINT( wxControl::OnPaint 
)  
  32 #include <wx/mac/uma.h> 
  36 ControlActionUPP wxMacLiveScrollbarActionUPP 
= NULL 
; 
  38 pascal void wxMacLiveScrollbarActionProc( ControlHandle control 
, ControlPartCode partCode 
) ; 
  39 pascal void wxMacLiveScrollbarActionProc( ControlHandle control 
, ControlPartCode partCode 
) 
  43                 wxControl
*      wx 
= (wxControl
*) GetControlReference( control 
) ; 
  46                         wx
->MacHandleControlClick( control 
, partCode 
) ; 
  51 wxControl::wxControl() 
  54         m_macHorizontalBorder 
= 0 ; // additional pixels around the real control 
  55         m_macVerticalBorder 
= 0 ; 
  56     m_backgroundColour 
= *wxWHITE
; 
  57     m_foregroundColour 
= *wxBLACK
; 
  58 #if WXWIN_COMPATIBILITY 
  60 #endif // WXWIN_COMPATIBILITY 
  62         if ( wxMacLiveScrollbarActionUPP 
== NULL 
) 
  64                 wxMacLiveScrollbarActionUPP 
= NewControlActionProc( wxMacLiveScrollbarActionProc 
) ; 
  68 bool wxControl::Create(wxWindow 
*parent
, wxWindowID id
, 
  70                        const wxSize
& size
, long style
, 
  71                        const wxValidator
& validator
, 
  75         m_macHorizontalBorder 
= 0 ; // additional pixels around the real control 
  76         m_macVerticalBorder 
= 0 ; 
  77     bool rval 
= wxWindow::Create(parent
, id
, pos
, size
, style
, name
); 
  80         SetValidator(validator
); 
  86 wxControl::~wxControl() 
  88     m_isBeingDeleted 
= TRUE
; 
  89     // If we delete an item, we should initialize the parent panel, 
  90     // because it could now be invalid. 
  91     wxPanel 
*panel 
= wxDynamicCast(GetParent(), wxPanel
); 
  94         if (panel
->GetDefaultItem() == (wxButton
*) this) 
  95             panel
->SetDefaultItem(NULL
); 
  99         UMADisposeControl( m_macControl 
) ; 
 100         m_macControl 
= NULL 
; 
 104 void wxControl::SetLabel(const wxString
& title
) 
 113                 if( wxApp::s_macDefaultEncodingIsPC 
) 
 114                         label 
= wxMacMakeMacStringFromPC( title 
) ; 
 118                 strcpy( (char*) maclabel 
, label 
) ; 
 119                 c2pstr( (char*) maclabel 
) ; 
 121                 ::SetControlTitle( m_macControl 
, maclabel 
) ; 
 125 wxSize 
wxControl::DoGetBestSize() const 
 127     return wxSize(20, 20); 
 130 bool wxControl::ProcessCommand (wxCommandEvent 
& event
) 
 133   // 1) A callback function (to become obsolete) 
 134   // 2) OnCommand, starting at this window and working up parent hierarchy 
 135   // 3) OnCommand then calls ProcessEvent to search the event tables. 
 136 #if WXWIN_COMPATIBILITY 
 139         (void)(*m_callback
)(this, event
); 
 144 #endif // WXWIN_COMPATIBILITY 
 146       return GetEventHandler()->ProcessEvent(event
); 
 150 // ------------------------ 
 151 wxList 
*wxWinMacControlList 
= NULL
; 
 152 wxControl 
*wxFindControlFromMacControl(ControlHandle inControl 
) 
 154     wxNode 
*node 
= wxWinMacControlList
->Find((long)inControl
); 
 157     return (wxControl 
*)node
->Data(); 
 160 void wxAssociateControlWithMacControl(ControlHandle inControl
, wxControl 
*control
) 
 162     // adding NULL WindowRef is (first) surely a result of an error and 
 163     // (secondly) breaks menu command processing 
 164     wxCHECK_RET( inControl 
!= (ControlHandle
) NULL
, "attempt to add a NULL WindowRef to window list" ); 
 166     if ( !wxWinMacControlList
->Find((long)inControl
) ) 
 167         wxWinMacControlList
->Append((long)inControl
, control
); 
 170 void wxRemoveMacControlAssociation(wxControl 
*control
) 
 172     wxWinMacControlList
->DeleteObject(control
); 
 175 void wxControl::MacPreControlCreate( wxWindow 
*parent
, wxWindowID id
, wxString label 
,  
 177                          const wxSize
& size
, long style
, 
 178                          const wxValidator
& validator
, 
 179                          const wxString
& name 
, Rect 
*outBounds 
, StringPtr maclabel 
)  
 184         SetValidator(validator
); 
 186   m_windowStyle 
= style
; 
 187   parent
->AddChild((wxButton 
*)this); 
 189   m_backgroundColour 
= parent
->GetBackgroundColour() ; 
 190   m_foregroundColour 
= parent
->GetForegroundColour() ; 
 193       m_windowId 
= NewControlId(); 
 201         AdjustForParentClientOrigin(x
, y
, wxSIZE_USE_EXISTING
); 
 209         parent
->MacClientToRootWindow( &x 
, &y 
) ; 
 210         outBounds
->top 
= y 
+ m_macVerticalBorder 
; 
 211         outBounds
->left 
= x 
+ m_macHorizontalBorder 
; 
 212         outBounds
->bottom 
= outBounds
->top 
+ m_height 
- 2 * m_macVerticalBorder
; 
 213         outBounds
->right 
= outBounds
->left 
+ m_width 
- 2 * m_macHorizontalBorder 
; 
 215         strcpy( (char*) maclabel 
, label 
) ; 
 216         if( wxApp::s_macDefaultEncodingIsPC 
) 
 218                 wxMacConvertFromPCForControls( (char*) maclabel 
) ; 
 221         c2pstr( (char*) maclabel 
) ; 
 224 void wxControl::MacPostControlCreate() 
 226         wxASSERT_MSG( m_macControl 
!= NULL 
, "No valid mac control" ) ; 
 228         if ( IsKindOf( CLASSINFO( wxScrollBar 
) ) ) 
 232         else if ( IsKindOf( CLASSINFO( wxStaticBox 
) ) || IsKindOf( CLASSINFO( wxRadioBox 
) ) || IsKindOf( CLASSINFO( wxButton 
) ) ) 
 234                 ControlFontStyleRec             controlstyle 
; 
 235                 controlstyle
.flags 
= kControlUseFontMask 
; 
 236                 controlstyle
.font 
= kControlFontSmallBoldSystemFont 
; 
 238                 ::UMASetControlFontStyle( m_macControl 
, &controlstyle 
) ; 
 242                 ControlFontStyleRec             controlstyle 
; 
 243                 controlstyle
.flags 
= kControlUseFontMask 
; 
 244                 controlstyle
.font 
= kControlFontSmallSystemFont 
; 
 246                 ::UMASetControlFontStyle( m_macControl 
, &controlstyle 
) ; 
 248         ControlHandle container 
= GetParent()->MacGetContainerForEmbedding() ; 
 249         wxASSERT_MSG( container 
!= NULL 
, "No valid mac container control" ) ; 
 250         ::UMAEmbedControl( m_macControl 
, container 
) ; 
 251         MacAdjustControlRect() ; 
 252         wxAssociateControlWithMacControl( m_macControl 
, this ) ; 
 255 void wxControl::MacAdjustControlRect()  
 257         wxASSERT_MSG( m_macControl 
!= NULL 
, "No valid mac control" ) ; 
 258         if ( m_width 
== -1 || m_height 
== -1 ) 
 260                 Rect    bestsize 
= { 0 , 0 , 0 , 0 } ; 
 261                 short   baselineoffset 
; 
 263                 UMAGetBestControlRect( m_macControl 
, &bestsize 
, &baselineoffset 
) ; 
 265                 if ( EmptyRect( &bestsize 
) ) 
 268                         bestsize
.left 
= bestsize
.top 
= 0 ; 
 269                         bestsize
.right 
= 16 ; 
 270                         bestsize
.bottom 
= 16 ; 
 271                         if ( IsKindOf( CLASSINFO( wxScrollBar 
) ) ) 
 273                                 bestsize
.bottom 
= 16 ; 
 275                         else if ( IsKindOf( CLASSINFO( wxSpinButton 
) ) ) 
 277                                 bestsize
.bottom 
= 24 ;  
 283                         if ( IsKindOf( CLASSINFO( wxButton 
) ) ) 
 285                                 m_width 
= m_label
.Length() * 8 + 12 ; 
 287                         else if ( IsKindOf( CLASSINFO( wxStaticText 
) ) ) 
 289                                 m_width 
= m_label
.Length() * 8 ; 
 292                                 m_width 
= bestsize
.right 
- bestsize
.left 
; 
 294                         m_width 
+= 2 * m_macHorizontalBorder 
; 
 296                 if ( m_height 
== -1 ) 
 298                         m_height 
= bestsize
.bottom 
- bestsize
.top 
; 
 302                         m_height 
+= 2 * m_macVerticalBorder
; 
 305                 wxMacDrawingHelper 
helper ( wxFindWinFromMacWindow( GetMacRootWindow() ) ) ; 
 308                 UMASizeControl( m_macControl 
, m_width 
- 2 * m_macHorizontalBorder
, m_height 
-  2 * m_macVerticalBorder 
) ; 
 312 ControlHandle 
wxControl::MacGetContainerForEmbedding()  
 315                 return m_macControl 
; 
 317         return wxWindow::MacGetContainerForEmbedding() ; 
 320 void wxControl::MacSuperChangedPosition()  
 325                 GetControlBounds( m_macControl 
, &contrlRect 
) ;  
 326                 int former_mac_x 
= contrlRect
.left 
; 
 327                 int former_mac_y 
= contrlRect
.top 
; 
 330                 GetParent()->MacClientToRootWindow( & mac_x 
, & mac_y 
) ; 
 332                 WindowRef rootwindow 
= GetMacRootWindow() ; 
 333                 wxWindow
* wxrootwindow 
= wxFindWinFromMacWindow( rootwindow 
) ; 
 334                 UMASetThemeWindowBackground( rootwindow 
, kThemeBrushDialogBackgroundActive 
, false ) ; 
 335                 wxMacDrawingHelper 
focus( wxrootwindow 
) ; 
 337                 if ( mac_x 
!= former_mac_x 
|| mac_y 
!= former_mac_y 
) 
 340                                 Rect inval 
= { former_mac_y 
, former_mac_x 
, former_mac_y 
+ m_height 
, former_mac_x 
+ m_width 
} ; 
 341                                 InvalWindowRect( rootwindow 
, &inval 
) ; 
 343                         UMAMoveControl( m_macControl 
, mac_x 
+ m_macHorizontalBorder 
, mac_y 
+ m_macVerticalBorder 
) ; 
 345                                 Rect inval 
= { mac_y 
, mac_x 
, mac_y 
+ m_height 
, mac_x 
+ m_width 
} ; 
 346                                 InvalWindowRect( rootwindow 
, &inval 
) ; 
 349                 if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog 
) ) ) 
 354                         UMASetThemeWindowBackground( rootwindow 
, kThemeBrushDocumentWindowBackground 
, false ) ; 
 358         wxWindow::MacSuperChangedPosition() ; 
 361 void wxControl::MacSuperEnabled( bool enabled 
)  
 366                 if ( UMAHasAppearance() ) 
 370                                 ::DeactivateControl( m_macControl ) ;  
 375                                         ::ActivateControl( m_macControl ) ; 
 382                                 ::HiliteControl( m_macControl , 255 ) ; 
 387                                         ::HiliteControl( m_macControl , 0 ) ; 
 391         wxWindow::MacSuperEnabled( enabled ) ; 
 395 void  wxControl::MacSuperShown( bool show 
)  
 401                         ::UMAHideControl( m_macControl 
) ; 
 406                                 ::UMAShowControl( m_macControl 
) ; 
 410         wxWindow::MacSuperShown( show 
) ; 
 413 void  wxControl::DoSetSize(int x
, int y
, 
 414             int width
, int height
, 
 417         if ( m_macControl 
== NULL 
) 
 419                 wxWindow::DoSetSize( x 
, y 
,width 
, height 
,sizeFlags 
) ; 
 423         WindowRef rootwindow 
= GetMacRootWindow() ; 
 424         wxWindow
* wxrootwindow 
= wxFindWinFromMacWindow( rootwindow 
) ; 
 425         UMASetThemeWindowBackground( rootwindow 
, kThemeBrushDialogBackgroundActive 
, false ) ; 
 429         int former_w 
= m_width 
; 
 430         int former_h 
= m_height 
; 
 433         GetControlBounds( m_macControl 
, &contrlRect 
) ;  
 434         int former_mac_x 
= contrlRect
.left 
; 
 435         int former_mac_y 
= contrlRect
.top 
; 
 437   int currentX
, currentY
; 
 438   GetPosition(¤tX
, ¤tY
); 
 439   int currentW
,currentH
; 
 440   GetSize(¤tW
, ¤tH
); 
 442   int actualWidth 
= width
; 
 443   int actualHeight 
= height
; 
 446   if (x 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 448   if (y 
== -1 && !(sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 451       actualWidth 
= currentW 
; 
 453       actualHeight 
= currentH 
; 
 455         if ( actualX 
== currentX 
&& actualY 
== currentY 
&& actualWidth 
== currentW 
&& actualHeight 
== currentH
) 
 458         AdjustForParentClientOrigin(actualX
, actualY
, sizeFlags
); 
 459         WindowRef macrootwindow 
= GetMacRootWindow() ; 
 460         wxMacDrawingHelper 
focus( wxFindWinFromMacWindow( macrootwindow 
) ) ; 
 462         int mac_x 
= actualX 
; 
 463         int mac_y 
= actualY 
; 
 464         GetParent()->MacClientToRootWindow( & mac_x 
, & mac_y 
) ; 
 466         if ( mac_x 
!= former_mac_x 
|| mac_y 
!= former_mac_y 
) 
 469                         Rect inval 
= { former_mac_y 
, former_mac_x 
, former_mac_y 
+ m_height 
, former_mac_x 
+ m_width 
} ; 
 470                         InvalWindowRect( macrootwindow
, &inval 
) ; 
 472                 UMAMoveControl( m_macControl 
, mac_x 
+ m_macHorizontalBorder 
, mac_y  
+ m_macVerticalBorder 
) ; 
 474                         Rect inval 
= { mac_y 
, mac_x 
, mac_y 
+ m_height 
, mac_x 
+ m_width 
} ; 
 475                         InvalWindowRect(macrootwindow
, &inval 
) ; 
 479         if ( actualX 
!= former_x 
|| actualY 
!= former_y 
) 
 484                 MacRepositionScrollBars() ; 
 485                 // To consider -> should the parameters be the effective or the virtual coordinates (AdjustForParent..) 
 486     wxMoveEvent 
event(wxPoint(m_x
, m_y
), m_windowId
); 
 487     event
.SetEventObject(this); 
 488     GetEventHandler()->ProcessEvent(event
); 
 490         if ( actualWidth 
!= former_w 
|| actualHeight 
!= former_h 
) 
 493                         Rect inval 
= { mac_y 
, mac_x 
, mac_y 
+ former_h 
, mac_x 
+ former_w 
} ; 
 494                         InvalWindowRect( macrootwindow
, &inval 
) ; 
 496                 m_width 
= actualWidth 
; 
 497                 m_height 
= actualHeight 
; 
 499                 UMASizeControl( m_macControl 
,  m_width 
- 2 * m_macHorizontalBorder
, m_height 
-  2 * m_macVerticalBorder 
) ; 
 501                         Rect inval 
= { mac_y 
, mac_x 
, mac_y 
+ m_height 
, mac_x 
+ m_width 
} ; 
 502                         InvalWindowRect( macrootwindow 
, &inval 
) ; 
 505                 MacRepositionScrollBars() ; 
 506     wxSizeEvent 
event(wxSize(m_width
, m_height
), m_windowId
); 
 507     event
.SetEventObject(this); 
 508     GetEventHandler()->ProcessEvent(event
); 
 510         if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog 
) ) ) 
 515                 UMASetThemeWindowBackground( rootwindow 
, kThemeBrushDocumentWindowBackground 
, false ) ; 
 519 bool  wxControl::Show(bool show
)  
 521         if ( !wxWindow::Show( show 
) ) 
 527                         ::UMAShowControl( m_macControl 
) ; 
 529                         ::UMAHideControl( m_macControl 
) ; 
 534 bool  wxControl::Enable(bool enable
)  
 536     if ( !wxWindow::Enable(enable
) ) 
 542                 if ( UMAHasAppearance() ) 
 545                                 ::ActivateControl( m_macControl 
) ; 
 547                                 ::DeactivateControl( m_macControl 
) ; 
 552                                 ::HiliteControl( m_macControl 
, 0 ) ; 
 554                                 ::HiliteControl( m_macControl 
, 255 ) ; 
 560 void wxControl::Refresh(bool eraseBack
, const wxRect 
*rect
) 
 564         wxWindow::Refresh( eraseBack 
, rect 
) ; 
 568         wxWindow::Refresh( eraseBack 
, rect 
) ; 
 572 void wxControl::MacRedrawControl() 
 576                 WindowRef window 
= GetMacRootWindow() ; 
 579                         wxWindow
* win 
= wxFindWinFromMacWindow( window 
) ; 
 582                                 wxMacDrawingHelper 
help( win 
) ; 
 583                                 // the mac control manager always assumes to have the origin at 0,0 
 586                                 bool                    hasTabBehind 
= false ; 
 587                                 wxWindow
* parent 
= GetParent() ; 
 590                                         if( parent
->MacGetWindowData() ) 
 592                                                 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow 
, kThemeBrushDialogBackgroundActive 
, false ) ; 
 596                                         if( parent
->IsKindOf( CLASSINFO( wxNotebook 
) ) ||  parent
->IsKindOf( CLASSINFO( wxTabCtrl 
) )) 
 598                                                 if ( ((wxControl
*)parent
)->m_macControl 
) 
 599                                                         SetUpControlBackground( ((wxControl
*)parent
)->m_macControl 
, -1 , true ) ; 
 603                                         parent 
= parent
->GetParent() ; 
 606                                 UMADrawControl( m_macControl 
) ; 
 607                                 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow 
, win
->MacGetWindowData()->m_macWindowBackgroundTheme 
, false ) ; 
 613 void wxControl::OnPaint(wxPaintEvent
& event
) 
 617                 WindowRef window 
= GetMacRootWindow() ; 
 620                         wxWindow
* win 
= wxFindWinFromMacWindow( window 
) ; 
 623                                 wxMacDrawingHelper 
help( win 
) ; 
 624                                 // the mac control manager always assumes to have the origin at 0,0 
 627                                 bool                    hasTabBehind 
= false ; 
 628                                 wxWindow
* parent 
= GetParent() ; 
 631                                         if( parent
->MacGetWindowData() ) 
 633                                                 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow 
, kThemeBrushDialogBackgroundActive 
, false ) ; 
 637                                         if( parent
->IsKindOf( CLASSINFO( wxNotebook 
) ) ||  parent
->IsKindOf( CLASSINFO( wxTabCtrl 
) )) 
 639                                                 if ( ((wxControl
*)parent
)->m_macControl 
) 
 640                                                         SetUpControlBackground( ((wxControl
*)parent
)->m_macControl 
, -1 , true ) ; 
 644                                         parent 
= parent
->GetParent() ; 
 647                                 UMADrawControl( m_macControl 
) ; 
 648                                 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow 
, win
->MacGetWindowData()->m_macWindowBackgroundTheme 
, false ) ; 
 654                 // wxWindow::OnPaint( event ) ; 
 657 void wxControl::OnEraseBackground(wxEraseEvent
& event
) 
 659     // In general, you don't want to erase the background of a control, 
 660     // or you'll get a flicker. 
 661     // TODO: move this 'null' function into each control that 
 666 void  wxControl::OnKeyDown( wxKeyEvent 
&event 
)  
 668         if ( m_macControl 
== NULL 
) 
 671         EventRecord 
*ev 
= wxTheApp
->MacGetCurrentEvent() ; 
 674         keychar 
= short(ev
->message 
& charCodeMask
); 
 675         keycode 
= short(ev
->message 
& keyCodeMask
) >> 8 ; 
 677         UMAHandleControlKey( m_macControl 
, keycode 
, keychar 
, ev
->modifiers 
) ; 
 680 void  wxControl::OnMouseEvent( wxMouseEvent 
&event 
)  
 682         if ( m_macControl 
== NULL 
) 
 688         if (event
.GetEventType() == wxEVT_LEFT_DOWN 
|| event
.GetEventType() == wxEVT_LEFT_DCLICK 
) 
 694                 MacClientToRootWindow( &x 
, &y 
) ; 
 696                 ControlHandle   control 
; 
 700                 WindowRef       window 
= GetMacRootWindow() ; 
 707                 if ( !event
.m_leftDown 
&& !event
.m_rightDown 
) 
 708                         modifiers  
|= btnState 
; 
 710                 if ( event
.m_shiftDown 
) 
 711                         modifiers 
|= shiftKey 
; 
 713                 if ( event
.m_controlDown 
) 
 714                         modifiers 
|= controlKey 
; 
 716                 if ( event
.m_altDown 
) 
 717                         modifiers 
|= optionKey 
; 
 719                 if ( event
.m_metaDown 
) 
 720                         modifiers 
|= cmdKey 
; 
 722                 controlpart 
= FindControl( localwhere 
, window 
, &control 
) ; 
 724                         if ( AcceptsFocus() && FindFocus() != this ) 
 728                         if ( control 
&& UMAIsControlActive( control 
) ) 
 731                                         if ( controlpart 
== kControlIndicatorPart 
&& !UMAHasAppearance() ) 
 732                                                 controlpart 
= UMAHandleControlClick( control 
, localwhere 
, modifiers 
, (ControlActionUPP
) NULL 
) ; 
 734                                                 controlpart 
= UMAHandleControlClick( control 
, localwhere 
, modifiers 
, (ControlActionUPP
) -1 ) ; 
 735                                         wxTheApp
->s_lastMouseDown 
= 0 ; 
 736                                         if ( controlpart 
&& ! ( ( UMAHasAppearance() || (controlpart 
!= kControlIndicatorPart
) )  
 737                                                 && (IsKindOf( CLASSINFO( wxScrollBar 
) ) ) ) ) // otherwise we will get the event twice 
 739                                                 MacHandleControlClick( control 
, controlpart 
) ; 
 747 bool wxControl::MacCanFocus() const 
 749                 { if ( m_macControl 
== NULL 
)  
 756 void wxControl::MacHandleControlClick( ControlHandle control 
, SInt16 controlpart 
)  
 758         wxASSERT_MSG( m_macControl 
!= NULL 
, "No valid mac control" ) ;