custom list control in cocoa - cocoa

I am trying to get something like in this screenshot
(source: smokingapples.com)
in cocoa, I mean a custom list control. Do you know how this kind of things can be done?
Thanks in advance for your help,
Regards,

Update:
NSTableView now supports view-based rows with variable heights:
- (NSTableViewRowSizeStyle)rowSizeStyle
Return Value
The row style style. See NSTableViewRowSizeStyle for the supported options.
Discussion
The row size style can be modified on a row by row basis by invoking the delegate method tableView:heightOfRow:, if implemented.
The rowSizeStyle defaults to NSTableViewRowSizeStyleCustom. NSTableViewRowSizeStyleCustom indicates to use the rowHeight of the table, instead of the pre-determined system values.
Generally, rowSizeStyle should always be NSTableViewRowSizeStyleCustom except for "source lists". To implement variable row heights, set the value to NSTableViewRowSizeStyleCustom and implement tableView:heightOfRow: in the delegate.
Availability
Available in OS X v10.7 and later.
Original Answer:
An approach, that's more modern than view hacking NSTableView would be either one of these:
http://github.com/sdegutis/SDListView
SDListView - Clone of NSCollectionView, but with
variable-height items and only using a
single column.
http://github.com/uliwitness/PXListView
PXListView - An optimized list view control for Mac
OS X 10.5 and greater. It was created
after I wrote this post on the
subject.
PXListView is licensed under the New
BSD license.
PXListView uses similar optimizations
as UITableView for the iPhone, by
enqueuing and dequeuing NSViews which
are used to display rows, in order to
keep a low memory footprint when there
are a large number of rows in the
list, yet still allowing each row to
be represented by an NSView, which is
easier than dealing with cells.
The architecture of the control is
based on the list view controls which
are present in both Tweetie (Mac) and
Echofon (Mac).
The project is still very much a work
in progress, and as such no
documentation exists at current.
[Edit: it case it wasn't obvious: the class descriptions seen above are quotations of course ;) Where "I" in the latter one actually refers to "Alex Rozanski", not me.]

This is a simple NSTableView with a redrawn table cell which consists of NSImageView and a fiew customized NSTextFields.

Related

Is there a concept of viewcontroller containment in NSViewController

In iOS, you have a concept of View Containment, is there such things in OSX?
Basically I want to create multiple nsviewcontroller each managing a specific view. I'd have a MasterViewController with a menu on the left (like ITunes), each time the user click on an item on the left, it would load the correct nsviewcontroller to display it's view.
Any tips to achieve what I need is appreciated
Thanks,
As of OSX 10.10 there is, watch Storyboards and Controllers on OS X.
Comment.
NSViewController did basically nothing (other that load NIBs) for years, I'm glad to see that it finally got from attention. Certain people in the Cocoa crowd here have a snotty attitude about the view controller programming style; I've asked questions like this before and had the "are you a iOS newbie coming to Cocoa" response. That's something that I never understood, it's a great model for containment, and reuse.
The main difference between OS X and iOS is that on an iOS device you have only one "window". On OS X there are desktops that can contain many windows that you can view and interact with at the same time.
In general, it sounds like you are trying to create an NSWindow that contains a single-column NSTableView for your list of choices on the left, and some other view that will display the detail of the selection on the right. It's common to place these within a vertical NSSplitView so the user can adjust their relative widths, but they could also stand on their own, as two separate subviews within the window's main view.
You typically use an NSArrayController to manage the list contents and track which particular item is selected. For your detail view on the right, you would use a single NSView with NSControl subviews that display values bound to the array controller's selected object.
If the data structure varies among your objects, swap in or show/hide various subviews as needed for the different types of data the particular selected object represents. You can use the "Conditionally Sets Hidden" binding option to automatically hide controls for which there is no applicable keyed value.
Alternatively, if there's a fixed number of objects in your list and their structures are all quite different from one another, then you may wish to use a tabless NSTabView that has a separate tab with its own custom view for each of your objects. Observe when the selection changes in your list, and select the appropriate tab accordingly.

NSButtonCell vs NSButton

I've been reading through the Apple documentation about NSButtons and cells and I really can't seem to understand the distinction between the two. Adding to this complexity, it looks like both of them have a large overlap of methods like setTitle: etc. and I'm not sure which ones I should use.
Can anyone explain what the basic differences are?
Thanks,
Teja
You can think of a control as a cell's representative, or "agent".1 The control is an NSView, which means two important things in these circumstances. First, that it represents an area of a window to be drawn in. Second, that it accepts user interaction.2
The control doesn't do very much itself, though. The cell is the thing that does all the work -- notice, for example, that cells can draw themselves into a given frame. This is the responsibility of a view, but the control defers that to the cell, simply providing an area for drawing.
Likewise, when a user clicks on a control, the control receives the event and figures out what it means, but the work of performing an action in response to the event is passed on to the cell.
If you look at the docs for various control/cell pairs (NSButton and NSButtonCell being one such pair), you will see mention of "cover" methods. This means that the control has methods with the same names as its counterpart cell, which simply call through to the cell's. That's the source of the duplication that you mentioned. When you want to use one of these methods, call it on the control -- as the public face of the pair, it will most likely simply ask the cell anyways.
The best Apple-provided description of the interaction is "How Controls and Cells Interact" in the Control and Cell Programming Topics guide.
1In the sense of a actor having an agent who procures gigs.
2This is not strictly true of all views; it's actually a feature of NSResponder from which NSView inherits.
Excerpted from Cocoa Programming for OS X: The Big Nerd Ranch Guide
“A cell handles the implementation details of the control. For the
most part, the cell’s properties and methods are “covered” by
identical properties and methods in the corresponding control. For
instance, when you change the title on a label, the label’s cell is
doing the work, but you interact with the label’s stringValue
property.
Cells have a long history in Cocoa. They were originally
added to address performance issues: many of the basic tasks of a
control were handed off to the cell, which could do them more
efficiently than the control.
Mac computers are much more powerful
than they were in those days, and cells have become an encumbrance.
Apple has stated that it is in the process of deprecating cells, but
you will still see them in your document outline and in older code.”
NSButtonCell is a subclass of NSActionCell used to implement the user interfaces of push buttons, switches, and radio buttons. It can also be used for any other region of a view that's designed to send a message to a target when clicked.
The NSButton subclass of NSControl uses a single NSButtonCell. To create groups of switches or radio buttons, use an NSMatrix holding a set of NSButtonCells.
NSButton Cell has alot more cutomizable options for drawing and behaviour. The differences are better seen in the classes they inherit from (NSButtonCell inherits from the ActionCell class, while the NSButton inherits from the NSControl class.
Take a look at the documentation better:
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSButton_Class/Reference/Reference.html
http://developer.apple.com/library/mac/#documentation/Cocoa/Reference/ApplicationKit/Classes/NSButtonCell_Class/Reference/Reference.html
You should choose based on how you want the buttons to be drawn and behave. If its a simple button you want, use NSButton.

Horizontal NSTableView (i.e. entity data per column vs. standard entity data per row)

I am trying to create a Mac OS X Cocoa based application with data displayed in a tabular format, but the data needs be displayed vertically in one column per entity instead of the standard NSTableView one row per entity functionality.
Is there an appropriate Cocoa class for this? Essentially I'm looking for a "horizontal" table of NSControls, but I do not need headers, sorting, etc. I just need a view to bind my core data array of entities to that displays the data in various NSCells depending on the field. (i.e. instead of one column of checkboxes and another column of textfields, I need one row of checkboxes and another row of textfields, etc.)
Thanks!
There is no pre-baked Cocoa control that handles this exactly like a table, just in "vertical" mode.
You might try NSCollectionView set to one row and unlimited columns. Create your NSCollectionViewItem (as the "prototype" or template) in a vertical configuration and you should be good to go for the most basic needs and even throws in some pretty animation.
The problem is, it's only available starting at 10.5 and is a lot less useful unless you're targeting 10.6 as a minimum. Even then NSCollectionView/Item can quickly become too unwieldy if your needs go beyond the basics it provides. At that point, creating your own home-brewed equivalent that targets what you need might be easier.

How do I implement a customized list in Cocoa?

I want to build a Cocoa App with a list of entries very similar to the ToDo list of Things.app (see the screencast). The question is whether I should use
a TableView,
a CollectionView or
a WebView.
I think it could work with all of them, but which one suits the following requirements best?
have a list of entries -> 1 column & many rows
reordering with drag & drop
select single entries & use keys for actions like delete
open up an entry: the row should expand to show more input fields
customized look: rounded corners, shadow, background gradient
So far my research says that the TableView has most of the functionality, but is harder to customize in its appearance, the CollectionView doesn't have drag & drop (right?) but is easy to design and the WebView would take much effort to not hurt the user experience and I can't bind my model directly to input fields.
What pros and cons am I missing and what would you recommend to use?
A WebView doesn't make sense. You might as well create a web application if you use a WebView. An NSCollectionView is more for grid like data, like TV listings per hour.
NSTableView is the only one that makes sense in this case. I've implemented all 5 bullet points with with an NSTableView without issue. You need to extend NSTableView and do some custom drawing for the customized look. That's the hardest part.
open up an entry: the row should expand to show more input fields
You need an outline view. A table view is for flat lists.
Note that NSOutlineView is a subclass of NSTableView, so all the table-view features work on an outline view as well.
There are people who've done this already. One that I've used successfully is by Matteo Bertozzi and is available here: http://th30z.netsons.org/2009/03/cocoa-sidebar-with-badges-take-2/ It might take a bit of massaging to get it to work properly (especially if you need complex drag-and-drop behavior), but for basic functionality, such as getting the section titles and items in the list, it works excellently.
Edit: This has come up before and is a common question on the cocoa-dev email list. Here are some other options.
Just took a look at Things.app itself using "F-script anywhere".
They've used a subclass of NSTableView called "DetailTableView" which presents the condensed todo items. Collapsed todo items are implemented using a custom cell called "ToDoCell", but the expanded look you get when editing is interesting. In that case they've got a custom view called "ToDoEditView" which is inserted as a subview of the DetailTableView when required. I suspect this editing view is temporarily added as a subview in the correct location and the corresponding row of the tableview gets resized temporarily while it is present.
All pretty speculative .. I'd love to know the details of how this was done. It's an awesome UI.
I'm approaching the very same problem in my app (with one big list similar to the Things todo list) and I think a table view would make a lot of sense here.
The trick is having your cells ("rows") expand when double-clicked. That's about all the progress I've made so far.

How would one implement a sidebar similar to Mail/iTunes/Finder/etc in Cocoa/IB?

I think the title pretty much says it all... I'm looking to implement an interface similar to the standard OS X sidebar used in all the above mentioned programs, and I'm wondering if anybody has any thoughts as to the easiest way to do it, namely about what view to use for the left hand selection pane. Really I don't think I even need the hierarchical component as seen in the apple apps, I just need a good looking flat list of choices which determine what's shown in the right hand pane.
The obvious start is a vertical split layout view, but beyond that I'm not entirely sure where to go. A collection view with only one column or something like that?
I've done a few applications that use a similar setup.
I generally use an NSSplitView, with a single column NSTableView in the left pane. Don't forget to disable the headers, and make it display as a "Source View" style.
If you want the disclosure triangles, then you'll want to use NSOutlineView instead of NSTableView, but at least for the first go, I'd stick to a simple NSTableView.
A pattern I also use is to make the NSTableView slightly shorter than the NSSplitView, and have buttons at the bottom (add, delete, etc). I've usually built the program around Core Data, so it's easy to hook up these to methods to create/delete objects, and then bind the NSTableView to the array of objects.
Direct support for this sort of thing was added in Leopard. It's called a 'source list'.
Please see the AppKit release notes. Search for NSTableViewSelectionHighlightStyleSourceList in the document.
Or, drag out a table view and select Highlight: Source List in Interface Builder.

Resources