« June 2005 | Main | August 2005 »

July 28, 2005

Drag and Drop in an NSTableView

Drag and Drop in an NSTableView is easy to do. However, I think the documentation (Table Views: Using Drag and Drop in Tables) for it isn't particularly great. It misses a few points, so I'm going to go over the basic steps on how to add drag and drop to your TableView. Here, I'll assume you have a TableView with your source code controller class set as the delegate.

Declare your custom pasteboard format:

#define BasicTableViewDragAndDropDataType @"BasicTableViewDragAndDropDataType"

In awakeFromNib you must register for the drag types you want to receive (you could have others here):

- (void)awakeFromNib {

    [myTableView registerForDraggedTypes:[NSArray arrayWithObjects:BasicTableViewDragAndDropDataType, nil]];

}

Then, you must implement writeRowsWithIndexes to add your data to the pasteboard:

- (BOOL)tableView:(NSTableView *)tv writeRowsWithIndexes:(NSIndexSet *)rowIndexes toPasteboard:(NSPasteboard*)pboard {

    // Drag and drop support

    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:rowIndexes];

    [pboard declareTypes:[NSArray arrayWithObject:BasicTableViewDragAndDropDataType] owner:self];

    [pboard setData:data forType:BasicTableViewDragAndDropDataType];

    return YES;

}

Next you will validate the drop:

- (NSDragOperation)tableView:(NSTableView*)tv validateDrop:(id <NSDraggingInfo>)info proposedRow:(int)row proposedDropOperation:(NSTableViewDropOperation)op {

    // Add code here to validate the drop

    NSLog(@"validate Drop");

    return NSDragOperationEvery;    

}

Finally, you must have a method that accepts the drop. Here you could access the BasicTableViewDragAndDropDataType and look at the rows that were dragged.

- (BOOL)tableView:(NSTableView*)tv acceptDrop:(id <NSDraggingInfo>)info row:(int)row dropOperation:(NSTableViewDropOperation)op {

    NSLog(@"acceptDrop");

    // Add code here to accept the drop

    return YES;    

}

And that is it! It is pretty easy...

Technorati Tags:

Posted by corbin at 06:44 PM | Comments (1) | TrackBack

July 26, 2005

Dynamically populating an NSPopUpButtonCell in an NSTableView

It is quite common. You have a PopUpButton (NSPopUpButtonCell) in an NSTableView and you want to dynamically change the contents based on the selected row:

Popupcellpicture1

How do you do this? There are a few tricky steps. First, add a menu to the nib and set the delegate for the menu to be your Controller:

Menusdelegatepopupbutton

Okay. Next is the tricky part. In IB, when you have a column in a tableview selected, it has a little white triangle in the corner:

Picture 1-3

Clicking on that will allow you to modify properties of the cell (in this case, the NSPopUpButtonCell). However, we want to set the menu for the NSPopUpButtonCell, so drag from that little triangle to your menu and set the menu outlet:

Popupcellhookup

Okay, good! Now, all your controller needs is a little bit of code to dynamically populate the menu:

- (void)menuNeedsUpdate:(NSMenu *)menu {

    // remove all previous items

    while ([menu numberOfItems] > 0) {

        [menu removeItemAtIndex:0];

    }

    // dynamically build the menu

    int i;

    int selectedRow = [tableViewStuff selectedRow];

    for (i = 0; i &lt;= selectedRow; i++) {

        NSMenuItem *item = [[NSMenuItem alloc] 

            initWithTitle:[NSString stringWithFormat:@“Menu %d”, i] 

                   action:@selector(menuClicked:) keyEquivalent:@“”];

        [item setTarget:self];

        [menu addItem:item];

    }

}

Okay, that should work, right? Normally, yes. But in a tableview when a cell is tracked, it is first copied. Unfortunately, a small bug in the menu code doesn't copy the delegate. Therefore, we must fix it up in the nstableview's delegate method:

- (void)tableView:(NSTableView *)tableView 

  willDisplayCell:(id)cell 

   forTableColumn:(NSTableColumn *)tableColumn 

              row:(int)row 

{

    if ([cell isKindOfClass:[NSPopUpButtonCell class]]) {

        [[cell menu] setDelegate:self];

    }

}

That's it! Have fun...happy coding.

Posted by corbin at 04:14 PM | Comments (0)

July 19, 2005

Delphi easter eggs

I can't believe people found out about the Kitchen sink!

http://www.blong.com/Undocumented/Delphi2005.htm

I did write that silly easter egg.

Posted by corbin at 04:36 PM | Comments (0)

Discovery HD -- Weird Homes

Hi All,
Someone just emailed me saying they saw the episode of “Weird Homes” with me in it. It appears to be airing right now! Discovery HD Theater channel. here's info:

http://dhd.discovery.com/schedule/episode.jsp?episode=26&cpi=82216&gid=0

Cool, huh! I'm the “busy builder who swings through the trees”.

Posted by corbin at 02:58 PM | Comments (1)

July 08, 2005

Adding a popup menu to any NSButton

It is easy to add a popup to any button (NSButton).
Picture 1-2

Here are the steps:

  1. In your nib, drop down an NSPopupButton and add the items you want to its popup list.
  2. Set the NSPopupButton to be hidden.
  3. Add an outlet for the NSPopupButton (named popupButton in this case)
  4. Drop down an NSButton.
  5. Set the image (or whatever else you want) for the button
  6. In the action for the button, run the following code:
    [[popupButton cell] performClickWithFrame:[sender frame] inView:[sender superview]];    

That is it!

Posted by corbin at 04:07 PM | Comments (8)

Santa Cruz Guerilla Drive-In

Tonight, I'm going to go see a movie. But, it's going to be free!

The Santa Cruz Guerilla Drive-In is really cool. Tonight the Delicatessen is playing. This will be my first time going. You should go too!


Delecatessen

Posted by corbin at 09:20 AM | Comments (0)

July 05, 2005

Wood iPod

I just thought this was sooo cool!:

Flickr: ZapWizard's photos tagged with woodipod

 23324213 95626Afea8

Posted by corbin at 08:33 AM | Comments (0)