1 ///////////////////////////////////////////////////////////////////////////// 
   4 // Author:      Stefan Csomor 
   8 // Copyright:   (c) Stefan Csomor 
   9 // Licence:     The wxWindows licence 
  10 ///////////////////////////////////////////////////////////////////////////// 
  13 #pragma implementation "toolbar.h" 
  20 #include "wx/toolbar.h" 
  21 #include "wx/notebook.h" 
  22 #include "wx/tabctrl.h" 
  23 #include "wx/bitmap.h" 
  25 #if !USE_SHARED_LIBRARY 
  26 IMPLEMENT_DYNAMIC_CLASS(wxToolBar
, wxControl
) 
  28 BEGIN_EVENT_TABLE(wxToolBar
, wxToolBarBase
) 
  29     EVT_MOUSE_EVENTS( wxToolBar::OnMouse 
)  
  30     EVT_PAINT( wxToolBar::OnPaint 
)  
  34 #include "wx/mac/uma.h" 
  35 #include "wx/geometry.h" 
  36 // ---------------------------------------------------------------------------- 
  38 // ---------------------------------------------------------------------------- 
  40 class wxToolBarTool 
: public wxToolBarToolBase
 
  43     wxToolBarTool(wxToolBar 
*tbar
, 
  45                   const wxString
& label
, 
  46                   const wxBitmap
& bmpNormal
, 
  47                   const wxBitmap
& bmpDisabled
, 
  50                   const wxString
& shortHelp
, 
  51                   const wxString
& longHelp
) ; 
  53     wxToolBarTool(wxToolBar 
*tbar
, wxControl 
*control
) 
  54         : wxToolBarToolBase(tbar
, control
) 
  61         if ( m_controlHandle 
) 
  62             DisposeControl( m_controlHandle 
) ; 
  65     ControlHandle   
GetControlHandle() { return m_controlHandle 
; } 
  66     void SetControlHandle( ControlHandle handle 
) { m_controlHandle 
= handle 
; } 
  68     void SetSize(const wxSize
& size
) ; 
  69     void SetPosition( const wxPoint
& position 
) ; 
  70     wxSize 
GetSize() const 
  74             return GetControl()->GetSize() ; 
  76         else if ( IsButton() ) 
  78             return GetToolBar()->GetToolSize() ; 
  82             wxSize sz 
= GetToolBar()->GetToolSize() ; 
  88     wxPoint 
GetPosition() const 
  90         return wxPoint(m_x
, m_y
); 
  95         m_controlHandle 
= NULL 
; 
  97     ControlHandle m_controlHandle 
; 
 103 // ============================================================================ 
 105 // ============================================================================ 
 107 // ---------------------------------------------------------------------------- 
 109 // ---------------------------------------------------------------------------- 
 111 void wxToolBarTool::SetSize(const wxSize
& size
) 
 115         GetControl()->SetSize( size 
) ; 
 119 void wxToolBarTool::SetPosition(const wxPoint
& position
) 
 128         WindowRef rootwindow 
= (WindowRef
) GetToolBar()->MacGetRootWindow() ;     
 129         GetToolBar()->MacWindowToRootWindow( &x 
, &y 
) ; 
 130         int mac_x 
= x 
+ position
.x 
; 
 131         int mac_y 
= y 
+ position
.y 
; 
 135         GetControlBounds( m_controlHandle 
, &contrlRect 
) ;  
 136         int former_mac_x 
= contrlRect
.left 
; 
 137         int former_mac_y 
= contrlRect
.top 
; 
 138         wxSize sz 
= GetToolBar()->GetToolSize() ; 
 140         if ( mac_x 
!= former_mac_x 
|| mac_y 
!= former_mac_y 
) 
 143                 Rect inval 
= { former_mac_y 
, former_mac_x 
, former_mac_y 
+ sz
.y 
, former_mac_x 
+ sz
.x 
} ; 
 144                 InvalWindowRect( rootwindow 
, &inval 
) ; 
 146             UMAMoveControl( m_controlHandle 
, mac_x 
, mac_y 
) ; 
 148                 Rect inval 
= { mac_y 
, mac_x 
, mac_y 
+ sz
.y 
, mac_x 
+ sz
.x 
} ; 
 149                 InvalWindowRect( rootwindow 
, &inval 
) ; 
 153     else if ( IsControl() ) 
 155         GetControl()->Move( position 
) ; 
 159 const short kwxMacToolBarToolDefaultWidth 
= 24 ; 
 160 const short kwxMacToolBarToolDefaultHeight 
= 22 ; 
 161 const short kwxMacToolBarTopMargin 
= 2 ; 
 162 const short kwxMacToolBarLeftMargin 
= 2 ; 
 164 wxToolBarTool::wxToolBarTool(wxToolBar 
*tbar
, 
 166   const wxString
& label
, 
 167   const wxBitmap
& bmpNormal
, 
 168   const wxBitmap
& bmpDisabled
, 
 170   wxObject 
*clientData
, 
 171   const wxString
& shortHelp
, 
 172   const wxString
& longHelp
) 
 173         : wxToolBarToolBase(tbar
, id
, label
, bmpNormal
, bmpDisabled
, kind
, 
 174                             clientData
, shortHelp
, longHelp
) 
 178     if (id 
== wxID_SEPARATOR
) return; 
 180     WindowRef window 
= (WindowRef
) tbar
->MacGetRootWindow() ;     
 181     wxSize toolSize 
= tbar
->GetToolSize() ;     
 182     Rect toolrect 
= { 0, 0 , toolSize
.y 
, toolSize
.x 
} ; 
 184     ControlButtonContentInfo info 
; 
 185     wxMacCreateBitmapButton( &info 
, GetNormalBitmap() ) ; 
 187     SInt16 behaviour 
= kControlBehaviorOffsetContents 
; 
 188     if ( CanBeToggled() ) 
 189         behaviour 
+= kControlBehaviorToggles 
; 
 191     if ( info
.contentType 
!= kControlNoContent 
)  
 193         m_controlHandle 
= ::NewControl( window 
, &toolrect 
, "\p" , false , 0 ,  
 194                                         behaviour 
+ info
.contentType 
, 0 , kControlBevelButtonNormalBevelProc 
, (long) this ) ; 
 196         ::SetControlData( m_controlHandle 
, kControlButtonPart 
, kControlBevelButtonContentTag 
, sizeof(info
) , (char*) &info 
) ; 
 200         m_controlHandle 
= ::NewControl( window 
, &toolrect 
, "\p" , false , 0 ,  
 201                                         behaviour  
, 0 , kControlBevelButtonNormalBevelProc 
, (long) this ) ; 
 203     UMAShowControl( m_controlHandle 
) ; 
 206         UMADeactivateControl( m_controlHandle 
) ; 
 208     if ( CanBeToggled() && IsToggled() ) 
 210         ::SetControl32BitValue( m_controlHandle 
, 1 ) ; 
 214         ::SetControl32BitValue( m_controlHandle 
, 0 ) ; 
 217     ControlHandle container 
= (ControlHandle
) tbar
->MacGetContainerForEmbedding() ; 
 218     wxASSERT_MSG( container 
!= NULL 
, wxT("No valid mac container control") ) ; 
 219     ::EmbedControl( m_controlHandle 
, container 
) ; 
 223 wxToolBarToolBase 
*wxToolBar::CreateTool(int id
, 
 224                                          const wxString
& label
, 
 225                                          const wxBitmap
& bmpNormal
, 
 226                                          const wxBitmap
& bmpDisabled
, 
 228                                          wxObject 
*clientData
, 
 229                                          const wxString
& shortHelp
, 
 230                                          const wxString
& longHelp
) 
 232     return new wxToolBarTool(this, id
, label
, bmpNormal
, bmpDisabled
, kind
, 
 233                              clientData
, shortHelp
, longHelp
); 
 236 wxToolBarToolBase 
*wxToolBar::CreateTool(wxControl 
*control
) 
 238     return new wxToolBarTool(this, control
); 
 241 void wxToolBar::Init() 
 245     m_defaultWidth 
= kwxMacToolBarToolDefaultWidth
; 
 246     m_defaultHeight 
= kwxMacToolBarToolDefaultHeight
; 
 249 bool wxToolBar::Create(wxWindow 
*parent
, wxWindowID id
, const wxPoint
& pos
, const wxSize
& size
, 
 250             long style
, const wxString
& name
) 
 268     m_windowStyle 
= style
; 
 269     parent
->AddChild(this); 
 271     m_backgroundColour 
= parent
->GetBackgroundColour() ; 
 272     m_foregroundColour 
= parent
->GetForegroundColour() ; 
 275         m_windowId 
= NewControlId(); 
 284         AdjustForParentClientOrigin(x
, y
, wxSIZE_USE_EXISTING
); 
 292 wxToolBar::~wxToolBar() 
 294     // we must refresh the frame size when the toolbar is deleted but the frame 
 295     // is not - otherwise toolbar leaves a hole in the place it used to occupy 
 298 bool wxToolBar::Realize() 
 300     if (m_tools
.GetCount() == 0) 
 303     int x 
= m_xMargin 
+ kwxMacToolBarLeftMargin 
; 
 304     int y 
= m_yMargin 
+ kwxMacToolBarTopMargin 
; 
 312     int maxToolWidth 
= 0; 
 313     int maxToolHeight 
= 0; 
 315     // Find the maximum tool width and height 
 316     wxToolBarToolsList::Node 
*node 
= m_tools
.GetFirst(); 
 319         wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->GetData(); 
 320         wxSize sz 
= tool
->GetSize() ; 
 322         if ( sz
.x 
> maxToolWidth 
) 
 323             maxToolWidth 
= sz
.x 
; 
 324         if (sz
.y
> maxToolHeight
) 
 325             maxToolHeight 
= sz
.y
; 
 327         node 
= node
->GetNext(); 
 330     node 
= m_tools
.GetFirst(); 
 333         wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->GetData(); 
 334         wxSize cursize 
= tool
->GetSize() ; 
 336         // for the moment we just do a single row/column alignement 
 337         if ( x 
+ cursize
.x 
> maxWidth 
) 
 338             maxWidth 
= x 
+ cursize
.x 
; 
 339         if ( y 
+ cursize
.y 
> maxHeight 
) 
 340             maxHeight 
= y 
+ cursize
.y 
; 
 342         tool
->SetPosition( wxPoint( x 
, y 
) ) ; 
 344         if ( GetWindowStyleFlag() & wxTB_VERTICAL 
) 
 353         node 
= node
->GetNext(); 
 356     if ( GetWindowStyleFlag() & wxTB_HORIZONTAL 
) 
 358         if ( m_maxRows 
== 0 ) 
 360             // if not set yet, only one row 
 364         maxHeight 
+= m_yMargin 
+ kwxMacToolBarTopMargin
; 
 365         m_maxHeight 
= maxHeight 
; 
 369         if ( GetToolsCount() > 0 && m_maxRows 
== 0 ) 
 371             // if not set yet, have one column 
 372             SetRows(GetToolsCount()); 
 375         maxWidth 
+= m_xMargin 
+ kwxMacToolBarLeftMargin
; 
 376         m_maxWidth 
= maxWidth 
; 
 379     SetSize(maxWidth
, maxHeight
); 
 384 void wxToolBar::SetToolBitmapSize(const wxSize
& size
) 
 386     m_defaultWidth 
= size
.x
+4; m_defaultHeight 
= size
.y
+4; 
 389 // The button size is bigger than the bitmap size 
 390 wxSize 
wxToolBar::GetToolSize() const 
 392     return wxSize(m_defaultWidth 
+ 4, m_defaultHeight 
+ 4); 
 395 void wxToolBar::MacHandleControlClick( WXWidget control 
, wxInt16 controlpart 
, bool WXUNUSED( mouseStillDown 
) )  
 397     wxToolBarToolsList::Node 
*node
; 
 398     for ( node 
= m_tools
.GetFirst(); node
; node 
= node
->GetNext() ) 
 400         wxToolBarTool
* tool 
= (wxToolBarTool
*) node
->GetData() ;  
 401         if ( tool
->IsButton() ) 
 403            if( tool
->GetControlHandle() == control 
)  
 405                 if ( tool
->CanBeToggled() ) 
 407                     tool
->Toggle( GetControl32BitValue( (ControlHandle
) control 
) ) ; 
 409                 OnLeftClick( tool
->GetId() , tool 
-> IsToggled() ) ; 
 416 void wxToolBar::SetRows(int nRows
) 
 418     if ( nRows 
== m_maxRows 
) 
 420         // avoid resizing the frame uselessly 
 427 void wxToolBar::MacSuperChangedPosition()  
 429     wxWindow::MacSuperChangedPosition() ; 
 433 wxToolBarToolBase 
*wxToolBar::FindToolForPosition(wxCoord x
, wxCoord y
) const 
 435     wxToolBarToolsList::Node 
*node 
= m_tools
.GetFirst(); 
 438         wxToolBarTool 
*tool 
= (wxToolBarTool 
*)node
->GetData() ; 
 439         wxRect2DInt 
r( tool
->GetPosition() , tool
->GetSize() ) ; 
 440         if ( r
.Contains( wxPoint( x 
, y 
) ) ) 
 445         node 
= node
->GetNext(); 
 448     return (wxToolBarToolBase 
*)NULL
; 
 451 wxString 
wxToolBar::MacGetToolTipString( wxPoint 
&pt 
) 
 453     wxToolBarToolBase
* tool 
= FindToolForPosition( pt
.x 
, pt
.y 
) ; 
 456         return tool
->GetShortHelp() ; 
 458     return wxEmptyString 
; 
 461 void wxToolBar::DoEnableTool(wxToolBarToolBase 
*t
, bool enable
) 
 466     wxToolBarTool 
*tool 
= (wxToolBarTool 
*)t
; 
 467     if ( tool
->IsControl() ) 
 469         tool
->GetControl()->Enable( enable 
) ; 
 471     else if ( tool
->IsButton() ) 
 474             UMAActivateControl( tool
->GetControlHandle() ) ; 
 476             UMADeactivateControl( tool
->GetControlHandle() ) ; 
 480 void wxToolBar::DoToggleTool(wxToolBarToolBase 
*t
, bool toggle
) 
 485     wxToolBarTool 
*tool 
= (wxToolBarTool 
*)t
; 
 486     if ( tool
->IsButton() ) 
 488         ::SetControl32BitValue( tool
->GetControlHandle() , toggle 
) ; 
 492 bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos
), 
 493                              wxToolBarToolBase 
*tool
) 
 495     // nothing special to do here - we relayout in Realize() later 
 501 void wxToolBar::DoSetToggle(wxToolBarToolBase 
*WXUNUSED(tool
), bool WXUNUSED(toggle
)) 
 503     wxFAIL_MSG( _T("not implemented") ); 
 506 bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos
), wxToolBarToolBase 
*tool
) 
 508     wxToolBarToolsList::Node 
*node
; 
 509     for ( node 
= m_tools
.GetFirst(); node
; node 
= node
->GetNext() ) 
 511         wxToolBarToolBase 
*tool2 
= node
->GetData(); 
 514             // let node point to the next node in the list 
 515             node 
= node
->GetNext(); 
 521     wxSize sz 
= ((wxToolBarTool
*)tool
)->GetSize() ; 
 525     // and finally reposition all the controls after this one 
 527     for ( /* node -> first after deleted */ ; node
; node 
= node
->GetNext() ) 
 529         wxToolBarTool 
*tool2 
= (wxToolBarTool
*) node
->GetData(); 
 530         wxPoint pt 
= tool2
->GetPosition() ; 
 532         if ( GetWindowStyleFlag() & wxTB_VERTICAL 
) 
 540         tool2
->SetPosition( pt 
) ; 
 546 void wxToolBar::OnPaint(wxPaintEvent
& event
) 
 549     wxMacPortSetter 
helper(&dc
) ; 
 551     Rect toolbarrect 
= { dc
.YLOG2DEVMAC(0) , dc
.XLOG2DEVMAC(0) ,  
 552         dc
.YLOG2DEVMAC(m_height
) , dc
.XLOG2DEVMAC(m_width
) } ; 
 553     UMADrawThemePlacard( &toolbarrect 
, IsEnabled() ? kThemeStateActive 
: kThemeStateInactive
) ; 
 555         wxToolBarToolsList::Node 
*node
; 
 556         for ( node 
= m_tools
.GetFirst(); node
; node 
= node
->GetNext() ) 
 558             wxToolBarTool
* tool 
= (wxToolBarTool
*) node
->GetData() ;  
 559             if ( tool
->IsButton() ) 
 561                UMADrawControl( tool
->GetControlHandle() ) ; 
 567 void  wxToolBar::OnMouse( wxMouseEvent 
&event 
)  
 569     if (event
.GetEventType() == wxEVT_LEFT_DOWN 
|| event
.GetEventType() == wxEVT_LEFT_DCLICK 
) 
 575         MacClientToRootWindow( &x 
, &y 
) ; 
 577         ControlHandle   control 
; 
 580         WindowRef   window 
= (WindowRef
) MacGetRootWindow() ; 
 587         if ( !event
.m_leftDown 
&& !event
.m_rightDown 
) 
 588             modifiers  
|= btnState 
; 
 590         if ( event
.m_shiftDown 
) 
 591             modifiers 
|= shiftKey 
; 
 593         if ( event
.m_controlDown 
) 
 594             modifiers 
|= controlKey 
; 
 596         if ( event
.m_altDown 
) 
 597             modifiers 
|= optionKey 
; 
 599         if ( event
.m_metaDown 
) 
 600             modifiers 
|= cmdKey 
; 
 602         controlpart 
= ::FindControl( localwhere 
, window 
, &control 
) ; 
 604             if ( control 
&& ::IsControlActive( control 
) ) 
 607                     controlpart 
= ::HandleControlClick( control 
, localwhere 
, modifiers 
, (ControlActionUPP
) -1 ) ; 
 608                     wxTheApp
->s_lastMouseDown 
= 0 ; 
 609                     if ( control 
&& controlpart 
!= kControlNoPart 
) // otherwise we will get the event twice 
 611                         MacHandleControlClick( control 
, controlpart 
, false /* not down anymore */ ) ; 
 619 #endif // wxUSE_TOOLBAR