Re: How to add a menu to a listView
Posted: Sun Nov 06, 2016 10:01 pm
This new example code needs at least MacOS 10.7 (Lion). I tested it successfully on MacOS 10.8.6 (Mountain Lion) and 10.12.1 (Sierra) with PB 5.43 x86 and x64 in both ASCII and Unicode mode.
Since PureBasic is still using NSCells (deprecated cell-based approach, NSCells are not based on NSView, alot less flexible and therefore much harder to modify) to display the cell contents and according to Apple the cell-based and view-based approach may not be mixed, I had to use the delegate method tableView:viewForTableColumn:row: (introduced in Lion) and return a newly allocated view (NSComboBox for a column with a ComboBox or NSTextField for a normal column) for each cell that has to be displayed:
Since PureBasic is still using NSCells (deprecated cell-based approach, NSCells are not based on NSView, alot less flexible and therefore much harder to modify) to display the cell contents and according to Apple the cell-based and view-based approach may not be mixed, I had to use the delegate method tableView:viewForTableColumn:row: (introduced in Lion) and return a newly allocated view (NSComboBox for a column with a ComboBox or NSTextField for a normal column) for each cell that has to be displayed:
Code: Select all
EnableExplicit
; ----- Only necessary when compiling with PB x64 on MacOS 10.12 "Sierra"
; Import "-stdlib=libc++ -mmacosx-version-min=10.7" : EndImport
If OSVersion() < #PB_OS_MacOSX_10_7
MessageRequester("Compilation terminated",
"Sorry, but you need at least MacOS 10.7 (Lion) to compile this code!")
End
EndIf
#ListIcon = 0
Define AppDelegate.I = CocoaMessage(0, CocoaMessage(0, 0,
"NSApplication sharedApplication"), "delegate")
Define DelegateClass.I = CocoaMessage(0, AppDelegate, "class")
Define RowHeight.CGFloat = 25
Define Selector.I = sel_registerName_("tableView:viewForTableColumn:row:")
ProcedureC GetViewForCellCallback(Object.I, Selector.I, TableView.I,
ColumnObject.I, Row.I)
Protected CellContent.S
Protected Column.I
Protected ColumnID.S = PeekS(CocoaMessage(0, CocoaMessage(0,
ColumnObject, "identifier"), "UTF8String"), -1, #PB_UTF8)
Protected ComboBox.I
Protected TextFrame.NSRect
Protected View.I
Column = Val(ColumnID)
If Column = 1
; ----- If column = 1, create ComboBox and return it
ComboBox = CocoaMessage(0, 0, "NSComboBox new")
CocoaMessage(0, ComboBox, "addItemWithObjectValue:$",
@"12 Parliament Way, Battle Street, By the Bay")
CocoaMessage(0, ComboBox, "addItemWithObjectValue:$",
@"130 PureBasic Road, BigTown, CodeCity")
CocoaMessage(0, ComboBox, "addItemWithObjectValue:$",
@"321 Logo Drive, Mouse House, Downtown")
View = ComboBox
Else
; ----- If Column <> 1, read current cell content, create new view with
; NSTextField, write current content into that view and return it
CellContent = GetGadgetItemText(#ListIcon, Row, Column)
TextFrame\size\width = GetGadgetItemAttribute(#ListIcon,
#PB_ListIcon_ColumnWidth, Column)
TextFrame\size\height = 18
View = CocoaMessage(0, CocoaMessage(0, 0, "NSTextField new"),
"initWithFrame:@", TextFrame)
CocoaMessage(0, View, "setStringValue:$", @CellContent)
EndIf
ProcedureReturn View
EndProcedure
OpenWindow(0, 200, 100, 430, 126, "ListIconGadget with ComboBox")
ListIconGadget(0, 10, 10, WindowWidth(0) - 20, WindowHeight(0) - 20,
"Name", 110)
AddGadgetColumn(0, 1, "Address", GadgetWidth(0) - GetGadgetItemAttribute(0,
0, #PB_ListIcon_ColumnWidth) - 8)
AddGadgetItem(0, -1, "Harry Rannit")
AddGadgetItem(0, -1, "Ginger Brokeit")
AddGadgetItem(0, -1, "Didi Foundit")
; ----- Increase row height to be able to display larger ComboBox
CocoaMessage(0, GadgetID(0), "setRowHeight:@", @RowHeight)
; ----- Initialize callback that returns a new NSView (view-based) instead
; of the old NSCell (cell-based) for each cell drawn
class_addMethod_(DelegateClass, Selector, @GetViewForCellCallback(), "v@:@@@")
CocoaMessage(0, GadgetID(0), "setDelegate:", AppDelegate)
Repeat
Until WaitWindowEvent() = #PB_Event_CloseWindow