Cocoa: How to feed an OutlineView Programatically

Mac OSX specific forum
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Cocoa: How to feed an OutlineView Programatically

Post by fsw »

Tried to create an OutlineView with ObjC which worked, but filling the NSColumn with rows of data is a disaster.
All examples I found use either a NIB file or a Storyboard and with this, some stuff seems to be achieved automatically.
(like setting a datasource or a delegate is allowed but doing the same programmatically raises an error)

The Cocoa API gets more convoluted with every iteration and programmers not using Xcode for the UI are screwed...
Any hint are appreciated.
Thanks.

I am to provide the public with beneficial shocks.
Alfred Hitshock
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Cocoa: How to feed an OutlineView Programatically

Post by wilbert »

As far as I know you have to create your own class which implements the NSOutlineViewDataSource protocol and set an instance of that class as the dataSource .
Maybe this post will give you some idea. It's a table view so not an outline view but in both cases you need to create your own data source. Only the methods you need to implement are different.
http://www.purebasic.fr/english/viewtop ... 75#p484975
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Cocoa: How to feed an OutlineView Programatically

Post by fsw »

Wow Wilbert, this was fast.
Not sure why I didn't find this example when I did a search...

Will walk through the code line by line.
Thank you.

I am to provide the public with beneficial shocks.
Alfred Hitshock
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Cocoa: How to feed an OutlineView Programatically

Post by wilbert »

I tried a bit for myself, got it at least to do something.

Code: Select all

Global RootNode = CocoaMessage(0, 0, "NSTreeNode treeNodeWithRepresentedObject:$", @"Root node")
CocoaMessage(0, RootNode, "retain")

ChildNode1 = CocoaMessage(0, 0, "NSTreeNode treeNodeWithRepresentedObject:$", @"Child node 1")
ChildNode2 = CocoaMessage(0, 0, "NSTreeNode treeNodeWithRepresentedObject:$", @"Child node 2")
ChildNode1_1 = CocoaMessage(0, 0, "NSTreeNode treeNodeWithRepresentedObject:$", @"Child node 1.1")
ChildNode1_2 = CocoaMessage(0, 0, "NSTreeNode treeNodeWithRepresentedObject:$", @"Child node 1.2")
ChildNode1_3 = CocoaMessage(0, 0, "NSTreeNode treeNodeWithRepresentedObject:$", @"Child node 1.3")
ChildNodes = CocoaMessage(0, RootNode, "mutableChildNodes")
CocoaMessage(0, ChildNodes, "addObject:", ChildNode1)
CocoaMessage(0, ChildNodes, "addObject:", ChildNode2)
ChildNodes = CocoaMessage(0, ChildNode1, "mutableChildNodes")
CocoaMessage(0, ChildNodes, "addObject:", ChildNode1_1)
CocoaMessage(0, ChildNodes, "addObject:", ChildNode1_2)
CocoaMessage(0, ChildNodes, "addObject:", ChildNode1_3)



; dataSource => child of item
ProcedureC.i child_ofItem(obj, sel, outlineView, index, item)
  If item = #nil : item = RootNode : EndIf
  ProcedureReturn CocoaMessage(0, CocoaMessage(0, item, "mutableChildNodes"), "objectAtIndex:", index)
EndProcedure

; dataSource => is item expandable ?
ProcedureC.i isItemExpandable(obj, sel, outlineView, item)
  If CocoaMessage(0, item, "isLeaf")
    ProcedureReturn #NO
  Else
    ProcedureReturn #YES
  EndIf
EndProcedure

; dataSource => number of children of item
ProcedureC numberOfChildrenOfItem(obj, sel, outlineView, item)
  If item = #nil : item = RootNode : EndIf
  ProcedureReturn CocoaMessage(0, CocoaMessage(0, item, "mutableChildNodes"), "count")
EndProcedure

; dataSource => object value
ProcedureC objectValueForTableColumn_byItem(obj, sel, outlineView, tableColumn, item)
  ProcedureReturn CocoaMessage(0, item, "representedObject")
EndProcedure



; create class(es)
class = objc_allocateClassPair_(objc_getClass_("NSObject"), "MyDataSourceClass", 0)
class_addMethod_(class, sel_registerName_("outlineView:child:ofItem:"), @child_ofItem(), "@@:i@")
class_addMethod_(class, sel_registerName_("outlineView:isItemExpandable:"), @isItemExpandable(), "c@:@")
class_addMethod_(class, sel_registerName_("outlineView:numberOfChildrenOfItem:"), @numberOfChildrenOfItem(), "i@:@")
class_addMethod_(class, sel_registerName_("outlineView:objectValueForTableColumn:byItem:"), @objectValueForTableColumn_byItem(), "@@:@@")
objc_registerClassPair_(class)


; test
OpenWindow(0, 0, 0, 400, 340, "NSOutlineView test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
TreeGadget(0, 10, 10, 380, 280)

DataSource = CocoaMessage(0, 0, "MyDataSourceClass new")
CocoaMessage(0, GadgetID(0), "setDataSource:", DataSource)

Repeat 
  Event = WaitWindowEvent()
Until Event  = #PB_Event_CloseWindow
A better approach might be using a NSTreeController but I don't understand how to bind it to a NSOutlineView programmatically.
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: Cocoa: How to feed an OutlineView Programatically

Post by fsw »

This is awesome stuff Wilbert.
When I see your code... it all looks so easy.

Thank you
8)

I am to provide the public with beneficial shocks.
Alfred Hitshock
Post Reply