2004-02-25 03:27:23 +00:00
|
|
|
/** <title>NSWindow+Toolbar</title>
|
|
|
|
|
|
|
|
<abstract>The window class category to include toolbar support</abstract>
|
|
|
|
|
|
|
|
Copyright (C) 2004 Free Software Foundation, Inc.
|
|
|
|
|
2004-03-12 22:55:02 +00:00
|
|
|
Author: Quentin Mathe <qmathe@club-internet.fr>
|
2004-02-25 03:27:23 +00:00
|
|
|
Date: January 2004
|
|
|
|
|
|
|
|
This file is part of the GNUstep GUI Library.
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
2007-10-29 21:16:17 +00:00
|
|
|
modify it under the terms of the GNU Lesser General Public
|
2004-02-25 03:27:23 +00:00
|
|
|
License as published by the Free Software Foundation; either
|
2008-06-10 04:01:49 +00:00
|
|
|
version 2 of the License, or (at your option) any later version.
|
2007-10-29 21:16:17 +00:00
|
|
|
|
2004-02-25 03:27:23 +00:00
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
2007-10-29 21:16:17 +00:00
|
|
|
Lesser General Public License for more details.
|
2004-02-25 03:27:23 +00:00
|
|
|
|
2007-10-29 21:16:17 +00:00
|
|
|
You should have received a copy of the GNU Lesser General Public
|
2004-02-25 03:27:23 +00:00
|
|
|
License along with this library; see the file COPYING.LIB.
|
2007-10-29 21:16:17 +00:00
|
|
|
If not, see <http://www.gnu.org/licenses/> or write to the
|
|
|
|
Free Software Foundation, 51 Franklin Street, Fifth Floor,
|
|
|
|
Boston, MA 02110-1301, USA.
|
2004-02-25 03:27:23 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <Foundation/NSDebug.h>
|
|
|
|
#include <Foundation/NSException.h>
|
2004-07-07 21:25:42 +00:00
|
|
|
#include <Foundation/NSAutoreleasePool.h>
|
2004-04-02 15:40:49 +00:00
|
|
|
#include "AppKit/NSWindow+Toolbar.h"
|
2004-02-25 03:27:23 +00:00
|
|
|
#include "AppKit/NSView.h"
|
|
|
|
#include "AppKit/NSToolbar.h"
|
|
|
|
#include "GNUstepGUI/GSToolbarView.h"
|
|
|
|
|
2008-12-30 22:20:21 +00:00
|
|
|
@interface GSToolbar (GNUstepPrivate)
|
2004-02-25 03:27:23 +00:00
|
|
|
- (GSToolbarView *) _toolbarView;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@interface GSToolbarView (GNUstepPrivate)
|
2004-03-12 22:55:02 +00:00
|
|
|
- (void) _setToolbar: (NSToolbar *)toolbar;
|
2004-04-13 13:12:53 +00:00
|
|
|
- (float) _heightFromLayout;
|
|
|
|
- (void) _reload;
|
2004-02-25 03:27:23 +00:00
|
|
|
@end
|
|
|
|
|
|
|
|
@interface NSWindow (ToolbarPrivate)
|
2004-04-13 13:12:53 +00:00
|
|
|
- (void) _adjustToolbarView;
|
2008-12-31 16:06:58 +00:00
|
|
|
- (void) _toggleToolbarView;
|
|
|
|
- (NSView *) _contentViewWithoutToolbar;
|
2004-02-25 03:27:23 +00:00
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation NSWindow (Toolbar)
|
|
|
|
|
|
|
|
- (void) runToolbarCustomizationPalette: (id)sender
|
|
|
|
{
|
|
|
|
[[self toolbar] runCustomizationPalette: sender];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) toggleToolbarShown: (id)sender
|
|
|
|
{
|
|
|
|
NSToolbar *toolbar = [self toolbar];
|
2008-12-31 16:06:58 +00:00
|
|
|
|
|
|
|
if (!toolbar)
|
|
|
|
return;
|
|
|
|
|
|
|
|
[self _toggleToolbarView];
|
|
|
|
|
|
|
|
// Important to set _visible after the toolbar view has been toggled because
|
|
|
|
// NSWindow method contentViewWithoutToolbar uses [NSToolbar visible]
|
|
|
|
// when we toggle the toolbar
|
|
|
|
// example : the toolbar needs to be still known visible in order to hide
|
|
|
|
// it.
|
|
|
|
[toolbar setVisible: ![toolbar isVisible]];
|
|
|
|
|
|
|
|
[self display];
|
2004-02-25 03:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Accessors
|
|
|
|
|
2008-12-31 16:06:58 +00:00
|
|
|
- (NSView *) _contentViewWithoutToolbar
|
2004-02-25 03:27:23 +00:00
|
|
|
{
|
|
|
|
NSToolbar *toolbar = [self toolbar];
|
|
|
|
|
|
|
|
if (toolbar != nil && [toolbar isVisible])
|
2008-12-28 15:16:05 +00:00
|
|
|
{
|
|
|
|
NSArray *subviews = [_contentView subviews];
|
|
|
|
// Take in account this method call returns an array which is an
|
|
|
|
// autoreleased copy.
|
|
|
|
// By side effect, this increments the toolbar view retain count until the
|
|
|
|
// autorelease pool is cleared.
|
|
|
|
NSView *subview;
|
|
|
|
int i, n = [subviews count];
|
|
|
|
GSToolbarView *toolbarView = [toolbar _toolbarView];
|
|
|
|
|
|
|
|
if (n > 2 || ![[toolbarView superview] isEqual: _contentView])
|
|
|
|
{
|
|
|
|
[NSException raise: @"_contentView error"
|
|
|
|
format: @"_contenView is not valid. _contentView needs a \
|
2004-03-12 22:55:02 +00:00
|
|
|
toolbar view and a contentViewWithoutToolbar, with \
|
|
|
|
no others subviews."];
|
2008-12-28 15:16:05 +00:00
|
|
|
}
|
2004-02-25 03:27:23 +00:00
|
|
|
|
2008-12-28 15:16:05 +00:00
|
|
|
for (i = 0; i < n; i++)
|
|
|
|
{
|
|
|
|
subview = [subviews objectAtIndex: i];
|
|
|
|
if (![subview isEqual: toolbarView])
|
|
|
|
{
|
|
|
|
return subview;
|
|
|
|
}
|
|
|
|
}
|
2004-02-25 03:27:23 +00:00
|
|
|
|
2008-12-28 15:16:05 +00:00
|
|
|
return nil;
|
|
|
|
}
|
2004-02-25 03:27:23 +00:00
|
|
|
|
|
|
|
return [self contentView];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSToolbar *) toolbar
|
|
|
|
{
|
2008-12-31 16:06:58 +00:00
|
|
|
return _toolbar;
|
2004-02-25 03:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setToolbar: (NSToolbar*)toolbar
|
|
|
|
{
|
2008-12-31 17:36:35 +00:00
|
|
|
if (toolbar == _toolbar)
|
2008-12-31 16:06:58 +00:00
|
|
|
return;
|
|
|
|
|
2008-12-31 17:36:35 +00:00
|
|
|
if (_toolbar != nil)
|
2008-12-28 15:16:05 +00:00
|
|
|
{
|
2008-12-31 17:36:35 +00:00
|
|
|
GSToolbarView *toolbarView = [_toolbar _toolbarView];
|
|
|
|
|
2008-12-28 15:16:05 +00:00
|
|
|
// We throw the last toolbar out
|
2008-12-31 17:36:35 +00:00
|
|
|
if ([_toolbar isVisible])
|
2008-12-31 16:06:58 +00:00
|
|
|
{
|
|
|
|
[self _toggleToolbarView];
|
|
|
|
}
|
2008-12-31 17:36:35 +00:00
|
|
|
[toolbarView _setToolbar: nil];
|
|
|
|
// Release the toolbarView, this will release the toolbar
|
|
|
|
RELEASE(toolbarView);
|
2008-12-28 15:16:05 +00:00
|
|
|
}
|
2004-02-25 03:27:23 +00:00
|
|
|
|
2008-12-31 16:06:58 +00:00
|
|
|
ASSIGN(_toolbar, toolbar);
|
|
|
|
|
|
|
|
if (toolbar != nil)
|
2008-12-28 15:16:05 +00:00
|
|
|
{
|
2008-12-31 16:06:58 +00:00
|
|
|
GSToolbarView *toolbarView = [toolbar _toolbarView];
|
2004-02-25 03:27:23 +00:00
|
|
|
|
2008-12-31 16:06:58 +00:00
|
|
|
if (toolbarView != nil)
|
|
|
|
{
|
|
|
|
NSLog(@"Error: the new toolbar is still owned by a toolbar view");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Instantiate the toolbar view
|
|
|
|
toolbarView = [[GSToolbarView alloc]
|
|
|
|
initWithFrame:
|
|
|
|
NSMakeRect(0, 0,
|
|
|
|
[NSWindow contentRectForFrameRect: [self frame]
|
|
|
|
styleMask: [self styleMask]].size.width, 100)];
|
|
|
|
// _toggleToolbarView method will set the toolbar view to the right
|
|
|
|
// frame
|
|
|
|
[toolbarView setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin];
|
|
|
|
[toolbarView setBorderMask: GSToolbarViewBottomBorder];
|
|
|
|
// Load the toolbar inside the toolbar view
|
|
|
|
// Will set the _toolbarView variable for the toolbar
|
|
|
|
[toolbarView _setToolbar: toolbar];
|
|
|
|
}
|
2004-04-13 13:12:53 +00:00
|
|
|
|
2008-12-31 16:06:58 +00:00
|
|
|
// Make the toolbar view visible
|
|
|
|
if ([toolbar isVisible])
|
|
|
|
{
|
|
|
|
[self _toggleToolbarView];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// To show the changed toolbar
|
|
|
|
[self display];
|
2004-02-25 03:27:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Private methods
|
|
|
|
|
2004-04-13 13:12:53 +00:00
|
|
|
- (void) _adjustToolbarView
|
|
|
|
{
|
|
|
|
NSToolbar *toolbar = [self toolbar];
|
|
|
|
|
|
|
|
if ([toolbar isVisible])
|
|
|
|
{
|
2008-12-31 16:06:58 +00:00
|
|
|
// Views
|
|
|
|
GSToolbarView *toolbarView = [toolbar _toolbarView];
|
2004-04-13 13:12:53 +00:00
|
|
|
|
2008-12-31 16:06:58 +00:00
|
|
|
// Frame and height
|
|
|
|
NSRect toolbarViewFrame = [toolbarView frame];
|
|
|
|
float toolbarViewHeight = toolbarViewFrame.size.height;
|
|
|
|
float newToolbarViewHeight = [toolbarView _heightFromLayout];
|
2004-04-13 13:12:53 +00:00
|
|
|
|
2008-12-31 16:06:58 +00:00
|
|
|
if (toolbarViewHeight != newToolbarViewHeight)
|
|
|
|
{
|
|
|
|
NSView *contentViewWithoutToolbar = [self _contentViewWithoutToolbar];
|
|
|
|
NSRect windowFrame = [self frame];
|
2004-04-13 13:12:53 +00:00
|
|
|
|
2008-12-31 16:06:58 +00:00
|
|
|
[toolbarView setFrame: NSMakeRect(
|
|
|
|
toolbarViewFrame.origin.x,
|
|
|
|
toolbarViewFrame.origin.y + (toolbarViewHeight - newToolbarViewHeight),
|
|
|
|
toolbarViewFrame.size.width,
|
|
|
|
newToolbarViewHeight)];
|
|
|
|
|
|
|
|
// Resize the window
|
|
|
|
[contentViewWithoutToolbar setAutoresizingMask: NSViewNotSizable];
|
|
|
|
|
|
|
|
[self setFrame: NSMakeRect(
|
|
|
|
windowFrame.origin.x,
|
|
|
|
windowFrame.origin.y + (toolbarViewHeight - newToolbarViewHeight),
|
|
|
|
windowFrame.size.width,
|
|
|
|
windowFrame.size.height - (toolbarViewHeight - newToolbarViewHeight))
|
|
|
|
display: NO];
|
|
|
|
|
|
|
|
[contentViewWithoutToolbar setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
|
|
|
|
|
|
|
|
[self display];
|
|
|
|
}
|
2004-04-13 13:12:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2008-12-31 16:06:58 +00:00
|
|
|
- (void) _toggleToolbarView
|
|
|
|
{
|
2004-04-13 13:12:53 +00:00
|
|
|
// Views
|
|
|
|
GSToolbarView *toolbarView = [[self toolbar] _toolbarView];
|
|
|
|
NSView *contentViewWithoutToolbar;
|
|
|
|
|
|
|
|
// Frame
|
2004-07-06 23:31:57 +00:00
|
|
|
NSRect windowContentFrame
|
|
|
|
= [NSWindow contentRectForFrameRect: [self frame]
|
2008-12-28 15:16:05 +00:00
|
|
|
styleMask: [self styleMask]];
|
2004-02-25 03:27:23 +00:00
|
|
|
|
|
|
|
if ([toolbarView superview] == nil)
|
|
|
|
{
|
2008-12-31 16:06:58 +00:00
|
|
|
float newToolbarViewHeight;
|
2004-02-25 03:27:23 +00:00
|
|
|
NSRect contentViewWithoutToolbarFrame;
|
2004-04-13 13:12:53 +00:00
|
|
|
|
2008-12-31 16:06:58 +00:00
|
|
|
[toolbarView setFrameSize:
|
|
|
|
NSMakeSize(windowContentFrame.size.width, 100)];
|
|
|
|
// Will recalculate the layout
|
|
|
|
[toolbarView _reload];
|
|
|
|
newToolbarViewHeight = [toolbarView _heightFromLayout];
|
|
|
|
|
2004-02-25 03:27:23 +00:00
|
|
|
contentViewWithoutToolbar = _contentView;
|
2008-12-31 16:06:58 +00:00
|
|
|
contentViewWithoutToolbarFrame = [contentViewWithoutToolbar frame];
|
2004-02-25 03:27:23 +00:00
|
|
|
|
|
|
|
// Switch the content view
|
|
|
|
RETAIN(contentViewWithoutToolbar);
|
2004-03-12 22:55:02 +00:00
|
|
|
[self setContentView:
|
2008-12-31 16:06:58 +00:00
|
|
|
AUTORELEASE([[NSView alloc] initWithFrame:
|
|
|
|
contentViewWithoutToolbarFrame])];
|
2004-02-25 03:27:23 +00:00
|
|
|
|
|
|
|
// Resize the window
|
2004-07-06 23:31:57 +00:00
|
|
|
windowContentFrame.origin.y -= newToolbarViewHeight;
|
|
|
|
windowContentFrame.size.height += newToolbarViewHeight;
|
|
|
|
[self setFrame: [NSWindow frameRectForContentRect: windowContentFrame
|
2008-12-28 15:16:05 +00:00
|
|
|
styleMask: [self styleMask]]
|
|
|
|
display: NO];
|
2004-02-25 03:27:23 +00:00
|
|
|
|
|
|
|
// Plug the toolbar view
|
2004-04-13 13:12:53 +00:00
|
|
|
[toolbarView setFrame: NSMakeRect(
|
|
|
|
0,
|
2008-12-28 15:16:05 +00:00
|
|
|
contentViewWithoutToolbarFrame.size.height,
|
2004-04-13 13:12:53 +00:00
|
|
|
contentViewWithoutToolbarFrame.size.width,
|
2008-12-28 15:16:05 +00:00
|
|
|
newToolbarViewHeight)];
|
2004-02-25 03:27:23 +00:00
|
|
|
[_contentView addSubview: toolbarView];
|
2004-07-07 21:25:42 +00:00
|
|
|
RELEASE(toolbarView);
|
|
|
|
|
2004-02-25 03:27:23 +00:00
|
|
|
// Insert the previous content view
|
2004-07-06 23:31:57 +00:00
|
|
|
/* We want contentViewWithoutToolbarFrame at the origin of our new
|
|
|
|
content view. There's no guarantee that the old position was (0,0). */
|
|
|
|
contentViewWithoutToolbarFrame.origin.x = 0;
|
|
|
|
contentViewWithoutToolbarFrame.origin.y = 0;
|
|
|
|
[contentViewWithoutToolbar setFrame: contentViewWithoutToolbarFrame];
|
|
|
|
|
2004-02-25 03:27:23 +00:00
|
|
|
[_contentView addSubview: contentViewWithoutToolbar];
|
|
|
|
RELEASE(contentViewWithoutToolbar);
|
|
|
|
}
|
|
|
|
else
|
2004-04-13 13:12:53 +00:00
|
|
|
{
|
|
|
|
float toolbarViewHeight = [toolbarView frame].size.height;
|
|
|
|
|
2008-12-31 16:06:58 +00:00
|
|
|
contentViewWithoutToolbar = [self _contentViewWithoutToolbar];
|
2004-02-25 03:27:23 +00:00
|
|
|
|
|
|
|
// Unplug the toolbar view
|
2004-07-07 21:25:42 +00:00
|
|
|
RETAIN(toolbarView);
|
2008-12-31 16:06:58 +00:00
|
|
|
[toolbarView removeFromSuperviewWithoutNeedingDisplay];
|
2004-02-25 03:27:23 +00:00
|
|
|
|
|
|
|
// Resize the window
|
|
|
|
[contentViewWithoutToolbar setAutoresizingMask: NSViewMaxYMargin];
|
|
|
|
|
2004-07-06 23:31:57 +00:00
|
|
|
windowContentFrame.origin.y += toolbarViewHeight;
|
|
|
|
windowContentFrame.size.height -= toolbarViewHeight;
|
|
|
|
[self setFrame: [NSWindow frameRectForContentRect: windowContentFrame
|
2008-12-28 15:16:05 +00:00
|
|
|
styleMask: [self styleMask]]
|
|
|
|
display: NO];
|
2004-02-25 03:27:23 +00:00
|
|
|
|
2004-03-12 22:55:02 +00:00
|
|
|
[contentViewWithoutToolbar setAutoresizingMask: NSViewWidthSizable
|
|
|
|
| NSViewHeightSizable];
|
2004-02-25 03:27:23 +00:00
|
|
|
// Autoresizing mask will be set again by the setContentView: method
|
|
|
|
|
|
|
|
// Switch the content view
|
2004-03-12 22:55:02 +00:00
|
|
|
RETAIN(contentViewWithoutToolbar);
|
2004-07-07 21:25:42 +00:00
|
|
|
// Because setContentView: will release the parent view (aka _contentView) and
|
2008-12-31 16:06:58 +00:00
|
|
|
// its subviews and actually contentViewWithoutToolbar is a subview of _contentView
|
2004-03-12 22:55:02 +00:00
|
|
|
|
2004-07-07 21:25:42 +00:00
|
|
|
[contentViewWithoutToolbar removeFromSuperviewWithoutNeedingDisplay];
|
2004-02-25 03:27:23 +00:00
|
|
|
[self setContentView: contentViewWithoutToolbar];
|
2004-03-12 22:55:02 +00:00
|
|
|
|
2004-02-25 03:27:23 +00:00
|
|
|
RELEASE(contentViewWithoutToolbar);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|