Submitting Quentin's changes for NSToolbar.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@18651 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Gregory John Casamento 2004-02-25 03:27:23 +00:00
parent 9104c393a2
commit adb7cb3132
12 changed files with 1984 additions and 447 deletions

View file

@ -1,3 +1,16 @@
2004-02-24 Gregory John Casamento <greg_casamento@yahoo.com>
On behalf of Quentin Mathé <qmathe@club-internet.fr>
* Headers/Additions/GNUstepGUI/GSToolbarView.h: Changes for
new toolbar implementation.
* Headers/AppKit/NSToolbar.h: same as above.
* Headers/AppKit/NSToolbarItem.h: same...
* GNUmakefile: Added new files
* Source/NSButtonCell.m: Changes to improve the look of
unbordered buttons.
* Source/NSToolbar.m: Changes for new toolbar implementation.
* Source/NSToolbarItem.m: same...
2004-02-24 Fred Kiefer <FredKiefer@gmx.de>
* Headers/Additions/GNUstepGUI/GSDrawFunctions.h:

View file

@ -31,21 +31,63 @@
#define _GSToolbarView_h_INCLUDE
#include <Foundation/NSObject.h>
#include "AppKit/NSToolbarItem.h"
#include "AppKit/NSToolbar.h"
#include "AppKit/NSView.h"
#include <Foundation/NSGeometry.h>
@class NSMutableArray;
@class NSToolbar;
@class NSToolbarItem;
@class NSView;
@class NSClipView;
@class GSToolbarClippedItemsButton;
enum {
GSToolbarViewNoBorder = 0,
GSToolbarViewRightBorder = 2,
GSToolbarViewLeftBorder = 4,
GSToolbarViewTopBorder = 8,
GSToolbarViewBottomBorder = 16
};
typedef enum _ItemBackViewHeight {
_ItemBackViewDefaultHeight = 60,
_ItemBackViewRegularHeight = 60,
_ItemBackViewSmallHeight = 50
} _ItemBackViewHeight;
typedef enum _ItemViewWidth {
_ItemBackViewDefaultWidth = 60,
_ItemBackViewRegularWidth = 60,
_ItemBackViewSmallWidth = 50
} _ItemBackViewWidth;
static const int _ItemBackViewX = 0;
static const int _ItemBackViewY = 0;
static const int _InsetItemViewX = 10;
static const int _InsetItemViewY = 26;
static const int _InsetItemTextX = 3;
static const int _InsetItemTextY = 4;
static const int _ClippedItemsViewWidth = 28;
@interface GSToolbarView : NSView
{
NSToolbar *_toolbar;
NSClipView *_clipView, *_clipViewForEditMode;
NSView *_loadedViewEdited;
GSToolbarClippedItemsButton *_clippedItemsMark;
NSMutableArray *_visibleBackViews;
BOOL _willBeVisible;
unsigned int _borderMask;
}
- (id) initWithToolbar: (NSToolbar *)toolbar;
- (void) setToolbar: (NSToolbar *)toolbar;
- (NSToolbar *) toolbar;
@end
@interface NSToolbar (GNUstepPrivate)
- (id) _toolbarView;
- (id) initWithFrame: (NSRect)frame;
// Accessors
- (NSToolbar *) toolbar;
- (void) setToolbar: (NSToolbar *)toolbar;
- (unsigned int) borderMask;
- (void) setBorderMask: (unsigned int)borderMask;
@end
#endif

View file

@ -31,17 +31,17 @@
#define _GNUstep_H_NSToolbar
#include <Foundation/NSObject.h>
#include <Foundation/NSGeometry.h>
#include <AppKit/AppKitDefines.h>
@class NSString;
@class NSArray;
@class NSMutableArray;
@class NSString;
@class NSDictionary;
@class NSMutableDictionary;
@class NSToolbarItem;
@class NSNotification;
@class NSLock;
@class NSToolbarItem;
@class GSToolbarView;
@class NSWindow;
/*
* Constants
@ -54,6 +54,13 @@ typedef enum
NSToolbarDisplayModeLabelOnly
} NSToolbarDisplayMode;
typedef enum
{
NSToolbarSizeModeDefault,
NSToolbarSizeModeRegular,
NSToolbarSizeModeSmall,
} NSToolbarSizeMode;
APPKIT_EXPORT NSString *NSToolbarDidRemoveItemNotification;
APPKIT_EXPORT NSString *NSToolbarWillAddItemNotification;
@ -68,11 +75,19 @@ APPKIT_EXPORT NSString *NSToolbarWillAddItemNotification;
NSString *_identifier;
BOOL _visible;
NSMutableArray *_items;
NSMutableArray *_visibleItems;
id _toolbarView;
GSToolbarView *_toolbarView;
NSWindow *_window;
BOOL _build;;
}
// Instance methods
- (id) initWithIdentifier: (NSString*)identifier;
- (void) insertItemWithItemIdentifier: (NSString*)itemIdentifier atIndex: (int)index;
- (void) removeItemAtIndex: (int)index;
- (void) runCustomizationPalette: (id)sender;
// Accessors
- (BOOL) allowsUserCustomization;
- (BOOL) autosavesConfiguration;
- (NSDictionary*) configurationDictionary;
@ -80,22 +95,22 @@ APPKIT_EXPORT NSString *NSToolbarWillAddItemNotification;
- (id) delegate;
- (NSToolbarDisplayMode) displayMode;
- (NSString*) identifier;
- (id) initWithIdentifier: (NSString*)identifier;
- (void) insertItemWithItemIdentifier: (NSString*)itemIdentifier
atIndex: (int)index;
- (BOOL) isVisible;
- (NSArray*) items;
- (void) removeItemAtIndex: (int)index;
- (void) runCustomizationPalette: (id)sender;
- (NSString *) selectedItemIdentifier;
- (NSArray*) visibleItems;
- (void) setAllowsUserCustomization: (BOOL)flag;
- (void) setAutosavesConfiguration: (BOOL)flag;
- (void) setConfigurationFromDictionary: (NSDictionary*)configDict;
- (void) setDelegate: (id)delegate;
- (void) setDisplayMode: (NSToolbarDisplayMode)displayMode;
- (void) setSelectedItemIdentifier: (NSString *) identifier;
- (void) setSizeMode: (NSToolbarSizeMode)sizeMode;
- (void) setVisible: (BOOL)shown;
- (NSToolbarSizeMode) sizeMode;
- (void) validateVisibleItems;
- (NSArray*) visibleItems;
@end /* interface of NSToolbar */
/*
@ -110,11 +125,13 @@ APPKIT_EXPORT NSString *NSToolbarWillAddItemNotification;
// required method
- (NSToolbarItem*)toolbar: (NSToolbar*)toolbar
itemForItemIdentifier: (NSString*)itemIdentifier
willBeInsertedIntoToolbar: (BOOL)flag;
willBeInsertedIntoToolbar: (BOOL)flag;
// required method
- (NSArray*) toolbarAllowedItemIdentifiers: (NSToolbar*)toolbar;
// required method
- (NSArray*) toolbarDefaultItemIdentifiers: (NSToolbar*)toolbar;
// optional method
- (NSArray *) toolbarSelectableItemIdentifiers: (NSToolbar *)toolbar;
@end
#endif /* _GNUstep_H_NSToolbar */

View file

@ -31,9 +31,9 @@
#define _GNUstep_H_NSToolbarItem
#include <Foundation/NSObject.h>
#include <AppKit/NSUserInterfaceValidation.h>
#include <AppKit/AppKitDefines.h>
#include <Foundation/NSGeometry.h>
#include <AppKit/AppKitDefines.h>
#include <AppKit/NSUserInterfaceValidation.h>
@class NSArray;
@class NSString;
@ -63,11 +63,14 @@ APPKIT_EXPORT NSString *NSToolbarPrintItemIdentifier;
NSString *_label;
NSMenuItem *_menuFormRepresentation;
NSString *_paletteLabel;
NSImage *_image;
// toolbar
NSToolbar *_toolbar;
NSString *_toolTip;
id _view;
NSView *_backView;
BOOL _updated;
// size
NSSize _maxSize;
@ -95,39 +98,43 @@ APPKIT_EXPORT NSString *NSToolbarPrintItemIdentifier;
}
// Instance methods
- (SEL)action;
- (BOOL)allowsDuplicatesInToolbar;
- (NSImage *)image;
- (id)initWithItemIdentifier: (NSString *)itemIdentifier;
- (BOOL)isEnabled;
- (NSString *)itemIdentifier;
- (NSString *)label;
- (NSSize)maxSize;
- (NSMenuItem *)menuFormRepresentation;
- (NSSize)minSize;
- (NSString *)paletteLabel;
- (void)setAction: (SEL)action;
- (void)setEnabled: (BOOL)enabled;
- (void)setImage: (NSImage *)image;
- (void)setLabel: (NSString *)label;
- (void)setMaxSize: (NSSize)maxSize;
- (void)setMenuFormRepresentation: (NSMenuItem *)menuItem;
- (void)setMinSize: (NSSize)minSize;
- (void)setPaletteLabel: (NSString *)paletteLabel;
- (void)setTag: (int)tag;
- (void)setTarget: (id)target;
- (void)setToolTip: (NSString *)toolTip;
- (void)setView: (NSView *)view;
- (int)tag;
- (id)target;
- (NSString *)toolTip;
- (NSToolbar *)toolbar;
- (void)validate;
- (NSView *)view;
// Accessors
- (SEL) action;
- (BOOL) allowsDuplicatesInToolbar;
- (NSImage *) image;
- (BOOL) isEnabled;
- (NSString *) itemIdentifier;
- (NSString *) label;
- (NSSize) maxSize;
- (NSMenuItem *) menuFormRepresentation;
- (NSSize) minSize;
- (NSString *) paletteLabel;
- (int) tag;
- (id) target;
- (NSString *) toolTip;
- (NSToolbar *) toolbar;
- (NSView *) view;
- (void) setAction: (SEL)action;
- (void) setEnabled: (BOOL)enabled;
- (void) setImage: (NSImage *)image;
- (void) setLabel: (NSString *)label;
- (void) setMaxSize: (NSSize)maxSize;
- (void) setMenuFormRepresentation: (NSMenuItem *)menuItem;
- (void) setMinSize: (NSSize)minSize;
- (void) setPaletteLabel: (NSString *)paletteLabel;
- (void) setTag: (int)tag;
- (void) setTarget: (id)target;
- (void) setToolTip: (NSString *)toolTip;
- (void) setView: (NSView *)view;
@end /* interface of NSToolbarItem */
@protocol NSToolbarItemValidation
- (BOOL)validateToolbarItem: (NSToolbarItem *)theItem;
- (BOOL) validateToolbarItem: (NSToolbarItem *)theItem;
@end
#endif /* _GNUstep_H_NSToolbarItem */

View file

@ -107,6 +107,7 @@ common_LeftTabStop.tiff \
common_DecimalTabStop.tiff \
common_Diamond.tiff \
common_Printer.tiff \
common_ToolbarClippedItemsMark.tiff \
common_ToolbarSeperatorItem.tiff \
common_ToolbarShowColorsItem.tiff \
common_ToolbarShowFontsItem.tiff \

View file

@ -103,7 +103,6 @@ NSMenu.m \
NSMenuView.m \
NSMenuItem.m \
NSMenuItemCell.m \
NSNib.m \
NSOpenGLContext.m \
NSOpenGLPixelFormat.m \
NSOpenGLView.m \
@ -152,6 +151,7 @@ NSTextStorage.m \
NSToolbar.m \
NSToolbarItem.m \
NSView.m \
NSWindow+Toolbar.m \
NSWindow.m \
NSWindowController.m \
NSWorkspace.m \
@ -182,7 +182,8 @@ GSTypesetter.m \
GSHorizontalTypesetter.m \
GSNibTemplates.m \
GSNibCompatibility.m \
GSTitleView.m
GSTitleView.m \
GSToolbarView.m
# Turn off NSMenuItem warning that NSMenuItem conforms to <NSObject>,
# but does not implement <NSObject>'s methods itself (it inherits
@ -253,7 +254,6 @@ NSMenu.h \
NSMenuItem.h \
NSMenuItemCell.h \
NSMenuView.h \
NSNib.h \
NSOpenPanel.h \
NSOpenGL.h \
NSOpenGLView.h \

512
Source/GSToolbarView.m Normal file
View file

@ -0,0 +1,512 @@
/*
<title>GSToolbarView.m</title>
<abstract>The toolbar view class.</abstract>
Copyright (C) 2004 Free Software Foundation, Inc.
Author: Quentin Mathé <qmathe@club-internet.fr>
Date: January 2004
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSObject.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSException.h>
#include "AppKit/NSToolbarItem.h"
#include "AppKit/NSToolbar.h"
#include "AppKit/NSView.h"
#include "AppKit/NSClipView.h"
#include "AppKit/NSButton.h"
#include "AppKit/NSBezierPath.h"
#include "AppKit/NSImage.h"
#include "AppKit/NSMenu.h"
#include "AppKit/NSEvent.h"
#include "AppKit/NSWindow.h"
#include "GNUstepGUI/GSToolbarView.h"
// internal
static const int current_version = 1;
@interface NSToolbar (GNUstepPrivate)
- (void) _build;
- (void) _setToolbarView: (GSToolbarView *)toolbarView;
@end
@interface NSToolbarItem (GNUstepPrivate)
- (NSView *) _backView;
- (BOOL) _isModified;
- (BOOL) _isFlexibleSpace;
- (void) _layout;
@end
@interface GSToolbarClippedItemsButton : NSButton
{
NSToolbar *_toolbar;
}
- (id) init;
// Accessors
- (NSMenu *) returnMenu; // this method cannot be called menu otherwise
// it would override NSResponder method with the same name
- (void)setToolbar: (NSToolbar *)toolbar;
@end
@interface GSToolbarView (GNUstepPrivate)
- (void) _handleViewsSize;
- (void) _handleViewsOrigin;
- (void) _handleViewsVisibility;
- (void) _reload;
- (void) _takeInAccountFlexibleSpaces;
// Accessors
- (NSArray *) _visibleBackViews;
- (void) _setWillBeVisible: (BOOL)willBeVisible;
- (BOOL) _willBeVisible;
@end
@implementation GSToolbarClippedItemsButton
- (id)init
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarClippedItemsMark"];
if ((self = [super initWithFrame: NSMakeRect(0, 0, _ClippedItemsViewWidth, _ItemBackViewDefaultHeight)]) != nil)
{
[self setBordered: NO];
[[self cell] setHighlightsBy: NSChangeGrayCellMask | NSChangeBackgroundCellMask];
[self setAutoresizingMask: (NSViewNotSizable | NSViewMinXMargin)];
[self setImagePosition: NSImageOnly];
[image setScalesWhenResized: YES];
[image setSize: NSMakeSize(20., 20.)];
[self setImage: image];
return self;
}
return nil;
}
- (void)mouseDown: (NSEvent *)event {
NSMenu *clippedItemsMenu = [self menuForEvent:event];
if (clippedItemsMenu != nil)
{
[NSMenu popUpContextMenu: clippedItemsMenu withEvent: event forView: self];
}
}
- (NSMenu *)menuForEvent: (NSEvent *)event {
if ([event type] == NSLeftMouseDown)
{
return [self returnMenu];
}
return nil;
}
- (NSMenu *)returnMenu
// this method cannot be called menu otherwise it would override NSResponder method with the same name
{
NSMenu *menu = [[NSMenu alloc] initWithTitle:@""];
NSEnumerator *e;
id item;
NSArray *visibleItems;
AUTORELEASE(menu);
visibleItems = [_toolbar visibleItems];
e = [[_toolbar items] objectEnumerator];
while ((item = [e nextObject]) != nil)
{
if (![visibleItems containsObject: item])
{
id menuItem;
menuItem = [item menuFormRepresentation];
if (menuItem != nil)
[menu addItem: menuItem];
}
}
return menu;
}
// Accessors
- (void)setToolbar: (NSToolbar *)toolbar
{
ASSIGN(_toolbar, toolbar);
}
@end
// Implementation GSToolbarView
@implementation GSToolbarView
- (id) initWithFrame: (NSRect)frame
{
if((self = [super initWithFrame: frame]) != nil)
{
_clipView = [[NSClipView alloc] initWithFrame: NSMakeRect(0, 1, frame.size.width, frame.size.height)];
[_clipView setAutoresizingMask: (NSViewWidthSizable | NSViewHeightSizable)];
[self addSubview: _clipView];
_clippedItemsMark = [[GSToolbarClippedItemsButton alloc] init];
_borderMask = GSToolbarViewTopBorder | GSToolbarViewBottomBorder | GSToolbarViewRightBorder | GSToolbarViewLeftBorder;
}
return self;
}
- (void) dealloc
{
RELEASE(_toolbar);
RELEASE(_clippedItemsMark);
RELEASE(_clipView);
[super dealloc];
}
// More overrided methods
- (void) drawRect: (NSRect)aRect
{
NSBezierPath *rect = [NSBezierPath bezierPathWithRect: aRect];
NSRect viewFrame = [self frame];
// We draw the background
[[NSColor colorWithDeviceRed: 0.8 green: 0.8 blue: 0.8 alpha:1] set];
[rect fill];
// We draw the border
[[NSColor colorWithDeviceRed: 0.5 green: 0.5 blue: 0.5 alpha:1] set];
if (_borderMask & GSToolbarViewBottomBorder)
{
[NSBezierPath strokeLineFromPoint: NSMakePoint(0, 0.5)
toPoint: NSMakePoint(viewFrame.size.width, 0.5)];
}
if (_borderMask & GSToolbarViewTopBorder)
{
[NSBezierPath strokeLineFromPoint: NSMakePoint(0, viewFrame.size.height - 0.5)
toPoint: NSMakePoint(viewFrame.size.width, viewFrame.size.height - 0.5)];
}
if (_borderMask & GSToolbarViewLeftBorder)
{
[NSBezierPath strokeLineFromPoint: NSMakePoint(0.5, 0)
toPoint: NSMakePoint(0.5, viewFrame.size.height)];
}
if (_borderMask & GSToolbarViewRightBorder)
{
[NSBezierPath strokeLineFromPoint: NSMakePoint(viewFrame.size.width - 0.5, 0)
toPoint: NSMakePoint(viewFrame.size.width - 0.5, viewFrame.size.height)];
}
[super drawRect: aRect];
}
- (BOOL) isOpaque
{
return YES;
}
- (void) windowDidResize: (NSNotification *)notification
{
if (![_toolbar isVisible]) return;
[self _handleViewsVisibility];
}
- (void) viewDidMoveToSuperview
{
// NSView method called when a view is moved not to a superview
if (_toolbar != nil)
{
[self _handleViewsVisibility];
}
}
- (void) viewDidMoveToWindow
{
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
// NSView method called when a view is moved to a window (NSView has a variable _window)
[super viewDidMoveToWindow];
[nc removeObserver: self name: NSWindowDidResizeNotification object: _window];
[nc addObserver: self selector: @selector(windowDidResize:) name: NSWindowDidResizeNotification object: nil];
[self viewDidMoveToSuperview];
}
// More methods... Accessors
- (unsigned int) borderMask
{
return _borderMask;
}
- (NSToolbar *) toolbar
{
return _toolbar;
}
- (void) setBorderMask: (unsigned int)borderMask
{
_borderMask = borderMask;
}
- (void) setToolbar: (NSToolbar *)toolbar
{
ASSIGN(_toolbar, toolbar);
[_clippedItemsMark setToolbar: _toolbar];
[_toolbar _build]; // Use the delegate to build the toolbar
[_toolbar _setToolbarView: self];
[self _reload]; // Load the toolbar in the toolbar view
}
// Private methods
- (void) _handleViewsOrigin
{
NSEnumerator *e = [[_toolbar items] objectEnumerator];
NSToolbarItem *item;
NSView *itemView;
NSRect itemViewFrame;
float x = 0.;
while ((item = [e nextObject]) != nil)
{
itemView = [item _backView];
if ([item _isFlexibleSpace])
{
[item _layout];
}
itemViewFrame = [itemView frame];
[itemView setFrame: NSMakeRect(x, itemViewFrame.origin.y, itemViewFrame.size.width, itemViewFrame.size.height)];
x += [itemView frame].size.width;
}
}
- (void) _handleViewsSize
{
NSEnumerator *e = [[_toolbar items] objectEnumerator];
NSToolbarItem *item;
NSView *itemView, *itemViewEdited;
NSArray *subviews = [self subviews];
while ((item = [e nextObject]) != nil)
{
itemView = [item _backView];
if (![subviews containsObject: itemView] || [item _isModified])
{
itemViewEdited = itemView;
}
// Example : when a label is changed, _isModified returns YES
// to let us known we must recalculate the text lenght and
// then the item view size with the subsequent arrangement
if (itemViewEdited != nil)
[item _layout];
}
}
- (void) _handleViewsVisibility
{
NSArray *items = [_toolbar items];
// the backViews which are associated with the toolbar items now (the toolbar items doesn't
// reflect the toolbar view content)
NSArray *itemBackViews = [items valueForKey: @"_backView"];
// the backViews which will be visible in the toolbar view (when _handleViewsVisibility will be terminated)
NSArray *visibleItemBackViews = [self _visibleBackViews];
// the backViews which are visible in the toolbar view now
NSArray *currentItemBackViews = [_clipView subviews];
NSEnumerator *e;
NSView *itemBackView;
NSRect clipViewFrame;
[self _handleViewsOrigin];
[self _takeInAccountFlexibleSpaces];
// We remove the _backView (itemBackView variable) associated with the removed or not visible
// toolbar items
e = [currentItemBackViews objectEnumerator];
while ((itemBackView = [e nextObject]) != nil)
{
if (![itemBackViews containsObject: itemBackView] || ![visibleItemBackViews containsObject: itemBackView])
{
if ([itemBackView superview] != nil)
[itemBackView removeFromSuperview];
}
}
// We add the _backView (itemBackView variable) associated with the added toolbar item when it
// is visible
e = [visibleItemBackViews objectEnumerator];
while ((itemBackView = [e nextObject]) != nil)
{
if (![currentItemBackViews containsObject: itemBackView])
{
[_clipView addSubview: itemBackView];
}
}
clipViewFrame = [_clipView frame];
if (([_clippedItemsMark superview] == nil) && ([visibleItemBackViews count] < [itemBackViews count]))
{
[_clipView setFrame: NSMakeRect(clipViewFrame.origin.x, clipViewFrame.origin.y,
clipViewFrame.size.width - _ClippedItemsViewWidth,
clipViewFrame.size.height)];
clipViewFrame = [_clipView frame]; // we get the new _clipView frame
[_clippedItemsMark setFrameOrigin: NSMakePoint(clipViewFrame.size.width,
clipViewFrame.origin.y)];
[self addSubview: _clippedItemsMark];
}
else if (([_clippedItemsMark superview] != nil) && ([visibleItemBackViews count] >=
[itemBackViews count]))
{
[_clippedItemsMark removeFromSuperview];
[_clipView setFrame: NSMakeRect(clipViewFrame.origin.x, clipViewFrame.origin.y,
clipViewFrame.size.width + _ClippedItemsViewWidth, clipViewFrame.size.height)];
}
[self setNeedsDisplay: YES];
}
- (void) _reload {
[self _handleViewsSize];
[self _handleViewsVisibility];
}
- (void) _takeInAccountFlexibleSpaces
{
NSArray *items = [_toolbar items];
NSEnumerator *e = [items objectEnumerator];
NSToolbarItem *item;
NSView *itemView;
NSRect lastItemViewFrame = [[[items lastObject] _backView] frame];
float lengthAvailable = [self frame].size.width - (lastItemViewFrame.origin.x +
lastItemViewFrame.size.width);
int flexibleSpaceItemsNumber = 0;
BOOL mustAdjustNext = NO;
float x = 0.;
if (lengthAvailable < 1)
return;
while ((item = [e nextObject]) != nil)
{
if ([item _isFlexibleSpace])
{
flexibleSpaceItemsNumber++;
}
}
if (lengthAvailable < flexibleSpaceItemsNumber)
return;
e = [items objectEnumerator];
while ((item = [e nextObject]) != nil)
{
itemView = [item _backView];
if ([item _isFlexibleSpace])
{
NSRect itemViewFrame = [itemView frame];
[itemView setFrame:
NSMakeRect(x, itemViewFrame.origin.y, lengthAvailable / flexibleSpaceItemsNumber,
itemViewFrame.size.height)];
mustAdjustNext = YES;
}
else if (mustAdjustNext)
{
NSRect itemViewFrame = [itemView frame];
[itemView setFrame: NSMakeRect(x, itemViewFrame.origin.y, itemViewFrame.size.width,
itemViewFrame.size.height)];
}
x += [itemView frame].size.width;
}
}
// Accessors private methods
- (NSArray *) _visibleBackViews
{
NSArray *items = [_toolbar items];
NSView *itemView;
int i, n = [items count];
float totalWidth = 0, toolbarWidth;
if (![_toolbar isVisible] && ![self _willBeVisible])
return nil;
[_visibleBackViews release];
_visibleBackViews = [[NSMutableArray alloc] init];
toolbarWidth = [self frame].size.width;;
for (i = 0; i < n; i++)
{
itemView = [[items objectAtIndex:i] _backView];
totalWidth += [itemView frame].size.width;
if ((totalWidth + _ClippedItemsViewWidth <= toolbarWidth) || (i == n - 1 && totalWidth <=
toolbarWidth))
{
[_visibleBackViews addObject: itemView];
}
}
return _visibleBackViews;
}
- (BOOL) _willBeVisible
{
return _willBeVisible;
}
- (void) _setWillBeVisible: (BOOL)willBeVisible
{
_willBeVisible = willBeVisible;
}
@end

View file

@ -413,21 +413,7 @@
- (BOOL) isOpaque
{
/*
* MacOS-X says we should return !transparent && [self isBordered],
* but that's wrong in our case, since if there is no border,
* we draw the interior of the cell to fill completely the bounds.
* They are likely to draw differently.
*/
// This seems the best to achieve a correct behaviour
// (consistent with Nextstep)
if (!(_cell.is_bordered
|| (_highlightsByMask & NSChangeBackgroundCellMask)
|| (_highlightsByMask & NSChangeGrayCellMask)))
return NO;
return !_buttoncell_is_transparent;
return !_buttoncell_is_transparent && _cell.is_bordered;
}
- (NSBezelStyle)bezelStyle
@ -706,15 +692,6 @@
cellFrame = NSOffsetRect(cellFrame, 1., flippedView ? 1. : -1.);
}
/* Determine the background color. */
if (mask & (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
{
backgroundColor = [NSColor selectedControlColor];
}
if (backgroundColor == nil)
backgroundColor = [NSColor controlBackgroundColor];
/* Draw the cell's background color.
We draw when there is a border or when highlightsByMask
is NSChangeBackgroundCellMask or NSChangeGrayCellMask,
@ -723,8 +700,22 @@
|| (_highlightsByMask & NSChangeBackgroundCellMask)
|| (_highlightsByMask & NSChangeGrayCellMask))
{
[backgroundColor set];
NSRectFill (cellFrame);
/* Determine the background color. */
if (mask & (NSChangeGrayCellMask | NSChangeBackgroundCellMask))
{
backgroundColor = [NSColor selectedControlColor];
}
else if (_cell.is_bordered)
{
backgroundColor = [NSColor controlBackgroundColor];
}
if (backgroundColor != nil)
{
[backgroundColor set];
NSRectFill (cellFrame);
}
}
/*
@ -800,10 +791,7 @@
titleRect = imageRect;
titleRect.origin.x += imageSize.width + xDist;
titleRect.size.width = cellFrame.size.width - imageSize.width - xDist;
if (_cell.is_bordered || _cell.is_bezeled)
{
titleRect.size.width -= 3;
}
titleRect.size.width -= 3;
break;
case NSImageRight:
@ -820,11 +808,8 @@
titleRect.origin = cellFrame.origin;
titleRect.size.width = cellFrame.size.width - imageSize.width - xDist;
titleRect.size.height = cellFrame.size.height;
if (_cell.is_bordered || _cell.is_bezeled)
{
titleRect.origin.x += 3;
titleRect.size.width -= 3;
}
titleRect.origin.x += 3;
titleRect.size.width -= 3;
break;
case NSImageAbove:
@ -847,14 +832,13 @@
if (_cell.is_bordered || _cell.is_bezeled)
{
imageRect.origin.x += 3;
imageRect.size.width -= 6;
imageRect.origin.x += 3;
titleRect.size.width -= 6;
titleRect.origin.x += 3;
imageRect.size.height -= 1;
titleRect.size.height -= 1;
titleRect.origin.y += 1;
}
titleRect.origin.x += 3;
titleRect.origin.y += 4;
titleRect.size.width -= 6;
break;
case NSImageBelow:
@ -879,12 +863,12 @@
{
imageRect.size.width -= 6;
imageRect.origin.x += 3;
titleRect.size.width -= 6;
titleRect.origin.x += 3;
imageRect.size.height -= 1;
imageRect.origin.y += 1;
titleRect.size.height -= 1;
}
titleRect.size.width -= 6;
titleRect.origin.x += 3;
titleRect.size.height -= 4;
break;
case NSImageOverlaps:
@ -919,12 +903,7 @@
if (_cell.shows_first_responder
&& [[controlView window] firstResponder] == controlView)
{
if (_cell.is_bordered || _cell.is_bezeled)
NSDottedFrameRect(cellFrame);
else if (ipos == NSImageOnly)
NSDottedFrameRect(cellFrame);
else
NSDottedFrameRect(titleRect);
}
}

View file

@ -32,74 +32,75 @@
#include <Foundation/NSDictionary.h>
#include <Foundation/NSException.h>
#include <Foundation/NSNotification.h>
#include <Foundation/NSLock.h>
#include <Foundation/NSUserDefaults.h>
#include "AppKit/NSToolbarItem.h"
#include "AppKit/NSToolbar.h"
#include "AppKit/NSView.h"
#include "AppKit/NSClipView.h"
#include "AppKit/NSButton.h"
#include "AppKit/NSNibLoading.h"
#include "AppKit/NSBezierPath.h"
#include "AppKit/NSImage.h"
#include "AppKit/NSMenu.h"
#include "AppKit/NSEvent.h"
#include "AppKit/NSWindow.h"
#include "GNUstepGUI/GSToolbarView.h"
// internal
static NSNotificationCenter *nc = nil;
static const int current_version = 1;
@implementation GSToolbarView
- (id) initWithToolbar: (NSToolbar *)toolbar
{
if((self = [super init]) != nil)
{
ASSIGN(_toolbar,toolbar);
}
return self;
}
static NSMutableArray *toolbars;
- (void) dealloc
{
RELEASE(_toolbar);
[super dealloc];
}
- (void) setToolbar: (NSToolbar *)toolbar
{
ASSIGN(_toolbar, toolbar);
}
- (NSToolbar *) toolbar
{
return _toolbar;
}
@interface NSToolbar (GNUstepPrivate)
// Private class methods
+ (NSArray *) _toolbars;
+ (NSArray *) _toolbarsForIdentifier: (NSString *)identifier;
- (void) drawRect: (NSRect)aRect
{
NSArray *items = [_toolbar items];
NSEnumerator *en = [items objectEnumerator];
id item = nil;
float x = 0;
// ---
[super drawRect: aRect];
while((item = [en nextObject]) != nil)
{
NSView *itemView = [item view];
NSRect itemFrame = [itemView frame];
- (void) _insertItemWithItemIdentifier: (NSString *)itemIdentifier atIndex: (int)index broadcast: (BOOL)broadcast;
// now we need to draw the items...
itemFrame.origin.x = x; // start at x
itemFrame.origin.y = 0; // reset to top of view.
[itemView drawRect: itemFrame];
x += NSWidth(itemFrame) + 2; // move over by the frame width plus 2 pixels.
}
}
// Private methods with broacast support
- (void) _insertItemWithItemIdentifier: (NSString *)itemIdentifier atIndex: (int)index broadcast: (BOOL)broadcast;
- (void) _removeItemAtIndex: (int)index broadcast: (BOOL)broadcast;
- (void) _setAllowsUserCustomization: (BOOL)flag broadcast: (BOOL)broadcast;
- (void) _setAutosavesConfiguration: (BOOL)flag broadcast: (BOOL)broadcast;
- (void) _setConfigurationFromDictionary: (NSDictionary *)configDict broadcast: (BOOL)broadcast;
- (void) _setDisplayMode: (NSToolbarDisplayMode)displayMode broadcast: (BOOL)broadcast;
- (void) _setVisible: (BOOL)shown broadcast: (BOOL)broadcast;
- (void) _setDelegate: (id)delegate broadcast: (BOOL)broadcast;
// Few other private methods
- (void) _build;
- (void) _loadConfig;
// Accessors
- (void) _setToolbarView: (GSToolbarView *)toolbarView;
- (GSToolbarView *) _toolbarView;
- (void) _setWindow: (NSWindow *)window;
- (NSWindow *) _window;
@end
@implementation NSToolbar (GNUstepPrivate)
- (id) _toolbarView
{
return _toolbarView;
}
@interface NSToolbarItem (GNUstepPrivate)
- (void) _setToolbar: (NSToolbar *)toolbar;
@end
@interface GSToolbarView (GNUstepPrivate)
- (void) _reload;
- (NSArray *) _visibleBackViews;
- (BOOL) _willBeVisible;
- (void) _setWillBeVisible: (BOOL)willBeVisible;
@end
// ---
@implementation NSToolbar
// Class methods
// Initialize the class when it is loaded
+ (void) initialize
{
@ -107,10 +108,142 @@ static const int current_version = 1;
{
[self setVersion: current_version];
nc = [NSNotificationCenter defaultCenter];
toolbars = [[NSMutableArray alloc] init];
}
}
// Private class methods
+ (NSArray *) _toolbars
{
return toolbars;
}
+ (NSArray *) _toolbarsForIdentifier: (NSString *)identifier
{
NSMutableArray *wanted = [[NSMutableArray alloc] init];
NSArray *identifiers = [toolbars valueForKey: @"identifier"];
int i, n;
if (identifiers == nil)
return nil;
n = [identifiers count];
for (i = 0; i < n; i++)
{
if ([[identifiers objectAtIndex: i] isEqualToString: identifier])
{
[wanted addObject: [toolbars objectAtIndex: i]];
}
}
return wanted;
}
// ---
// Instance methods
- (id) initWithIdentifier: (NSString*)identifier
{
NSArray *linked;
NSToolbar *toolbarModel = nil;
[super init];
ASSIGN(_identifier, identifier);
_items = [[NSMutableArray alloc] init];
linked = [NSToolbar _toolbarsForIdentifier: _identifier];
if (linked != nil && [linked count] > 0)
{
toolbarModel = [linked objectAtIndex: 0];
}
if (toolbarModel != nil)
{
_customizationPaletteIsRunning = NO;
_allowsUserCustomization = [toolbarModel allowsUserCustomization];
_autosavesConfiguration = [toolbarModel autosavesConfiguration];
ASSIGN(_configurationDictionary, [toolbarModel configurationDictionary]);
_displayMode = [toolbarModel displayMode];
_visible = [toolbarModel isVisible];
//[self _loadConfig];
[self _setDelegate: [toolbarModel delegate] broadcast: NO];
}
else
{
_customizationPaletteIsRunning = NO;
_allowsUserCustomization = NO;
_autosavesConfiguration = NO;
_configurationDictionary = nil;
_displayMode = NSToolbarDisplayModeDefault;
_visible = YES;
_items = [[NSMutableArray alloc] init];
[self _loadConfig];
_delegate = nil;
}
[toolbars addObject: self];
return self;
}
- (void) dealloc
{
DESTROY (_identifier);
DESTROY (_configurationDictionary);
if (_delegate != nil)
{
[nc removeObserver: _delegate name: nil object: self];
_delegate = nil;
}
[super dealloc];
}
- (void) insertItemWithItemIdentifier: (NSString *)itemIdentifier
atIndex: (int)index
{
[self _insertItemWithItemIdentifier: itemIdentifier atIndex: index broadcast: YES];
}
- (void) removeItemAtIndex: (int)index
{
[self _removeItemAtIndex: index broadcast: YES];
}
- (void) runCustomizationPalette: (id)sender
{
_customizationPaletteIsRunning = [NSBundle loadNibNamed: @"GSToolbarCustomizationPalette"
owner: self];
if(!_customizationPaletteIsRunning)
{
NSLog(@"Failed to load gorm for GSToolbarCustomizationPalette");
}
}
- (void) validateVisibleItems
{
NSEnumerator *en = [[self visibleItems] objectEnumerator];
NSToolbarItem *item = nil;
while((item = [en nextObject]) != nil)
{
[item validate];
}
}
// Accessors
- (BOOL) allowsUserCustomization
{
return _allowsUserCustomization;
@ -146,6 +279,118 @@ static const int current_version = 1;
return _identifier;
}
- (BOOL) isVisible
{
return _visible;
}
- (NSArray *) items
{
return _items;
}
- (NSString *) selectedItemIdentifier
{
return nil;
}
- (NSArray *) visibleItems
{
return [[_toolbarView _visibleBackViews] valueForKey: @"toolbarItem"];
}
- (void) setAllowsUserCustomization: (BOOL)flag
{
[self _setAllowsUserCustomization: flag broadcast: YES];
}
- (void) setAutosavesConfiguration: (BOOL)flag
{
[self _setAutosavesConfiguration: flag broadcast: YES];
}
- (void) setConfigurationFromDictionary: (NSDictionary *)configDict
{
ASSIGN(_configurationDictionary, configDict);
}
/**
* Sets the receivers delegate ... this is the object which will receive
* -toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:
* -toolbarAllowedItemIdentifiers: and -toolbarDefaultItemIdentifiers:
* messages.
*/
- (void) setDelegate: (id)delegate
{
[self _setDelegate: delegate broadcast: YES];
}
- (void) setDisplayMode: (NSToolbarDisplayMode)displayMode
{
[self _setDisplayMode: displayMode broadcast: YES];
}
- (void) setSelectedItemIdentifier: (NSString *)itemIdentifier
{
}
- (void) setSizeMode: (NSToolbarSizeMode)sizeMode
{
}
- (void) setVisible: (BOOL)shown
{
[self _setVisible: shown broadcast: NO];
}
- (NSToolbarSizeMode) sizeMode
{
return 0;
}
// Private methods
- (void) _build
{
/*
* toolbar build :
* will use the delegate when there is no toolbar model
*/
NSToolbar *toolbarModel;
NSArray *wantedItemIdentifiers;
NSEnumerator *e;
id itemIdentifier;
int i = 0;
_build = YES;
RELEASE(_items);
_items = [[NSMutableArray alloc] init];
toolbarModel = [[NSToolbar _toolbarsForIdentifier: _identifier] objectAtIndex: 0];
if (toolbarModel != nil && toolbarModel != self)
{
wantedItemIdentifiers = [[toolbarModel items] valueForKey: @"itemIdentifier"];
}
else
{
wantedItemIdentifiers = [_delegate toolbarDefaultItemIdentifiers:self];
}
e = [wantedItemIdentifiers objectEnumerator];
while ((itemIdentifier = [e nextObject]) != nil)
{
[self _insertItemWithItemIdentifier: itemIdentifier atIndex: i broadcast: NO];
i++;
}
_build = NO;
}
- (void) _loadConfig
{
if(_identifier != nil)
@ -165,156 +410,192 @@ static const int current_version = 1;
}
}
- (id) initWithIdentifier: (NSString*)identifier
{
[super init];
/*
*
* The methods below handles the toolbar edition and broacasts each associated event
* to the other toolbars with identical identifiers.
*
*/
_customizationPaletteIsRunning = NO;
_allowsUserCustomization = NO;
_autosavesConfiguration = NO;
_configurationDictionary = nil;
_delegate = nil;
_displayMode = NSToolbarDisplayModeDefault;
_visible = YES;
_items = nil;
_visibleItems = nil;
ASSIGN(_identifier, identifier);
[self _loadConfig];
return self;
}
- (void) dealloc
{
DESTROY (_identifier);
DESTROY (_configurationDictionary);
if (_delegate != nil)
{
[nc removeObserver: _delegate name: nil object: self];
_delegate = nil;
#define TRANSMIT(signature) \
NSEnumerator *e = [[NSToolbar _toolbarsForIdentifier: _identifier] objectEnumerator]; \
NSToolbar *toolbar; \
\
while ((toolbar = [e nextObject]) != nil) \
{ \
if (toolbar != self) \
[toolbar signature]; \
}
[super dealloc];
}
- (void) insertItemWithItemIdentifier: (NSString *)itemIdentifier
atIndex: (int)index
- (void) _insertItemWithItemIdentifier: (NSString *)itemIdentifier atIndex: (int)index broadcast: (BOOL)broadcast
{
NSToolbarItem *item = nil;
NSArray *allowedItems = [_delegate toolbarAllowedItemIdentifiers: self];
if([allowedItems containsObject: itemIdentifier])
{
item = [_delegate toolbar: self
itemForItemIdentifier: itemIdentifier
willBeInsertedIntoToolbar: YES];
[nc postNotificationName: NSToolbarWillAddItemNotification
object: self];
[_items insertObject: item atIndex: index];
}
itemForItemIdentifier: itemIdentifier
willBeInsertedIntoToolbar: YES];
if (item != nil)
{
[nc postNotificationName: NSToolbarWillAddItemNotification object: self];
[item _setToolbar: self];
[_items insertObject: item atIndex: index];
if (!_build) // we reload the toolbarView each time a new item is added except when we build/create the toolbar
[_toolbarView _reload];
if (broadcast)
{
TRANSMIT(_insertItemWithItemIdentifier: itemIdentifier atIndex: index broadcast: NO);
}
}
}
}
- (BOOL) isVisible
{
return _visible;
}
- (NSArray *) items
{
return _items;
}
- (void) removeItemAtIndex: (int)index
- (void) _removeItemAtIndex: (int)index broadcast: (BOOL)broadcast
{
id obj = [_items objectAtIndex: index];
[_items removeObjectAtIndex: index];
[_visibleItems removeObject: obj];
[_toolbarView _reload];
[nc postNotificationName: NSToolbarDidRemoveItemNotification
object: self];
}
- (void) runCustomizationPalette: (id)sender
{
_customizationPaletteIsRunning = [NSBundle loadNibNamed: @"GSToolbarCustomizationPalette"
owner: self];
if(!_customizationPaletteIsRunning)
if (broadcast)
{
NSLog(@"Failed to load gorm for GSToolbarCustomizationPalette");
TRANSMIT(_removeItemAtIndex: index broadcast: NO);
}
}
- (void) setAllowsUserCustomization: (BOOL)flag
- (void) _setAllowsUserCustomization: (BOOL)flag broadcast: (BOOL)broadcast
{
_allowsUserCustomization = flag;
if (broadcast)
{
TRANSMIT(_setAllowsUserCustomization: _allowsUserCustomization broadcast: NO);
}
}
- (void) setAutosavesConfiguration: (BOOL)flag
- (void) _setAutosavesConfiguration: (BOOL)flag broadcast: (BOOL)broadcast
{
_autosavesConfiguration = flag;
if (broadcast)
{
TRANSMIT(_setAutosavesConfiguration: _autosavesConfiguration broadcast: NO);
}
}
- (void) setConfigurationFromDictionary: (NSDictionary *)configDict
- (void) _setConfigurationFromDictionary: (NSDictionary *)configDict broadcast: (BOOL)broadcast
{
ASSIGN(_configurationDictionary, configDict);
if (broadcast)
{
TRANSMIT(_setConfigurationFromDictionary: _configurationDictionary broadcast: NO);
}
}
/**
* Sets the receivers delgate ... this is the object which will receive
* -toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:
* -toolbarAllowedItemIdentifiers: and -toolbarDefaultItemIdentifiers:
* messages.
*/
- (void) setDelegate: (id)delegate
{
#define CHECK_REQUIRED_METHOD(selector_name) \
- (void) _setDisplayMode: (NSToolbarDisplayMode)displayMode broadcast: (BOOL)broadcast
{
_displayMode = displayMode;
if (broadcast)
{
TRANSMIT(_setDisplayMode: _displayMode broadcast: NO);
}
}
- (void) _setVisible: (BOOL)shown broadcast: (BOOL)broadcast
{
if (_visible != shown)
{
if (_window)
{
if (shown)
[_toolbarView _setWillBeVisible: YES];
[_window toggleToolbarShown: self];
[_toolbarView _setWillBeVisible: NO];
_visible = shown;
// Important to set _visible after the toolbar has been toggled
// because NSWindow method contentViewWithoutToolbar uses [NSToolbar visible]
// when we toggle the toolbar
}
else
{
NSLog(@"setVisible: doesn't work because the toolbar is not a window toolbar.");
}
}
if (broadcast)
{
TRANSMIT(_setVisible: _visible broadcast: NO);
}
}
- (void)_setDelegate: (id)delegate broadcast: (BOOL)broadcast
{
#define CHECK_REQUIRED_METHOD(selector_name) \
if (![delegate respondsToSelector: @selector(selector_name)]) \
[NSException raise: NSInternalInconsistencyException \
format: @"delegate does not respond to %@",@#selector_name]
format: @"delegate does not respond to %@",@#selector_name]
CHECK_REQUIRED_METHOD(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:);
CHECK_REQUIRED_METHOD(toolbarAllowedItemIdentifiers:);
CHECK_REQUIRED_METHOD(toolbarDefaultItemIdentifiers:);
if (_delegate)
if (_delegate)
[nc removeObserver: _delegate name: nil object: self];
_delegate = delegate;
#define SET_DELEGATE_NOTIFICATION(notif_name) \
#define SET_DELEGATE_NOTIFICATION(notif_name) \
if ([_delegate respondsToSelector: @selector(toolbar##notif_name:)]) \
[nc addObserver: _delegate \
selector: @selector(toolbar##notif_name:) \
name: NSToolbar##notif_name##Notification object: self]
selector: @selector(toolbar##notif_name:) \
name: NSToolbar##notif_name##Notification object: self]
SET_DELEGATE_NOTIFICATION(DidRemoveItem);
SET_DELEGATE_NOTIFICATION(WillAddItem);
}
- (void) setDisplayMode: (NSToolbarDisplayMode)displayMode
{
_displayMode = displayMode;
}
- (void) setVisible: (BOOL)shown
{
_visible = shown;
}
- (void) validateVisibleItems
{
NSEnumerator *en = [_visibleItems objectEnumerator];
NSToolbarItem *item = nil;
while((item = [en nextObject]) != nil)
if (_window != nil) // The delegate should be called when the toolbar will become visible (= window not nil)
{
[item validate];
[self _build]; // Build the toolbar with the delegate or a toolbar model
[_toolbarView _reload];
}
// broadcast now...
if (broadcast)
{
TRANSMIT(_setDelegate: _delegate broadcast: NO);
}
}
- (NSArray *) visibleItems
// Private Accessors
- (void) _setToolbarView: (GSToolbarView *)toolbarView
{
return _visibleItems;
ASSIGN(_toolbarView, toolbarView);
}
@end /* interface of NSToolbar */
- (GSToolbarView *) _toolbarView
{
return _toolbarView;
}
- (void)_setWindow: (NSWindow *)window
{
ASSIGN(_window, window); // call [NSWindow(Toolbar) setToolbar:] to set the toolbar window
}
- (NSWindow *) _window
{
return _window;
}
@end

View file

@ -29,11 +29,393 @@
#include <Foundation/NSObject.h>
#include <Foundation/NSString.h>
#include <Foundation/NSDebug.h>
#include "AppKit/NSToolbarItem.h"
#include "AppKit/NSToolbar.h"
#include "AppKit/NSMenu.h"
#include "AppKit/NSMenuItem.h"
#include "AppKit/NSImage.h"
#include "AppKit/NSButton.h"
#include "AppKit/NSFont.h"
#include "AppKit/NSEvent.h"
#include "GNUstepGUI/GSToolbarView.h"
/*
* Each NSToolbarItem object are coupled with a backView which is their representation
* on the screen.
* backView for the standard toolbar item (without custom view) are NSButton subclass
* called GSToolbarButton.
* backView for the toolbar item with a custom view are NSView subclass called
* GSToolbarBackView.
* GSToolbarButton and GSToolbarBackView are adjusted according to their content and
* their title when the method layout is called.
* The predefined GNUstep toolbar items are implemented with a class cluster pattern :
* initWithToolbarItemIdentifier: returns differents concrete subclass in accordance
* with the item identifier.
*/
@interface NSToolbar (GNUstepPrivate)
- (GSToolbarView *) _toolbarView;
@end
@interface NSToolbarItem (GNUstepPrivate)
- (void) _layout;
- (NSView *) _backView;
- (BOOL) _isUpdated;
- (BOOL) _isFlexibleSpace;
- (void) _setToolbar: (NSToolbar *)toolbar;
@end
@interface GSToolbarView (GNUstepPrivate)
- (void) _reload;
@end
/*
* NSButton subclass is the toolbar buttons _backView
*/
@interface GSToolbarButton : NSButton
{
NSToolbarItem *_toolbarItem;
}
- (id) initWithToolbarItem: (NSToolbarItem *)toolbarItem;
- (void) layout;
- (NSToolbarItem *) toolbarItem;
@end
@implementation GSToolbarButton
- (id) initWithToolbarItem: (NSToolbarItem *)toolbarItem
{
self = [super initWithFrame: NSMakeRect(_ItemBackViewX, _ItemBackViewY, _ItemBackViewDefaultWidth, _ItemBackViewDefaultHeight)];
if (self != nil)
{
ASSIGN(_toolbarItem, toolbarItem);
}
return self;
}
- (void) layout
{
float textWidth, layoutedWidth;
NSAttributedString *attrStr;
NSDictionary *attr;
NSFont *font =[NSFont systemFontOfSize: 11]; // [NSFont smallSystemFontSize] or better should NSControlContentFontSize
attr = [NSDictionary dictionaryWithObject: font forKey: @"NSFontAttributeName"];
attrStr = [[NSAttributedString alloc] initWithString: [_toolbarItem label] attributes: attr];
textWidth = [attrStr size].width + 2 * _InsetItemTextX;
if (textWidth > _ItemBackViewDefaultWidth)
{
layoutedWidth = textWidth;
}
else
{
layoutedWidth = _ItemBackViewDefaultWidth;
}
[self setFrameSize: NSMakeSize(layoutedWidth, _ItemBackViewDefaultHeight)];
}
- (NSToolbarItem *) toolbarItem
{
return _toolbarItem;
}
@end
/*
* Back view used to enclose toolbar item's custom view
*/
@interface GSToolbarBackView : NSView
{
NSToolbarItem *_toolbarItem;
BOOL _enabled;
}
- (id) initWithToolbarItem: (NSToolbarItem *)toolbarItem;
- (NSToolbarItem *) toolbarItem;
- (void) setEnabled: (BOOL)enabled;
@end
@implementation GSToolbarBackView
- (id)initWithToolbarItem: (NSToolbarItem *)toolbarItem
{
self = [super initWithFrame: NSMakeRect(_ItemBackViewX, _ItemBackViewY, _ItemBackViewDefaultWidth,
_ItemBackViewDefaultHeight)];
if (self != nil)
{
ASSIGN(_toolbarItem, toolbarItem);
}
return self;
}
- (void)drawRect: (NSRect)rect
{
NSAttributedString *attrString;
NSDictionary *attr;
NSFont *font = [NSFont systemFontOfSize: 11]; // [NSFont smallSystemFontSize] or better should be NSControlContentFontSize
int textX;
[super drawRect: rect]; // We draw _view which is a subview
if (_enabled)
{
[[NSColor blackColor] set];
}
else
{
[[NSColor grayColor] set];
}
attr = [NSDictionary dictionaryWithObject: font forKey: @"NSFontAttributeName"];
attrString = [[NSAttributedString alloc] initWithString: [_toolbarItem label] attributes: attr]; // we draw the label
textX = (([self frame].size.width - _InsetItemTextX) - [attrString size].width) / 2;
[attrString drawAtPoint: NSMakePoint(textX, _InsetItemTextY)];
}
- (void) layout
{
NSView *view;
float textWidth;
NSAttributedString *attrStr;
NSDictionary *attr;
NSFont *font = [NSFont systemFontOfSize: 11]; // [NSFont smallSystemFontSize] or better should be NSControlContentFontSize
view = [_toolbarItem view];
if ([view frame].size.height <= _ItemBackViewDefaultHeight)
{
[view setFrameOrigin: NSMakePoint(_InsetItemViewX, _InsetItemViewY)];
[self addSubview: view];
}
else
{
[view removeFromSuperview];
}
[self setFrameSize: NSMakeSize([view frame].size.width + 2 * _InsetItemViewX, _ItemBackViewDefaultHeight)];
attr = [NSDictionary dictionaryWithObject: font forKey: @"NSFontAttributeName"];
attrStr = [[NSAttributedString alloc] initWithString: [_toolbarItem label] attributes: attr];
textWidth = [attrStr size].width + 2 * _InsetItemTextX;
if (textWidth > [self frame].size.width)
{
[self setFrameSize: NSMakeSize(textWidth, _ItemBackViewDefaultHeight)];
[view setFrameOrigin: NSMakePoint((textWidth - [view frame].size.width) / 2, _InsetItemViewY)];
}
}
- (NSToolbarItem *)toolbarItem
{
return _toolbarItem;
}
- (void) setEnabled: (BOOL)enabled
{
id view = [_toolbarItem view];
_enabled = enabled;
if ([view respondsToSelector: @selector(setEnabled:)])
{
[view setEnabled: enabled];
}
}
@end
/*
*
* Standard toolbar items.
*
*/
// ---- NSToolbarSeparatorItemIdentifier
@interface GSToolbarSeparatorItem : NSToolbarItem
{
}
@end
@implementation GSToolbarSeparatorItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarSeperatorItem"];
self = [super initWithItemIdentifier: itemIdentifier];
[(NSButton *)[self _backView] setImagePosition: NSImageOnly];
[(NSButton *)[self _backView] setImage: image];
// We bypass the toolbar item accessor to set the image in order to have it (48 * 48) not resized
[[self _backView] setFrameSize: NSMakeSize(15, _ItemBackViewDefaultHeight)];
return self;
}
- (NSMenuItem *) menuFormRepresentation
{
return nil; // override the default implementation in order to do nothing
}
- (void) _layout
{
// override the default implementation in order to do nothing
}
@end
// ---- NSToolbarSpaceItemIdentifier
@interface GSToolbarSpaceItem : NSToolbarItem
{
}
@end
@implementation GSToolbarSpaceItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
self = [super initWithItemIdentifier: itemIdentifier];
[self setLabel: @""];
return self;
}
- (NSMenuItem *) menuFormRepresentation
{
return nil;// override the default implementation in order to do nothing
}
- (void) _layout
{
// override the default implementation in order to do nothing
}
@end
// ---- NSToolbarFlexibleSpaceItemIdentifier
@interface GSToolbarFlexibleSpaceItem : NSToolbarItem
{
}
@end
@implementation GSToolbarFlexibleSpaceItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
self = [super initWithItemIdentifier: itemIdentifier];
[self setLabel: @""];
[self _layout];
return self;
}
- (NSMenuItem *) menuFormRepresentation
{
return nil;// override the default implementation in order to do nothing
}
- (void) _layout
{
NSView *backView = [self _backView];
[backView setFrameSize: NSMakeSize(0, [backView frame].size.height)];
// override the default implementation in order to reset the _backView to a zero width
}
@end
// ---- NSToolbarShowColorsItemIdentifier
@interface GSToolbarShowColorsItem : NSToolbarItem
{
}
@end
@implementation GSToolbarShowColorsItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarShowColorsItem"];
self = [super initWithItemIdentifier: itemIdentifier];
[self setImage: image];
[self setLabel: @"Colors"];
// set action...
[self setTarget: nil]; // goes to first responder..
[self setAction: @selector(orderFrontColorPanel:)];
return self;
}
@end
// ---- NSToolbarShowFontsItemIdentifier
@interface GSToolbarShowFontsItem : NSToolbarItem
{
}
@end
@implementation GSToolbarShowFontsItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarShowFontsItem"];
self = [super initWithItemIdentifier: itemIdentifier];
[self setImage: image];
[self setLabel: @"Fonts"];
// set action...
[self setTarget: nil]; // goes to first responder..
[self setAction: @selector(orderFrontFontPanel:)];
return self;
}
@end
// ---- NSToolbarCustomizeToolbarItemIdentifier
@interface GSToolbarCustomizeToolbarItem : NSToolbarItem
{
}
@end
@implementation GSToolbarCustomizeToolbarItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarCustomizeToolbarItem"];
self = [super initWithItemIdentifier: itemIdentifier];
[self setImage: image];
[self setLabel: @"Customize"];
// set action...
[self setTarget: nil]; // goes to first responder..
[self setAction: @selector(runCustomizationPalette:)];
return self;
}
@end
// ---- NSToolbarPrintItemIdentifier
@interface GSToolbarPrintItem : NSToolbarItem
{
}
@end
@implementation GSToolbarPrintItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_Printer"];
self = [super initWithItemIdentifier: itemIdentifier];
[self setImage: image];
[self setLabel: @"Print..."];
// set action...
[self setTarget: nil]; // goes to first responder..
[self setAction: @selector(print:)];
return self;
}
@end
@implementation NSToolbarItem
- (BOOL)allowsDuplicatesInToolbar
@ -45,14 +427,105 @@
{
if(_flags._image)
{
return [_view image];
return [(id)_backView image];
}
return nil;
}
- (id)initWithItemIdentifier: (NSString *)itemIdentifier
{
ASSIGN(_itemIdentifier,itemIdentifier);
GSToolbarButton *button;
NSButtonCell *cell;
if ((self = [super init]) != nil)
{
// GNUstep predefined toolbar items
if ([itemIdentifier isEqualToString: @"NSToolbarSeparatorItemIdentifier"]
&& ![self isKindOfClass:[GSToolbarSeparatorItem class]])
{
[self release];
self = [[GSToolbarSeparatorItem alloc] initWithItemIdentifier: itemIdentifier];
}
else if ([itemIdentifier isEqualToString: @"NSToolbarSpaceItemIdentifier"]
&& ![self isKindOfClass:[GSToolbarSpaceItem class]])
{
[self release];
self = [[GSToolbarSpaceItem alloc] initWithItemIdentifier: itemIdentifier];
}
else if ([itemIdentifier isEqualToString: @"NSToolbarFlexibleSpaceItemIdentifier"]
&& ![self isKindOfClass:[GSToolbarFlexibleSpaceItem class]])
{
[self release];
self = [[GSToolbarFlexibleSpaceItem alloc] initWithItemIdentifier: itemIdentifier];
}
else if ([itemIdentifier isEqualToString: @"NSToolbarShowColorsItemIdentifier"]
&& ![self isKindOfClass:[GSToolbarShowColorsItem class]])
{
[self release];
self = [[GSToolbarShowColorsItem alloc] initWithItemIdentifier: itemIdentifier];
}
else if ([itemIdentifier isEqualToString: @"NSToolbarShowFontsItemIdentifier"]
&& ![self isKindOfClass:[GSToolbarShowFontsItem class]])
{
[self release];
self = [[GSToolbarShowFontsItem alloc] initWithItemIdentifier: itemIdentifier];
}
else if ([itemIdentifier isEqualToString: @"NSToolbarCustomizeToolbarItemIdentifier"]
&& ![self isKindOfClass:[GSToolbarCustomizeToolbarItem class]])
{
[self release];
self = [[GSToolbarCustomizeToolbarItem alloc] initWithItemIdentifier: itemIdentifier];
}
else if ([itemIdentifier isEqualToString: @"NSToolbarPrintItemIdentifier"]
&& ![self isKindOfClass:[GSToolbarPrintItem class]])
{
[self release];
self = [[GSToolbarPrintItem alloc] initWithItemIdentifier: itemIdentifier];
}
// Normal toolbar items
else
{
ASSIGN(_itemIdentifier, itemIdentifier);
button = [[GSToolbarButton alloc] initWithToolbarItem: self];
cell = [button cell];
[button setTitle: @""];
[button setEnabled: NO];
[button setBordered: NO];
[button setImagePosition: NSImageAbove];
[cell setBezeled: YES];
[cell setHighlightsBy: NSChangeGrayCellMask | NSChangeBackgroundCellMask];
[cell setFont: [NSFont systemFontOfSize: 11]]; // [NSFont smallSystemFontSize] or better should be controlContentFontSize
[_backView release];
_backView = button;
}
// gets
_flags._isEnabled = [_backView respondsToSelector: @selector(isEnabled)];
_flags._tag = YES;
_flags._action = [_backView respondsToSelector: @selector(action)];
_flags._target = [_backView respondsToSelector: @selector(target)];
_flags._image = [_backView respondsToSelector: @selector(image)];
// sets
_flags._setEnabled = [_backView respondsToSelector: @selector(setEnabled:)];
_flags._setTag = YES;
_flags._setAction = [_backView respondsToSelector: @selector(setAction:)];
_flags._setTarget = [_backView respondsToSelector: @selector(setTarget:)];
_flags._setImage = [_backView respondsToSelector: @selector(setImage:)];
}
return self;
}
@ -60,7 +533,7 @@
{
if(_flags._isEnabled)
{
return [_view isEnabled];
return [(id)_backView isEnabled];
}
return NO;
}
@ -82,7 +555,22 @@
- (NSMenuItem *)menuFormRepresentation
{
return _menuFormRepresentation;
NSMenuItem *menuItem;
if (_menuFormRepresentation == nil)
{
menuItem = [[NSMenuItem alloc] initWithTitle: [self label]
action: [self action]
keyEquivalent: @""];
[menuItem setTarget: [self target]];
AUTORELEASE(menuItem);
}
else
{
menuItem = [_menuFormRepresentation copy];
}
return menuItem;
}
- (NSSize)minSize
@ -99,29 +587,49 @@
{
if(_flags._setAction)
{
[_view setAction: action];
if ([_backView isKindOfClass: [NSButton class]])
[(NSButton *)_backView setAction: action];
if (action != NULL)
{
[(NSButton *)_backView setEnabled: YES];
}
else
{
[(NSButton *)_backView setEnabled: NO];
}
}
}
- (void)setEnabled: (BOOL)enabled
{
if(_flags._setEnabled)
{
[_view setEnabled: enabled];
}
[(id)_backView setEnabled: enabled];
}
- (void)setImage: (NSImage *)image
{
if(_flags._setImage)
{
[_view setImage: image];
{
ASSIGN(_image, image);
[_image setScalesWhenResized: YES];
[_image setSize: NSMakeSize(32, 32)];
if ([_backView isKindOfClass: [NSButton class]])
[(NSButton *)_backView setImage: _image];
}
}
- (void)setLabel: (NSString *)label
{
ASSIGN(_label, label);
if ([_backView isKindOfClass: [NSButton class]])
[(NSButton *)_backView setTitle:_label];
_updated = YES;
if (_toolbar != nil)
[[_toolbar _toolbarView] _reload];
}
- (void)setMaxSize: (NSSize)maxSize
@ -147,17 +655,16 @@
- (void)setTag: (int)tag
{
if(_flags._tag)
{
[_view setTag: tag];
}
[_backView setTag: tag];
}
- (void)setTarget: (id)target
{
{
if(_flags._target)
{
[_view setTarget: target];
}
{
if ([_backView isKindOfClass: [NSButton class]])
[(NSButton *)_backView setTarget: target];
}
}
- (void)setToolTip: (NSString *)toolTip
@ -168,26 +675,43 @@
- (void)setView: (NSView *)view
{
ASSIGN(_view, view);
// gets
_flags._isEnabled = [_view respondsToSelector: @selector(isEnabled)];
_flags._tag = [_view respondsToSelector: @selector(tag)];
_flags._action = [_view respondsToSelector: @selector(action)];
_flags._target = [_view respondsToSelector: @selector(target)];
_flags._image = [_view respondsToSelector: @selector(image)];
// sets
_flags._setEnabled = [_view respondsToSelector: @selector(setEnabled:)];
_flags._setTag = [_view respondsToSelector: @selector(setTag:)];
_flags._setAction = [_view respondsToSelector: @selector(setAction:)];
_flags._setTarget = [_view respondsToSelector: @selector(setTarget:)];
_flags._setImage = [_view respondsToSelector: @selector(setImage:)];
if (_view == nil)
{
// gets
_flags._isEnabled = [_backView respondsToSelector: @selector(isEnabled)];
_flags._action = [_backView respondsToSelector: @selector(action)];
_flags._target = [_backView respondsToSelector: @selector(target)];
_flags._image = [_backView respondsToSelector: @selector(image)];
// sets
_flags._setEnabled = [_backView respondsToSelector: @selector(setEnabled:)];
_flags._setAction = [_backView respondsToSelector: @selector(setAction:)];
_flags._setTarget = [_backView respondsToSelector: @selector(setTarget:)];
_flags._setImage = [_backView respondsToSelector: @selector(setImage:)];
}
else
{
// gets
_flags._isEnabled = [_view respondsToSelector: @selector(isEnabled)];
_flags._action = [_view respondsToSelector: @selector(action)];
_flags._target = [_view respondsToSelector: @selector(target)];
_flags._image = [_backView respondsToSelector: @selector(image)];
// sets
_flags._setEnabled = [_view respondsToSelector: @selector(setEnabled:)];
_flags._setAction = [_view respondsToSelector: @selector(setAction:)];
_flags._setTarget = [_view respondsToSelector: @selector(setTarget:)];
_flags._setImage = [_backView respondsToSelector: @selector(setImage:)];
}
[_backView release];
_backView = [[GSToolbarBackView alloc] initWithToolbarItem: self];
}
- (int)tag
{
if(_flags._tag)
{
return [_view tag];
}
return [_backView tag];
return 0;
}
@ -212,12 +736,40 @@
return _view;
}
// Private or package like visibility methods
- (NSView *)_backView
{
return _backView;
}
- (void) _layout
{
[(id)_backView layout];
}
- (BOOL)_isUpdated
{
return _updated;
}
- (BOOL)_isFlexibleSpace
{
return [self isKindOfClass: [GSToolbarFlexibleSpaceItem class]];
}
- (void) _setToolbar: (NSToolbar *)toolbar
{
ASSIGN(_toolbar, toolbar);
}
// NSValidatedUserInterfaceItem protocol
- (SEL)action
{
if(_flags._action)
{
return [_view action];
if ([_backView isKindOfClass: [NSButton class]])
return [(NSButton *)_backView action];
}
return 0;
}
@ -226,8 +778,10 @@
{
if(_flags._target)
{
return [_view target];
if ([_backView isKindOfClass: [NSButton class]])
return [(NSButton *)_backView target];
}
return nil;
}
@ -251,166 +805,3 @@
return self;
}
@end
/*
*
* Standard toolbar items.
*
*/
// ---- NSToolbarSeperatorItemIdentifier
@interface GSToolbarSeperatorItem : NSToolbarItem
{
}
@end
@implementation GSToolbarSeperatorItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarSeperatorItem"];
NSButton *button = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,48,48)];
[button setBordered: NO];
[super initWithItemIdentifier: itemIdentifier];
[self setView: button];
[self setImage: image];
return self;
}
@end
// ---- NSToolbarSpaceItemIdentifier
@interface GSToolbarSpaceItem : NSToolbarItem
{
}
@end
@implementation GSToolbarSpaceItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarSpaceItem"];
NSButton *button = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,48,48)];
[button setBordered: NO];
[super initWithItemIdentifier: itemIdentifier];
[self setView: button];
[self setImage: image];
return self;
}
@end
// ---- NSToolbarFlexibleSpaceItemIdentifier
@interface GSToolbarFlexibleSpaceItem : NSToolbarItem
{
}
@end
@implementation GSToolbarFlexibleSpaceItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarFlexibleSpaceItem"];
NSButton *button = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,48,48)];
[button setBordered: NO];
[super initWithItemIdentifier: itemIdentifier];
[self setView: button];
[self setImage: image];
return self;
}
@end
// ---- NSToolbarShowColorsItemIdentifier
@interface GSToolbarShowColorsItem : NSToolbarItem
{
}
@end
@implementation GSToolbarShowColorsItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarShowColorsItem"];
NSButton *button = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,48,48)];
[button setBordered: YES];
[super initWithItemIdentifier: itemIdentifier];
[self setView: button];
[self setImage: image];
// set action...
[self setTarget: nil]; // goes to first responder..
[self setAction: @selector(orderFrontColorPanel:)];
// return
return self;
}
@end
// ---- NSToolbarShowFontsItemIdentifier
@interface GSToolbarShowFontsItem : NSToolbarItem
{
}
@end
@implementation GSToolbarShowFontsItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarShowFontsItem"];
NSButton *button = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,48,48)];
[button setBordered: YES];
[super initWithItemIdentifier: itemIdentifier];
[self setView: button];
[self setImage: image];
// set action...
[self setTarget: nil]; // goes to first responder..
[self setAction: @selector(orderFrontFontPanel:)];
// return
return self;
}
@end
// ---- NSToolbarCustomizeToolbarItemIdentifier
@interface GSToolbarCustomizeToolbarItem : NSToolbarItem
{
}
@end
@implementation GSToolbarCustomizeToolbarItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_ToolbarCustomizeToolbarItem"];
NSButton *button = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,48,48)];
[button setBordered: YES];
[super initWithItemIdentifier: itemIdentifier];
[self setView: button];
[self setImage: image];
// set action...
[self setTarget: nil]; // goes to first responder..
[self setAction: @selector(runCustomizationPalette:)];
// return
return self;
}
@end
// ---- NSToolbarPrintItemIdentifier
@interface GSToolbarPrintItem : NSToolbarItem
{
}
@end
@implementation GSToolbarPrintItem
- (id) initWithItemIdentifier: (NSString *)itemIdentifier
{
NSImage *image = [NSImage imageNamed: @"common_Printer"];
NSButton *button = [[NSButton alloc] initWithFrame: NSMakeRect(0,0,48,48)];
[super initWithItemIdentifier: itemIdentifier];
[button setBordered: YES];
[self setView: button];
[self setImage: image];
// set action...
[self setTarget: nil]; // goes to first responder..
[self setAction: @selector(print:)];
// return
return self;
}
@end

45
Source/NSWindow+Toolbar.h Normal file
View file

@ -0,0 +1,45 @@
/*
NSWindow+Toolbar.h
The window toolbar category
Copyright (C) 2004 Free Software Foundation, Inc.
Author: Quentin Mathé <qmathe@club-internet.fr>
Date: January 2004
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _GNUstep_H_NSWindow_Toolbar
#define _GNUstep_H_NSWindow_Toolbar
#include "AppKit/NSWindow.h"
@class NSToolbar;
@interface NSWindow (Toolbar)
- (void) runToolbarCustomizationPalette: (id)sender;
- (void) toggleToolbarShown: (id)sender;
- (NSView *) contentViewWithoutToolbar;
- (NSToolbar *) toolbar;
- (void) setContentViewWithoutToolbar: (NSView *)contentViewWithoutToolbar;
- (void) setToolbar: (NSToolbar*)toolbar;
@end
#endif

249
Source/NSWindow+Toolbar.m Normal file
View file

@ -0,0 +1,249 @@
/** <title>NSWindow+Toolbar</title>
<abstract>The window class category to include toolbar support</abstract>
Copyright (C) 2004 Free Software Foundation, Inc.
Author: Quentin Mathé <qmathe@club-internet.fr>
Date: January 2004
This file is part of the GNUstep GUI Library.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
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
Library General Public License for more details.
You should have received a copy of the GNU Library General Public
License along with this library; see the file COPYING.LIB.
If not, write to the Free Software Foundation,
59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#include <Foundation/NSDebug.h>
#include <Foundation/NSException.h>
#include "NSWindow+Toolbar.h"
#include "AppKit/NSView.h"
#include "AppKit/NSToolbar.h"
#include "GNUstepGUI/GSToolbarView.h"
static const int ToolbarHeight = 61;
@interface NSToolbar (GNUstepPrivate)
+ (NSArray *) _toolbars;
- (GSToolbarView *) _toolbarView;
- (void) _setWindow: (NSWindow *)window;
- (NSWindow *) _window;
@end
@interface GSToolbarView (GNUstepPrivate)
- (void) _handleViewsVisibility;
@end
@interface NSWindow (ToolbarPrivate)
- (void) _toggleToolbarView: (GSToolbarView *)toolbarView display: (BOOL)flag;
@end
@implementation NSWindow (Toolbar)
- (void) runToolbarCustomizationPalette: (id)sender
{
[[self toolbar] runCustomizationPalette: sender];
}
- (void) toggleToolbarShown: (id)sender
{
NSToolbar *toolbar = [self toolbar];
if ([sender isEqual: toolbar]) // we can enter this branch when the toolbar class has called
toggleToolbarShown:
{
[self _toggleToolbarView: [toolbar _toolbarView] display: YES];
}
else
{
// we call the toolbar class letting it call back on toggleToolbarShown:
[toolbar setVisible: ![toolbar isVisible]];
}
}
// Accessors
- (NSView *) contentViewWithoutToolbar
{
NSToolbar *toolbar = [self toolbar];
if (toolbar != nil && [toolbar isVisible])
{
NSArray *subviews = [_contentView subviews];
id 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 toolbar view and a contentViewWithoutToolbar, with no others subviews."];
}
for (i = 0; i < n; i++)
{
subview = [subviews objectAtIndex: i];
if (![subview isEqual: toolbarView])
{
return subview;
}
}
return nil;
}
return [self contentView];
}
- (NSToolbar *) toolbar
{
NSArray *toolbars = [NSToolbar _toolbars];
NSArray *windows;
unsigned index = 0;
if (toolbars == nil)
return nil;
windows = [toolbars valueForKey: @"_window"];
index = [windows indexOfObjectIdenticalTo: self];
return (index == NSNotFound) ? nil : [toolbars objectAtIndex: index];
}
- (void) setContentViewWithoutToolbar: (NSView *)contentViewWithoutToolbar // user oriented method
{
NSToolbar *toolbar = [self toolbar];
if (toolbar != nil && [toolbar isVisible]) {
[_contentView replaceSubview: [self contentViewWithoutToolbar] with: contentViewWithoutToolbar];
}
else
{
[self setContentView: contentViewWithoutToolbar];
}
}
- (void) setToolbar: (NSToolbar*)toolbar
{
NSToolbar *lastToolbar = [self toolbar];
GSToolbarView *toolbarView = nil;
if (lastToolbar != nil)
{
// we throw the last toolbar out
[self _toggleToolbarView : [lastToolbar _toolbarView] display: NO];
[lastToolbar _setWindow: nil];
}
// when there is no new toolbar
if (toolbar == nil)
{
[self display]; // to show we have toggle the previous toolbar view
return;
}
// ELSE
// the window want to know which toolbar is binded
[toolbar _setWindow : self];
// insert the toolbar view (we create this view when the toolbar hasn't such view)...
toolbarView = [toolbar _toolbarView];
if (toolbarView == nil)
{
toolbarView = [[GSToolbarView alloc] initWithFrame: NSMakeRect(0, 0, 0, 0)];
// _toggleToolbarView:display: method will set the toolbar view to the right frame
[toolbarView setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin];
}
[toolbarView setBorderMask: GSToolbarViewBottomBorder];
[self _toggleToolbarView: toolbarView display: YES];
// load the toolbar inside the toolbar view
[toolbarView setToolbar: toolbar];
}
// Private methods
- (void) _toggleToolbarView: (GSToolbarView *)toolbarView display: (BOOL)flag {
NSRect windowFrame;
if ([toolbarView superview] == nil)
{
NSView *contentViewWithoutToolbar;
NSRect contentViewWithoutToolbarFrame;
contentViewWithoutToolbar = _contentView;
// Switch the content view
RETAIN(contentViewWithoutToolbar);
[self setContentView: [[NSView alloc] initWithFrame: [_contentView frame]]];
// Resize the window
windowFrame = [self frame];
[self setFrame: NSMakeRect(windowFrame.origin.x, windowFrame.origin.y - ToolbarHeight, windowFrame.size.width,
windowFrame.size.height + ToolbarHeight) display: flag];
// Plug the toolbar view
contentViewWithoutToolbarFrame = [contentViewWithoutToolbar frame];
[toolbarView setFrame: NSMakeRect(0, contentViewWithoutToolbarFrame.size.height, contentViewWithoutToolbarFrame.size.width, ToolbarHeight)];
[_contentView addSubview: toolbarView];
[toolbarView _handleViewsVisibility];
[toolbarView setNextResponder: self];
// Insert the previous content view
[_contentView addSubview: contentViewWithoutToolbar];
RELEASE(contentViewWithoutToolbar);
}
else
{
NSView *contentViewWithoutToolbar;
contentViewWithoutToolbar = [self contentViewWithoutToolbar];
// Unplug the toolbar view
[toolbarView removeFromSuperview];
// Resize the window
[contentViewWithoutToolbar setAutoresizingMask: NSViewMaxYMargin];
windowFrame = [self frame];
[self setFrame: NSMakeRect(windowFrame.origin.x, windowFrame.origin.y + ToolbarHeight,
windowFrame.size.width,
windowFrame.size.height - ToolbarHeight) display: flag];
[contentViewWithoutToolbar setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
// Autoresizing mask will be set again by the setContentView: method
// Switch the content view
RETAIN(contentViewWithoutToolbar); // because setContentView: will release the parent view and their subviews
[self setContentView: contentViewWithoutToolbar];
RELEASE(contentViewWithoutToolbar);
}
}
@end