Start to rewrite the window toolbar handling code.

git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@27478 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
Fred Kiefer 2008-12-31 16:06:58 +00:00
parent 32bd8091d9
commit 66e22d664f
8 changed files with 155 additions and 294 deletions

View file

@ -1,3 +1,14 @@
2008-12-31 Fred Kiefer <FredKiefer@gmx.de>
* Headers/AppKit/NSWindow.h: Use one of the spare ivars for toolbar.
* Headers/AppKit/NSToolbar.h: Remove window ivar.
* Source/NSWindow.m (-dealloc:): Unset the toolbar.
* Source/NSWindow+Toolbar.m: Start to rewrite
* Source/GSToolbar.m: Remove unused method declarations.
* Source/GSToolbarView.m: Remove unused methods.
* Source/NSToolbar.m: Remove all window related methods. Simplify
the rest of the code.
2008-12-31 Fred Kiefer <FredKiefer@gmx.de>
* Source/NSWindow.m (-validateMenuItem:): Add validation for

View file

@ -36,7 +36,6 @@
@interface NSToolbar : GSToolbar
{
NSWindow *_window;
BOOL _visible;
}

View file

@ -244,7 +244,7 @@ APPKIT_EXPORT NSSize NSTokenSize;
unsigned preserves_content_during_live_resize: 1;
} _f;
void *_reserved_s;
NSToolbar *_toolbar;
void *_reserved_1;
}

View file

@ -507,8 +507,6 @@ static GSValidationCenter *vc = nil;
// Accessors
- (void) _setToolbarView: (GSToolbarView *)toolbarView;
- (GSToolbarView *) _toolbarView;
- (void) _setWindow: (NSWindow *)window;
- (NSWindow *) _window;
@end
@interface NSToolbarItem (GNUstepPrivate)
@ -525,9 +523,7 @@ static GSValidationCenter *vc = nil;
// Accessors
- (NSArray *) _visibleBackViews;
- (BOOL) _usesStandardBackgroundColor;
- (BOOL) _willBeVisible;
- (void) _setUsesStandardBackgroundColor: (BOOL)standard;
- (void) _setWillBeVisible: (BOOL)willBeVisible;
@end
// ---
@ -1203,21 +1199,19 @@ static GSValidationCenter *vc = nil;
- (void) _setToolbarView: (GSToolbarView *)toolbarView
{
//GSToolbar *toolbarModel = [self _toolbarModel];
if (_toolbarView != nil)
{
[vc removeObserver: self window: nil];
}
if (toolbarView != nil)
{
[vc addObserver: self window: [toolbarView window]];
// In the case the window parameter is a nil value, nothing happens.
}
// Don't do an ASSIGN here, the toolbar itself retains us.
_toolbarView = toolbarView;
if (toolbarView != nil)
{
[vc addObserver: self window: [toolbarView window]];
// In the case the window parameter is a nil value, nothing happens.
}
}
- (GSToolbarView *) _toolbarView

View file

@ -189,8 +189,6 @@ static void initSystemExtensionsColors(void)
- (NSToolbarSizeMode) _sizeMode;
- (BOOL) _usesStandardBackgroundColor;
- (void) _setUsesStandardBackgroundColor: (BOOL)standard;
- (void) _setWillBeVisible: (BOOL)willBeVisible;
- (BOOL) _willBeVisible;
@end
@interface GSToolbarClippedItemsButton : NSButton
@ -975,20 +973,6 @@ static void initSystemExtensionsColors(void)
return _sizeMode;
}
/*
* _willBeVisible indicates that the toolbar view previously hidden is in
* process to become visible again before the end of current the event loop.
*/
- (BOOL) _willBeVisible
{
return _willBeVisible;
}
- (void) _setWillBeVisible: (BOOL)willBeVisible
{
_willBeVisible = willBeVisible;
}
- (BOOL) _usesStandardBackgroundColor
{
return [BackgroundColor isEqual: [self standardBackgroundColor]];

View file

@ -31,11 +31,9 @@
#include <Foundation/NSObject.h>
#include <Foundation/NSArray.h>
#include <Foundation/NSAutoreleasePool.h>
#include <Foundation/NSDictionary.h>
#include <Foundation/NSEnumerator.h>
#include <Foundation/NSException.h>
#include <Foundation/NSNotification.h>
#include "AppKit/NSToolbarItem.h"
#include "AppKit/NSView.h"
#include "AppKit/NSWindow.h"
@ -45,7 +43,6 @@
#include "AppKit/NSToolbar.h"
// internal
static NSNotificationCenter *nc = nil;
static const int current_version = 1;
@interface GSToolbar (GNUstepPrivate)
@ -62,27 +59,16 @@ static const int current_version = 1;
- (void) _setVisible: (BOOL)shown broadcast: (BOOL)broadcast;
// Few other private methods
- (void) _loadConfig;
- (GSToolbar *) _toolbarModel;
// Accessors
- (void) _setWindow: (NSWindow *)window;
- (NSWindow *) _window;
@end
@interface NSToolbarItem (GNUstepPrivate)
- (void) _setToolbar: (GSToolbar *)toolbar;
@end
@interface GSToolbarView (GNUstepPrivate)
- (void) _reload;
// Accessors
- (NSArray *) _visibleBackViews;
- (void) _setSizeMode: (NSToolbarSizeMode)sizeMode;
- (NSToolbarSizeMode) _sizeMode;
- (void) _setWillBeVisible: (BOOL)willBeVisible;
- (BOOL) _willBeVisible;
@end
@interface NSWindow (ToolbarPrivate)
@ -101,14 +87,13 @@ static const int current_version = 1;
if (self == [NSToolbar class])
{
[self setVersion: current_version];
nc = [NSNotificationCenter defaultCenter];
}
}
// Instance methods
- (id) initWithIdentifier: (NSString *)identifier
displayMode:(NSToolbarDisplayMode)displayMode
displayMode: (NSToolbarDisplayMode)displayMode
sizeMode: (NSToolbarSizeMode)sizeMode
{
NSToolbar *toolbarModel = nil;
@ -138,13 +123,6 @@ static const int current_version = 1;
return self;
}
- (void) dealloc
{
// NSLog(@"Dummy NSToolbar dealloc");
[super dealloc];
}
// Accessors
- (BOOL) isVisible
@ -179,7 +157,7 @@ static const int current_version = 1;
/*
*
* The methods below handles the toolbar edition and broacasts each associated
* The methods below handle the toolbar edition and broacast each associated
* event to the other toolbars with identical identifiers.
*
*/
@ -197,105 +175,52 @@ static const int current_version = 1;
- (void) _setDisplayMode: (NSToolbarDisplayMode)displayMode
broadcast: (BOOL)broadcast
{
_displayMode = displayMode;
if (_displayMode != displayMode)
{
_displayMode = displayMode;
[_toolbarView _reload];
[_window _adjustToolbarView];
if (broadcast)
{
TRANSMIT(_setDisplayMode: _displayMode broadcast: NO);
}
[_toolbarView _reload];
[[_toolbarView window] _adjustToolbarView];
if (broadcast)
{
TRANSMIT(_setDisplayMode: _displayMode broadcast: NO);
}
}
}
- (void) _setSizeMode: (NSToolbarSizeMode)sizeMode
broadcast: (BOOL)broadcast
{
_sizeMode = sizeMode;
[_toolbarView _setSizeMode: _sizeMode];
[_toolbarView _reload];
[_window _adjustToolbarView];
if (broadcast)
{
TRANSMIT(_setSizeMode: _sizeMode broadcast: NO);
}
if (_sizeMode != sizeMode)
{
_sizeMode = sizeMode;
[_toolbarView _setSizeMode: _sizeMode];
[_toolbarView _reload];
[[_toolbarView window] _adjustToolbarView];
if (broadcast)
{
TRANSMIT(_setSizeMode: _sizeMode broadcast: NO);
}
}
}
// This method wont make a toolbar visible or invisible by itself.
// Use [NSWindow toggleToolbarShown:]
- (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
// example : the toolbar needs to be still known visible in order to hide
// it.
}
if (broadcast)
{
TRANSMIT(_setVisible: _visible broadcast: NO);
}
}
// Notifications
- (void) handleNotification: (NSNotification *)notification
{
// We currently only worry about when our window closes.
// It's necessary to set the _window ivar in master list to nil when it is
// closed, so that it doesn't cause a segmentation fault when we looks at
// _window ivar with KVC in -[NSWindow(Toolbar) toolbar].
[self _setWindow: nil];
if ([_toolbarView superview] == nil)
RELEASE(_toolbarView);
// We release the toolbar view in such case because NSWindow(Toolbar) retains
// it when its superview value is nil.
}
// Private Accessors
- (void) _setWindow: (NSWindow *)window
{
if (_window != window)
{
if (_window)
{
[nc removeObserver: self];
}
if (window)
{
// Watch for this window closing....
[nc addObserver: self
selector: @selector(handleNotification:)
name: NSWindowWillCloseNotification
object: window];
}
if (broadcast)
{
TRANSMIT(_setVisible: _visible broadcast: NO);
}
}
// We don't do an ASSIGN because the toolbar view retains us.
// call [NSWindow(Toolbar) setToolbar:] to set the toolbar window
_window = window;
}
- (NSWindow *) _window
{
return _window;
}
@end

View file

@ -35,27 +35,19 @@
#include "GNUstepGUI/GSToolbarView.h"
@interface GSToolbar (GNUstepPrivate)
+ (NSArray *) _toolbars;
@end
@interface NSToolbar (GNUstepPrivate)
- (GSToolbarView *) _toolbarView;
- (void) _setWindow: (NSWindow *)window;
- (NSWindow *) _window;
@end
@interface GSToolbarView (GNUstepPrivate)
- (void) _setToolbar: (NSToolbar *)toolbar;
- (float) _heightFromLayout;
- (void) _reload;
- (void) _setWillBeVisible: (BOOL)willBeVisible;
@end
@interface NSWindow (ToolbarPrivate)
- (void) _adjustToolbarView;
- (void) _toggleToolbarViewWithDisplay: (BOOL)flag;
- (NSView *) contentViewWithoutToolbar;
- (void) setContentViewWithoutToolbar: (NSView *)contentViewWithoutToolbar;
- (void) _toggleToolbarView;
- (NSView *) _contentViewWithoutToolbar;
@end
@implementation NSWindow (Toolbar)
@ -68,35 +60,25 @@
- (void) toggleToolbarShown: (id)sender
{
NSToolbar *toolbar = [self toolbar];
BOOL isVisible = [toolbar isVisible];
GSToolbarView *toolbarView = [toolbar _toolbarView];
// We can enter this branch when the toolbar class has called
// toggleToolbarShown:
if ([sender isEqual: toolbar])
{
if (!isVisible) // In the case : not visible when the method has been called
{
[toolbarView setFrameSize:
NSMakeSize([NSWindow
contentRectForFrameRect: [self frame]
styleMask: [self styleMask]].size.width, 100)];
// -toogleToolbarViewWithDisplay: will reset the toolbarView frame
[toolbarView _reload]; // Will recalculate the layout
}
[self _toggleToolbarViewWithDisplay: YES];
}
else
{
// We call the toolbar class letting it call back on toggleToolbarShown:
[toolbar setVisible: !isVisible];
}
if (!toolbar)
return;
[self _toggleToolbarView];
// Important to set _visible after the toolbar view has been toggled because
// NSWindow method contentViewWithoutToolbar uses [NSToolbar visible]
// when we toggle the toolbar
// example : the toolbar needs to be still known visible in order to hide
// it.
[toolbar setVisible: ![toolbar isVisible]];
[self display];
}
// Accessors
- (NSView *) contentViewWithoutToolbar
- (NSView *) _contentViewWithoutToolbar
{
NSToolbar *toolbar = [self toolbar];
@ -136,97 +118,62 @@
- (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];
}
// User oriented method
- (void) setContentViewWithoutToolbar: (NSView *)contentViewWithoutToolbar
{
NSToolbar *toolbar = [self toolbar];
if (toolbar != nil && [toolbar isVisible])
{
[_contentView replaceSubview: [self contentViewWithoutToolbar]
with: contentViewWithoutToolbar];
}
else
{
[self setContentView: contentViewWithoutToolbar];
}
return _toolbar;
}
- (void) setToolbar: (NSToolbar*)toolbar
{
NSToolbar *lastToolbar = [self toolbar];
GSToolbarView *toolbarView = [toolbar _toolbarView];
if (toolbarView != nil)
{
NSLog(@"Error: the new toolbar is still owned by a toolbar view");
return;
}
if (toolbar == lastToolbar)
return;
if (lastToolbar != nil)
{
// We throw the last toolbar out
[self _toggleToolbarViewWithDisplay: NO];
[lastToolbar _setWindow: nil];
if ([lastToolbar isVisible])
{
[self _toggleToolbarView];
}
// FIXME: Should release the toolbarView
}
// When there is no new toolbar
if (toolbar == nil)
ASSIGN(_toolbar, toolbar);
if (toolbar != nil)
{
[self display]; // To show we have toggle the previous toolbar view
return;
}
GSToolbarView *toolbarView = [toolbar _toolbarView];
/*
* Else we do
*/
// The window want to know which toolbar is binded
[toolbar _setWindow : self];
// Instantiate the toolbar view
if (toolbarView == nil)
{
toolbarView = [[GSToolbarView alloc] initWithFrame:
NSMakeRect(0, 0,
[NSWindow contentRectForFrameRect: [self frame]
styleMask: [self styleMask]].size.width, 100)];
// _toggleToolbarView:display: method will set the toolbar view to the right
// frame
[toolbarView setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin];
}
[toolbarView setBorderMask: GSToolbarViewBottomBorder];
// Load the toolbar inside the toolbar view
[toolbarView _setWillBeVisible: YES];
[toolbarView _setToolbar: toolbar]; // Will set the _toolbarView variable for the toolbar
[toolbarView _setWillBeVisible: NO];
if (toolbarView != nil)
{
NSLog(@"Error: the new toolbar is still owned by a toolbar view");
}
else
{
// Instantiate the toolbar view
toolbarView = [[GSToolbarView alloc]
initWithFrame:
NSMakeRect(0, 0,
[NSWindow contentRectForFrameRect: [self frame]
styleMask: [self styleMask]].size.width, 100)];
// _toggleToolbarView method will set the toolbar view to the right
// frame
[toolbarView setAutoresizingMask: NSViewWidthSizable | NSViewMinYMargin];
[toolbarView setBorderMask: GSToolbarViewBottomBorder];
// Load the toolbar inside the toolbar view
// Will set the _toolbarView variable for the toolbar
[toolbarView _setToolbar: toolbar];
}
// Make the toolbar view visible
// We do that in this way...
// because _toggleToolbarViewWithDisplay: will call -toolbarView method for the toolbar
if ([toolbar isVisible])
[self _toggleToolbarViewWithDisplay: YES];
// Make the toolbar view visible
if ([toolbar isVisible])
{
[self _toggleToolbarView];
}
}
// To show the changed toolbar
[self display];
}
// Private methods
@ -235,42 +182,47 @@
{
NSToolbar *toolbar = [self toolbar];
// Views
GSToolbarView *toolbarView = [toolbar _toolbarView];
NSView *contentViewWithoutToolbar = [self contentViewWithoutToolbar];
// Frame and height
NSRect windowFrame = [self frame];
NSRect toolbarViewFrame = [toolbarView frame];
float toolbarViewHeight = toolbarViewFrame.size.height;
float newToolbarViewHeight = [toolbarView _heightFromLayout];
[toolbarView setFrame: NSMakeRect(
toolbarViewFrame.origin.x,
toolbarViewFrame.origin.y + (toolbarViewHeight - newToolbarViewHeight),
toolbarViewFrame.size.width,
newToolbarViewHeight)];
if ([toolbar isVisible])
{
// Resize the window
// Views
GSToolbarView *toolbarView = [toolbar _toolbarView];
[contentViewWithoutToolbar setAutoresizingMask: NSViewNotSizable];
// Frame and height
NSRect toolbarViewFrame = [toolbarView frame];
float toolbarViewHeight = toolbarViewFrame.size.height;
float newToolbarViewHeight = [toolbarView _heightFromLayout];
[self setFrame: NSMakeRect(
windowFrame.origin.x,
windowFrame.origin.y + (toolbarViewHeight - newToolbarViewHeight),
windowFrame.size.width,
windowFrame.size.height - (toolbarViewHeight - newToolbarViewHeight)) display: NO];
if (toolbarViewHeight != newToolbarViewHeight)
{
NSView *contentViewWithoutToolbar = [self _contentViewWithoutToolbar];
NSRect windowFrame = [self frame];
[contentViewWithoutToolbar setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
[self display];
[toolbarView setFrame: NSMakeRect(
toolbarViewFrame.origin.x,
toolbarViewFrame.origin.y + (toolbarViewHeight - newToolbarViewHeight),
toolbarViewFrame.size.width,
newToolbarViewHeight)];
// Resize the window
[contentViewWithoutToolbar setAutoresizingMask: NSViewNotSizable];
[self setFrame: NSMakeRect(
windowFrame.origin.x,
windowFrame.origin.y + (toolbarViewHeight - newToolbarViewHeight),
windowFrame.size.width,
windowFrame.size.height - (toolbarViewHeight - newToolbarViewHeight))
display: NO];
[contentViewWithoutToolbar setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
[self display];
}
}
}
- (void) _toggleToolbarViewWithDisplay: (BOOL)flag {
- (void) _toggleToolbarView
{
// Views
GSToolbarView *toolbarView = [[self toolbar] _toolbarView];
NSView *contentViewWithoutToolbar;
@ -282,31 +234,32 @@
if ([toolbarView superview] == nil)
{
float newToolbarViewHeight = [toolbarView _heightFromLayout];
float newToolbarViewHeight;
NSRect contentViewWithoutToolbarFrame;
[toolbarView setFrameSize:
NSMakeSize(windowContentFrame.size.width, 100)];
// Will recalculate the layout
[toolbarView _reload];
newToolbarViewHeight = [toolbarView _heightFromLayout];
contentViewWithoutToolbar = _contentView;
contentViewWithoutToolbarFrame = [contentViewWithoutToolbar frame];
// Switch the content view
RETAIN(contentViewWithoutToolbar);
[self setContentView:
AUTORELEASE([[NSView alloc] initWithFrame: [_contentView frame]])];
AUTORELEASE([[NSView alloc] initWithFrame:
contentViewWithoutToolbarFrame])];
// Resize the window
windowContentFrame.origin.y -= newToolbarViewHeight;
windowContentFrame.size.height += newToolbarViewHeight;
[self setFrame: [NSWindow frameRectForContentRect: windowContentFrame
styleMask: [self styleMask]]
display: NO];
// Plug the toolbar view
contentViewWithoutToolbarFrame = [contentViewWithoutToolbar frame];
[toolbarView setFrame: NSMakeRect(
0,
contentViewWithoutToolbarFrame.size.height,
@ -316,7 +269,6 @@
RELEASE(toolbarView);
// Insert the previous content view
/* We want contentViewWithoutToolbarFrame at the origin of our new
content view. There's no guarantee that the old position was (0,0). */
contentViewWithoutToolbarFrame.origin.x = 0;
@ -330,14 +282,13 @@
{
float toolbarViewHeight = [toolbarView frame].size.height;
contentViewWithoutToolbar = [self contentViewWithoutToolbar];
contentViewWithoutToolbar = [self _contentViewWithoutToolbar];
// Unplug the toolbar view
RETAIN(toolbarView);
[toolbarView removeFromSuperview];
[toolbarView removeFromSuperviewWithoutNeedingDisplay];
// Resize the window
[contentViewWithoutToolbar setAutoresizingMask: NSViewMaxYMargin];
windowContentFrame.origin.y += toolbarViewHeight;
@ -351,19 +302,15 @@
// Autoresizing mask will be set again by the setContentView: method
// Switch the content view
RETAIN(contentViewWithoutToolbar);
// Because setContentView: will release the parent view (aka _contentView) and
// their subviews and actually contentViewWithoutToolbar is a subview of _contentView
// its subviews and actually contentViewWithoutToolbar is a subview of _contentView
[contentViewWithoutToolbar removeFromSuperviewWithoutNeedingDisplay];
[self setContentView: contentViewWithoutToolbar];
RELEASE(contentViewWithoutToolbar);
}
if (flag)
[self display];
}
@end

View file

@ -729,6 +729,7 @@ many times.
- (void) dealloc
{
[self setToolbar: nil];
[nc removeObserver: self];
[isa _removeAutodisplayedWindow: self];
[NSApp removeWindowsItem: self];