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