+ tool->SetIndex( currentPosition );
+ if ( tool->IsControl() )
+ {
+ CFIndex count = CFGetRetainCount( tool->GetControl()->GetPeer()->GetControlRef() ) ;
+ wxASSERT_MSG( count == 3 || count == 2, wxT("Reference Count of native tool was illegal after insertion") );
+ wxASSERT( IsValidControlHandle(tool->GetControl()->GetPeer()->GetControlRef() )) ;
+ }
+ }
+
+ currentPosition++;
+ }
+ }
+#endif
+
+ // update radio button (and group) state
+ lastIsRadio = curIsRadio;
+ curIsRadio = ( tool->IsButton() && (tool->GetKind() == wxITEM_RADIO) );
+
+ if ( !curIsRadio )
+ {
+ if ( tool->IsToggled() )
+ DoToggleTool( tool, true );
+ }
+ else
+ {
+ if ( !lastIsRadio )
+ {
+ if ( tool->Toggle( true ) )
+ {
+ DoToggleTool( tool, true );
+ }
+ }
+ else if ( tool->IsToggled() )
+ {
+ if ( tool->IsToggled() )
+ DoToggleTool( tool, true );
+
+ wxToolBarToolsList::compatibility_iterator nodePrev = node->GetPrevious();
+ while ( nodePrev )
+ {
+ wxToolBarToolBase *toggleTool = nodePrev->GetData();
+ if ( (toggleTool == NULL) || !toggleTool->IsButton() || (toggleTool->GetKind() != wxITEM_RADIO) )
+ break;
+
+ if ( toggleTool->Toggle( false ) )
+ DoToggleTool( toggleTool, false );
+
+ nodePrev = nodePrev->GetPrevious();
+ }
+ }
+ }
+
+ node = node->GetNext();
+ }
+
+ if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
+ {
+ // if not set yet, only one row
+ if ( m_maxRows <= 0 )
+ SetRows( 1 );
+
+ m_minWidth = maxWidth;
+ maxWidth = tw;
+ maxHeight += m_yMargin + kwxMacToolBarTopMargin;
+ m_minHeight = m_maxHeight = maxHeight;
+ }
+ else
+ {
+ // if not set yet, have one column
+ if ( (GetToolsCount() > 0) && (m_maxRows <= 0) )
+ SetRows( GetToolsCount() );
+
+ m_minHeight = maxHeight;
+ maxHeight = th;
+ maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
+ m_minWidth = m_maxWidth = maxWidth;
+ }
+
+#if 0
+ // FIXME: should this be OSX-only?
+ {
+ bool wantNativeToolbar, ownToolbarInstalled;
+
+ // attempt to install the native toolbar
+ wantNativeToolbar = ((GetWindowStyleFlag() & wxTB_VERTICAL) == 0);
+ MacInstallNativeToolbar( wantNativeToolbar );
+ (void)MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
+ if (!ownToolbarInstalled)
+ {
+ SetSize( maxWidth, maxHeight );
+ InvalidateBestSize();
+ }
+ }
+#else
+ SetSize( maxWidth, maxHeight );
+ InvalidateBestSize();
+#endif
+
+ SetInitialSize();
+
+ return true;
+}
+
+void wxToolBar::SetToolBitmapSize(const wxSize& size)
+{
+ m_defaultWidth = size.x + kwxMacToolBorder;
+ m_defaultHeight = size.y + kwxMacToolBorder;
+
+#if wxMAC_USE_NATIVE_TOOLBAR
+ if (m_macHIToolbarRef != NULL)
+ {
+ int maxs = wxMax( size.x, size.y );
+ HIToolbarDisplaySize sizeSpec;
+ if ( maxs > 32 )
+ sizeSpec = kHIToolbarDisplaySizeNormal;
+ else if ( maxs > 24 )
+ sizeSpec = kHIToolbarDisplaySizeDefault;
+ else
+ sizeSpec = kHIToolbarDisplaySizeSmall;
+
+ HIToolbarSetDisplaySize( (HIToolbarRef) m_macHIToolbarRef, sizeSpec );
+ }
+#endif
+}
+
+// The button size is bigger than the bitmap size
+wxSize wxToolBar::GetToolSize() const
+{
+ return wxSize(m_defaultWidth + kwxMacToolBorder, m_defaultHeight + kwxMacToolBorder);
+}
+
+void wxToolBar::SetRows(int nRows)
+{
+ // avoid resizing the frame uselessly
+ if ( nRows != m_maxRows )
+ m_maxRows = nRows;
+}
+
+void wxToolBar::MacSuperChangedPosition()
+{
+ wxWindow::MacSuperChangedPosition();
+
+#if wxMAC_USE_NATIVE_TOOLBAR
+ if (! m_macUsesNativeToolbar )
+ Realize();
+#else
+
+ Realize();
+#endif
+}
+
+void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap )
+{
+ wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, FindById(id));
+ if ( tool )
+ {
+ wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
+
+ tool->SetNormalBitmap(bitmap);
+
+ // a side-effect of the UpdateToggleImage function is that it always changes the bitmap used on the button.
+ tool->UpdateToggleImage( tool->CanBeToggled() && tool->IsToggled() );
+ }
+}
+
+void wxToolBar::SetToolDisabledBitmap( int id, const wxBitmap& bitmap )
+{
+ wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, FindById(id));
+ if ( tool )
+ {
+ wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
+
+ tool->SetDisabledBitmap(bitmap);
+
+ // TODO: what to do for this one?
+ }
+}
+
+wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
+{
+ wxToolBarTool *tool;
+ wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
+ while ( node )
+ {
+ tool = (wxToolBarTool *)node->GetData();
+ if (tool != NULL)
+ {
+ wxRect2DInt r( tool->GetPosition(), tool->GetSize() );
+ if ( r.Contains( wxPoint( x, y ) ) )
+ return tool;
+ }
+
+ node = node->GetNext();
+ }
+
+ return (wxToolBarToolBase*)NULL;
+}
+
+wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
+{
+ wxToolBarToolBase *tool = FindToolForPosition( pt.x, pt.y );
+ if ( tool != NULL )
+ return tool->GetShortHelp();
+
+ return wxEmptyString;
+}
+
+void wxToolBar::DoEnableTool(wxToolBarToolBase *t, bool enable)
+{
+ if ( t != NULL )
+ ((wxToolBarTool*)t)->DoEnable( enable );
+}
+
+void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
+{
+ wxToolBarTool *tool = (wxToolBarTool *)t;
+ if ( ( tool != NULL ) && tool->IsButton() )
+ tool->UpdateToggleImage( toggle );
+}
+
+bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
+{
+ wxToolBarTool *tool = wx_static_cast( wxToolBarTool*, toolBase );
+ if (tool == NULL)
+ return false;
+
+ WindowRef window = (WindowRef) MacGetTopLevelWindowRef();
+ wxSize toolSize = GetToolSize();
+ Rect toolrect = { 0, 0, toolSize.y, toolSize.x };
+ ControlRef controlHandle = NULL;
+ OSStatus err = 0;
+ tool->Attach( this );
+
+#if wxMAC_USE_NATIVE_TOOLBAR
+ wxString label = tool->GetLabel();
+ if (m_macHIToolbarRef && !label.empty() )
+ {
+ // strip mnemonics from the label for compatibility
+ // with the usual labels in wxStaticText sense
+ label = wxStripMenuCodes(label);
+ }
+#endif // wxMAC_USE_NATIVE_TOOLBAR
+
+ 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;
+
+ // in flat style we need a visual separator
+#if wxMAC_USE_NATIVE_TOOLBAR
+ if (m_macHIToolbarRef != NULL)
+ {
+ HIToolbarItemRef item;
+ err = HIToolbarItemCreate(
+ kHIToolbarSeparatorIdentifier,
+ kHIToolbarItemCantBeRemoved | kHIToolbarItemIsSeparator | kHIToolbarItemAllowDuplicates,
+ &item );
+ if (err == noErr)
+ tool->SetToolbarItemRef( item );
+ }
+ else
+ err = noErr;
+#endif // wxMAC_USE_NATIVE_TOOLBAR
+
+ CreateSeparatorControl( window, &toolrect, &controlHandle );
+ tool->SetControlHandle( controlHandle );
+ }
+ break;
+
+ case wxTOOL_STYLE_BUTTON:
+ {
+ wxASSERT( tool->GetControlHandle() == NULL );
+ ControlButtonContentInfo info;
+ wxMacCreateBitmapButton( &info, tool->GetNormalBitmap() );
+
+ if ( UMAGetSystemVersion() >= 0x1000)
+ {
+ // contrary to the docs this control only works with iconrefs
+ ControlButtonContentInfo info;
+ wxMacCreateBitmapButton( &info, tool->GetNormalBitmap(), kControlContentIconRef );
+ CreateIconControl( window, &toolrect, &info, false, &controlHandle );
+ wxMacReleaseBitmapButton( &info );
+ }
+ else
+ {
+ SInt16 behaviour = kControlBehaviorOffsetContents;
+ if ( tool->CanBeToggled() )
+ behaviour |= kControlBehaviorToggles;
+ err = CreateBevelButtonControl( window,
+ &toolrect, CFSTR(""), kControlBevelButtonNormalBevel,
+ behaviour, &info, 0, 0, 0, &controlHandle );
+ }
+
+#if wxMAC_USE_NATIVE_TOOLBAR
+ if (m_macHIToolbarRef != NULL)
+ {
+ HIToolbarItemRef item;
+ wxString labelStr = wxString::Format(wxT("%p"), tool);
+ err = HIToolbarItemCreate(
+ wxMacCFStringHolder(labelStr, wxFont::GetDefaultEncoding()),
+ kHIToolbarItemCantBeRemoved | kHIToolbarItemAnchoredLeft | kHIToolbarItemAllowDuplicates, &item );
+ if (err == noErr)
+ {
+ ControlButtonContentInfo info2;
+ wxMacCreateBitmapButton( &info2, tool->GetNormalBitmap(), kControlContentCGImageRef);
+
+ InstallEventHandler(
+ HIObjectGetEventTarget(item), GetwxMacToolBarEventHandlerUPP(),
+ GetEventTypeCount(toolBarEventList), toolBarEventList, tool, NULL );
+ HIToolbarItemSetLabel( item, wxMacCFStringHolder(label, m_font.GetEncoding()) );
+ HIToolbarItemSetImage( item, info2.u.imageRef );
+ HIToolbarItemSetCommandID( item, kHIToolbarCommandPressAction );
+ tool->SetToolbarItemRef( item );
+
+ wxMacReleaseBitmapButton( &info2 );
+ }
+ }
+ else
+ err = noErr;
+#endif // wxMAC_USE_NATIVE_TOOLBAR
+
+ wxMacReleaseBitmapButton( &info );
+
+#if 0
+ SetBevelButtonTextPlacement( m_controlHandle, kControlBevelButtonPlaceBelowGraphic );
+ UMASetControlTitle( m_controlHandle, label, wxFont::GetDefaultEncoding() );
+#endif
+
+ InstallControlEventHandler(
+ (ControlRef) controlHandle, GetwxMacToolBarToolEventHandlerUPP(),
+ GetEventTypeCount(eventList), eventList, tool, NULL );
+
+ tool->SetControlHandle( controlHandle );
+ }
+ break;
+
+ case wxTOOL_STYLE_CONTROL:
+
+#if wxMAC_USE_NATIVE_TOOLBAR
+ if (m_macHIToolbarRef != NULL)
+ {
+ wxCHECK_MSG( tool->GetControl(), false, _T("control must be non-NULL") );
+ HIToolbarItemRef item;
+ HIViewRef viewRef = (HIViewRef) tool->GetControl()->GetHandle() ;
+ CFDataRef data = CFDataCreate( kCFAllocatorDefault , (UInt8*) &viewRef , sizeof(viewRef) ) ;
+ err = HIToolbarCreateItemWithIdentifier((HIToolbarRef) m_macHIToolbarRef,kControlToolbarItemClassID,
+ data , &item ) ;
+
+ if (err == noErr)
+ {
+ tool->SetToolbarItemRef( item );
+ }
+ CFRelease( data ) ;
+ }
+ else
+ {
+ err = noErr;
+ break;
+ }
+#else
+ // right now there's nothing to do here
+#endif
+ break;
+
+ default:
+ break;
+ }
+
+ if ( err == noErr )
+ {
+ 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
+ InvalidateBestSize();
+ }
+ else
+ {
+ wxFAIL_MSG( wxString::Format( wxT("wxToolBar::DoInsertTool - failure [%ld]"), (long)err ) );
+ }
+
+ return (err == noErr);
+}
+
+void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
+{
+ wxFAIL_MSG( wxT("not implemented") );
+}
+
+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() )
+ {
+ wxToolBarToolBase *tool2 = node->GetData();
+ if ( tool2 == tool )
+ {
+ // let node point to the next node in the list
+ node = node->GetNext();
+
+ break;
+ }
+ }
+
+ wxSize sz = ((wxToolBarTool*)tool)->GetSize();
+
+ tool->Detach();
+
+#if wxMAC_USE_NATIVE_TOOLBAR
+ CFIndex removeIndex = tool->GetIndex();
+#endif
+
+#if wxMAC_USE_NATIVE_TOOLBAR
+ if (m_macHIToolbarRef != NULL)
+ {
+ if ( removeIndex != -1 && m_macHIToolbarRef )
+ {
+ HIToolbarRemoveItemAtIndex( (HIToolbarRef) m_macHIToolbarRef, removeIndex );
+ tool->SetIndex( -1 );
+ }
+ }
+#endif
+ switch ( tool->GetStyle() )
+ {
+ case wxTOOL_STYLE_CONTROL:
+ if ( tool->GetControl() )
+ tool->GetControl()->Destroy();
+ break;
+
+ case wxTOOL_STYLE_BUTTON:
+ case wxTOOL_STYLE_SEPARATOR:
+ // nothing special
+ break;
+
+ default:
+ break;
+ }
+ tool->ClearControl();
+
+ // and finally reposition all the controls after this one
+
+ for ( /* node -> first after deleted */; node; node = node->GetNext() )
+ {
+ wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
+ wxPoint pt = tool2->GetPosition();
+
+ if ( GetWindowStyleFlag() & wxTB_VERTICAL )
+ pt.y -= sz.y;
+ else
+ pt.x -= sz.x;
+
+ tool2->SetPosition( pt );
+
+#if wxMAC_USE_NATIVE_TOOLBAR
+ if (m_macHIToolbarRef != NULL)
+ {
+ if ( removeIndex != -1 && tool2->GetIndex() > removeIndex )
+ tool2->SetIndex( tool2->GetIndex() - 1 );
+ }
+#endif
+ }
+
+ InvalidateBestSize();
+
+ return true;
+}
+
+void wxToolBar::OnPaint(wxPaintEvent& event)
+{
+#if wxMAC_USE_NATIVE_TOOLBAR
+ if ( m_macUsesNativeToolbar )
+ {
+ event.Skip(true);
+ return;
+ }
+#endif
+
+ wxPaintDC dc(this);
+
+ int w, h;
+ GetSize( &w, &h );
+
+ bool drawMetalTheme = MacGetTopLevelWindow()->MacGetMetalAppearance();
+
+ if ( !drawMetalTheme )
+ {
+ 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)
+ }
+
+ event.Skip();
+}
+
+#endif // wxUSE_TOOLBAR