After a little more tooling around with Myriad Tables and Dialog Toolkit Plus, I’ve put together a script that demonstrates how to build and use and get results from Accessory Views in Myriad tables.
Keep in mind a couple things. First this is made for an appleScript writer (me) to be able to quickly figure out which accessory view to use, how to use it, and how to get its result.
So it’s a little klunky and doesn’t test to see if the height of all your views is greater than 250 (causes an error) but I find it useful.
Edit, the script below must be saved as an applet or a bundle (.scptd) before it runs or PrefsStorageLib will throw an error.
As always I’m very open to suggestions for improving it!
use AppleScript version "2.4"
use scripting additions
use framework "Foundation"
use framework "Carbon"
use script "Dialog Toolkit Plus" version "1.1.2"
use script "Myriad Tables Lib" version "1.0.12"
use script "PrefsStorageLib" version "1.1.0"
use script "FileManagerLib" version "2.3.5"
property theAccessoryView : missing value
property accessoryViewResults : missing value
property theTop : 0
property theTableData : {}
property selectedViews : {}
property lastPosition : {}
property whichViews : {}
property viewPath : {}
set theTableData to {¬
{"create image view", 40}, ¬
{"create label", 17}, ¬
{"create field", 23}, ¬
{"create side labeled field", 22}, ¬
{"create top labeled field", 47}, ¬
{"create checkbox", 18}, ¬
{"create labeled checkbox", 18}, ¬
{"create matrix", 58}, ¬
{"create labeled matrix", 58}, ¬
{"create path control", 26}, ¬
{"create labeled path control", 42}, ¬
{"create popup", 26}, ¬
{"create labeled popup", 26}, ¬
{"create secure field", 22}, ¬
{"create rule", 1} ¬
}
PersistentVariables()
repeat
set accessoryView to AssembleAccessoryViews(whichViews)
set whichViews to DisplayTheTable(theTableData, theAccessoryView)
StorePersistentValues()
end repeat
on DisplayTheTable(theTableData, the accessoryView)
local tableResult
if accessoryViewResults is not {} then
set middleButtonName to "Display Results"
else
set middleButtonName to missing value
end if
set tablePrompt to ("Select the Accessory Views you want to see" & return & "Last top: " & theTop as text)
set theTable to make new table with data theTableData ¬
empty selection allowed true ¬
with title ("Accessory View Demo") ¬
with prompt tablePrompt ¬
multiple selections allowed true ¬
can add and delete true ¬
editable columns {} ¬
column headings {"Accessory View", "View Height"} ¬
row numbering false ¬
initially selected rows selectedViews ¬
with double click means OK
modify table theTable ¬
OK button name ("Continue") ¬
OK button is default true ¬
extra button name middleButtonName ¬
accessory view theAccessoryView ¬
initial position lastPosition
set theTop to 0
set theAccessoryView to missing value -- to avoid error messages when saving
set tableResult to display table theTable ¬
with extended results
tell tableResult
set selectedValues to its values selected
set selectedViews to its rows selected
set lastPosition to items 1 thru 2 of its final position
set whichButton to its button number
end tell
if accessoryViewResults is not {} and whichButton is 2 then
set controlResults to {}
repeat with thisAccessoryView in accessoryViewResults
set {viewType, aControl} to thisAccessoryView as item
if (aControl's isKindOfClass:(current application's NSTextField)) as boolean then
set end of controlResults to {viewType, viewType & "'s stringValue()", aControl's stringValue() as text}
else if (aControl's isKindOfClass:(current application's NSPopUpButton)) as boolean then
set end of controlResults to {viewType, viewType & "'s titleOfSelectedItem()", aControl's titleOfSelectedItem() as text}
else if (aControl's isKindOfClass:(current application's NSButton)) as boolean then
set thisResult to aControl's state() as boolean
if thisResult then
set thisResult to "true" as text
else
set thisResult to "false" as text
end if
set end of controlResults to {viewType, viewType & "'s state()", thisResult}
else if (aControl's isKindOfClass:(current application's NSPathControl)) as boolean then
set end of controlResults to {viewType, viewType & "'s |URL|()'s |path|()", aControl's |URL|()'s |path|() as text}
else if (aControl's isKindOfClass:(current application's NSMatrix)) as boolean then
set end of controlResults to {viewType, viewType & "'s title()", aControl's selectedCell()'s title() as text}
else if (aControl's isKindOfClass:(current application's NSImageView)) as boolean then
set end of controlResults to {viewType, viewType & "'s image()'s |name|()", aControl's image()'s |name|() as text}
else -- NSBox
set end of controlResults to missing value
end if
end repeat
--DisplayTableWithData
set tableData to controlResults
set tableTitle to ("Accessory View Results")
set tablePrompt to ("These are the values of the accessory views shown")
set multipleLinesAllowed to true --trueOrFalse ¬
set multipleSelectionsAllowed to true --trueOrFalse
set emptySelectionAllowed to true --trueOrFalse
set canAddAndDelete to false --trueOrFalse
set rowNumbering to true --trueOrFalse
set editableColumns to {}
set columnHeadings to {"View Variable", "View Ref", "TextValue"}
set initiallySelectedRows to {}
set doubleClickable to true --trueOrFalse
try
set tableResult to display table with data tableData ¬
with title tableTitle ¬
with prompt tablePrompt ¬
multiple lines allowed multipleLinesAllowed ¬
multiple selections allowed multipleSelectionsAllowed ¬
empty selection allowed emptySelectionAllowed ¬
can add and delete canAddAndDelete ¬
row numbering rowNumbering ¬
editable columns editableColumns ¬
column headings columnHeadings ¬
initially selected rows initiallySelectedRows ¬
double click means OK doubleClickable
on error errMsg number errNum
errMsg
end try
set buttonNumber to button number of tableResult
set finalPosition to final position of tableResult
set selectedRows to rows selected of tableResult
set timedOut to timed out of tableResult
set valuesReturned to values returned of tableResult
set resultsSelected to values selected of tableResult
end if
return selectedValues
end DisplayTheTable
on AssembleAccessoryViews(whichViews)
local viewsList, accViewControls, AccViewLeft, AccViewBottom, AccViewWidth, AccViewTop, spacer
set accessoryViewResults to {}
set viewsList to {}
repeat with thisView in whichViews
set the end of viewsList to item 1 of thisView as text
end repeat
set accViewControls to {}
set AccViewLeft to 1
set AccViewBottom to 0
set AccViewWidth to 300
set AccViewTop to 250
set theBottom to AccViewBottom
set theLeft to AccViewLeft
set spacer to 1
set maxWidth to AccViewWidth
--create rule
if "create rule" is in viewsList then
set {rule1, theTop} to create rule theBottom ¬
left inset AccViewLeft ¬
rule width AccViewWidth
set the end of accViewControls to rule1
set theBottom to theTop + spacer
end if
--create field
if "create field" is in viewsList then
set enteredText to "Entered Text"
set defaultText to "Default Text"
set theWidth to maxWidth
set extraHeight to spacer
set acceptsTabs to true
set fieldLeft to AccViewLeft
set {theField, theTop} to create field enteredText ¬
placeholder text defaultText ¬
left inset fieldLeft ¬
bottom theBottom ¬
field width theWidth ¬
extra height extraHeight ¬
with accepts linebreak and tab
set theBottom to theTop + spacer
set the end of accViewControls to theField
set the end of accessoryViewResults to {"theField", theField}
end if
--create image view
if "create image view" is in viewsList then
set posixPath to POSIX path of viewPath
set viewWidth to 40
set viewHeight to 40
set imageScale to scale to fit
-- scales: scale down proportionally, scale to fit, scale none, scale proportionally}
set imageAlignment to bottom left aligned
-- imageAlignments: center aligned, top aligned, top left aligned, top right aligned
-- left aligned, bottom left aligned, bottom right aligned, right aligned, bottom aligned
set {theImage, theTop} to create image view posixPath ¬
left inset AccViewLeft ¬
bottom theBottom ¬
view width viewWidth ¬
view height viewHeight ¬
scale image imageScale ¬
align image imageAlignment
set theBottom to theTop + spacer
set the end of accViewControls to theImage
set the end of accessoryViewResults to {"theImage", theImage}
end if
--create label
if "create label" is in viewsList then
set maxWidth to 280
set wrapsBool to false
set boldType to true
set labelString to "LabelString:"
set LabelLeft to 0
set alignment to left aligned
-- alignments: left aligned, right aligned or center aligned
set controlSize to regular size
-- control sizes: regular size, mini size, small size,large size
set labelWidth to max width for labels {labelString} ¬
control size controlSize ¬
bold type boldType
set labelDepth to max depth for label labelString ¬
max width labelWidth ¬
control size controlSize ¬
bold type boldType
set {theLabel, theTop} to create label labelString ¬
left inset LabelLeft ¬
bottom theBottom ¬
max width maxWidth ¬
aligns alignment ¬
multiline wrapsBool ¬
control size controlSize ¬
bold type boldType
set theBottom to theTop + spacer
set the end of accViewControls to theLabel
end if
--create labeled matrix
if "create labeled matrix" is in viewsList then
-- makes label and matrix; if matrixLeft is less than leftInset, the label will start at leftInset, with the matrix following;
-- if matrixLeft is more than leftInset, the matrix will start at matrixLeft, and the label will will appear to its left
set radioButtonNames to {"Button 1", "Button two", "Button button button"}
set labelText to "Matrix Label"
set matrixLabelWidth to (max width for labels {labelText}) + AccViewLeft
set {labeledMatrix, matrixLabel, theTop, matrixLeft} to ¬
create labeled matrix radioButtonNames ¬
left inset AccViewLeft ¬
bottom theBottom ¬
max width maxWidth ¬
arranged vertically true ¬
matrix left matrixLabelWidth ¬
label text labelText ¬
initial choice (some item of radioButtonNames)
set theBottom to theTop + spacer
set the end of accViewControls to labeledMatrix
set the end of accViewControls to matrixLabel
set the end of accessoryViewResults to {"labeledMatrix", labeledMatrix}
end if
--create labeled path control
if "create labeled path control" is in viewsList then
set labelText to "Path control label"
set pathControlLabelWidth to max width for labels {labelText}
set myPath to POSIX path of (path to me)
set {labeledPathControl, pathControlLabel, theTop} to create labeled path control myPath ¬
left inset AccViewLeft ¬
bottom theBottom ¬
control width maxWidth ¬
pops up (some item of {true, false}) ¬
label text labelText
set theBottom to theTop + spacer
set the end of accViewControls to labeledPathControl
set the end of accViewControls to pathControlLabel
set the end of accessoryViewResults to {"labeledPathControl", labeledPathControl}
end if
--create create labeled popup
if "create labeled popup" is in viewsList then
set labelText to "Popup label"
set popupLabelWidth to max width for labels {labelText}
set popupList to {"Fred", "Frieda", "George", "Georgina"}
set {theLabeledPopup, thePopupLabel, theTop, theWidth} to ¬
create labeled popup popupList ¬
left inset AccViewLeft ¬
bottom theTop ¬
popup width maxWidth - popupLabelWidth ¬
max width maxWidth ¬
label text labelText ¬
popup left popupLabelWidth ¬
initial choice (some item of popupList)
set theBottom to theTop + spacer
set the end of accViewControls to thePopupLabel
set the end of accViewControls to theLabeledPopup
set the end of accessoryViewResults to {"theLabeledPopup", theLabeledPopup}
end if
--create matrix
if "create matrix" is in viewsList then
set radioButtonNames to {"Button 1", "Button two", "Button button button"}
set {theMatrix, theTop} to create matrix radioButtonNames ¬
left inset AccViewLeft ¬
bottom theBottom ¬
max width maxWidth ¬
arranged vertically true ¬
initial choice some item of radioButtonNames
set theBottom to theTop + spacer
set the end of accViewControls to theMatrix
set the end of accessoryViewResults to {"theMatrix", theMatrix}
end if
--create path control
if "create path control" is in viewsList then
set myPath to POSIX path of (path to me)
set {thePathControl, theTop} to create path control myPath ¬
left inset AccViewLeft ¬
bottom theBottom ¬
control width maxWidth ¬
with pops up
set theBottom to theTop + spacer
set the end of accViewControls to thePathControl
set the end of accessoryViewResults to {"thePathControl", thePathControl}
end if
--create popup
if "create popup" is in viewsList then
set popupList to {"Fred", "Frieda", "George", "Georgina"}
set {thePopup, theTop} to create popup popupList ¬
left inset AccViewLeft ¬
bottom theBottom ¬
popup width maxWidth ¬
initial choice (some item of popupList)
set theBottom to theTop + spacer
set the end of accViewControls to thePopup
set the end of accessoryViewResults to {"thePopup", thePopup}
end if
--create checkbox
if "create checkbox" is in viewsList then
set checkBoxTitle to "Check Box Title"
set {theCheckbox, theTop} to create checkbox checkBoxTitle ¬
left inset theLeft ¬
bottom theBottom ¬
max width maxWidth ¬
with initial state
set theBottom to theTop + spacer
set the end of accViewControls to theCheckbox
set the end of accessoryViewResults to {"theCheckbox", theCheckbox}
end if
--create labeled checkbox
if "create labeled checkbox" is in viewsList then
-- makes label and checkbox; if checkboxLeft is less than leftInset, the label will start at leftInset, with the checkbox following;
-- if checkboxLeft is more than leftInset, the checkbox will start at checkboxLeft, and the label will will appear to its left
set ceckboxLabel to "Label for checkbox"
set checkboxLeft to AccViewLeft
set checkBoxLabelText to "Text for Checkbox"
set {theLabeledCheckBox, theCheckBoxLabel, theTop, theLeft} to ¬
create labeled checkbox ceckboxLabel ¬
left inset AccViewLeft ¬
bottom theBottom ¬
max width maxWidth ¬
label text checkBoxLabelText ¬
checkbox left checkboxLeft ¬
without initial state
set theBottom to theTop + spacer
set the end of accViewControls to theCheckBoxLabel
set the end of accViewControls to theLabeledCheckBox
set the end of accessoryViewResults to {"theLabeledCheckBox", theLabeledCheckBox}
end if
--create secure field
if "create secure field" is in viewsList then
set secureFieldText to "Secure Field"
set secureFieldPlaceHolder to "Secure Placeholder"
set {theSecureField, theTop} to create secure field secureFieldText ¬
placeholder text secureFieldPlaceHolder ¬
left inset AccViewLeft ¬
bottom theTop ¬
field width maxWidth
set theBottom to theTop + spacer
set the end of accViewControls to theSecureField
set the end of accessoryViewResults to {"theSecureField", theSecureField}
end if
--create side labeled field
if "create side labeled field" is in viewsList then
set labelText to "field label"
set labelWidth to max width for labels {labelText}
set fieldContents to "Side label field contents"
set placeHolderText to "Side label field placeholder"
set {theSideLabeledField, theFieldLabel, theTop, theWidth} ¬
to create side labeled field fieldContents ¬
placeholder text placeHolderText ¬
left inset AccViewLeft ¬
bottom theTop ¬
total width maxWidth ¬
accepts linebreak and tab true ¬
label text labelText ¬
field left AccViewLeft + labelWidth
set theBottom to theTop + spacer
set the end of accViewControls to theFieldLabel
set the end of accViewControls to theSideLabeledField
set the end of accessoryViewResults to {"theSideLabeledField", theSideLabeledField}
end if
--create top labeled field
if "create top labeled field" is in viewsList then
set labelText to "field label"
set labelWidth to max width for labels {labelText}
set fieldContents to "Top label field contents"
set placeHolderText to "top label field placeholder"
set {theTopLabeledField, theFieldLabel, theTop} to create top labeled field fieldContents ¬
placeholder text placeHolderText ¬
left inset AccViewLeft ¬
bottom theTop ¬
field width maxWidth ¬
extra height spacer ¬
accepts linebreak and tab true ¬
label text labelText
set theBottom to theTop + spacer
set the end of accViewControls to theTopLabeledField
set the end of accViewControls to theFieldLabel
set the end of accessoryViewResults to {"theTopLabeledField", theTopLabeledField}
end if
if theTop > 250 then
set AccViewTop to 250
else
set AccViewTop to theTop
end if
my AssembleAccessoryViewsMainThread:{accViewControls, AccViewLeft, AccViewBottom, AccViewWidth, AccViewTop}
end AssembleAccessoryViews
on AssembleAccessoryViewsMainThread:theArg
set {accViewControls, theLeft, theBottom, theWidth, theTop} to theArg
set my theAccessoryView to current application's NSView's alloc()'s initWithFrame:{{theLeft, theBottom}, {theWidth, theTop - theBottom}}
repeat with aControl in accViewControls
(theAccessoryView's addSubview:aControl)
end repeat
end AssembleAccessoryViewsMainThread:
on PersistentVariables()
set newView to false
prepare storage for (path to me) default values {selectedViews:{}, lastPosition:{}, whichViews:{}, viewPath:{}}
set my selectedViews to value for key "selectedViews"
set my lastPosition to value for key "lastPosition"
set my whichViews to value for key "whichViews"
set my viewPath to value for key "viewPath"
if selectedViews = {} then
set selectedViews to {1, 2, 3}
assign value selectedViews to key "selectedViews"
end if
if lastPosition = {} then
set lastPosition to {30, 30}
assign value lastPosition to key "lastPosition"
end if
if whichViews = {} then
set whichViews to items 1 thru 3 of theTableData
assign value whichViews to key "whichViews"
end if
if viewPath = {} then
set newView to true
else
try
if not (exists object viewPath) then set newView to true
on error
set newView to true
end try
end if
if newView then
set viewPath to choose file with prompt ("Select an image for image view") ¬
of type {"jpg", "jpeg", "tif", "tiff"} ¬
invisibles false ¬
multiple selections allowed false ¬
without showing package contents
set viewPath to POSIX path of viewPath
assign value viewPath to key "viewPath"
end if
end PersistentVariables
on StorePersistentValues()
assign value selectedViews to key "selectedViews"
assign value lastPosition to key "lastPosition"
assign value whichViews to key "whichViews"
assign value viewPath to key "viewPath"
end StorePersistentValues
on RetreiveStoredValues()
set my selectedViews to value for key "selectedViews"
set my lastPosition to value for key "lastPosition"
set my whichViews to value for key "whichViews"
set my viewPath to value for key "viewPath"
end RetreiveStoredValues
Edit: Better result Reporting