Re: Fwd: NSSplitView hacking
Re: Fwd: NSSplitView hacking
- Subject: Re: Fwd: NSSplitView hacking
- From: "Louis C. Sacha" <email@hidden>
- Date: Thu, 18 Dec 2003 01:34:44 -0800
Hello...
You might be able to do what you want by overriding the
adjustSubViews method...
It wouldn't exactly be a trivial thing to do, though.
/* All code typed in mail, and completely untested, so user beware... */
This particular implementation would require that you add an instance
variable and its setter method to your subclass in order to do hit
testing properly when dealing with mouse clicks to trigger the
dragging of the divider bar(s), but you might be able to come up with
a slightly different way that works better within your implementation.
@interface YourSplitView : NSSplitView
{
...
NSArray *cachedFrames;
}
...
- (void)setCachedFrames:(NSArray *)frames;
@end
Your dividerThickness method would return the "virtual thickness" of
your divider (and also, an odd number for the thickness might be more
appropriate for a one pixel divider so that the draggable area can be
centered on the visible onscreen divider). For example:
- (float)dividerThickness {return 5.0;}
You would need to override the adjustSubViews method to do something like this:
- (void)adjustSubviews
{
[super adjustSubviews];
unsigned i;
NSArray *panes = [self subviews];
NSMutableArray *frameRects = [NSMutableArray array];
/* cache the current frames of the subviews for use later for
hit testing (see hitTest:) */
for (i=0; i<[panes count]; i++)
{
[frameRects addObject:[NSValue valueWithRect:[[panes
objectAtIndex:i] frame]]];
}
[self setCachedFrames:frameRects];
/* iterate through subviews, determine their locations relative to
each other and update all of their frames so that there is one pixel
space between each view by adding half of the extra pixels in that
dimension to each view. Fairly easy for two views, more fun for 3 or
more (which you will want to support to make your class as reusable
as possible). You'll need to write the code to do this, which
shouldn't be too difficult, it just takes a bit of time and is a pain
to do in an email without automatic indentation :) There are several
things to watch out for: calculating the origins of the new frames
correctly when the views are stacked vertically if NSSplitView is a
flipped view, dealing with subviews that might be collapsed, etc... */
}
You will also need to override the inherited NSView method hitTest:
in your SplitView to prevent clicks in the "virtual thickness"
drag-able part of your divider from being passed on to the subviews
instead of the splitview.
- (NSView *)hitTest:(NSPoint)aPoint
{
unsigned i;
/* aPoint is the coordinate system of the superview, so it must
be converted */
NSPoint testPoint = [[self superview] convertPoint:aPoint toView:self];
/* use the cached rects from the subviews before the
modifications for the hit test */
for (i=0; i<[cachedFrames count]; i++)
{
if ([self mouse:testPoint inRect:[[cachedFrames
objectAtIndex:i] rectValue]])
{
return [super hitTest:aPoint];
}
}
return self;
}
Depending on how you are using your NSSplitView subclass, be aware
that you might have interface issues when a user is trying to click
on something in one of the subviews but catches the padding for the
divider bar instead (for example, starting to select a line of text
and clicking at the very edge of the subview might grab and drag the
divider bar instead of creating the intended selection in the
subview). Of course, they also have to be able to move the divider,
and one pixel is definitely a bit tight, so I agree that you probably
need a bit of padding.
I would recommend that once you get it working, play around with it
a bit and see how small you can make the padding and still grab the
divider easily enough. I would try to go as small as 3 pixels if
possible, but that's something you need to decide based on how you
are using the subclass and what you might use it for in the future.
Hope this helps...
Louis
Thanks for the tip, but I've already tried it ;-)
My problem is that I want the divider to appear to be only 1 pixel
thick, but have a grabbable area of 6 pixels. If I set
dividerThickness to 6, and only draw a 1px line, I get a few pixels
of pinstripe around the subviews. If I set my dividerThickness to 1,
the subviews place correctly, but Its very hard to get hold of the
divider.
cheers,
Nicholas
On Dec 17, 2003, at 5:44 PM, email@hidden wrote:
Override drawDividerInRect() and put your own drawing code in it.
You will also
need to override dividerThickness() with the size of your new divider.
Robert La Ferla
OSX Cocoa Consultant
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives:
http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.