mirror of
https://github.com/gnustep/libs-gui.git
synced 2025-04-23 12:00:52 +00:00
Implemented autosaveName for splitviews - a cool addition from a user perspective
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@26420 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
190c13dca9
commit
82d086b439
3 changed files with 213 additions and 44 deletions
16
ChangeLog
16
ChangeLog
|
@ -1,3 +1,19 @@
|
|||
2008-04-01 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
Implemented -setAutosaveName: for NSSplitView.
|
||||
* Headers/AppKit/NSSplitView.h ([-setAutosaveName:],
|
||||
[autosaveName]): New methods. New instance variable
|
||||
_autosaveName.
|
||||
* Source/NSSplitView.m ([-_autosaveSubviewProportions]): New
|
||||
method. ([-mouseDown:]): Invoke _autosaveSubviewProportions at
|
||||
the end of the tracking. ([-adjustSubviews]): Rewritten to support
|
||||
loading autosaved subview proportions as well as proportionally
|
||||
resizing current ones. ([-autosaveName], [-setAutosaveName:]):
|
||||
New methods. ([-dealloc]): Release the new
|
||||
ivar. ([-encodeWithCoder:]): Encode autosaveName using
|
||||
NSAutosaveName key. ([-initWithCoder:]): If the NSAutosaveName
|
||||
key is set, decode it.
|
||||
|
||||
2008-04-01 Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
|
||||
* Source/NSSplitView.m ([-adjustSubviews]): Removed unused
|
||||
|
|
|
@ -36,14 +36,15 @@
|
|||
|
||||
@interface NSSplitView : NSView
|
||||
{
|
||||
id _delegate;
|
||||
float _dividerWidth;
|
||||
float _draggedBarWidth;
|
||||
BOOL _isVertical;
|
||||
NSImage *_dimpleImage;
|
||||
NSColor *_backgroundColor;
|
||||
NSColor *_dividerColor;
|
||||
BOOL _never_displayed_before;
|
||||
id _delegate;
|
||||
float _dividerWidth;
|
||||
float _draggedBarWidth;
|
||||
BOOL _isVertical;
|
||||
NSImage *_dimpleImage;
|
||||
NSColor *_backgroundColor;
|
||||
NSColor *_dividerColor;
|
||||
BOOL _never_displayed_before;
|
||||
NSString *_autosaveName;
|
||||
}
|
||||
|
||||
- (void) setDelegate: (id)anObject;
|
||||
|
@ -60,6 +61,8 @@
|
|||
- (BOOL) isSubviewCollapsed: (NSView *)subview;
|
||||
- (BOOL) isPaneSplitter;
|
||||
- (void) setIsPaneSplitter: (BOOL)flag;
|
||||
- (void) setAutosaveName: (NSString *)autosaveName;
|
||||
- (NSString *) autosaveName;
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
<abstract>Allows multiple views to share a region in a window</abstract>
|
||||
|
||||
Copyright (C) 1996, 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc.
|
||||
Copyright (C) 1996, 1998, 1999, 2000, 2001, 2004, 2008 Free Software Foundation, Inc.
|
||||
|
||||
Author: Robert Vasvari <vrobi@ddrummer.com>
|
||||
Date: Jul 1998
|
||||
|
@ -10,8 +10,8 @@
|
|||
Date: November 1998
|
||||
Author: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
Date: January 1999
|
||||
Author: Nicola Pero <n.pero@mi.flashnet.it>
|
||||
Date: 2000, 2001
|
||||
Author: Nicola Pero <nicola.pero@meta-innovation.com>
|
||||
Date: 2000, 2001, 2008
|
||||
|
||||
This file is part of the GNUstep GUI Library.
|
||||
|
||||
|
@ -35,12 +35,14 @@
|
|||
#include <math.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSCoder.h>
|
||||
#include <Foundation/NSDecimalNumber.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSGeometry.h>
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSRunLoop.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
|
||||
#include "AppKit/NSApplication.h"
|
||||
#include "AppKit/NSColor.h"
|
||||
|
@ -84,6 +86,7 @@ static NSNotificationCenter *nc = nil;
|
|||
RELEASE(_backgroundColor);
|
||||
RELEASE(_dividerColor);
|
||||
RELEASE(_dimpleImage);
|
||||
TEST_RELEASE(_autosaveName);
|
||||
|
||||
if (_delegate != nil)
|
||||
{
|
||||
|
@ -94,6 +97,68 @@ static NSNotificationCenter *nc = nil;
|
|||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void) _autosaveSubviewProportions
|
||||
{
|
||||
if (_autosaveName != nil)
|
||||
{
|
||||
NSUserDefaults *defaults;
|
||||
NSString *splitViewKey;
|
||||
NSMutableDictionary *config;
|
||||
NSArray *subs = [self subviews];
|
||||
unsigned count = [subs count];
|
||||
NSView *views[count];
|
||||
|
||||
defaults = [NSUserDefaults standardUserDefaults];
|
||||
splitViewKey = [NSString stringWithFormat: @"NSSplitView Dividers %@",
|
||||
_autosaveName];
|
||||
config = [NSMutableDictionary new];
|
||||
|
||||
[subs getObjects: views];
|
||||
|
||||
/* Compute the proportions and store them. */
|
||||
if (count > 0)
|
||||
{
|
||||
int i;
|
||||
float oldTotal = 0.0;
|
||||
NSRect frames[count];
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
frames[i] = [views[i] frame];
|
||||
if (_isVertical == NO)
|
||||
{
|
||||
oldTotal += NSHeight(frames[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
oldTotal += NSWidth(frames[i]);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < (count - 1); i++)
|
||||
{
|
||||
double proportion;
|
||||
|
||||
if (_isVertical == NO)
|
||||
{
|
||||
proportion = (NSHeight(frames[i]))/oldTotal;
|
||||
}
|
||||
else
|
||||
{
|
||||
proportion = (NSWidth(frames[i]))/oldTotal;
|
||||
}
|
||||
|
||||
[config setObject: [NSNumber numberWithDouble: proportion]
|
||||
forKey: [NSNumber numberWithInt: i]];
|
||||
}
|
||||
}
|
||||
|
||||
[defaults setObject: config forKey: splitViewKey];
|
||||
[defaults synchronize];
|
||||
RELEASE (config);
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL) acceptsFirstMouse: (NSEvent*)theEvent
|
||||
{
|
||||
return YES;
|
||||
|
@ -604,6 +669,7 @@ static NSNotificationCenter *nc = nil;
|
|||
[nc postNotificationName: NSSplitViewDidResizeSubviewsNotification
|
||||
object: self];
|
||||
|
||||
[self _autosaveSubviewProportions];
|
||||
|
||||
[self setNeedsDisplay: YES];
|
||||
|
||||
|
@ -626,46 +692,114 @@ static NSNotificationCenter *nc = nil;
|
|||
|
||||
- (void) adjustSubviews
|
||||
{
|
||||
/* Try to load the autosaved view proportions, if any; if there are
|
||||
* no autosaved view proportions, then manually adjust subviews
|
||||
* proportionally to their current sizes.
|
||||
*/
|
||||
NSArray *subs = [self subviews];
|
||||
unsigned count = [subs count];
|
||||
NSView *views[count];
|
||||
NSRect frames[count];
|
||||
NSSize newSize;
|
||||
NSPoint newPoint;
|
||||
unsigned i;
|
||||
float oldTotal;
|
||||
float newTotal;
|
||||
float scale;
|
||||
float running;
|
||||
|
||||
BOOL autoloading = NO;
|
||||
double proportions[count];
|
||||
|
||||
[nc postNotificationName: NSSplitViewWillResizeSubviewsNotification
|
||||
object: self];
|
||||
|
||||
|
||||
|
||||
/* Try loading the autosaved view proportions. We store the
|
||||
* proportions between the size of each view and the size of the
|
||||
* whole area occupied by the views. */
|
||||
if (_autosaveName != nil)
|
||||
{
|
||||
NSUserDefaults *defaults;
|
||||
NSDictionary *config;
|
||||
NSString *splitViewKey;
|
||||
|
||||
defaults = [NSUserDefaults standardUserDefaults];
|
||||
splitViewKey = [NSString stringWithFormat: @"NSSplitView Dividers %@",
|
||||
_autosaveName];
|
||||
config = [defaults objectForKey: splitViewKey];
|
||||
if (config != nil)
|
||||
{
|
||||
autoloading = YES;
|
||||
/* Please note that we don't save the 'proportion' of the
|
||||
* last view; it will be set up to take exactly the
|
||||
* remaining available space. */
|
||||
for (i = 0; i < (count - 1); i++)
|
||||
{
|
||||
NSNumber *proportion = [config objectForKey: [NSNumber numberWithInt: i]];
|
||||
|
||||
if (proportion == nil)
|
||||
{
|
||||
/* If any autosaved proportion is missing, do not do
|
||||
* any autoloading.
|
||||
*/
|
||||
autoloading = NO;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
proportions[i] = [proportion doubleValue];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[subs getObjects: views];
|
||||
if (_isVertical == NO)
|
||||
|
||||
/* If we haven't managed to load any saved view proportions, compute
|
||||
* default proportions using the current view sizes. */
|
||||
if (autoloading == NO)
|
||||
{
|
||||
newTotal = NSHeight(_bounds) - _dividerWidth*(count - 1);
|
||||
oldTotal = 0.0;
|
||||
float oldTotal = 0.0;
|
||||
NSRect frames[count];
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
frames[i] = [views[i] frame];
|
||||
oldTotal += NSHeight(frames[i]);
|
||||
if (_isVertical == NO)
|
||||
{
|
||||
oldTotal += NSHeight(frames[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
oldTotal += NSWidth(frames[i]);
|
||||
}
|
||||
}
|
||||
scale = newTotal/oldTotal;
|
||||
running = 0.0;
|
||||
|
||||
for (i = 0; i < (count - 1); i++)
|
||||
{
|
||||
if (_isVertical == NO)
|
||||
{
|
||||
proportions[i] = (NSHeight(frames[i]))/oldTotal;
|
||||
}
|
||||
else
|
||||
{
|
||||
proportions[i] = (NSWidth(frames[i]))/oldTotal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_isVertical == NO)
|
||||
{
|
||||
float newTotal = NSHeight(_bounds) - _dividerWidth*(count - 1);
|
||||
float running = 0.0;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
float newHeight;
|
||||
|
||||
newHeight = NSHeight(frames[i]) * scale;
|
||||
if (i == count - 1)
|
||||
if (i < (count - 1))
|
||||
{
|
||||
newHeight = floor(newHeight);
|
||||
newHeight = floor(proportions[i] * newTotal);
|
||||
}
|
||||
else
|
||||
{
|
||||
newHeight = ceil(newHeight);
|
||||
/* Size the last view to take exactly the remaining
|
||||
* space. */
|
||||
newHeight = NSHeight(_bounds) - running;
|
||||
}
|
||||
newSize = NSMakeSize(NSWidth(_bounds), newHeight);
|
||||
newPoint = NSMakePoint(0.0, running);
|
||||
|
@ -676,27 +810,20 @@ static NSNotificationCenter *nc = nil;
|
|||
}
|
||||
else
|
||||
{
|
||||
newTotal = NSWidth(_bounds) - _dividerWidth*(count - 1);
|
||||
oldTotal = 0.0;
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
frames[i] = [views[i] frame];
|
||||
oldTotal += NSWidth(frames[i]);
|
||||
}
|
||||
scale = newTotal/oldTotal;
|
||||
running = 0.0;
|
||||
float newTotal = NSWidth(_bounds) - _dividerWidth*(count - 1);
|
||||
float running = 0.0;
|
||||
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
float newWidth;
|
||||
|
||||
newWidth = NSWidth(frames[i]) * scale;
|
||||
if (i == count - 1)
|
||||
if (i < (count - 1))
|
||||
{
|
||||
newWidth = floor(newWidth);
|
||||
newWidth = floor(proportions[i] * newTotal);
|
||||
}
|
||||
else
|
||||
{
|
||||
newWidth = ceil(newWidth);
|
||||
newWidth = NSWidth(_bounds) - running;
|
||||
}
|
||||
newSize = NSMakeSize(newWidth, NSHeight(_bounds));
|
||||
newPoint = NSMakePoint(running, 0.0);
|
||||
|
@ -710,6 +837,13 @@ static NSNotificationCenter *nc = nil;
|
|||
|
||||
[nc postNotificationName: NSSplitViewDidResizeSubviewsNotification
|
||||
object: self];
|
||||
|
||||
/* Do not autosave if we just autoloaded - there's no point as it
|
||||
* would be the same information we just loaded. ;-) */
|
||||
if (autoloading == NO)
|
||||
{
|
||||
[self _autosaveSubviewProportions];
|
||||
}
|
||||
}
|
||||
|
||||
- (float) dividerThickness
|
||||
|
@ -775,13 +909,23 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
|
|||
|
||||
- (BOOL) isPaneSplitter
|
||||
{
|
||||
// FIXME
|
||||
/* TODO */
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void) setIsPaneSplitter: (BOOL)flag
|
||||
{
|
||||
// FIXME
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
- (NSString *) autosaveName
|
||||
{
|
||||
return _autosaveName;
|
||||
}
|
||||
|
||||
- (void) setAutosaveName: (NSString *)autosaveName
|
||||
{
|
||||
ASSIGN(_autosaveName, autosaveName);
|
||||
}
|
||||
|
||||
/* Overridden Methods */
|
||||
|
@ -883,6 +1027,7 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
|
|||
if([aCoder allowsKeyedCoding])
|
||||
{
|
||||
[aCoder encodeBool: _isVertical forKey: @"NSIsVertical"];
|
||||
[aCoder encodeObject: _autosaveName forKey: @"NSAutosaveName"];
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -917,6 +1062,11 @@ static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
|
|||
[self setVertical: [aDecoder decodeBoolForKey: @"NSIsVertical"]];
|
||||
}
|
||||
|
||||
if ([aDecoder containsValueForKey: @"NSAutosaveName"])
|
||||
{
|
||||
[self setAutosaveName: [aDecoder decodeObjectForKey: @"NSAutosaveName"]];
|
||||
}
|
||||
|
||||
_dividerWidth = [self dividerThickness];
|
||||
_draggedBarWidth = 8; // default bigger than dividerThickness
|
||||
ASSIGN(_dividerColor, [NSColor controlShadowColor]);
|
||||
|
|
Loading…
Reference in a new issue