diff --git a/ChangeLog b/ChangeLog index 25e2b1ac6..adf5ac3ae 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2004-03-12 Quentin Mathe + + * Source/GSToolbarView.m: Bug fixes related to clipped items and more + efficient code. + * Headers/Additions/GNUstepGUI/GSToolbarView.h: Minor changes. + * Source/NSToolbar.m: Refactored NSToolbar implementation, most part of + the code has moved to GSToolbar. + * Headers/AppKit/NSToolbar.h: Same. + * Source/GSToolbar.m: New class which implements functionnality for the + basic GNUstep toolbars with some bug fixes. + * Headers/Additions/GNUstepGUI/GSToolbar.h: Header for the new basic + GNUstep toolbar class. + * Source/NSWindow+Toolbar.m: Bug fixes. + * Source/NSWindow+Toolbar.h: Minor changes. + 2004-03-12 15:30 Alexander Malmberg * Source/NSTableView.m (-mouseDown:): Send our action if we get diff --git a/Headers/Additions/GNUstepGUI/GSToolbar.h b/Headers/Additions/GNUstepGUI/GSToolbar.h new file mode 100644 index 000000000..4fdf6aa42 --- /dev/null +++ b/Headers/Additions/GNUstepGUI/GSToolbar.h @@ -0,0 +1,141 @@ +/* + GSToolbar.h + + The basic toolbar class. + + Copyright (C) 2004 Free Software Foundation, Inc. + + Author: Gregory John Casamento , + Fabien Vallon , + Quentin Mathe + Date: February 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_GSToolbar +#define _GNUstep_H_GSToolbar + +#include + +@class NSString; +@class NSArray; +@class NSMutableArray; +@class NSDictionary; +@class NSMutableDictionary; +@class NSNotification; +@class NSToolbarItem; +@class GSToolbarView; +@class NSWindow; + +/* + * Constants + */ + +typedef enum +{ + NSToolbarDisplayModeDefault, + NSToolbarDisplayModeIconAndLabel, + NSToolbarDisplayModeIconOnly, + NSToolbarDisplayModeLabelOnly +} NSToolbarDisplayMode; + +typedef enum +{ + NSToolbarSizeModeDefault, + NSToolbarSizeModeRegular, + NSToolbarSizeModeSmall, +} NSToolbarSizeMode; + +APPKIT_EXPORT NSString *NSToolbarDidRemoveItemNotification; +APPKIT_EXPORT NSString *NSToolbarWillAddItemNotification; + +@interface GSToolbar : NSObject +{ + BOOL _allowsUserCustomization; + BOOL _autosavesConfiguration; + NSMutableDictionary *_configurationDictionary; + BOOL _customizationPaletteIsRunning; + id _delegate; + NSToolbarDisplayMode _displayMode; + NSToolbarSizeMode _sizeMode; + NSString *_identifier; + NSMutableArray *_items; + GSToolbarView *_toolbarView; + NSWindow *_window; + BOOL _build; +} + +// Instance methods +- (id) initWithIdentifier: (NSString*)identifier; +- (id) initWithIdentifier: (NSString *)identifier + displayMode: (NSToolbarDisplayMode)displayMode + sizeMode: (NSToolbarSizeMode)sizeMode; + +- (void) insertItemWithItemIdentifier: (NSString*)itemIdentifier atIndex: (int)index; +- (void) removeItemAtIndex: (int)index; +- (void) runCustomizationPalette: (id)sender; + +// Accessors +- (BOOL) allowsUserCustomization; +- (BOOL) autosavesConfiguration; +- (NSDictionary*) configurationDictionary; +- (BOOL) customizationPaletteIsRunning; +- (id) delegate; +- (NSString*) identifier; +- (NSArray*) items; +- (NSString *) selectedItemIdentifier; +- (NSArray*) visibleItems; +- (void) setAllowsUserCustomization: (BOOL)flag; +- (void) setAutosavesConfiguration: (BOOL)flag; +- (void) setConfigurationFromDictionary: (NSDictionary*)configDict; +- (void) setDelegate: (id)delegate; +- (void) setSelectedItemIdentifier: (NSString *) identifier; +- (void) validateVisibleItems; + +@end /* interface of NSToolbar */ + +/* + * Methods Implemented by the Delegate + */ +@interface NSObject (GSToolbarDelegate) +// notification methods +- (void) toolbarDidRemoveItem: (NSNotification*)aNotification; +- (void) toolbarWillAddItem: (NSNotification*)aNotification; + +// delegate methods +// required method +- (NSToolbarItem*)toolbar: (GSToolbar*)toolbar + itemForItemIdentifier: (NSString*)itemIdentifier +willBeInsertedIntoToolbar: (BOOL)flag; +// required method +- (NSArray*) toolbarAllowedItemIdentifiers: (GSToolbar*)toolbar; +// required method +- (NSArray*) toolbarDefaultItemIdentifiers: (GSToolbar*)toolbar; +// optional method +- (NSArray *) toolbarSelectableItemIdentifiers: (GSToolbar *)toolbar; +@end + + +// Extensions + +@interface NSArray (ObjectsWithValueForKey) +- (NSArray *) objectsWithValue: (NSString *)value forKey: (NSString *)key; +@end + +#endif /* _GNUstep_H_NSToolbar */ diff --git a/Headers/Additions/GNUstepGUI/GSToolbarView.h b/Headers/Additions/GNUstepGUI/GSToolbarView.h index 4303cf0b4..b275cf2ac 100644 --- a/Headers/Additions/GNUstepGUI/GSToolbarView.h +++ b/Headers/Additions/GNUstepGUI/GSToolbarView.h @@ -6,7 +6,8 @@ Copyright (C) 2002 Free Software Foundation, Inc. Author: Gregory John Casamento , - Fabien Vallon + Fabien Vallon , + Quentin Mathe Date: May 2002 This file is part of the GNUstep GUI Library. @@ -34,7 +35,7 @@ #include @class NSMutableArray; -@class NSToolbar; +@class GSToolbar; @class NSToolbarItem; @class NSView; @class NSClipView; @@ -71,9 +72,8 @@ static const int _ClippedItemsViewWidth = 28; @interface GSToolbarView : NSView { - NSToolbar *_toolbar; + GSToolbar *_toolbar; NSClipView *_clipView, *_clipViewForEditMode; - NSView *_loadedViewEdited; GSToolbarClippedItemsButton *_clippedItemsMark; NSMutableArray *_visibleBackViews; BOOL _willBeVisible; @@ -83,8 +83,8 @@ static const int _ClippedItemsViewWidth = 28; - (id) initWithFrame: (NSRect)frame; // Accessors -- (NSToolbar *) toolbar; -- (void) setToolbar: (NSToolbar *)toolbar; +- (GSToolbar *) toolbar; +- (void) setToolbar: (GSToolbar *)toolbar; - (unsigned int) borderMask; - (void) setBorderMask: (unsigned int)borderMask; diff --git a/Headers/AppKit/NSToolbar.h b/Headers/AppKit/NSToolbar.h index 3504689b8..d1832e184 100644 --- a/Headers/AppKit/NSToolbar.h +++ b/Headers/AppKit/NSToolbar.h @@ -6,7 +6,8 @@ Copyright (C) 2002 Free Software Foundation, Inc. Author: Gregory John Casamento , - Fabien Vallon + Fabien Vallon , + Quentin Mathe Date: May 2002 This file is part of the GNUstep GUI Library. @@ -30,96 +31,27 @@ #ifndef _GNUstep_H_NSToolbar #define _GNUstep_H_NSToolbar -#include +#include "GNUstepGUI/GSToolbar.h" -@class NSString; -@class NSArray; -@class NSMutableArray; -@class NSDictionary; -@class NSMutableDictionary; -@class NSNotification; -@class NSLock; -@class NSToolbarItem; -@class GSToolbarView; -@class NSWindow; - -/* - * Constants - */ -typedef enum -{ - NSToolbarDisplayModeDefault, - NSToolbarDisplayModeIconAndLabel, - NSToolbarDisplayModeIconOnly, - NSToolbarDisplayModeLabelOnly -} NSToolbarDisplayMode; - -typedef enum -{ - NSToolbarSizeModeDefault, - NSToolbarSizeModeRegular, - NSToolbarSizeModeSmall, -} NSToolbarSizeMode; - -APPKIT_EXPORT NSString *NSToolbarDidRemoveItemNotification; -APPKIT_EXPORT NSString *NSToolbarWillAddItemNotification; - -@interface NSToolbar : NSObject +@interface NSToolbar : GSToolbar { - BOOL _allowsUserCustomization; - BOOL _autosavesConfiguration; - NSMutableDictionary *_configurationDictionary; - BOOL _customizationPaletteIsRunning; - id _delegate; - NSToolbarDisplayMode _displayMode; - NSString *_identifier; BOOL _visible; - NSMutableArray *_items; - 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; -- (BOOL) customizationPaletteIsRunning; -- (id) delegate; - (NSToolbarDisplayMode) displayMode; -- (NSString*) identifier; - (BOOL) isVisible; -- (NSArray*) items; -- (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; - @end /* interface of NSToolbar */ /* * Methods Implemented by the Delegate */ @interface NSObject (NSToolbarDelegate) -// notification methods -- (void) toolbarDidRemoveItem: (NSNotification*)aNotification; -- (void) toolbarWillAddItem: (NSNotification*)aNotification; // delegate methods // required method diff --git a/Source/GNUmakefile b/Source/GNUmakefile index ff60fcb9f..2ed63b415 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -183,6 +183,7 @@ GSHorizontalTypesetter.m \ GSNibTemplates.m \ GSNibCompatibility.m \ GSTitleView.m \ +GSToolbar.m \ GSToolbarView.m # Turn off NSMenuItem warning that NSMenuItem conforms to , @@ -346,6 +347,7 @@ GSLayoutManager.h \ GSLayoutManager_internal.h \ GSTypesetter.h \ GSHorizontalTypesetter.h \ +GSToolbar.h \ GSToolbarView.h \ GSNibCompatibility.h \ GSTitleView.h diff --git a/Source/GSToolbar.m b/Source/GSToolbar.m new file mode 100644 index 000000000..ab828a5d7 --- /dev/null +++ b/Source/GSToolbar.m @@ -0,0 +1,608 @@ +/* + GSToolbar.m + + The basic toolbar class. + + Copyright (C) 2004 Free Software Foundation, Inc. + + Author: Gregory John Casamento , + Fabien Vallon , + Quentin Mathe + Date: February 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 +#include +#include +#include +#include +#include +#include "AppKit/NSToolbarItem.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" +#include "GNUstepGUI/GSToolbar.h" + +// internal +static NSNotificationCenter *nc = nil; +static const int current_version = 1; + +static NSMutableArray *toolbars; + + +// Extensions + +@implementation NSArray (ObjectsWithValueForKey) + +- (NSArray *) objectsWithValue: (NSString *)value forKey: (NSString *)key +{ + NSMutableArray *result = [[NSMutableArray alloc] init]; + NSArray *keys = [self valueForKey: key]; + int i, n = 0; + + if (keys == nil) + return nil; + + n = [keys count]; + + for (i = 0; i < n; i++) + { + if ([[keys objectAtIndex: i] isEqualToString: value]) + { + [result addObject: [self objectAtIndex: i]]; + } + } + + if ([result count] == 0) + return nil; + + return result; +} +@end + +// --- + +@interface GSToolbar (GNUstepPrivate) + +// Private class method + ++ (NSMutableArray *) _toolbars; + +- (void) _insertItemWithItemIdentifier: (NSString *)itemIdentifier + atIndex: (int)index + broadcast: (BOOL)broadcast; + +// Private methods with broadcast 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) _setDelegate: (id)delegate broadcast: (BOOL)broadcast; + +// Few other private methods +- (void) _build; +- (void) _loadConfig; +- (NSToolbarItem *) _toolbarItemForIdentifier: (NSString *)itemIdent; +- (GSToolbar *) _toolbarModel; + +// Accessors +- (void) _setToolbarView: (GSToolbarView *)toolbarView; +- (GSToolbarView *) _toolbarView; +- (void) _setWindow: (NSWindow *)window; +- (NSWindow *) _window; +@end + +@interface NSToolbarItem (GNUstepPrivate) +- (void) _setToolbar: (GSToolbar *)toolbar; +@end + +@interface GSToolbarView (GNUstepPrivate) +- (void) _reload; +- (NSArray *) _visibleBackViews; +- (BOOL) _willBeVisible; +- (void) _setWillBeVisible: (BOOL)willBeVisible; +@end + +// --- + +@implementation GSToolbar + +// Class methods + +// Initialize the class when it is loaded ++ (void) initialize +{ + if (self == [GSToolbar class]) + { + [self setVersion: current_version]; + nc = [NSNotificationCenter defaultCenter]; + toolbars = [[NSMutableArray alloc] init]; + } +} + +// Private class method to access static variable toolbars in subclasses + ++ (NSMutableArray *) _toolbars +{ + return toolbars; +} + +// Instance methods + +- (id) initWithIdentifier: (NSString *)identifier +{ + return [self initWithIdentifier: identifier + displayMode: NSToolbarDisplayModeIconAndLabel + sizeMode: NSToolbarSizeModeRegular]; +} + + +// default initialiser +- (id) initWithIdentifier: (NSString *)identifier + displayMode: (NSToolbarDisplayMode)displayMode + sizeMode: (NSToolbarSizeMode)sizeMode +{ + GSToolbar *toolbarModel; + + if ((self = [super init]) == nil) + return nil; + + ASSIGN(_identifier, identifier); + _displayMode = displayMode; + _sizeMode = sizeMode; + + _items = [[NSMutableArray alloc] init]; + + toolbarModel = [self _toolbarModel]; + + if (toolbarModel != nil) + { + _customizationPaletteIsRunning = NO; + _allowsUserCustomization = [toolbarModel allowsUserCustomization]; + _autosavesConfiguration = [toolbarModel autosavesConfiguration]; + ASSIGN(_configurationDictionary, [toolbarModel configurationDictionary]); + + //[self _loadConfig]; + + [self _setDelegate: [toolbarModel delegate] broadcast: NO]; + } + else + { + _customizationPaletteIsRunning = NO; + _allowsUserCustomization = NO; + _autosavesConfiguration = NO; + _configurationDictionary = nil; + + //[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 *e = [[self visibleItems] objectEnumerator]; + NSToolbarItem *item = nil; + + while((item = [e nextObject]) != nil) + { + [item validate]; + } +} + +// Accessors + +- (BOOL) allowsUserCustomization +{ + return _allowsUserCustomization; +} + +- (BOOL) autosavesConfiguration +{ + return _autosavesConfiguration; +} + +- (NSDictionary *) configurationDictionary +{ + return _configurationDictionary; +} + +- (BOOL) customizationPaletteIsRunning +{ + return _customizationPaletteIsRunning; +} + +- (id) delegate +{ + return _delegate; +} + +- (NSString *) identifier +{ + return _identifier; +} + +- (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) setSelectedItemIdentifier: (NSString *)itemIdentifier +{ + // do something here +} + +- (NSToolbarSizeMode) sizeMode +{ + return 0; +} + +// Private methods + +- (void) _build +{ + /* + * toolbar build : + * will use the delegate when there is no toolbar model + */ + + GSToolbar *toolbarModel; + NSArray *wantedItemIdentifiers; + NSEnumerator *e; + id itemIdentifier; + int i = 0; + + _build = YES; + + RELEASE(_items); + _items = [[NSMutableArray alloc] init]; + + toolbarModel = [self _toolbarModel]; + + if (toolbarModel != nil + && toolbarModel != self + && [toolbarModel delegate] == _delegate) + { + 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) + { + NSUserDefaults *defaults; + NSString *tableKey; + id config; + + defaults = [NSUserDefaults standardUserDefaults]; + tableKey = + [NSString stringWithFormat: @"GSToolbar Config %@",_identifier]; + + config = [defaults objectForKey: tableKey]; + + if (config != nil) + { + [self setConfigurationFromDictionary: config]; + } + } +} + +- (GSToolbar *) _toolbarModel +{ + NSArray *linked; + id toolbar; + + linked = [toolbars objectsWithValue: [self identifier] + forKey: @"_identifier"]; + + if (linked != nil && [linked count] > 0) + { + toolbar = [linked objectAtIndex: 0]; + if ([toolbar isMemberOfClass: [self class]] && toolbar != self) + return toolbar; + } + + return nil; +} + +- (NSToolbarItem *) _toolbarItemForIdentifier: (NSString *)itemIdent +{ + NSToolbarItem *item = nil; + + if([itemIdent isEqual: NSToolbarSeparatorItemIdentifier] || + [itemIdent isEqual: NSToolbarSpaceItemIdentifier] || + [itemIdent isEqual: NSToolbarFlexibleSpaceItemIdentifier] || + [itemIdent isEqual: NSToolbarShowColorsItemIdentifier] || + [itemIdent isEqual: NSToolbarShowFontsItemIdentifier] || + [itemIdent isEqual: NSToolbarCustomizeToolbarItemIdentifier] || + [itemIdent isEqual: NSToolbarPrintItemIdentifier]) + { + item = [[NSToolbarItem alloc] initWithItemIdentifier: itemIdent]; + } + + return item; +} + + +/* + * + * The methods below handles the toolbar edition and broacasts each associated + * event to the other toolbars with identical identifiers. + * + */ + +#define TRANSMIT(signature) \ + NSEnumerator *e = [[toolbars objectsWithValue: _identifier forKey: @"_identifier"] objectEnumerator]; \ + GSToolbar *toolbar; \ + \ + while ((toolbar = [e nextObject]) != nil) \ + { \ + if (toolbar != self && [toolbar isMemberOfClass: [self class]]) \ + [toolbar signature]; \ + } + +- (void) _insertItemWithItemIdentifier: (NSString *)itemIdentifier + atIndex: (int)index + broadcast: (BOOL)broadcast +{ + NSToolbarItem *item = nil; + NSArray *allowedItems = [_delegate toolbarAllowedItemIdentifiers: self]; + + if([allowedItems containsObject: itemIdentifier]) + { + item = [self _toolbarItemForIdentifier: itemIdentifier]; + if(item == nil) + { + item = + [_delegate toolbar: self itemForItemIdentifier: itemIdentifier + willBeInsertedIntoToolbar: YES]; + } + + if (item != nil) + { + [nc postNotificationName: NSToolbarWillAddItemNotification + object: self]; + + [item _setToolbar: self]; + [_items insertObject: item atIndex: index]; + + // We reload the toolbarView each time a new item is added except when + // we build/create the toolbar + if (!_build) + [_toolbarView _reload]; + + if (broadcast) + { + TRANSMIT(_insertItemWithItemIdentifier: itemIdentifier + atIndex: index + broadcast: NO); + } + } + } + +} + +- (void) _removeItemAtIndex: (int)index broadcast: (BOOL)broadcast +{ + + [_items removeObjectAtIndex: index]; + [_toolbarView _reload]; + [nc postNotificationName: NSToolbarDidRemoveItemNotification object: self]; + + if (broadcast) + { + TRANSMIT(_removeItemAtIndex: index broadcast: NO); + } +} + +- (void) _setAllowsUserCustomization: (BOOL)flag broadcast: (BOOL)broadcast +{ + _allowsUserCustomization = flag; + + if (broadcast) + { + TRANSMIT(_setAllowsUserCustomization: _allowsUserCustomization + broadcast: NO); + } +} + +- (void) _setAutosavesConfiguration: (BOOL)flag broadcast: (BOOL)broadcast +{ + _autosavesConfiguration = flag; + + if (broadcast) + { + TRANSMIT(_setAutosavesConfiguration: _autosavesConfiguration + broadcast: NO); + } +} + +- (void) _setConfigurationFromDictionary: (NSDictionary *)configDict + broadcast: (BOOL)broadcast +{ + ASSIGN(_configurationDictionary, configDict); + + if (broadcast) + { + TRANSMIT(_setConfigurationFromDictionary: _configurationDictionary + broadcast: NO); + } +} + +- (void) _setDelegate: (id)delegate broadcast: (BOOL)broadcast +{ + if (_delegate == delegate) + return; + + #define CHECK_REQUIRED_METHOD(selector_name) \ + if (![delegate respondsToSelector: @selector(selector_name)]) \ + [NSException raise: NSInternalInconsistencyException \ + format: @"delegate does not respond to %@",@#selector_name] + + CHECK_REQUIRED_METHOD(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:); + CHECK_REQUIRED_METHOD(toolbarAllowedItemIdentifiers:); + CHECK_REQUIRED_METHOD(toolbarDefaultItemIdentifiers:); + + if (_delegate) + [nc removeObserver: _delegate name: nil object: self]; + + ASSIGN(_delegate, delegate); + + #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] + + SET_DELEGATE_NOTIFICATION(DidRemoveItem); + SET_DELEGATE_NOTIFICATION(WillAddItem); + + [self _build]; + if (_toolbarView != nil) + [_toolbarView _reload]; + + // broadcast now... + + if (broadcast) + { + TRANSMIT(_setDelegate: _delegate broadcast: NO); + } +} + +// Private Accessors + +- (void) _setToolbarView: (GSToolbarView *)toolbarView +{ + ASSIGN(_toolbarView, toolbarView); +} + +- (GSToolbarView *) _toolbarView +{ + return _toolbarView; +} + +@end diff --git a/Source/GSToolbarView.m b/Source/GSToolbarView.m index fc915cce2..913911c28 100644 --- a/Source/GSToolbarView.m +++ b/Source/GSToolbarView.m @@ -1,11 +1,11 @@ /* - GSToolbarView.m + GSToolbarView.m The toolbar view class. Copyright (C) 2004 Free Software Foundation, Inc. - Author: Quentin Mathé + Author: Quentin Mathe Date: January 2004 This file is part of the GNUstep GUI Library. @@ -29,9 +29,7 @@ #include #include #include -#include #include "AppKit/NSToolbarItem.h" -#include "AppKit/NSToolbar.h" #include "AppKit/NSView.h" #include "AppKit/NSClipView.h" #include "AppKit/NSButton.h" @@ -40,13 +38,14 @@ #include "AppKit/NSMenu.h" #include "AppKit/NSEvent.h" #include "AppKit/NSWindow.h" +#include "GNUstepGUI/GSToolbar.h" #include "GNUstepGUI/GSToolbarView.h" // internal static const int current_version = 1; -@interface NSToolbar (GNUstepPrivate) +@interface GSToolbar (GNUstepPrivate) - (void) _build; - (void) _setToolbarView: (GSToolbarView *)toolbarView; @end @@ -58,24 +57,11 @@ static const int current_version = 1; - (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) _handleViewsFrame; - (void) _handleViewsVisibility; - (void) _reload; +- (void) _setToolbar: (GSToolbar *)toolbar; - (void) _takeInAccountFlexibleSpaces; // Accessors @@ -84,19 +70,37 @@ static const int current_version = 1; - (BOOL) _willBeVisible; @end +@interface GSToolbarClippedItemsButton : NSButton +{ + GSToolbar *_toolbar; +} + +- (id) init; + +// Accessors +- (NSMenu *) returnMenu; + +// this method cannot be called "menu" otherwise it would override NSResponder +// method with the same name + +- (void)setToolbar: (GSToolbar *)toolbar; +@end + @implementation GSToolbarClippedItemsButton - (id)init { NSImage *image = [NSImage imageNamed: @"common_ToolbarClippedItemsMark"]; - if ((self = [super initWithFrame: NSMakeRect(0, 0, _ClippedItemsViewWidth, _ItemBackViewDefaultHeight)]) != nil) + if ((self = [super initWithFrame: NSMakeRect(0, 0, _ClippedItemsViewWidth, + _ItemBackViewDefaultHeight)]) != nil) { [self setBordered: NO]; - [[self cell] setHighlightsBy: NSChangeGrayCellMask | NSChangeBackgroundCellMask]; - [self setAutoresizingMask: (NSViewNotSizable | NSViewMinXMargin)]; + [[self cell] setHighlightsBy: NSChangeGrayCellMask + | NSChangeBackgroundCellMask]; + [self setAutoresizingMask: NSViewNotSizable | NSViewMinXMargin]; [self setImagePosition: NSImageOnly]; [image setScalesWhenResized: YES]; - [image setSize: NSMakeSize(20., 20.)]; + [image setSize: NSMakeSize(20, 20)]; [self setImage: image]; return self; } @@ -106,10 +110,15 @@ static const int current_version = 1; - (void)mouseDown: (NSEvent *)event { NSMenu *clippedItemsMenu = [self menuForEvent:event]; + [super highlight: YES]; + if (clippedItemsMenu != nil) { - [NSMenu popUpContextMenu: clippedItemsMenu withEvent: event forView: self]; + [NSMenu popUpContextMenu: clippedItemsMenu withEvent: event + forView: self]; } + + [super highlight: NO]; } - (NSMenu *)menuForEvent: (NSEvent *)event { @@ -121,8 +130,9 @@ static const int current_version = 1; } - (NSMenu *)returnMenu -// this method cannot be called menu otherwise it would override NSResponder method with the same name { + // 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; @@ -150,7 +160,7 @@ static const int current_version = 1; // Accessors -- (void)setToolbar: (NSToolbar *)toolbar +- (void)setToolbar: (GSToolbar *)toolbar { ASSIGN(_toolbar, toolbar); } @@ -163,15 +173,22 @@ static const int current_version = 1; { if((self = [super initWithFrame: frame]) != nil) { - _clipView = [[NSClipView alloc] initWithFrame: NSMakeRect(0, 1, frame.size.width, frame.size.height)]; - [_clipView setAutoresizingMask: (NSViewWidthSizable | NSViewHeightSizable)]; + _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; + _borderMask = GSToolbarViewTopBorder | GSToolbarViewBottomBorder + | GSToolbarViewRightBorder | GSToolbarViewLeftBorder; + + return self; } - return self; + return nil; } - (void) dealloc @@ -204,7 +221,8 @@ static const int current_version = 1; if (_borderMask & GSToolbarViewTopBorder) { [NSBezierPath strokeLineFromPoint: NSMakePoint(0, viewFrame.size.height - 0.5) - toPoint: NSMakePoint(viewFrame.size.width, viewFrame.size.height - 0.5)]; + toPoint: NSMakePoint(viewFrame.size.width, + viewFrame.size.height - 0.5)]; } if (_borderMask & GSToolbarViewLeftBorder) { @@ -213,8 +231,9 @@ static const int current_version = 1; } if (_borderMask & GSToolbarViewRightBorder) { - [NSBezierPath strokeLineFromPoint: NSMakePoint(viewFrame.size.width - 0.5, 0) - toPoint: NSMakePoint(viewFrame.size.width - 0.5, viewFrame.size.height)]; + [NSBezierPath strokeLineFromPoint: NSMakePoint(viewFrame.size.width - 0.5,0) + toPoint: NSMakePoint(viewFrame.size.width - 0.5, + viewFrame.size.height)]; } [super drawRect: aRect]; @@ -228,7 +247,8 @@ static const int current_version = 1; - (void) windowDidResize: (NSNotification *)notification { - if (![_toolbar isVisible]) return; + if ([self superview] == nil) + return; [self _handleViewsVisibility]; } @@ -247,11 +267,13 @@ static const int current_version = 1; { NSNotificationCenter *nc = [NSNotificationCenter defaultCenter]; - // NSView method called when a view is moved to a window (NSView has a variable _window) + // 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]; + [nc addObserver: self selector: @selector(windowDidResize:) + name: NSWindowDidResizeNotification object: nil]; [self viewDidMoveToSuperview]; } @@ -263,7 +285,7 @@ static const int current_version = 1; return _borderMask; } -- (NSToolbar *) toolbar +- (GSToolbar *) toolbar { return _toolbar; } @@ -273,63 +295,48 @@ static const int current_version = 1; _borderMask = borderMask; } -- (void) setToolbar: (NSToolbar *)toolbar +- (void) setToolbar: (GSToolbar *)toolbar { - ASSIGN(_toolbar, toolbar); - [_clippedItemsMark setToolbar: _toolbar]; + if ([toolbar isKindOfClass: [NSToolbar class]]) + [NSException raise: NSInvalidArgumentException + format: @"NSToolbar instance can't be attached directly to a \ + toolbar view, setToolbar: from the NSWindow toolbar \ + category must be used."]; - [_toolbar _build]; // Use the delegate to build the toolbar - - [_toolbar _setToolbarView: self]; - [self _reload]; // Load the toolbar in the toolbar view + [self _setToolbar: toolbar]; } // Private methods -- (void) _handleViewsOrigin +- (void) _handleViewsFrame { 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; + NSView *itemBackView; + NSRect itemBackViewFrame; + float x = 0; + // --- NSArray *subviews = [self subviews]; while ((item = [e nextObject]) != nil) { - itemView = [item _backView]; - if (![subviews containsObject: itemView] || [item _isModified]) + itemBackView = [item _backView]; + if (![subviews containsObject: itemBackView] + || [item _isModified] + || [item _isFlexibleSpace]) { - itemViewEdited = itemView; + // When a label is changed, _isModified returns YES to let us known we + // must recalculate the text length and then the size for the edited + // item back view + [item _layout]; } - - // 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]; + + itemBackViewFrame = [itemBackView frame]; + [itemBackView setFrame: NSMakeRect(x, + itemBackViewFrame.origin.y, + itemBackViewFrame.size.width, + itemBackViewFrame.size.height)]; + x += [itemBackView frame].size.width; } } @@ -338,79 +345,106 @@ static const int current_version = 1; { NSArray *items = [_toolbar items]; - // the backViews which are associated with the toolbar items now (the toolbar items doesn't - // reflect the toolbar view content) + // The back views which are associated with each toolbar item (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]; + // The back views which are visible in the toolbar view now (before taking the + // last user action in account) + NSArray *visibleItemBackViews = [_clipView subviews]; + // more efficient than [self _visibleBackViews] + // The back views which will be visible in the toolbar view (when + // _handleViewsVisibility will be terminated) + NSArray *willBeVisibleItemBackViews; + NSEnumerator *e; NSView *itemBackView; NSRect clipViewFrame; - [self _handleViewsOrigin]; - + // First, we resize + [self _handleViewsFrame]; [self _takeInAccountFlexibleSpaces]; - // We remove the _backView (itemBackView variable) associated with the removed or not visible - // toolbar items + // Then we retrieve the back views which should be visible now that the resize + // process has been taken in account + willBeVisibleItemBackViews = [self _visibleBackViews]; + + // We remove the back view associated with the removed or not visible toolbar + // items - e = [currentItemBackViews objectEnumerator]; + e = [visibleItemBackViews objectEnumerator]; while ((itemBackView = [e nextObject]) != nil) { - if (![itemBackViews containsObject: itemBackView] || ![visibleItemBackViews containsObject: itemBackView]) + if (![itemBackViews containsObject: itemBackView] + || ![willBeVisibleItemBackViews containsObject: itemBackView]) { if ([itemBackView superview] != nil) [itemBackView removeFromSuperview]; } } - // We add the _backView (itemBackView variable) associated with the added toolbar item when it - // is visible + // We add the backView associated with the added toolbar item when it should + // become visible - e = [visibleItemBackViews objectEnumerator]; + e = [willBeVisibleItemBackViews objectEnumerator]; while ((itemBackView = [e nextObject]) != nil) { - if (![currentItemBackViews containsObject: itemBackView]) + if (![visibleItemBackViews containsObject: itemBackView]) { [_clipView addSubview: itemBackView]; } } + + // We manage the clipped items view in the case it should become visible or + // invisible clipViewFrame = [_clipView frame]; - if (([_clippedItemsMark superview] == nil) && ([visibleItemBackViews count] < [itemBackViews count])) + if (([_clippedItemsMark superview] == nil) + && ([willBeVisibleItemBackViews count] < [itemBackViews count])) { - [_clipView setFrame: NSMakeRect(clipViewFrame.origin.x, clipViewFrame.origin.y, - clipViewFrame.size.width - _ClippedItemsViewWidth, - clipViewFrame.size.height)]; + [_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)]; + [_clippedItemsMark setFrameOrigin: NSMakePoint(clipViewFrame.size.width, + clipViewFrame.origin.y)]; + [self addSubview: _clippedItemsMark]; } - else if (([_clippedItemsMark superview] != nil) && ([visibleItemBackViews count] >= - [itemBackViews count])) + else if (([_clippedItemsMark superview] != nil) + && ([willBeVisibleItemBackViews count] >= [itemBackViews count])) { [_clippedItemsMark removeFromSuperview]; - [_clipView setFrame: NSMakeRect(clipViewFrame.origin.x, clipViewFrame.origin.y, - clipViewFrame.size.width + _ClippedItemsViewWidth, clipViewFrame.size.height)]; + [_clipView setFrame: NSMakeRect(clipViewFrame.origin.x, + clipViewFrame.origin.y, + clipViewFrame.size.width + _ClippedItemsViewWidth, + clipViewFrame.size.height)]; } [self setNeedsDisplay: YES]; } -- (void) _reload { - - [self _handleViewsSize]; +- (void) _reload +{ [self _handleViewsVisibility]; +} + +- (void) _setToolbar: (GSToolbar *)toolbar +{ + [_toolbar _setToolbarView: nil]; + ASSIGN(_toolbar, toolbar); + [_clippedItemsMark setToolbar: _toolbar]; + + [_toolbar _setToolbarView: self]; + + [self _reload]; // Load the toolbar in the toolbar view } - (void) _takeInAccountFlexibleSpaces @@ -418,13 +452,13 @@ static const int current_version = 1; 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; + NSView *itemBackView; + NSRect lastItemBackViewFrame = [[[items lastObject] _backView] frame]; + float lengthAvailable = [self frame].size.width - + NSMaxX(lastItemBackViewFrame); + unsigned int flexibleSpaceItemsNumber = 0; BOOL mustAdjustNext = NO; - float x = 0.; + float x = 0; if (lengthAvailable < 1) return; @@ -443,24 +477,24 @@ static const int current_version = 1; e = [items objectEnumerator]; while ((item = [e nextObject]) != nil) { - itemView = [item _backView]; + itemBackView = [item _backView]; if ([item _isFlexibleSpace]) { - NSRect itemViewFrame = [itemView frame]; + NSRect itemBackViewFrame = [itemBackView frame]; - [itemView setFrame: - NSMakeRect(x, itemViewFrame.origin.y, lengthAvailable / flexibleSpaceItemsNumber, - itemViewFrame.size.height)]; + [itemBackView setFrame: NSMakeRect(x, itemBackViewFrame.origin.y, + lengthAvailable / flexibleSpaceItemsNumber, + itemBackViewFrame.size.height)]; mustAdjustNext = YES; } else if (mustAdjustNext) { - NSRect itemViewFrame = [itemView frame]; + NSRect itemBackViewFrame = [itemBackView frame]; - [itemView setFrame: NSMakeRect(x, itemViewFrame.origin.y, itemViewFrame.size.width, - itemViewFrame.size.height)]; + [itemBackView setFrame: NSMakeRect(x, itemBackViewFrame.origin.y, + itemBackViewFrame.size.width, itemBackViewFrame.size.height)]; } - x += [itemView frame].size.width; + x += [itemBackView frame].size.width; } } @@ -470,11 +504,13 @@ static const int current_version = 1; - (NSArray *) _visibleBackViews { NSArray *items = [_toolbar items]; - NSView *itemView; + NSView *itemBackView; int i, n = [items count]; - float totalWidth = 0, toolbarWidth; + float itemBackViewsWidth = 0, toolbarWidth; - if (![_toolbar isVisible] && ![self _willBeVisible]) + // _willBeVisible indicates that the toolbar view previously hidden is in + // process to become visible again before the end of current the event loop. + if ([self superview] == nil && ![self _willBeVisible]) return nil; [_visibleBackViews release]; @@ -484,14 +520,14 @@ static const int current_version = 1; for (i = 0; i < n; i++) { - itemView = [[items objectAtIndex:i] _backView]; + itemBackView = [[items objectAtIndex:i] _backView]; - totalWidth += [itemView frame].size.width; + itemBackViewsWidth += [itemBackView frame].size.width; - if ((totalWidth + _ClippedItemsViewWidth <= toolbarWidth) || (i == n - 1 && totalWidth <= - toolbarWidth)) + if ((itemBackViewsWidth + _ClippedItemsViewWidth <= toolbarWidth) + || (i == n - 1 && itemBackViewsWidth <= toolbarWidth)) { - [_visibleBackViews addObject: itemView]; + [_visibleBackViews addObject: itemBackView]; } } diff --git a/Source/NSToolbar.m b/Source/NSToolbar.m index 5544e9a39..b58c6334a 100644 --- a/Source/NSToolbar.m +++ b/Source/NSToolbar.m @@ -6,7 +6,8 @@ Copyright (C) 2002 Free Software Foundation, Inc. Author: Gregory John Casamento , - Fabien Vallon + Fabien Vallon , + Quentin Mathe Date: May 2002 This file is part of the GNUstep GUI Library. @@ -32,60 +33,41 @@ #include #include #include -#include -#include #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" +#include "GNUstepGUI/GSToolbar.h" +#include "AppKit/NSToolbar.h" // internal static NSNotificationCenter *nc = nil; static const int current_version = 1; -static NSMutableArray *toolbars; - @interface NSToolbar (GNUstepPrivate) -// Private class methods -+ (NSArray *) _toolbars; -+ (NSArray *) _toolbarsForIdentifier: (NSString *)identifier; -// --- ++ (NSMutableArray *) _toolbars; -- (void) _insertItemWithItemIdentifier: (NSString *)itemIdentifier atIndex: (int)index broadcast: (BOOL)broadcast; - -// 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; +// Private methods with broadcast support +- (void) _setDisplayMode: (NSToolbarDisplayMode)displayMode + broadcast: (BOOL)broadcast; +- (void) _setSizeMode: (NSToolbarSizeMode)sizeMode + 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; +- (GSToolbar *) _toolbarModel; // Accessors -- (void) _setToolbarView: (GSToolbarView *)toolbarView; -- (GSToolbarView *) _toolbarView; - (void) _setWindow: (NSWindow *)window; - (NSWindow *) _window; @end @interface NSToolbarItem (GNUstepPrivate) -- (void) _setToolbar: (NSToolbar *)toolbar; +- (void) _setToolbar: (GSToolbar *)toolbar; @end @interface GSToolbarView (GNUstepPrivate) @@ -108,175 +90,58 @@ static NSMutableArray *toolbars; { [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 +- (id) initWithIdentifier: (NSString *)identifier + displayMode:(NSToolbarDisplayMode)displayMode + sizeMode: (NSToolbarSizeMode)sizeMode { - NSArray *linked; NSToolbar *toolbarModel = nil; - - [super init]; - - ASSIGN(_identifier, identifier); - - _items = [[NSMutableArray alloc] init]; - linked = [NSToolbar _toolbarsForIdentifier: _identifier]; - - if (linked != nil && [linked count] > 0) + if ((self = [super initWithIdentifier: identifier + displayMode: displayMode + sizeMode: sizeMode]) == nil) { - toolbarModel = [linked objectAtIndex: 0]; + return nil; } - + + toolbarModel = (NSToolbar *)[self _toolbarModel]; + if (toolbarModel != nil) { - _customizationPaletteIsRunning = NO; - _allowsUserCustomization = [toolbarModel allowsUserCustomization]; - _autosavesConfiguration = [toolbarModel autosavesConfiguration]; - ASSIGN(_configurationDictionary, [toolbarModel configurationDictionary]); - _displayMode = [toolbarModel displayMode]; + _displayMode = [toolbarModel displayMode]; + _sizeMode = [toolbarModel sizeMode]; _visible = [toolbarModel isVisible]; - - //[self _loadConfig]; - - [self _setDelegate: [toolbarModel delegate] broadcast: NO]; } else { - _customizationPaletteIsRunning = NO; - _allowsUserCustomization = NO; - _autosavesConfiguration = NO; - _configurationDictionary = nil; - _displayMode = NSToolbarDisplayModeDefault; + _displayMode = displayMode; + _sizeMode = sizeMode; _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; -} - -- (BOOL) autosavesConfiguration -{ - return _autosavesConfiguration; -} - -- (NSDictionary *) configurationDictionary -{ - return _configurationDictionary; -} - -- (BOOL) customizationPaletteIsRunning -{ - return _customizationPaletteIsRunning; -} - -- (id) delegate -{ - return _delegate; -} - - (NSToolbarDisplayMode) displayMode { return _displayMode; } -- (NSString *) identifier +- (NSToolbarSizeMode) sizeMode { - return _identifier; + return _sizeMode; } - (BOOL) isVisible @@ -284,35 +149,6 @@ static NSMutableArray *toolbars; 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 @@ -321,24 +157,14 @@ static NSMutableArray *toolbars; * 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 { - + [self _setSizeMode: sizeMode broadcast: YES]; } - (void) setVisible: (BOOL)shown @@ -346,188 +172,48 @@ static NSMutableArray *toolbars; [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) - { - NSUserDefaults *defaults; - NSString *tableKey; - id config; - - defaults = [NSUserDefaults standardUserDefaults]; - tableKey = [NSString stringWithFormat: @"NSToolbar Config %@", - _identifier]; - config = [defaults objectForKey: tableKey]; - if (config != nil) - { - [self setConfigurationFromDictionary: config]; - } - } -} - -- (id) _toolbarItemForIdentifier: (NSString *)itemIdent -{ - id item = nil; - if([itemIdent isEqual: NSToolbarSeparatorItemIdentifier] || - [itemIdent isEqual: NSToolbarSpaceItemIdentifier] || - [itemIdent isEqual: NSToolbarFlexibleSpaceItemIdentifier] || - [itemIdent isEqual: NSToolbarShowColorsItemIdentifier] || - [itemIdent isEqual: NSToolbarShowFontsItemIdentifier] || - [itemIdent isEqual: NSToolbarCustomizeToolbarItemIdentifier] || - [itemIdent isEqual: NSToolbarPrintItemIdentifier]) - { - item = [[NSToolbarItem alloc] initWithItemIdentifier: itemIdent]; - } - return item; -} - /* * - * The methods below handles the toolbar edition and broacasts each associated event - * to the other toolbars with identical identifiers. + * The methods below handles the toolbar edition and broacasts each associated + * event to the other toolbars with identical identifiers. * */ #define TRANSMIT(signature) \ - NSEnumerator *e = [[NSToolbar _toolbarsForIdentifier: _identifier] objectEnumerator]; \ + NSEnumerator *e = [[[GSToolbar _toolbars] objectsWithValue: _identifier forKey: @"_identifier"] objectEnumerator]; \ NSToolbar *toolbar; \ \ while ((toolbar = [e nextObject]) != nil) \ { \ - if (toolbar != self) \ + if (toolbar != self && [self isMemberOfClass: [self class]]) \ [toolbar signature]; \ } -- (void) _insertItemWithItemIdentifier: (NSString *)itemIdentifier atIndex: (int)index broadcast: (BOOL)broadcast -{ - NSToolbarItem *item = nil; - NSArray *allowedItems = [_delegate toolbarAllowedItemIdentifiers: self]; - - if([allowedItems containsObject: itemIdentifier]) - { - item = [self _toolbarItemForIdentifier: itemIdentifier]; - if(item == nil) - { - item = [_delegate toolbar: self - itemForItemIdentifier: itemIdentifier - willBeInsertedIntoToolbar: YES]; - } - - if (item != nil) - { - [nc postNotificationName: NSToolbarWillAddItemNotification object: self]; - [item _setToolbar: self]; - [_items insertObject: item atIndex: index]; - // We reload the toolbarView each time a new item is - // added except when we build/create the toolbar - if (!_build) - [_toolbarView _reload]; - - if (broadcast) - { - TRANSMIT(_insertItemWithItemIdentifier: itemIdentifier - atIndex: index broadcast: NO); - } - } - } -} - -- (void) _removeItemAtIndex: (int)index broadcast: (BOOL)broadcast -{ - - [_items removeObjectAtIndex: index]; - [_toolbarView _reload]; - [nc postNotificationName: NSToolbarDidRemoveItemNotification - object: self]; - - if (broadcast) - { - TRANSMIT(_removeItemAtIndex: index broadcast: NO); - } -} - -- (void) _setAllowsUserCustomization: (BOOL)flag broadcast: (BOOL)broadcast -{ - _allowsUserCustomization = flag; - - if (broadcast) - { - TRANSMIT(_setAllowsUserCustomization: _allowsUserCustomization broadcast: NO); - } -} - -- (void) _setAutosavesConfiguration: (BOOL)flag broadcast: (BOOL)broadcast -{ - _autosavesConfiguration = flag; - - if (broadcast) - { - TRANSMIT(_setAutosavesConfiguration: _autosavesConfiguration broadcast: NO); - } -} - -- (void) _setConfigurationFromDictionary: (NSDictionary *)configDict broadcast: (BOOL)broadcast -{ - ASSIGN(_configurationDictionary, configDict); - - if (broadcast) - { - TRANSMIT(_setConfigurationFromDictionary: _configurationDictionary broadcast: NO); - } -} - -- (void) _setDisplayMode: (NSToolbarDisplayMode)displayMode broadcast: (BOOL)broadcast +- (void) _setDisplayMode: (NSToolbarDisplayMode)displayMode + broadcast: (BOOL)broadcast { _displayMode = displayMode; + + // do more if (broadcast) { - TRANSMIT(_setDisplayMode: _displayMode broadcast: NO); + TRANSMIT(_setDisplayMode: _displayMode broadcast: NO); + } +} + +- (void) setSizeMode: (NSToolbarSizeMode)sizeMode + broadcast: (BOOL)broadcast +{ + _sizeMode = sizeMode; + + // do more + + if (broadcast) + { + TRANSMIT(_setSizeMode: _sizeMode broadcast: NO); } } @@ -543,15 +229,14 @@ static NSMutableArray *toolbars; [_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."); } + + _visible = shown; + // Important to set _visible after the toolbar 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. } if (broadcast) @@ -560,59 +245,12 @@ static NSMutableArray *toolbars; } } -- (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] - - CHECK_REQUIRED_METHOD(toolbar:itemForItemIdentifier:willBeInsertedIntoToolbar:); - CHECK_REQUIRED_METHOD(toolbarAllowedItemIdentifiers:); - CHECK_REQUIRED_METHOD(toolbarDefaultItemIdentifiers:); - - if (_delegate) - [nc removeObserver: _delegate name: nil object: self]; - _delegate = delegate; - - #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] - - SET_DELEGATE_NOTIFICATION(DidRemoveItem); - SET_DELEGATE_NOTIFICATION(WillAddItem); - - if (_window != nil) // The delegate should be called when the toolbar will become visible (= window not nil) - { - [self _build]; // Build the toolbar with the delegate or a toolbar model - [_toolbarView _reload]; - } - - // broadcast now... - - if (broadcast) - { - TRANSMIT(_setDelegate: _delegate broadcast: NO); - } -} - // Private Accessors -- (void) _setToolbarView: (GSToolbarView *)toolbarView -{ - ASSIGN(_toolbarView, toolbarView); -} - -- (GSToolbarView *) _toolbarView -{ - return _toolbarView; -} - - (void)_setWindow: (NSWindow *)window { - ASSIGN(_window, window); // call [NSWindow(Toolbar) setToolbar:] to set the toolbar window + ASSIGN(_window, window); + // call [NSWindow(Toolbar) setToolbar:] to set the toolbar window } - (NSWindow *) _window diff --git a/Source/NSWindow+Toolbar.h b/Source/NSWindow+Toolbar.h index ee738b8d5..8c6fcc4cd 100644 --- a/Source/NSWindow+Toolbar.h +++ b/Source/NSWindow+Toolbar.h @@ -5,7 +5,7 @@ Copyright (C) 2004 Free Software Foundation, Inc. - Author: Quentin Mathé + Author: Quentin Mathe Date: January 2004 This file is part of the GNUstep GUI Library. diff --git a/Source/NSWindow+Toolbar.m b/Source/NSWindow+Toolbar.m index 68e619553..eaa256568 100644 --- a/Source/NSWindow+Toolbar.m +++ b/Source/NSWindow+Toolbar.m @@ -4,7 +4,7 @@ Copyright (C) 2004 Free Software Foundation, Inc. - Author: Quentin Mathé + Author: Quentin Mathe Date: January 2004 This file is part of the GNUstep GUI Library. @@ -43,6 +43,7 @@ static const int ToolbarHeight = 61; @end @interface GSToolbarView (GNUstepPrivate) +- (void) _setToolbar: (NSToolbar *)toolbar; - (void) _handleViewsVisibility; @end @@ -61,8 +62,9 @@ static const int ToolbarHeight = 61; { NSToolbar *toolbar = [self toolbar]; - if ([sender isEqual: toolbar]) // we can enter this branch when the toolbar class has called -toggleToolbarShown: + if ([sender isEqual: toolbar]) + // we can enter this branch when the toolbar class has called + // toggleToolbarShown: { [self _toggleToolbarView: [toolbar _toolbarView] display: YES]; } @@ -89,7 +91,9 @@ toggleToolbarShown: 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."]; + format: @"_contenView is not valid. _contentView needs a \ + toolbar view and a contentViewWithoutToolbar, with \ + no others subviews."]; } for (i = 0; i < n; i++) @@ -115,18 +119,22 @@ toggleToolbarShown: 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 +// user oriented method +- (void) setContentViewWithoutToolbar: (NSView *)contentViewWithoutToolbar { NSToolbar *toolbar = [self toolbar]; - if (toolbar != nil && [toolbar isVisible]) { - [_contentView replaceSubview: [self contentViewWithoutToolbar] with: contentViewWithoutToolbar]; + if (toolbar != nil && [toolbar isVisible]) + { + [_contentView replaceSubview: [self contentViewWithoutToolbar] + with: contentViewWithoutToolbar]; } else { @@ -139,6 +147,7 @@ toggleToolbarShown: { NSToolbar *lastToolbar = [self toolbar]; GSToolbarView *toolbarView = nil; + // --- if (lastToolbar != nil) { @@ -161,13 +170,15 @@ toggleToolbarShown: [toolbar _setWindow : self]; - // insert the toolbar view (we create this view when the toolbar hasn't such view)... + // 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 + // _toggleToolbarView:display: method will set the toolbar view to the right + // frame [toolbarView setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin]; } [toolbarView setBorderMask: GSToolbarViewBottomBorder]; @@ -175,7 +186,7 @@ toggleToolbarShown: // load the toolbar inside the toolbar view - [toolbarView setToolbar: toolbar]; + [toolbarView _setToolbar: toolbar]; } @@ -194,18 +205,22 @@ toggleToolbarShown: // Switch the content view RETAIN(contentViewWithoutToolbar); - [self setContentView: [[NSView alloc] initWithFrame: [_contentView frame]]]; + [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]; + [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)]; + [toolbarView setFrame: NSMakeRect(0,contentViewWithoutToolbarFrame.size.height, + contentViewWithoutToolbarFrame.size.width, ToolbarHeight)]; + [_contentView addSubview: toolbarView]; [toolbarView _handleViewsVisibility]; [toolbarView setNextResponder: self]; @@ -230,17 +245,21 @@ toggleToolbarShown: [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]; + [self setFrame: NSMakeRect(windowFrame.origin.x, + windowFrame.origin.y + ToolbarHeight, windowFrame.size.width, + windowFrame.size.height - ToolbarHeight) display: flag]; - [contentViewWithoutToolbar setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable]; + [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 + RETAIN(contentViewWithoutToolbar); + // because setContentView: will release the parent view and their subviews + [self setContentView: contentViewWithoutToolbar]; + RELEASE(contentViewWithoutToolbar); }