toolbar support in all orientations

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@66905 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor 2011-02-16 18:30:55 +00:00
parent ca9adee47f
commit baac715443
4 changed files with 307 additions and 168 deletions

View File

@ -64,6 +64,7 @@ public:
// event handlers
void OnActivate(wxActivateEvent& event);
void OnSysColourChanged(wxSysColourChangedEvent& event);
void OnSize(wxSizeEvent& event);
// Toolbar
#if wxUSE_TOOLBAR
@ -88,8 +89,6 @@ public:
void PositionBars();
// osx specific event handling common for all osx-ports
virtual void HandleResized( double timestampsec );
protected:
// common part of all ctors

View File

@ -29,6 +29,7 @@
BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
EVT_ACTIVATE(wxFrame::OnActivate)
EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
EVT_SIZE(wxFrame::OnSize)
END_EVENT_TABLE()
#define WX_MAC_STATUSBAR_HEIGHT 18
@ -216,14 +217,12 @@ void wxFrame::OnActivate(wxActivateEvent& event)
}
}
void wxFrame::HandleResized( double timestampsec )
{
// according to the other ports we handle this within the OS level
// resize event, not within a wxSizeEvent
void wxFrame::OnSize(wxSizeEvent& event)
{
PositionBars();
wxNonOwnedWindow::HandleResized( timestampsec );
event.Skip();
}
#if wxUSE_MENUS
@ -274,11 +273,16 @@ void wxFrame::DoGetClientSize(int *x, int *y) const
int w, h;
toolbar->GetSize(&w, &h);
if ( toolbar->GetWindowStyleFlag() & wxTB_VERTICAL )
if ( toolbar->IsVertical() )
{
if ( x )
*x -= w;
}
else if ( toolbar->HasFlag( wxTB_BOTTOM ) )
{
if ( y )
*y -= h;
}
else
{
#if !wxOSX_USE_NATIVE_TOOLBAR
@ -359,7 +363,7 @@ void wxFrame::PositionToolBar()
{
int cw, ch;
GetSize( &cw , &ch ) ;
wxTopLevelWindow::DoGetClientSize( &cw , &ch );
int statusX = 0 ;
int statusY = 0 ;
@ -367,7 +371,7 @@ void wxFrame::PositionToolBar()
#if wxUSE_STATUSBAR
if (GetStatusBar() && GetStatusBar()->IsShown())
{
GetStatusBar()->GetClientSize(&statusX, &statusY);
GetStatusBar()->GetSize(&statusX, &statusY);
ch -= statusY;
}
#endif
@ -384,20 +388,25 @@ void wxFrame::PositionToolBar()
tx = ty = 0 ;
GetToolBar()->GetSize(&tw, &th);
if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
if (GetToolBar()->HasFlag(wxTB_LEFT))
{
// Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
// means, pretend we don't have toolbar/status bar, so we
// have the original client size.
GetToolBar()->SetSize(tx , ty , tw, ch , wxSIZE_NO_ADJUSTMENTS );
}
else if (GetToolBar()->GetWindowStyleFlag() & wxTB_BOTTOM)
else if (GetToolBar()->HasFlag(wxTB_RIGHT))
{
// Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
// means, pretend we don't have toolbar/status bar, so we
// have the original client size.
tx = cw - tw;
GetToolBar()->SetSize(tx , ty , tw, ch , wxSIZE_NO_ADJUSTMENTS );
}
else if (GetToolBar()->HasFlag(wxTB_BOTTOM))
{
//FIXME: this positions the tool bar almost correctly, but still it doesn't work right yet,
//as 1) the space for the 'old' top toolbar is still taken up, and 2) the toolbar
//doesn't extend it's width to the width of the frame.
tx = 0;
ty = ch - (th + statusY);
ty = ch - th;
GetToolBar()->SetSize(tx, ty, cw, th, wxSIZE_NO_ADJUSTMENTS );
}
else

View File

@ -1424,6 +1424,18 @@ bool wxToolBar::Realize()
return true;
}
void wxToolBar::DoLayout()
{
// TODO port back osx_cocoa layout solution
}
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;

View File

@ -43,6 +43,21 @@ END_EVENT_TABLE()
// 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
@ -130,13 +145,15 @@ public:
}
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;
@ -158,20 +175,23 @@ public:
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()
@ -298,19 +318,6 @@ private:
#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
@ -540,6 +547,7 @@ void wxToolBarTool::UpdateToggleImage( bool toggle )
else
#endif
{
if ( IsButton() )
[(NSButton*)m_controlHandle setState:(toggle ? NSOnState : NSOffState)];
}
}
@ -656,6 +664,13 @@ bool wxToolBar::Create(
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;
@ -745,11 +760,11 @@ void wxToolBar::DoGetSize( int *width, int *height ) const
wxSize wxToolBar::DoGetBestSize() const
{
int width, height;
// was updated in Realize()
DoGetSize( &width, &height );
wxSize size = GetMinSize();
return wxSize( width, height );
return size;
}
void wxToolBar::SetWindowStyleFlag( long style )
@ -805,7 +820,7 @@ bool wxToolBar::MacInstallNativeToolbar(bool usesNative)
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();
@ -862,24 +877,17 @@ void wxToolBar::MacUninstallNativeToolbar()
}
#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
unsigned numStretchableSpaces = 0;
wxToolBarTool *tool;
wxToolBarToolsList::compatibility_iterator node = m_tools.GetFirst();
while ( node )
@ -893,27 +901,22 @@ bool wxToolBar::Realize()
maxToolWidth = sz.x;
if ( sz.y > maxToolHeight )
maxToolHeight = sz.y;
if ( tool->IsStretchableSpace() )
numStretchableSpaces++;
}
node = node->GetNext();
}
bool lastIsRadio = false;
bool curIsRadio = false;
// layout non-native toolbar
#if wxOSX_USE_NATIVE_TOOLBAR
CFIndex currentPosition = 0;
bool insertAll = false;
bool isHorizontal = !IsVertical();
NSToolbar* refTB = (NSToolbar*)m_macToolbar;
wxFont f;
wxFontEncoding enc;
f = GetFont();
if ( f.IsOk() )
enc = f.GetEncoding();
else
enc = wxFont::GetDefaultEncoding();
#endif
int maxWidth = 0;
int maxHeight = 0;
int x = m_xMargin + kwxMacToolBarLeftMargin;
int y = m_yMargin + kwxMacToolBarTopMargin;
node = m_tools.GetFirst();
while ( node )
@ -933,7 +936,79 @@ bool wxToolBar::Realize()
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) );
@ -945,12 +1020,47 @@ bool wxToolBar::Realize()
}
// 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 )
{
@ -1006,8 +1116,28 @@ bool wxToolBar::Realize()
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) );
@ -1049,54 +1179,21 @@ bool wxToolBar::Realize()
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( wxSize(m_minWidth, m_minHeight));
SetInitialSize();
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;
@ -1136,6 +1233,7 @@ void wxToolBar::MacSuperChangedPosition()
{
wxWindow::MacSuperChangedPosition();
/*
#if wxOSX_USE_NATIVE_TOOLBAR
if (! m_macUsesNativeToolbar )
Realize();
@ -1143,6 +1241,7 @@ void wxToolBar::MacSuperChangedPosition()
Realize();
#endif
*/
}
void wxToolBar::SetToolNormalBitmap( int id, const wxBitmap& bitmap )
@ -1219,6 +1318,8 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
if (tool == NULL)
return false;
long style = GetWindowStyleFlag();
wxSize toolSize = GetToolSize();
WXWidget controlHandle = NULL;
NSRect toolrect = NSMakeRect(0, 0, toolSize.x, toolSize.y );
@ -1240,7 +1341,7 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
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;
@ -1274,6 +1375,14 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
[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;
#if wxOSX_USE_NATIVE_TOOLBAR
@ -1290,10 +1399,8 @@ bool wxToolBar::DoInsertTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolBase)
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(),
@ -1389,7 +1496,7 @@ bool wxToolBar::DoDeleteTool(size_t WXUNUSED(pos), wxToolBarToolBase *toolbase)
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;
@ -1417,18 +1524,18 @@ void wxToolBar::OnPaint(wxPaintEvent& event)
#if wxOSX_USE_NATIVE_TOOLBAR
if ( m_macUsesNativeToolbar )
{
event.Skip(true);
return;
// nothing to do here
}
else
#endif
wxPaintDC dc(this);
{
int w, h;
GetSize( &w, &h );
bool drawMetalTheme = MacGetTopLevelWindow()->GetExtraStyle() & wxFRAME_EX_METAL;
if ( UMAGetSystemVersion() < 0x1050 )
{
if ( !drawMetalTheme )
{
HIThemePlacardDrawInfo info;
@ -1444,7 +1551,19 @@ void wxToolBar::OnPaint(wxPaintEvent& event)
{
// 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 ) ) );
dc.DrawRectangle(rect);
}
}
event.Skip();
}