Friday, December 2, 2022
  • Index
  •  » Code Exchange
  •  » Adding accessory views to Myriad Tables with Dialog Toolkit Plus

#1 2022-08-17 05:09:50 pm

estockly
Member
Registered: 2009-01-03
Posts: 158

Adding accessory views to Myriad Tables with Dialog Toolkit Plus

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!

Applescript:


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

Last edited by estockly (2022-08-20 07:33:56 am)

Offline

 

#2 2022-08-17 09:18:34 pm

Micker
Member
Registered: 2020-01-04
Posts: 2

Re: Adding accessory views to Myriad Tables with Dialog Toolkit Plus

Received the following error when I tried to execute it:

error "The file passed to the 'prepare storage' command is not a valid applet or script bundle" number -2700 from «script "PrefsStorageLib"» to item

Model: iMac
AppleScript: 2.7
Browser: Safari 537.36
Operating System: macOS 10.12

Offline

 

#3 2022-08-18 12:04:03 am

estockly
Member
Registered: 2009-01-03
Posts: 158

Re: Adding accessory views to Myriad Tables with Dialog Toolkit Plus

I should have mentioned it needs to be saved as a bundle or an app before you run it.

I'll add that to the OP

Offline

 
  • Index
  •  » Code Exchange
  •  » Adding accessory views to Myriad Tables with Dialog Toolkit Plus

Board footer

Powered by FluxBB

RSS (new topics) RSS (active topics)