1/////////////////////////////////////////////////////////////////////////////
2// Name:        src/osx/cocoa/toolbar.mm
3// Purpose:     wxToolBar
4// Author:      Stefan Csomor
5// Modified by:
6// Created:     04/01/98
7// Copyright:   (c) Stefan Csomor
8// Licence:     wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#include "wx/wxprec.h"
12
13#if wxUSE_TOOLBAR
14
15#ifndef WX_PRECOMP
16    #include "wx/wx.h"
17#endif
18
19#include "wx/toolbar.h"
20#include "wx/app.h"
21#include "wx/osx/private.h"
22#include "wx/osx/private/available.h"
23#include "wx/geometry.h"
24#include "wx/sysopt.h"
25
26const short kwxMacToolBarToolDefaultWidth = 16;
27const short kwxMacToolBarToolDefaultHeight = 16;
28const short kwxMacToolBarTopMargin = 4;
29const short kwxMacToolBarLeftMargin =  4;
30const short kwxMacToolBorder = 0;
31const short kwxMacToolSpacing = 6;
32
33wxBEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
34    EVT_PAINT( wxToolBar::OnPaint )
35wxEND_EVENT_TABLE()
36
37
38#pragma mark -
39#pragma mark Tool Implementation
40
41// ----------------------------------------------------------------------------
42// private classes
43// ----------------------------------------------------------------------------
44
45class wxToolBarTool;
46
47@interface wxNSToolBarButton : NSButton
48{
49    wxToolBarTool* impl;
50}
51
52- (id)initWithFrame:(NSRect)frame;
53- (void) clickedAction: (id) sender;
54- (void)setImplementation: (wxToolBarTool *) theImplementation;
55- (wxToolBarTool*) implementation;
56- (BOOL) isFlipped;
57
58@end
59
60// We have a dual implementation for each tool, WXWidget and NSToolbarItem*
61
62// when embedding native controls in the native toolbar we must make sure the
63// control does not get deleted behind our backs, so the retain count gets increased
64// (after creation it is 1), first be the creation of the custom NSToolbarItem wrapper
65// object, and second by the code 'creating' the custom HIView (which is the same as the
66// already existing native control, therefore we just increase the ref count)
67// when this view is removed from the native toolbar its count gets decremented again
68// and when the HITooolbarItem wrapper object gets destroyed it is decremented as well
69// so in the end the control lives with a refcount of one and can be disposed of by the
70// wxControl code. For embedded controls on a non-native toolbar this ref count is less
71// so we can only test against a range, not a specific value of the refcount.
72
73class wxToolBarTool : public wxToolBarToolBase
74{
75public:
76    wxToolBarTool(
77        wxToolBar *tbar,
78        int id,
79        const wxString& label,
80        const wxBitmap& bmpNormal,
81        const wxBitmap& bmpDisabled,
82        wxItemKind kind,
83        wxObject *clientData,
84        const wxString& shortHelp,
85        const wxString& longHelp );
86
87    wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label)
88        : wxToolBarToolBase(tbar, control, label)
89    {
90        Init();
91        if (control != NULL)
92            SetControlHandle( (WXWidget) control->GetHandle() );
93    }
94
95    virtual ~wxToolBarTool()
96    {
97        ClearControl();
98    }
99
100    WXWidget GetControlHandle()
101    {
102        return (WXWidget) m_controlHandle;
103    }
104
105    void SetControlHandle( WXWidget handle )
106    {
107        m_controlHandle = handle;
108    }
109
110    void SetPosition( const wxPoint& position );
111
112    void ClearControl()
113    {
114        if ( m_controlHandle )
115        {
116            if ( !IsControl() )
117            {
118                [m_controlHandle removeFromSuperview];
119                [m_controlHandle release];
120            }
121            else
122            {
123                // the embedded control is not under the responsibility of the tool, it gets disposed of in the
124                // proper wxControl destructor
125            }
126            m_controlHandle = NULL ;
127        }
128
129#if wxOSX_USE_NATIVE_TOOLBAR
130        if ( m_toolbarItem )
131        {
132            [m_toolbarItem release];
133            m_toolbarItem = NULL;
134        }
135#endif // wxOSX_USE_NATIVE_TOOLBAR
136    }
137
138    wxSize GetSize() const
139    {
140        wxSize curSize;
141
142        if ( IsControl() )
143        {
144            curSize = GetControl()->GetSize();
145        }
146        else if ( IsButton() )
147        {
148            // curSize = GetToolBar()->GetToolSize();
149            NSRect best = [(wxNSToolBarButton*)m_controlHandle frame];
150            curSize = wxSize(best.size.width, best.size.height);
151        }
152        else
153        {
154            // separator size
155            curSize = GetToolBar()->GetToolSize();
156            if ( GetToolBar()->IsVertical() )
157                curSize.y /= 4;
158            else
159                curSize.x /= 4;
160        }
161
162        return curSize;
163    }
164
165    wxPoint GetPosition() const
166    {
167        return wxPoint( m_x, m_y );
168    }
169
170    bool Enable( bool enable ) wxOVERRIDE;
171
172    void UpdateImages();
173
174    void UpdateToggleImage( bool toggle );
175
176    void UpdateLabel()
177    {
178        // Use an empty string if we're not displaying text
179        wxString labelStr;
180        wxToolBar *tbar = (wxToolBar*) GetToolBar();
181        int style = (tbar ? tbar->GetWindowStyleFlag() : 0);
182        if ( (style & (wxTB_NOICONS | wxTB_TEXT)) != 0 )
183            labelStr = wxStripMenuCodes(m_label);
184
185        wxCFStringRef l(labelStr, GetToolBarFontEncoding());
186        wxCFStringRef sh( GetShortHelp(), GetToolBarFontEncoding() );
187#if wxOSX_USE_NATIVE_TOOLBAR
188       if ( m_toolbarItem )
189        {
190            // strip mnemonics from the label for compatibility with the usual
191            // labels in wxStaticText sense
192
193            [m_toolbarItem setLabel:l.AsNSString()];
194
195            [m_toolbarItem setToolTip:sh.AsNSString()];
196        }
197#endif
198        if ( IsButton() )
199        {
200            NSButton* const btn = (NSButton*)m_controlHandle;
201
202            [btn setTitle:l.AsNSString()];
203
204            if ( style & wxTB_NOICONS )
205                [btn setImagePosition:NSNoImage];
206            else if ( style & wxTB_TEXT )
207                [btn setImagePosition:NSImageAbove];
208            else
209                [btn setImagePosition:NSImageOnly];
210
211            if ( (style & (wxTB_NOICONS | wxTB_TEXT)) != 0 )
212            {
213                [btn sizeToFit];
214            }
215            else if (tbar)
216            {
217                wxSize toolsize = tbar->GetToolSize();
218                NSRect frame = [m_controlHandle frame];
219                frame.size.width = toolsize.x;
220                frame.size.height = toolsize.y + 2;
221                [btn setFrame:frame];
222            }
223        }
224
225        if ( m_controlHandle )
226        {
227            [m_controlHandle setToolTip:sh.AsNSString()];
228        }
229    }
230
231    void Action()
232    {
233        wxToolBar *tbar = (wxToolBar*) GetToolBar();
234        if (CanBeToggled())
235        {
236            bool    shouldToggle;
237
238            shouldToggle = !IsToggled();
239            tbar->ToggleTool( GetId(), shouldToggle );
240        }
241
242        tbar->OnLeftClick( GetId(), IsToggled() );
243    }
244
245#if wxOSX_USE_NATIVE_TOOLBAR
246    void SetToolbarItemRef( NSToolbarItem* ref )
247    {
248        if ( m_toolbarItem )
249            [m_toolbarItem release];
250
251        m_toolbarItem = ref;
252    }
253
254    NSToolbarItem* GetToolbarItemRef() const
255    {
256        return m_toolbarItem;
257    }
258
259    void SetIndex( CFIndex idx )
260    {
261        m_index = idx;
262    }
263
264    CFIndex GetIndex() const
265    {
266        return m_index;
267    }
268
269    virtual void SetLabel(const wxString& label) wxOVERRIDE
270    {
271        wxToolBarToolBase::SetLabel(label);
272        UpdateLabel();
273    }
274
275    virtual bool SetShortHelp(const wxString& help) wxOVERRIDE
276    {
277        if ( !wxToolBarToolBase::SetShortHelp(help) )
278            return false;
279
280        UpdateLabel();
281
282        return true;
283    }
284#endif // wxOSX_USE_NATIVE_TOOLBAR
285
286private:
287    wxFontEncoding GetToolBarFontEncoding() const
288    {
289        wxFont f;
290        if ( GetToolBar() )
291            f = GetToolBar()->GetFont();
292        return f.IsOk() ? f.GetEncoding() : wxFont::GetDefaultEncoding();
293    }
294
295    void Init()
296    {
297        m_controlHandle = NULL;
298
299#if wxOSX_USE_NATIVE_TOOLBAR
300        m_toolbarItem = NULL;
301        m_index = -1;
302#endif
303    }
304
305    WXWidget m_controlHandle;
306    wxCoord     m_x;
307    wxCoord     m_y;
308    wxBitmap    m_alternateBitmap;
309
310#if wxOSX_USE_NATIVE_TOOLBAR
311    NSToolbarItem* m_toolbarItem;
312    // position in its toolbar, -1 means not inserted
313    CFIndex m_index;
314#endif
315};
316
317#if wxOSX_USE_NATIVE_TOOLBAR
318
319@interface wxNSToolbarItem : NSToolbarItem
320{
321    wxToolBarTool* impl;
322}
323
324- (id) initWithItemIdentifier: (NSString*) identifier;
325- (void)setImplementation: (wxToolBarTool *) theImplementation;
326- (wxToolBarTool*) implementation;
327- (void) clickedAction: (id) sender;
328- (BOOL) validateToolbarItem:(NSToolbarItem *)theItem;
329
330@end
331
332
333@interface wxNSToolbarDelegate : NSObject <NSToolbarDelegate>
334{
335    bool m_isSelectable;
336}
337
338- (void)setSelectable:(bool) value;
339
340- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag;
341
342- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar;
343
344- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar;
345
346- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar;
347
348@end
349
350
351@interface wxNSToolbar : NSToolbar
352{
353    wxNSToolbarDelegate* toolbarDelegate;
354}
355
356- (id)initWithIdentifier:(NSString *)identifier;
357- (void) dealloc;
358
359@end
360
361#endif
362
363
364#if wxOSX_USE_NATIVE_TOOLBAR
365
366@implementation wxNSToolbarItem
367
368- (id)initWithItemIdentifier: (NSString*) identifier
369{
370    if ( self = [super initWithItemIdentifier:identifier] )
371    {
372        impl = NULL;
373        [self setTarget: self];
374        [self setAction: @selector(clickedAction:)];
375    }
376    return self;
377}
378
379- (void) clickedAction: (id) sender
380{
381    wxUnusedVar(sender);
382    if ( impl )
383    {
384        impl->Action();
385    }
386}
387
388- (void)setImplementation: (wxToolBarTool *) theImplementation
389{
390    impl = theImplementation;
391}
392
393- (wxToolBarTool*) implementation
394{
395    return impl;
396}
397
398- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
399{
400    wxUnusedVar(theItem);
401    return impl->IsEnabled() ? YES:NO;
402}
403
404@end
405
406@implementation wxNSToolbarDelegate
407
408- (id)init
409{
410    if ( self = [super init] )
411    {
412        m_isSelectable = false;
413    }
414    return self;
415}
416
417- (void)setSelectable:(bool) value
418{
419    wxUnusedVar(value);
420    m_isSelectable = true;
421}
422
423- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
424{
425    wxUnusedVar(toolbar);
426    return nil;
427}
428
429- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
430{
431    wxUnusedVar(toolbar);
432    return nil;
433}
434
435- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
436{
437  if ( m_isSelectable )
438      return [[toolbar items] valueForKey:@"itemIdentifier"];
439  else
440      return nil;
441}
442
443- (NSToolbarItem*) toolbar:(NSToolbar*) toolbar itemForItemIdentifier:(NSString*) itemIdentifier willBeInsertedIntoToolbar:(BOOL) flag
444{
445    wxUnusedVar(toolbar);
446#ifdef __LP64__
447    wxToolBarTool* tool = (wxToolBarTool*) [itemIdentifier longLongValue];
448#else
449    wxToolBarTool* tool = (wxToolBarTool*) [itemIdentifier intValue];
450#endif
451    if ( tool )
452    {
453        wxNSToolbarItem* item = (wxNSToolbarItem*) tool->GetToolbarItemRef();
454        if ( flag && tool->IsControl() )
455        {
456            NSView* view = tool->GetControl()->GetHandle();
457            [view removeFromSuperview];
458            [item setView:view];
459            wxSize sz = tool->GetControl()->GetSize();
460            NSSize size = NSMakeSize((float)sz.x, (float)sz.y);
461            [item setMaxSize:size];
462            [item setMinSize:size];
463            [view setHidden:NO];
464        }
465        return item;
466    }
467    return nil;
468}
469
470@end
471
472
473@implementation wxNSToolbar
474
475- (id)initWithIdentifier:(NSString *)identifier
476{
477    if (self = [super initWithIdentifier:identifier])
478    {
479        toolbarDelegate = [[wxNSToolbarDelegate alloc] init];
480        [self setDelegate:toolbarDelegate];
481    }
482    return self;
483}
484
485- (void)dealloc
486{
487    [toolbarDelegate release];
488    [super dealloc];
489}
490
491@end
492
493#endif
494
495@implementation wxNSToolBarButton
496
497- (id)initWithFrame:(NSRect)frame
498{
499    if ( self = [super initWithFrame:frame] )
500    {
501        impl = NULL;
502        [self setTarget: self];
503        [self setAction: @selector(clickedAction:)];
504    }
505    return self;
506}
507
508- (void) clickedAction: (id) sender
509{
510    wxUnusedVar(sender);
511    if ( impl )
512    {
513        impl->Action();
514    }
515}
516
517- (void)setImplementation: (wxToolBarTool *) theImplementation
518{
519    impl = theImplementation;
520}
521
522- (wxToolBarTool*) implementation
523{
524    return impl;
525}
526
527- (BOOL) isFlipped
528{
529    return YES;
530}
531
532@end
533
534bool wxToolBarTool::Enable( bool enable )
535{
536    if ( wxToolBarToolBase::Enable( enable ) == false )
537        return false;
538
539    if ( IsControl() )
540    {
541        GetControl()->Enable( enable );
542    }
543    else if ( IsButton() )
544    {
545#if wxOSX_USE_NATIVE_TOOLBAR
546        if ( m_toolbarItem != NULL )
547            [m_toolbarItem setEnabled:enable];
548#endif
549
550        if ( m_controlHandle != NULL )
551            [(NSControl*)m_controlHandle setEnabled:enable];
552    }
553
554    return true;
555}
556
557void wxToolBarTool::SetPosition( const wxPoint& position )
558{
559    m_x = position.x;
560    m_y = position.y;
561
562    int mac_x = position.x;
563    int mac_y = position.y;
564
565    if ( IsButton() )
566    {
567        NSRect frame = [m_controlHandle frame];
568        if ( frame.origin.x != mac_x || frame.origin.y != mac_y )
569        {
570            frame.origin.x = mac_x;
571            frame.origin.y = mac_y;
572            [m_controlHandle setFrame:frame];
573        }
574    }
575    else if ( IsControl() )
576    {
577        // embedded native controls are moved by the OS
578#if wxOSX_USE_NATIVE_TOOLBAR
579        if ( ((wxToolBar*)GetToolBar())->MacWantsNativeToolbar() == false )
580#endif
581        {
582            GetControl()->Move( position );
583        }
584    }
585    else
586    {
587        NSRect frame = [m_controlHandle frame];
588        if ( frame.origin.x != mac_x || frame.origin.y != mac_y )
589        {
590            frame.origin.x = mac_x;
591            frame.origin.y = mac_y;
592            [m_controlHandle setFrame:frame];
593        }
594    }
595}
596
597void wxToolBarTool::UpdateImages()
598{
599    [(NSButton*) m_controlHandle setImage:m_bmpNormal.GetNSImage()];
600
601    if ( CanBeToggled() )
602    {
603        int w = m_bmpNormal.GetScaledWidth();
604        int h = m_bmpNormal.GetScaledHeight();
605        m_alternateBitmap = wxBitmap();
606        m_alternateBitmap.CreateScaled(w, h, -1, m_bmpNormal.GetScaleFactor());
607        m_alternateBitmap.UseAlpha();
608        wxMemoryDC dc;
609
610        dc.SelectObject(m_alternateBitmap);
611        // This color corresponds to OS X Yosemite's rendering of selected toolbar items
612        // See also https://trac.wxwidgets.org/ticket/16645
613        wxColour grey(0xB9, 0xB9, 0xB9);
614        dc.SetBackground(*wxTRANSPARENT_BRUSH);
615        dc.Clear();
616        dc.SetPen(grey);
617        dc.SetBrush(grey);
618        dc.DrawRoundedRectangle( 0, 0, w, h, 3 );
619        dc.DrawBitmap( m_bmpNormal, 0, 0, true );
620        dc.SelectObject( wxNullBitmap );
621
622        [(NSButton*) m_controlHandle setAlternateImage:m_alternateBitmap.GetNSImage()];
623    }
624    UpdateToggleImage( CanBeToggled() && IsToggled() );
625}
626
627void wxToolBarTool::UpdateToggleImage( bool toggle )
628{
629#if wxOSX_USE_NATIVE_TOOLBAR
630    // Avoid setting the image if we're not showing icons because the image may
631    // be invalid.
632    wxToolBar *tbar = (wxToolBar*) GetToolBar();
633    int style = tbar ? tbar->GetWindowStyleFlag() : 0;
634    if ( m_toolbarItem != NULL && !(style & wxTB_NOICONS) )
635    {
636        // the native toolbar item only has a 'selected' state (one for one toolbar)
637        // so we emulate the toggle here
638        if ( CanBeToggled() && toggle )
639            [m_toolbarItem setImage:m_alternateBitmap.GetNSImage()];
640        else
641            [m_toolbarItem setImage:m_bmpNormal.GetNSImage()];
642    }
643#endif
644
645    if ( IsButton() )
646        [(NSButton*)m_controlHandle setState:(toggle ? NSOnState : NSOffState)];
647}
648
649wxToolBarTool::wxToolBarTool(
650    wxToolBar *tbar,
651    int id,
652    const wxString& label,
653    const wxBitmap& bmpNormal,
654    const wxBitmap& bmpDisabled,
655    wxItemKind kind,
656    wxObject *clientData,
657    const wxString& shortHelp,
658    const wxString& longHelp )
659    :
660    wxToolBarToolBase(
661        tbar, id, label, bmpNormal, bmpDisabled, kind,
662        clientData, shortHelp, longHelp )
663{
664    Init();
665}
666
667#pragma mark -
668#pragma mark Toolbar Implementation
669
670wxToolBarToolBase *wxToolBar::CreateTool(
671    int id,
672    const wxString& label,
673    const wxBitmap& bmpNormal,
674    const wxBitmap& bmpDisabled,
675    wxItemKind kind,
676    wxObject *clientData,
677    const wxString& shortHelp,
678    const wxString& longHelp )
679{
680    return new wxToolBarTool(
681        this, id, label, bmpNormal, bmpDisabled, kind,
682        clientData, shortHelp, longHelp );
683}
684
685wxToolBarToolBase *
686wxToolBar::CreateTool(wxControl *control, const wxString& label)
687{
688    return new wxToolBarTool(this, control, label);
689}
690
691void wxToolBar::Init()
692{
693    m_maxWidth = -1;
694    m_maxHeight = -1;
695    m_defaultWidth = kwxMacToolBarToolDefaultWidth;
696    m_defaultHeight = kwxMacToolBarToolDefaultHeight;
697
698#if wxOSX_USE_NATIVE_TOOLBAR
699    m_macToolbar = NULL;
700    m_macUsesNativeToolbar = false;
701#endif
702}
703
704// also for the toolbar we have the dual implementation:
705// only when MacInstallNativeToolbar is called is the native toolbar set as the window toolbar
706
707bool wxToolBar::Create(
708    wxWindow *parent,
709    wxWindowID id,
710    const wxPoint& pos,
711    const wxSize& size,
712    long style,
713    const wxString& name )
714{
715    if ( !wxToolBarBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ) )
716        return false;
717
718    FixupStyle();
719
720    OSStatus err = noErr;
721
722#if wxOSX_USE_NATIVE_TOOLBAR
723
724    if (parent->IsKindOf(CLASSINFO(wxFrame)) && wxSystemOptions::GetOptionInt(wxT("mac.toolbar.no-native")) != 1)
725    {
726        wxString identifier = wxString::Format( wxT("%p"), this );
727        wxCFStringRef cfidentifier(identifier);
728        NSToolbar* tb =  [[wxNSToolbar alloc] initWithIdentifier:cfidentifier.AsNSString()];
729
730        m_macToolbar = tb ;
731
732        if (m_macToolbar != NULL)
733        {
734            NSToolbarDisplayMode mode = NSToolbarDisplayModeDefault;
735            NSToolbarSizeMode displaySize = NSToolbarSizeModeSmall;
736
737            if ( style & wxTB_NOICONS )
738                mode = NSToolbarDisplayModeLabelOnly;
739            else if ( style & wxTB_TEXT )
740                mode = NSToolbarDisplayModeIconAndLabel;
741            else
742                mode = NSToolbarDisplayModeIconOnly;
743
744            [tb setDisplayMode:mode];
745            [tb setSizeMode:displaySize];
746       }
747    }
748#endif // wxOSX_USE_NATIVE_TOOLBAR
749
750    return (err == noErr);
751}
752
753wxToolBar::~wxToolBar()
754{
755    // removal only works while the toolbar is there
756    wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
757    if ( frame && frame->GetToolBar() == this )
758    {
759        frame->SetToolBar(NULL);
760    }
761
762#if wxOSX_USE_NATIVE_TOOLBAR
763    [(NSToolbar*)m_macToolbar setDelegate:nil];
764    [(NSToolbar*)m_macToolbar release];
765    m_macToolbar = NULL;
766#endif // wxOSX_USE_NATIVE_TOOLBAR
767}
768
769bool wxToolBar::Show( bool show )
770{
771    WXWindow tlw = MacGetTopLevelWindowRef();
772    bool bResult = (tlw != NULL);
773
774    if (bResult)
775    {
776#if wxOSX_USE_NATIVE_TOOLBAR
777        bool ownToolbarInstalled = false;
778        MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
779        if (ownToolbarInstalled)
780        {
781            bResult = ([(NSToolbar*)m_macToolbar isVisible] != show);
782            if ( bResult )
783                [(NSToolbar*)m_macToolbar setVisible:show];
784        }
785        else
786            bResult = wxToolBarBase::Show( show );
787#else
788
789        bResult = wxToolBarBase::Show( show );
790#endif
791    }
792
793    return bResult;
794}
795
796bool wxToolBar::IsShown() const
797{
798    bool bResult;
799
800#if wxOSX_USE_NATIVE_TOOLBAR
801    bool ownToolbarInstalled;
802
803    MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
804    if (ownToolbarInstalled)
805    {
806        bResult = [(NSToolbar*)m_macToolbar isVisible];
807    }
808    else
809        bResult = wxToolBarBase::IsShown();
810#else
811
812    bResult = wxToolBarBase::IsShown();
813#endif
814
815    return bResult;
816}
817
818void wxToolBar::DoGetSize( int *width, int *height ) const
819{
820#if wxOSX_USE_NATIVE_TOOLBAR
821    bool    ownToolbarInstalled;
822
823    MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
824    if ( ownToolbarInstalled )
825    {
826        WXWindow tlw = MacGetTopLevelWindowRef();
827        float toolbarHeight = 0.0;
828        NSRect windowFrame = NSMakeRect(0, 0, 0, 0);
829
830        if(m_macToolbar && [(NSToolbar*)m_macToolbar isVisible])
831        {
832            windowFrame = [NSWindow contentRectForFrameRect:[tlw frame]
833                                styleMask:[tlw styleMask]];
834            toolbarHeight = NSHeight(windowFrame)
835                        - NSHeight([[tlw contentView] frame]);
836        }
837
838        if ( width != NULL )
839            *width = (int)windowFrame.size.width;
840        if ( height != NULL )
841            *height = (int)toolbarHeight;
842    }
843    else
844        wxToolBarBase::DoGetSize( width, height );
845
846#else
847    wxToolBarBase::DoGetSize( width, height );
848#endif
849}
850
851void wxToolBar::DoGetPosition(int*x, int *y) const
852{
853#if wxOSX_USE_NATIVE_TOOLBAR
854    bool    ownToolbarInstalled;
855
856    MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
857    if ( ownToolbarInstalled )
858    {
859        WXWindow tlw = MacGetTopLevelWindowRef();
860        float toolbarHeight = 0.0;
861        NSRect windowFrame = NSMakeRect(0, 0, 0, 0);
862
863        if(m_macToolbar && [(NSToolbar*)m_macToolbar isVisible])
864        {
865            windowFrame = [NSWindow contentRectForFrameRect:[tlw frame]
866                                                  styleMask:[tlw styleMask]];
867            toolbarHeight = NSHeight(windowFrame)
868            - NSHeight([[tlw contentView] frame]);
869        }
870
871        // it is extending to the north of the content area
872
873        if ( x != NULL )
874            *x = 0;
875        if ( y != NULL )
876            *y = -toolbarHeight;
877    }
878    else
879        wxToolBarBase::DoGetPosition( x, y );
880
881#else
882    wxToolBarBase::DoGetPosition( x, y );
883#endif
884}
885
886wxSize wxToolBar::DoGetBestSize() const
887{
888    // was updated in Realize()
889
890    wxSize size = GetMinSize();
891
892    return size;
893}
894
895void wxToolBar::SetWindowStyleFlag( long style )
896{
897    wxToolBarBase::SetWindowStyleFlag( style );
898
899#if wxOSX_USE_NATIVE_TOOLBAR
900    if (m_macToolbar != NULL)
901    {
902        NSToolbarDisplayMode mode = NSToolbarDisplayModeDefault;
903
904        if ( style & wxTB_NOICONS )
905            mode = NSToolbarDisplayModeLabelOnly;
906        else if ( style & wxTB_TEXT )
907            mode = NSToolbarDisplayModeIconAndLabel;
908        else
909            mode = NSToolbarDisplayModeIconOnly;
910
911        [(NSToolbar*) m_macToolbar setDisplayMode:mode];
912    }
913#endif
914
915    wxToolBarTool *tool;
916    wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
917    while ( node )
918    {
919        tool = (wxToolBarTool *) node->GetData();
920        if ( tool != NULL )
921        {
922            tool->UpdateLabel();
923        }
924
925        node = node->GetNext();
926    }
927
928    InvalidateBestSize();
929}
930
931#if wxOSX_USE_NATIVE_TOOLBAR
932bool wxToolBar::MacWantsNativeToolbar()
933{
934    return m_macUsesNativeToolbar;
935}
936
937bool wxToolBar::MacTopLevelHasNativeToolbar(bool *ownToolbarInstalled) const
938{
939    bool bResultV = false;
940
941    if (ownToolbarInstalled != NULL)
942        *ownToolbarInstalled = false;
943
944    WXWindow tlw = MacGetTopLevelWindowRef();
945    if (tlw != NULL)
946    {
947        NSToolbar* curToolbarRef = [tlw toolbar];
948        bResultV = (curToolbarRef != NULL);
949        if (bResultV && (ownToolbarInstalled != NULL))
950            *ownToolbarInstalled = (curToolbarRef == m_macToolbar);
951    }
952
953    return bResultV;
954}
955
956bool wxToolBar::MacInstallNativeToolbar(bool usesNative)
957{
958    bool bResult = false;
959
960    if (usesNative && (m_macToolbar == NULL))
961        return bResult;
962
963    if (usesNative && HasFlag(wxTB_LEFT|wxTB_RIGHT|wxTB_BOTTOM) )
964        return bResult;
965
966    WXWindow tlw = MacGetTopLevelWindowRef();
967    if (tlw == NULL)
968        return bResult;
969
970    // check the existing toolbar
971    NSToolbar* curToolbarRef = [tlw toolbar];
972
973    m_macUsesNativeToolbar = usesNative;
974
975    if (m_macUsesNativeToolbar)
976    {
977        // only install toolbar if there isn't one installed already
978        if (curToolbarRef == NULL)
979        {
980            bResult = true;
981            [tlw setToolbar:(NSToolbar*) m_macToolbar];
982            [(NSToolbar*) m_macToolbar setVisible:YES];
983
984            GetPeer()->Move(0,0,0,0 );
985            SetSize( wxSIZE_AUTO_WIDTH, 0 );
986            GetPeer()->SetVisibility( false );
987            wxToolBarBase::Show( false );
988        }
989    }
990    else
991    {
992        // only deinstall toolbar if this is the installed one
993        if (m_macToolbar == curToolbarRef)
994        {
995            bResult = true;
996            [(NSToolbar*) m_macToolbar setVisible:NO];
997            MacUninstallNativeToolbar();
998            GetPeer()->SetVisibility( true );
999        }
1000    }
1001
1002    if (bResult)
1003        InvalidateBestSize();
1004
1005// wxLogDebug( wxT("    --> [%lx] - result [%s]"), (long)this, bResult ? wxT("T") : wxT("F") );
1006    return bResult;
1007}
1008
1009void wxToolBar::MacUninstallNativeToolbar()
1010{
1011    if (!m_macToolbar)
1012        return;
1013
1014    WXWindow tlw = MacGetTopLevelWindowRef();
1015    if (tlw)
1016        [tlw setToolbar:nil];
1017}
1018#endif
1019
1020void wxToolBar::DoLayout()
1021{
1022    int maxToolWidth = 0;
1023    int maxToolHeight = 0;
1024
1025    int tw, th;
1026    GetSize( &tw, &th );
1027
1028    // find the maximum tool width and height
1029    // and the number of stretchable items
1030    int numStretchableSpaces = 0;
1031    wxToolBarTool *tool;
1032    wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1033    while ( node )
1034    {
1035        tool = (wxToolBarTool *) node->GetData();
1036        if ( tool != NULL )
1037        {
1038            wxSize  sz = tool->GetSize();
1039
1040            if ( sz.x > maxToolWidth )
1041                maxToolWidth = sz.x;
1042            if ( sz.y > maxToolHeight )
1043                maxToolHeight = sz.y;
1044            if ( tool->IsStretchableSpace() )
1045                numStretchableSpaces++;
1046        }
1047
1048        node = node->GetNext();
1049    }
1050
1051    // layout non-native toolbar
1052
1053    bool isHorizontal =  !IsVertical();
1054
1055    int maxWidth = 0;
1056    int maxHeight = 0;
1057
1058    int x = m_xMargin + kwxMacToolBarLeftMargin;
1059    int y = m_yMargin + kwxMacToolBarTopMargin;
1060
1061    node = m_tools.GetFirst();
1062    while ( node )
1063    {
1064        tool = (wxToolBarTool*) node->GetData();
1065        if ( tool == NULL )
1066        {
1067            node = node->GetNext();
1068            continue;
1069        }
1070
1071        // set tool position:
1072        // for the moment just perform a single row/column alignment
1073        wxSize  cursize = tool->GetSize();
1074        if ( x + cursize.x > maxWidth )
1075            maxWidth = x + cursize.x;
1076        if ( y + cursize.y > maxHeight )
1077            maxHeight = y + cursize.y;
1078
1079        // update the item positioning state
1080        if ( !isHorizontal )
1081            y += cursize.y + kwxMacToolSpacing;
1082        else
1083            x += cursize.x + kwxMacToolSpacing;
1084
1085        node = node->GetNext();
1086    }
1087
1088    if ( isHorizontal )
1089    {
1090        // if not set yet, only one row
1091        if ( m_maxRows <= 0 )
1092            SetRows( 1 );
1093
1094        maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
1095        m_minWidth = maxWidth;
1096        m_minHeight = m_maxHeight = maxToolHeight + 2 * (m_yMargin + kwxMacToolBarTopMargin);
1097    }
1098    else
1099    {
1100        // if not set yet, have one column
1101        if ( (GetToolsCount() > 0) && (m_maxRows <= 0) )
1102            SetRows( GetToolsCount() );
1103
1104        maxHeight += m_yMargin + kwxMacToolBarTopMargin;
1105        m_minHeight = maxHeight;
1106        m_minWidth = m_maxWidth = maxToolWidth + 2 * (m_yMargin + kwxMacToolBarTopMargin);
1107    }
1108
1109    int totalStretchableSpace = 0;
1110    int spacePerStretchable = 0;
1111    if ( numStretchableSpaces > 0 )
1112    {
1113        if ( isHorizontal )
1114            totalStretchableSpace = tw - maxWidth;
1115        else
1116            totalStretchableSpace = th - maxHeight;
1117
1118        if ( totalStretchableSpace > 0 )
1119            spacePerStretchable = totalStretchableSpace / numStretchableSpaces;
1120    }
1121
1122    // perform real positioning
1123
1124    x = m_xMargin + kwxMacToolBarLeftMargin;
1125    y = m_yMargin + kwxMacToolBarTopMargin;
1126
1127    node = m_tools.GetFirst();
1128    int currentStretchable = 0;
1129    while ( node )
1130    {
1131        tool = (wxToolBarTool*) node->GetData();
1132        if ( tool == NULL )
1133        {
1134            node = node->GetNext();
1135            continue;
1136        }
1137
1138        wxSize  cursize = tool->GetSize();
1139        if ( tool->IsStretchableSpace() )
1140        {
1141            ++currentStretchable;
1142            int thisSpace = currentStretchable == numStretchableSpaces ?
1143            totalStretchableSpace - (currentStretchable-1)*spacePerStretchable :
1144            spacePerStretchable;
1145            if ( isHorizontal )
1146                cursize.x += thisSpace;
1147            else
1148                cursize.y += thisSpace;
1149        }
1150
1151        if ( !isHorizontal )
1152        {
1153            int x1 = x + ( maxToolWidth - cursize.x ) / 2;
1154            tool->SetPosition( wxPoint(x1, y) );
1155        }
1156        else
1157        {
1158            int y1 = y + ( maxToolHeight - cursize.y ) / 2;
1159            tool->SetPosition( wxPoint(x, y1) );
1160        }
1161
1162        // update the item positioning state
1163        if ( !isHorizontal )
1164            y += cursize.y + kwxMacToolSpacing;
1165        else
1166            x += cursize.x + kwxMacToolSpacing;
1167
1168        node = node->GetNext();
1169    }
1170
1171}
1172
1173bool wxToolBar::Realize()
1174{
1175    if ( !wxToolBarBase::Realize() )
1176        return false;
1177
1178    wxToolBarTool *tool;
1179    wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1180
1181#if wxOSX_USE_NATIVE_TOOLBAR
1182    CFIndex currentPosition = 0;
1183    bool insertAll = false;
1184
1185    NSToolbar* refTB = (NSToolbar*)m_macToolbar;
1186    wxFont f;
1187    wxFontEncoding enc;
1188    f = GetFont();
1189    if ( f.IsOk() )
1190        enc = f.GetEncoding();
1191    else
1192        enc = wxFont::GetDefaultEncoding();
1193
1194    node = m_tools.GetFirst();
1195    while ( node )
1196    {
1197        tool = (wxToolBarTool*) node->GetData();
1198        if ( tool == NULL )
1199        {
1200            node = node->GetNext();
1201            continue;
1202        }
1203
1204        // install in native NSToolbar
1205        if ( refTB )
1206        {
1207            NSToolbarItem* hiItemRef = tool->GetToolbarItemRef();
1208            if ( hiItemRef != NULL )
1209            {
1210                // since setting the help texts is non-virtual we have to update
1211                // the strings now
1212                wxCFStringRef sh( tool->GetShortHelp(), enc);
1213                [hiItemRef setToolTip:sh.AsNSString()];
1214
1215                if ( insertAll || (tool->GetIndex() != currentPosition) )
1216                {
1217                    if ( !insertAll )
1218                    {
1219                        insertAll = true;
1220
1221                        // if this is the first tool that gets newly inserted or repositioned
1222                        // first remove all 'old' tools from here to the right, because of this
1223                        // all following tools will have to be reinserted (insertAll).
1224                        for ( wxToolBarToolsList::compatibility_iterator node2 = m_tools.GetLast();
1225                             node2 != node;
1226                             node2 = node2->GetPrevious() )
1227                        {
1228                            wxToolBarTool *tool2 = (wxToolBarTool*) node2->GetData();
1229
1230                            const long idx = tool2->GetIndex();
1231                            if ( idx != -1 )
1232                            {
1233                                [refTB removeItemAtIndex:idx];
1234                                tool2->SetIndex(-1);
1235                            }
1236                        }
1237                    }
1238
1239                    wxCFStringRef cfidentifier;
1240                    NSString *nsItemId;
1241                    if (tool->GetStyle() == wxTOOL_STYLE_SEPARATOR)
1242                    {
1243                        if ( tool->IsStretchable() )
1244                            nsItemId = NSToolbarFlexibleSpaceItemIdentifier;
1245                        else
1246                            nsItemId = NSToolbarSpaceItemIdentifier;
1247                    }
1248                    else
1249                    {
1250                        cfidentifier = wxCFStringRef(wxString::Format("%ld", (long)tool));
1251                        nsItemId = cfidentifier.AsNSString();
1252                    }
1253
1254                    [refTB insertItemWithItemIdentifier:nsItemId atIndex:currentPosition];
1255                    tool->SetIndex( currentPosition );
1256                }
1257
1258                currentPosition++;
1259            }
1260        }
1261        node = node->GetNext();
1262    }
1263
1264#endif
1265
1266    DoLayout();
1267
1268    // adjust radio items
1269
1270    bool lastIsRadio = false;
1271    bool curIsRadio = false;
1272
1273    node = m_tools.GetFirst();
1274    while ( node )
1275    {
1276        tool = (wxToolBarTool*) node->GetData();
1277        if ( tool == NULL )
1278        {
1279            node = node->GetNext();
1280            continue;
1281        }
1282
1283        // update radio button (and group) state
1284        lastIsRadio = curIsRadio;
1285        curIsRadio = ( tool->IsButton() && (tool->GetKind() == wxITEM_RADIO) );
1286
1287        if ( !curIsRadio )
1288        {
1289            if ( tool->IsToggled() )
1290                DoToggleTool( tool, true );
1291        }
1292        else
1293        {
1294            if ( !lastIsRadio )
1295            {
1296                if ( tool->Toggle( true ) )
1297                {
1298                    DoToggleTool( tool, true );
1299                }
1300            }
1301            else if ( tool->IsToggled() )
1302            {
1303                if ( tool->IsToggled() )
1304                    DoToggleTool( tool, true );
1305
1306                wxToolBarToolsList::compatibility_iterator  nodePrev = node->GetPrevious();
1307                while ( nodePrev )
1308                {
1309                    wxToolBarToolBase   *toggleTool = nodePrev->GetData();
1310                    if ( (toggleTool == NULL) || !toggleTool->IsButton() || (toggleTool->GetKind() != wxITEM_RADIO) )
1311                        break;
1312
1313                    if ( toggleTool->Toggle( false ) )
1314                        DoToggleTool( toggleTool, false );
1315
1316                    nodePrev = nodePrev->GetPrevious();
1317                }
1318            }
1319        }
1320
1321        node = node->GetNext();
1322    }
1323
1324    InvalidateBestSize();
1325    SetInitialSize( wxSize(m_minWidth, m_minHeight));
1326
1327    SendSizeEventToParent();
1328
1329    return true;
1330}
1331
1332void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1333{
1334    wxToolBarBase::DoSetSize(x, y, width, height, sizeFlags);
1335
1336    DoLayout();
1337}
1338
1339void wxToolBar::SetToolBitmapSize(const wxSize& size)
1340{
1341    m_defaultWidth = size.x + kwxMacToolBorder;
1342    m_defaultHeight = size.y + kwxMacToolBorder;
1343
1344#if wxOSX_USE_NATIVE_TOOLBAR
1345    if (m_macToolbar != NULL)
1346    {
1347        int maxs = wxMax( size.x, size.y );
1348        NSToolbarSizeMode sizeSpec;
1349
1350        if ( maxs > 24 )
1351            sizeSpec = NSToolbarSizeModeRegular;
1352        else
1353            sizeSpec = NSToolbarSizeModeSmall;
1354
1355        [(NSToolbar*) m_macToolbar setSizeMode:sizeSpec ];
1356    }
1357#endif
1358}
1359
1360// The button size is bigger than the bitmap size
1361wxSize wxToolBar::GetToolSize() const
1362{
1363    return wxSize(m_defaultWidth + kwxMacToolBorder, m_defaultHeight + kwxMacToolBorder);
1364}
1365
1366void wxToolBar::SetRows(int nRows)
1367{
1368    // avoid resizing the frame uselessly
1369    if ( nRows != m_maxRows )
1370        m_maxRows = nRows;
1371}
1372
1373void wxToolBar::MacSuperChangedPosition()
1374{
1375    wxWindow::MacSuperChangedPosition();
1376
1377    /*
1378#if wxOSX_USE_NATIVE_TOOLBAR
1379    if (! m_macUsesNativeToolbar )
1380        Realize();
1381#else
1382
1383    Realize();
1384#endif
1385     */
1386}
1387
1388void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap )
1389{
1390    wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id));
1391    if ( tool )
1392    {
1393        wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
1394
1395        tool->SetNormalBitmap(bitmap);
1396
1397        // a side-effect of the UpdateToggleImage function is that it always changes the bitmap used on the button.
1398        tool->UpdateImages();
1399    }
1400}
1401
1402void wxToolBar::SetToolDisabledBitmap( int id, const wxBitmap& bitmap )
1403{
1404    wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id));
1405    if ( tool )
1406    {
1407        wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
1408
1409        tool->SetDisabledBitmap(bitmap);
1410
1411        // TODO:  what to do for this one?
1412    }
1413}
1414
1415wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
1416{
1417    wxToolBarTool *tool;
1418    wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1419    while ( node )
1420    {
1421        tool = (wxToolBarTool *)node->GetData();
1422        if (tool != NULL)
1423        {
1424            wxRect2DInt r( tool->GetPosition(), tool->GetSize() );
1425            if ( r.Contains( wxPoint( x, y ) ) )
1426                return tool;
1427        }
1428
1429        node = node->GetNext();
1430    }
1431
1432    return NULL;
1433}
1434
1435wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
1436{
1437    wxToolBarToolBase *tool = FindToolForPosition( pt.x, pt.y );
1438    if ( tool != NULL )
1439        return tool->GetShortHelp();
1440
1441    return wxEmptyString;
1442}
1443
1444void wxToolBar::DoEnableTool(wxToolBarToolBase * WXUNUSED(t), bool WXUNUSED(enable))
1445{
1446    // everything already done in the tool's Enable implementation
1447}
1448
1449void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
1450{
1451    wxToolBarTool *tool = (wxToolBarTool *)t;
1452    if ( ( tool != NULL ) && tool->IsButton() )
1453        tool->UpdateToggleImage( toggle );
1454}
1455
1456bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
1457{
1458    wxToolBarTool *tool = static_cast< wxToolBarTool*>(toolBase );
1459    if (tool == NULL)
1460        return false;
1461
1462    long style = GetWindowStyleFlag();
1463
1464    wxSize toolSize = GetToolSize();
1465    WXWidget controlHandle = NULL;
1466    NSRect toolrect = NSMakeRect(0, 0, toolSize.x, toolSize.y + 2 );
1467
1468#if wxOSX_USE_NATIVE_TOOLBAR
1469    wxString label = tool->GetLabel();
1470    if (m_macToolbar && !label.empty() )
1471    {
1472        // strip mnemonics from the label for compatibility
1473        // with the usual labels in wxStaticText sense
1474        label = wxStripMenuCodes(label);
1475    }
1476#endif // wxOSX_USE_NATIVE_TOOLBAR
1477
1478    switch (tool->GetStyle())
1479    {
1480        case wxTOOL_STYLE_SEPARATOR:
1481            {
1482                wxASSERT( tool->GetControlHandle() == NULL );
1483                toolSize.x /= 4;
1484                toolSize.y /= 4;
1485                if ( IsVertical() )
1486                    toolrect.size.height = toolSize.y;
1487                else
1488                    toolrect.size.width = toolSize.x;
1489
1490                // in flat style we need a visual separator
1491#if wxOSX_USE_NATIVE_TOOLBAR
1492                if (m_macToolbar != NULL)
1493                {
1494                    NSString * nsItemId = nil;
1495
1496                    if ( tool->IsStretchable() )
1497                        nsItemId = NSToolbarFlexibleSpaceItemIdentifier;
1498                    else
1499                        nsItemId = NSToolbarSpaceItemIdentifier;
1500
1501                    NSToolbarItem* item = [[NSToolbarItem alloc] initWithItemIdentifier:nsItemId];
1502                    tool->SetToolbarItemRef( item );
1503                }
1504#endif // wxOSX_USE_NATIVE_TOOLBAR
1505
1506                NSBox* box = [[NSBox alloc] initWithFrame:toolrect];
1507                [box setBoxType:NSBoxSeparator];
1508                controlHandle = box;
1509                tool->SetControlHandle( controlHandle );
1510            }
1511            break;
1512
1513        case wxTOOL_STYLE_BUTTON:
1514            {
1515                wxASSERT( tool->GetControlHandle() == NULL );
1516
1517                wxNSToolBarButton* v = [[wxNSToolBarButton alloc] initWithFrame:toolrect];
1518
1519                [v setBezelStyle:NSSmallSquareBezelStyle];
1520                [[v cell] setControlSize:NSSmallControlSize];
1521                [v setFont:[NSFont fontWithName:[[v font] fontName] size:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
1522                [v setBordered:NO];
1523                [v setButtonType: ( tool->CanBeToggled() ? NSToggleButton : NSMomentaryPushInButton )];
1524                [v setImplementation:tool];
1525
1526                controlHandle = v;
1527
1528#if wxOSX_USE_NATIVE_TOOLBAR
1529                if (m_macToolbar != NULL)
1530                {
1531                    wxString identifier = wxString::Format(wxT("%ld"), (long) tool);
1532                    wxCFStringRef cfidentifier( identifier, wxFont::GetDefaultEncoding() );
1533                    wxNSToolbarItem* item = [[wxNSToolbarItem alloc] initWithItemIdentifier:cfidentifier.AsNSString() ];
1534                    [item setImplementation:tool];
1535                    tool->SetToolbarItemRef( item );
1536                }
1537
1538#endif // wxOSX_USE_NATIVE_TOOLBAR
1539                tool->SetControlHandle( controlHandle );
1540                if ( !(style & wxTB_NOICONS) )
1541                    tool->UpdateImages();
1542                tool->UpdateLabel();
1543
1544#if 0
1545                InstallControlEventHandler(
1546                    (WXWidget) controlHandle, GetwxMacToolBarToolEventHandlerUPP(),
1547                    GetEventTypeCount(eventList), eventList, tool, NULL );
1548#endif
1549            }
1550            break;
1551
1552        case wxTOOL_STYLE_CONTROL:
1553
1554#if wxOSX_USE_NATIVE_TOOLBAR
1555            if (m_macToolbar != NULL)
1556            {
1557                WXWidget view = (WXWidget) tool->GetControl()->GetHandle() ;
1558                wxCHECK_MSG( view, false, wxT("control must be non-NULL") );
1559
1560                wxString identifier = wxString::Format(wxT("%ld"), (long) tool);
1561                wxCFStringRef cfidentifier( identifier, wxFont::GetDefaultEncoding() );
1562                wxNSToolbarItem* item = [[wxNSToolbarItem alloc] initWithItemIdentifier:cfidentifier.AsNSString() ];
1563                [item setImplementation:tool];
1564                tool->SetToolbarItemRef( item );
1565           }
1566#else
1567            // right now there's nothing to do here
1568#endif
1569            tool->UpdateLabel();
1570            break;
1571
1572        default:
1573            break;
1574    }
1575
1576    if ( controlHandle )
1577    {
1578        WXWidget container = (WXWidget) GetHandle();
1579        wxASSERT_MSG( container != NULL, wxT("No valid Mac container control") );
1580
1581//        SetControlVisibility( controlHandle, true, true );
1582        [container addSubview:controlHandle];
1583    }
1584
1585    // nothing special to do here - we relayout in Realize() later
1586    InvalidateBestSize();
1587
1588    return true;
1589
1590}
1591
1592void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
1593{
1594    wxFAIL_MSG( wxT("not implemented") );
1595}
1596
1597bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolbase)
1598{
1599    wxToolBarTool* tool = static_cast< wxToolBarTool*>(toolbase );
1600    wxToolBarToolsList::compatibility_iterator node;
1601    for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
1602    {
1603        wxToolBarToolBase *tool2 = node->GetData();
1604        if ( tool2 == tool )
1605        {
1606            // let node point to the next node in the list
1607            node = node->GetNext();
1608
1609            break;
1610        }
1611    }
1612
1613    wxSize sz = ((wxToolBarTool*)tool)->GetSize();
1614
1615#if wxOSX_USE_NATIVE_TOOLBAR
1616    CFIndex removeIndex = tool->GetIndex();
1617#endif
1618
1619#if wxOSX_USE_NATIVE_TOOLBAR
1620    if (m_macToolbar != NULL)
1621    {
1622        if ( removeIndex != -1 && m_macToolbar )
1623        {
1624            [(NSToolbar*) m_macToolbar removeItemAtIndex:removeIndex];
1625            tool->SetIndex( -1 );
1626        }
1627    }
1628#endif
1629
1630    tool->ClearControl();
1631
1632    // and finally reposition all the controls after this one
1633
1634    for ( /* node -> first after deleted */; node; node = node->GetNext() )
1635    {
1636        wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
1637        wxPoint pt = tool2->GetPosition();
1638
1639        if ( IsVertical() )
1640            pt.y -= sz.y;
1641        else
1642            pt.x -= sz.x;
1643
1644        tool2->SetPosition( pt );
1645
1646#if wxOSX_USE_NATIVE_TOOLBAR
1647        if (m_macToolbar != NULL)
1648        {
1649            if ( removeIndex != -1 && tool2->GetIndex() > removeIndex )
1650                tool2->SetIndex( tool2->GetIndex() - 1 );
1651        }
1652#endif
1653    }
1654
1655    InvalidateBestSize();
1656
1657    return true;
1658}
1659
1660#include <Carbon/Carbon.h>
1661
1662void wxToolBar::OnPaint(wxPaintEvent& event)
1663{
1664#if wxOSX_USE_NATIVE_TOOLBAR
1665    if ( m_macUsesNativeToolbar )
1666    {
1667        // nothing to do here
1668    }
1669    else
1670#endif
1671    {
1672        const int direction = GetDirection();
1673        int w, h;
1674        GetSize( &w, &h );
1675
1676        wxPaintDC dc(this);
1677
1678        wxRect rect(0,0,w,h);
1679
1680        //  TODO determine whether to use flat appearance in earlier system
1681        if ( WX_IS_MACOS_AVAILABLE(10, 14 ) )
1682        {
1683            // No gradient.
1684        }
1685        else
1686        {
1687            dc.GradientFillLinear( rect , wxColour( 0xCC,0xCC,0xCC ), wxColour( 0xA8,0xA8,0xA8 ) , wxSOUTH );
1688        }
1689
1690        dc.SetPen( wxPen( wxColour( 0x51,0x51,0x51 ) ) );
1691
1692        if ( direction == wxTB_RIGHT )
1693            dc.DrawLine(0, 0, 0, h);
1694        else if ( direction == wxTB_LEFT )
1695            dc.DrawLine(w-1, 0, w-1, h);
1696        else if ( direction == wxTB_BOTTOM )
1697            dc.DrawLine(0, 0, w, 0);
1698        else if ( direction == wxTB_TOP )
1699            dc.DrawLine(0, h-1, w, h-1);
1700    }
1701    event.Skip();
1702}
1703
1704#if wxOSX_USE_NATIVE_TOOLBAR
1705void wxToolBar::OSXSetSelectableTools(bool set)
1706{
1707    wxCHECK_RET( m_macToolbar, "toolbar must be non-NULL" );
1708    [(wxNSToolbarDelegate*)[(NSToolbar*)m_macToolbar delegate] setSelectable:set];
1709}
1710
1711void wxToolBar::OSXSelectTool(int toolId)
1712{
1713    wxToolBarToolBase *tool = FindById(toolId);
1714    wxCHECK_RET( tool, "invalid tool ID" );
1715    wxCHECK_RET( m_macToolbar, "toolbar must be non-NULL" );
1716
1717    wxString identifier = wxString::Format(wxT("%ld"), (long)tool);
1718    wxCFStringRef cfidentifier(identifier, wxFont::GetDefaultEncoding());
1719    [(NSToolbar*)m_macToolbar setSelectedItemIdentifier:cfidentifier.AsNSString()];
1720}
1721#endif // wxOSX_USE_NATIVE_TOOLBAR
1722
1723#endif // wxUSE_TOOLBAR
1724