Thursday, February 25, 2010

TimeLine view - header

I have been working on the timeline header view. In Cello this is called the FrameView as it contains details of fime frames. I have just got the selection working. The selection normally shows a single frame - the current frame, but it is possible to select a contiguous strip of frames as well.

Before starting work on the selection I once again had a look at CocoaTron NSTableView to see how the mouse down - and shift selection was handled. The code was less liftable - but studying someone else's code is always useful.

Selection of a Single Frame

Selection of Multiple Frames

Friday, February 19, 2010

Drag resizable columns in a headerless NSTableView

Currently table headers are responsible for handling the dynamic resizing of table columns. I have needed to make it possible to resize table columns from within the table - so the idea is that you will be able to:
  • move your mouse to the divider between two columns
  • the cursor will change to indicate that you can resize the column
  • click and drag and your column will resize.
I already have a NSTableView sublclass that has modest, general, enrichments for the very few enhancements I need to NSTableView - so my aim is to enhance this a little.

As a start point I looked at the CocoaTron code for the NSTableHeader. My thought was the CocoaTron NSTableHeader will be much like the cocoa table header, it handles resizing so will in the least be a reasonable template for implementing my own table. As it happens I was able to more-or-less copy/paste the code for the following key methods into my NSTableView.

-(void)resetCursorRects;
-(void)resizeWithOldSuperviewSize:(NSSize)size;
-(void)mouseDown:(NSEvent *)theEvent;

Of course there is a little more to it than this - but it is small beer and this small piece of CocoaTron proved an excellent starting - and indeed took me most of the way.

Wednesday, February 17, 2010

Synchronizing the selection in two NSTableViews

I have been looking at a problem of synchronizing the selection across two NSTableViews. It took a few attempts to come to a solution that worked as I wanted it to. The idea is to have two table views with the same number of elements - as soon as you make a selection in one the other one updates to show the same items selected.

My first port of call was to hook into the tableViewSelectionDidChange notification. Then when one selection changes you just change the other. This works - but there is a lag. Click in one table the selection changes, the window updates and then the second selection changes.

The solution was to override selectRowIndexes and to use that to trigger the selection in the paired table. This works fine and produces the required results. I was able to 'hack' this in as a proof of concept fairly quickley.

Implementing it 'properly' or rather 'as I wanted it' I dod not want my two tables to carry references to each other - insead I wanted to have this in the controller class. I did this my adding a new protocol to my subclass of the table:

- (void)selectedRowIndexes:(NSIndexSet *)indexes forTableView:(NSTableView *)tableView byExtendingSelection:(BOOL)extend;

Then, by implementing this protocol, I can add the synchronization logic to the controller which is where I want it.

Monday, February 15, 2010

Interface Builder

Working with an application framework has a few parts - there is the first staggering steps of familiarity and the kind of awkwardness you have because of the difference between what you knew before and what you are looking at. Then there is the familiarity when you know more-or-less how to do what you did before and then there is that time a while later when you sort of "get it". This part is the most exciting part as that is when you can work with the flow and get the benefits of the good current.

I think have had something of a slow burn Eureka moment with interface builder. It goes like this - any class member that is declared with the magic IBOutlet in front of it can be connected up in interface builder. It is difficult to kick off in Cocoa (I started with Aaron Hillegass' book) without seeing that this is the way you connect up views and controllers - but you can connect up other things as well. If you have a table and you need to deal with the columns you can do it in two ways. You can give each column an Identifier and loop through the columns until you find the column that you want - or you can pick out the columns you want, add them to your controller with a IBOutlet - and hook them up in Interface builder. The anything part of this is quite powerful - if you need to set attributes on the NSCell derivative that powers the drawing of your column - you can hook this up as well - and so it goes on.

Thursday, February 4, 2010

BWToolKit

I have downloaded and built BWToolKit by Brandon Walkin. This is a framework that extends the existing components that are available in Inerface Builder. It is of particular interest to me at the moment as it contains an improved splitter. The BWSplitView is a subclass of the NSSplitView that handles improvements like the splitter collapsing, max min sizes etc. BWToolKit comes with interface builder plugin so you can drag out Brandon Walkin's carefully crafted goodies just as if they were a piece of appkit. BWToolKit is available under the New-BSD licence. I downloaded the code and built it myself as I feel insecure if I don't have the source code.