1///////////////////////////////////////////////////////////////////////////// 2// Name: src/osx/cocoa/toolbar.mm 3// Purpose: wxToolBar 4// Author: Stefan Csomor 5// Modified by: 6// Created: 04/01/98 7// Copyright: (c) Stefan Csomor 8// Licence: wxWindows licence 9///////////////////////////////////////////////////////////////////////////// 10 11#include "wx/wxprec.h" 12 13#if wxUSE_TOOLBAR 14 15#ifndef WX_PRECOMP 16 #include "wx/wx.h" 17#endif 18 19#include "wx/toolbar.h" 20#include "wx/app.h" 21#include "wx/osx/private.h" 22#include "wx/osx/private/available.h" 23#include "wx/geometry.h" 24#include "wx/sysopt.h" 25 26const short kwxMacToolBarToolDefaultWidth = 16; 27const short kwxMacToolBarToolDefaultHeight = 16; 28const short kwxMacToolBarTopMargin = 4; 29const short kwxMacToolBarLeftMargin = 4; 30const short kwxMacToolBorder = 0; 31const short kwxMacToolSpacing = 6; 32 33wxBEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase) 34 EVT_PAINT( wxToolBar::OnPaint ) 35wxEND_EVENT_TABLE() 36 37 38#pragma mark - 39#pragma mark Tool Implementation 40 41// ---------------------------------------------------------------------------- 42// private classes 43// ---------------------------------------------------------------------------- 44 45class wxToolBarTool; 46 47@interface wxNSToolBarButton : NSButton 48{ 49 wxToolBarTool* impl; 50} 51 52- (id)initWithFrame:(NSRect)frame; 53- (void) clickedAction: (id) sender; 54- (void)setImplementation: (wxToolBarTool *) theImplementation; 55- (wxToolBarTool*) implementation; 56- (BOOL) isFlipped; 57 58@end 59 60// We have a dual implementation for each tool, WXWidget and NSToolbarItem* 61 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 NSToolbarItem 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 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. 72 73class wxToolBarTool : public wxToolBarToolBase 74{ 75public: 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 ); 86 87 wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label) 88 : wxToolBarToolBase(tbar, control, label) 89 { 90 Init(); 91 if (control != NULL) 92 SetControlHandle( (WXWidget) control->GetHandle() ); 93 } 94 95 virtual ~wxToolBarTool() 96 { 97 ClearControl(); 98 } 99 100 WXWidget GetControlHandle() 101 { 102 return (WXWidget) m_controlHandle; 103 } 104 105 void SetControlHandle( WXWidget handle ) 106 { 107 m_controlHandle = handle; 108 } 109 110 void SetPosition( const wxPoint& position ); 111 112 void ClearControl() 113 { 114 if ( m_controlHandle ) 115 { 116 if ( !IsControl() ) 117 { 118 [m_controlHandle removeFromSuperview]; 119 [m_controlHandle release]; 120 } 121 else 122 { 123 // the embedded control is not under the responsibility of the tool, it gets disposed of in the 124 // proper wxControl destructor 125 } 126 m_controlHandle = NULL ; 127 } 128 129#if wxOSX_USE_NATIVE_TOOLBAR 130 if ( m_toolbarItem ) 131 { 132 [m_toolbarItem release]; 133 m_toolbarItem = NULL; 134 } 135#endif // wxOSX_USE_NATIVE_TOOLBAR 136 } 137 138 wxSize GetSize() const 139 { 140 wxSize curSize; 141 142 if ( IsControl() ) 143 { 144 curSize = GetControl()->GetSize(); 145 } 146 else if ( IsButton() ) 147 { 148 // curSize = GetToolBar()->GetToolSize(); 149 NSRect best = [(wxNSToolBarButton*)m_controlHandle frame]; 150 curSize = wxSize(best.size.width, best.size.height); 151 } 152 else 153 { 154 // separator size 155 curSize = GetToolBar()->GetToolSize(); 156 if ( GetToolBar()->IsVertical() ) 157 curSize.y /= 4; 158 else 159 curSize.x /= 4; 160 } 161 162 return curSize; 163 } 164 165 wxPoint GetPosition() const 166 { 167 return wxPoint( m_x, m_y ); 168 } 169 170 bool Enable( bool enable ) wxOVERRIDE; 171 172 void UpdateImages(); 173 174 void UpdateToggleImage( bool toggle ); 175 176 void UpdateLabel() 177 { 178 // Use an empty string if we're not displaying text 179 wxString labelStr; 180 wxToolBar *tbar = (wxToolBar*) GetToolBar(); 181 int style = (tbar ? tbar->GetWindowStyleFlag() : 0); 182 if ( (style & (wxTB_NOICONS | wxTB_TEXT)) != 0 ) 183 labelStr = wxStripMenuCodes(m_label); 184 185 wxCFStringRef l(labelStr, GetToolBarFontEncoding()); 186 wxCFStringRef sh( GetShortHelp(), GetToolBarFontEncoding() ); 187#if wxOSX_USE_NATIVE_TOOLBAR 188 if ( m_toolbarItem ) 189 { 190 // strip mnemonics from the label for compatibility with the usual 191 // labels in wxStaticText sense 192 193 [m_toolbarItem setLabel:l.AsNSString()]; 194 195 [m_toolbarItem setToolTip:sh.AsNSString()]; 196 } 197#endif 198 if ( IsButton() ) 199 { 200 NSButton* const btn = (NSButton*)m_controlHandle; 201 202 [btn setTitle:l.AsNSString()]; 203 204 if ( style & wxTB_NOICONS ) 205 [btn setImagePosition:NSNoImage]; 206 else if ( style & wxTB_TEXT ) 207 [btn setImagePosition:NSImageAbove]; 208 else 209 [btn setImagePosition:NSImageOnly]; 210 211 if ( (style & (wxTB_NOICONS | wxTB_TEXT)) != 0 ) 212 { 213 [btn sizeToFit]; 214 } 215 else if (tbar) 216 { 217 wxSize toolsize = tbar->GetToolSize(); 218 NSRect frame = [m_controlHandle frame]; 219 frame.size.width = toolsize.x; 220 frame.size.height = toolsize.y + 2; 221 [btn setFrame:frame]; 222 } 223 } 224 225 if ( m_controlHandle ) 226 { 227 [m_controlHandle setToolTip:sh.AsNSString()]; 228 } 229 } 230 231 void Action() 232 { 233 wxToolBar *tbar = (wxToolBar*) GetToolBar(); 234 if (CanBeToggled()) 235 { 236 bool shouldToggle; 237 238 shouldToggle = !IsToggled(); 239 tbar->ToggleTool( GetId(), shouldToggle ); 240 } 241 242 tbar->OnLeftClick( GetId(), IsToggled() ); 243 } 244 245#if wxOSX_USE_NATIVE_TOOLBAR 246 void SetToolbarItemRef( NSToolbarItem* ref ) 247 { 248 if ( m_toolbarItem ) 249 [m_toolbarItem release]; 250 251 m_toolbarItem = ref; 252 } 253 254 NSToolbarItem* GetToolbarItemRef() const 255 { 256 return m_toolbarItem; 257 } 258 259 void SetIndex( CFIndex idx ) 260 { 261 m_index = idx; 262 } 263 264 CFIndex GetIndex() const 265 { 266 return m_index; 267 } 268 269 virtual void SetLabel(const wxString& label) wxOVERRIDE 270 { 271 wxToolBarToolBase::SetLabel(label); 272 UpdateLabel(); 273 } 274 275 virtual bool SetShortHelp(const wxString& help) wxOVERRIDE 276 { 277 if ( !wxToolBarToolBase::SetShortHelp(help) ) 278 return false; 279 280 UpdateLabel(); 281 282 return true; 283 } 284#endif // wxOSX_USE_NATIVE_TOOLBAR 285 286private: 287 wxFontEncoding GetToolBarFontEncoding() const 288 { 289 wxFont f; 290 if ( GetToolBar() ) 291 f = GetToolBar()->GetFont(); 292 return f.IsOk() ? f.GetEncoding() : wxFont::GetDefaultEncoding(); 293 } 294 295 void Init() 296 { 297 m_controlHandle = NULL; 298 299#if wxOSX_USE_NATIVE_TOOLBAR 300 m_toolbarItem = NULL; 301 m_index = -1; 302#endif 303 } 304 305 WXWidget m_controlHandle; 306 wxCoord m_x; 307 wxCoord m_y; 308 wxBitmap m_alternateBitmap; 309 310#if wxOSX_USE_NATIVE_TOOLBAR 311 NSToolbarItem* m_toolbarItem; 312 // position in its toolbar, -1 means not inserted 313 CFIndex m_index; 314#endif 315}; 316 317#if wxOSX_USE_NATIVE_TOOLBAR 318 319@interface wxNSToolbarItem : NSToolbarItem 320{ 321 wxToolBarTool* impl; 322} 323 324- (id) initWithItemIdentifier: (NSString*) identifier; 325- (void)setImplementation: (wxToolBarTool *) theImplementation; 326- (wxToolBarTool*) implementation; 327- (void) clickedAction: (id) sender; 328- (BOOL) validateToolbarItem:(NSToolbarItem *)theItem; 329 330@end 331 332 333@interface wxNSToolbarDelegate : NSObject <NSToolbarDelegate> 334{ 335 bool m_isSelectable; 336} 337 338- (void)setSelectable:(bool) value; 339 340- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag; 341 342- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar; 343 344- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar; 345 346- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar; 347 348@end 349 350 351@interface wxNSToolbar : NSToolbar 352{ 353 wxNSToolbarDelegate* toolbarDelegate; 354} 355 356- (id)initWithIdentifier:(NSString *)identifier; 357- (void) dealloc; 358 359@end 360 361#endif 362 363 364#if wxOSX_USE_NATIVE_TOOLBAR 365 366@implementation wxNSToolbarItem 367 368- (id)initWithItemIdentifier: (NSString*) identifier 369{ 370 if ( self = [super initWithItemIdentifier:identifier] ) 371 { 372 impl = NULL; 373 [self setTarget: self]; 374 [self setAction: @selector(clickedAction:)]; 375 } 376 return self; 377} 378 379- (void) clickedAction: (id) sender 380{ 381 wxUnusedVar(sender); 382 if ( impl ) 383 { 384 impl->Action(); 385 } 386} 387 388- (void)setImplementation: (wxToolBarTool *) theImplementation 389{ 390 impl = theImplementation; 391} 392 393- (wxToolBarTool*) implementation 394{ 395 return impl; 396} 397 398- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem 399{ 400 wxUnusedVar(theItem); 401 return impl->IsEnabled() ? YES:NO; 402} 403 404@end 405 406@implementation wxNSToolbarDelegate 407 408- (id)init 409{ 410 if ( self = [super init] ) 411 { 412 m_isSelectable = false; 413 } 414 return self; 415} 416 417- (void)setSelectable:(bool) value 418{ 419 wxUnusedVar(value); 420 m_isSelectable = true; 421} 422 423- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar 424{ 425 wxUnusedVar(toolbar); 426 return nil; 427} 428 429- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar 430{ 431 wxUnusedVar(toolbar); 432 return nil; 433} 434 435- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar 436{ 437 if ( m_isSelectable ) 438 return [[toolbar items] valueForKey:@"itemIdentifier"]; 439 else 440 return nil; 441} 442 443- (NSToolbarItem*) toolbar:(NSToolbar*) toolbar itemForItemIdentifier:(NSString*) itemIdentifier willBeInsertedIntoToolbar:(BOOL) flag 444{ 445 wxUnusedVar(toolbar); 446#ifdef __LP64__ 447 wxToolBarTool* tool = (wxToolBarTool*) [itemIdentifier longLongValue]; 448#else 449 wxToolBarTool* tool = (wxToolBarTool*) [itemIdentifier intValue]; 450#endif 451 if ( tool ) 452 { 453 wxNSToolbarItem* item = (wxNSToolbarItem*) tool->GetToolbarItemRef(); 454 if ( flag && tool->IsControl() ) 455 { 456 NSView* view = tool->GetControl()->GetHandle(); 457 [view removeFromSuperview]; 458 [item setView:view]; 459 wxSize sz = tool->GetControl()->GetSize(); 460 NSSize size = NSMakeSize((float)sz.x, (float)sz.y); 461 [item setMaxSize:size]; 462 [item setMinSize:size]; 463 [view setHidden:NO]; 464 } 465 return item; 466 } 467 return nil; 468} 469 470@end 471 472 473@implementation wxNSToolbar 474 475- (id)initWithIdentifier:(NSString *)identifier 476{ 477 if (self = [super initWithIdentifier:identifier]) 478 { 479 toolbarDelegate = [[wxNSToolbarDelegate alloc] init]; 480 [self setDelegate:toolbarDelegate]; 481 } 482 return self; 483} 484 485- (void)dealloc 486{ 487 [toolbarDelegate release]; 488 [super dealloc]; 489} 490 491@end 492 493#endif 494 495@implementation wxNSToolBarButton 496 497- (id)initWithFrame:(NSRect)frame 498{ 499 if ( self = [super initWithFrame:frame] ) 500 { 501 impl = NULL; 502 [self setTarget: self]; 503 [self setAction: @selector(clickedAction:)]; 504 } 505 return self; 506} 507 508- (void) clickedAction: (id) sender 509{ 510 wxUnusedVar(sender); 511 if ( impl ) 512 { 513 impl->Action(); 514 } 515} 516 517- (void)setImplementation: (wxToolBarTool *) theImplementation 518{ 519 impl = theImplementation; 520} 521 522- (wxToolBarTool*) implementation 523{ 524 return impl; 525} 526 527- (BOOL) isFlipped 528{ 529 return YES; 530} 531 532@end 533 534bool wxToolBarTool::Enable( bool enable ) 535{ 536 if ( wxToolBarToolBase::Enable( enable ) == false ) 537 return false; 538 539 if ( IsControl() ) 540 { 541 GetControl()->Enable( enable ); 542 } 543 else if ( IsButton() ) 544 { 545#if wxOSX_USE_NATIVE_TOOLBAR 546 if ( m_toolbarItem != NULL ) 547 [m_toolbarItem setEnabled:enable]; 548#endif 549 550 if ( m_controlHandle != NULL ) 551 [(NSControl*)m_controlHandle setEnabled:enable]; 552 } 553 554 return true; 555} 556 557void wxToolBarTool::SetPosition( const wxPoint& position ) 558{ 559 m_x = position.x; 560 m_y = position.y; 561 562 int mac_x = position.x; 563 int mac_y = position.y; 564 565 if ( IsButton() ) 566 { 567 NSRect frame = [m_controlHandle frame]; 568 if ( frame.origin.x != mac_x || frame.origin.y != mac_y ) 569 { 570 frame.origin.x = mac_x; 571 frame.origin.y = mac_y; 572 [m_controlHandle setFrame:frame]; 573 } 574 } 575 else if ( IsControl() ) 576 { 577 // embedded native controls are moved by the OS 578#if wxOSX_USE_NATIVE_TOOLBAR 579 if ( ((wxToolBar*)GetToolBar())->MacWantsNativeToolbar() == false ) 580#endif 581 { 582 GetControl()->Move( position ); 583 } 584 } 585 else 586 { 587 NSRect frame = [m_controlHandle frame]; 588 if ( frame.origin.x != mac_x || frame.origin.y != mac_y ) 589 { 590 frame.origin.x = mac_x; 591 frame.origin.y = mac_y; 592 [m_controlHandle setFrame:frame]; 593 } 594 } 595} 596 597void wxToolBarTool::UpdateImages() 598{ 599 [(NSButton*) m_controlHandle setImage:m_bmpNormal.GetNSImage()]; 600 601 if ( CanBeToggled() ) 602 { 603 int w = m_bmpNormal.GetScaledWidth(); 604 int h = m_bmpNormal.GetScaledHeight(); 605 m_alternateBitmap = wxBitmap(); 606 m_alternateBitmap.CreateScaled(w, h, -1, m_bmpNormal.GetScaleFactor()); 607 m_alternateBitmap.UseAlpha(); 608 wxMemoryDC dc; 609 610 dc.SelectObject(m_alternateBitmap); 611 // This color corresponds to OS X Yosemite's rendering of selected toolbar items 612 // See also https://trac.wxwidgets.org/ticket/16645 613 wxColour grey(0xB9, 0xB9, 0xB9); 614 dc.SetBackground(*wxTRANSPARENT_BRUSH); 615 dc.Clear(); 616 dc.SetPen(grey); 617 dc.SetBrush(grey); 618 dc.DrawRoundedRectangle( 0, 0, w, h, 3 ); 619 dc.DrawBitmap( m_bmpNormal, 0, 0, true ); 620 dc.SelectObject( wxNullBitmap ); 621 622 [(NSButton*) m_controlHandle setAlternateImage:m_alternateBitmap.GetNSImage()]; 623 } 624 UpdateToggleImage( CanBeToggled() && IsToggled() ); 625} 626 627void wxToolBarTool::UpdateToggleImage( bool toggle ) 628{ 629#if wxOSX_USE_NATIVE_TOOLBAR 630 // Avoid setting the image if we're not showing icons because the image may 631 // be invalid. 632 wxToolBar *tbar = (wxToolBar*) GetToolBar(); 633 int style = tbar ? tbar->GetWindowStyleFlag() : 0; 634 if ( m_toolbarItem != NULL && !(style & wxTB_NOICONS) ) 635 { 636 // the native toolbar item only has a 'selected' state (one for one toolbar) 637 // so we emulate the toggle here 638 if ( CanBeToggled() && toggle ) 639 [m_toolbarItem setImage:m_alternateBitmap.GetNSImage()]; 640 else 641 [m_toolbarItem setImage:m_bmpNormal.GetNSImage()]; 642 } 643#endif 644 645 if ( IsButton() ) 646 [(NSButton*)m_controlHandle setState:(toggle ? NSOnState : NSOffState)]; 647} 648 649wxToolBarTool::wxToolBarTool( 650 wxToolBar *tbar, 651 int id, 652 const wxString& label, 653 const wxBitmap& bmpNormal, 654 const wxBitmap& bmpDisabled, 655 wxItemKind kind, 656 wxObject *clientData, 657 const wxString& shortHelp, 658 const wxString& longHelp ) 659 : 660 wxToolBarToolBase( 661 tbar, id, label, bmpNormal, bmpDisabled, kind, 662 clientData, shortHelp, longHelp ) 663{ 664 Init(); 665} 666 667#pragma mark - 668#pragma mark Toolbar Implementation 669 670wxToolBarToolBase *wxToolBar::CreateTool( 671 int id, 672 const wxString& label, 673 const wxBitmap& bmpNormal, 674 const wxBitmap& bmpDisabled, 675 wxItemKind kind, 676 wxObject *clientData, 677 const wxString& shortHelp, 678 const wxString& longHelp ) 679{ 680 return new wxToolBarTool( 681 this, id, label, bmpNormal, bmpDisabled, kind, 682 clientData, shortHelp, longHelp ); 683} 684 685wxToolBarToolBase * 686wxToolBar::CreateTool(wxControl *control, const wxString& label) 687{ 688 return new wxToolBarTool(this, control, label); 689} 690 691void wxToolBar::Init() 692{ 693 m_maxWidth = -1; 694 m_maxHeight = -1; 695 m_defaultWidth = kwxMacToolBarToolDefaultWidth; 696 m_defaultHeight = kwxMacToolBarToolDefaultHeight; 697 698#if wxOSX_USE_NATIVE_TOOLBAR 699 m_macToolbar = NULL; 700 m_macUsesNativeToolbar = false; 701#endif 702} 703 704// also for the toolbar we have the dual implementation: 705// only when MacInstallNativeToolbar is called is the native toolbar set as the window toolbar 706 707bool wxToolBar::Create( 708 wxWindow *parent, 709 wxWindowID id, 710 const wxPoint& pos, 711 const wxSize& size, 712 long style, 713 const wxString& name ) 714{ 715 if ( !wxToolBarBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ) ) 716 return false; 717 718 FixupStyle(); 719 720 OSStatus err = noErr; 721 722#if wxOSX_USE_NATIVE_TOOLBAR 723 724 if (parent->IsKindOf(CLASSINFO(wxFrame)) && wxSystemOptions::GetOptionInt(wxT("mac.toolbar.no-native")) != 1) 725 { 726 wxString identifier = wxString::Format( wxT("%p"), this ); 727 wxCFStringRef cfidentifier(identifier); 728 NSToolbar* tb = [[wxNSToolbar alloc] initWithIdentifier:cfidentifier.AsNSString()]; 729 730 m_macToolbar = tb ; 731 732 if (m_macToolbar != NULL) 733 { 734 NSToolbarDisplayMode mode = NSToolbarDisplayModeDefault; 735 NSToolbarSizeMode displaySize = NSToolbarSizeModeSmall; 736 737 if ( style & wxTB_NOICONS ) 738 mode = NSToolbarDisplayModeLabelOnly; 739 else if ( style & wxTB_TEXT ) 740 mode = NSToolbarDisplayModeIconAndLabel; 741 else 742 mode = NSToolbarDisplayModeIconOnly; 743 744 [tb setDisplayMode:mode]; 745 [tb setSizeMode:displaySize]; 746 } 747 } 748#endif // wxOSX_USE_NATIVE_TOOLBAR 749 750 return (err == noErr); 751} 752 753wxToolBar::~wxToolBar() 754{ 755 // removal only works while the toolbar is there 756 wxFrame *frame = wxDynamicCast(GetParent(), wxFrame); 757 if ( frame && frame->GetToolBar() == this ) 758 { 759 frame->SetToolBar(NULL); 760 } 761 762#if wxOSX_USE_NATIVE_TOOLBAR 763 [(NSToolbar*)m_macToolbar setDelegate:nil]; 764 [(NSToolbar*)m_macToolbar release]; 765 m_macToolbar = NULL; 766#endif // wxOSX_USE_NATIVE_TOOLBAR 767} 768 769bool wxToolBar::Show( bool show ) 770{ 771 WXWindow tlw = MacGetTopLevelWindowRef(); 772 bool bResult = (tlw != NULL); 773 774 if (bResult) 775 { 776#if wxOSX_USE_NATIVE_TOOLBAR 777 bool ownToolbarInstalled = false; 778 MacTopLevelHasNativeToolbar( &ownToolbarInstalled ); 779 if (ownToolbarInstalled) 780 { 781 bResult = ([(NSToolbar*)m_macToolbar isVisible] != show); 782 if ( bResult ) 783 [(NSToolbar*)m_macToolbar setVisible:show]; 784 } 785 else 786 bResult = wxToolBarBase::Show( show ); 787#else 788 789 bResult = wxToolBarBase::Show( show ); 790#endif 791 } 792 793 return bResult; 794} 795 796bool wxToolBar::IsShown() const 797{ 798 bool bResult; 799 800#if wxOSX_USE_NATIVE_TOOLBAR 801 bool ownToolbarInstalled; 802 803 MacTopLevelHasNativeToolbar( &ownToolbarInstalled ); 804 if (ownToolbarInstalled) 805 { 806 bResult = [(NSToolbar*)m_macToolbar isVisible]; 807 } 808 else 809 bResult = wxToolBarBase::IsShown(); 810#else 811 812 bResult = wxToolBarBase::IsShown(); 813#endif 814 815 return bResult; 816} 817 818void wxToolBar::DoGetSize( int *width, int *height ) const 819{ 820#if wxOSX_USE_NATIVE_TOOLBAR 821 bool ownToolbarInstalled; 822 823 MacTopLevelHasNativeToolbar( &ownToolbarInstalled ); 824 if ( ownToolbarInstalled ) 825 { 826 WXWindow tlw = MacGetTopLevelWindowRef(); 827 float toolbarHeight = 0.0; 828 NSRect windowFrame = NSMakeRect(0, 0, 0, 0); 829 830 if(m_macToolbar && [(NSToolbar*)m_macToolbar isVisible]) 831 { 832 windowFrame = [NSWindow contentRectForFrameRect:[tlw frame] 833 styleMask:[tlw styleMask]]; 834 toolbarHeight = NSHeight(windowFrame) 835 - NSHeight([[tlw contentView] frame]); 836 } 837 838 if ( width != NULL ) 839 *width = (int)windowFrame.size.width; 840 if ( height != NULL ) 841 *height = (int)toolbarHeight; 842 } 843 else 844 wxToolBarBase::DoGetSize( width, height ); 845 846#else 847 wxToolBarBase::DoGetSize( width, height ); 848#endif 849} 850 851void wxToolBar::DoGetPosition(int*x, int *y) const 852{ 853#if wxOSX_USE_NATIVE_TOOLBAR 854 bool ownToolbarInstalled; 855 856 MacTopLevelHasNativeToolbar( &ownToolbarInstalled ); 857 if ( ownToolbarInstalled ) 858 { 859 WXWindow tlw = MacGetTopLevelWindowRef(); 860 float toolbarHeight = 0.0; 861 NSRect windowFrame = NSMakeRect(0, 0, 0, 0); 862 863 if(m_macToolbar && [(NSToolbar*)m_macToolbar isVisible]) 864 { 865 windowFrame = [NSWindow contentRectForFrameRect:[tlw frame] 866 styleMask:[tlw styleMask]]; 867 toolbarHeight = NSHeight(windowFrame) 868 - NSHeight([[tlw contentView] frame]); 869 } 870 871 // it is extending to the north of the content area 872 873 if ( x != NULL ) 874 *x = 0; 875 if ( y != NULL ) 876 *y = -toolbarHeight; 877 } 878 else 879 wxToolBarBase::DoGetPosition( x, y ); 880 881#else 882 wxToolBarBase::DoGetPosition( x, y ); 883#endif 884} 885 886wxSize wxToolBar::DoGetBestSize() const 887{ 888 // was updated in Realize() 889 890 wxSize size = GetMinSize(); 891 892 return size; 893} 894 895void wxToolBar::SetWindowStyleFlag( long style ) 896{ 897 wxToolBarBase::SetWindowStyleFlag( style ); 898 899#if wxOSX_USE_NATIVE_TOOLBAR 900 if (m_macToolbar != NULL) 901 { 902 NSToolbarDisplayMode mode = NSToolbarDisplayModeDefault; 903 904 if ( style & wxTB_NOICONS ) 905 mode = NSToolbarDisplayModeLabelOnly; 906 else if ( style & wxTB_TEXT ) 907 mode = NSToolbarDisplayModeIconAndLabel; 908 else 909 mode = NSToolbarDisplayModeIconOnly; 910 911 [(NSToolbar*) m_macToolbar setDisplayMode:mode]; 912 } 913#endif 914 915 wxToolBarTool *tool; 916 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); 917 while ( node ) 918 { 919 tool = (wxToolBarTool *) node->GetData(); 920 if ( tool != NULL ) 921 { 922 tool->UpdateLabel(); 923 } 924 925 node = node->GetNext(); 926 } 927 928 InvalidateBestSize(); 929} 930 931#if wxOSX_USE_NATIVE_TOOLBAR 932bool wxToolBar::MacWantsNativeToolbar() 933{ 934 return m_macUsesNativeToolbar; 935} 936 937bool wxToolBar::MacTopLevelHasNativeToolbar(bool *ownToolbarInstalled) const 938{ 939 bool bResultV = false; 940 941 if (ownToolbarInstalled != NULL) 942 *ownToolbarInstalled = false; 943 944 WXWindow tlw = MacGetTopLevelWindowRef(); 945 if (tlw != NULL) 946 { 947 NSToolbar* curToolbarRef = [tlw toolbar]; 948 bResultV = (curToolbarRef != NULL); 949 if (bResultV && (ownToolbarInstalled != NULL)) 950 *ownToolbarInstalled = (curToolbarRef == m_macToolbar); 951 } 952 953 return bResultV; 954} 955 956bool wxToolBar::MacInstallNativeToolbar(bool usesNative) 957{ 958 bool bResult = false; 959 960 if (usesNative && (m_macToolbar == NULL)) 961 return bResult; 962 963 if (usesNative && HasFlag(wxTB_LEFT|wxTB_RIGHT|wxTB_BOTTOM) ) 964 return bResult; 965 966 WXWindow tlw = MacGetTopLevelWindowRef(); 967 if (tlw == NULL) 968 return bResult; 969 970 // check the existing toolbar 971 NSToolbar* curToolbarRef = [tlw toolbar]; 972 973 m_macUsesNativeToolbar = usesNative; 974 975 if (m_macUsesNativeToolbar) 976 { 977 // only install toolbar if there isn't one installed already 978 if (curToolbarRef == NULL) 979 { 980 bResult = true; 981 [tlw setToolbar:(NSToolbar*) m_macToolbar]; 982 [(NSToolbar*) m_macToolbar setVisible:YES]; 983 984 GetPeer()->Move(0,0,0,0 ); 985 SetSize( wxSIZE_AUTO_WIDTH, 0 ); 986 GetPeer()->SetVisibility( false ); 987 wxToolBarBase::Show( false ); 988 } 989 } 990 else 991 { 992 // only deinstall toolbar if this is the installed one 993 if (m_macToolbar == curToolbarRef) 994 { 995 bResult = true; 996 [(NSToolbar*) m_macToolbar setVisible:NO]; 997 MacUninstallNativeToolbar(); 998 GetPeer()->SetVisibility( true ); 999 } 1000 } 1001 1002 if (bResult) 1003 InvalidateBestSize(); 1004 1005// wxLogDebug( wxT(" --> [%lx] - result [%s]"), (long)this, bResult ? wxT("T") : wxT("F") ); 1006 return bResult; 1007} 1008 1009void wxToolBar::MacUninstallNativeToolbar() 1010{ 1011 if (!m_macToolbar) 1012 return; 1013 1014 WXWindow tlw = MacGetTopLevelWindowRef(); 1015 if (tlw) 1016 [tlw setToolbar:nil]; 1017} 1018#endif 1019 1020void wxToolBar::DoLayout() 1021{ 1022 int maxToolWidth = 0; 1023 int maxToolHeight = 0; 1024 1025 int tw, th; 1026 GetSize( &tw, &th ); 1027 1028 // find the maximum tool width and height 1029 // and the number of stretchable items 1030 int numStretchableSpaces = 0; 1031 wxToolBarTool *tool; 1032 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); 1033 while ( node ) 1034 { 1035 tool = (wxToolBarTool *) node->GetData(); 1036 if ( tool != NULL ) 1037 { 1038 wxSize sz = tool->GetSize(); 1039 1040 if ( sz.x > maxToolWidth ) 1041 maxToolWidth = sz.x; 1042 if ( sz.y > maxToolHeight ) 1043 maxToolHeight = sz.y; 1044 if ( tool->IsStretchableSpace() ) 1045 numStretchableSpaces++; 1046 } 1047 1048 node = node->GetNext(); 1049 } 1050 1051 // layout non-native toolbar 1052 1053 bool isHorizontal = !IsVertical(); 1054 1055 int maxWidth = 0; 1056 int maxHeight = 0; 1057 1058 int x = m_xMargin + kwxMacToolBarLeftMargin; 1059 int y = m_yMargin + kwxMacToolBarTopMargin; 1060 1061 node = m_tools.GetFirst(); 1062 while ( node ) 1063 { 1064 tool = (wxToolBarTool*) node->GetData(); 1065 if ( tool == NULL ) 1066 { 1067 node = node->GetNext(); 1068 continue; 1069 } 1070 1071 // set tool position: 1072 // for the moment just perform a single row/column alignment 1073 wxSize cursize = tool->GetSize(); 1074 if ( x + cursize.x > maxWidth ) 1075 maxWidth = x + cursize.x; 1076 if ( y + cursize.y > maxHeight ) 1077 maxHeight = y + cursize.y; 1078 1079 // update the item positioning state 1080 if ( !isHorizontal ) 1081 y += cursize.y + kwxMacToolSpacing; 1082 else 1083 x += cursize.x + kwxMacToolSpacing; 1084 1085 node = node->GetNext(); 1086 } 1087 1088 if ( isHorizontal ) 1089 { 1090 // if not set yet, only one row 1091 if ( m_maxRows <= 0 ) 1092 SetRows( 1 ); 1093 1094 maxWidth += m_xMargin + kwxMacToolBarLeftMargin; 1095 m_minWidth = maxWidth; 1096 m_minHeight = m_maxHeight = maxToolHeight + 2 * (m_yMargin + kwxMacToolBarTopMargin); 1097 } 1098 else 1099 { 1100 // if not set yet, have one column 1101 if ( (GetToolsCount() > 0) && (m_maxRows <= 0) ) 1102 SetRows( GetToolsCount() ); 1103 1104 maxHeight += m_yMargin + kwxMacToolBarTopMargin; 1105 m_minHeight = maxHeight; 1106 m_minWidth = m_maxWidth = maxToolWidth + 2 * (m_yMargin + kwxMacToolBarTopMargin); 1107 } 1108 1109 int totalStretchableSpace = 0; 1110 int spacePerStretchable = 0; 1111 if ( numStretchableSpaces > 0 ) 1112 { 1113 if ( isHorizontal ) 1114 totalStretchableSpace = tw - maxWidth; 1115 else 1116 totalStretchableSpace = th - maxHeight; 1117 1118 if ( totalStretchableSpace > 0 ) 1119 spacePerStretchable = totalStretchableSpace / numStretchableSpaces; 1120 } 1121 1122 // perform real positioning 1123 1124 x = m_xMargin + kwxMacToolBarLeftMargin; 1125 y = m_yMargin + kwxMacToolBarTopMargin; 1126 1127 node = m_tools.GetFirst(); 1128 int currentStretchable = 0; 1129 while ( node ) 1130 { 1131 tool = (wxToolBarTool*) node->GetData(); 1132 if ( tool == NULL ) 1133 { 1134 node = node->GetNext(); 1135 continue; 1136 } 1137 1138 wxSize cursize = tool->GetSize(); 1139 if ( tool->IsStretchableSpace() ) 1140 { 1141 ++currentStretchable; 1142 int thisSpace = currentStretchable == numStretchableSpaces ? 1143 totalStretchableSpace - (currentStretchable-1)*spacePerStretchable : 1144 spacePerStretchable; 1145 if ( isHorizontal ) 1146 cursize.x += thisSpace; 1147 else 1148 cursize.y += thisSpace; 1149 } 1150 1151 if ( !isHorizontal ) 1152 { 1153 int x1 = x + ( maxToolWidth - cursize.x ) / 2; 1154 tool->SetPosition( wxPoint(x1, y) ); 1155 } 1156 else 1157 { 1158 int y1 = y + ( maxToolHeight - cursize.y ) / 2; 1159 tool->SetPosition( wxPoint(x, y1) ); 1160 } 1161 1162 // update the item positioning state 1163 if ( !isHorizontal ) 1164 y += cursize.y + kwxMacToolSpacing; 1165 else 1166 x += cursize.x + kwxMacToolSpacing; 1167 1168 node = node->GetNext(); 1169 } 1170 1171} 1172 1173bool wxToolBar::Realize() 1174{ 1175 if ( !wxToolBarBase::Realize() ) 1176 return false; 1177 1178 wxToolBarTool *tool; 1179 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); 1180 1181#if wxOSX_USE_NATIVE_TOOLBAR 1182 CFIndex currentPosition = 0; 1183 bool insertAll = false; 1184 1185 NSToolbar* refTB = (NSToolbar*)m_macToolbar; 1186 wxFont f; 1187 wxFontEncoding enc; 1188 f = GetFont(); 1189 if ( f.IsOk() ) 1190 enc = f.GetEncoding(); 1191 else 1192 enc = wxFont::GetDefaultEncoding(); 1193 1194 node = m_tools.GetFirst(); 1195 while ( node ) 1196 { 1197 tool = (wxToolBarTool*) node->GetData(); 1198 if ( tool == NULL ) 1199 { 1200 node = node->GetNext(); 1201 continue; 1202 } 1203 1204 // install in native NSToolbar 1205 if ( refTB ) 1206 { 1207 NSToolbarItem* hiItemRef = tool->GetToolbarItemRef(); 1208 if ( hiItemRef != NULL ) 1209 { 1210 // since setting the help texts is non-virtual we have to update 1211 // the strings now 1212 wxCFStringRef sh( tool->GetShortHelp(), enc); 1213 [hiItemRef setToolTip:sh.AsNSString()]; 1214 1215 if ( insertAll || (tool->GetIndex() != currentPosition) ) 1216 { 1217 if ( !insertAll ) 1218 { 1219 insertAll = true; 1220 1221 // if this is the first tool that gets newly inserted or repositioned 1222 // first remove all 'old' tools from here to the right, because of this 1223 // all following tools will have to be reinserted (insertAll). 1224 for ( wxToolBarToolsList::compatibility_iterator node2 = m_tools.GetLast(); 1225 node2 != node; 1226 node2 = node2->GetPrevious() ) 1227 { 1228 wxToolBarTool *tool2 = (wxToolBarTool*) node2->GetData(); 1229 1230 const long idx = tool2->GetIndex(); 1231 if ( idx != -1 ) 1232 { 1233 [refTB removeItemAtIndex:idx]; 1234 tool2->SetIndex(-1); 1235 } 1236 } 1237 } 1238 1239 wxCFStringRef cfidentifier; 1240 NSString *nsItemId; 1241 if (tool->GetStyle() == wxTOOL_STYLE_SEPARATOR) 1242 { 1243 if ( tool->IsStretchable() ) 1244 nsItemId = NSToolbarFlexibleSpaceItemIdentifier; 1245 else 1246 nsItemId = NSToolbarSpaceItemIdentifier; 1247 } 1248 else 1249 { 1250 cfidentifier = wxCFStringRef(wxString::Format("%ld", (long)tool)); 1251 nsItemId = cfidentifier.AsNSString(); 1252 } 1253 1254 [refTB insertItemWithItemIdentifier:nsItemId atIndex:currentPosition]; 1255 tool->SetIndex( currentPosition ); 1256 } 1257 1258 currentPosition++; 1259 } 1260 } 1261 node = node->GetNext(); 1262 } 1263 1264#endif 1265 1266 DoLayout(); 1267 1268 // adjust radio items 1269 1270 bool lastIsRadio = false; 1271 bool curIsRadio = false; 1272 1273 node = m_tools.GetFirst(); 1274 while ( node ) 1275 { 1276 tool = (wxToolBarTool*) node->GetData(); 1277 if ( tool == NULL ) 1278 { 1279 node = node->GetNext(); 1280 continue; 1281 } 1282 1283 // update radio button (and group) state 1284 lastIsRadio = curIsRadio; 1285 curIsRadio = ( tool->IsButton() && (tool->GetKind() == wxITEM_RADIO) ); 1286 1287 if ( !curIsRadio ) 1288 { 1289 if ( tool->IsToggled() ) 1290 DoToggleTool( tool, true ); 1291 } 1292 else 1293 { 1294 if ( !lastIsRadio ) 1295 { 1296 if ( tool->Toggle( true ) ) 1297 { 1298 DoToggleTool( tool, true ); 1299 } 1300 } 1301 else if ( tool->IsToggled() ) 1302 { 1303 if ( tool->IsToggled() ) 1304 DoToggleTool( tool, true ); 1305 1306 wxToolBarToolsList::compatibility_iterator nodePrev = node->GetPrevious(); 1307 while ( nodePrev ) 1308 { 1309 wxToolBarToolBase *toggleTool = nodePrev->GetData(); 1310 if ( (toggleTool == NULL) || !toggleTool->IsButton() || (toggleTool->GetKind() != wxITEM_RADIO) ) 1311 break; 1312 1313 if ( toggleTool->Toggle( false ) ) 1314 DoToggleTool( toggleTool, false ); 1315 1316 nodePrev = nodePrev->GetPrevious(); 1317 } 1318 } 1319 } 1320 1321 node = node->GetNext(); 1322 } 1323 1324 InvalidateBestSize(); 1325 SetInitialSize( wxSize(m_minWidth, m_minHeight)); 1326 1327 SendSizeEventToParent(); 1328 1329 return true; 1330} 1331 1332void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags) 1333{ 1334 wxToolBarBase::DoSetSize(x, y, width, height, sizeFlags); 1335 1336 DoLayout(); 1337} 1338 1339void wxToolBar::SetToolBitmapSize(const wxSize& size) 1340{ 1341 m_defaultWidth = size.x + kwxMacToolBorder; 1342 m_defaultHeight = size.y + kwxMacToolBorder; 1343 1344#if wxOSX_USE_NATIVE_TOOLBAR 1345 if (m_macToolbar != NULL) 1346 { 1347 int maxs = wxMax( size.x, size.y ); 1348 NSToolbarSizeMode sizeSpec; 1349 1350 if ( maxs > 24 ) 1351 sizeSpec = NSToolbarSizeModeRegular; 1352 else 1353 sizeSpec = NSToolbarSizeModeSmall; 1354 1355 [(NSToolbar*) m_macToolbar setSizeMode:sizeSpec ]; 1356 } 1357#endif 1358} 1359 1360// The button size is bigger than the bitmap size 1361wxSize wxToolBar::GetToolSize() const 1362{ 1363 return wxSize(m_defaultWidth + kwxMacToolBorder, m_defaultHeight + kwxMacToolBorder); 1364} 1365 1366void wxToolBar::SetRows(int nRows) 1367{ 1368 // avoid resizing the frame uselessly 1369 if ( nRows != m_maxRows ) 1370 m_maxRows = nRows; 1371} 1372 1373void wxToolBar::MacSuperChangedPosition() 1374{ 1375 wxWindow::MacSuperChangedPosition(); 1376 1377 /* 1378#if wxOSX_USE_NATIVE_TOOLBAR 1379 if (! m_macUsesNativeToolbar ) 1380 Realize(); 1381#else 1382 1383 Realize(); 1384#endif 1385 */ 1386} 1387 1388void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap ) 1389{ 1390 wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id)); 1391 if ( tool ) 1392 { 1393 wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools.")); 1394 1395 tool->SetNormalBitmap(bitmap); 1396 1397 // a side-effect of the UpdateToggleImage function is that it always changes the bitmap used on the button. 1398 tool->UpdateImages(); 1399 } 1400} 1401 1402void wxToolBar::SetToolDisabledBitmap( int id, const wxBitmap& bitmap ) 1403{ 1404 wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id)); 1405 if ( tool ) 1406 { 1407 wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools.")); 1408 1409 tool->SetDisabledBitmap(bitmap); 1410 1411 // TODO: what to do for this one? 1412 } 1413} 1414 1415wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const 1416{ 1417 wxToolBarTool *tool; 1418 wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst(); 1419 while ( node ) 1420 { 1421 tool = (wxToolBarTool *)node->GetData(); 1422 if (tool != NULL) 1423 { 1424 wxRect2DInt r( tool->GetPosition(), tool->GetSize() ); 1425 if ( r.Contains( wxPoint( x, y ) ) ) 1426 return tool; 1427 } 1428 1429 node = node->GetNext(); 1430 } 1431 1432 return NULL; 1433} 1434 1435wxString wxToolBar::MacGetToolTipString( wxPoint &pt ) 1436{ 1437 wxToolBarToolBase *tool = FindToolForPosition( pt.x, pt.y ); 1438 if ( tool != NULL ) 1439 return tool->GetShortHelp(); 1440 1441 return wxEmptyString; 1442} 1443 1444void wxToolBar::DoEnableTool(wxToolBarToolBase * WXUNUSED(t), bool WXUNUSED(enable)) 1445{ 1446 // everything already done in the tool's Enable implementation 1447} 1448 1449void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle) 1450{ 1451 wxToolBarTool *tool = (wxToolBarTool *)t; 1452 if ( ( tool != NULL ) && tool->IsButton() ) 1453 tool->UpdateToggleImage( toggle ); 1454} 1455 1456bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase) 1457{ 1458 wxToolBarTool *tool = static_cast< wxToolBarTool*>(toolBase ); 1459 if (tool == NULL) 1460 return false; 1461 1462 long style = GetWindowStyleFlag(); 1463 1464 wxSize toolSize = GetToolSize(); 1465 WXWidget controlHandle = NULL; 1466 NSRect toolrect = NSMakeRect(0, 0, toolSize.x, toolSize.y + 2 ); 1467 1468#if wxOSX_USE_NATIVE_TOOLBAR 1469 wxString label = tool->GetLabel(); 1470 if (m_macToolbar && !label.empty() ) 1471 { 1472 // strip mnemonics from the label for compatibility 1473 // with the usual labels in wxStaticText sense 1474 label = wxStripMenuCodes(label); 1475 } 1476#endif // wxOSX_USE_NATIVE_TOOLBAR 1477 1478 switch (tool->GetStyle()) 1479 { 1480 case wxTOOL_STYLE_SEPARATOR: 1481 { 1482 wxASSERT( tool->GetControlHandle() == NULL ); 1483 toolSize.x /= 4; 1484 toolSize.y /= 4; 1485 if ( IsVertical() ) 1486 toolrect.size.height = toolSize.y; 1487 else 1488 toolrect.size.width = toolSize.x; 1489 1490 // in flat style we need a visual separator 1491#if wxOSX_USE_NATIVE_TOOLBAR 1492 if (m_macToolbar != NULL) 1493 { 1494 NSString * nsItemId = nil; 1495 1496 if ( tool->IsStretchable() ) 1497 nsItemId = NSToolbarFlexibleSpaceItemIdentifier; 1498 else 1499 nsItemId = NSToolbarSpaceItemIdentifier; 1500 1501 NSToolbarItem* item = [[NSToolbarItem alloc] initWithItemIdentifier:nsItemId]; 1502 tool->SetToolbarItemRef( item ); 1503 } 1504#endif // wxOSX_USE_NATIVE_TOOLBAR 1505 1506 NSBox* box = [[NSBox alloc] initWithFrame:toolrect]; 1507 [box setBoxType:NSBoxSeparator]; 1508 controlHandle = box; 1509 tool->SetControlHandle( controlHandle ); 1510 } 1511 break; 1512 1513 case wxTOOL_STYLE_BUTTON: 1514 { 1515 wxASSERT( tool->GetControlHandle() == NULL ); 1516 1517 wxNSToolBarButton* v = [[wxNSToolBarButton alloc] initWithFrame:toolrect]; 1518 1519 [v setBezelStyle:NSSmallSquareBezelStyle]; 1520 [[v cell] setControlSize:NSSmallControlSize]; 1521 [v setFont:[NSFont fontWithName:[[v font] fontName] size:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]]; 1522 [v setBordered:NO]; 1523 [v setButtonType: ( tool->CanBeToggled() ? NSToggleButton : NSMomentaryPushInButton )]; 1524 [v setImplementation:tool]; 1525 1526 controlHandle = v; 1527 1528#if wxOSX_USE_NATIVE_TOOLBAR 1529 if (m_macToolbar != NULL) 1530 { 1531 wxString identifier = wxString::Format(wxT("%ld"), (long) tool); 1532 wxCFStringRef cfidentifier( identifier, wxFont::GetDefaultEncoding() ); 1533 wxNSToolbarItem* item = [[wxNSToolbarItem alloc] initWithItemIdentifier:cfidentifier.AsNSString() ]; 1534 [item setImplementation:tool]; 1535 tool->SetToolbarItemRef( item ); 1536 } 1537 1538#endif // wxOSX_USE_NATIVE_TOOLBAR 1539 tool->SetControlHandle( controlHandle ); 1540 if ( !(style & wxTB_NOICONS) ) 1541 tool->UpdateImages(); 1542 tool->UpdateLabel(); 1543 1544#if 0 1545 InstallControlEventHandler( 1546 (WXWidget) controlHandle, GetwxMacToolBarToolEventHandlerUPP(), 1547 GetEventTypeCount(eventList), eventList, tool, NULL ); 1548#endif 1549 } 1550 break; 1551 1552 case wxTOOL_STYLE_CONTROL: 1553 1554#if wxOSX_USE_NATIVE_TOOLBAR 1555 if (m_macToolbar != NULL) 1556 { 1557 WXWidget view = (WXWidget) tool->GetControl()->GetHandle() ; 1558 wxCHECK_MSG( view, false, wxT("control must be non-NULL") ); 1559 1560 wxString identifier = wxString::Format(wxT("%ld"), (long) tool); 1561 wxCFStringRef cfidentifier( identifier, wxFont::GetDefaultEncoding() ); 1562 wxNSToolbarItem* item = [[wxNSToolbarItem alloc] initWithItemIdentifier:cfidentifier.AsNSString() ]; 1563 [item setImplementation:tool]; 1564 tool->SetToolbarItemRef( item ); 1565 } 1566#else 1567 // right now there's nothing to do here 1568#endif 1569 tool->UpdateLabel(); 1570 break; 1571 1572 default: 1573 break; 1574 } 1575 1576 if ( controlHandle ) 1577 { 1578 WXWidget container = (WXWidget) GetHandle(); 1579 wxASSERT_MSG( container != NULL, wxT("No valid Mac container control") ); 1580 1581// SetControlVisibility( controlHandle, true, true ); 1582 [container addSubview:controlHandle]; 1583 } 1584 1585 // nothing special to do here - we relayout in Realize() later 1586 InvalidateBestSize(); 1587 1588 return true; 1589 1590} 1591 1592void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle)) 1593{ 1594 wxFAIL_MSG( wxT("not implemented") ); 1595} 1596 1597bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolbase) 1598{ 1599 wxToolBarTool* tool = static_cast< wxToolBarTool*>(toolbase ); 1600 wxToolBarToolsList::compatibility_iterator node; 1601 for ( node = m_tools.GetFirst(); node; node = node->GetNext() ) 1602 { 1603 wxToolBarToolBase *tool2 = node->GetData(); 1604 if ( tool2 == tool ) 1605 { 1606 // let node point to the next node in the list 1607 node = node->GetNext(); 1608 1609 break; 1610 } 1611 } 1612 1613 wxSize sz = ((wxToolBarTool*)tool)->GetSize(); 1614 1615#if wxOSX_USE_NATIVE_TOOLBAR 1616 CFIndex removeIndex = tool->GetIndex(); 1617#endif 1618 1619#if wxOSX_USE_NATIVE_TOOLBAR 1620 if (m_macToolbar != NULL) 1621 { 1622 if ( removeIndex != -1 && m_macToolbar ) 1623 { 1624 [(NSToolbar*) m_macToolbar removeItemAtIndex:removeIndex]; 1625 tool->SetIndex( -1 ); 1626 } 1627 } 1628#endif 1629 1630 tool->ClearControl(); 1631 1632 // and finally reposition all the controls after this one 1633 1634 for ( /* node -> first after deleted */; node; node = node->GetNext() ) 1635 { 1636 wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData(); 1637 wxPoint pt = tool2->GetPosition(); 1638 1639 if ( IsVertical() ) 1640 pt.y -= sz.y; 1641 else 1642 pt.x -= sz.x; 1643 1644 tool2->SetPosition( pt ); 1645 1646#if wxOSX_USE_NATIVE_TOOLBAR 1647 if (m_macToolbar != NULL) 1648 { 1649 if ( removeIndex != -1 && tool2->GetIndex() > removeIndex ) 1650 tool2->SetIndex( tool2->GetIndex() - 1 ); 1651 } 1652#endif 1653 } 1654 1655 InvalidateBestSize(); 1656 1657 return true; 1658} 1659 1660#include <Carbon/Carbon.h> 1661 1662void wxToolBar::OnPaint(wxPaintEvent& event) 1663{ 1664#if wxOSX_USE_NATIVE_TOOLBAR 1665 if ( m_macUsesNativeToolbar ) 1666 { 1667 // nothing to do here 1668 } 1669 else 1670#endif 1671 { 1672 const int direction = GetDirection(); 1673 int w, h; 1674 GetSize( &w, &h ); 1675 1676 wxPaintDC dc(this); 1677 1678 wxRect rect(0,0,w,h); 1679 1680 // TODO determine whether to use flat appearance in earlier system 1681 if ( WX_IS_MACOS_AVAILABLE(10, 14 ) ) 1682 { 1683 // No gradient. 1684 } 1685 else 1686 { 1687 dc.GradientFillLinear( rect , wxColour( 0xCC,0xCC,0xCC ), wxColour( 0xA8,0xA8,0xA8 ) , wxSOUTH ); 1688 } 1689 1690 dc.SetPen( wxPen( wxColour( 0x51,0x51,0x51 ) ) ); 1691 1692 if ( direction == wxTB_RIGHT ) 1693 dc.DrawLine(0, 0, 0, h); 1694 else if ( direction == wxTB_LEFT ) 1695 dc.DrawLine(w-1, 0, w-1, h); 1696 else if ( direction == wxTB_BOTTOM ) 1697 dc.DrawLine(0, 0, w, 0); 1698 else if ( direction == wxTB_TOP ) 1699 dc.DrawLine(0, h-1, w, h-1); 1700 } 1701 event.Skip(); 1702} 1703 1704#if wxOSX_USE_NATIVE_TOOLBAR 1705void wxToolBar::OSXSetSelectableTools(bool set) 1706{ 1707 wxCHECK_RET( m_macToolbar, "toolbar must be non-NULL" ); 1708 [(wxNSToolbarDelegate*)[(NSToolbar*)m_macToolbar delegate] setSelectable:set]; 1709} 1710 1711void wxToolBar::OSXSelectTool(int toolId) 1712{ 1713 wxToolBarToolBase *tool = FindById(toolId); 1714 wxCHECK_RET( tool, "invalid tool ID" ); 1715 wxCHECK_RET( m_macToolbar, "toolbar must be non-NULL" ); 1716 1717 wxString identifier = wxString::Format(wxT("%ld"), (long)tool); 1718 wxCFStringRef cfidentifier(identifier, wxFont::GetDefaultEncoding()); 1719 [(NSToolbar*)m_macToolbar setSelectedItemIdentifier:cfidentifier.AsNSString()]; 1720} 1721#endif // wxOSX_USE_NATIVE_TOOLBAR 1722 1723#endif // wxUSE_TOOLBAR 1724