1723 lines
45 KiB
Plaintext
1723 lines
45 KiB
Plaintext
/////////////////////////////////////////////////////////////////////////////
|
|
// Name: src/osx/cocoa/toolbar.mm
|
|
// Purpose: wxToolBar
|
|
// Author: Stefan Csomor
|
|
// Modified by:
|
|
// Created: 04/01/98
|
|
// Copyright: (c) Stefan Csomor
|
|
// Licence: wxWindows licence
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
|
|
#include "wx/wxprec.h"
|
|
|
|
#if wxUSE_TOOLBAR
|
|
|
|
#ifndef WX_PRECOMP
|
|
#include "wx/wx.h"
|
|
#endif
|
|
|
|
#include "wx/toolbar.h"
|
|
#include "wx/app.h"
|
|
#include "wx/osx/private.h"
|
|
#include "wx/osx/private/available.h"
|
|
#include "wx/geometry.h"
|
|
#include "wx/sysopt.h"
|
|
|
|
const short kwxMacToolBarToolDefaultWidth = 16;
|
|
const short kwxMacToolBarToolDefaultHeight = 16;
|
|
const short kwxMacToolBarTopMargin = 4;
|
|
const short kwxMacToolBarLeftMargin = 4;
|
|
const short kwxMacToolBorder = 0;
|
|
const short kwxMacToolSpacing = 6;
|
|
|
|
wxBEGIN_EVENT_TABLE(wxToolBar, wxToolBarBase)
|
|
EVT_PAINT( wxToolBar::OnPaint )
|
|
wxEND_EVENT_TABLE()
|
|
|
|
|
|
#pragma mark -
|
|
#pragma mark Tool Implementation
|
|
|
|
// ----------------------------------------------------------------------------
|
|
// private classes
|
|
// ----------------------------------------------------------------------------
|
|
|
|
class wxToolBarTool;
|
|
|
|
@interface wxNSToolBarButton : NSButton
|
|
{
|
|
wxToolBarTool* impl;
|
|
}
|
|
|
|
- (id)initWithFrame:(NSRect)frame;
|
|
- (void) clickedAction: (id) sender;
|
|
- (void)setImplementation: (wxToolBarTool *) theImplementation;
|
|
- (wxToolBarTool*) implementation;
|
|
- (BOOL) isFlipped;
|
|
|
|
@end
|
|
|
|
// We have a dual implementation for each tool, WXWidget and NSToolbarItem*
|
|
|
|
// when embedding native controls in the native toolbar we must make sure the
|
|
// control does not get deleted behind our backs, so the retain count gets increased
|
|
// (after creation it is 1), first be the creation of the custom NSToolbarItem wrapper
|
|
// object, and second by the code 'creating' the custom HIView (which is the same as the
|
|
// already existing native control, therefore we just increase the ref count)
|
|
// when this view is removed from the native toolbar its count gets decremented again
|
|
// and when the HITooolbarItem wrapper object gets destroyed it is decremented as well
|
|
// so in the end the control lives with a refcount of one and can be disposed of by the
|
|
// wxControl code. For embedded controls on a non-native toolbar this ref count is less
|
|
// so we can only test against a range, not a specific value of the refcount.
|
|
|
|
class wxToolBarTool : public wxToolBarToolBase
|
|
{
|
|
public:
|
|
wxToolBarTool(
|
|
wxToolBar *tbar,
|
|
int id,
|
|
const wxString& label,
|
|
const wxBitmap& bmpNormal,
|
|
const wxBitmap& bmpDisabled,
|
|
wxItemKind kind,
|
|
wxObject *clientData,
|
|
const wxString& shortHelp,
|
|
const wxString& longHelp );
|
|
|
|
wxToolBarTool(wxToolBar *tbar, wxControl *control, const wxString& label)
|
|
: wxToolBarToolBase(tbar, control, label)
|
|
{
|
|
Init();
|
|
if (control != NULL)
|
|
SetControlHandle( (WXWidget) control->GetHandle() );
|
|
}
|
|
|
|
virtual ~wxToolBarTool()
|
|
{
|
|
ClearControl();
|
|
}
|
|
|
|
WXWidget GetControlHandle()
|
|
{
|
|
return (WXWidget) m_controlHandle;
|
|
}
|
|
|
|
void SetControlHandle( WXWidget handle )
|
|
{
|
|
m_controlHandle = handle;
|
|
}
|
|
|
|
void SetPosition( const wxPoint& position );
|
|
|
|
void ClearControl()
|
|
{
|
|
if ( m_controlHandle )
|
|
{
|
|
if ( !IsControl() )
|
|
{
|
|
[m_controlHandle removeFromSuperview];
|
|
[m_controlHandle release];
|
|
}
|
|
else
|
|
{
|
|
// the embedded control is not under the responsibility of the tool, it gets disposed of in the
|
|
// proper wxControl destructor
|
|
}
|
|
m_controlHandle = NULL ;
|
|
}
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if ( m_toolbarItem )
|
|
{
|
|
[m_toolbarItem release];
|
|
m_toolbarItem = NULL;
|
|
}
|
|
#endif // wxOSX_USE_NATIVE_TOOLBAR
|
|
}
|
|
|
|
wxSize GetSize() const
|
|
{
|
|
wxSize curSize;
|
|
|
|
if ( IsControl() )
|
|
{
|
|
curSize = GetControl()->GetSize();
|
|
}
|
|
else if ( IsButton() )
|
|
{
|
|
// curSize = GetToolBar()->GetToolSize();
|
|
NSRect best = [(wxNSToolBarButton*)m_controlHandle frame];
|
|
curSize = wxSize(best.size.width, best.size.height);
|
|
}
|
|
else
|
|
{
|
|
// separator size
|
|
curSize = GetToolBar()->GetToolSize();
|
|
if ( GetToolBar()->IsVertical() )
|
|
curSize.y /= 4;
|
|
else
|
|
curSize.x /= 4;
|
|
}
|
|
|
|
return curSize;
|
|
}
|
|
|
|
wxPoint GetPosition() const
|
|
{
|
|
return wxPoint( m_x, m_y );
|
|
}
|
|
|
|
bool Enable( bool enable ) wxOVERRIDE;
|
|
|
|
void UpdateImages();
|
|
|
|
void UpdateToggleImage( bool toggle );
|
|
|
|
void UpdateLabel()
|
|
{
|
|
// Use an empty string if we're not displaying text
|
|
wxString labelStr;
|
|
wxToolBar *tbar = (wxToolBar*) GetToolBar();
|
|
int style = (tbar ? tbar->GetWindowStyleFlag() : 0);
|
|
if ( (style & (wxTB_NOICONS | wxTB_TEXT)) != 0 )
|
|
labelStr = wxStripMenuCodes(m_label);
|
|
|
|
wxCFStringRef l(labelStr, GetToolBarFontEncoding());
|
|
wxCFStringRef sh( GetShortHelp(), GetToolBarFontEncoding() );
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if ( m_toolbarItem )
|
|
{
|
|
// strip mnemonics from the label for compatibility with the usual
|
|
// labels in wxStaticText sense
|
|
|
|
[m_toolbarItem setLabel:l.AsNSString()];
|
|
|
|
[m_toolbarItem setToolTip:sh.AsNSString()];
|
|
}
|
|
#endif
|
|
if ( IsButton() )
|
|
{
|
|
NSButton* const btn = (NSButton*)m_controlHandle;
|
|
|
|
[btn setTitle:l.AsNSString()];
|
|
|
|
if ( style & wxTB_NOICONS )
|
|
[btn setImagePosition:NSNoImage];
|
|
else if ( style & wxTB_TEXT )
|
|
[btn setImagePosition:NSImageAbove];
|
|
else
|
|
[btn setImagePosition:NSImageOnly];
|
|
|
|
if ( (style & (wxTB_NOICONS | wxTB_TEXT)) != 0 )
|
|
{
|
|
[btn sizeToFit];
|
|
}
|
|
else if (tbar)
|
|
{
|
|
wxSize toolsize = tbar->GetToolSize();
|
|
NSRect frame = [m_controlHandle frame];
|
|
frame.size.width = toolsize.x;
|
|
frame.size.height = toolsize.y + 2;
|
|
[btn setFrame:frame];
|
|
}
|
|
}
|
|
|
|
if ( m_controlHandle )
|
|
{
|
|
[m_controlHandle setToolTip:sh.AsNSString()];
|
|
}
|
|
}
|
|
|
|
void Action()
|
|
{
|
|
wxToolBar *tbar = (wxToolBar*) GetToolBar();
|
|
if (CanBeToggled())
|
|
{
|
|
bool shouldToggle;
|
|
|
|
shouldToggle = !IsToggled();
|
|
tbar->ToggleTool( GetId(), shouldToggle );
|
|
}
|
|
|
|
tbar->OnLeftClick( GetId(), IsToggled() );
|
|
}
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
void SetToolbarItemRef( NSToolbarItem* ref )
|
|
{
|
|
if ( m_toolbarItem )
|
|
[m_toolbarItem release];
|
|
|
|
m_toolbarItem = ref;
|
|
}
|
|
|
|
NSToolbarItem* GetToolbarItemRef() const
|
|
{
|
|
return m_toolbarItem;
|
|
}
|
|
|
|
void SetIndex( CFIndex idx )
|
|
{
|
|
m_index = idx;
|
|
}
|
|
|
|
CFIndex GetIndex() const
|
|
{
|
|
return m_index;
|
|
}
|
|
|
|
virtual void SetLabel(const wxString& label) wxOVERRIDE
|
|
{
|
|
wxToolBarToolBase::SetLabel(label);
|
|
UpdateLabel();
|
|
}
|
|
|
|
virtual bool SetShortHelp(const wxString& help) wxOVERRIDE
|
|
{
|
|
if ( !wxToolBarToolBase::SetShortHelp(help) )
|
|
return false;
|
|
|
|
UpdateLabel();
|
|
|
|
return true;
|
|
}
|
|
#endif // wxOSX_USE_NATIVE_TOOLBAR
|
|
|
|
private:
|
|
wxFontEncoding GetToolBarFontEncoding() const
|
|
{
|
|
wxFont f;
|
|
if ( GetToolBar() )
|
|
f = GetToolBar()->GetFont();
|
|
return f.IsOk() ? f.GetEncoding() : wxFont::GetDefaultEncoding();
|
|
}
|
|
|
|
void Init()
|
|
{
|
|
m_controlHandle = NULL;
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
m_toolbarItem = NULL;
|
|
m_index = -1;
|
|
#endif
|
|
}
|
|
|
|
WXWidget m_controlHandle;
|
|
wxCoord m_x;
|
|
wxCoord m_y;
|
|
wxBitmap m_alternateBitmap;
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
NSToolbarItem* m_toolbarItem;
|
|
// position in its toolbar, -1 means not inserted
|
|
CFIndex m_index;
|
|
#endif
|
|
};
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
|
|
@interface wxNSToolbarItem : NSToolbarItem
|
|
{
|
|
wxToolBarTool* impl;
|
|
}
|
|
|
|
- (id) initWithItemIdentifier: (NSString*) identifier;
|
|
- (void)setImplementation: (wxToolBarTool *) theImplementation;
|
|
- (wxToolBarTool*) implementation;
|
|
- (void) clickedAction: (id) sender;
|
|
- (BOOL) validateToolbarItem:(NSToolbarItem *)theItem;
|
|
|
|
@end
|
|
|
|
|
|
@interface wxNSToolbarDelegate : NSObject <NSToolbarDelegate>
|
|
{
|
|
bool m_isSelectable;
|
|
}
|
|
|
|
- (void)setSelectable:(bool) value;
|
|
|
|
- (NSToolbarItem *)toolbar:(NSToolbar *)toolbar itemForItemIdentifier:(NSString *)itemIdentifier willBeInsertedIntoToolbar:(BOOL)flag;
|
|
|
|
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar;
|
|
|
|
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar;
|
|
|
|
- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar;
|
|
|
|
@end
|
|
|
|
|
|
@interface wxNSToolbar : NSToolbar
|
|
{
|
|
wxNSToolbarDelegate* toolbarDelegate;
|
|
}
|
|
|
|
- (id)initWithIdentifier:(NSString *)identifier;
|
|
- (void) dealloc;
|
|
|
|
@end
|
|
|
|
#endif
|
|
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
|
|
@implementation wxNSToolbarItem
|
|
|
|
- (id)initWithItemIdentifier: (NSString*) identifier
|
|
{
|
|
if ( self = [super initWithItemIdentifier:identifier] )
|
|
{
|
|
impl = NULL;
|
|
[self setTarget: self];
|
|
[self setAction: @selector(clickedAction:)];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void) clickedAction: (id) sender
|
|
{
|
|
wxUnusedVar(sender);
|
|
if ( impl )
|
|
{
|
|
impl->Action();
|
|
}
|
|
}
|
|
|
|
- (void)setImplementation: (wxToolBarTool *) theImplementation
|
|
{
|
|
impl = theImplementation;
|
|
}
|
|
|
|
- (wxToolBarTool*) implementation
|
|
{
|
|
return impl;
|
|
}
|
|
|
|
- (BOOL)validateToolbarItem:(NSToolbarItem *)theItem
|
|
{
|
|
wxUnusedVar(theItem);
|
|
return impl->IsEnabled() ? YES:NO;
|
|
}
|
|
|
|
@end
|
|
|
|
@implementation wxNSToolbarDelegate
|
|
|
|
- (id)init
|
|
{
|
|
if ( self = [super init] )
|
|
{
|
|
m_isSelectable = false;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)setSelectable:(bool) value
|
|
{
|
|
m_isSelectable = true;
|
|
}
|
|
|
|
- (NSArray *)toolbarDefaultItemIdentifiers:(NSToolbar*)toolbar
|
|
{
|
|
wxUnusedVar(toolbar);
|
|
return nil;
|
|
}
|
|
|
|
- (NSArray *)toolbarAllowedItemIdentifiers:(NSToolbar*)toolbar
|
|
{
|
|
wxUnusedVar(toolbar);
|
|
return nil;
|
|
}
|
|
|
|
- (NSArray *)toolbarSelectableItemIdentifiers:(NSToolbar *)toolbar
|
|
{
|
|
if ( m_isSelectable )
|
|
return [[toolbar items] valueForKey:@"itemIdentifier"];
|
|
else
|
|
return nil;
|
|
}
|
|
|
|
- (NSToolbarItem*) toolbar:(NSToolbar*) toolbar itemForItemIdentifier:(NSString*) itemIdentifier willBeInsertedIntoToolbar:(BOOL) flag
|
|
{
|
|
wxUnusedVar(toolbar);
|
|
#ifdef __LP64__
|
|
wxToolBarTool* tool = (wxToolBarTool*) [itemIdentifier longLongValue];
|
|
#else
|
|
wxToolBarTool* tool = (wxToolBarTool*) [itemIdentifier intValue];
|
|
#endif
|
|
if ( tool )
|
|
{
|
|
wxNSToolbarItem* item = (wxNSToolbarItem*) tool->GetToolbarItemRef();
|
|
if ( flag && tool->IsControl() )
|
|
{
|
|
NSView* view = tool->GetControl()->GetHandle();
|
|
[view removeFromSuperview];
|
|
[item setView:view];
|
|
wxSize sz = tool->GetControl()->GetSize();
|
|
NSSize size = NSMakeSize((float)sz.x, (float)sz.y);
|
|
[item setMaxSize:size];
|
|
[item setMinSize:size];
|
|
[view setHidden:NO];
|
|
}
|
|
return item;
|
|
}
|
|
return nil;
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
@implementation wxNSToolbar
|
|
|
|
- (id)initWithIdentifier:(NSString *)identifier
|
|
{
|
|
if (self = [super initWithIdentifier:identifier])
|
|
{
|
|
toolbarDelegate = [[wxNSToolbarDelegate alloc] init];
|
|
[self setDelegate:toolbarDelegate];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)dealloc
|
|
{
|
|
[toolbarDelegate release];
|
|
[super dealloc];
|
|
}
|
|
|
|
@end
|
|
|
|
#endif
|
|
|
|
@implementation wxNSToolBarButton
|
|
|
|
- (id)initWithFrame:(NSRect)frame
|
|
{
|
|
if ( self = [super initWithFrame:frame] )
|
|
{
|
|
impl = NULL;
|
|
[self setTarget: self];
|
|
[self setAction: @selector(clickedAction:)];
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void) clickedAction: (id) sender
|
|
{
|
|
wxUnusedVar(sender);
|
|
if ( impl )
|
|
{
|
|
impl->Action();
|
|
}
|
|
}
|
|
|
|
- (void)setImplementation: (wxToolBarTool *) theImplementation
|
|
{
|
|
impl = theImplementation;
|
|
}
|
|
|
|
- (wxToolBarTool*) implementation
|
|
{
|
|
return impl;
|
|
}
|
|
|
|
- (BOOL) isFlipped
|
|
{
|
|
return YES;
|
|
}
|
|
|
|
@end
|
|
|
|
bool wxToolBarTool::Enable( bool enable )
|
|
{
|
|
if ( wxToolBarToolBase::Enable( enable ) == false )
|
|
return false;
|
|
|
|
if ( IsControl() )
|
|
{
|
|
GetControl()->Enable( enable );
|
|
}
|
|
else if ( IsButton() )
|
|
{
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if ( m_toolbarItem != NULL )
|
|
[m_toolbarItem setEnabled:enable];
|
|
#endif
|
|
|
|
if ( m_controlHandle != NULL )
|
|
[(NSControl*)m_controlHandle setEnabled:enable];
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void wxToolBarTool::SetPosition( const wxPoint& position )
|
|
{
|
|
m_x = position.x;
|
|
m_y = position.y;
|
|
|
|
int mac_x = position.x;
|
|
int mac_y = position.y;
|
|
|
|
if ( IsButton() )
|
|
{
|
|
NSRect frame = [m_controlHandle frame];
|
|
if ( frame.origin.x != mac_x || frame.origin.y != mac_y )
|
|
{
|
|
frame.origin.x = mac_x;
|
|
frame.origin.y = mac_y;
|
|
[m_controlHandle setFrame:frame];
|
|
}
|
|
}
|
|
else if ( IsControl() )
|
|
{
|
|
// embedded native controls are moved by the OS
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if ( ((wxToolBar*)GetToolBar())->MacWantsNativeToolbar() == false )
|
|
#endif
|
|
{
|
|
GetControl()->Move( position );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
NSRect frame = [m_controlHandle frame];
|
|
if ( frame.origin.x != mac_x || frame.origin.y != mac_y )
|
|
{
|
|
frame.origin.x = mac_x;
|
|
frame.origin.y = mac_y;
|
|
[m_controlHandle setFrame:frame];
|
|
}
|
|
}
|
|
}
|
|
|
|
void wxToolBarTool::UpdateImages()
|
|
{
|
|
[(NSButton*) m_controlHandle setImage:m_bmpNormal.GetNSImage()];
|
|
|
|
if ( CanBeToggled() )
|
|
{
|
|
int w = m_bmpNormal.GetScaledWidth();
|
|
int h = m_bmpNormal.GetScaledHeight();
|
|
m_alternateBitmap = wxBitmap();
|
|
m_alternateBitmap.CreateScaled(w, h, -1, m_bmpNormal.GetScaleFactor());
|
|
m_alternateBitmap.UseAlpha();
|
|
wxMemoryDC dc;
|
|
|
|
dc.SelectObject(m_alternateBitmap);
|
|
// This color corresponds to OS X Yosemite's rendering of selected toolbar items
|
|
// See also https://trac.wxwidgets.org/ticket/16645
|
|
wxColour grey(0xB9, 0xB9, 0xB9);
|
|
dc.SetBackground(*wxTRANSPARENT_BRUSH);
|
|
dc.Clear();
|
|
dc.SetPen(grey);
|
|
dc.SetBrush(grey);
|
|
dc.DrawRoundedRectangle( 0, 0, w, h, 3 );
|
|
dc.DrawBitmap( m_bmpNormal, 0, 0, true );
|
|
dc.SelectObject( wxNullBitmap );
|
|
|
|
[(NSButton*) m_controlHandle setAlternateImage:m_alternateBitmap.GetNSImage()];
|
|
}
|
|
UpdateToggleImage( CanBeToggled() && IsToggled() );
|
|
}
|
|
|
|
void wxToolBarTool::UpdateToggleImage( bool toggle )
|
|
{
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
// Avoid setting the image if we're not showing icons because the image may
|
|
// be invalid.
|
|
wxToolBar *tbar = (wxToolBar*) GetToolBar();
|
|
int style = tbar ? tbar->GetWindowStyleFlag() : 0;
|
|
if ( m_toolbarItem != NULL && !(style & wxTB_NOICONS) )
|
|
{
|
|
// the native toolbar item only has a 'selected' state (one for one toolbar)
|
|
// so we emulate the toggle here
|
|
if ( CanBeToggled() && toggle )
|
|
[m_toolbarItem setImage:m_alternateBitmap.GetNSImage()];
|
|
else
|
|
[m_toolbarItem setImage:m_bmpNormal.GetNSImage()];
|
|
}
|
|
#endif
|
|
|
|
if ( IsButton() )
|
|
[(NSButton*)m_controlHandle setState:(toggle ? NSOnState : NSOffState)];
|
|
}
|
|
|
|
wxToolBarTool::wxToolBarTool(
|
|
wxToolBar *tbar,
|
|
int id,
|
|
const wxString& label,
|
|
const wxBitmap& bmpNormal,
|
|
const wxBitmap& bmpDisabled,
|
|
wxItemKind kind,
|
|
wxObject *clientData,
|
|
const wxString& shortHelp,
|
|
const wxString& longHelp )
|
|
:
|
|
wxToolBarToolBase(
|
|
tbar, id, label, bmpNormal, bmpDisabled, kind,
|
|
clientData, shortHelp, longHelp )
|
|
{
|
|
Init();
|
|
}
|
|
|
|
#pragma mark -
|
|
#pragma mark Toolbar Implementation
|
|
|
|
wxToolBarToolBase *wxToolBar::CreateTool(
|
|
int id,
|
|
const wxString& label,
|
|
const wxBitmap& bmpNormal,
|
|
const wxBitmap& bmpDisabled,
|
|
wxItemKind kind,
|
|
wxObject *clientData,
|
|
const wxString& shortHelp,
|
|
const wxString& longHelp )
|
|
{
|
|
return new wxToolBarTool(
|
|
this, id, label, bmpNormal, bmpDisabled, kind,
|
|
clientData, shortHelp, longHelp );
|
|
}
|
|
|
|
wxToolBarToolBase *
|
|
wxToolBar::CreateTool(wxControl *control, const wxString& label)
|
|
{
|
|
return new wxToolBarTool(this, control, label);
|
|
}
|
|
|
|
void wxToolBar::Init()
|
|
{
|
|
m_maxWidth = -1;
|
|
m_maxHeight = -1;
|
|
m_defaultWidth = kwxMacToolBarToolDefaultWidth;
|
|
m_defaultHeight = kwxMacToolBarToolDefaultHeight;
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
m_macToolbar = NULL;
|
|
m_macUsesNativeToolbar = false;
|
|
#endif
|
|
}
|
|
|
|
// also for the toolbar we have the dual implementation:
|
|
// only when MacInstallNativeToolbar is called is the native toolbar set as the window toolbar
|
|
|
|
bool wxToolBar::Create(
|
|
wxWindow *parent,
|
|
wxWindowID id,
|
|
const wxPoint& pos,
|
|
const wxSize& size,
|
|
long style,
|
|
const wxString& name )
|
|
{
|
|
if ( !wxToolBarBase::Create( parent, id, pos, size, style, wxDefaultValidator, name ) )
|
|
return false;
|
|
|
|
FixupStyle();
|
|
|
|
OSStatus err = noErr;
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
|
|
if (parent->IsKindOf(CLASSINFO(wxFrame)) && wxSystemOptions::GetOptionInt(wxT("mac.toolbar.no-native")) != 1)
|
|
{
|
|
wxString identifier = wxString::Format( wxT("%p"), this );
|
|
wxCFStringRef cfidentifier(identifier);
|
|
NSToolbar* tb = [[wxNSToolbar alloc] initWithIdentifier:cfidentifier.AsNSString()];
|
|
|
|
m_macToolbar = tb ;
|
|
|
|
if (m_macToolbar != NULL)
|
|
{
|
|
NSToolbarDisplayMode mode = NSToolbarDisplayModeDefault;
|
|
NSToolbarSizeMode displaySize = NSToolbarSizeModeSmall;
|
|
|
|
if ( style & wxTB_NOICONS )
|
|
mode = NSToolbarDisplayModeLabelOnly;
|
|
else if ( style & wxTB_TEXT )
|
|
mode = NSToolbarDisplayModeIconAndLabel;
|
|
else
|
|
mode = NSToolbarDisplayModeIconOnly;
|
|
|
|
[tb setDisplayMode:mode];
|
|
[tb setSizeMode:displaySize];
|
|
}
|
|
}
|
|
#endif // wxOSX_USE_NATIVE_TOOLBAR
|
|
|
|
return (err == noErr);
|
|
}
|
|
|
|
wxToolBar::~wxToolBar()
|
|
{
|
|
// removal only works while the toolbar is there
|
|
wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
|
|
if ( frame && frame->GetToolBar() == this )
|
|
{
|
|
frame->SetToolBar(NULL);
|
|
}
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
[(NSToolbar*)m_macToolbar setDelegate:nil];
|
|
[(NSToolbar*)m_macToolbar release];
|
|
m_macToolbar = NULL;
|
|
#endif // wxOSX_USE_NATIVE_TOOLBAR
|
|
}
|
|
|
|
bool wxToolBar::Show( bool show )
|
|
{
|
|
WXWindow tlw = MacGetTopLevelWindowRef();
|
|
bool bResult = (tlw != NULL);
|
|
|
|
if (bResult)
|
|
{
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
bool ownToolbarInstalled = false;
|
|
MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
|
|
if (ownToolbarInstalled)
|
|
{
|
|
bResult = ([(NSToolbar*)m_macToolbar isVisible] != show);
|
|
if ( bResult )
|
|
[(NSToolbar*)m_macToolbar setVisible:show];
|
|
}
|
|
else
|
|
bResult = wxToolBarBase::Show( show );
|
|
#else
|
|
|
|
bResult = wxToolBarBase::Show( show );
|
|
#endif
|
|
}
|
|
|
|
return bResult;
|
|
}
|
|
|
|
bool wxToolBar::IsShown() const
|
|
{
|
|
bool bResult;
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
bool ownToolbarInstalled;
|
|
|
|
MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
|
|
if (ownToolbarInstalled)
|
|
{
|
|
bResult = [(NSToolbar*)m_macToolbar isVisible];
|
|
}
|
|
else
|
|
bResult = wxToolBarBase::IsShown();
|
|
#else
|
|
|
|
bResult = wxToolBarBase::IsShown();
|
|
#endif
|
|
|
|
return bResult;
|
|
}
|
|
|
|
void wxToolBar::DoGetSize( int *width, int *height ) const
|
|
{
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
bool ownToolbarInstalled;
|
|
|
|
MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
|
|
if ( ownToolbarInstalled )
|
|
{
|
|
WXWindow tlw = MacGetTopLevelWindowRef();
|
|
float toolbarHeight = 0.0;
|
|
NSRect windowFrame = NSMakeRect(0, 0, 0, 0);
|
|
|
|
if(m_macToolbar && [(NSToolbar*)m_macToolbar isVisible])
|
|
{
|
|
windowFrame = [NSWindow contentRectForFrameRect:[tlw frame]
|
|
styleMask:[tlw styleMask]];
|
|
toolbarHeight = NSHeight(windowFrame)
|
|
- NSHeight([[tlw contentView] frame]);
|
|
}
|
|
|
|
if ( width != NULL )
|
|
*width = (int)windowFrame.size.width;
|
|
if ( height != NULL )
|
|
*height = (int)toolbarHeight;
|
|
}
|
|
else
|
|
wxToolBarBase::DoGetSize( width, height );
|
|
|
|
#else
|
|
wxToolBarBase::DoGetSize( width, height );
|
|
#endif
|
|
}
|
|
|
|
void wxToolBar::DoGetPosition(int*x, int *y) const
|
|
{
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
bool ownToolbarInstalled;
|
|
|
|
MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
|
|
if ( ownToolbarInstalled )
|
|
{
|
|
WXWindow tlw = MacGetTopLevelWindowRef();
|
|
float toolbarHeight = 0.0;
|
|
NSRect windowFrame = NSMakeRect(0, 0, 0, 0);
|
|
|
|
if(m_macToolbar && [(NSToolbar*)m_macToolbar isVisible])
|
|
{
|
|
windowFrame = [NSWindow contentRectForFrameRect:[tlw frame]
|
|
styleMask:[tlw styleMask]];
|
|
toolbarHeight = NSHeight(windowFrame)
|
|
- NSHeight([[tlw contentView] frame]);
|
|
}
|
|
|
|
// it is extending to the north of the content area
|
|
|
|
if ( x != NULL )
|
|
*x = 0;
|
|
if ( y != NULL )
|
|
*y = -toolbarHeight;
|
|
}
|
|
else
|
|
wxToolBarBase::DoGetPosition( x, y );
|
|
|
|
#else
|
|
wxToolBarBase::DoGetPosition( x, y );
|
|
#endif
|
|
}
|
|
|
|
wxSize wxToolBar::DoGetBestSize() const
|
|
{
|
|
// was updated in Realize()
|
|
|
|
wxSize size = GetMinSize();
|
|
|
|
return size;
|
|
}
|
|
|
|
void wxToolBar::SetWindowStyleFlag( long style )
|
|
{
|
|
wxToolBarBase::SetWindowStyleFlag( style );
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if (m_macToolbar != NULL)
|
|
{
|
|
NSToolbarDisplayMode mode = NSToolbarDisplayModeDefault;
|
|
|
|
if ( style & wxTB_NOICONS )
|
|
mode = NSToolbarDisplayModeLabelOnly;
|
|
else if ( style & wxTB_TEXT )
|
|
mode = NSToolbarDisplayModeIconAndLabel;
|
|
else
|
|
mode = NSToolbarDisplayModeIconOnly;
|
|
|
|
[(NSToolbar*) m_macToolbar setDisplayMode:mode];
|
|
}
|
|
#endif
|
|
|
|
wxToolBarTool *tool;
|
|
wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
|
|
while ( node )
|
|
{
|
|
tool = (wxToolBarTool *) node->GetData();
|
|
if ( tool != NULL )
|
|
{
|
|
tool->UpdateLabel();
|
|
}
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
InvalidateBestSize();
|
|
}
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
bool wxToolBar::MacWantsNativeToolbar()
|
|
{
|
|
return m_macUsesNativeToolbar;
|
|
}
|
|
|
|
bool wxToolBar::MacTopLevelHasNativeToolbar(bool *ownToolbarInstalled) const
|
|
{
|
|
bool bResultV = false;
|
|
|
|
if (ownToolbarInstalled != NULL)
|
|
*ownToolbarInstalled = false;
|
|
|
|
WXWindow tlw = MacGetTopLevelWindowRef();
|
|
if (tlw != NULL)
|
|
{
|
|
NSToolbar* curToolbarRef = [tlw toolbar];
|
|
bResultV = (curToolbarRef != NULL);
|
|
if (bResultV && (ownToolbarInstalled != NULL))
|
|
*ownToolbarInstalled = (curToolbarRef == m_macToolbar);
|
|
}
|
|
|
|
return bResultV;
|
|
}
|
|
|
|
bool wxToolBar::MacInstallNativeToolbar(bool usesNative)
|
|
{
|
|
bool bResult = false;
|
|
|
|
if (usesNative && (m_macToolbar == NULL))
|
|
return bResult;
|
|
|
|
if (usesNative && HasFlag(wxTB_LEFT|wxTB_RIGHT|wxTB_BOTTOM) )
|
|
return bResult;
|
|
|
|
WXWindow tlw = MacGetTopLevelWindowRef();
|
|
if (tlw == NULL)
|
|
return bResult;
|
|
|
|
// check the existing toolbar
|
|
NSToolbar* curToolbarRef = [tlw toolbar];
|
|
|
|
m_macUsesNativeToolbar = usesNative;
|
|
|
|
if (m_macUsesNativeToolbar)
|
|
{
|
|
// only install toolbar if there isn't one installed already
|
|
if (curToolbarRef == NULL)
|
|
{
|
|
bResult = true;
|
|
[tlw setToolbar:(NSToolbar*) m_macToolbar];
|
|
[(NSToolbar*) m_macToolbar setVisible:YES];
|
|
|
|
GetPeer()->Move(0,0,0,0 );
|
|
SetSize( wxSIZE_AUTO_WIDTH, 0 );
|
|
GetPeer()->SetVisibility( false );
|
|
wxToolBarBase::Show( false );
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// only deinstall toolbar if this is the installed one
|
|
if (m_macToolbar == curToolbarRef)
|
|
{
|
|
bResult = true;
|
|
[(NSToolbar*) m_macToolbar setVisible:NO];
|
|
MacUninstallNativeToolbar();
|
|
GetPeer()->SetVisibility( true );
|
|
}
|
|
}
|
|
|
|
if (bResult)
|
|
InvalidateBestSize();
|
|
|
|
// wxLogDebug( wxT(" --> [%lx] - result [%s]"), (long)this, bResult ? wxT("T") : wxT("F") );
|
|
return bResult;
|
|
}
|
|
|
|
void wxToolBar::MacUninstallNativeToolbar()
|
|
{
|
|
if (!m_macToolbar)
|
|
return;
|
|
|
|
WXWindow tlw = MacGetTopLevelWindowRef();
|
|
if (tlw)
|
|
[tlw setToolbar:nil];
|
|
}
|
|
#endif
|
|
|
|
void wxToolBar::DoLayout()
|
|
{
|
|
int maxToolWidth = 0;
|
|
int maxToolHeight = 0;
|
|
|
|
int tw, th;
|
|
GetSize( &tw, &th );
|
|
|
|
// find the maximum tool width and height
|
|
// and the number of stretchable items
|
|
int numStretchableSpaces = 0;
|
|
wxToolBarTool *tool;
|
|
wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
|
|
while ( node )
|
|
{
|
|
tool = (wxToolBarTool *) node->GetData();
|
|
if ( tool != NULL )
|
|
{
|
|
wxSize sz = tool->GetSize();
|
|
|
|
if ( sz.x > maxToolWidth )
|
|
maxToolWidth = sz.x;
|
|
if ( sz.y > maxToolHeight )
|
|
maxToolHeight = sz.y;
|
|
if ( tool->IsStretchableSpace() )
|
|
numStretchableSpaces++;
|
|
}
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
// layout non-native toolbar
|
|
|
|
bool isHorizontal = !IsVertical();
|
|
|
|
int maxWidth = 0;
|
|
int maxHeight = 0;
|
|
|
|
int x = m_xMargin + kwxMacToolBarLeftMargin;
|
|
int y = m_yMargin + kwxMacToolBarTopMargin;
|
|
|
|
node = m_tools.GetFirst();
|
|
while ( node )
|
|
{
|
|
tool = (wxToolBarTool*) node->GetData();
|
|
if ( tool == NULL )
|
|
{
|
|
node = node->GetNext();
|
|
continue;
|
|
}
|
|
|
|
// set tool position:
|
|
// for the moment just perform a single row/column alignment
|
|
wxSize cursize = tool->GetSize();
|
|
if ( x + cursize.x > maxWidth )
|
|
maxWidth = x + cursize.x;
|
|
if ( y + cursize.y > maxHeight )
|
|
maxHeight = y + cursize.y;
|
|
|
|
// update the item positioning state
|
|
if ( !isHorizontal )
|
|
y += cursize.y + kwxMacToolSpacing;
|
|
else
|
|
x += cursize.x + kwxMacToolSpacing;
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
if ( isHorizontal )
|
|
{
|
|
// if not set yet, only one row
|
|
if ( m_maxRows <= 0 )
|
|
SetRows( 1 );
|
|
|
|
maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
|
|
m_minWidth = maxWidth;
|
|
m_minHeight = m_maxHeight = maxToolHeight + 2 * (m_yMargin + kwxMacToolBarTopMargin);
|
|
}
|
|
else
|
|
{
|
|
// if not set yet, have one column
|
|
if ( (GetToolsCount() > 0) && (m_maxRows <= 0) )
|
|
SetRows( GetToolsCount() );
|
|
|
|
maxHeight += m_yMargin + kwxMacToolBarTopMargin;
|
|
m_minHeight = maxHeight;
|
|
m_minWidth = m_maxWidth = maxToolWidth + 2 * (m_yMargin + kwxMacToolBarTopMargin);
|
|
}
|
|
|
|
int totalStretchableSpace = 0;
|
|
int spacePerStretchable = 0;
|
|
if ( numStretchableSpaces > 0 )
|
|
{
|
|
if ( isHorizontal )
|
|
totalStretchableSpace = tw - maxWidth;
|
|
else
|
|
totalStretchableSpace = th - maxHeight;
|
|
|
|
if ( totalStretchableSpace > 0 )
|
|
spacePerStretchable = totalStretchableSpace / numStretchableSpaces;
|
|
}
|
|
|
|
// perform real positioning
|
|
|
|
x = m_xMargin + kwxMacToolBarLeftMargin;
|
|
y = m_yMargin + kwxMacToolBarTopMargin;
|
|
|
|
node = m_tools.GetFirst();
|
|
int currentStretchable = 0;
|
|
while ( node )
|
|
{
|
|
tool = (wxToolBarTool*) node->GetData();
|
|
if ( tool == NULL )
|
|
{
|
|
node = node->GetNext();
|
|
continue;
|
|
}
|
|
|
|
wxSize cursize = tool->GetSize();
|
|
if ( tool->IsStretchableSpace() )
|
|
{
|
|
++currentStretchable;
|
|
int thisSpace = currentStretchable == numStretchableSpaces ?
|
|
totalStretchableSpace - (currentStretchable-1)*spacePerStretchable :
|
|
spacePerStretchable;
|
|
if ( isHorizontal )
|
|
cursize.x += thisSpace;
|
|
else
|
|
cursize.y += thisSpace;
|
|
}
|
|
|
|
if ( !isHorizontal )
|
|
{
|
|
int x1 = x + ( maxToolWidth - cursize.x ) / 2;
|
|
tool->SetPosition( wxPoint(x1, y) );
|
|
}
|
|
else
|
|
{
|
|
int y1 = y + ( maxToolHeight - cursize.y ) / 2;
|
|
tool->SetPosition( wxPoint(x, y1) );
|
|
}
|
|
|
|
// update the item positioning state
|
|
if ( !isHorizontal )
|
|
y += cursize.y + kwxMacToolSpacing;
|
|
else
|
|
x += cursize.x + kwxMacToolSpacing;
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
}
|
|
|
|
bool wxToolBar::Realize()
|
|
{
|
|
if ( !wxToolBarBase::Realize() )
|
|
return false;
|
|
|
|
wxToolBarTool *tool;
|
|
wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
CFIndex currentPosition = 0;
|
|
bool insertAll = false;
|
|
|
|
NSToolbar* refTB = (NSToolbar*)m_macToolbar;
|
|
wxFont f;
|
|
wxFontEncoding enc;
|
|
f = GetFont();
|
|
if ( f.IsOk() )
|
|
enc = f.GetEncoding();
|
|
else
|
|
enc = wxFont::GetDefaultEncoding();
|
|
|
|
node = m_tools.GetFirst();
|
|
while ( node )
|
|
{
|
|
tool = (wxToolBarTool*) node->GetData();
|
|
if ( tool == NULL )
|
|
{
|
|
node = node->GetNext();
|
|
continue;
|
|
}
|
|
|
|
// install in native NSToolbar
|
|
if ( refTB )
|
|
{
|
|
NSToolbarItem* hiItemRef = tool->GetToolbarItemRef();
|
|
if ( hiItemRef != NULL )
|
|
{
|
|
// since setting the help texts is non-virtual we have to update
|
|
// the strings now
|
|
wxCFStringRef sh( tool->GetShortHelp(), enc);
|
|
[hiItemRef setToolTip:sh.AsNSString()];
|
|
|
|
if ( insertAll || (tool->GetIndex() != currentPosition) )
|
|
{
|
|
if ( !insertAll )
|
|
{
|
|
insertAll = true;
|
|
|
|
// if this is the first tool that gets newly inserted or repositioned
|
|
// first remove all 'old' tools from here to the right, because of this
|
|
// all following tools will have to be reinserted (insertAll).
|
|
for ( wxToolBarToolsList::compatibility_iterator node2 = m_tools.GetLast();
|
|
node2 != node;
|
|
node2 = node2->GetPrevious() )
|
|
{
|
|
wxToolBarTool *tool2 = (wxToolBarTool*) node2->GetData();
|
|
|
|
const long idx = tool2->GetIndex();
|
|
if ( idx != -1 )
|
|
{
|
|
[refTB removeItemAtIndex:idx];
|
|
tool2->SetIndex(-1);
|
|
}
|
|
}
|
|
}
|
|
|
|
wxCFStringRef cfidentifier;
|
|
NSString *nsItemId;
|
|
if (tool->GetStyle() == wxTOOL_STYLE_SEPARATOR)
|
|
{
|
|
if ( tool->IsStretchable() )
|
|
nsItemId = NSToolbarFlexibleSpaceItemIdentifier;
|
|
else
|
|
nsItemId = NSToolbarSpaceItemIdentifier;
|
|
}
|
|
else
|
|
{
|
|
cfidentifier = wxCFStringRef(wxString::Format("%ld", (long)tool));
|
|
nsItemId = cfidentifier.AsNSString();
|
|
}
|
|
|
|
[refTB insertItemWithItemIdentifier:nsItemId atIndex:currentPosition];
|
|
tool->SetIndex( currentPosition );
|
|
}
|
|
|
|
currentPosition++;
|
|
}
|
|
}
|
|
node = node->GetNext();
|
|
}
|
|
|
|
#endif
|
|
|
|
DoLayout();
|
|
|
|
// adjust radio items
|
|
|
|
bool lastIsRadio = false;
|
|
bool curIsRadio = false;
|
|
|
|
node = m_tools.GetFirst();
|
|
while ( node )
|
|
{
|
|
tool = (wxToolBarTool*) node->GetData();
|
|
if ( tool == NULL )
|
|
{
|
|
node = node->GetNext();
|
|
continue;
|
|
}
|
|
|
|
// update radio button (and group) state
|
|
lastIsRadio = curIsRadio;
|
|
curIsRadio = ( tool->IsButton() && (tool->GetKind() == wxITEM_RADIO) );
|
|
|
|
if ( !curIsRadio )
|
|
{
|
|
if ( tool->IsToggled() )
|
|
DoToggleTool( tool, true );
|
|
}
|
|
else
|
|
{
|
|
if ( !lastIsRadio )
|
|
{
|
|
if ( tool->Toggle( true ) )
|
|
{
|
|
DoToggleTool( tool, true );
|
|
}
|
|
}
|
|
else if ( tool->IsToggled() )
|
|
{
|
|
if ( tool->IsToggled() )
|
|
DoToggleTool( tool, true );
|
|
|
|
wxToolBarToolsList::compatibility_iterator nodePrev = node->GetPrevious();
|
|
while ( nodePrev )
|
|
{
|
|
wxToolBarToolBase *toggleTool = nodePrev->GetData();
|
|
if ( (toggleTool == NULL) || !toggleTool->IsButton() || (toggleTool->GetKind() != wxITEM_RADIO) )
|
|
break;
|
|
|
|
if ( toggleTool->Toggle( false ) )
|
|
DoToggleTool( toggleTool, false );
|
|
|
|
nodePrev = nodePrev->GetPrevious();
|
|
}
|
|
}
|
|
}
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
InvalidateBestSize();
|
|
SetInitialSize( wxSize(m_minWidth, m_minHeight));
|
|
|
|
SendSizeEventToParent();
|
|
|
|
return true;
|
|
}
|
|
|
|
void wxToolBar::DoSetSize(int x, int y, int width, int height, int sizeFlags)
|
|
{
|
|
wxToolBarBase::DoSetSize(x, y, width, height, sizeFlags);
|
|
|
|
DoLayout();
|
|
}
|
|
|
|
void wxToolBar::SetToolBitmapSize(const wxSize& size)
|
|
{
|
|
m_defaultWidth = size.x + kwxMacToolBorder;
|
|
m_defaultHeight = size.y + kwxMacToolBorder;
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if (m_macToolbar != NULL)
|
|
{
|
|
int maxs = wxMax( size.x, size.y );
|
|
NSToolbarSizeMode sizeSpec;
|
|
|
|
if ( maxs > 24 )
|
|
sizeSpec = NSToolbarSizeModeRegular;
|
|
else
|
|
sizeSpec = NSToolbarSizeModeSmall;
|
|
|
|
[(NSToolbar*) m_macToolbar setSizeMode:sizeSpec ];
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// The button size is bigger than the bitmap size
|
|
wxSize wxToolBar::GetToolSize() const
|
|
{
|
|
return wxSize(m_defaultWidth + kwxMacToolBorder, m_defaultHeight + kwxMacToolBorder);
|
|
}
|
|
|
|
void wxToolBar::SetRows(int nRows)
|
|
{
|
|
// avoid resizing the frame uselessly
|
|
if ( nRows != m_maxRows )
|
|
m_maxRows = nRows;
|
|
}
|
|
|
|
void wxToolBar::MacSuperChangedPosition()
|
|
{
|
|
wxWindow::MacSuperChangedPosition();
|
|
|
|
/*
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if (! m_macUsesNativeToolbar )
|
|
Realize();
|
|
#else
|
|
|
|
Realize();
|
|
#endif
|
|
*/
|
|
}
|
|
|
|
void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap )
|
|
{
|
|
wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id));
|
|
if ( tool )
|
|
{
|
|
wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
|
|
|
|
tool->SetNormalBitmap(bitmap);
|
|
|
|
// a side-effect of the UpdateToggleImage function is that it always changes the bitmap used on the button.
|
|
tool->UpdateImages();
|
|
}
|
|
}
|
|
|
|
void wxToolBar::SetToolDisabledBitmap( int id, const wxBitmap& bitmap )
|
|
{
|
|
wxToolBarTool* tool = static_cast<wxToolBarTool*>(FindById(id));
|
|
if ( tool )
|
|
{
|
|
wxCHECK_RET( tool->IsButton(), wxT("Can only set bitmap on button tools."));
|
|
|
|
tool->SetDisabledBitmap(bitmap);
|
|
|
|
// TODO: what to do for this one?
|
|
}
|
|
}
|
|
|
|
wxToolBarToolBase *wxToolBar::FindToolForPosition(wxCoord x, wxCoord y) const
|
|
{
|
|
wxToolBarTool *tool;
|
|
wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
|
|
while ( node )
|
|
{
|
|
tool = (wxToolBarTool *)node->GetData();
|
|
if (tool != NULL)
|
|
{
|
|
wxRect2DInt r( tool->GetPosition(), tool->GetSize() );
|
|
if ( r.Contains( wxPoint( x, y ) ) )
|
|
return tool;
|
|
}
|
|
|
|
node = node->GetNext();
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
wxString wxToolBar::MacGetToolTipString( wxPoint &pt )
|
|
{
|
|
wxToolBarToolBase *tool = FindToolForPosition( pt.x, pt.y );
|
|
if ( tool != NULL )
|
|
return tool->GetShortHelp();
|
|
|
|
return wxEmptyString;
|
|
}
|
|
|
|
void wxToolBar::DoEnableTool(wxToolBarToolBase * WXUNUSED(t), bool WXUNUSED(enable))
|
|
{
|
|
// everything already done in the tool's Enable implementation
|
|
}
|
|
|
|
void wxToolBar::DoToggleTool(wxToolBarToolBase *t, bool toggle)
|
|
{
|
|
wxToolBarTool *tool = (wxToolBarTool *)t;
|
|
if ( ( tool != NULL ) && tool->IsButton() )
|
|
tool->UpdateToggleImage( toggle );
|
|
}
|
|
|
|
bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
|
|
{
|
|
wxToolBarTool *tool = static_cast< wxToolBarTool*>(toolBase );
|
|
if (tool == NULL)
|
|
return false;
|
|
|
|
long style = GetWindowStyleFlag();
|
|
|
|
wxSize toolSize = GetToolSize();
|
|
WXWidget controlHandle = NULL;
|
|
NSRect toolrect = NSMakeRect(0, 0, toolSize.x, toolSize.y + 2 );
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
wxString label = tool->GetLabel();
|
|
if (m_macToolbar && !label.empty() )
|
|
{
|
|
// strip mnemonics from the label for compatibility
|
|
// with the usual labels in wxStaticText sense
|
|
label = wxStripMenuCodes(label);
|
|
}
|
|
#endif // wxOSX_USE_NATIVE_TOOLBAR
|
|
|
|
switch (tool->GetStyle())
|
|
{
|
|
case wxTOOL_STYLE_SEPARATOR:
|
|
{
|
|
wxASSERT( tool->GetControlHandle() == NULL );
|
|
toolSize.x /= 4;
|
|
toolSize.y /= 4;
|
|
if ( IsVertical() )
|
|
toolrect.size.height = toolSize.y;
|
|
else
|
|
toolrect.size.width = toolSize.x;
|
|
|
|
// in flat style we need a visual separator
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if (m_macToolbar != NULL)
|
|
{
|
|
NSString * nsItemId = nil;
|
|
|
|
if ( tool->IsStretchable() )
|
|
nsItemId = NSToolbarFlexibleSpaceItemIdentifier;
|
|
else
|
|
nsItemId = NSToolbarSpaceItemIdentifier;
|
|
|
|
NSToolbarItem* item = [[NSToolbarItem alloc] initWithItemIdentifier:nsItemId];
|
|
tool->SetToolbarItemRef( item );
|
|
}
|
|
#endif // wxOSX_USE_NATIVE_TOOLBAR
|
|
|
|
NSBox* box = [[NSBox alloc] initWithFrame:toolrect];
|
|
[box setBoxType:NSBoxSeparator];
|
|
controlHandle = box;
|
|
tool->SetControlHandle( controlHandle );
|
|
}
|
|
break;
|
|
|
|
case wxTOOL_STYLE_BUTTON:
|
|
{
|
|
wxASSERT( tool->GetControlHandle() == NULL );
|
|
|
|
wxNSToolBarButton* v = [[wxNSToolBarButton alloc] initWithFrame:toolrect];
|
|
|
|
[v setBezelStyle:NSSmallSquareBezelStyle];
|
|
[[v cell] setControlSize:NSSmallControlSize];
|
|
[v setFont:[NSFont fontWithName:[[v font] fontName] size:[NSFont systemFontSizeForControlSize:NSSmallControlSize]]];
|
|
[v setBordered:NO];
|
|
[v setButtonType: ( tool->CanBeToggled() ? NSToggleButton : NSMomentaryPushInButton )];
|
|
[v setImplementation:tool];
|
|
|
|
controlHandle = v;
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if (m_macToolbar != NULL)
|
|
{
|
|
wxString identifier = wxString::Format(wxT("%ld"), (long) tool);
|
|
wxCFStringRef cfidentifier( identifier, wxFont::GetDefaultEncoding() );
|
|
wxNSToolbarItem* item = [[wxNSToolbarItem alloc] initWithItemIdentifier:cfidentifier.AsNSString() ];
|
|
[item setImplementation:tool];
|
|
tool->SetToolbarItemRef( item );
|
|
}
|
|
|
|
#endif // wxOSX_USE_NATIVE_TOOLBAR
|
|
tool->SetControlHandle( controlHandle );
|
|
if ( !(style & wxTB_NOICONS) )
|
|
tool->UpdateImages();
|
|
tool->UpdateLabel();
|
|
|
|
#if 0
|
|
InstallControlEventHandler(
|
|
(WXWidget) controlHandle, GetwxMacToolBarToolEventHandlerUPP(),
|
|
GetEventTypeCount(eventList), eventList, tool, NULL );
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
case wxTOOL_STYLE_CONTROL:
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if (m_macToolbar != NULL)
|
|
{
|
|
WXWidget view = (WXWidget) tool->GetControl()->GetHandle() ;
|
|
wxCHECK_MSG( view, false, wxT("control must be non-NULL") );
|
|
|
|
wxString identifier = wxString::Format(wxT("%ld"), (long) tool);
|
|
wxCFStringRef cfidentifier( identifier, wxFont::GetDefaultEncoding() );
|
|
wxNSToolbarItem* item = [[wxNSToolbarItem alloc] initWithItemIdentifier:cfidentifier.AsNSString() ];
|
|
[item setImplementation:tool];
|
|
tool->SetToolbarItemRef( item );
|
|
}
|
|
#else
|
|
// right now there's nothing to do here
|
|
#endif
|
|
tool->UpdateLabel();
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if ( controlHandle )
|
|
{
|
|
WXWidget container = (WXWidget) GetHandle();
|
|
wxASSERT_MSG( container != NULL, wxT("No valid Mac container control") );
|
|
|
|
// SetControlVisibility( controlHandle, true, true );
|
|
[container addSubview:controlHandle];
|
|
}
|
|
|
|
// nothing special to do here - we relayout in Realize() later
|
|
InvalidateBestSize();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
void wxToolBar::DoSetToggle(wxToolBarToolBase *WXUNUSED(tool), bool WXUNUSED(toggle))
|
|
{
|
|
wxFAIL_MSG( wxT("not implemented") );
|
|
}
|
|
|
|
bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolbase)
|
|
{
|
|
wxToolBarTool* tool = static_cast< wxToolBarTool*>(toolbase );
|
|
wxToolBarToolsList::compatibility_iterator node;
|
|
for ( node = m_tools.GetFirst(); node; node = node->GetNext() )
|
|
{
|
|
wxToolBarToolBase *tool2 = node->GetData();
|
|
if ( tool2 == tool )
|
|
{
|
|
// let node point to the next node in the list
|
|
node = node->GetNext();
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
wxSize sz = ((wxToolBarTool*)tool)->GetSize();
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
CFIndex removeIndex = tool->GetIndex();
|
|
#endif
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if (m_macToolbar != NULL)
|
|
{
|
|
if ( removeIndex != -1 && m_macToolbar )
|
|
{
|
|
[(NSToolbar*) m_macToolbar removeItemAtIndex:removeIndex];
|
|
tool->SetIndex( -1 );
|
|
}
|
|
}
|
|
#endif
|
|
|
|
tool->ClearControl();
|
|
|
|
// and finally reposition all the controls after this one
|
|
|
|
for ( /* node -> first after deleted */; node; node = node->GetNext() )
|
|
{
|
|
wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
|
|
wxPoint pt = tool2->GetPosition();
|
|
|
|
if ( IsVertical() )
|
|
pt.y -= sz.y;
|
|
else
|
|
pt.x -= sz.x;
|
|
|
|
tool2->SetPosition( pt );
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if (m_macToolbar != NULL)
|
|
{
|
|
if ( removeIndex != -1 && tool2->GetIndex() > removeIndex )
|
|
tool2->SetIndex( tool2->GetIndex() - 1 );
|
|
}
|
|
#endif
|
|
}
|
|
|
|
InvalidateBestSize();
|
|
|
|
return true;
|
|
}
|
|
|
|
#include <Carbon/Carbon.h>
|
|
|
|
void wxToolBar::OnPaint(wxPaintEvent& event)
|
|
{
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
if ( m_macUsesNativeToolbar )
|
|
{
|
|
// nothing to do here
|
|
}
|
|
else
|
|
#endif
|
|
{
|
|
const int direction = GetDirection();
|
|
int w, h;
|
|
GetSize( &w, &h );
|
|
|
|
wxPaintDC dc(this);
|
|
|
|
wxRect rect(0,0,w,h);
|
|
|
|
// TODO determine whether to use flat appearance in earlier system
|
|
if ( WX_IS_MACOS_AVAILABLE(10, 14 ) )
|
|
{
|
|
// No gradient.
|
|
}
|
|
else
|
|
{
|
|
dc.GradientFillLinear( rect , wxColour( 0xCC,0xCC,0xCC ), wxColour( 0xA8,0xA8,0xA8 ) , wxSOUTH );
|
|
}
|
|
|
|
dc.SetPen( wxPen( wxColour( 0x51,0x51,0x51 ) ) );
|
|
|
|
if ( direction == wxTB_RIGHT )
|
|
dc.DrawLine(0, 0, 0, h);
|
|
else if ( direction == wxTB_LEFT )
|
|
dc.DrawLine(w-1, 0, w-1, h);
|
|
else if ( direction == wxTB_BOTTOM )
|
|
dc.DrawLine(0, 0, w, 0);
|
|
else if ( direction == wxTB_TOP )
|
|
dc.DrawLine(0, h-1, w, h-1);
|
|
}
|
|
event.Skip();
|
|
}
|
|
|
|
#if wxOSX_USE_NATIVE_TOOLBAR
|
|
void wxToolBar::OSXSetSelectableTools(bool set)
|
|
{
|
|
wxCHECK_RET( m_macToolbar, "toolbar must be non-NULL" );
|
|
[(wxNSToolbarDelegate*)[(NSToolbar*)m_macToolbar delegate] setSelectable:set];
|
|
}
|
|
|
|
void wxToolBar::OSXSelectTool(int toolId)
|
|
{
|
|
wxToolBarToolBase *tool = FindById(toolId);
|
|
wxCHECK_RET( tool, "invalid tool ID" );
|
|
wxCHECK_RET( m_macToolbar, "toolbar must be non-NULL" );
|
|
|
|
wxString identifier = wxString::Format(wxT("%ld"), (long)tool);
|
|
wxCFStringRef cfidentifier(identifier, wxFont::GetDefaultEncoding());
|
|
[(NSToolbar*)m_macToolbar setSelectedItemIdentifier:cfidentifier.AsNSString()];
|
|
}
|
|
#endif // wxOSX_USE_NATIVE_TOOLBAR
|
|
|
|
#endif // wxUSE_TOOLBAR
|