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