+}
+
+#define kControlToolbarItemClassID CFSTR( "org.wxwidgets.controltoolbaritem" )
+
+const EventTypeSpec kEvents[] =
+{
+ { kEventClassHIObject, kEventHIObjectConstruct },
+ { kEventClassHIObject, kEventHIObjectInitialize },
+ { kEventClassHIObject, kEventHIObjectDestruct },
+
+ { kEventClassToolbarItem, kEventToolbarItemCreateCustomView }
+};
+
+const EventTypeSpec kViewEvents[] =
+{
+ { kEventClassControl, kEventControlGetSizeConstraints }
+};
+
+struct ControlToolbarItem
+{
+ HIToolbarItemRef toolbarItem;
+ HIViewRef viewRef;
+ wxSize lastValidSize ;
+};
+
+static pascal OSStatus ControlToolbarItemHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
+{
+ OSStatus result = eventNotHandledErr;
+ ControlToolbarItem* object = (ControlToolbarItem*)inUserData;
+
+ switch ( GetEventClass( inEvent ) )
+ {
+ case kEventClassHIObject:
+ switch ( GetEventKind( inEvent ) )
+ {
+ case kEventHIObjectConstruct:
+ {
+ HIObjectRef toolbarItem;
+ ControlToolbarItem* item;
+
+ GetEventParameter( inEvent, kEventParamHIObjectInstance, typeHIObjectRef, NULL,
+ sizeof( HIObjectRef ), NULL, &toolbarItem );
+
+ item = (ControlToolbarItem*) malloc(sizeof(ControlToolbarItem)) ;
+ item->toolbarItem = toolbarItem ;
+ item->viewRef = NULL ;
+
+ SetEventParameter( inEvent, kEventParamHIObjectInstance, typeVoidPtr, sizeof( void * ), &item );
+
+ result = noErr ;
+ }
+ break;
+
+ case kEventHIObjectInitialize:
+ result = CallNextEventHandler( inCallRef, inEvent );
+ if ( result == noErr )
+ {
+ CFDataRef data;
+ GetEventParameter( inEvent, kEventParamToolbarItemConfigData, typeCFTypeRef, NULL,
+ sizeof( CFTypeRef ), NULL, &data );
+
+ HIViewRef viewRef ;
+
+ wxASSERT_MSG( CFDataGetLength( data ) == sizeof( viewRef ) , wxT("Illegal Data passed") ) ;
+ memcpy( &viewRef , CFDataGetBytePtr( data ) , sizeof( viewRef ) ) ;
+
+ object->viewRef = (HIViewRef) viewRef ;
+
+ result = noErr ;
+ }
+ break;
+
+ case kEventHIObjectDestruct:
+ free( object ) ;
+ result = noErr;
+ break;
+ }
+ break;
+
+ case kEventClassToolbarItem:
+ switch ( GetEventKind( inEvent ) )
+ {
+ case kEventToolbarItemCreateCustomView:
+ {
+ HIViewRef viewRef = object->viewRef ;
+
+ HIViewRemoveFromSuperview( viewRef ) ;
+ HIViewSetVisible(viewRef, true) ;
+ InstallEventHandler( GetControlEventTarget( viewRef ), ControlToolbarItemHandler,
+ GetEventTypeCount( kViewEvents ), kViewEvents, object, NULL );
+
+ result = SetEventParameter( inEvent, kEventParamControlRef, typeControlRef, sizeof( HIViewRef ), &viewRef );
+ }
+ break;
+ }
+ break;
+
+ case kEventClassControl:
+ switch ( GetEventKind( inEvent ) )
+ {
+ case kEventControlGetSizeConstraints:
+ {
+ wxWindow* wxwindow = wxFindControlFromMacControl(object->viewRef ) ;
+ if ( wxwindow )
+ {
+ wxSize sz = wxwindow->GetSize() ;
+ sz.x -= wxwindow->MacGetLeftBorderSize() + wxwindow->MacGetRightBorderSize();
+ sz.y -= wxwindow->MacGetTopBorderSize() + wxwindow->MacGetBottomBorderSize();
+ // during toolbar layout the native window sometimes gets negative sizes
+ // so we always keep the last valid size here, to make sure we survive the
+ // shuffle ...
+ if ( sz.x > 0 && sz.y > 0 )
+ object->lastValidSize = sz ;
+ else
+ sz = object->lastValidSize ;
+
+ HISize min, max;
+ min.width = max.width = sz.x ;
+ min.height = max.height = sz.y ;
+
+ result = SetEventParameter( inEvent, kEventParamMinimumSize, typeHISize,
+ sizeof( HISize ), &min );
+
+ result = SetEventParameter( inEvent, kEventParamMaximumSize, typeHISize,
+ sizeof( HISize ), &max );
+ result = noErr ;
+ }
+ }
+ break;
+ }
+ break;
+ }
+
+ return result;
+}
+
+void RegisterControlToolbarItemClass()
+{
+ static bool sRegistered;
+
+ if ( !sRegistered )
+ {
+ HIObjectRegisterSubclass( kControlToolbarItemClassID, kHIToolbarItemClassID, 0,
+ ControlToolbarItemHandler, GetEventTypeCount( kEvents ), kEvents, 0, NULL );
+
+ sRegistered = true;
+ }
+}
+
+HIToolbarItemRef CreateControlToolbarItem(CFStringRef inIdentifier, CFTypeRef inConfigData)
+{
+ RegisterControlToolbarItemClass();
+
+ OSStatus err;
+ EventRef event;
+ UInt32 options = kHIToolbarItemAllowDuplicates;
+ HIToolbarItemRef result = NULL;
+
+ err = CreateEvent( NULL, kEventClassHIObject, kEventHIObjectInitialize, GetCurrentEventTime(), 0, &event );
+ require_noerr( err, CantCreateEvent );
+
+ SetEventParameter( event, kEventParamAttributes, typeUInt32, sizeof( UInt32 ), &options );
+ SetEventParameter( event, kEventParamToolbarItemIdentifier, typeCFStringRef, sizeof( CFStringRef ), &inIdentifier );
+
+ if ( inConfigData )
+ SetEventParameter( event, kEventParamToolbarItemConfigData, typeCFTypeRef, sizeof( CFTypeRef ), &inConfigData );
+
+ err = HIObjectCreate( kControlToolbarItemClassID, event, (HIObjectRef*)&result );
+ check_noerr( err );
+
+ ReleaseEvent( event );
+CantCreateEvent :
+ return result ;
+}
+
+#if wxMAC_USE_NATIVE_TOOLBAR
+static const EventTypeSpec kToolbarEvents[] =
+{
+ { kEventClassToolbar, kEventToolbarGetDefaultIdentifiers },
+ { kEventClassToolbar, kEventToolbarGetAllowedIdentifiers },
+ { kEventClassToolbar, kEventToolbarCreateItemWithIdentifier },
+};
+
+static OSStatus ToolbarDelegateHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* inUserData )
+{
+ OSStatus result = eventNotHandledErr;
+ // Not yet needed
+ // wxToolBar* toolbar = (wxToolBar*) inUserData ;
+ CFMutableArrayRef array;
+
+ switch ( GetEventKind( inEvent ) )
+ {
+ case kEventToolbarGetDefaultIdentifiers:
+ {
+ GetEventParameter( inEvent, kEventParamMutableArray, typeCFMutableArrayRef, NULL,
+ sizeof( CFMutableArrayRef ), NULL, &array );
+ // not implemented yet
+ // GetToolbarDefaultItems( array );
+ result = noErr;
+ }
+ break;
+
+ case kEventToolbarGetAllowedIdentifiers:
+ {
+ GetEventParameter( inEvent, kEventParamMutableArray, typeCFMutableArrayRef, NULL,
+ sizeof( CFMutableArrayRef ), NULL, &array );
+ // not implemented yet
+ // GetToolbarAllowedItems( array );
+ result = noErr;
+ }
+ break;
+ case kEventToolbarCreateItemWithIdentifier:
+ {
+ HIToolbarItemRef item = NULL;
+ CFTypeRef data = NULL;
+ CFStringRef identifier = NULL ;
+
+ GetEventParameter( inEvent, kEventParamToolbarItemIdentifier, typeCFStringRef, NULL,
+ sizeof( CFStringRef ), NULL, &identifier );
+
+ GetEventParameter( inEvent, kEventParamToolbarItemConfigData, typeCFTypeRef, NULL,
+ sizeof( CFTypeRef ), NULL, &data );
+
+ if ( CFStringCompare( kControlToolbarItemClassID, identifier, kCFCompareBackwards ) == kCFCompareEqualTo )
+ {
+ item = CreateControlToolbarItem( kControlToolbarItemClassID, data );
+ if ( item )
+ {
+ SetEventParameter( inEvent, kEventParamToolbarItem, typeHIToolbarItemRef,
+ sizeof( HIToolbarItemRef ), &item );
+ result = noErr;
+ }
+ }
+
+ }
+ break;
+ }
+ return result ;
+}
+#endif // wxMAC_USE_NATIVE_TOOLBAR
+
+// also for the toolbar we have the dual implementation:
+// only when MacInstallNativeToolbar is called is the native toolbar set as the window toolbar
+
+bool wxToolBar::Create(
+ wxWindow *parent,
+ wxWindowID id,
+ const wxPoint& pos,
+ const wxSize& size,
+ long style,
+ const wxString& name )
+{
+ if ( !wxToolBarBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ) )
+ return false;
+
+ OSStatus err = noErr;
+
+#if wxMAC_USE_NATIVE_TOOLBAR
+ wxString labelStr = wxString::Format( wxT("%xd"), (int)this );
+ err = HIToolbarCreate(
+ wxMacCFStringHolder( labelStr, wxFont::GetDefaultEncoding() ), 0,
+ (HIToolbarRef*) &m_macHIToolbarRef );
+
+ if (m_macHIToolbarRef != NULL)
+ {
+ InstallEventHandler( HIObjectGetEventTarget((HIToolbarRef)m_macHIToolbarRef ), ToolbarDelegateHandler,
+ GetEventTypeCount( kToolbarEvents ), kToolbarEvents, this, NULL );
+
+ HIToolbarDisplayMode mode = kHIToolbarDisplayModeDefault;
+ HIToolbarDisplaySize displaySize = kHIToolbarDisplaySizeSmall;
+
+ if ( style & wxTB_NOICONS )
+ mode = kHIToolbarDisplayModeLabelOnly;
+ else if ( style & wxTB_TEXT )
+ mode = kHIToolbarDisplayModeIconAndLabel;
+ else
+ mode = kHIToolbarDisplayModeIconOnly;
+
+ HIToolbarSetDisplayMode( (HIToolbarRef) m_macHIToolbarRef, mode );
+ HIToolbarSetDisplaySize( (HIToolbarRef) m_macHIToolbarRef, displaySize );
+ }
+#endif
+
+ return (err == noErr);