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