X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/20b6985553b4e01e7960847e3211d940aeff8742..b9efe021b554fa3967d1442cf758435c5cd5ae8f:/src/mac/carbon/toolbar.cpp diff --git a/src/mac/carbon/toolbar.cpp b/src/mac/carbon/toolbar.cpp index 7cfd6a9594..2f4ac0c6a3 100644 --- a/src/mac/carbon/toolbar.cpp +++ b/src/mac/carbon/toolbar.cpp @@ -23,16 +23,31 @@ #include "wx/tabctrl.h" #include "wx/bitmap.h" -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl) BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) EVT_PAINT( wxToolBar::OnPaint ) END_EVENT_TABLE() -#endif #include "wx/mac/uma.h" #include "wx/geometry.h" + +#ifdef __WXMAC_OSX__ +const short kwxMacToolBarToolDefaultWidth = 16 ; +const short kwxMacToolBarToolDefaultHeight = 16 ; +const short kwxMacToolBarTopMargin = 4 ; +const short kwxMacToolBarLeftMargin = 4 ; +const short kwxMacToolBorder = 0 ; +const short kwxMacToolSpacing = 6 ; +#else +const short kwxMacToolBarToolDefaultWidth = 24 ; +const short kwxMacToolBarToolDefaultHeight = 22 ; +const short kwxMacToolBarTopMargin = 2 ; +const short kwxMacToolBarLeftMargin = 2 ; +const short kwxMacToolBorder = 4 ; +const short kwxMacToolSpacing = 0 ; +#endif + // ---------------------------------------------------------------------------- // private classes // ---------------------------------------------------------------------------- @@ -68,6 +83,8 @@ public: void SetSize(const wxSize& size) ; void SetPosition( const wxPoint& position ) ; + void ClearControl() { m_control = NULL ; } + wxSize GetSize() const { if ( IsControl() ) @@ -80,9 +97,12 @@ public: } else { + // separator size wxSize sz = GetToolBar()->GetToolSize() ; - sz.x /= 4 ; - sz.y /= 4 ; + if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL ) + sz.y /= 4 ; + else + sz.x /= 4 ; return sz ; } } @@ -91,6 +111,8 @@ public: return wxPoint(m_x, m_y); } bool DoEnable( bool enable ) ; + + void UpdateToggleImage( bool toggle ) ; private : void Init() { @@ -105,6 +127,9 @@ private : static const EventTypeSpec eventList[] = { { kEventClassControl , kEventControlHit } , +#ifdef __WXMAC_OSX__ + { kEventClassControl , kEventControlHitTest } , +#endif } ; static pascal OSStatus wxMacToolBarToolControlEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) @@ -124,19 +149,38 @@ static pascal OSStatus wxMacToolBarToolControlEventHandler( EventHandlerCallRef wxToolBarTool* tbartool = (wxToolBarTool*)data ; if ( tbartool->CanBeToggled() ) { +#ifdef __WXMAC_OSX__ + ((wxToolBar*)tbartool->GetToolBar())->ToggleTool(tbartool->GetId(), !tbartool->IsToggled() ); +#else ((wxToolBar*)tbartool->GetToolBar())->ToggleTool(tbartool->GetId(), GetControl32BitValue((ControlRef)tbartool->GetControlHandle())); +#endif } ((wxToolBar*)tbartool->GetToolBar())->OnLeftClick( tbartool->GetId() , tbartool -> IsToggled() ) ; result = noErr; } break ; +#ifdef __WXMAC_OSX__ + case kEventControlHitTest : + { + HIPoint pt = cEvent.GetParameter(kEventParamMouseLocation) ; + HIRect rect ; + HIViewGetBounds( controlRef , &rect ) ; + + ControlPartCode pc = kControlNoPart ; + if ( CGRectContainsPoint( rect , pt ) ) + pc = kControlIconPart ; + cEvent.SetParameter( kEventParamControlPart , typeControlPartCode, pc ) ; + result = noErr ; + } + break ; +#endif default : break ; } return result ; } -pascal OSStatus wxMacToolBarToolEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) +static pascal OSStatus wxMacToolBarToolEventHandler( EventHandlerCallRef handler , EventRef event , void *data ) { OSStatus result = eventNotHandledErr ; @@ -196,18 +240,20 @@ void wxToolBarTool::SetPosition(const wxPoint& position) m_x = position.x; m_y = position.y; - if ( IsButton() ) + int x , y ; + x = y = 0 ; + int mac_x = position.x ; + int mac_y = position.y ; + + if ( ! GetToolBar()->MacGetTopLevelWindow()->MacUsesCompositing() ) { - int x , y ; - x = y = 0 ; - int mac_x = position.x ; - int mac_y = position.y ; -#if !TARGET_API_MAC_OSX - WindowRef rootwindow = (WindowRef) GetToolBar()->MacGetTopLevelWindowRef() ; GetToolBar()->MacWindowToRootWindow( &x , &y ) ; mac_x += x; mac_y += y; -#endif + } + + if ( IsButton() ) + { Rect contrlRect ; GetControlBounds( m_controlHandle , &contrlRect ) ; int former_mac_x = contrlRect.left ; @@ -223,12 +269,62 @@ void wxToolBarTool::SetPosition(const wxPoint& position) { GetControl()->Move( position ) ; } + else + { + // separator +#ifdef __WXMAC_OSX__ + Rect contrlRect ; + GetControlBounds( m_controlHandle , &contrlRect ) ; + int former_mac_x = contrlRect.left ; + int former_mac_y = contrlRect.top ; + + if ( mac_x != former_mac_x || mac_y != former_mac_y ) + { + UMAMoveControl( m_controlHandle , mac_x , mac_y ) ; + } +#endif + } } -const short kwxMacToolBarToolDefaultWidth = 24 ; -const short kwxMacToolBarToolDefaultHeight = 22 ; -const short kwxMacToolBarTopMargin = 2 ; -const short kwxMacToolBarLeftMargin = 2 ; +void wxToolBarTool::UpdateToggleImage( bool toggle ) +{ +#ifdef __WXMAC_OSX__ + if ( toggle ) + { + int w = m_bmpNormal.GetWidth() ; + int h = m_bmpNormal.GetHeight() ; + wxBitmap bmp( w , h ) ; + wxMemoryDC dc ; + dc.SelectObject( bmp ) ; + dc.SetPen( wxNullPen ) ; + dc.SetBackground( *wxWHITE ) ; + dc.DrawRectangle( 0 , 0 , w , h ) ; + dc.DrawBitmap( m_bmpNormal , 0 , 0 , true) ; + dc.SelectObject( wxNullBitmap ) ; + ControlButtonContentInfo info ; + wxMacCreateBitmapButton( &info , bmp ) ; + SetControlData( m_controlHandle , 0, kControlIconContentTag, sizeof( info ), + (Ptr)&info ); + wxMacReleaseBitmapButton( &info ) ; + } + else + { + ControlButtonContentInfo info ; + wxMacCreateBitmapButton( &info , m_bmpNormal ) ; + SetControlData( m_controlHandle , 0, kControlIconContentTag, sizeof( info ), + (Ptr)&info ); + wxMacReleaseBitmapButton( &info ) ; + } + + IconTransformType transform = toggle ? kTransformSelected : kTransformNone ; + SetControlData( m_controlHandle, 0, kControlIconTransformTag, sizeof( transform ), + (Ptr)&transform ); + HIViewSetNeedsDisplay( m_controlHandle , true ) ; + +#else + ::SetControl32BitValue( m_controlHandle , toggle ) ; +#endif +} wxToolBarTool::wxToolBarTool(wxToolBar *tbar, int id, @@ -243,38 +339,6 @@ wxToolBarTool::wxToolBarTool(wxToolBar *tbar, clientData, shortHelp, longHelp) { Init(); - - if (id == wxID_SEPARATOR) return; - - WindowRef window = (WindowRef) tbar->MacGetTopLevelWindowRef() ; - wxSize toolSize = tbar->GetToolSize() ; - Rect toolrect = { 0, 0 , toolSize.y , toolSize.x } ; - - ControlButtonContentInfo info ; - wxMacCreateBitmapButton( &info , GetNormalBitmap() ) ; - - SInt16 behaviour = kControlBehaviorOffsetContents ; - if ( CanBeToggled() ) - behaviour += kControlBehaviorToggles ; - - CreateBevelButtonControl( window , &toolrect , CFSTR("") , kControlBevelButtonNormalBevel , behaviour , &info , - 0 , 0 , 0 , &m_controlHandle ) ; - - wxMacReleaseBitmapButton( &info ) ; - - InstallControlEventHandler( (ControlRef) m_controlHandle, GetwxMacToolBarToolEventHandlerUPP(), - GetEventTypeCount(eventList), eventList, this,NULL); - - UMAShowControl( m_controlHandle ) ; - - if ( CanBeToggled() && IsToggled() ) - ::SetControl32BitValue( m_controlHandle , 1 ) ; - else - ::SetControl32BitValue( m_controlHandle , 0 ) ; - - ControlRef container = (ControlRef) tbar->GetHandle() ; - wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; - ::EmbedControl( m_controlHandle , container ) ; } @@ -307,6 +371,7 @@ void wxToolBar::Init() bool wxToolBar::Create(wxWindow *parent, wxWindowID id, const wxPoint& pos, const wxSize& size, long style, const wxString& name) { + if ( !wxToolBarBase::Create( parent , id , pos , size , style ) ) return FALSE ; @@ -369,6 +434,21 @@ bool wxToolBar::Realize() DoToggleTool(tool, true); } } + else if (tool->IsToggled()) + { + wxToolBarToolsList::compatibility_iterator nodePrev = node->GetPrevious(); + while ( nodePrev ) + { + wxToolBarToolBase *tool = nodePrev->GetData(); + if ( !tool->IsButton() || (tool->GetKind() != wxITEM_RADIO) ) + break; + if ( tool->Toggle(false) ) + { + DoToggleTool(tool, false); + } + nodePrev = nodePrev->GetPrevious(); + } + } isRadio = TRUE; } else @@ -383,15 +463,25 @@ bool wxToolBar::Realize() if ( y + cursize.y > maxHeight ) maxHeight = y + cursize.y ; - tool->SetPosition( wxPoint( x , y ) ) ; - + if ( GetWindowStyleFlag() & wxTB_VERTICAL ) + { + int x1 = x + (maxToolWidth - cursize.x)/2 ; + tool->SetPosition( wxPoint( x1 , y ) ) ; + } + else + { + int y1 = y + (maxToolHeight - cursize.y)/2 ; + tool->SetPosition( wxPoint( x , y1 ) ) ; + } if ( GetWindowStyleFlag() & wxTB_VERTICAL ) { y += cursize.y ; + y += kwxMacToolSpacing ; } else { x += cursize.x ; + x += kwxMacToolSpacing ; } node = node->GetNext(); @@ -430,13 +520,13 @@ bool wxToolBar::Realize() void wxToolBar::SetToolBitmapSize(const wxSize& size) { - m_defaultWidth = size.x+4; m_defaultHeight = size.y+4; + m_defaultWidth = size.x+kwxMacToolBorder; m_defaultHeight = size.y+kwxMacToolBorder; } // The button size is bigger than the bitmap size wxSize wxToolBar::GetToolSize() const { - return wxSize(m_defaultWidth + 4, m_defaultHeight + 4); + return wxSize(m_defaultWidth + kwxMacToolBorder, m_defaultHeight + kwxMacToolBorder); } void wxToolBar::SetRows(int nRows) @@ -494,13 +584,90 @@ void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle) wxToolBarTool *tool = (wxToolBarTool *)t; if ( tool->IsButton() ) { - ::SetControl32BitValue( (ControlRef) tool->GetControlHandle() , toggle ) ; + tool->UpdateToggleImage( toggle ) ; } } bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), - wxToolBarToolBase *tool) + wxToolBarToolBase *toolBase) { + wxToolBarTool* tool = wx_static_cast( wxToolBarTool* , toolBase ) ; + + WindowRef window = (WindowRef) MacGetTopLevelWindowRef() ; + wxSize toolSize = GetToolSize() ; + Rect toolrect = { 0, 0 , toolSize.y , toolSize.x } ; + ControlRef controlHandle = NULL ; + + switch( tool->GetStyle() ) + { + case wxTOOL_STYLE_SEPARATOR : + { + wxASSERT( tool->GetControlHandle() == NULL ) ; + toolSize.x /= 4 ; + toolSize.y /= 4 ; + if ( GetWindowStyleFlag() & wxTB_VERTICAL ) + { + toolrect.bottom = toolSize.y ; + } + else + { + toolrect.right = toolSize.x ; + } + #ifdef __WXMAC_OSX__ + // in flat style we need a visual separator + CreateSeparatorControl( window , &toolrect , &controlHandle ) ; + tool->SetControlHandle( controlHandle ) ; + #endif + } + break ; + case wxTOOL_STYLE_BUTTON : + { + wxASSERT( tool->GetControlHandle() == NULL ) ; + ControlButtonContentInfo info ; + wxMacCreateBitmapButton( &info , tool->GetNormalBitmap() , kControlContentIconRef ) ; + + #ifdef __WXMAC_OSX__ + CreateIconControl( window , &toolrect , &info , false , &controlHandle ) ; + #else + SInt16 behaviour = kControlBehaviorOffsetContents ; + if ( tool->CanBeToggled() ) + behaviour += kControlBehaviorToggles ; + CreateBevelButtonControl( window , &toolrect , CFSTR("") , kControlBevelButtonNormalBevel , behaviour , &info , + 0 , 0 , 0 , &controlHandle ) ; + #endif + + wxMacReleaseBitmapButton( &info ) ; + /* + SetBevelButtonTextPlacement( m_controlHandle , kControlBevelButtonPlaceBelowGraphic ) ; + UMASetControlTitle( m_controlHandle , label , wxFont::GetDefaultEncoding() ) ; + */ + + InstallControlEventHandler( (ControlRef) controlHandle, GetwxMacToolBarToolEventHandlerUPP(), + GetEventTypeCount(eventList), eventList, tool,NULL); + + tool->SetControlHandle( controlHandle ) ; + } + break ; + case wxTOOL_STYLE_CONTROL : + wxASSERT( tool->GetControl() != NULL ) ; + // right now there's nothing to do here + break ; + } + + if ( controlHandle ) + { + ControlRef container = (ControlRef) GetHandle() ; + wxASSERT_MSG( container != NULL , wxT("No valid mac container control") ) ; + + UMAShowControl( controlHandle ) ; + ::EmbedControl( controlHandle , container ) ; + } + + if ( tool->CanBeToggled() && tool->IsToggled() ) + { + tool->UpdateToggleImage( true ) ; + } + // nothing special to do here - we relayout in Realize() later tool->Attach(this); InvalidateBestSize(); @@ -513,8 +680,9 @@ void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(tog wxFAIL_MSG( _T("not implemented") ); } -bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) +bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolbase) { + wxToolBarTool* tool = wx_static_cast( wxToolBarTool* , toolbase ) ; wxToolBarToolsList::compatibility_iterator node; for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) { @@ -532,6 +700,25 @@ bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) tool->Detach(); + switch ( tool->GetStyle() ) + { + case wxTOOL_STYLE_CONTROL: + { + tool->GetControl()->Destroy(); + tool->ClearControl() ; + } + break; + + case wxTOOL_STYLE_BUTTON: + case wxTOOL_STYLE_SEPARATOR: + if ( tool->GetControlHandle() ) + { + DisposeControl( (ControlRef) tool->GetControlHandle() ) ; + tool->SetControlHandle( (ControlRef) NULL ) ; + } + break; + } + // and finally reposition all the controls after this one for ( /* node -> first after deleted */ ; node; node = node->GetNext() ) @@ -557,11 +744,30 @@ bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *tool) void wxToolBar::OnPaint(wxPaintEvent& event) { wxPaintDC dc(this) ; -#if wxMAC_USE_CORE_GRAPHICS -#else - wxMacPortSetter helper(&dc) ; + int w, h ; GetSize( &w , &h ) ; +#if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3 + if ( !MacGetTopLevelWindow()->MacGetMetalAppearance() ) + { + if ( UMAGetSystemVersion() >= 0x1030 ) + { + HIThemePlacardDrawInfo info ; + memset( &info, 0 , sizeof( info ) ) ; + info.version = 0 ; + info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive ; + + CGContextRef cgContext = (CGContextRef) MacGetCGContextRef() ; + HIRect rect = CGRectMake( 0 , 0 , w , h ) ; + HIThemeDrawPlacard( &rect , & info , cgContext, kHIThemeOrientationNormal) ; + } + } + else + { + // leave the background as it is (striped or metal) + } +#else + wxMacPortSetter helper(&dc) ; Rect toolbarrect = { dc.YLOG2DEVMAC(0) , dc.XLOG2DEVMAC(0) , dc.YLOG2DEVMAC(h) , dc.XLOG2DEVMAC(w) } ;