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