Creating a custom hierarchical list view
Creating a custom hierarchical list view
- Subject: Creating a custom hierarchical list view
- From: Daniel Thorpe <email@hidden>
- Date: Thu, 30 Apr 2009 21:55:23 +0100
Hi everyone, I'm wondering if anyone can put me on the right path to
create the following custom view...
I'm trying to write a new view, to displaying hierarchical data which
only uses one column. To navigate though the hierarchy, double
clicking an item in the list loads that items contents into the list,
and sets the list header to the name of the item. Additionally, I want
to have a "back" button in the list header to go back up the hierarchy
(something that looks similar to the arrow used in iTunes to switch
between selected and playing artwork).
I've briefly thought about subclassing or otherwise constraining
NSOutlineView or NSBrowser, but I think that might well make things
unnecessarily complicated. So far I've thought that it'll need the
following classes:
NSView subclasses:
DTList, DTListHeader
So far, the DTList creates an NSMatrix for DTListCell cell class, and
sets this to the document view of an NSScrollView, which is added as a
subview. Additionally it'll add a DTListHeader as a subview. This is a
mixture of what NSBrowser and NSTableView have.
My DTList's initWithFrame: method looks like this at the moment...
- (id)initWithFrame:(NSRect)frame {
self = [super initWithFrame:frame];
if(self) {
// Enable subview resizing
[self setAutoresizesSubviews:YES];
// An NSMatrix is contained within an NSScrollView (the document view)
self.matrix = [[NSMatrix alloc] initWithFrame:frame cellClass:
[DTListCell class] numberOfRows:1 numberOfColumns:1];
[matrix setAllowsEmptySelection:NO];
[matrix setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
// The view contains an NSScrollView
// Leave space for the header
NSRect scrollViewFrame = frame;
scrollViewFrame.size.height -= kDTListHeaderHeight;
NSScrollView *scrollView = [[NSScrollView alloc]
initWithFrame:scrollViewFrame];
// Configure scroll view
[scrollView setHasVerticalScroller:YES];
[scrollView setHasHorizontalScroller:NO];
[scrollView setBorderType:NSNoBorder];
[scrollView setAutoresizingMask:NSViewWidthSizable |
NSViewHeightSizable];
[scrollView setDocumentView:matrix];
// Add the scroll view as a subview
[self addSubview:scrollView];
// Add a DTHeaderView
NSRect headerRect = frame;
headerRect.size.height = kDTListHeaderHeight;
headerRect.origin.y = NSMaxY(frame) - kDTListHeaderHeight;
self.header = [[DTListHeader alloc] initWithFrame:headerRect];
// Configure the header
[header setAutoresizingMask:NSViewWidthSizable];
// Add the header view as a subview
[self addSubview:header];
}
return self;
}
NSCell subclasses:
DTListHeaderCell, DTListCell
The DTListHeaderCell would actually inherit from NSActionCell as it
need to use the target/action paradigm to navigate back up the
hierarchy. DTListCell would be similar to NSBrowserCell, in that some
will be lead nodes and other branch nodes. Those that are branch nodes
need to draw a triangle (possibly a custom NSButton subclass) at their
right hand side. Leaf nodes would just draw their string title.
Anyway, I've sort of come unstuck when it comes to the delegate/
content bindings stuff. I'm not really sure how best to start when it
comes to actually providing the objects of my hierarchy.
In terms of using a delegate, I have a protocol for DTList delegate,
it can return the number of rows, but I don't really know where to
write the code to create the DTListCell objects (presumably retrieving
the titles from the delegate?). What would my drawRect: method look
like on the DTList?
And if it used an NSTreeController? Well, I've go no idea how to setup
the bindings for that!
Any thoughts are very much appreciated, thanks for reading this far!
Cheers
Dan
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please 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