We made a lot of “miniature garden” interface on the alert dialog. But NSOutlineView remains. Does somobody has an idea to use NSOutlineView on alert dialog.
If we can use NSOutlineView with alert dialog, we can select multi-leveled data easily.
–checkbox
http://piyocast.com/as/archives/8067
–path control
http://piyocast.com/as/archives/7140
–popup menu
http://piyocast.com/as/archives/8046
–date picker
http://piyocast.com/as/archives/7713
–WkWebView
http://piyocast.com/as/archives/8120
–Table View
http://piyocast.com/as/archives/7295
–NSBrowser + Map view
http://piyocast.com/as/archives/5820
My trial code is here.
-- Created 2019-02-23 by Takaaki Naganoya
-- 2019 Piyomaru Software
use AppleScript version "2.5"
use scripting additions
use framework "Foundation"
use framework "AppKit"
property NSAlert : a reference to current application's NSAlert
property NSIndexSet : a reference to current application's NSIndexSet
property NSScrollView : a reference to current application's NSScrollView
property NSTableView : a reference to current application's NSTableView
property NSTableColumn : a reference to current application's NSTableColumn
property NSMutableArray : a reference to current application's NSMutableArray
property NSTreeController : a reference to current application's NSTreeController
property NSRunningApplication : a reference to current application's NSRunningApplication
property NSSegmentedControl : a reference to current application's NSSegmentedControl
property NSAlertSecondButtonReturn : a reference to current application's NSAlertSecondButtonReturn
property NSSegmentStyleTexturedRounded : a reference to current application's NSSegmentStyleTexturedRounded
property aMaxViewWidth : 800
property theResult : 0
property rootDirectory : ""
property rootDirectoryItems : {}
property allChildItems : {}
property filtered_list : {}
property aTree : missing value --NSTreeViewController
set paramObj to {myMessage:"Choose one line", mySubMessage:"Select one line you want"}
--my chooseItemByOutlineView:paramObj--for debugging
my performSelectorOnMainThread:"chooseItemByOutlineView:" withObject:(paramObj) waitUntilDone:true
if (my theResult) = 0 then error number -128
return (my theResult)
on chooseItemByOutlineView:paramObj
set aMainMes to myMessage of paramObj
set aSubMes to mySubMessage of paramObj
set aWidth to 600
set aHeight to 400
--Make OutlineView+Scroll View
set aScroll to current application's NSScrollView's alloc()'s initWithFrame:(current application's NSMakeRect(0, 0, aWidth, aHeight))
set aView to current application's NSOutlineView's alloc()'s initWithFrame:(current application's NSMakeRect(0, 0, aWidth, aHeight))
aScroll's setDocumentView:aView
aView's setDelegate:me
aView's setIndentationPerLevel:(16 as real)
aView's setIndentationMarkerFollowsCell:true
set level1 to {"l1a", "l1b", "l1c", "l1d"}
set level2 to {"l1a/l2a", "l1a/l2c", "l1a/l2e"}
set level3 to {"l1a/l2a/l3f", "l1a/l2a/l3g", "l1a/l2e/l3a"}
set aTree to NSTreeController's alloc()'s init()
set optRec to current application's NSMutableDictionary's dictionaryWithObjects:{true, true} forKeys:{current application's NSRaisesForNotApplicableKeysBindingOption, current application's NSConditionallySetsEditableBindingOption}
--aTree's bind:"contentArray" toObject:(me) withKeyPath:"treeContents" options:(optRec) --????
set rootDirectoryItems to level1
set allChildItems to level2 & level3
aView's setDataSource:allChildItems
-- set up alert
set theAlert to NSAlert's alloc()'s init()
tell theAlert
its setMessageText:aMainMes
its setInformativeText:aSubMes
its addButtonWithTitle:"OK"
its addButtonWithTitle:"Cancel"
its setAccessoryView:aScroll
end tell
-- show alert in modal loop
NSRunningApplication's currentApplication()'s activateWithOptions:0
my performSelectorOnMainThread:"doModal:" withObject:(theAlert) waitUntilDone:true
end chooseItemByOutlineView:
on doModal:aParam
set (my returnCode) to aParam's runModal()
end doModal:
-- (id)outlineView:(NSOutlineView *)outlineView child:(NSInteger)index ofItem:(id)item
on outlineView:outlineView child:theChild ofItem:outlineItem
display dialog "1"
set childItem to ""
try
-- theChild is an index to the rootDirectoryItems list
if outlineItem is equal to missing value then
-- Note the rootDirectoryItems list is one based
set childItem to (get item (theChild + 1) of rootDirectoryItems) as string
else
-- create filtered_list containg items starting with outlineitem
set filtered_list to {}
myfilter(allChildItems, outlineItem) of me
--theChild is zero based and filtered_list is one based
set childItem to (get item (theChild + 1) of filtered_list) as string
end if
end try
(* Uncomment for debugging purposes *)
--list2text(rootDirectoryItems)
return childItem
end outlineView:child:ofItem:
-- (id)outlineView:(NSOutlineView *)outlineView objectValueForTableColumn:(NSTableColumn *)tableColumn byItem:(id)item
on outlineView:outlineView objectValueForTableColumn:tableColumn byItem:outlineItem
display dialog "2"
-- itemValue defaults to rootDirectory
set itemValue to "default"
--try
-- set itemValue to outlineItem as string
--end try
-- Note Applescript's is a required keyword
-- for the delimiting procedure to work properly
set AppleScript's text item delimiters to {"/"}
try
-- last text item
set str_outlineItem to outlineItem as string
set itemValue to (text item -1) of str_outlineItem
end try
-- revert to default state
set AppleScript's text item delimiters to ""
(* Uncomment for debugging purposes *)
--log "2 the itemvalue is " & itemValue
--display alert "2 the itemValue is " & itemValue
return itemValue
end outlineView:objectValueForTableColumn:byItem:
-- (NSInteger)outlineView:(NSOutlineView *)outlineView numberOfChildrenOfItem:(id)item
on outlineView:outlineView numberOfChildrenOfItem:outlineItem
set itemCount to 0
try
if (count of rootDirectoryItems) is greater than 0 then
if outlineItem is equal to missing value then
-- one extra spot for the rootDirectory entry
set itemCount to (count of rootDirectoryItems) + 1
else
-- create filtered_list containg items starting with outlineitem
myfilter(allChildItems, outlineItem)
-- count of filtered_list items
set itemCount to (count of filtered_list)
end if
end if
end try
return itemCount
end outlineView:numberOfChildrenOfItem:
-- (BOOL)outlineView:(NSOutlineView *)outlineView isItemExpandable:(id)item
on outlineView:outlineView isItemExpandable:outlineItem
set isExpandable to false
try
if outlineItem is missing value then
if (length of rootDirectoryItems) is greater than 1 then
set isExpandable to true
end if
else
-- create filtered_list containg items starting with outlineitem
set filtered_list to {}
myfilter(allChildItems, outlineItem)
--log filtered_list as text
if (count of filtered_list) is greater than 0 then
set isExpandable to true
end if
end if
end try
return isExpandable
end outlineView:isItemExpandable:
on outlineView:aView shouldExpandItem:outlineItem
return true
end outlineView:shouldExpandItem:
on outlineView:aView shouldCollapseItem:outlineItem
return true
end outlineView:shouldCollapseItem:
on outlineView:aView shouldSelectItem:outlineItem
return true
end outlineView:shouldSelectItem:
on outlineView:aView shouldSelectTableColumn:outlineItem
return true
end outlineView:shouldSelectTableColumn:
-- utility subroutines
-- convert a list into a string for display purposes *)
on list2text(theList)
if theList is missing value then
set var1 to "The list is empty"
else
set var1 to ""
-- count of the list items
repeat with i from 1 to length of theList
set var to item i of theList
-- save var1
set var2 to var1
set var1 to var2 & "[" & var & "]"
end repeat
end if
--display alert var1 message "The list is shown above"
end list2text
-- Filter the srcList to retain items that are children of thisItem
-- write results to filtered_list
on myfilter(srcList, thisItem)
set filtered_list to {}
repeat with i from 1 to (count of srcList)
set itemx to item i of srcList
-- derive theParent of thisItem
if itemx contains "/" then
-- Note Applescript's is a required keyword
-- for the delimiting procedure to work properly
set AppleScript's text item delimiters to {"/"}
-- text 1 thru second last text item
set theParent to text 1 thru (text item -2) of itemx
set AppleScript's text item delimiters to ""
end if
--log "itemx = " & itemx & " theParent = " & theParent & " thisItem = " & thisItem
if thisItem is not "" then
-- what does this do
if (theParent ends with thisItem) then
set end of filtered_list to itemx
end if
end if
end repeat
end myfilter
(*
---https://www.macscripter.net/viewtopic.php?id=47017
on tableViewSelectionDidChange:aNotification
set tableView to aNotification's object
set selectedRowIdx to (tableView's selectedRow) as integer
set rowData to arrayController's arrangedObjects's objectAtIndex:selectedRowIdx
set theNibName to (rowData's nibName) as text
if theNibName is not "" then
set viewController to current application's class "MyViewController"'s alloc's initWithNibName:(rowData's nibName) bundle:(current application's NSBundle's mainBundle)
viewController's loadView()
set theView to viewController's view
set theView's translatesAutoresizingMaskIntoConstraints to false
set detailSubviews to (detailView's subviews) as list
if detailSubviews is not {} then
set oldLabel to item 1 of detailSubviews
detailView's replaceSubview:oldLabel |with|:theView
else
detailView's addSubview:theView
end if
(* set view constraints *)
set constraintLeading to theView's leadingAnchor's constraintEqualToAnchor:(detailView's leadingAnchor)
set constraintTop to theView's topAnchor's constraintEqualToAnchor:(detailView's topAnchor)
set constraintBottom to theView's bottomAnchor's constraintEqualToAnchor:(detailView's bottomAnchor)
set constraintTrailing to theView's trailingAnchor's constraintEqualToAnchor:(detailView's trailingAnchor)
constraintLeading's setActive:true
constraintTop's setActive:true
constraintBottom's setActive:true
constraintTrailing's setActive:true
end if
end tableViewSelectionDidChange:
*)
Model: MacBook Pro 2012
AppleScript: 2.7
Browser: Safari 13.0.1
Operating System: macOS 10.14