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