How to create a side drawer of fixed height
How to create a side drawer of fixed height
- Subject: How to create a side drawer of fixed height
- From: "Tim Armes" <email@hidden>
- Date: Tue, 28 Nov 2006 09:59:47 +0100
Hi all,
Further to my previous email requesting help with the implementation of a
fixed height drawer, I've since made some major progress.
I now have a subclass of NSDrawer than maintains a fixed *maximum* height.
Two important points to note:
* I manage to recover the drawer's underlying window in a relatively clean
way
* For a side drawer, setContentSize and it's siblings do *not* have any
effect on the height
of the content's view. The drawer's height is based on the parent height
and the
leading/trailing offsets, and the content view's height is always set to
fill the drawer.
This means that given the drawer frame and the content frame, we can
calculate the "padding"
at the top and bottom of the drawer.
Here is the most important function:
- (void) calculateOffsets
{
// Get the frames of the windows concerned
NSRect parentRect = [[self parentWindow] frame];
NSRect drawerRect = [[[self contentView] window] frame];
NSRect contentRect = [[self contentView] frame];
// totallLeadingOffset = distance between top of content view and top of
parent frame
float totallLeadingOffset = (parentRect.origin.y +
parentRect.size.height) -
(contentRect.origin.y +
contentRect.size.height);
// bottomPadding = distance between bottom of dramer's frame and bottom
of content view
float bottomPadding = contentRect.origin.y - drawerRect .origin.y;
// Calculate and set the trailing offset.
float trailingOffset = parentRect.size.height - totallLeadingOffset -
myMaxHeight - bottomPadding;
if (trailingOffset < 0) trailingOffset = 0;
[self setTrailingOffset: trailingOffset];
}
This function however leads to a side effect. It seems that something,
probably NSDrawer itself, is responsible for setting the window's minimum
height based on this formula:
min height = Total leading offset + top padding + *min* content height +
bottom padding + trailing offset.
(The padding is the difference between the drawer's frame and the contents
view's frame.)
If we set the minimum height of the drawer to be the same as the maximum
height, then the following occurs:
1) The user makes the parent bigger.
2) The new trailing offset is calculated so as to retain the drawer's max
height
3) NSDrawer sets the parent's min height based on th new trailing offset.
The result is that the window can't then be reduced in size!
The only solution is to set a minimum content height of 0 so that the window
can always be reduced.
Now, on to the point of this post...
I wish my drawer class to calculate the parent's true minimum height to be
based on the maximum height that the drawer can take on. If I do this, then
I'll erase the window's previous setting. Does anyone have any ideas on how
NSDrawer handles this issue?
At a basic level, it must do something like this:
1) Recover the initial value
2) When the drawer opens, set the new min height
3) When the drawer closes, reset the value
However, with multiple drawers this procedure won't work, since the
following could happen:
1) Draws A and B are closed
2) User opens drawer A
3) A memorises the min height (h1) and sets a new min height (dh1)
4) User opens B
5) B memorises the current min height (dh1) and sets a new min height (dh2)
6) User closes A
7) A resets height to (h1), wiping the current value
8) User closes B
9) B resets height to dh1 !!
Not only that, but the program could be changing the minimum height
programatically while the drawers are open.
Clearly the minimum height handling isn't done it this way.
Do any of you have any insights?
Thanks,
Tim
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden