AppKit系のオブジェクトで最難関との呼び声も高い、NSOutlineViewをAppleScriptから呼び出しやすく機能をまとめたものです。
edama2さんと数年前に「Outline Viewがどうにかならないものか」と相談し、まとめていただいたものです。本当はもっとシンプルに書いてあったのですが、データを外部から指定できるようにしたり、デフォルト状態でNSOutlineViewを展開状態で表示する機能を追加したり、行ごとの背景色を変更できるようにしたり……と、機能が増えました。
本UIをAppleScript上で利用する用途は、データ選択や階層データのプレビュー(PDFのTOCなど)などです。
NSTreeControllerの使い方だったり、Cocoa Bindingをプログラマティックに実行していたりと、そのあたりが見どころでしょう。
スクリプトエディタとScript Debuggerの両方で動作確認していますし、スクリプトメニュー上で動作しています。
CotEditorの内蔵スクリプトメニューに入れたところ最前面にダイアログ表示されませんでした。
AppleScript名:Outline View Lib.scpt |
— – Created by: edama2 & Piyomaru – Created on: 2024/12/16 — – Copyright © 2024 edama2 & Piyomaru, All Rights Reserved — use AppleScript use framework "Cocoa" property dRes : missing value –Selection property _data_source : missing value set aRecord to {} set aRecord’s end to {|name|:"🟥 格闘機", isLeaf:false, children:{{|name|:"RGM-79(G)陸戦型ジム", isLeaf:true}, {|name|:"RB-79KボールK型", isLeaf:true}, {|name|:"RGM-79Lジム・ライトアーマー", isLeaf:true}, {|name|:"RGM-79ジム(指揮官機)", isLeaf:true}, {|name|:"RGM-79FPジム・ストライカー", isLeaf:true}, {|name|:"RGM-79Vジム・ナイトシーカー", isLeaf:true}, {|name|:"RX-77-3ガンキャノン重装型", isLeaf:true}, {|name|:"RX-78XXピクシー", isLeaf:true}}} set aRecord’s end to {|name|:"🟧 近距離機", isLeaf:false, children:{{|name|:"RGM-79ジム", isLeaf:true}, {|name|:"TGM-79ジム・トレーナー", isLeaf:true}, {|name|:"RAG-79アクア・ジム", isLeaf:true}, {|name|:"RGM-79ジム(WD隊)", isLeaf:true}, {|name|:"MS-06F-2ザクII(F2)", isLeaf:true}}} set aRecord’s end to {|name|:"🟩 射撃型機", isLeaf:false, children:{{|name|:"RGC-80Sジム・キャノン(空間突撃仕様)", isLeaf:true}, {|name|:"RGM-79Fデザート・ジム", isLeaf:true}, {|name|:"RX-79(G)陸戦型ガンダム(ジム頭)", isLeaf:true}}} set aRecord’s end to {|name|:"🟪 支援型機", isLeaf:false, children:{{|name|:"RGM-79SCジム・スナイパーカスタム", isLeaf:true}, {|name|:"RGM-79SCジム・スナイパーカスタム(SP)", isLeaf:true}, {|name|:"RX-77-2ガンキャノン", isLeaf:true}, {|name|:"RGM-79SPジム・スナイパーII", isLeaf:true}, {|name|:"FA-78-2ヘビーガンダム", isLeaf:true}, {|name|:"FA-78-1フルアーマーガンダム", isLeaf:true}}} set aRecord’s end to {|name|:"🟦 遠距離型機", isLeaf:false, children:{{|name|:"RB-79ボール", isLeaf:true}, {|name|:"RGM-79(G)ジム・スナイパー", isLeaf:true}, {|name|:"RGC-80ジム・キャノン", isLeaf:true}, {|name|:"RX-75量産型ガンタンク", isLeaf:true}, {|name|:"RGC-80ジム・キャノン(WD隊)", isLeaf:true}, {|name|:"RTX-440陸戦強襲型ガンタンク", isLeaf:true}, {|name|:"RX-75ガンタンク", isLeaf:true}, {|name|:"RX-77D量産型ガンキャノン", isLeaf:true}, {|name|:"FA-78-1Bフルアーマーガンダム(TYPE-B)", isLeaf:true}}} set mainMes to "戦場の絆MS選択" set subMes to "以下のリストから希望の機体を選択してください" set aRes to displayOutline(aRecord, mainMes, subMes, true, 400, 700) of me on displayOutline(treeData, messageText, informativeText, isExpand, aWidth, aHeight) set (my _data_source) to missing value –init set paramObj to {treeData:treeData, messageText:messageText, informativeText:informativeText, isExpand:isExpand, aWidth:aWidth, aHeight:aHeight} my performSelectorOnMainThread:"raizeAlert:" withObject:(paramObj) waitUntilDone:true return dRes end displayOutline on raizeAlert:paramObj –Initialize return value set dRes to missing value –Recieve Parameters set treeData to (treeData of paramObj) as list set messageText to (messageText of paramObj) set informativeText to (informativeText of paramObj) set isExpand to (isExpand of paramObj) as boolean set aWidth to (aWidth of paramObj) as integer set aHeight to (aHeight of paramObj) as integer –Make Accessory View set accessoryView to makeAccessoryView(treeData, isExpand, aWidth, aHeight) of me tell current application’s NSAlert’s new() current application’s NSApplication’s sharedApplication()’s setActivationPolicy:(current application’s NSApplicationActivationPolicyRegular) current application’s NSApp’s activateIgnoringOtherApps:(true) setMessageText_(messageText) setInformativeText_(informativeText) setAccessoryView_(accessoryView) runModal() end tell set selectedObject to (my _data_source)’s selectedObjects()’s firstObject() set dRes to {selectedObjects:selectedObject as {record, anything}} end raizeAlert: on makeAccessoryView(treeData as list, isExpand as boolean, aWidth as integer, aHeight as integer) set my _data_source to current application’s NSTreeController’s alloc()’s initWithContent:treeData (my _data_source)’s setChildrenKeyPath:"children" (my _data_source)’s setLeafKeyPath:"isLeaf" set scrollView to (current application’s NSScrollView’s alloc()’s initWithFrame:(current application’s NSMakeRect(0, 0, aWidth, aHeight))) tell (current application’s NSOutlineView’s alloc()’s initWithFrame:(current application’s NSZeroRect)) addTableColumn_(current application’s NSTableColumn’s alloc()’s initWithIdentifier:"name") bind_toObject_withKeyPath_options_(current application’s NSContentBinding, (my _data_source), "arrangedObjects", missing value) bind_toObject_withKeyPath_options_(current application’s NSSelectionIndexPathsBinding, (my _data_source), current application’s NSSelectionIndexPathsBinding, {}) expandItem_expandChildren_(missing value, isExpand) scrollView’s setDocumentView:it setHeaderView_(missing value) setOutlineTableColumn_(tableColumns()’s firstObject()) setUsesAlternatingRowBackgroundColors_(true) tell tableColumns()’s firstObject() bind_toObject_withKeyPath_options_(current application’s NSValueBinding, (my _data_source), ("arrangedObjects." & its identifier()), missing value) setTitle_(its identifier()) setWidth_(current application’s NSWidth(tableView()’s superview()’s |bounds|())) end tell end tell return scrollView end makeAccessoryView |