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