]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/toolbar.cpp
Update Readme.txt
[wxWidgets.git] / src / mac / carbon / toolbar.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/toolbar.cpp
3 // Purpose: wxToolBar
4 // Author: Stefan Csomor
5 // Modified by:
6 // Created: 04/01/98
7 // RCS-ID: $Id$
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
11
12 #include "wx/wxprec.h"
13
14 #if wxUSE_TOOLBAR
15
16 #include "wx/toolbar.h"
17
18 #ifndef WX_PRECOMP
19 #include "wx/wx.h"
20 #endif
21
22 #include "wx/mac/uma.h"
23 #include "wx/geometry.h"
24
25
26 #ifdef __WXMAC_OSX__
27 const short kwxMacToolBarToolDefaultWidth = 16;
28 const short kwxMacToolBarToolDefaultHeight = 16;
29 const short kwxMacToolBarTopMargin = 4;
30 const short kwxMacToolBarLeftMargin = 4;
31 const short kwxMacToolBorder = 0;
32 const short kwxMacToolSpacing = 6;
33 #else
34 const short kwxMacToolBarToolDefaultWidth = 24;
35 const short kwxMacToolBarToolDefaultHeight = 22;
36 const short kwxMacToolBarTopMargin = 2;
37 const short kwxMacToolBarLeftMargin = 2;
38 const short kwxMacToolBorder = 4;
39 const short kwxMacToolSpacing = 0;
40 #endif
41
42
43 IMPLEMENT_DYNAMIC_CLASS(wxToolBar, wxControl)
44
45 BEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
46 EVT_PAINT( wxToolBar::OnPaint )
47 END_EVENT_TABLE()
48
49
50 #pragma mark -
51 #pragma mark Tool Implementation
52
53
54 // ----------------------------------------------------------------------------
55 // private classes
56 // ----------------------------------------------------------------------------
57
58 // We have a dual implementation for each tool, ControlRef and HIToolbarItemRef
59
60 class wxToolBarTool : public wxToolBarToolBase
61 {
62 public:
63 wxToolBarTool(
64 wxToolBar *tbar,
65 int id,
66 const wxString& label,
67 const wxBitmap& bmpNormal,
68 const wxBitmap& bmpDisabled,
69 wxItemKind kind,
70 wxObject *clientData,
71 const wxString& shortHelp,
72 const wxString& longHelp );
73
74 wxToolBarTool(wxToolBar *tbar, wxControl *control)
75 : wxToolBarToolBase(tbar, control)
76 {
77 Init();
78 if (control != NULL)
79 SetControlHandle( (ControlRef) control->GetHandle() );
80 }
81
82 virtual ~wxToolBarTool()
83 {
84 ClearControl();
85 }
86
87 WXWidget GetControlHandle()
88 {
89 return (WXWidget) m_controlHandle;
90 }
91
92 void SetControlHandle( ControlRef handle )
93 {
94 m_controlHandle = handle;
95 }
96
97 void SetPosition( const wxPoint& position );
98
99 void ClearControl()
100 {
101 m_control = NULL;
102 if ( m_controlHandle )
103 {
104 if ( !IsControl() )
105 DisposeControl( m_controlHandle );
106 else
107 {
108 // the embedded control is not under the responsibility of the tool
109 }
110 m_controlHandle = NULL ;
111 }
112
113 #if wxMAC_USE_NATIVE_TOOLBAR
114 if ( m_toolbarItemRef )
115 {
116 CFIndex count = CFGetRetainCount( m_toolbarItemRef ) ;
117 wxASSERT_MSG( count == 1 , wxT("Reference Count of native tool was not 1 in wxToolBarTool destructor") );
118 CFRelease( m_toolbarItemRef );
119 m_toolbarItemRef = NULL;
120 }
121 #endif
122 }
123
124 wxSize GetSize() const
125 {
126 wxSize curSize;
127
128 if ( IsControl() )
129 {
130 curSize = GetControl()->GetSize();
131 }
132 else if ( IsButton() )
133 {
134 curSize = GetToolBar()->GetToolSize();
135 }
136 else
137 {
138 // separator size
139 curSize = GetToolBar()->GetToolSize();
140 if ( GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL )
141 curSize.y /= 4;
142 else
143 curSize.x /= 4;
144 }
145
146 return curSize;
147 }
148
149 wxPoint GetPosition() const
150 {
151 return wxPoint( m_x, m_y );
152 }
153
154 bool DoEnable( bool enable );
155
156 void UpdateToggleImage( bool toggle );
157
158 #if wxMAC_USE_NATIVE_TOOLBAR
159 void SetToolbarItemRef( HIToolbarItemRef ref )
160 {
161 if ( m_controlHandle )
162 HideControl( m_controlHandle );
163 if ( m_toolbarItemRef )
164 CFRelease( m_toolbarItemRef );
165
166 m_toolbarItemRef = ref;
167 if ( m_toolbarItemRef )
168 {
169 HIToolbarItemSetHelpText(
170 m_toolbarItemRef,
171 wxMacCFStringHolder( GetShortHelp(), GetToolBar()->GetFont().GetEncoding() ),
172 wxMacCFStringHolder( GetLongHelp(), GetToolBar()->GetFont().GetEncoding() ) );
173 }
174 }
175
176 HIToolbarItemRef GetToolbarItemRef() const
177 {
178 return m_toolbarItemRef;
179 }
180
181 void SetIndex( CFIndex idx )
182 {
183 m_index = idx;
184 }
185
186 CFIndex GetIndex() const
187 {
188 return m_index;
189 }
190 #endif
191
192 private:
193 void Init()
194 {
195 m_controlHandle = NULL;
196
197 #if wxMAC_USE_NATIVE_TOOLBAR
198 m_toolbarItemRef = NULL;
199 m_index = -1;
200 #endif
201 }
202
203 ControlRef m_controlHandle;
204 wxCoord m_x;
205 wxCoord m_y;
206
207 #if wxMAC_USE_NATIVE_TOOLBAR
208 HIToolbarItemRef m_toolbarItemRef;
209 // position in its toolbar, -1 means not inserted
210 CFIndex m_index;
211 #endif
212 };
213
214 static const EventTypeSpec eventList[] =
215 {
216 { kEventClassControl, kEventControlHit },
217 #ifdef __WXMAC_OSX__
218 { kEventClassControl, kEventControlHitTest },
219 #endif
220 };
221
222 static pascal OSStatus wxMacToolBarToolControlEventHandler( EventHandlerCallRef handler, EventRef event, void *data )
223 {
224 OSStatus result = eventNotHandledErr;
225 ControlRef controlRef;
226 wxMacCarbonEvent cEvent( event );
227
228 cEvent.GetParameter( kEventParamDirectObject, &controlRef );
229
230 switch ( GetEventKind( event ) )
231 {
232 case kEventControlHit:
233 {
234 wxToolBarTool *tbartool = (wxToolBarTool*)data;
235 wxToolBar *tbar = tbartool != NULL ? (wxToolBar*) (tbartool->GetToolBar()) : NULL;
236 if ((tbartool != NULL) && tbartool->CanBeToggled())
237 {
238 bool shouldToggle;
239
240 #ifdef __WXMAC_OSX__
241 shouldToggle = !tbartool->IsToggled();
242 #else
243 shouldToggle = (GetControl32BitValue( (ControlRef)(tbartool->GetControlHandle()) ) != 0);
244 #endif
245
246 tbar->ToggleTool( tbartool->GetId(), shouldToggle );
247 }
248
249 if (tbartool != NULL)
250 tbar->OnLeftClick( tbartool->GetId(), tbartool->IsToggled() );
251 result = noErr;
252 }
253 break;
254
255 #ifdef __WXMAC_OSX__
256 case kEventControlHitTest:
257 {
258 HIPoint pt = cEvent.GetParameter<HIPoint>(kEventParamMouseLocation);
259 HIRect rect;
260 HIViewGetBounds( controlRef, &rect );
261
262 ControlPartCode pc = kControlNoPart;
263 if ( CGRectContainsPoint( rect, pt ) )
264 pc = kControlIconPart;
265 cEvent.SetParameter( kEventParamControlPart, typeControlPartCode, pc );
266 result = noErr;
267 }
268 break;
269 #endif
270
271 default:
272 break;
273 }
274
275 return result;
276 }
277
278 static pascal OSStatus wxMacToolBarToolEventHandler( EventHandlerCallRef handler, EventRef event, void *data )
279 {
280 OSStatus result = eventNotHandledErr;
281
282 switch ( GetEventClass( event ) )
283 {
284 case kEventClassControl:
285 result = wxMacToolBarToolControlEventHandler( handler, event, data );
286 break;
287
288 default:
289 break;
290 }
291
292 return result;
293 }
294
295 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacToolBarToolEventHandler )
296
297 #if wxMAC_USE_NATIVE_TOOLBAR
298
299 static const EventTypeSpec toolBarEventList[] =
300 {
301 { kEventClassToolbarItem, kEventToolbarItemPerformAction },
302 };
303
304 static pascal OSStatus wxMacToolBarCommandEventHandler( EventHandlerCallRef handler, EventRef event, void *data )
305 {
306 OSStatus result = eventNotHandledErr;
307
308 switch ( GetEventKind( event ) )
309 {
310 case kEventToolbarItemPerformAction:
311 {
312 wxToolBarTool* tbartool = (wxToolBarTool*) data;
313 if ( tbartool != NULL )
314 {
315 wxToolBar *tbar = (wxToolBar*)(tbartool->GetToolBar());
316 int toolID = tbartool->GetId();
317
318 if ( tbartool->CanBeToggled() )
319 {
320 if ( tbar != NULL )
321 tbar->ToggleTool(toolID, !tbartool->IsToggled() );
322 }
323
324 if ( tbar != NULL )
325 tbar->OnLeftClick( toolID, tbartool->IsToggled() );
326 result = noErr;
327 }
328 }
329 break;
330
331 default:
332 break;
333 }
334
335 return result;
336 }
337
338 static pascal OSStatus wxMacToolBarEventHandler( EventHandlerCallRef handler, EventRef event, void *data )
339 {
340 OSStatus result = eventNotHandledErr;
341
342 switch ( GetEventClass( event ) )
343 {
344 case kEventClassToolbarItem:
345 result = wxMacToolBarCommandEventHandler( handler, event, data );
346 break;
347
348 default:
349 break;
350 }
351
352 return result;
353 }
354
355 DEFINE_ONE_SHOT_HANDLER_GETTER( wxMacToolBarEventHandler )
356
357 #endif
358
359 bool wxToolBarTool::DoEnable( bool enable )
360 {
361 if ( IsControl() )
362 {
363 GetControl()->Enable( enable );
364 }
365 else if ( IsButton() )
366 {
367 #if wxMAC_USE_NATIVE_TOOLBAR
368 if ( m_toolbarItemRef != NULL )
369 HIToolbarItemSetEnabled( m_toolbarItemRef, enable );
370 #endif
371
372 if ( m_controlHandle != NULL )
373 {
374 #if TARGET_API_MAC_OSX
375 if ( enable )
376 EnableControl( m_controlHandle );
377 else
378 DisableControl( m_controlHandle );
379 #else
380 if ( enable )
381 ActivateControl( m_controlHandle );
382 else
383 DeactivateControl( m_controlHandle );
384 #endif
385 }
386 }
387
388 return true;
389 }
390
391 void wxToolBarTool::SetPosition( const wxPoint& position )
392 {
393 m_x = position.x;
394 m_y = position.y;
395
396 int mac_x = position.x;
397 int mac_y = position.y;
398
399 if ( IsButton() )
400 {
401 Rect contrlRect;
402 GetControlBounds( m_controlHandle, &contrlRect );
403 int former_mac_x = contrlRect.left;
404 int former_mac_y = contrlRect.top;
405 GetToolBar()->GetToolSize();
406
407 if ( mac_x != former_mac_x || mac_y != former_mac_y )
408 {
409 UMAMoveControl( m_controlHandle, mac_x, mac_y );
410 }
411 }
412 else if ( IsControl() )
413 {
414 // embedded native controls are moved by the OS
415 #if wxMAC_USE_NATIVE_TOOLBAR
416 if ( ((wxToolBar*)GetToolBar())->MacWantsNativeToolbar() == false )
417 #endif
418 {
419 GetControl()->Move( position );
420 }
421 }
422 else
423 {
424 // separator
425 #ifdef __WXMAC_OSX__
426 Rect contrlRect;
427 GetControlBounds( m_controlHandle, &contrlRect );
428 int former_mac_x = contrlRect.left;
429 int former_mac_y = contrlRect.top;
430
431 if ( mac_x != former_mac_x || mac_y != former_mac_y )
432 UMAMoveControl( m_controlHandle, mac_x, mac_y );
433 #endif
434 }
435 }
436
437 void wxToolBarTool::UpdateToggleImage( bool toggle )
438 {
439 #ifdef __WXMAC_OSX__
440 if ( toggle )
441 {
442 int w = m_bmpNormal.GetWidth();
443 int h = m_bmpNormal.GetHeight();
444 wxBitmap bmp( w, h );
445 wxMemoryDC dc;
446
447 dc.SelectObject( bmp );
448 dc.SetPen( wxPen(*wxBLACK) );
449 dc.SetBrush( wxBrush( *wxLIGHT_GREY ));
450 dc.DrawRectangle( 0, 0, w, h );
451 dc.DrawBitmap( m_bmpNormal, 0, 0, true );
452 dc.SelectObject( wxNullBitmap );
453 ControlButtonContentInfo info;
454 wxMacCreateBitmapButton( &info, bmp );
455 SetControlData( m_controlHandle, 0, kControlIconContentTag, sizeof(info), (Ptr)&info );
456 #if wxMAC_USE_NATIVE_TOOLBAR
457 if (m_toolbarItemRef != NULL)
458 {
459 HIToolbarItemSetIconRef( m_toolbarItemRef, info.u.iconRef );
460 }
461 #endif
462 wxMacReleaseBitmapButton( &info );
463 }
464 else
465 {
466 ControlButtonContentInfo info;
467 wxMacCreateBitmapButton( &info, m_bmpNormal );
468 SetControlData( m_controlHandle, 0, kControlIconContentTag, sizeof(info), (Ptr)&info );
469 #if wxMAC_USE_NATIVE_TOOLBAR
470 if (m_toolbarItemRef != NULL)
471 {
472 HIToolbarItemSetIconRef( m_toolbarItemRef, info.u.iconRef );
473 }
474 #endif
475 wxMacReleaseBitmapButton( &info );
476 }
477
478 IconTransformType transform = toggle ? kTransformSelected : kTransformNone;
479 SetControlData(
480 m_controlHandle, 0, kControlIconTransformTag,
481 sizeof(transform), (Ptr)&transform );
482 HIViewSetNeedsDisplay( m_controlHandle, true );
483
484 #else
485 ::SetControl32BitValue( m_controlHandle, toggle );
486 #endif
487 }
488
489 wxToolBarTool::wxToolBarTool(
490 wxToolBar *tbar,
491 int id,
492 const wxString& label,
493 const wxBitmap& bmpNormal,
494 const wxBitmap& bmpDisabled,
495 wxItemKind kind,
496 wxObject *clientData,
497 const wxString& shortHelp,
498 const wxString& longHelp )
499 :
500 wxToolBarToolBase(
501 tbar, id, label, bmpNormal, bmpDisabled, kind,
502 clientData, shortHelp, longHelp )
503 {
504 Init();
505 }
506
507 #pragma mark -
508 #pragma mark Toolbar Implementation
509
510 wxToolBarToolBase *wxToolBar::CreateTool(
511 int id,
512 const wxString& label,
513 const wxBitmap& bmpNormal,
514 const wxBitmap& bmpDisabled,
515 wxItemKind kind,
516 wxObject *clientData,
517 const wxString& shortHelp,
518 const wxString& longHelp )
519 {
520 return new wxToolBarTool(
521 this, id, label, bmpNormal, bmpDisabled, kind,
522 clientData, shortHelp, longHelp );
523 }
524
525 wxToolBarToolBase * wxToolBar::CreateTool( wxControl *control )
526 {
527 return new wxToolBarTool( this, control );
528 }
529
530 void wxToolBar::Init()
531 {
532 m_maxWidth = -1;
533 m_maxHeight = -1;
534 m_defaultWidth = kwxMacToolBarToolDefaultWidth;
535 m_defaultHeight = kwxMacToolBarToolDefaultHeight;
536
537 #if wxMAC_USE_NATIVE_TOOLBAR
538 m_macHIToolbarRef = NULL;
539 m_macUsesNativeToolbar = false;
540 #endif
541 }
542
543 #define kControlToolbarItemClassID CFSTR( "org.wxwidgets.controltoolbaritem" )
544
545 const EventTypeSpec kEvents[] =
546 {
547 { kEventClassHIObject, kEventHIObjectConstruct },
548 { kEventClassHIObject, kEventHIObjectInitialize },
549 { kEventClassHIObject, kEventHIObjectDestruct },
550
551 { kEventClassToolbarItem, kEventToolbarItemCreateCustomView }
552 };
553
554 const EventTypeSpec kViewEvents[] =
555 {
556 { kEventClassControl, kEventControlGetSizeConstraints }
557 };
558
559 struct ControlToolbarItem
560 {
561 HIToolbarItemRef toolbarItem;
562 HIViewRef viewRef;
563 wxSize lastValidSize ;
564 };
565
566 static pascal OSStatus ControlToolbarItemHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
567 {
568 OSStatus result = eventNotHandledErr;
569 ControlToolbarItem* object = (ControlToolbarItem*)inUserData;
570
571 switch ( GetEventClass( inEvent ) )
572 {
573 case kEventClassHIObject:
574 switch ( GetEventKind( inEvent ) )
575 {
576 case kEventHIObjectConstruct:
577 {
578 HIObjectRef toolbarItem;
579 ControlToolbarItem* item;
580
581 GetEventParameter( inEvent, kEventParamHIObjectInstance, typeHIObjectRef, NULL,
582 sizeof( HIObjectRef ), NULL, &toolbarItem );
583
584 item = (ControlToolbarItem*) malloc(sizeof(ControlToolbarItem)) ;
585 item->toolbarItem = toolbarItem ;
586 item->viewRef = NULL ;
587
588 SetEventParameter( inEvent, kEventParamHIObjectInstance, typeVoidPtr, sizeof( void * ), &item );
589
590 result = noErr ;
591 }
592 break;
593
594 case kEventHIObjectInitialize:
595 result = CallNextEventHandler( inCallRef, inEvent );
596 if ( result == noErr )
597 {
598 CFDataRef data;
599 GetEventParameter( inEvent, kEventParamToolbarItemConfigData, typeCFTypeRef, NULL,
600 sizeof( CFTypeRef ), NULL, &data );
601
602 HIViewRef viewRef ;
603
604 wxASSERT_MSG( CFDataGetLength( data ) == sizeof( viewRef ) , wxT("Illegal Data passed") ) ;
605 memcpy( &viewRef , CFDataGetBytePtr( data ) , sizeof( viewRef ) ) ;
606
607 object->viewRef = (HIViewRef) viewRef ;
608
609 result = noErr ;
610 }
611 break;
612
613 case kEventHIObjectDestruct:
614 {
615 // we've increased the ref count when creating this, so we decrease manually again in case
616 // it was never really installed and deinstalled
617 HIViewRef viewRef = object->viewRef ;
618 if( viewRef && CFGetRetainCount( viewRef ) > 1 )
619 {
620 CFRelease( viewRef ) ;
621 }
622 free( object ) ;
623 result = noErr;
624 }
625 break;
626 }
627 break;
628
629 case kEventClassToolbarItem:
630 switch ( GetEventKind( inEvent ) )
631 {
632 case kEventToolbarItemCreateCustomView:
633 {
634 HIViewRef viewRef = object->viewRef ;
635
636 HIViewRemoveFromSuperview( viewRef ) ;
637 HIViewSetVisible(viewRef, true) ;
638 InstallEventHandler( GetControlEventTarget( viewRef ), ControlToolbarItemHandler,
639 GetEventTypeCount( kViewEvents ), kViewEvents, object, NULL );
640
641 result = SetEventParameter( inEvent, kEventParamControlRef, typeControlRef, sizeof( HIViewRef ), &viewRef );
642 }
643 break;
644 }
645 break;
646
647 case kEventClassControl:
648 switch ( GetEventKind( inEvent ) )
649 {
650 case kEventControlGetSizeConstraints:
651 {
652 wxWindow* wxwindow = wxFindControlFromMacControl(object->viewRef ) ;
653 if ( wxwindow )
654 {
655 wxSize sz = wxwindow->GetSize() ;
656 sz.x -= wxwindow->MacGetLeftBorderSize() + wxwindow->MacGetRightBorderSize();
657 sz.y -= wxwindow->MacGetTopBorderSize() + wxwindow->MacGetBottomBorderSize();
658 // during toolbar layout the native window sometimes gets negative sizes
659 // so we always keep the last valid size here, to make sure we survive the
660 // shuffle ...
661 if ( sz.x > 0 && sz.y > 0 )
662 object->lastValidSize = sz ;
663 else
664 sz = object->lastValidSize ;
665
666 HISize min, max;
667 min.width = max.width = sz.x ;
668 min.height = max.height = sz.y ;
669
670 result = SetEventParameter( inEvent, kEventParamMinimumSize, typeHISize,
671 sizeof( HISize ), &min );
672
673 result = SetEventParameter( inEvent, kEventParamMaximumSize, typeHISize,
674 sizeof( HISize ), &max );
675 result = noErr ;
676 }
677 }
678 break;
679 }
680 break;
681 }
682
683 return result;
684 }
685
686 void RegisterControlToolbarItemClass()
687 {
688 static bool sRegistered;
689
690 if ( !sRegistered )
691 {
692 HIObjectRegisterSubclass( kControlToolbarItemClassID, kHIToolbarItemClassID, 0,
693 ControlToolbarItemHandler, GetEventTypeCount( kEvents ), kEvents, 0, NULL );
694
695 sRegistered = true;
696 }
697 }
698
699 HIToolbarItemRef CreateControlToolbarItem(CFStringRef inIdentifier, CFTypeRef inConfigData)
700 {
701 RegisterControlToolbarItemClass();
702
703 OSStatus err;
704 EventRef event;
705 UInt32 options = kHIToolbarItemAllowDuplicates;
706 HIToolbarItemRef result = NULL;
707
708 err = CreateEvent( NULL, kEventClassHIObject, kEventHIObjectInitialize, GetCurrentEventTime(), 0, &event );
709 require_noerr( err, CantCreateEvent );
710
711 SetEventParameter( event, kEventParamAttributes, typeUInt32, sizeof( UInt32 ), &options );
712 SetEventParameter( event, kEventParamToolbarItemIdentifier, typeCFStringRef, sizeof( CFStringRef ), &inIdentifier );
713
714 if ( inConfigData )
715 SetEventParameter( event, kEventParamToolbarItemConfigData, typeCFTypeRef, sizeof( CFTypeRef ), &inConfigData );
716
717 err = HIObjectCreate( kControlToolbarItemClassID, event, (HIObjectRef*)&result );
718 check_noerr( err );
719
720 ReleaseEvent( event );
721 CantCreateEvent :
722 return result ;
723 }
724
725 #if wxMAC_USE_NATIVE_TOOLBAR
726 static const EventTypeSpec kToolbarEvents[] =
727 {
728 { kEventClassToolbar, kEventToolbarGetDefaultIdentifiers },
729 { kEventClassToolbar, kEventToolbarGetAllowedIdentifiers },
730 { kEventClassToolbar, kEventToolbarCreateItemWithIdentifier },
731 };
732
733 static OSStatus ToolbarDelegateHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
734 {
735 OSStatus result = eventNotHandledErr;
736 // Not yet needed
737 // wxToolBar* toolbar = (wxToolBar*) inUserData ;
738 CFMutableArrayRef array;
739
740 switch ( GetEventKind( inEvent ) )
741 {
742 case kEventToolbarGetDefaultIdentifiers:
743 {
744 GetEventParameter( inEvent, kEventParamMutableArray, typeCFMutableArrayRef, NULL,
745 sizeof( CFMutableArrayRef ), NULL, &array );
746 // not implemented yet
747 // GetToolbarDefaultItems( array );
748 result = noErr;
749 }
750 break;
751
752 case kEventToolbarGetAllowedIdentifiers:
753 {
754 GetEventParameter( inEvent, kEventParamMutableArray, typeCFMutableArrayRef, NULL,
755 sizeof( CFMutableArrayRef ), NULL, &array );
756 // not implemented yet
757 // GetToolbarAllowedItems( array );
758 result = noErr;
759 }
760 break;
761 case kEventToolbarCreateItemWithIdentifier:
762 {
763 HIToolbarItemRef item = NULL;
764 CFTypeRef data = NULL;
765 CFStringRef identifier = NULL ;
766
767 GetEventParameter( inEvent, kEventParamToolbarItemIdentifier, typeCFStringRef, NULL,
768 sizeof( CFStringRef ), NULL, &identifier );
769
770 GetEventParameter( inEvent, kEventParamToolbarItemConfigData, typeCFTypeRef, NULL,
771 sizeof( CFTypeRef ), NULL, &data );
772
773 if ( CFStringCompare( kControlToolbarItemClassID, identifier, kCFCompareBackwards ) == kCFCompareEqualTo )
774 {
775 item = CreateControlToolbarItem( kControlToolbarItemClassID, data );
776 if ( item )
777 {
778 SetEventParameter( inEvent, kEventParamToolbarItem, typeHIToolbarItemRef,
779 sizeof( HIToolbarItemRef ), &item );
780 result = noErr;
781 }
782 }
783
784 }
785 break;
786 }
787 return result ;
788 }
789 #endif // wxMAC_USE_NATIVE_TOOLBAR
790
791 // also for the toolbar we have the dual implementation:
792 // only when MacInstallNativeToolbar is called is the native toolbar set as the window toolbar
793
794 bool wxToolBar::Create(
795 wxWindow *parent,
796 wxWindowID id,
797 const wxPoint& pos,
798 const wxSize& size,
799 long style,
800 const wxString& name )
801 {
802 if ( !wxToolBarBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ) )
803 return false;
804
805 FixupStyle();
806
807 OSStatus err = noErr;
808
809 #if wxMAC_USE_NATIVE_TOOLBAR
810 wxString labelStr = wxString::Format( wxT("%xd"), (int)this );
811 err = HIToolbarCreate(
812 wxMacCFStringHolder( labelStr, wxFont::GetDefaultEncoding() ), 0,
813 (HIToolbarRef*) &m_macHIToolbarRef );
814
815 if (m_macHIToolbarRef != NULL)
816 {
817 InstallEventHandler( HIObjectGetEventTarget((HIToolbarRef)m_macHIToolbarRef ), ToolbarDelegateHandler,
818 GetEventTypeCount( kToolbarEvents ), kToolbarEvents, this, NULL );
819
820 HIToolbarDisplayMode mode = kHIToolbarDisplayModeDefault;
821 HIToolbarDisplaySize displaySize = kHIToolbarDisplaySizeSmall;
822
823 if ( style & wxTB_NOICONS )
824 mode = kHIToolbarDisplayModeLabelOnly;
825 else if ( style & wxTB_TEXT )
826 mode = kHIToolbarDisplayModeIconAndLabel;
827 else
828 mode = kHIToolbarDisplayModeIconOnly;
829
830 HIToolbarSetDisplayMode( (HIToolbarRef) m_macHIToolbarRef, mode );
831 HIToolbarSetDisplaySize( (HIToolbarRef) m_macHIToolbarRef, displaySize );
832 }
833 #endif
834
835 return (err == noErr);
836 }
837
838 wxToolBar::~wxToolBar()
839 {
840 #if wxMAC_USE_NATIVE_TOOLBAR
841 if (m_macHIToolbarRef != NULL)
842 {
843 // if this is the installed toolbar, then deinstall it
844 if (m_macUsesNativeToolbar)
845 MacInstallNativeToolbar( false );
846
847 CFIndex count = CFGetRetainCount( m_macHIToolbarRef ) ;
848 wxASSERT_MSG( count == 1 , wxT("Reference Count of native control was not 1 in wxToolBar destructor") );
849
850 CFRelease( (HIToolbarRef)m_macHIToolbarRef );
851 m_macHIToolbarRef = NULL;
852 }
853 #endif
854 }
855
856 bool wxToolBar::Show( bool show )
857 {
858 WindowRef tlw = MAC_WXHWND(MacGetTopLevelWindowRef());
859 bool bResult = (tlw != NULL);
860
861 if (bResult)
862 {
863 #if wxMAC_USE_NATIVE_TOOLBAR
864 bool ownToolbarInstalled = false;
865 MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
866 if (ownToolbarInstalled)
867 {
868 bResult = (IsWindowToolbarVisible( tlw ) != show);
869 if ( bResult )
870 ShowHideWindowToolbar( tlw, show, false );
871 }
872 else
873 bResult = wxToolBarBase::Show( show );
874 #else
875
876 bResult = wxToolBarBase::Show( show );
877 #endif
878 }
879
880 return bResult;
881 }
882
883 bool wxToolBar::IsShown() const
884 {
885 bool bResult;
886
887 #if wxMAC_USE_NATIVE_TOOLBAR
888 bool ownToolbarInstalled;
889
890 MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
891 if (ownToolbarInstalled)
892 {
893 WindowRef tlw = MAC_WXHWND(MacGetTopLevelWindowRef());
894 bResult = IsWindowToolbarVisible( tlw );
895 }
896 else
897 bResult = wxToolBarBase::IsShown();
898 #else
899
900 bResult = wxToolBarBase::IsShown();
901 #endif
902
903 return bResult;
904 }
905
906 void wxToolBar::DoGetSize( int *width, int *height ) const
907 {
908 #if wxMAC_USE_NATIVE_TOOLBAR
909 Rect boundsR;
910 bool ownToolbarInstalled;
911
912 MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
913 if ( ownToolbarInstalled )
914 {
915 // TODO: is this really a control ?
916 GetControlBounds( (ControlRef) m_macHIToolbarRef, &boundsR );
917 if ( width != NULL )
918 *width = boundsR.right - boundsR.left;
919 if ( height != NULL )
920 *height = boundsR.bottom - boundsR.top;
921 }
922 else
923 wxToolBarBase::DoGetSize( width, height );
924
925 #else
926 wxToolBarBase::DoGetSize( width, height );
927 #endif
928 }
929
930 wxSize wxToolBar::DoGetBestSize() const
931 {
932 int width, height;
933
934 DoGetSize( &width, &height );
935
936 return wxSize( width, height );
937 }
938
939 void wxToolBar::SetWindowStyleFlag( long style )
940 {
941 wxToolBarBase::SetWindowStyleFlag( style );
942
943 #if wxMAC_USE_NATIVE_TOOLBAR
944 if (m_macHIToolbarRef != NULL)
945 {
946 HIToolbarDisplayMode mode = kHIToolbarDisplayModeDefault;
947
948 if ( style & wxTB_NOICONS )
949 mode = kHIToolbarDisplayModeLabelOnly;
950 else if ( style & wxTB_TEXT )
951 mode = kHIToolbarDisplayModeIconAndLabel;
952 else
953 mode = kHIToolbarDisplayModeIconOnly;
954
955 HIToolbarSetDisplayMode( (HIToolbarRef) m_macHIToolbarRef, mode );
956 }
957 #endif
958 }
959
960 #if wxMAC_USE_NATIVE_TOOLBAR
961 bool wxToolBar::MacWantsNativeToolbar()
962 {
963 return m_macUsesNativeToolbar;
964 }
965
966 bool wxToolBar::MacTopLevelHasNativeToolbar(bool *ownToolbarInstalled) const
967 {
968 bool bResultV = false;
969
970 if (ownToolbarInstalled != NULL)
971 *ownToolbarInstalled = false;
972
973 WindowRef tlw = MAC_WXHWND(MacGetTopLevelWindowRef());
974 if (tlw != NULL)
975 {
976 HIToolbarRef curToolbarRef = NULL;
977 OSStatus err = GetWindowToolbar( tlw, &curToolbarRef );
978 bResultV = ((err == noErr) && (curToolbarRef != NULL));
979 if (bResultV && (ownToolbarInstalled != NULL))
980 *ownToolbarInstalled = (curToolbarRef == m_macHIToolbarRef);
981 }
982
983 return bResultV;
984 }
985
986 bool wxToolBar::MacInstallNativeToolbar(bool usesNative)
987 {
988 bool bResult = false;
989
990 if (usesNative && (m_macHIToolbarRef == NULL))
991 return bResult;
992
993 if (usesNative && ((GetWindowStyleFlag() & wxTB_VERTICAL) != 0))
994 return bResult;
995
996 WindowRef tlw = MAC_WXHWND(MacGetTopLevelWindowRef());
997 if (tlw == NULL)
998 return bResult;
999
1000 // check the existing toolbar
1001 HIToolbarRef curToolbarRef = NULL;
1002 OSStatus err = GetWindowToolbar( tlw, &curToolbarRef );
1003 if (err != noErr)
1004 curToolbarRef = NULL;
1005
1006 m_macUsesNativeToolbar = usesNative;
1007
1008 if (m_macUsesNativeToolbar)
1009 {
1010 // only install toolbar if there isn't one installed already
1011 if (curToolbarRef == NULL)
1012 {
1013 bResult = true;
1014
1015 SetWindowToolbar( tlw, (HIToolbarRef) m_macHIToolbarRef );
1016 ShowHideWindowToolbar( tlw, true, false );
1017 ChangeWindowAttributes( tlw, kWindowToolbarButtonAttribute, 0 );
1018 SetAutomaticControlDragTrackingEnabledForWindow( tlw, true );
1019
1020 Rect r = { 0, 0, 0, 0 };
1021 m_peer->SetRect( &r );
1022 SetSize( wxSIZE_AUTO_WIDTH, 0 );
1023 m_peer->SetVisibility( false, true );
1024 wxToolBarBase::Show( false );
1025 }
1026 }
1027 else
1028 {
1029 // only deinstall toolbar if this is the installed one
1030 if (m_macHIToolbarRef == curToolbarRef)
1031 {
1032 bResult = true;
1033
1034 ShowHideWindowToolbar( tlw, false, false );
1035 ChangeWindowAttributes( tlw, 0, kWindowToolbarButtonAttribute );
1036 SetWindowToolbar( tlw, NULL );
1037
1038 m_peer->SetVisibility( true, true );
1039 }
1040 }
1041
1042 if (bResult)
1043 InvalidateBestSize();
1044
1045 // wxLogDebug( wxT(" --> [%lx] - result [%s]"), (long)this, bResult ? wxT("T") : wxT("F") );
1046 return bResult;
1047 }
1048 #endif
1049
1050 bool wxToolBar::Realize()
1051 {
1052 if (m_tools.GetCount() == 0)
1053 return false;
1054
1055 int maxWidth = 0;
1056 int maxHeight = 0;
1057
1058 int maxToolWidth = 0;
1059 int maxToolHeight = 0;
1060
1061 int x = m_xMargin + kwxMacToolBarLeftMargin;
1062 int y = m_yMargin + kwxMacToolBarTopMargin;
1063
1064 int tw, th;
1065 GetSize( &tw, &th );
1066
1067 // find the maximum tool width and height
1068 wxToolBarTool *tool;
1069 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1070 while ( node != NULL )
1071 {
1072 tool = (wxToolBarTool *) node->GetData();
1073 if ( tool != NULL )
1074 {
1075 wxSize sz = tool->GetSize();
1076
1077 if ( sz.x > maxToolWidth )
1078 maxToolWidth = sz.x;
1079 if ( sz.y > maxToolHeight )
1080 maxToolHeight = sz.y;
1081 }
1082
1083 node = node->GetNext();
1084 }
1085
1086 bool lastIsRadio = false;
1087 bool curIsRadio = false;
1088
1089 #if wxMAC_USE_NATIVE_TOOLBAR
1090 CFIndex currentPosition = 0;
1091 bool insertAll = false;
1092 #endif
1093
1094 node = m_tools.GetFirst();
1095 while ( node != NULL )
1096 {
1097 tool = (wxToolBarTool*) node->GetData();
1098 if ( tool == NULL )
1099 {
1100 node = node->GetNext();
1101 continue;
1102 }
1103
1104 // set tool position:
1105 // for the moment just perform a single row/column alignment
1106 wxSize cursize = tool->GetSize();
1107 if ( x + cursize.x > maxWidth )
1108 maxWidth = x + cursize.x;
1109 if ( y + cursize.y > maxHeight )
1110 maxHeight = y + cursize.y;
1111
1112 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
1113 {
1114 int x1 = x + ( maxToolWidth - cursize.x ) / 2;
1115 tool->SetPosition( wxPoint(x1, y) );
1116 }
1117 else
1118 {
1119 int y1 = y + ( maxToolHeight - cursize.y ) / 2;
1120 tool->SetPosition( wxPoint(x, y1) );
1121 }
1122
1123 // update the item positioning state
1124 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
1125 y += cursize.y + kwxMacToolSpacing;
1126 else
1127 x += cursize.x + kwxMacToolSpacing;
1128
1129 #if wxMAC_USE_NATIVE_TOOLBAR
1130 // install in native HIToolbar
1131 if ( m_macHIToolbarRef != NULL )
1132 {
1133 HIToolbarItemRef hiItemRef = tool->GetToolbarItemRef();
1134 if ( hiItemRef != NULL )
1135 {
1136 if ( insertAll || (tool->GetIndex() != currentPosition) )
1137 {
1138 OSStatus err = noErr;
1139 if ( !insertAll )
1140 {
1141 insertAll = true;
1142
1143 // if this is the first tool that gets newly inserted or repositioned
1144 // first remove all 'old' tools from here to the right, because of this
1145 // all following tools will have to be reinserted (insertAll). i = 100 because there's
1146 // no way to determine how many there are in a toolbar, so just a high number :-(
1147 for ( CFIndex i = 100; i >= currentPosition; --i )
1148 {
1149 err = HIToolbarRemoveItemAtIndex( (HIToolbarRef) m_macHIToolbarRef, i );
1150 }
1151
1152 if (err != noErr)
1153 {
1154 wxString errMsg = wxString::Format( wxT("HIToolbarRemoveItemAtIndex failed [%ld]"), (long)err );
1155 wxFAIL_MSG( errMsg.c_str() );
1156 }
1157 }
1158
1159 err = HIToolbarInsertItemAtIndex( (HIToolbarRef) m_macHIToolbarRef, hiItemRef, currentPosition );
1160 if (err != noErr)
1161 {
1162 wxString errMsg = wxString::Format( wxT("HIToolbarInsertItemAtIndex failed [%ld]"), (long)err );
1163 wxFAIL_MSG( errMsg.c_str() );
1164 }
1165
1166 tool->SetIndex( currentPosition );
1167 }
1168
1169 currentPosition++;
1170 }
1171 }
1172 #endif
1173
1174 // update radio button (and group) state
1175 lastIsRadio = curIsRadio;
1176 curIsRadio = ( tool->IsButton() && (tool->GetKind() == wxITEM_RADIO) );
1177
1178 if ( !curIsRadio )
1179 {
1180 if ( tool->IsToggled() )
1181 DoToggleTool( tool, true );
1182 }
1183 else
1184 {
1185 if ( !lastIsRadio )
1186 {
1187 if ( tool->Toggle( true ) )
1188 {
1189 DoToggleTool( tool, true );
1190 }
1191 }
1192 else if ( tool->IsToggled() )
1193 {
1194 if ( tool->IsToggled() )
1195 DoToggleTool( tool, true );
1196
1197 wxToolBarToolsList::compatibility_iterator nodePrev = node->GetPrevious();
1198 while ( nodePrev != NULL )
1199 {
1200 wxToolBarToolBase *toggleTool = nodePrev->GetData();
1201 if ( (toggleTool == NULL) || !toggleTool->IsButton() || (toggleTool->GetKind() != wxITEM_RADIO) )
1202 break;
1203
1204 if ( toggleTool->Toggle( false ) )
1205 DoToggleTool( toggleTool, false );
1206
1207 nodePrev = nodePrev->GetPrevious();
1208 }
1209 }
1210 }
1211
1212 node = node->GetNext();
1213 }
1214
1215 if ( GetWindowStyleFlag() & wxTB_HORIZONTAL )
1216 {
1217 // if not set yet, only one row
1218 if ( m_maxRows <= 0 )
1219 SetRows( 1 );
1220
1221 m_minWidth = maxWidth;
1222 maxWidth = tw;
1223 maxHeight += m_yMargin + kwxMacToolBarTopMargin;
1224 m_minHeight = m_maxHeight = maxHeight;
1225 }
1226 else
1227 {
1228 // if not set yet, have one column
1229 if ( (GetToolsCount() > 0) && (m_maxRows <= 0) )
1230 SetRows( GetToolsCount() );
1231
1232 m_minHeight = maxHeight;
1233 maxHeight = th;
1234 maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
1235 m_minWidth = m_maxWidth = maxWidth;
1236 }
1237
1238 #if 0
1239 // FIXME: should this be OSX-only?
1240 {
1241 bool wantNativeToolbar, ownToolbarInstalled;
1242
1243 // attempt to install the native toolbar
1244 wantNativeToolbar = ((GetWindowStyleFlag() & wxTB_VERTICAL) == 0);
1245 MacInstallNativeToolbar( wantNativeToolbar );
1246 (void)MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
1247 if (!ownToolbarInstalled)
1248 {
1249 SetSize( maxWidth, maxHeight );
1250 InvalidateBestSize();
1251 }
1252 }
1253 #else
1254 SetSize( maxWidth, maxHeight );
1255 InvalidateBestSize();
1256 #endif
1257
1258 SetInitialSize();
1259
1260 return true;
1261 }
1262
1263 void wxToolBar::SetToolBitmapSize(const wxSize& size)
1264 {
1265 m_defaultWidth = size.x + kwxMacToolBorder;
1266 m_defaultHeight = size.y + kwxMacToolBorder;
1267
1268 #if wxMAC_USE_NATIVE_TOOLBAR
1269 if (m_macHIToolbarRef != NULL)
1270 {
1271 int maxs = wxMax( size.x, size.y );
1272 HIToolbarDisplaySize sizeSpec;
1273 if ( maxs > 32 )
1274 sizeSpec = kHIToolbarDisplaySizeNormal;
1275 else if ( maxs > 24 )
1276 sizeSpec = kHIToolbarDisplaySizeDefault;
1277 else
1278 sizeSpec = kHIToolbarDisplaySizeSmall;
1279
1280 HIToolbarSetDisplaySize( (HIToolbarRef) m_macHIToolbarRef, sizeSpec );
1281 }
1282 #endif
1283 }
1284
1285 // The button size is bigger than the bitmap size
1286 wxSize wxToolBar::GetToolSize() const
1287 {
1288 return wxSize(m_defaultWidth + kwxMacToolBorder, m_defaultHeight + kwxMacToolBorder);
1289 }
1290
1291 void wxToolBar::SetRows(int nRows)
1292 {
1293 // avoid resizing the frame uselessly
1294 if ( nRows != m_maxRows )
1295 m_maxRows = nRows;
1296 }
1297
1298 void wxToolBar::MacSuperChangedPosition()
1299 {
1300 wxWindow::MacSuperChangedPosition();
1301
1302 #if wxMAC_USE_NATIVE_TOOLBAR
1303 if (! m_macUsesNativeToolbar )
1304 Realize();
1305 #else
1306
1307 Realize();
1308 #endif
1309 }
1310
1311 wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
1312 {
1313 wxToolBarTool *tool;
1314 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
1315 while ( node != NULL )
1316 {
1317 tool = (wxToolBarTool *)node->GetData();
1318 if (tool != NULL)
1319 {
1320 wxRect2DInt r( tool->GetPosition(), tool->GetSize() );
1321 if ( r.Contains( wxPoint( x, y ) ) )
1322 return tool;
1323 }
1324
1325 node = node->GetNext();
1326 }
1327
1328 return (wxToolBarToolBase*)NULL;
1329 }
1330
1331 wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
1332 {
1333 wxToolBarToolBase *tool = FindToolForPosition( pt.x, pt.y );
1334 if ( tool != NULL )
1335 return tool->GetShortHelp();
1336
1337 return wxEmptyString;
1338 }
1339
1340 void wxToolBar::DoEnableTool(wxToolBarToolBase *t, bool enable)
1341 {
1342 if ( t != NULL )
1343 ((wxToolBarTool*)t)->DoEnable( enable );
1344 }
1345
1346 void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
1347 {
1348 wxToolBarTool *tool = (wxToolBarTool *)t;
1349 if ( ( tool != NULL ) && tool->IsButton() )
1350 tool->UpdateToggleImage( toggle );
1351 }
1352
1353 bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
1354 {
1355 wxToolBarTool *tool = wx_static_cast( wxToolBarTool*, toolBase );
1356 if (tool == NULL)
1357 return false;
1358
1359 WindowRef window = (WindowRef) MacGetTopLevelWindowRef();
1360 wxSize toolSize = GetToolSize();
1361 Rect toolrect = { 0, 0, toolSize.y, toolSize.x };
1362 ControlRef controlHandle = NULL;
1363 OSStatus err = 0;
1364
1365 switch (tool->GetStyle())
1366 {
1367 case wxTOOL_STYLE_SEPARATOR:
1368 {
1369 wxASSERT( tool->GetControlHandle() == NULL );
1370 toolSize.x /= 4;
1371 toolSize.y /= 4;
1372 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
1373 toolrect.bottom = toolSize.y;
1374 else
1375 toolrect.right = toolSize.x;
1376
1377 #ifdef __WXMAC_OSX__
1378 // in flat style we need a visual separator
1379 #if wxMAC_USE_NATIVE_TOOLBAR
1380 HIToolbarItemRef item;
1381 err = HIToolbarItemCreate(
1382 kHIToolbarSeparatorIdentifier,
1383 kHIToolbarItemCantBeRemoved | kHIToolbarItemIsSeparator | kHIToolbarItemAllowDuplicates,
1384 &item );
1385 if (err == noErr)
1386 tool->SetToolbarItemRef( item );
1387 #endif
1388
1389 CreateSeparatorControl( window, &toolrect, &controlHandle );
1390 tool->SetControlHandle( controlHandle );
1391 #endif
1392 }
1393 break;
1394
1395 case wxTOOL_STYLE_BUTTON:
1396 {
1397 wxASSERT( tool->GetControlHandle() == NULL );
1398 ControlButtonContentInfo info;
1399 wxMacCreateBitmapButton( &info, tool->GetNormalBitmap(), kControlContentIconRef );
1400
1401 if ( UMAGetSystemVersion() >= 0x1000)
1402 {
1403 CreateIconControl( window, &toolrect, &info, false, &controlHandle );
1404 }
1405 else
1406 {
1407 SInt16 behaviour = kControlBehaviorOffsetContents;
1408 if ( tool->CanBeToggled() )
1409 behaviour |= kControlBehaviorToggles;
1410 err = CreateBevelButtonControl( window,
1411 &toolrect, CFSTR(""), kControlBevelButtonNormalBevel,
1412 behaviour, &info, 0, 0, 0, &controlHandle );
1413 }
1414
1415 #if wxMAC_USE_NATIVE_TOOLBAR
1416 HIToolbarItemRef item;
1417 wxString labelStr = wxString::Format(wxT("%xd"), (int)tool);
1418 err = HIToolbarItemCreate(
1419 wxMacCFStringHolder(labelStr, wxFont::GetDefaultEncoding()),
1420 kHIToolbarItemCantBeRemoved | kHIToolbarItemAnchoredLeft | kHIToolbarItemAllowDuplicates, &item );
1421 if (err == noErr)
1422 {
1423 InstallEventHandler(
1424 HIObjectGetEventTarget(item), GetwxMacToolBarEventHandlerUPP(),
1425 GetEventTypeCount(toolBarEventList), toolBarEventList, tool, NULL );
1426 HIToolbarItemSetLabel( item, wxMacCFStringHolder(tool->GetLabel(), m_font.GetEncoding()) );
1427 HIToolbarItemSetIconRef( item, info.u.iconRef );
1428 HIToolbarItemSetCommandID( item, kHIToolbarCommandPressAction );
1429 tool->SetToolbarItemRef( item );
1430 }
1431 #endif
1432
1433 wxMacReleaseBitmapButton( &info );
1434
1435 #if 0
1436 SetBevelButtonTextPlacement( m_controlHandle, kControlBevelButtonPlaceBelowGraphic );
1437 UMASetControlTitle( m_controlHandle, label, wxFont::GetDefaultEncoding() );
1438 #endif
1439
1440 InstallControlEventHandler(
1441 (ControlRef) controlHandle, GetwxMacToolBarToolEventHandlerUPP(),
1442 GetEventTypeCount(eventList), eventList, tool, NULL );
1443
1444 tool->SetControlHandle( controlHandle );
1445 }
1446 break;
1447
1448 case wxTOOL_STYLE_CONTROL:
1449
1450 #if wxMAC_USE_NATIVE_TOOLBAR
1451 {
1452 wxASSERT( tool->GetControl() != NULL );
1453 HIToolbarItemRef item;
1454 HIViewRef viewRef = (HIViewRef) tool->GetControl()->GetHandle() ;
1455 // as this control now is part of both the wxToolBar children and the native toolbar, we have to increase the
1456 // reference count to make sure we are not dealing with zombie controls after the native toolbar has released its views
1457 CFRetain( viewRef ) ;
1458 CFDataRef data = CFDataCreate( kCFAllocatorDefault , (UInt8*) &viewRef , sizeof(viewRef) ) ;
1459 err = HIToolbarCreateItemWithIdentifier((HIToolbarRef) m_macHIToolbarRef,kControlToolbarItemClassID,
1460 data , &item ) ;
1461
1462 if (err == noErr)
1463 {
1464 tool->SetToolbarItemRef( item );
1465 }
1466 CFRelease( data ) ;
1467 }
1468
1469 #else
1470 // right now there's nothing to do here
1471 #endif
1472 break;
1473
1474 default:
1475 break;
1476 }
1477
1478 if ( err == noErr )
1479 {
1480 if ( controlHandle )
1481 {
1482 ControlRef container = (ControlRef) GetHandle();
1483 wxASSERT_MSG( container != NULL, wxT("No valid Mac container control") );
1484
1485 UMAShowControl( controlHandle );
1486 ::EmbedControl( controlHandle, container );
1487 }
1488
1489 if ( tool->CanBeToggled() && tool->IsToggled() )
1490 tool->UpdateToggleImage( true );
1491
1492 // nothing special to do here - we relayout in Realize() later
1493 tool->Attach( this );
1494 InvalidateBestSize();
1495 }
1496 else
1497 {
1498 wxString errMsg = wxString::Format( wxT("wxToolBar::DoInsertTool - failure [%ld]"), (long)err );
1499 wxFAIL_MSG( errMsg.c_str() );
1500 }
1501
1502 return (err == noErr);
1503 }
1504
1505 void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
1506 {
1507 wxFAIL_MSG( wxT("not implemented") );
1508 }
1509
1510 bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolbase)
1511 {
1512 wxToolBarTool* tool = wx_static_cast( wxToolBarTool*, toolbase );
1513 wxToolBarToolsList::compatibility_iterator node;
1514 for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
1515 {
1516 wxToolBarToolBase *tool2 = node->GetData();
1517 if ( tool2 == tool )
1518 {
1519 // let node point to the next node in the list
1520 node = node->GetNext();
1521
1522 break;
1523 }
1524 }
1525
1526 wxSize sz = ((wxToolBarTool*)tool)->GetSize();
1527
1528 tool->Detach();
1529
1530 #if wxMAC_USE_NATIVE_TOOLBAR
1531 CFIndex removeIndex = tool->GetIndex();
1532 #endif
1533
1534 #if wxMAC_USE_NATIVE_TOOLBAR
1535 if ( removeIndex != -1 && m_macHIToolbarRef )
1536 {
1537 HIToolbarRemoveItemAtIndex( (HIToolbarRef) m_macHIToolbarRef, removeIndex );
1538 tool->SetIndex( -1 );
1539 }
1540 #endif
1541 switch ( tool->GetStyle() )
1542 {
1543 case wxTOOL_STYLE_CONTROL:
1544 if ( tool->GetControl() )
1545 tool->GetControl()->Destroy();
1546 break;
1547
1548 case wxTOOL_STYLE_BUTTON:
1549 case wxTOOL_STYLE_SEPARATOR:
1550 // nothing special
1551 break;
1552
1553 default:
1554 break;
1555 }
1556 tool->ClearControl();
1557
1558 // and finally reposition all the controls after this one
1559
1560 for ( /* node -> first after deleted */; node; node = node->GetNext() )
1561 {
1562 wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
1563 wxPoint pt = tool2->GetPosition();
1564
1565 if ( GetWindowStyleFlag() & wxTB_VERTICAL )
1566 pt.y -= sz.y;
1567 else
1568 pt.x -= sz.x;
1569
1570 tool2->SetPosition( pt );
1571
1572 #if wxMAC_USE_NATIVE_TOOLBAR
1573 if ( removeIndex != -1 && tool2->GetIndex() > removeIndex )
1574 tool2->SetIndex( tool2->GetIndex() - 1 );
1575 #endif
1576 }
1577
1578 InvalidateBestSize();
1579
1580 return true;
1581 }
1582
1583 void wxToolBar::OnPaint(wxPaintEvent& event)
1584 {
1585 #if wxMAC_USE_NATIVE_TOOLBAR
1586 if ( m_macUsesNativeToolbar )
1587 {
1588 event.Skip(true);
1589 return;
1590 }
1591 #endif
1592
1593 wxPaintDC dc(this);
1594
1595 int w, h;
1596 GetSize( &w, &h );
1597
1598 bool drawMetalTheme = MacGetTopLevelWindow()->MacGetMetalAppearance();
1599 bool minimumUmaAvailable = (UMAGetSystemVersion() >= 0x1030);
1600
1601 #if wxMAC_USE_CORE_GRAPHICS && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
1602 if ( !drawMetalTheme && minimumUmaAvailable )
1603 {
1604 HIThemePlacardDrawInfo info;
1605 memset( &info, 0, sizeof(info) );
1606 info.version = 0;
1607 info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive;
1608
1609 CGContextRef cgContext = (CGContextRef) MacGetCGContextRef();
1610 HIRect rect = CGRectMake( 0, 0, w, h );
1611 HIThemeDrawPlacard( &rect, &info, cgContext, kHIThemeOrientationNormal );
1612 }
1613 else
1614 {
1615 // leave the background as it is (striped or metal)
1616 }
1617
1618 #else
1619
1620 const bool drawBorder = true;
1621
1622 if (drawBorder)
1623 {
1624 wxMacPortSetter helper( &dc );
1625
1626 if ( !drawMetalTheme || !minimumUmaAvailable )
1627 {
1628 Rect toolbarrect = { dc.YLOG2DEVMAC(0), dc.XLOG2DEVMAC(0),
1629 dc.YLOG2DEVMAC(h), dc.XLOG2DEVMAC(w) };
1630
1631 #if 0
1632 if ( toolbarrect.left < 0 )
1633 toolbarrect.left = 0;
1634 if ( toolbarrect.top < 0 )
1635 toolbarrect.top = 0;
1636 #endif
1637
1638 UMADrawThemePlacard( &toolbarrect, IsEnabled() ? kThemeStateActive : kThemeStateInactive );
1639 }
1640 else
1641 {
1642 #if TARGET_API_MAC_OSX
1643 HIRect hiToolbarrect = CGRectMake(
1644 dc.YLOG2DEVMAC(0), dc.XLOG2DEVMAC(0),
1645 dc.YLOG2DEVREL(h), dc.XLOG2DEVREL(w) );
1646 CGContextRef cgContext;
1647 Rect bounds;
1648
1649 GetPortBounds( (CGrafPtr) dc.m_macPort, &bounds );
1650 QDBeginCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
1651
1652 CGContextTranslateCTM( cgContext, 0, bounds.bottom - bounds.top );
1653 CGContextScaleCTM( cgContext, 1, -1 );
1654
1655 HIThemeBackgroundDrawInfo drawInfo;
1656 drawInfo.version = 0;
1657 drawInfo.state = kThemeStateActive;
1658 drawInfo.kind = kThemeBackgroundMetal;
1659 HIThemeApplyBackground( &hiToolbarrect, &drawInfo, cgContext, kHIThemeOrientationNormal );
1660
1661 #ifndef __LP64__
1662 QDEndCGContext( (CGrafPtr) dc.m_macPort, &cgContext );
1663 #endif
1664 #endif
1665 }
1666 }
1667 #endif
1668
1669 event.Skip();
1670 }
1671
1672 #endif // wxUSE_TOOLBAR