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