• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: Fwd: NSSplitView hacking
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

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.

References: 
 >Fwd: NSSplitView hacking (From: Nicholas Francis <email@hidden>)

  • Prev by Date: Re: why do this not work??
  • Next by Date: Change style of an Alert Panel!
  • Previous by thread: Fwd: NSSplitView hacking
  • Next by thread: Re: NSSplitView hacking
  • Index(es):
    • Date
    • Thread