Permalink
Browse files

UKViewListView can animate.

git-svn-id: svn://witness.is-a-geek.org/svn@71 378c4bed-2673-4746-83ae-d22ddc8c5b7c
  • Loading branch information...
1 parent 6290385 commit 6b785b9c71a9a9cdc0bcff6e0c6f60b07d948e51 uli committed Jan 17, 2010
Showing with 47 additions and 46 deletions.
  1. +14 −1 UKViewListView.h
  2. +33 −45 UKViewListView.m
View
@@ -14,6 +14,13 @@
This is very handy with bindings: You can set a view to auto-hide according
to a specific binding, then call reLayoutViewListViews, and poof, all other
views will move up accordingly.
+
+ The autosizing option in the NIB file should be correctly set (upper-left)
+ if the BOOL doAnimateResizing is set to TRUE. Otherwise you might see a
+ bad resizing effect during the resizing of the window.
+
+ Also be sure to call reLayoutViewListViews after hidding/showing some views,
+ so that the window will be updated.
*/
#import <Cocoa/Cocoa.h>
@@ -28,6 +35,8 @@
float interViewSpacing; // Distance between bottom of one subview and top of the next.
BOOL forceToContentHeight; // Change height of this view to fit all its subviews + margins.
BOOL isInReLayout; // To avoid recursion when layouting views.
+ BOOL doAnimateResizing; // To have an animation when resizing the window.
+ BOOL isFlipped; // Use flipped-Y-axis coordinates to avoid problems with NSAnimation during combined fading and resizing.
}
-(void) setForceToContentHeight: (BOOL)doForce;
@@ -48,9 +57,13 @@
- (float)interViewSpacing;
- (void)setInterViewSpacing:(float)value;
+-(void) setAnimateResizing: (BOOL)animateResizing;
+
-(NSSize) bestSize;
-(void) reLayoutViewListViews;
--(void) observeAllSubviewsVisibilityChanges: (id)sender;
+
+-(BOOL) isFlipped;
+-(void) setIsFlipped: (BOOL)state;
@end
View
@@ -10,9 +10,6 @@
#import "NSView+SetFrameSizePinnedToTopLeft.h"
-#define HIDDEN_PROP_NAME @"isHidden"
-
-
@implementation UKViewListView
- (id)initWithFrame:(NSRect)frame
@@ -24,6 +21,7 @@ - (id)initWithFrame:(NSRect)frame
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(viewFrameDidChange:) name: NSViewFrameDidChangeNotification object: self];
interViewSpacing = -1;
forceToContentHeight = YES;
+ doAnimateResizing = NO;
}
return self;
}
@@ -38,37 +36,19 @@ - (id)initWithCoder:(NSCoder*)coder
[[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(viewFrameDidChange:) name: NSViewFrameDidChangeNotification object: self];
interViewSpacing = -1;
forceToContentHeight = YES;
+ doAnimateResizing = NO;
}
return self;
}
--(void) dealloc
-{
- NSEnumerator* enny = [[self subviews] objectEnumerator];
- NSView* currView = nil;
- while(( currView = [enny nextObject] ))
- [currView removeObserver: self forKeyPath: HIDDEN_PROP_NAME];
-
- [super dealloc];
-}
-
-(void) awakeFromNib
{
- [self performSelector: @selector(observeAllSubviewsVisibilityChanges:) withObject: nil afterDelay: 0];
[self reLayoutViewListViews];
}
--(void) observeAllSubviewsVisibilityChanges: (id)sender
-{
- NSEnumerator* enny = [[self subviews] objectEnumerator];
- NSView* currView = nil;
- while(( currView = [enny nextObject] ))
- [currView addObserver: self forKeyPath: HIDDEN_PROP_NAME options: NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context: nil];
-}
-
-(void) drawRect: (NSRect)rect
{
//NSDrawGrayBezel( [self bounds], [self bounds] ); // Debugging only.
@@ -80,14 +60,6 @@ -(void) didAddSubview: (NSView*)subview
[super didAddSubview: subview];
[self reLayoutViewListViews]; // Invalidates new box.
-
- [subview addObserver: self forKeyPath: HIDDEN_PROP_NAME options: NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew context: nil];
-}
-
-
--(void) willRemoveSubview: (NSView *)subview
-{
- [subview removeObserver: self forKeyPath: HIDDEN_PROP_NAME];
}
@@ -97,16 +69,6 @@ -(void) viewDidMoveToWindow
}
--(void) observeValueForKeyPath: (NSString*)propName ofObject: (NSView*)subview
- change: (NSDictionary*)change context: (void*)refCon
-{
- if( [propName isEqualToString: HIDDEN_PROP_NAME] )
- {
- [self reLayoutViewListViews];
- }
-}
-
-
-(void) reLayoutViewListViewsAndAdjustFrame: (BOOL)adjustFrame
{
if( !isInReLayout )
@@ -115,13 +77,22 @@ -(void) reLayoutViewListViewsAndAdjustFrame: (BOOL)adjustFrame
if( forceToContentHeight && adjustFrame )
{
if( [[self window] contentView] == self )
- [[self window] setContentSize: [self bestSize]];
+ {
+ NSWindow* wd = [self window];
+ NSRect newBox = [wd contentRectForFrameRect: [wd frame]];
+ NSSize newSize = [self bestSize];
+ newBox.size.width = newSize.width;
+ newBox.origin.y += newBox.size.height -newSize.height;
+ newBox.size.height = newSize.height;
+ newBox = [wd frameRectForContentRect: newBox];
+ [wd setFrame: newBox display: YES animate: doAnimateResizing];
+ }
else
[self setFrameSizePinnedToTopLeft: [self bestSize]];
}
NSRect myBounds = [self bounds];
- NSPoint viewPos = NSMakePoint( leftMargin, NSMaxY( myBounds ) -topMargin );
+ NSPoint viewPos = NSMakePoint( leftMargin, isFlipped ? topMargin : (NSMaxY( myBounds ) -topMargin) );
NSArray* subs = [[[self subviews] copy] autorelease];
NSEnumerator* enny = [subs objectEnumerator];
NSView* currSubview = nil;
@@ -131,11 +102,15 @@ -(void) reLayoutViewListViewsAndAdjustFrame: (BOOL)adjustFrame
if( ![currSubview isHidden] )
{
NSRect currViewBox = [currSubview bounds];
- viewPos.y -= currViewBox.size.height;
+ if( !isFlipped )
+ viewPos.y -= currViewBox.size.height;
currViewBox.origin = viewPos;
currViewBox.size.width = myBounds.size.width -leftMargin -rightMargin;
[currSubview setFrame: currViewBox];
- viewPos.y -= interViewSpacing;
+ if( !isFlipped )
+ viewPos.y -= interViewSpacing;
+ else
+ viewPos.y += currViewBox.size.height +interViewSpacing;
}
}
@@ -150,6 +125,16 @@ -(void) reLayoutViewListViews
[self reLayoutViewListViewsAndAdjustFrame: YES];
}
+-(BOOL) isFlipped
+{
+ return isFlipped;
+}
+
+
+-(void) setIsFlipped: (BOOL)state
+{
+ isFlipped = state;
+}
-(NSSize) bestSize
{
@@ -183,7 +168,6 @@ -(NSSize) bestSize
-(void) viewFrameDidChange: (NSNotification*)notif
{
- //NSLog(@"viewFrameDidChange:");
[self reLayoutViewListViewsAndAdjustFrame: NO];
}
@@ -267,5 +251,9 @@ - (void)setInterViewSpacing:(float)value
}
}
+-(void) setAnimateResizing: (BOOL)animateResizing
+{
+ doAnimateResizing = animateResizing;
+}
@end

0 comments on commit 6b785b9

Please sign in to comment.