1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     The wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  12 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA) 
  13 #pragma implementation "toolbar.h" 
  16 #include "wx/wxprec.h" 
  21 #include "wx/toolbar.h" 
  22 #include "wx/notebook.h" 
  23 #include "wx/tabctrl.h" 
  24 #include "wx/bitmap.h" 
  26 #if !USE_SHARED_LIBRARY 
  27 IMPLEMENT_DYNAMIC_CLASS(wxToolBar
, wxControl
) 
  29 BEGIN_EVENT_TABLE(wxToolBar
, wxToolBarBase
) 
  30     EVT_PAINT( wxToolBar::OnPaint 
)  
  34 #include "wx/mac/uma.h" 
  35 #include "wx/geometry.h" 
  38 const short kwxMacToolBarToolDefaultWidth 
= 32 ; 
  39 const short kwxMacToolBarToolDefaultHeight 
= 32 ; 
  40 const short kwxMacToolBarTopMargin 
= 4 ; 
  41 const short kwxMacToolBarLeftMargin 
= 4 ; 
  42 const short kwxMacToolBorder 
= 0 ; 
  44 const short kwxMacToolBarToolDefaultWidth 
= 24 ; 
  45 const short kwxMacToolBarToolDefaultHeight 
= 22 ; 
  46 const short kwxMacToolBarTopMargin 
= 2 ; 
  47 const short kwxMacToolBarLeftMargin 
= 2 ; 
  48 const short kwxMacToolBorder 
= 4 ; 
  51 // ---------------------------------------------------------------------------- 
  53 // ---------------------------------------------------------------------------- 
  55 class wxToolBarTool 
: public wxToolBarToolBase
 
  58     wxToolBarTool(wxToolBar 
*tbar
, 
  60                   const wxString
& label
, 
  61                   const wxBitmap
& bmpNormal
, 
  62                   const wxBitmap
& bmpDisabled
, 
  65                   const wxString
& shortHelp
, 
  66                   const wxString
& longHelp
) ; 
  68     wxToolBarTool(wxToolBar 
*tbar
, wxControl 
*control
) 
  69         : wxToolBarToolBase(tbar
, control
) 
  76         if ( m_controlHandle 
) 
  77             DisposeControl( m_controlHandle 
) ; 
  80     WXWidget 
GetControlHandle() { return (WXWidget
) m_controlHandle 
; } 
  81     void SetControlHandle( ControlRef handle 
) { m_controlHandle 
= handle 
; } 
  83     void SetSize(const wxSize
& size
) ; 
  84     void SetPosition( const wxPoint
& position 
) ; 
  86     wxSize 
GetSize() const 
  90             return GetControl()->GetSize() ; 
  92         else if ( IsButton() ) 
  94             return GetToolBar()->GetToolSize() ; 
  98             wxSize sz 
= GetToolBar()->GetToolSize() ; 
 104     wxPoint 
GetPosition() const 
 106         return wxPoint(m_x
, m_y
); 
 108     bool DoEnable( bool enable 
) ; 
 112         m_controlHandle 
= NULL 
; 
 114     ControlRef m_controlHandle 
; 
 120 static const EventTypeSpec eventList
[] = 
 122         { kEventClassControl 
, kEventControlHit 
} , 
 125 static pascal OSStatus 
wxMacToolBarToolControlEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
 127     OSStatus result 
= eventNotHandledErr 
; 
 129     wxMacCarbonEvent 
cEvent( event 
) ; 
 131     ControlRef controlRef 
; 
 133     cEvent
.GetParameter( kEventParamDirectObject 
, &controlRef 
) ; 
 135     switch( GetEventKind( event 
) ) 
 137         case kEventControlHit 
: 
 139                 wxToolBarTool
* tbartool 
= (wxToolBarTool
*)data 
; 
 140                 if ( tbartool
->CanBeToggled() ) 
 142                     ((wxToolBar
*)tbartool
->GetToolBar())->ToggleTool(tbartool
->GetId(), GetControl32BitValue((ControlRef
)tbartool
->GetControlHandle())); 
 144                 ((wxToolBar
*)tbartool
->GetToolBar())->OnLeftClick( tbartool
->GetId() , tbartool 
-> IsToggled() ) ; 
 154 pascal OSStatus 
wxMacToolBarToolEventHandler( EventHandlerCallRef handler 
, EventRef event 
, void *data 
) 
 156     OSStatus result 
= eventNotHandledErr 
; 
 158     switch ( GetEventClass( event 
) ) 
 160         case kEventClassControl 
: 
 161             result 
= wxMacToolBarToolControlEventHandler( handler
, event
, data 
) ; 
 169 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacToolBarToolEventHandler 
) 
 171 // ============================================================================ 
 173 // ============================================================================ 
 175 // ---------------------------------------------------------------------------- 
 177 // ---------------------------------------------------------------------------- 
 179 bool wxToolBarTool::DoEnable(bool enable
) 
 183         GetControl()->Enable( enable 
) ; 
 185     else if ( IsButton() ) 
 187 #if TARGET_API_MAC_OSX 
 189             EnableControl( m_controlHandle 
) ; 
 191             DisableControl( m_controlHandle 
) ; 
 194             ActivateControl( m_controlHandle 
) ; 
 196             DeactivateControl( m_controlHandle 
) ; 
 201 void wxToolBarTool::SetSize(const wxSize
& size
) 
 205         GetControl()->SetSize( size 
) ; 
 209 void wxToolBarTool::SetPosition(const wxPoint
& position
) 
 218         int mac_x 
= position
.x 
; 
 219         int mac_y 
= position
.y 
; 
 221         wxSize toolSize 
= m_tbar
->GetToolSize() ;     
 223         if ( toolSize
.x 
>= 32 && toolSize
.y 
>= 32) 
 227         mac_x 
+= ( toolSize
.x 
- iconsize 
) / 2 ; 
 228         mac_y 
+= ( toolSize
.y 
- iconsize 
) / 2  ; 
 230         WindowRef rootwindow 
= (WindowRef
) GetToolBar()->MacGetTopLevelWindowRef() ;     
 231         GetToolBar()->MacWindowToRootWindow( &x 
, &y 
) ; 
 236         GetControlBounds( m_controlHandle 
, &contrlRect 
) ;  
 237         int former_mac_x 
= contrlRect
.left 
; 
 238         int former_mac_y 
= contrlRect
.top 
; 
 239         GetToolBar()->GetToolSize() ; 
 241         if ( mac_x 
!= former_mac_x 
|| mac_y 
!= former_mac_y 
) 
 243             UMAMoveControl( m_controlHandle 
, mac_x 
, mac_y 
) ; 
 246     else if ( IsControl() ) 
 248         GetControl()->Move( position 
) ; 
 252 wxToolBarTool::wxToolBarTool(wxToolBar 
*tbar
, 
 254   const wxString
& label
, 
 255   const wxBitmap
& bmpNormal
, 
 256   const wxBitmap
& bmpDisabled
, 
 258   wxObject 
*clientData
, 
 259   const wxString
& shortHelp
, 
 260   const wxString
& longHelp
) 
 261         : wxToolBarToolBase(tbar
, id
, label
, bmpNormal
, bmpDisabled
, kind
, 
 262                             clientData
, shortHelp
, longHelp
) 
 266     if (id 
== wxID_SEPARATOR
) return; 
 268     WindowRef window 
= (WindowRef
) tbar
->MacGetTopLevelWindowRef() ;     
 269     wxSize toolSize 
= tbar
->GetToolSize() ;     
 270     Rect toolrect 
= { 0, 0 , toolSize
.y 
, toolSize
.x 
} ; 
 272     ControlButtonContentInfo info 
; 
 273     wxMacCreateBitmapButton( &info 
, GetNormalBitmap() ) ; 
 275     SInt16 behaviour 
= kControlBehaviorOffsetContents 
; 
 276     if ( CanBeToggled() ) 
 277         behaviour 
+= kControlBehaviorToggles 
; 
 281     if ( toolSize
.x 
>= 32 && toolSize
.y 
>= 32) 
 285     toolrect
.left 
+= ( toolSize
.x 
- iconsize 
) / 2 ; 
 286     toolrect
.right 
= toolrect
.left 
+ iconsize 
; 
 287     toolrect
.top 
+= ( toolSize
.y 
- iconsize 
) / 2  ; 
 288     toolrect
.bottom 
= toolrect
.top 
+ iconsize 
; 
 289     CreateIconControl( window 
, &toolrect 
, &info 
, false , &m_controlHandle 
) ; 
 291     CreateBevelButtonControl( window 
, &toolrect 
, CFSTR("") , kControlBevelButtonNormalBevel 
, behaviour 
, &info 
,  
 292         0 , 0 , 0 , &m_controlHandle 
) ; 
 295     wxMacReleaseBitmapButton( &info 
) ; 
 297     SetBevelButtonTextPlacement( m_controlHandle , kControlBevelButtonPlaceBelowGraphic ) ; 
 298     UMASetControlTitle(  m_controlHandle , label , wxFont::GetDefaultEncoding() ) ; 
 301     InstallControlEventHandler( (ControlRef
) m_controlHandle
, GetwxMacToolBarToolEventHandlerUPP(), 
 302         GetEventTypeCount(eventList
), eventList
, this,NULL
); 
 304     UMAShowControl( m_controlHandle 
) ; 
 306     if ( CanBeToggled() && IsToggled() ) 
 307         ::SetControl32BitValue( m_controlHandle 
, 1 ) ; 
 309         ::SetControl32BitValue( m_controlHandle 
, 0 ) ; 
 311     ControlRef container 
= (ControlRef
) tbar
->GetHandle() ; 
 312     wxASSERT_MSG( container 
!= NULL 
, wxT("No valid mac container control") ) ; 
 313     ::EmbedControl( m_controlHandle 
, container 
) ; 
 317 wxToolBarToolBase 
*wxToolBar::CreateTool(int id
, 
 318                                          const wxString
& label
, 
 319                                          const wxBitmap
& bmpNormal
, 
 320                                          const wxBitmap
& bmpDisabled
, 
 322                                          wxObject 
*clientData
, 
 323                                          const wxString
& shortHelp
, 
 324                                          const wxString
& longHelp
) 
 326     return new wxToolBarTool(this, id
, label
, bmpNormal
, bmpDisabled
, kind
, 
 327                              clientData
, shortHelp
, longHelp
); 
 330 wxToolBarToolBase 
*wxToolBar::CreateTool(wxControl 
*control
) 
 332     return new wxToolBarTool(this, control
); 
 335 void wxToolBar::Init() 
 339     m_defaultWidth 
= kwxMacToolBarToolDefaultWidth
; 
 340     m_defaultHeight 
= kwxMacToolBarToolDefaultHeight
; 
 343 bool wxToolBar::Create(wxWindow 
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, 
 344             long style
, const wxString
& name
) 
 347     if ( !wxToolBarBase::Create( parent 
, id 
, pos 
, size 
, style 
) ) 
 353 wxToolBar::~wxToolBar() 
 355     // we must refresh the frame size when the toolbar is deleted but the frame 
 356     // is not - otherwise toolbar leaves a hole in the place it used to occupy 
 359 bool wxToolBar::Realize() 
 361     if (m_tools
.GetCount() == 0) 
 364     int x 
= m_xMargin 
+ kwxMacToolBarLeftMargin 
; 
 365     int y 
= m_yMargin 
+ kwxMacToolBarTopMargin 
; 
 373     int maxToolWidth 
= 0; 
 374     int maxToolHeight 
= 0; 
 376     // Find the maximum tool width and height 
 377     wxToolBarToolsList::compatibility_iterator node 
= m_tools
.GetFirst(); 
 380         wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->GetData(); 
 381         wxSize sz 
= tool
->GetSize() ; 
 383         if ( sz
.x 
> maxToolWidth 
) 
 384             maxToolWidth 
= sz
.x 
; 
 385         if (sz
.y
> maxToolHeight
) 
 386             maxToolHeight 
= sz
.y
; 
 388         node 
= node
->GetNext(); 
 391     bool lastWasRadio 
= FALSE
; 
 392     node 
= m_tools
.GetFirst(); 
 395         wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->GetData(); 
 396         wxSize cursize 
= tool
->GetSize() ; 
 398         bool isRadio 
= FALSE
; 
 400         if ( tool
->IsButton() && tool
->GetKind() == wxITEM_RADIO 
) 
 404                 if (tool
->Toggle(true)) 
 406                     DoToggleTool(tool
, true); 
 415         lastWasRadio 
= isRadio
; 
 417         // for the moment we just do a single row/column alignement 
 418         if ( x 
+ cursize
.x 
> maxWidth 
) 
 419             maxWidth 
= x 
+ cursize
.x 
; 
 420         if ( y 
+ cursize
.y 
> maxHeight 
) 
 421             maxHeight 
= y 
+ cursize
.y 
; 
 423         tool
->SetPosition( wxPoint( x 
, y 
) ) ; 
 425         if ( GetWindowStyleFlag() & wxTB_VERTICAL 
) 
 434         node 
= node
->GetNext(); 
 437     if ( GetWindowStyleFlag() & wxTB_HORIZONTAL 
) 
 439         if ( m_maxRows 
== 0 ) 
 441             // if not set yet, only one row 
 444         m_minWidth 
= maxWidth
; 
 446         maxHeight 
+= m_yMargin 
+ kwxMacToolBarTopMargin
; 
 447         m_minHeight 
= m_maxHeight 
= maxHeight 
; 
 451         if ( GetToolsCount() > 0 && m_maxRows 
== 0 ) 
 453             // if not set yet, have one column 
 454             SetRows(GetToolsCount()); 
 456         m_minHeight 
= maxHeight
; 
 458         maxWidth 
+= m_xMargin 
+ kwxMacToolBarLeftMargin
; 
 459         m_minWidth 
= m_maxWidth 
= maxWidth 
; 
 462     SetSize( maxWidth
, maxHeight 
); 
 463     InvalidateBestSize(); 
 468 void wxToolBar::SetToolBitmapSize(const wxSize
& size
) 
 470     m_defaultWidth 
= size
.x
+kwxMacToolBorder
; m_defaultHeight 
= size
.y
+kwxMacToolBorder
; 
 473 // The button size is bigger than the bitmap size 
 474 wxSize 
wxToolBar::GetToolSize() const 
 476     return wxSize(m_defaultWidth 
+ kwxMacToolBorder
, m_defaultHeight 
+ kwxMacToolBorder
); 
 479 void wxToolBar::SetRows(int nRows
) 
 481     if ( nRows 
== m_maxRows 
) 
 483         // avoid resizing the frame uselessly 
 490 void wxToolBar::MacSuperChangedPosition()  
 492     wxWindow::MacSuperChangedPosition() ; 
 496 wxToolBarToolBase 
*wxToolBar::FindToolForPosition(wxCoord x
, wxCoord y
) const 
 498     wxToolBarToolsList::compatibility_iterator node 
= m_tools
.GetFirst(); 
 501         wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->GetData() ; 
 502         wxRect2DInt 
r( tool
->GetPosition() , tool
->GetSize() ) ; 
 503         if ( r
.Contains( wxPoint( x 
, y 
) ) ) 
 508         node 
= node
->GetNext(); 
 511     return (wxToolBarToolBase 
*)NULL
; 
 514 wxString 
wxToolBar::MacGetToolTipString( wxPoint 
&pt 
) 
 516     wxToolBarToolBase
* tool 
= FindToolForPosition( pt
.x 
, pt
.y 
) ; 
 519         return tool
->GetShortHelp() ; 
 521     return wxEmptyString 
; 
 524 void wxToolBar::DoEnableTool(wxToolBarToolBase 
*t
, bool enable
) 
 526     ((wxToolBarTool
*)t
)->DoEnable( enable 
) ; 
 529 void wxToolBar::DoToggleTool(wxToolBarToolBase 
*t
, bool toggle
) 
 531     wxToolBarTool 
*tool 
= (wxToolBarTool 
*)t
; 
 532     if ( tool
->IsButton() ) 
 535         IconTransformType transform 
= toggle 
? kTransformSelected 
: kTransformNone 
; 
 536         SetControlData( (ControlRef
) tool
->GetControlHandle(), 0, kControlIconTransformTag
, sizeof( transform 
), 
 539         ::SetControl32BitValue( (ControlRef
) tool
->GetControlHandle() , toggle 
) ; 
 544 bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos
), 
 545                              wxToolBarToolBase 
*tool
) 
 547     // nothing special to do here - we relayout in Realize() later 
 549     InvalidateBestSize(); 
 554 void wxToolBar::DoSetToggle(wxToolBarToolBase 
*WXUNUSED(tool
), bool WXUNUSED(toggle
)) 
 556     wxFAIL_MSG( _T("not implemented") ); 
 559 bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos
), wxToolBarToolBase 
*tool
) 
 561     wxToolBarToolsList::compatibility_iterator node
; 
 562     for ( node 
= m_tools
.GetFirst(); node
; node 
= node
->GetNext() ) 
 564         wxToolBarToolBase 
*tool2 
= node
->GetData(); 
 567             // let node point to the next node in the list 
 568             node 
= node
->GetNext(); 
 574     wxSize sz 
= ((wxToolBarTool
*)tool
)->GetSize() ; 
 578     // and finally reposition all the controls after this one 
 580     for ( /* node -> first after deleted */ ; node
; node 
= node
->GetNext() ) 
 582         wxToolBarTool 
*tool2 
= (wxToolBarTool
*) node
->GetData(); 
 583         wxPoint pt 
= tool2
->GetPosition() ; 
 585         if ( GetWindowStyleFlag() & wxTB_VERTICAL 
) 
 593         tool2
->SetPosition( pt 
) ; 
 596     InvalidateBestSize(); 
 600 void wxToolBar::OnPaint(wxPaintEvent
& event
) 
 603 #if wxMAC_USE_CORE_GRAPHICS 
 604     // leave the background as it is (striped or metal) 
 606     wxMacPortSetter 
helper(&dc
) ; 
 610     Rect toolbarrect 
= { dc
.YLOG2DEVMAC(0) , dc
.XLOG2DEVMAC(0) ,  
 611         dc
.YLOG2DEVMAC(h
) , dc
.XLOG2DEVMAC(w
) } ; 
 613     if( toolbarrect.left < 0 ) 
 614         toolbarrect.left = 0 ; 
 615     if ( toolbarrect.top < 0 ) 
 616         toolbarrect.top = 0 ; 
 618     if ( !MacGetTopLevelWindow()->MacGetMetalAppearance() ) 
 620         UMADrawThemePlacard( &toolbarrect 
, IsEnabled() ? kThemeStateActive 
: kThemeStateInactive
) ; 
 624 #if TARGET_API_MAC_OSX 
 625 #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2 
 626         if ( UMAGetSystemVersion() >= 0x1030 ) 
 628             HIRect hiToolbarrect 
= CGRectMake( dc
.YLOG2DEVMAC(0) , dc
.XLOG2DEVMAC(0) ,  
 629             dc
.YLOG2DEVREL(h
) , dc
.XLOG2DEVREL(w
) ); 
 630             CGContextRef cgContext 
; 
 632             GetPortBounds( (CGrafPtr
) dc
.m_macPort 
, &bounds 
) ; 
 633             QDBeginCGContext( (CGrafPtr
) dc
.m_macPort 
, &cgContext 
) ; 
 634             CGContextTranslateCTM( cgContext 
, 0 , bounds
.bottom 
- bounds
.top 
) ; 
 635             CGContextScaleCTM( cgContext 
, 1 , -1 ) ; 
 638                 HIThemeBackgroundDrawInfo drawInfo 
; 
 639                 drawInfo
.version 
= 0 ; 
 640                 drawInfo
.state 
= kThemeStateActive 
; 
 641                 drawInfo
.kind 
= kThemeBackgroundMetal 
; 
 642                 HIThemeApplyBackground( &hiToolbarrect
, &drawInfo 
, cgContext
,kHIThemeOrientationNormal
) ; 
 644             QDEndCGContext( (CGrafPtr
) dc
.m_macPort 
, &cgContext 
) ; 
 649             UMADrawThemePlacard( &toolbarrect 
, IsEnabled() ? kThemeStateActive 
: kThemeStateInactive
) ; 
 658 #endif // wxUSE_TOOLBAR