1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/osx/carbon/toolbar.cpp
4 // Author: Stefan Csomor
7 // RCS-ID: $Id: toolbar.cpp 54954 2008-08-03 11:27:03Z VZ $
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
16 #include "wx/toolbar.h"
23 #include "wx/osx/private.h"
24 #include "wx/geometry.h"
25 #include "wx/sysopt.h"
27 const short kwxMacToolBarToolDefaultWidth = 16;
28 const short kwxMacToolBarToolDefaultHeight = 16;
29 const short kwxMacToolBarTopMargin = 4;
30 const short kwxMacToolBarLeftMargin = 4;
31 const short kwxMacToolBorder = 0;
32 const short kwxMacToolSpacing = 6;
34 BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
35 EVT_PAINT( wxToolBar::OnPaint )
40 #pragma mark Tool Implementation
43 #define wxOSX_USE_NATIVE_TOOLBAR 1
46 // ----------------------------------------------------------------------------
48 // ----------------------------------------------------------------------------
50 // We have a dual implementation for each tool, WXWidget and NSToolbarItem*
52 // when embedding native controls in the native toolbar we must make sure the
53 // control does not get deleted behind our backs, so the retain count gets increased
54 // (after creation it is 1), first be the creation of the custom NSToolbarItem wrapper
55 // object, and second by the code 'creating' the custom HIView (which is the same as the
56 // already existing native control, therefore we just increase the ref count)
57 // when this view is removed from the native toolbar its count gets decremented again
58 // and when the HITooolbarItem wrapper object gets destroyed it is decremented as well
59 // so in the end the control lives with a refcount of one and can be disposed of by the
60 // wxControl code. For embedded controls on a non-native toolbar this ref count is less
61 // so we can only test against a range, not a specific value of the refcount.
63 class wxToolBarTool : public wxToolBarToolBase
69 const wxString& label,
70 const wxBitmap& bmpNormal,
71 const wxBitmap& bmpDisabled,
74 const wxString& shortHelp,
75 const wxString& longHelp );
77 wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label)
78 : wxToolBarToolBase(tbar, control, label)
82 SetControlHandle( (WXWidget) control->GetHandle() );
85 virtual ~wxToolBarTool()
90 WXWidget GetControlHandle()
92 return (WXWidget) m_controlHandle;
95 void SetControlHandle( WXWidget handle )
97 m_controlHandle = handle;
100 void SetPosition( const wxPoint& position );
104 if ( m_controlHandle )
108 [m_controlHandle retain];
112 // the embedded control is not under the responsibility of the tool, it gets disposed of in the
113 // proper wxControl destructor
115 m_controlHandle = NULL ;
118 #if wxOSX_USE_NATIVE_TOOLBAR
121 [m_toolbarItem release];
122 m_toolbarItem = NULL;
124 #endif // wxOSX_USE_NATIVE_TOOLBAR
127 wxSize GetSize() const
133 curSize = GetControl()->GetSize();
135 else if ( IsButton() )
137 curSize = GetToolBar()->GetToolSize();
142 curSize = GetToolBar()->GetToolSize();
143 if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
152 wxPoint GetPosition() const
154 return wxPoint( m_x, m_y );
157 bool DoEnable( bool enable );
161 void UpdateToggleImage( bool toggle );
167 // strip mnemonics from the label for compatibility with the usual
168 // labels in wxStaticText sense
169 wxString labelStr = wxStripMenuCodes(m_label);
170 wxCFStringRef l(labelStr, GetToolBarFontEncoding());
172 [m_toolbarItem setLabel:l.AsNSString()];
174 wxCFStringRef sh( GetShortHelp(), GetToolBarFontEncoding() );
175 [m_toolbarItem setToolTip:sh.AsNSString()];
181 wxToolBar *tbar = (wxToolBar*) GetToolBar();
186 shouldToggle = !IsToggled();
187 tbar->ToggleTool( GetId(), shouldToggle );
190 tbar->OnLeftClick( GetId(), IsToggled() );
193 #if wxOSX_USE_NATIVE_TOOLBAR
194 void SetToolbarItemRef( NSToolbarItem* ref )
196 if ( m_controlHandle )
197 [m_controlHandle setHidden:YES];
199 [m_toolbarItem release];
204 NSToolbarItem* GetToolbarItemRef() const
206 return m_toolbarItem;
209 void SetIndex( CFIndex idx )
214 CFIndex GetIndex() const
219 virtual void SetLabel(const wxString& label)
221 wxToolBarToolBase::SetLabel(label);
224 #endif // wxOSX_USE_NATIVE_TOOLBAR
227 #if wxOSX_USE_NATIVE_TOOLBAR
228 wxFontEncoding GetToolBarFontEncoding() const
232 f = GetToolBar()->GetFont();
233 return f.IsOk() ? f.GetEncoding() : wxFont::GetDefaultEncoding();
235 #endif // wxOSX_USE_NATIVE_TOOLBAR
239 m_controlHandle = NULL;
241 #if wxOSX_USE_NATIVE_TOOLBAR
242 m_toolbarItem = NULL;
247 WXWidget m_controlHandle;
250 wxBitmap m_alternateBitmap;
252 #if wxOSX_USE_NATIVE_TOOLBAR
253 NSToolbarItem* m_toolbarItem;
254 // position in its toolbar, -1 means not inserted
259 @interface wxNSToolbarItem : NSToolbarItem
264 - (id) initWithItemIdentifier: (NSString*) identifier;
265 - (void)setImplementation: (wxToolBarTool *) theImplementation;
266 - (wxToolBarTool*) implementation;
267 - (void) clickedAction: (id) sender;
272 @interface wxNSToolbarDelegate : NSObject
276 - (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag;
278 - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar;
280 - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar;
282 - (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar;
288 @interface wxNSToolBarButton : NSButton
293 - (id)initWithFrame:(NSRect)frame;
294 - (void) clickedAction: (id) sender;
295 - (void)setImplementation: (wxToolBarTool *) theImplementation;
296 - (wxToolBarTool*) implementation;
301 @implementation wxNSToolbarItem
303 - (id)initWithItemIdentifier: (NSString*) identifier
305 [super initWithItemIdentifier:identifier];
307 [self setTarget: self];
308 [self setAction: @selector(clickedAction:)];
312 - (void) clickedAction: (id) sender
320 - (void)setImplementation: (wxToolBarTool *) theImplementation
322 impl = theImplementation;
325 - (wxToolBarTool*) implementation
332 @implementation wxNSToolbarDelegate
334 - (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
339 - (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
344 - (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
349 - (NSToolbarItem*) toolbar:(NSToolbar*) toolbar itemForItemIdentifier:(NSString*) itemIdentifier willBeInsertedIntoToolbar:(BOOL) flag
352 wxToolBarTool* tool = (wxToolBarTool*) [itemIdentifier longLongValue];
354 wxToolBarTool* tool = (wxToolBarTool*) [itemIdentifier intValue];
358 wxNSToolbarItem* item = (wxNSToolbarItem*) tool->GetToolbarItemRef();
359 if ( flag && tool->IsControl() )
361 NSView* view = tool->GetControl()->GetHandle();
362 [view removeFromSuperview];
364 wxSize sz = tool->GetControl()->GetSize();
365 NSSize size = NSMakeSize((float)sz.x, (float)sz.y);
366 [item setMaxSize:size];
367 [item setMinSize:size];
377 @implementation wxNSToolBarButton
379 - (id)initWithFrame:(NSRect)frame
381 [super initWithFrame:frame];
383 [self setTarget: self];
384 [self setAction: @selector(clickedAction:)];
388 - (void) clickedAction: (id) sender
396 - (void)setImplementation: (wxToolBarTool *) theImplementation
398 impl = theImplementation;
401 - (wxToolBarTool*) implementation
413 bool wxToolBarTool::DoEnable( bool enable )
417 GetControl()->Enable( enable );
419 else if ( IsButton() )
421 #if wxOSX_USE_NATIVE_TOOLBAR
422 if ( m_toolbarItem != NULL )
423 [m_toolbarItem setEnabled:enable];
426 if ( m_controlHandle != NULL )
427 [(NSControl*)m_controlHandle setEnabled:enable];
433 void wxToolBarTool::SetPosition( const wxPoint& position )
438 int mac_x = position.x;
439 int mac_y = position.y;
443 NSRect frame = [m_controlHandle frame];
444 if ( frame.origin.x != mac_x || frame.origin.y != mac_y )
446 frame.origin.x = mac_x;
447 frame.origin.y = mac_y;
448 [m_controlHandle setFrame:frame];
451 else if ( IsControl() )
453 // embedded native controls are moved by the OS
454 #if wxOSX_USE_NATIVE_TOOLBAR
455 if ( ((wxToolBar*)GetToolBar())->MacWantsNativeToolbar() == false )
458 GetControl()->Move( position );
463 NSRect frame = [m_controlHandle frame];
464 if ( frame.origin.x != mac_x || frame.origin.y != mac_y )
466 frame.origin.x = mac_x;
467 frame.origin.y = mac_y;
468 [m_controlHandle setFrame:frame];
473 void wxToolBarTool::UpdateImages()
475 [(NSButton*) m_controlHandle setImage:m_bmpNormal.GetNSImage()];
477 if ( CanBeToggled() )
479 int w = m_bmpNormal.GetWidth();
480 int h = m_bmpNormal.GetHeight();
481 m_alternateBitmap = wxBitmap( w, h );
484 dc.SelectObject( m_alternateBitmap );
485 dc.SetPen( wxPen(*wxBLACK) );
486 dc.SetBrush( wxBrush( *wxLIGHT_GREY ));
487 dc.DrawRectangle( 0, 0, w, h );
488 dc.DrawBitmap( m_bmpNormal, 0, 0, true );
489 dc.SelectObject( wxNullBitmap );
491 [(NSButton*) m_controlHandle setAlternateImage:m_alternateBitmap.GetNSImage()];
493 UpdateToggleImage( CanBeToggled() && IsToggled() );
496 void wxToolBarTool::UpdateToggleImage( bool toggle )
498 #if wxOSX_USE_NATIVE_TOOLBAR
499 if (m_toolbarItem != NULL )
501 // the native toolbar item only has a 'selected' state (one for one toolbar)
502 // so we emulate the toggle here
503 if ( CanBeToggled() && toggle )
504 [m_toolbarItem setImage:m_alternateBitmap.GetNSImage()];
506 [m_toolbarItem setImage:m_bmpNormal.GetNSImage()];
511 wxToolBarTool::wxToolBarTool(
514 const wxString& label,
515 const wxBitmap& bmpNormal,
516 const wxBitmap& bmpDisabled,
518 wxObject *clientData,
519 const wxString& shortHelp,
520 const wxString& longHelp )
523 tbar, id, label, bmpNormal, bmpDisabled, kind,
524 clientData, shortHelp, longHelp )
530 #pragma mark Toolbar Implementation
532 wxToolBarToolBase *wxToolBar::CreateTool(
534 const wxString& label,
535 const wxBitmap& bmpNormal,
536 const wxBitmap& bmpDisabled,
538 wxObject *clientData,
539 const wxString& shortHelp,
540 const wxString& longHelp )
542 return new wxToolBarTool(
543 this, id, label, bmpNormal, bmpDisabled, kind,
544 clientData, shortHelp, longHelp );
548 wxToolBar::CreateTool(wxControl *control, const wxString& label)
550 return new wxToolBarTool(this, control, label);
553 void wxToolBar::Init()
557 m_defaultWidth = kwxMacToolBarToolDefaultWidth;
558 m_defaultHeight = kwxMacToolBarToolDefaultHeight;
560 #if wxOSX_USE_NATIVE_TOOLBAR
562 m_macUsesNativeToolbar = false;
566 // also for the toolbar we have the dual implementation:
567 // only when MacInstallNativeToolbar is called is the native toolbar set as the window toolbar
569 bool wxToolBar::Create(
575 const wxString& name )
577 if ( !wxToolBarBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ) )
582 OSStatus err = noErr;
584 #if wxOSX_USE_NATIVE_TOOLBAR
586 if (parent->IsKindOf(CLASSINFO(wxFrame)) && wxSystemOptions::GetOptionInt(wxT("mac.toolbar.no-native")) != 1)
588 static wxNSToolbarDelegate* controller = nil;
590 if ( controller == nil )
591 controller = [[wxNSToolbarDelegate alloc] init];
592 wxString identifier = wxString::Format( wxT("%p"), this );
593 wxCFStringRef cfidentifier(identifier);
594 NSToolbar* tb = [[NSToolbar alloc] initWithIdentifier:cfidentifier.AsNSString()];
598 if (m_macToolbar != NULL)
600 [tb setDelegate:controller];
602 NSToolbarDisplayMode mode = NSToolbarDisplayModeDefault;
603 NSToolbarSizeMode displaySize = NSToolbarSizeModeSmall;
605 if ( style & wxTB_NOICONS )
606 mode = NSToolbarDisplayModeLabelOnly;
607 else if ( style & wxTB_TEXT )
608 mode = NSToolbarDisplayModeIconAndLabel;
610 mode = NSToolbarDisplayModeIconOnly;
612 [tb setDisplayMode:mode];
613 [tb setSizeMode:displaySize];
616 #endif // wxOSX_USE_NATIVE_TOOLBAR
618 return (err == noErr);
621 wxToolBar::~wxToolBar()
623 #if wxOSX_USE_NATIVE_TOOLBAR
624 if (m_macToolbar != NULL)
626 // if this is the installed toolbar, then deinstall it
627 if (m_macUsesNativeToolbar)
628 MacInstallNativeToolbar( false );
630 [(NSToolbar*)m_macToolbar release];
636 bool wxToolBar::Show( bool show )
638 WXWindow tlw = MacGetTopLevelWindowRef();
639 bool bResult = (tlw != NULL);
643 #if wxOSX_USE_NATIVE_TOOLBAR
644 bool ownToolbarInstalled = false;
645 MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
646 if (ownToolbarInstalled)
648 bResult = ([(NSToolbar*)m_macToolbar isVisible] != show);
650 [(NSToolbar*)m_macToolbar setVisible:show];
653 bResult = wxToolBarBase::Show( show );
656 bResult = wxToolBarBase::Show( show );
663 bool wxToolBar::IsShown() const
667 #if wxOSX_USE_NATIVE_TOOLBAR
668 bool ownToolbarInstalled;
670 MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
671 if (ownToolbarInstalled)
673 bResult = [(NSToolbar*)m_macToolbar isVisible];
676 bResult = wxToolBarBase::IsShown();
679 bResult = wxToolBarBase::IsShown();
685 void wxToolBar::DoGetSize( int *width, int *height ) const
687 #if wxOSX_USE_NATIVE_TOOLBAR
688 bool ownToolbarInstalled;
690 MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
691 if ( ownToolbarInstalled )
693 WXWindow tlw = MacGetTopLevelWindowRef();
694 float toolbarHeight = 0.0;
697 if(m_macToolbar && [(NSToolbar*)m_macToolbar isVisible])
699 windowFrame = [NSWindow contentRectForFrameRect:[tlw frame]
700 styleMask:[tlw styleMask]];
701 toolbarHeight = NSHeight(windowFrame)
702 - NSHeight([[tlw contentView] frame]);
706 *width = windowFrame.size.width;
707 if ( height != NULL )
708 *height = toolbarHeight;
711 wxToolBarBase::DoGetSize( width, height );
714 wxToolBarBase::DoGetSize( width, height );
718 wxSize wxToolBar::DoGetBestSize() const
722 DoGetSize( &width, &height );
724 return wxSize( width, height );
727 void wxToolBar::SetWindowStyleFlag( long style )
729 wxToolBarBase::SetWindowStyleFlag( style );
731 #if wxOSX_USE_NATIVE_TOOLBAR
732 if (m_macToolbar != NULL)
734 NSToolbarDisplayMode mode = NSToolbarDisplayModeDefault;
736 if ( style & wxTB_NOICONS )
737 mode = NSToolbarDisplayModeLabelOnly;
738 else if ( style & wxTB_TEXT )
739 mode = NSToolbarDisplayModeIconAndLabel;
741 mode = NSToolbarDisplayModeIconOnly;
743 [(NSToolbar*) m_macToolbar setDisplayMode:mode];
748 #if wxOSX_USE_NATIVE_TOOLBAR
749 bool wxToolBar::MacWantsNativeToolbar()
751 return m_macUsesNativeToolbar;
754 bool wxToolBar::MacTopLevelHasNativeToolbar(bool *ownToolbarInstalled) const
756 bool bResultV = false;
758 if (ownToolbarInstalled != NULL)
759 *ownToolbarInstalled = false;
761 WXWindow tlw = MacGetTopLevelWindowRef();
764 NSToolbar* curToolbarRef = [tlw toolbar];
765 bResultV = (curToolbarRef != NULL);
766 if (bResultV && (ownToolbarInstalled != NULL))
767 *ownToolbarInstalled = (curToolbarRef == m_macToolbar);
773 bool wxToolBar::MacInstallNativeToolbar(bool usesNative)
775 bool bResult = false;
777 if (usesNative && (m_macToolbar == NULL))
780 if (usesNative && ((GetWindowStyleFlag() & wxTB_VERTICAL) != 0))
783 WXWindow tlw = MacGetTopLevelWindowRef();
787 // check the existing toolbar
788 NSToolbar* curToolbarRef = [tlw toolbar];
790 m_macUsesNativeToolbar = usesNative;
792 if (m_macUsesNativeToolbar)
794 // only install toolbar if there isn't one installed already
795 if (curToolbarRef == NULL)
798 [tlw setToolbar:(NSToolbar*) m_macToolbar];
799 [(NSToolbar*) m_macToolbar setVisible:YES];
801 m_peer->Move(0,0,0,0 );
802 SetSize( wxSIZE_AUTO_WIDTH, 0 );
803 m_peer->SetVisibility( false );
804 wxToolBarBase::Show( false );
809 // only deinstall toolbar if this is the installed one
810 if (m_macToolbar == curToolbarRef)
813 [(NSToolbar*) m_macToolbar setVisible:NO];
814 [tlw setToolbar:nil];
815 m_peer->SetVisibility( true );
820 InvalidateBestSize();
822 // wxLogDebug( wxT(" --> [%lx] - result [%s]"), (long)this, bResult ? wxT("T") : wxT("F") );
827 bool wxToolBar::Realize()
829 if (m_tools.GetCount() == 0)
835 int maxToolWidth = 0;
836 int maxToolHeight = 0;
838 int x = m_xMargin + kwxMacToolBarLeftMargin;
839 int y = m_yMargin + kwxMacToolBarTopMargin;
844 // find the maximum tool width and height
846 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
849 tool = (wxToolBarTool *) node->GetData();
852 wxSize sz = tool->GetSize();
854 if ( sz.x > maxToolWidth )
856 if ( sz.y > maxToolHeight )
857 maxToolHeight = sz.y;
860 node = node->GetNext();
863 bool lastIsRadio = false;
864 bool curIsRadio = false;
866 #if wxOSX_USE_NATIVE_TOOLBAR
867 CFIndex currentPosition = 0;
868 bool insertAll = false;
870 NSToolbar* refTB = (NSToolbar*)m_macToolbar;
875 enc = f.GetEncoding();
877 enc = wxFont::GetDefaultEncoding();
880 node = m_tools.GetFirst();
883 tool = (wxToolBarTool*) node->GetData();
886 node = node->GetNext();
890 // set tool position:
891 // for the moment just perform a single row/column alignment
892 wxSize cursize = tool->GetSize();
893 if ( x + cursize.x > maxWidth )
894 maxWidth = x + cursize.x;
895 if ( y + cursize.y > maxHeight )
896 maxHeight = y + cursize.y;
898 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
900 int x1 = x + ( maxToolWidth - cursize.x ) / 2;
901 tool->SetPosition( wxPoint(x1, y) );
905 int y1 = y + ( maxToolHeight - cursize.y ) / 2;
906 tool->SetPosition( wxPoint(x, y1) );
909 // update the item positioning state
910 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
911 y += cursize.y + kwxMacToolSpacing;
913 x += cursize.x + kwxMacToolSpacing;
915 #if wxOSX_USE_NATIVE_TOOLBAR
916 // install in native NSToolbar
919 NSToolbarItem* hiItemRef = tool->GetToolbarItemRef();
920 if ( hiItemRef != NULL )
922 // since setting the help texts is non-virtual we have to update
924 wxCFStringRef sh( tool->GetShortHelp(), enc);
925 [hiItemRef setToolTip:sh.AsNSString()];
927 if ( insertAll || (tool->GetIndex() != currentPosition) )
933 // if this is the first tool that gets newly inserted or repositioned
934 // first remove all 'old' tools from here to the right, because of this
935 // all following tools will have to be reinserted (insertAll).
936 for ( wxToolBarToolsList::compatibility_iterator node2 = m_tools.GetLast();
938 node2 = node2->GetPrevious() )
940 wxToolBarTool *tool2 = (wxToolBarTool*) node2->GetData();
942 const long idx = tool2->GetIndex();
945 [refTB removeItemAtIndex:idx];
950 wxString identifier = wxString::Format( wxT("%ld"), (long) tool );
951 wxCFStringRef cfidentifier(identifier);
953 [refTB insertItemWithItemIdentifier:cfidentifier.AsNSString() atIndex:currentPosition];
954 tool->SetIndex( currentPosition );
962 // update radio button (and group) state
963 lastIsRadio = curIsRadio;
964 curIsRadio = ( tool->IsButton() && (tool->GetKind() == wxITEM_RADIO) );
968 if ( tool->IsToggled() )
969 DoToggleTool( tool, true );
975 if ( tool->Toggle( true ) )
977 DoToggleTool( tool, true );
980 else if ( tool->IsToggled() )
982 if ( tool->IsToggled() )
983 DoToggleTool( tool, true );
985 wxToolBarToolsList::compatibility_iterator nodePrev = node->GetPrevious();
988 wxToolBarToolBase *toggleTool = nodePrev->GetData();
989 if ( (toggleTool == NULL) || !toggleTool->IsButton() || (toggleTool->GetKind() != wxITEM_RADIO) )
992 if ( toggleTool->Toggle( false ) )
993 DoToggleTool( toggleTool, false );
995 nodePrev = nodePrev->GetPrevious();
1000 node = node->GetNext();
1003 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
1005 // if not set yet, only one row
1006 if ( m_maxRows <= 0 )
1009 m_minWidth = maxWidth;
1011 maxHeight += m_yMargin + kwxMacToolBarTopMargin;
1012 m_minHeight = m_maxHeight = maxHeight;
1016 // if not set yet, have one column
1017 if ( (GetToolsCount() > 0) && (m_maxRows <= 0) )
1018 SetRows( GetToolsCount() );
1020 m_minHeight = maxHeight;
1022 maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
1023 m_minWidth = m_maxWidth = maxWidth;
1027 // FIXME: should this be OSX-only?
1029 bool wantNativeToolbar, ownToolbarInstalled;
1031 // attempt to install the native toolbar
1032 wantNativeToolbar = ((GetWindowStyleFlag() & wxTB_VERTICAL) == 0);
1033 MacInstallNativeToolbar( wantNativeToolbar );
1034 (void)MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
1035 if (!ownToolbarInstalled)
1037 SetSize( maxWidth, maxHeight );
1038 InvalidateBestSize();
1042 SetSize( maxWidth, maxHeight );
1043 InvalidateBestSize();
1051 void wxToolBar::SetToolBitmapSize(const wxSize& size)
1053 m_defaultWidth = size.x + kwxMacToolBorder;
1054 m_defaultHeight = size.y + kwxMacToolBorder;
1056 #if wxOSX_USE_NATIVE_TOOLBAR
1057 if (m_macToolbar != NULL)
1059 int maxs = wxMax( size.x, size.y );
1060 NSToolbarSizeMode sizeSpec;
1062 sizeSpec = NSToolbarSizeModeRegular;
1063 else if ( maxs > 24 )
1064 sizeSpec = NSToolbarSizeModeDefault;
1066 sizeSpec = NSToolbarSizeModeSmall;
1068 [(NSToolbar*) m_macToolbar setSizeMode:sizeSpec ];
1073 // The button size is bigger than the bitmap size
1074 wxSize wxToolBar::GetToolSize() const
1076 return wxSize(m_defaultWidth + kwxMacToolBorder, m_defaultHeight + kwxMacToolBorder);
1079 void wxToolBar::SetRows(int nRows)
1081 // avoid resizing the frame uselessly
1082 if ( nRows != m_maxRows )
1086 void wxToolBar::MacSuperChangedPosition()
1088 wxWindow::MacSuperChangedPosition();
1090 #if wxOSX_USE_NATIVE_TOOLBAR
1091 if (! m_macUsesNativeToolbar )
1099 void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap )
1101 wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, FindById(id));
1104 wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
1106 tool->SetNormalBitmap(bitmap);
1108 // a side-effect of the UpdateToggleImage function is that it always changes the bitmap used on the button.
1109 tool->UpdateImages();
1113 void wxToolBar::SetToolDisabledBitmap( int id, const wxBitmap& bitmap )
1115 wxToolBarTool* tool = wx_static_cast(wxToolBarTool*, FindById(id));
1118 wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
1120 tool->SetDisabledBitmap(bitmap);
1122 // TODO: what to do for this one?
1126 wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
1128 wxToolBarTool *tool;
1129 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1132 tool = (wxToolBarTool *)node->GetData();
1135 wxRect2DInt r( tool->GetPosition(), tool->GetSize() );
1136 if ( r.Contains( wxPoint( x, y ) ) )
1140 node = node->GetNext();
1143 return (wxToolBarToolBase*)NULL;
1146 wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
1148 wxToolBarToolBase *tool = FindToolForPosition( pt.x, pt.y );
1150 return tool->GetShortHelp();
1152 return wxEmptyString;
1155 void wxToolBar::DoEnableTool(wxToolBarToolBase *t, bool enable)
1158 ((wxToolBarTool*)t)->DoEnable( enable );
1161 void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
1163 wxToolBarTool *tool = (wxToolBarTool *)t;
1164 if ( ( tool != NULL ) && tool->IsButton() )
1165 tool->UpdateToggleImage( toggle );
1168 bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
1170 wxToolBarTool *tool = wx_static_cast( wxToolBarTool*, toolBase );
1174 wxSize toolSize = GetToolSize();
1175 WXWidget controlHandle = NULL;
1176 NSRect toolrect = NSMakeRect(0, 0, toolSize.x, toolSize.y );
1178 #if wxOSX_USE_NATIVE_TOOLBAR
1179 wxString label = tool->GetLabel();
1180 if (m_macToolbar && !label.empty() )
1182 // strip mnemonics from the label for compatibility
1183 // with the usual labels in wxStaticText sense
1184 label = wxStripMenuCodes(label);
1186 #endif // wxOSX_USE_NATIVE_TOOLBAR
1188 switch (tool->GetStyle())
1190 case wxTOOL_STYLE_SEPARATOR:
1192 wxASSERT( tool->GetControlHandle() == NULL );
1195 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
1196 toolrect.size.height = toolSize.y;
1198 toolrect.size.width = toolSize.x;
1200 // in flat style we need a visual separator
1201 #if wxOSX_USE_NATIVE_TOOLBAR
1202 if (m_macToolbar != NULL)
1204 NSToolbarItem* item = [[NSToolbarItem alloc] initWithItemIdentifier:NSToolbarSeparatorItemIdentifier];
1205 tool->SetToolbarItemRef( item );
1207 #endif // wxOSX_USE_NATIVE_TOOLBAR
1209 NSBox* box = [[NSBox alloc] initWithFrame:toolrect];
1210 [box setBoxType:NSBoxSeparator];
1211 controlHandle = box;
1212 tool->SetControlHandle( controlHandle );
1216 case wxTOOL_STYLE_BUTTON:
1218 wxASSERT( tool->GetControlHandle() == NULL );
1220 wxNSToolBarButton* v = [[wxNSToolBarButton alloc] initWithFrame:toolrect];
1222 [v setBezelStyle:NSRegularSquareBezelStyle];
1224 [v setButtonType: ( tool->CanBeToggled() ? NSOnOffButton : NSMomentaryPushInButton )];
1225 [v setImplementation:tool];
1229 #if wxOSX_USE_NATIVE_TOOLBAR
1230 if (m_macToolbar != NULL)
1232 wxString identifier = wxString::Format(wxT("%ld"), (long) tool);
1233 wxCFStringRef cfidentifier( identifier, wxFont::GetDefaultEncoding() );
1234 wxNSToolbarItem* item = [[wxNSToolbarItem alloc] initWithItemIdentifier:cfidentifier.AsNSString() ];
1235 [item setImplementation:tool];
1236 tool->SetToolbarItemRef( item );
1239 #endif // wxOSX_USE_NATIVE_TOOLBAR
1240 tool->SetControlHandle( controlHandle );
1241 tool->UpdateImages();
1242 tool->UpdateLabel();
1244 SetBevelButtonTextPlacement( m_controlHandle, kControlBevelButtonPlaceBelowGraphic );
1245 SetControlTitleWithCFString( m_controlHandle , wxCFStringRef( label, wxFont::GetDefaultEncoding() );
1248 InstallControlEventHandler(
1249 (WXWidget) controlHandle, GetwxMacToolBarToolEventHandlerUPP(),
1250 GetEventTypeCount(eventList), eventList, tool, NULL );
1255 case wxTOOL_STYLE_CONTROL:
1257 #if wxOSX_USE_NATIVE_TOOLBAR
1258 if (m_macToolbar != NULL)
1260 WXWidget view = (WXWidget) tool->GetControl()->GetHandle() ;
1261 wxCHECK_MSG( view, false, _T("control must be non-NULL") );
1263 wxString identifier = wxString::Format(wxT("%ld"), (long) tool);
1264 wxCFStringRef cfidentifier( identifier, wxFont::GetDefaultEncoding() );
1265 wxNSToolbarItem* item = [[wxNSToolbarItem alloc] initWithItemIdentifier:cfidentifier.AsNSString() ];
1266 [item setImplementation:tool];
1267 tool->SetToolbarItemRef( item );
1270 // right now there's nothing to do here
1272 tool->UpdateLabel();
1279 if ( controlHandle )
1281 WXWidget container = (WXWidget) GetHandle();
1282 wxASSERT_MSG( container != NULL, wxT("No valid Mac container control") );
1284 // SetControlVisibility( controlHandle, true, true );
1285 [container addSubview:controlHandle];
1288 // nothing special to do here - we relayout in Realize() later
1289 InvalidateBestSize();
1295 void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
1297 wxFAIL_MSG( wxT("not implemented") );
1300 bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolbase)
1302 wxToolBarTool* tool = wx_static_cast( wxToolBarTool*, toolbase );
1303 wxToolBarToolsList::compatibility_iterator node;
1304 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
1306 wxToolBarToolBase *tool2 = node->GetData();
1307 if ( tool2 == tool )
1309 // let node point to the next node in the list
1310 node = node->GetNext();
1316 wxSize sz = ((wxToolBarTool*)tool)->GetSize();
1318 #if wxOSX_USE_NATIVE_TOOLBAR
1319 CFIndex removeIndex = tool->GetIndex();
1322 #if wxOSX_USE_NATIVE_TOOLBAR
1323 if (m_macToolbar != NULL)
1325 if ( removeIndex != -1 && m_macToolbar )
1327 [(NSToolbar*) m_macToolbar removeItemAtIndex:removeIndex];
1328 tool->SetIndex( -1 );
1333 tool->ClearControl();
1335 // and finally reposition all the controls after this one
1337 for ( /* node -> first after deleted */; node; node = node->GetNext() )
1339 wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
1340 wxPoint pt = tool2->GetPosition();
1342 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
1347 tool2->SetPosition( pt );
1349 #if wxOSX_USE_NATIVE_TOOLBAR
1350 if (m_macToolbar != NULL)
1352 if ( removeIndex != -1 && tool2->GetIndex() > removeIndex )
1353 tool2->SetIndex( tool2->GetIndex() - 1 );
1358 InvalidateBestSize();
1363 #include <Carbon/Carbon.h>
1365 void wxToolBar::OnPaint(wxPaintEvent& event)
1367 #if wxOSX_USE_NATIVE_TOOLBAR
1368 if ( m_macUsesNativeToolbar )
1380 bool drawMetalTheme = MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL;
1382 if ( !drawMetalTheme )
1384 HIThemePlacardDrawInfo info;
1385 memset( &info, 0, sizeof(info) );
1387 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive;
1389 CGContextRef cgContext = (CGContextRef) MacGetCGContextRef();
1390 HIRect rect = CGRectMake( 0, 0, w, h );
1391 HIThemeDrawPlacard( &rect, &info, cgContext, kHIThemeOrientationNormal );
1395 // leave the background as it is (striped or metal)
1401 #endif // wxUSE_TOOLBAR