Sunday, November 27, 2022

#1 2019-11-02 02:07:00 pm

From:: Greece
Registered: 2019-03-03
Posts: 2583

Improved Choose From List Dialog

Using the Choose From List command of Standard Additions, I came across 2 significant flaws. 1) The first is the impossibility of obtaining the index of an element selected by the user (NOTE: list contains duplicates too). And I want to continue the process, starting with the selected list item and further, without returning to the already processed ones. 2) The second problem concerns the impossibility of customizing and adding buttons.

I asked for help in post Get index of element, chozen in choose from list dialog and got a positive solution from Shane Stanley - to use his "Myriad Tables Lib". It solves the above problems fine, so I was interested in how Shane does it. Unfortunately, this script library is run-only, so I was not able to look into the "little secrets" of this library. Fortunately, I found another script that was written by a Japanese Takaaki Naganoya (Macscripter user maro). I edited it a bit and provide it here. The script does not use third-party software, although it may be slightly slower than the library from Shane Stanley. So, the script:


use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"

property |⌘| : a reference to current application
property aList : {3, "None", "Apple", 3, 4, "Chick", "Gyouza", "Snagi also", "Apple", "Peaches"}
property aSubMessage : "Please select the appropriate one from the following"
property theAlert : missing value
property theResult : 0
property returnCode : 0
property theDataSource : {}

my performSelectorOnMainThread:"createAlert" withObject:(missing value) waitUntilDone:true
my performSelectorOnMainThread:"displayAlert" withObject:(missing value) waitUntilDone:true
if theResult = (|⌘|'s NSAlertSecondButtonReturn) then error number -128
set aResult to my chooseItemByTableView()

on createAlert()
   set my theAlert to |⌘|'s NSAlert's alloc()'s init()
   my performSelectorOnMainThread:"displayAlert:" withObject:theAlert waitUntilDone:true
end createAlert

on chooseItemByTableView()
   -- define the matrix size where you’ll put the radio buttons
   set aScrollWithTable to makeTableView(300, 150) of me
   -- set up alert
   tell theAlert
       its setMessageText:aMainMessage
       its setInformativeText:aSubMessage
       its addButtonWithTitle:"OK"
       its addButtonWithTitle:"Cancel"
       its setAccessoryView:aScrollWithTable
   end tell
   -- show alert in modal loop
   |⌘|'s NSRunningApplication's currentApplication()'s activateWithOptions:0
   my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
   if (my returnCode as number) = 1001 then error number -128
   return (aScrollWithTable's documentView's selectedRow()) + 1
end chooseItemByTableView

on doModal:aParam
   set (my returnCode) to aParam's runModal()
end doModal:

on makeTableView(aWidth as number, aHeight as number)
   set aOffset to 40
   set sourceList to {}
   repeat with i in aList
       set the end of sourceList to {dataItem:(contents of i)}
   end repeat
   set theDataSource to |⌘|'s NSMutableArray's alloc()'s init()
   theDataSource's addObjectsFromArray:sourceList
   set aScroll to |⌘|'s NSScrollView's alloc()'s initWithFrame:(|⌘|'s NSMakeRect(0, aOffset, aWidth, aHeight))
   set aView to |⌘|'s NSTableView's alloc()'s initWithFrame:(|⌘|'s NSMakeRect(0, aOffset, aWidth, aHeight))
   set aColumn to (|⌘|'s NSTableColumn's alloc()'s initWithIdentifier:"dataItem")
   (aColumn's setWidth:aWidth)
   (aColumn's headerCell()'s setStringValue:"dataItem")
   (aView's addTableColumn:aColumn)
   aView's setDelegate:me
   aView's setDataSource:me
   aView's reloadData()
   aScroll's setDocumentView:aView
   aView's enclosingScrollView()'s setHasVerticalScroller:true
   -- Select line
   set aIndexSet to |⌘|'s NSIndexSet's indexSetWithIndex:0
   aView's selectRowIndexes:aIndexSet byExtendingSelection:false
   -- Force scroll to top
   -- set maxHeight to aScroll’s documentView()’s |bounds|()’s |size|()’s height
   set aDBounds to aScroll's documentView()'s |bounds|()
   if class of aDBounds = list then
       -- macOS 10.13 or later
       set maxHeight to item 2 of item 1 of aDBounds
       -- macOS 10.10….10.12
       set maxHeight to height of |size| of aDBounds
   end if
   set aPoint to |⌘|'s NSMakePoint(0.0, -40.0)
   aScroll's documentView()'s scrollPoint:aPoint
   return aScroll
end makeTableView

-- TableView Event Handlers
on numberOfRowsInTableView:aView
   return my theDataSource's |count|()
end numberOfRowsInTableView:

on tableView:aView objectValueForTableColumn:aColumn row:aRow
   set aRecord to (my theDataSource)'s objectAtIndex:(aRow as number)
   set aTitle to (aColumn's headerCell()'s title()) as string
   set aResult to (aRecord's valueForKey:aTitle)
   return aResult
end tableView:objectValueForTableColumn:row:

Last edited by KniazidisR (2019-11-02 02:26:21 pm)

Model: MacBook Pro
OS X: Catalina 10.15.7
Web Browser: Safari 15.6.1
Ram: 4 GB



Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)