/////////////////////////////////////////////////////////////////////////////
-// Name: src/osx/carbon/toolbar.cpp
+// Name: src/osx/cocoa/toolbar.mm
// Purpose: wxToolBar
// Author: Stefan Csomor
// Modified by:
// Created: 04/01/98
-// RCS-ID: $Id: toolbar.cpp 54954 2008-08-03 11:27:03Z VZ $
+// RCS-ID: $Id$
// Copyright: (c) Stefan Csomor
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
// 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
}
else if ( IsButton() )
{
- curSize = GetToolBar()->GetToolSize();
+ // 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()->GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT) )
+ if ( GetToolBar()->IsVertical() )
curSize.y /= 4;
else
curSize.x /= 4;
void UpdateLabel()
{
+ wxString 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
- wxString labelStr = wxStripMenuCodes(m_label);
- wxCFStringRef l(labelStr, GetToolBarFontEncoding());
[m_toolbarItem setLabel:l.AsNSString()];
- wxCFStringRef sh( GetShortHelp(), GetToolBarFontEncoding() );
[m_toolbarItem setToolTip:sh.AsNSString()];
}
#endif
+ if ( IsButton() )
+ [(NSButton*)m_controlHandle setTitle:l.AsNSString()];
+
}
void Action()
#endif
-@interface wxNSToolBarButton : NSButton
-{
- wxToolBarTool* impl;
-}
-
-- (id)initWithFrame:(NSRect)frame;
-- (void) clickedAction: (id) sender;
-- (void)setImplementation: (wxToolBarTool *) theImplementation;
-- (wxToolBarTool*) implementation;
-- (BOOL) isFlipped;
-
-@end
-
#if wxOSX_USE_NATIVE_TOOLBAR
@implementation wxNSToolbarItem
- (id)initWithItemIdentifier: (NSString*) identifier
{
- [super initWithItemIdentifier:identifier];
+ self = [super initWithItemIdentifier:identifier];
impl = NULL;
[self setTarget: self];
[self setAction: @selector(clickedAction:)];
- (id)initWithFrame:(NSRect)frame
{
- [super initWithFrame:frame];
+ self = [super initWithFrame:frame];
impl = NULL;
[self setTarget: self];
[self setAction: @selector(clickedAction:)];
else
#endif
{
- [(NSButton*)m_controlHandle setState:(toggle ? NSOnState : NSOffState)];
+ if ( IsButton() )
+ [(NSButton*)m_controlHandle setState:(toggle ? NSOnState : NSOffState)];
}
}
wxToolBar::~wxToolBar()
{
+ // removal only works while the toolbar is there
+ wxFrame *frame = wxDynamicCast(GetParent(), wxFrame);
+ if ( frame && frame->GetToolBar() == this )
+ {
+ frame->SetToolBar(NULL);
+ }
+
[(NSToolbar*)m_macToolbar setDelegate:nil];
[(NSToolbar*)m_macToolbar release];
m_macToolbar = NULL;
wxSize wxToolBar::DoGetBestSize() const
{
- int width, height;
-
- DoGetSize( &width, &height );
+ // was updated in Realize()
+
+ wxSize size = GetMinSize();
- return wxSize( width, height );
+ return size;
}
void wxToolBar::SetWindowStyleFlag( long style )
if (usesNative && (m_macToolbar == NULL))
return bResult;
- if (usesNative && ((GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT|wxTB_BOTTOM)) != 0))
+ if (usesNative && HasFlag(wxTB_LEFT|wxTB_RIGHT|wxTB_BOTTOM) )
return bResult;
WXWindow tlw = MacGetTopLevelWindowRef();
[tlw setToolbar:(NSToolbar*) m_macToolbar];
[(NSToolbar*) m_macToolbar setVisible:YES];
- m_peer->Move(0,0,0,0 );
+ GetPeer()->Move(0,0,0,0 );
SetSize( wxSIZE_AUTO_WIDTH, 0 );
- m_peer->SetVisibility( false );
+ GetPeer()->SetVisibility( false );
wxToolBarBase::Show( false );
}
}
bResult = true;
[(NSToolbar*) m_macToolbar setVisible:NO];
MacUninstallNativeToolbar();
- m_peer->SetVisibility( true );
+ GetPeer()->SetVisibility( true );
}
}
}
#endif
-bool wxToolBar::Realize()
+void wxToolBar::DoLayout()
{
- if ( !wxToolBarBase::Realize() )
- return false;
-
- int maxWidth = 0;
- int maxHeight = 0;
-
int maxToolWidth = 0;
int maxToolHeight = 0;
-
- int x = m_xMargin + kwxMacToolBarLeftMargin;
- int y = m_yMargin + kwxMacToolBarTopMargin;
-
+
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 )
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();
}
- bool lastIsRadio = false;
- bool curIsRadio = false;
-
-#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();
-#endif
-
+ // 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 )
{
node = node->GetNext();
continue;
}
-
+
// set tool position:
// for the moment just perform a single row/column alignment
wxSize cursize = tool->GetSize();
maxWidth = x + cursize.x;
if ( y + cursize.y > maxHeight )
maxHeight = y + cursize.y;
-
- if ( GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT) )
+
+ // 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) );
int y1 = y + ( maxToolHeight - cursize.y ) / 2;
tool->SetPosition( wxPoint(x, y1) );
}
-
+
// update the item positioning state
- if ( GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT) )
+ 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 )
{
// 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() )
+ node2 != node;
+ node2 = node2->GetPrevious() )
{
wxToolBarTool *tool2 = (wxToolBarTool*) node2->GetData();
-
+
const long idx = tool2->GetIndex();
if ( idx != -1 )
{
}
}
}
-
+
wxCFStringRef cfidentifier;
NSString *nsItemId;
if (tool->GetStyle() == wxTOOL_STYLE_SEPARATOR)
{
nsItemId = tool->IsStretchable() ? NSToolbarFlexibleSpaceItemIdentifier
- : NSToolbarSeparatorItemIdentifier;
+ : NSToolbarSeparatorItemIdentifier;
}
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) );
node = node->GetNext();
}
- if ( GetWindowStyleFlag() & (wxTB_TOP|wxTB_BOTTOM) )
- {
- // if not set yet, only one row
- if ( m_maxRows <= 0 )
- SetRows( 1 );
-
- m_minWidth = maxWidth;
- // maxHeight = th;
- maxHeight += m_yMargin + kwxMacToolBarTopMargin;
- m_minHeight = m_maxHeight = maxHeight;
- }
- else
- {
- // if not set yet, have one column
- if ( (GetToolsCount() > 0) && (m_maxRows <= 0) )
- SetRows( GetToolsCount() );
-
- m_minHeight = maxHeight;
- // maxWidth = tw;
- maxWidth += m_xMargin + kwxMacToolBarLeftMargin;
- m_minWidth = m_maxWidth = maxWidth;
- }
-
-#if 0
- // FIXME: should this be OSX-only?
- {
- bool wantNativeToolbar, ownToolbarInstalled;
-
- // attempt to install the native toolbar
- wantNativeToolbar = ((GetWindowStyleFlag() & (wxTB_LEFT|wxTB_BOTTOM|wxTB_RIGHT)) == 0);
- MacInstallNativeToolbar( wantNativeToolbar );
- (void)MacTopLevelHasNativeToolbar( &ownToolbarInstalled );
- if (!ownToolbarInstalled)
- {
- SetSize( maxWidth, maxHeight );
- InvalidateBestSize();
- }
- }
-#else
- SetSize( maxWidth, maxHeight );
InvalidateBestSize();
-#endif
-
- SetInitialSize();
+ 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;
{
wxWindow::MacSuperChangedPosition();
+ /*
#if wxOSX_USE_NATIVE_TOOLBAR
if (! m_macUsesNativeToolbar )
Realize();
Realize();
#endif
+ */
}
void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap )
if (tool == NULL)
return false;
+ long style = GetWindowStyleFlag();
+
wxSize toolSize = GetToolSize();
WXWidget controlHandle = NULL;
NSRect toolrect = NSMakeRect(0, 0, toolSize.x, toolSize.y );
wxASSERT( tool->GetControlHandle() == NULL );
toolSize.x /= 4;
toolSize.y /= 4;
- if ( GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT) )
+ if ( IsVertical() )
toolrect.size.height = toolSize.y;
else
toolrect.size.width = toolSize.x;
[v setBordered:NO];
[v setButtonType: ( tool->CanBeToggled() ? NSToggleButton : NSMomentaryPushInButton )];
[v setImplementation:tool];
+
+ if ( style & wxTB_NOICONS )
+ [v setImagePosition:NSNoImage];
+ else if ( style & wxTB_TEXT )
+ [v setImagePosition:NSImageAbove];
+ else
+ [v setImagePosition:NSImageOnly];
+
controlHandle = v;
tool->SetControlHandle( controlHandle );
tool->UpdateImages();
tool->UpdateLabel();
-#if 0
- SetBevelButtonTextPlacement( m_controlHandle, kControlBevelButtonPlaceBelowGraphic );
- SetControlTitleWithCFString( m_controlHandle , wxCFStringRef( label, wxFont::GetDefaultEncoding() );
-#endif
+ [v sizeToFit];
+
#if 0
InstallControlEventHandler(
(WXWidget) controlHandle, GetwxMacToolBarToolEventHandlerUPP(),
wxToolBarTool *tool2 = (wxToolBarTool*) node->GetData();
wxPoint pt = tool2->GetPosition();
- if ( GetWindowStyleFlag() & (wxTB_LEFT|wxTB_RIGHT) )
+ if ( IsVertical() )
pt.y -= sz.y;
else
pt.x -= sz.x;
#if wxOSX_USE_NATIVE_TOOLBAR
if ( m_macUsesNativeToolbar )
{
- event.Skip(true);
- return;
+ // nothing to do here
}
+ else
#endif
+ {
+ int w, h;
+ GetSize( &w, &h );
- wxPaintDC dc(this);
-
- int w, h;
- GetSize( &w, &h );
-
- bool drawMetalTheme = MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL;
+ bool drawMetalTheme = MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL;
- if ( !drawMetalTheme )
- {
- HIThemePlacardDrawInfo info;
- memset( &info, 0, sizeof(info) );
- info.version = 0;
- info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive;
-
- CGContextRef cgContext = (CGContextRef) MacGetCGContextRef();
- HIRect rect = CGRectMake( 0, 0, w, h );
- HIThemeDrawPlacard( &rect, &info, cgContext, kHIThemeOrientationNormal );
- }
- else
- {
- // leave the background as it is (striped or metal)
+ if ( UMAGetSystemVersion() < 0x1050 )
+ {
+ if ( !drawMetalTheme )
+ {
+ HIThemePlacardDrawInfo info;
+ memset( &info, 0, sizeof(info) );
+ info.version = 0;
+ info.state = IsEnabled() ? kThemeStateActive : kThemeStateInactive;
+
+ CGContextRef cgContext = (CGContextRef) MacGetCGContextRef();
+ HIRect rect = CGRectMake( 0, 0, w, h );
+ HIThemeDrawPlacard( &rect, &info, cgContext, kHIThemeOrientationNormal );
+ }
+ else
+ {
+ // leave the background as it is (striped or metal)
+ }
+ }
+ else
+ {
+ wxPaintDC dc(this);
+
+ wxRect rect(0,0,w,h);
+
+ dc.GradientFillLinear( rect , wxColour( 0xCC,0xCC,0xCC ), wxColour( 0xA8,0xA8,0xA8 ) , wxSOUTH );
+ dc.SetPen( wxPen( wxColour( 0x51,0x51,0x51 ) ) );
+ if ( HasFlag(wxTB_LEFT) )
+ dc.DrawLine(w-1, 0, w-1, h);
+ else if ( HasFlag(wxTB_RIGHT) )
+ dc.DrawLine(0, 0, 0, h);
+ else if ( HasFlag(wxTB_BOTTOM) )
+ dc.DrawLine(0, 0, w, 0);
+ else if ( HasFlag(wxTB_TOP) )
+ dc.DrawLine(0, h-1, w, h-1);
+ }
}
-
event.Skip();
}