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/spinbutt.h" 
  21 IMPLEMENT_ABSTRACT_CLASS(wxControl
, wxWindow
) 
  23 BEGIN_EVENT_TABLE(wxControl
, wxControlBase
) 
  24         EVT_MOUSE_EVENTS( wxControl::OnMouseEvent 
)  
  25         EVT_CHAR( wxControl::OnKeyDown 
)  
  26         EVT_PAINT( wxControl::OnPaint 
)  
  29 #include <wx/mac/uma.h> 
  33 ControlActionUPP wxMacLiveScrollbarActionUPP 
= NULL 
; 
  35 pascal void wxMacLiveScrollbarActionProc( ControlHandle control 
, ControlPartCode partCode 
) 
  39                 wxControl
*      wx 
= (wxControl
*) GetControlReference( control 
) ; 
  42                         wx
->MacHandleControlClick( control 
, partCode 
) ; 
  47 wxControl::wxControl() 
  50                 m_macHorizontalBorder 
= 0 ; // additional pixels around the real control 
  51                 m_macVerticalBorder 
= 0 ; 
  52     m_backgroundColour 
= *wxWHITE
; 
  53     m_foregroundColour 
= *wxBLACK
; 
  54 #if WXWIN_COMPATIBILITY 
  56 #endif // WXWIN_COMPATIBILITY 
  58         if ( wxMacLiveScrollbarActionUPP 
== NULL 
) 
  60                 wxMacLiveScrollbarActionUPP 
= NewControlActionProc( wxMacLiveScrollbarActionProc 
) ; 
  64 wxControl::~wxControl() 
  66     m_isBeingDeleted 
= TRUE
; 
  67     // If we delete an item, we should initialize the parent panel, 
  68     // because it could now be invalid. 
  69     wxPanel 
*panel 
= wxDynamicCast(GetParent(), wxPanel
); 
  72         if (panel
->GetDefaultItem() == (wxButton
*) this) 
  73             panel
->SetDefaultItem(NULL
); 
  77         UMADisposeControl( m_macControl 
) ; 
  82 bool wxControl::Create(wxWindow 
*parent
, wxWindowID id
, 
  84                        const wxSize
& size
, long style
, 
  85                        const wxValidator
& validator
, 
  88     bool rval 
= wxWindow::Create(parent
, id
, pos
, size
, style
, name
); 
  91         SetValidator(validator
); 
  97 void wxControl::SetLabel(const wxString
& title
) 
 106                 if( wxApp::s_macDefaultEncodingIsPC 
) 
 107                         label 
= wxMacMakeMacStringFromPC( title 
) ; 
 111                 strcpy( (char*) maclabel 
, label 
) ; 
 112                 c2pstr( (char*) maclabel 
) ; 
 114                 ::SetControlTitle( m_macControl 
, maclabel 
) ; 
 118 wxSize 
wxControl::DoGetBestSize() const 
 120     return wxSize(20, 20); 
 123 bool wxControl::ProcessCommand (wxCommandEvent 
& event
) 
 126   // 1) A callback function (to become obsolete) 
 127   // 2) OnCommand, starting at this window and working up parent hierarchy 
 128   // 3) OnCommand then calls ProcessEvent to search the event tables. 
 129 #if WXWIN_COMPATIBILITY 
 132         (void)(*m_callback
)(this, event
); 
 137 #endif // WXWIN_COMPATIBILITY 
 139       return GetEventHandler()->ProcessEvent(event
); 
 143 // ------------------------ 
 144 wxList 
*wxWinMacControlList 
= NULL
; 
 145 wxControl 
*wxFindControlFromMacControl(ControlHandle inControl 
) 
 147     wxNode 
*node 
= wxWinMacControlList
->Find((long)inControl
); 
 150     return (wxControl 
*)node
->Data(); 
 153 void wxAssociateControlWithMacControl(ControlHandle inControl
, wxControl 
*control
) 
 155     // adding NULL WindowRef is (first) surely a result of an error and 
 156     // (secondly) breaks menu command processing 
 157     wxCHECK_RET( inControl 
!= (ControlHandle
) NULL
, "attempt to add a NULL WindowRef to window list" ); 
 159     if ( !wxWinMacControlList
->Find((long)inControl
) ) 
 160         wxWinMacControlList
->Append((long)inControl
, control
); 
 163 void wxRemoveMacControlAssociation(wxControl 
*control
) 
 165     wxWinMacControlList
->DeleteObject(control
); 
 168 void wxControl::MacPreControlCreate( wxWindow 
*parent
, wxWindowID id
, wxString label 
,  
 170                          const wxSize
& size
, long style
, 
 171                          const wxValidator
& validator
, 
 172                          const wxString
& name 
, Rect 
*outBounds 
, StringPtr maclabel 
)  
 177         SetValidator(validator
); 
 179   m_windowStyle 
= style
; 
 180   parent
->AddChild((wxButton 
*)this); 
 182   m_backgroundColour 
= parent
->GetBackgroundColour() ; 
 183   m_foregroundColour 
= parent
->GetForegroundColour() ; 
 186       m_windowId 
= NewControlId(); 
 194         AdjustForParentClientOrigin(x
, y
, wxSIZE_USE_EXISTING
); 
 202         parent
->MacClientToRootWindow( &x 
, &y 
) ; 
 203         outBounds
->top 
= y 
+ m_macVerticalBorder 
; 
 204         outBounds
->left 
= x 
+ m_macHorizontalBorder 
; 
 205         outBounds
->bottom 
= outBounds
->top 
+ m_height 
- 2 * m_macVerticalBorder
; 
 206         outBounds
->right 
= outBounds
->left 
+ m_width 
- 2 * m_macHorizontalBorder 
; 
 208         strcpy( (char*) maclabel 
, label 
) ; 
 209         if( wxApp::s_macDefaultEncodingIsPC 
) 
 211                 wxMacConvertFromPCForControls( (char*) maclabel 
) ; 
 214         c2pstr( (char*) maclabel 
) ; 
 217 void wxControl::MacPostControlCreate() 
 219         wxASSERT_MSG( m_macControl 
!= NULL 
, "No valid mac control" ) ; 
 221         if ( IsKindOf( CLASSINFO( wxScrollBar 
) ) ) 
 225         else if ( IsKindOf( CLASSINFO( wxStaticBox 
) ) ) 
 227                 ControlFontStyleRec             controlstyle 
; 
 228                 controlstyle
.flags 
= kControlUseFontMask 
; 
 229                 controlstyle
.font 
= kControlFontSmallBoldSystemFont 
; 
 231                 ::UMASetControlFontStyle( m_macControl 
, &controlstyle 
) ; 
 235                 ControlFontStyleRec             controlstyle 
; 
 236                 controlstyle
.flags 
= kControlUseFontMask 
; 
 237                 controlstyle
.font 
= kControlFontSmallSystemFont 
; 
 239                 ::UMASetControlFontStyle( m_macControl 
, &controlstyle 
) ; 
 241         ControlHandle container 
= GetParent()->MacGetContainerForEmbedding() ; 
 242         wxASSERT_MSG( container 
!= NULL 
, "No valid mac container control" ) ; 
 243         ::UMAEmbedControl( m_macControl 
, container 
) ; 
 244         MacAdjustControlRect() ; 
 245         wxAssociateControlWithMacControl( m_macControl 
, this ) ; 
 248 void wxControl::MacAdjustControlRect()  
 250         wxASSERT_MSG( m_macControl 
!= NULL 
, "No valid mac control" ) ; 
 251         if ( m_width 
== -1 || m_height 
== -1 ) 
 253                 Rect    bestsize 
= { 0 , 0 , 0 , 0 } ; 
 254                 short   baselineoffset 
; 
 256                 UMAGetBestControlRect( m_macControl 
, &bestsize 
, &baselineoffset 
) ; 
 258                 if ( EmptyRect( &bestsize 
) ) 
 261                         bestsize
.left 
= bestsize
.top 
= 0 ; 
 262                         bestsize
.right 
= 16 ; 
 263                         bestsize
.bottom 
= 16 ; 
 264                         if ( IsKindOf( CLASSINFO( wxScrollBar 
) ) ) 
 266                                 bestsize
.bottom 
= 16 ; 
 268                         else if ( IsKindOf( CLASSINFO( wxSpinButton 
) ) ) 
 270                                 bestsize
.bottom 
= 24 ;  
 276                         if ( IsKindOf( CLASSINFO( wxButton 
) ) ) 
 278                                 m_width 
= m_label
.Length() * 8 + 12 + 2 * m_macHorizontalBorder
; 
 280                         else if ( IsKindOf( CLASSINFO( wxStaticText 
) ) ) 
 282                                 m_width 
= m_label
.Length() * 8 ; 
 285                                 m_width 
= bestsize
.right 
- bestsize
.left 
+ 2 * m_macHorizontalBorder
; 
 287                 if ( m_height 
== -1 ) 
 289                         m_height 
= bestsize
.bottom 
- bestsize
.top 
; 
 293                         m_height 
+= 2 * m_macVerticalBorder
; 
 296                 wxMacDrawingHelper 
helper ( wxFindWinFromMacWindow( GetMacRootWindow() ) ) ; 
 299             UMASizeControl( m_macControl 
, m_width 
- 2 * m_macHorizontalBorder
, m_height 
-  2 * m_macVerticalBorder 
) ; 
 303 ControlHandle 
wxControl::MacGetContainerForEmbedding()  
 306                 return m_macControl 
; 
 308         return wxWindow::MacGetContainerForEmbedding() ; 
 311 void wxControl::MacSuperChangedPosition()  
 315                 int former_mac_x 
= (**m_macControl
).contrlRect
.left 
; 
 316                 int former_mac_y 
= (**m_macControl
).contrlRect
.top 
; 
 319                 GetParent()->MacClientToRootWindow( & mac_x 
, & mac_y 
) ; 
 321                 WindowRef rootwindow 
= GetMacRootWindow() ; 
 322                 wxWindow
* wxrootwindow 
= wxFindWinFromMacWindow( rootwindow 
) ; 
 323                 UMASetThemeWindowBackground( rootwindow 
, kThemeBrushDialogBackgroundActive 
, false ) ; 
 324                 wxMacDrawingHelper 
focus( wxrootwindow 
) ; 
 326                 if ( mac_x 
!= former_mac_x 
|| mac_y 
!= former_mac_y 
) 
 329                                 Rect inval 
= { former_mac_y 
, former_mac_x 
, former_mac_y 
+ m_height 
, former_mac_x 
+ m_width 
} ; 
 330                                 InvalRect( &inval 
) ; 
 332                 UMAMoveControl( m_macControl 
, mac_x 
+ m_macHorizontalBorder 
, mac_y 
+ m_macVerticalBorder 
) ; 
 334                                 Rect inval 
= { mac_y 
, mac_x 
, mac_y 
+ m_height 
, mac_x 
+ m_width 
} ; 
 335                                 InvalRect( &inval 
) ; 
 338                 if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog 
) ) ) 
 343                         UMASetThemeWindowBackground( rootwindow 
, kThemeBrushDocumentWindowBackground 
, false ) ; 
 347         wxWindow::MacSuperChangedPosition() ; 
 350 void wxControl::MacSuperEnabled( bool enabled 
)  
 355                 if ( UMAHasAppearance() ) 
 359                                 ::DeactivateControl( m_macControl ) ;  
 364                                         ::ActivateControl( m_macControl ) ; 
 371                                 ::HiliteControl( m_macControl , 255 ) ; 
 376                                         ::HiliteControl( m_macControl , 0 ) ; 
 380         wxWindow::MacSuperEnabled( enabled ) ; 
 384 void  wxControl::MacSuperShown( bool show 
)  
 390                         ::UMAHideControl( m_macControl 
) ; 
 395                                 ::UMAShowControl( m_macControl 
) ; 
 399         wxWindow::MacSuperShown( show 
) ; 
 402 void  wxControl::DoSetSize(int x
, int y
, 
 403             int width
, int height
, 
 406         if ( m_macControl 
== NULL 
) 
 408                 wxWindow::DoSetSize( x 
, y 
,width 
, height 
,sizeFlags 
) ; 
 412         WindowRef rootwindow 
= GetMacRootWindow() ; 
 413         wxWindow
* wxrootwindow 
= wxFindWinFromMacWindow( rootwindow 
) ; 
 414         UMASetThemeWindowBackground( rootwindow 
, kThemeBrushDialogBackgroundActive 
, false ) ; 
 418         int former_w 
= m_width 
; 
 419         int former_h 
= m_height 
; 
 421         int former_mac_x 
= (**m_macControl
).contrlRect
.left 
; 
 422         int former_mac_y 
= (**m_macControl
).contrlRect
.top 
; 
 424   int currentX
, currentY
; 
 425   GetPosition(¤tX
, ¤tY
); 
 426   int currentW
,currentH
; 
 427   GetSize(¤tW
, ¤tH
); 
 429   int actualWidth 
= width
; 
 430   int actualHeight 
= height
; 
 433   if (x 
== -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 435   if (y 
== -1 || (sizeFlags 
& wxSIZE_ALLOW_MINUS_ONE
)) 
 438       actualWidth 
= currentW 
; 
 440       actualHeight 
= currentH 
; 
 442         if ( actualX 
== currentX 
&& actualY 
== currentY 
&& actualWidth 
== currentW 
&& actualHeight 
== currentH
) 
 445         AdjustForParentClientOrigin(actualX
, actualY
, sizeFlags
); 
 446         wxMacDrawingHelper 
focus( wxFindWinFromMacWindow( GetMacRootWindow() ) ) ; 
 448         int mac_x 
= actualX 
; 
 449         int mac_y 
= actualY 
; 
 450         GetParent()->MacClientToRootWindow( & mac_x 
, & mac_y 
) ; 
 452         if ( mac_x 
!= former_mac_x 
|| mac_y 
!= former_mac_y 
) 
 455                         Rect inval 
= { former_mac_y 
, former_mac_x 
, former_mac_y 
+ m_height 
, former_mac_x 
+ m_width 
} ; 
 456                         InvalRect( &inval 
) ; 
 458         UMAMoveControl( m_macControl 
, mac_x 
+ m_macHorizontalBorder 
, mac_y  
+ m_macVerticalBorder 
) ; 
 460                         Rect inval 
= { mac_y 
, mac_x 
, mac_y 
+ m_height 
, mac_x 
+ m_width 
} ; 
 461                         InvalRect( &inval 
) ; 
 465         if ( actualX 
!= former_x 
|| actualY 
!= former_y 
) 
 470                 MacRepositionScrollBars() ; 
 471                 // To consider -> should the parameters be the effective or the virtual coordinates (AdjustForParent..) 
 472     wxMoveEvent 
event(wxPoint(m_x
, m_y
), m_windowId
); 
 473     event
.SetEventObject(this); 
 474     GetEventHandler()->ProcessEvent(event
); 
 476         if ( actualWidth 
!= former_w 
|| actualHeight 
!= former_h 
) 
 479                         Rect inval 
= { mac_y 
, mac_x 
, mac_y 
+ former_h 
, mac_x 
+ former_w 
} ; 
 480                         InvalRect( &inval 
) ; 
 482                 m_width 
= actualWidth 
; 
 483                 m_height 
= actualHeight 
; 
 485         UMASizeControl( m_macControl 
,  m_width 
- 2 * m_macHorizontalBorder
, m_height 
-  2 * m_macVerticalBorder 
) ; 
 487                         Rect inval 
= { mac_y 
, mac_x 
, mac_y 
+ m_height 
, mac_x 
+ m_width 
} ; 
 488                         InvalRect( &inval 
) ; 
 491                 MacRepositionScrollBars() ; 
 492     wxSizeEvent 
event(wxSize(m_width
, m_height
), m_windowId
); 
 493     event
.SetEventObject(this); 
 494     GetEventHandler()->ProcessEvent(event
); 
 496         if ( wxrootwindow
->IsKindOf( CLASSINFO( wxDialog 
) ) ) 
 501                 UMASetThemeWindowBackground( rootwindow 
, kThemeBrushDocumentWindowBackground 
, false ) ; 
 505 bool  wxControl::Show(bool show
)  
 507         if ( !wxWindow::Show( show 
) ) 
 513                         ::UMAShowControl( m_macControl 
) ; 
 515                         ::UMAHideControl( m_macControl 
) ; 
 520 bool  wxControl::Enable(bool enable
)  
 522     if ( !wxWindow::Enable(enable
) ) 
 528                 if ( UMAHasAppearance() ) 
 531                                 ::ActivateControl( m_macControl 
) ; 
 533                                 ::DeactivateControl( m_macControl 
) ; 
 538                                 ::HiliteControl( m_macControl 
, 0 ) ; 
 540                                 ::HiliteControl( m_macControl 
, 255 ) ; 
 546 void wxControl::Refresh(bool eraseBack
, const wxRect 
*rect
) 
 550         wxWindow::Refresh( eraseBack 
, rect 
) ; 
 554         wxWindow::Refresh( eraseBack 
, rect 
) ; 
 558 void wxControl::OnPaint(wxPaintEvent
& event
) 
 562                 WindowRef window 
= GetMacRootWindow() ; 
 565                         wxWindow
* win 
= wxFindWinFromMacWindow( window 
) ; 
 568                                 wxMacDrawingHelper 
help( win 
) ; 
 571                                 bool                    hasTabBehind 
= false ; 
 572                                 wxWindow
* parent 
= GetParent() ; 
 575                                         if( parent
->MacGetWindowData() ) 
 577                                                 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow 
, kThemeBrushDialogBackgroundActive 
, false ) ; 
 581                                         if( parent
->IsKindOf( CLASSINFO( wxNotebook 
) ) ||  parent
->IsKindOf( CLASSINFO( wxTabCtrl 
) )) 
 583                                                 if ( ((wxControl
*)parent
)->m_macControl 
) 
 584                                                         SetUpControlBackground( ((wxControl
*)parent
)->m_macControl 
, -1 , true ) ; 
 588                                         parent 
= parent
->GetParent() ; 
 591                                 UMADrawControl( m_macControl 
) ; 
 592                                 UMASetThemeWindowBackground( win
->MacGetWindowData()->m_macWindow 
, win
->MacGetWindowData()->m_macWindowBackgroundTheme 
, false ) ; 
 598                 // wxWindow::OnPaint( event ) ; 
 601 void wxControl::OnEraseBackground(wxEraseEvent
& event
) 
 603     // In general, you don't want to erase the background of a control, 
 604     // or you'll get a flicker. 
 605     // TODO: move this 'null' function into each control that 
 610 void  wxControl::OnKeyDown( wxKeyEvent 
&event 
)  
 612         if ( m_macControl 
== NULL 
) 
 615         EventRecord 
*ev 
= wxTheApp
->MacGetCurrentEvent() ; 
 618         keychar 
= short(ev
->message 
& charCodeMask
); 
 619         keycode 
= short(ev
->message 
& keyCodeMask
) >> 8 ; 
 621         UMAHandleControlKey( m_macControl 
, keycode 
, keychar 
, ev
->modifiers 
) ; 
 624 void  wxControl::OnMouseEvent( wxMouseEvent 
&event 
)  
 626         if ( m_macControl 
== NULL 
) 
 632         if (event
.GetEventType() == wxEVT_LEFT_DOWN 
) 
 638                 MacClientToRootWindow( &x 
, &y 
) ; 
 640                 ControlHandle   control 
; 
 644                 WindowRef       window 
= GetMacRootWindow() ; 
 651                 if ( !event
.m_leftDown 
&& !event
.m_rightDown 
) 
 652                         modifiers  
|= btnState 
; 
 654                 if ( event
.m_shiftDown 
) 
 655                         modifiers 
|= shiftKey 
; 
 657                 if ( event
.m_controlDown 
) 
 658                         modifiers 
|= controlKey 
; 
 660                 if ( event
.m_altDown 
) 
 661                         modifiers 
|= optionKey 
; 
 663                 if ( event
.m_metaDown 
) 
 664                         modifiers 
|= cmdKey 
; 
 666                 controlpart 
= FindControl( localwhere 
, window 
, &control 
) ; 
 668                         if ( AcceptsFocus() && FindFocus() != this ) 
 672                         if ( control 
&& UMAIsControlActive( control 
) ) 
 675                                         if ( controlpart 
== kControlIndicatorPart 
&& !UMAHasAppearance() ) 
 676                                                 controlpart 
= UMAHandleControlClick( control 
, localwhere 
, modifiers 
, (ControlActionUPP
) NULL 
) ; 
 678                                                 controlpart 
= UMAHandleControlClick( control 
, localwhere 
, modifiers 
, (ControlActionUPP
) -1 ) ; 
 679                                         wxTheApp
->s_lastMouseDown 
= 0 ; 
 680                                         if ( controlpart 
&& ! ( ( UMAHasAppearance() || (controlpart 
!= kControlIndicatorPart
) )  
 681                                                 && (IsKindOf( CLASSINFO( wxScrollBar 
) ) ) ) ) // otherwise we will get the event twice 
 683                                                 MacHandleControlClick( control 
, controlpart 
) ; 
 691 bool wxControl::MacCanFocus() const 
 693                 { if ( m_macControl 
== NULL 
)  
 700 void wxControl::MacHandleControlClick( ControlHandle control 
, SInt16 controlpart 
)  
 702         wxASSERT_MSG( m_macControl 
!= NULL 
, "No valid mac control" ) ;