emada2さんからの投稿です。Collection Viewの利用については、Kamenokoの開発時に導入検討したことがありますが、Objective-CのサンプルコードをAppleScriptに翻訳しきれなくて中途半端に放置していました。
まとまった形でCollection Viewのサンプルコードが出てきたのは、おそらくこれが初めてだと思います。ありがとうございます。
Collection Viewを箱庭ダイアログに乗せることができました。 でも残念なのは、itemPrototypeは10.14でDeprecatedになっているので将来的に長く使えないでしょう その他のやり方を探してappleのサンプルコードをみたら、swift 3で書かれていているので10.14でビルドできませんでした。 なのでまだまだCollection Viewを使いこなすのは難しそうです😢
@property (nullable, strong) NSCollectionViewItem *itemPrototype API_DEPRECATED("Use -registerNib:forItemWithIdentifier: or -registerClass:forItemWithIdentifier: instead.", macos(10.5,10.14));
AppleScript名:アラートダイアログ上にCollection Viewを表示 |
use AppleScript version "2.4" — Yosemite (10.10) or later use framework "AppKit" use framework "AppleScriptObjC" use framework "CoreFoundation" use framework "Foundation" use scripting additions on run my testRun() end run on testRun() set aMainMes to "アプリケーションの選択" set aSubMes to "適切なものを以下からえらんでください" #ダイアログ内のビューサイズを指定 set aHeight to 384 set aWidth to 512 + 12 –> スクロールバーの分 #アプリケーションフォルダ内のアプリケーションを取得 set aFolder to path to applications folder set aPath to aFolder’s POSIX path set aURL to current application’s NSURL’s fileURLWithPath:aPath # 指定フォルダの直下のファイルを取得 set filePaths to current application’s NSFileManager’s defaultManager’s ¬ contentsOfDirectoryAtURL:aURL ¬ includingPropertiesForKeys:{current application’s NSURLNameKey} ¬ options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) ¬ |error|:(missing value) set filePaths to filePaths as list set thisFileType to "com.apple.application-bundle" set dataSourceList to {} repeat with anItem in filePaths set aPath to anItem’s contents’s POSIX path set aURL to (current application’s NSURL’s fileURLWithPath:aPath) set {aResult, aUTI, aError} to (aURL’s getResourceValue:(reference) ¬ forKey:(current application’s NSURLTypeIdentifierKey) ¬ |error|:(reference)) if (aUTI as text) is thisFileType then set iconImage to (current application’s NSWorkspace’s sharedWorkspace’s iconForFile:aPath) set dict to {fileURL:aURL, icon:iconImage} set dataSourceList’s end to dict end if end repeat set execButtonTitle to "OK😄" set dateObj to my chooseItemByCollectionView:aMainMes subMes:aSubMes myWidth:aWidth myHeight:aHeight myDataSource:dataSourceList okTitle:execButtonTitle end testRun on chooseItemByCollectionView:(aMainMes as text) subMes:(aSubMes as text) myWidth:(aWidth as integer) myHeight:(aHeight as integer) myDataSource:(dataSourceList as list) okTitle:(execButtonTitle as text) # Script Bundle内のResourcesフォルダを求める set resourcePath to POSIX path of (path to me) & "Contents/Resources/" set theBundle to current application’s NSBundle’s bundleWithPath:resourcePath theBundle’s loadAppleScriptObjectiveCScripts() # subClasses.scptを呼び出す set DialogCore to current application’s AppDelegate’s new() set fRes to DialogCore’s chooseItemByCollectionView:aMainMes subMes:aSubMes myWidth:aWidth myHeight:aHeight myDataSource:dataSourceList okTitle:execButtonTitle if fRes is missing value then error number -128 return fRes as list end chooseItemByCollectionView:subMes:myWidth:myHeight:myDataSource:okTitle: |
AppleScript名:subClasses |
script AppDelegate property parent : class "NSObject" — IBOutlets property theWindow : missing value on applicationShouldTerminate:sender return current application’s NSTerminateNow end applicationShouldTerminate: on applicationShouldTerminateAfterLastWindowClosed:sender return true end applicationShouldTerminateAfterLastWindowClosed: —————— on applicationWillFinishLaunching:aNotification log my testRun() end applicationWillFinishLaunching: on testRun() set aMainMes to "アプリケーションの選択" set aSubMes to "適切なものを以下からえらんでください" #ダイアログ内のビューサイズを指定 set aHeight to 384 set aWidth to 512 + 12 –> スクロールバーの分 #アプリケーションフォルダ内のアプリケーションを取得 set aFolder to path to applications folder set aPath to aFolder’s POSIX path set aURL to current application’s NSURL’s fileURLWithPath:aPath # 指定フォルダの直下のファイルを取得 set filePaths to current application’s NSFileManager’s defaultManager’s ¬ contentsOfDirectoryAtURL:aURL ¬ includingPropertiesForKeys:{current application’s NSURLNameKey} ¬ options:(current application’s NSDirectoryEnumerationSkipsHiddenFiles) ¬ |error|:(missing value) set filePaths to filePaths as list set thisFileType to "com.apple.application-bundle" set dataSourceList to {} repeat with anItem in filePaths set aPath to anItem’s contents’s POSIX path set aURL to (current application’s NSURL’s fileURLWithPath:aPath) set {aResult, aUTI, aError} to (aURL’s getResourceValue:(reference) ¬ forKey:(current application’s NSURLTypeIdentifierKey) ¬ |error|:(reference)) if (aUTI as text) is thisFileType then set iconImage to (current application’s NSWorkspace’s sharedWorkspace’s iconForFile:aPath) set dict to {fileURL:aURL, icon:iconImage} set dataSourceList’s end to dict end if end repeat set execButtonTitle to "OK😄" set dateObj to my chooseItemByCollectionView:aMainMes subMes:aSubMes myWidth:aWidth myHeight:aHeight myDataSource:dataSourceList okTitle:execButtonTitle end testRun # アラートダイアログでCollectionViewを表示 property _retrieve_data : missing value on chooseItemByCollectionView:(aMainMes as text) subMes:(aSubMes as text) myWidth:(aWidth as integer) myHeight:(aHeight as integer) myDataSource:(dataSourceList as list) okTitle:(execButtonTitle as text) set paramObj to {myMessage:aMainMes} set paramObj to paramObj & {mySubMessage:aSubMes} set paramObj to paramObj & {myDataSource:dataSourceList} set paramObj to paramObj & {myWidth:aWidth} set paramObj to paramObj & {myHeight:aHeight} set paramObj to paramObj & {myOKTitile:execButtonTitle} my performSelectorOnMainThread:"raizeAlert:" withObject:paramObj waitUntilDone:true if (my _retrieve_data) is missing value then error number -128 return (my _retrieve_data) end chooseItemByCollectionView:subMes:myWidth:myHeight:myDataSource:okTitle: ## retrieve date on raizeAlert:paramObj set mesText to paramObj’s myMessage as text set infoText to paramObj’s mySubMessage as text set dataSourceList to paramObj’s myDataSource as list set viewWidth to paramObj’s myWidth as integer set viewHeight to paramObj’s myHeight as integer set okButton to paramObj’s myOKTitile as text # set up view set {thisView, collectionView} to my makeContentView(dataSourceList, viewWidth, viewHeight) ### set up alert tell current application’s NSAlert’s new() addButtonWithTitle_(okButton) addButtonWithTitle_("Cancel") setAccessoryView_(thisView) –setIcon_(aImage) setInformativeText_(infoText) setMessageText_(mesText) tell |window|() setInitialFirstResponder_(thisView) end tell #### show alert in modal loop if runModal() is (current application’s NSAlertSecondButtonReturn) then return end tell ### retrieve data set aIndexSet to collectionView’s selectionIndexes() set theArray to current application’s NSArrayController’s alloc()’s initWithContent:(collectionView’s content()) set chooseItems to ((theArray)’s arrangedObjects()’s objectsAtIndexes:aIndexSet) as list # reset set _retrieve_data to {} repeat with anItem in chooseItems set (my _retrieve_data)’s end to anItem’s contents end repeat return my _retrieve_data end raizeAlert: # set up view on makeContentView(dataSourceList, viewWidth, viewHeight) set thisRect to current application’s NSMakeRect(0, 0, viewWidth, viewHeight) tell current application’s NSCollectionView’s alloc tell initWithFrame_(thisRect) setItemPrototype_(current application’s YKZCollectionViewItem’s new()) setAllowsEmptySelection_(true) setAllowsMultipleSelection_(true) setContent_(dataSourceList) setSelectable_(true) set collectionView to it end tell end tell # Viewを作成 tell current application’s NSScrollView’s alloc() tell initWithFrame_(thisRect) setBorderType_(current application’s NSBezelBorder) setDocumentView_(collectionView) setHasHorizontalScroller_(true) setHasVerticalScroller_(true) set baseView to it end tell end tell return {baseView, collectionView} end makeContentView end script #MARK: – script YKZView property parent : class "NSView" property imageView : missing value property selected : false property viewItemHeight : 128 property viewItemWidth : 128 on initWithFrame:rect set myRect to current application’s NSMakeRect(0, 0, viewItemWidth, viewItemHeight) continue initWithFrame:myRect set aHeight to viewItemHeight – 10 set aWidth to viewItemWidth – 10 set newRect to current application’s NSMakeRect(5, 5, aWidth, aHeight) tell current application’s NSImageView’s alloc() tell initWithFrame_(newRect) setImageScaling_(current application’s NSImageScaleProportionallyUpOrDown) setImageAlignment_(current application’s NSImageAlignCenter) set my imageView to it end tell end tell my addSubview:(my imageView) return me end initWithFrame: on drawRect:rect if my selected then current application’s NSColor’s redColor()’s |set|() else current application’s NSColor’s controlBackgroundColor()’s |set|() end if current application’s NSRectFill(rect) continue drawRect:rect end drawRect: end script #MARK: – script YKZCollectionViewItem property parent : class "NSCollectionViewItem" on loadView() my setView:(current application’s YKZView’s alloc()’s initWithFrame:(current application’s NSZeroRect)) end loadView on setRepresentedObject:representedObject –continue setRepresentedObject:representedObject if representedObject is missing value then return (my view())’s imageView’s setImage:(representedObject’s icon) end setRepresentedObject: on setSelected:isSelected set (my view())’s selected to isSelected (my view())’s setNeedsDisplay:true continue setSelected:isSelected end setSelected: end script |