Myriad Tables Accessory Views

I’ve been tooling around with SD Notary, Myriad Tables Lib, Dialog Toolkit Plus, accessory views and PrefsStorageLib lately. Today I decided to combine them all in one app, a modification of one I’ve been using for a while now.

This app will use the text in the clipboard in Safari to search one or more appleScript related pages (ASLG, SD Forums, MacScripter). The results appear in new tabs.

The app below is notarized.

The script below will run, but the icon that identifies it as a Safari search won’t show (it’s looking for it in an app or bundle’s resources).

AppleScript Safari Search.app.zip (2.1 MB)

 use AppleScript version "2.4"
use scripting additions
use framework "Carbon"
use script "Myriad Tables Lib" version "1.0.12"
use script "Dialog Toolkit Plus" version "1.1.2"
use script "PrefsStorageLib" version "1.1.0"

property theAccessoryView : missing value
property theField : missing value
property lastpaletteTablePosition : {}
property initialSelection : {}
property lastSearch : "AppleScript Language Guide"
property firstRun : true

PersistentVariables()
if lastpaletteTablePosition is {} then
	set {paletteTableX, paletteTableY} to {0, 0}
else
	set {paletteTableX, paletteTableY} to lastpaletteTablePosition
end if

set tableDisplayData to {"AppleScript Language Guide", "ScriptDebugger Forums", "MacScripter", "Google", "ScriptDebugger Forums (Google)", "MacScripter (Google)"}
set tableTitle to "Safari Search"
set okName to "Search"
set cancelName to "Close"
set extraName to "Refresh"
set paletteTablePosition to {paletteTableX, paletteTableY}
set tableSettings to {tableDisplayData, tableTitle, okName, cancelName, extraName, paletteTablePosition}

repeat
	set searchString to GetClipboard()
	my BuildAccessoryView(searchString)
	set {scriptList, searchString} to my DisplaySearchTable(tableSettings, searchString)
	RunTheScript(scriptList, searchString)
end repeat

on DisplaySearchTable(tableSettings, searchString)
	set {tableDisplayData, tableTitle, okName, cancelName, extraName, paletteTablePosition} to tableSettings
	set tablePrompt to "Safari: Searching  for “" & searchString & "”"
	
	set myTable to make new table with data tableDisplayData ¬
		with prompt tablePrompt ¬
		with title tableTitle ¬
		empty selection allowed true ¬
		initially selected rows initialSelection ¬
		multiple selections allowed true ¬
		row template {"", missing value} ¬
		with double click means OK
	
	modify table myTable initial position paletteTablePosition ¬
		OK button name okName ¬
		accessory view theAccessoryView ¬
		cancel button name cancelName ¬
		extra button name extraName
	
	tell me to activate
	set tableResult to display table myTable ¬
		with extended results
	set whichButton to button number of tableResult
	set userSelection to values selected of tableResult
	set initialSelection to rows selected of tableResult
	set lastpaletteTablePosition to final position of tableResult
	set searchString to (theField's stringValue()) as text
	
	set {paletteTableX, paletteTableY, paletteTableW, paletteTableH} to lastpaletteTablePosition
	if paletteTableX < 1 then set paletteTableX to 0
	if paletteTableY < 1 then set paletteTableY to 0
	
	set lastpaletteTablePosition to {paletteTableX, paletteTableY}
	set paletteTablePosition to lastpaletteTablePosition
	set userSelection to values selected of tableResult
	
	if userSelection is not {} and whichButton is not 2 then
		StorePersistentValues()
		return {the reverse of userSelection, searchString}
	else
		return {{}, searchString}
		
	end if
end DisplaySearchTable

on RunTheScript(scriptList, searchString)
	local scriptName
	
	set searchStringPlus to words of searchString
	set AppleScript's text item delimiters to {"+"}
	set searchStringPlus to searchStringPlus as text
	
	repeat with scriptName in scriptList
		set scriptName to scriptName as text
		set AppleScript's text item delimiters to {"\" \"", "\"", ", ", " "}
		
		set quotedSearchString to text items of searchString
		set quotedSearchString to {quote & quotedSearchString & quote} as text
		
		set AppleScript's text item delimiters to {"\" \"\""}
		set quotedSearchString to text items of quotedSearchString
		set AppleScript's text item delimiters to {"\""}
		set quotedSearchString to quotedSearchString as text
		--{"ParseIMDBCast", "Search Google IMDB", "Search Google", "Search LATimes", ¬
		--"Search Netflix", "Search Wiki"}
		
		--https://www.google.com/search?client=safari&rls=en&q=Handler+site%3Adeveloper.apple.com%2Flibrary%2Farchive%2Fdocumentation%2FAppleScript%2FConceptual%2FAppleScriptLangGuide%2F&ie=UTF-8&oe=UTF-8
		if scriptName is "Google" then
			set searchPreString to "google.com/search?q="
			set searchPostString to ""
			set searchURL to searchPreString & quotedSearchString & searchPostString
			tell application "Safari" to open location searchURL
			
		else if scriptName is "AppleScript Language Guide" then
			--				
			set searchPreString to "http://www.google.com/search?q="
			set searchPostString to "+site:developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/"
			set searchURL to searchPreString & quotedSearchString & searchPostString
			tell application "Safari" to open location searchURL
			
		else if scriptName is "MacScripter" then
			--https://macscripter.net/search.php?action=search&keywords=text+item+delimiters
			set searchPreString to "https://macscripter.net/search.php?action=search&keywords="
			set searchPostString to "&author=&forum=-1&sort_by=5&sort_dir=DESC&show_as=topics&search=Submit:"
			set searchURL to searchPreString & searchStringPlus & searchPostString
			tell application "Safari" to open location searchURL
			
		else if scriptName is "MacScripter (Google)" then
			set searchPreString to "http://www.google.com/search?q="
			set searchPostString to "+site:macscripter.net"
			set searchURL to searchPreString & quotedSearchString & searchPostString
			tell application "Safari" to open location searchURL
			
		else if scriptName is "ScriptDebugger Forums" then
			set AppleScript's text item delimiters to {"%20"}
			set SDsearchString to words of searchString as text
			--	text%20item%20delimiters
			--	https://forum.latenightsw.com/search?expanded=true&q=text%20item%20delimiters
			set searchPreString to "https://forum.latenightsw.com/search?expanded=false&q="
			set searchPostString to ""
			set searchURL to searchPreString & SDsearchString & searchPostString
			tell application "Safari" to open location searchURL
		else if scriptName is "ScriptDebugger Forums (Google)" then
			
			set searchPreString to "http://www.google.com/search?q="
			set searchPostString to "+site:forum.latenightsw.com"
			set searchURL to searchPreString & quotedSearchString & searchPostString
			tell application "Safari" to open location searchURL
			
		end if
	end repeat
	
	tell application "Safari" to activate
	tell me to activate
end RunTheScript


on PersistentVariables()
	prepare storage for (path to me) default values {lastpaletteTablePosition:{}, initialSelection:{}, lastSearch:{}, firstRun:{}}
	set my lastpaletteTablePosition to value for key "lastpaletteTablePosition"
	set my initialSelection to value for key "initialSelection"
	set my lastSearch to value for key "lastSearch"
	set my firstRun to value for key "firstRun"
	if firstRun = {} then set firstRun to false
	
end PersistentVariables

on StorePersistentValues()
	assign value lastpaletteTablePosition to key "lastpaletteTablePosition"
	assign value initialSelection to key "initialSelection"
	assign value lastSearch to key "lastSearch"
	assign value firstRun to key "firstRun"
end StorePersistentValues

on RetreiveStoredValues()
	set my lastpaletteTablePosition to value for key "lastpaletteTablePosition"
	set my initialSelection to value for key "initialSelection"
	set my lastSearch to value for key "lastSearch"
	set my firstRun to value for key "firstRun"
end RetreiveStoredValues

on GetClipboard()
	try
		set clipboardString to paragraph 1 of (the clipboard)
		
		set clipboardString to trimText(clipboardString)
	on error
		set clipboardString to lastSearch
		return clipboardString
	end try
	
	return clipboardString
end GetClipboard

on trimText(theString)
	set thePattern to "(?m)^[ \\t]+|[ \\t]+$"
	set theString to current application's NSString's stringWithString:theString
	set theString to (theString's stringByReplacingOccurrencesOfString:thePattern withString:"" options:(current application's NSRegularExpressionSearch) range:{0, theString's |length|()})
	return theString as text
end trimText

on BuildAccessoryView(displayString)
	set accViewControls to {}
	set AccViewLeft to 0
	set AccViewBottom to 0
	set AccViewWidth to 280
	set AccViewTop to 250
	
	set theBottom to AccViewBottom
	set theLeft to AccViewLeft
	
	set spacer to 20
	
	--Label variables
	set maxWidth to 280
	set alignment to left aligned
	-- alignments: left aligned, right aligned or center aligned
	set wrapsBool to false
	set controlSize to regular size
	--control sizes:regular size,  mini size, small size,large size 
	set boldType to true
	set labelString to "Safari search:"
	set LabelLeft to 0
	
	--Field variables
	set enteredText to displayString
	set defaultText to displayString
	set theWidth to maxWidth - 10
	set extraHeight to spacer
	set acceptsTabs to true
	set fieldLeft to 45
	--View variables
	set myPath to POSIX path of (path to me)
	
	set iconPath to myPath & "Contents/Resources/seachSafariIcon.jpg"
	set posixPath to POSIX path of iconPath
	
	
	set viewWidth to 40
	set viewHeight to 40
	set imageScale to scale to fit
	--{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 {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 the end of accViewControls to theField
	
	set {theImage, viewTop} to create image view posixPath ¬
		left inset theLeft ¬
		bottom theBottom ¬
		view width viewWidth ¬
		view height viewHeight ¬
		scale image imageScale ¬
		align image imageAlignment
	
	set theBottom to theTop
	
	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 the end of accViewControls to theLabel
	set theBottom to theTop + spacer
	
	set the end of accViewControls to theImage
	set theTop to theTop - AccViewBottom
	if theTop < AccViewTop then set AccViewTop to theTop
	
	my buildAccessoryViewMainThread:{accViewControls, AccViewLeft, AccViewBottom, AccViewWidth, AccViewTop}
end BuildAccessoryView

on create label labelString left inset theLeft : 0 bottom theBottom max width maxWidth aligns alignment : left aligned multiline wrapsBool : true control size controlSize : regular size bold type boldType : false
	if NSThread's isMainThread() as boolean then
		my createLabelMainThread:{labelString, theLeft, theBottom, maxWidth, alignment, wrapsBool, controlSize, boldType}
	else
		my performSelectorOnMainThread:"createLabelMainThread:" withObject:{labelString, theLeft, theBottom, maxWidth, alignment, wrapsBool, controlSize, boldType} waitUntilDone:true
	end if
	return handlerResult
end create label

on create field enteredText placeholder text placeholder left inset theLeft : 0 bottom theBottom field width theWidth extra height extraHeight : 0 accepts linebreak and tab acceptsTabs : false
	if NSThread's isMainThread() as boolean then
		my createFieldMainThread:{enteredText, placeholder, theLeft, theBottom, theWidth, extraHeight, acceptsTabs}
	else
		my performSelectorOnMainThread:"createFieldMainThread:" withObject:{enteredText, placeholder, theLeft, theBottom, theWidth, extraHeight, acceptsTabs} waitUntilDone:true
	end if
	return handlerResult
end create field

on create image view posixPath left inset theLeft bottom theBottom view width viewWidth view height viewHeight scale image imageScale : scale down proportionally align image imageAlignment : center aligned
	if NSThread's isMainThread() as boolean then
		my createImageViewMainThread:{posixPath, theLeft, theBottom, viewWidth, viewHeight, imageScale, imageAlignment}
	else
		my performSelectorOnMainThread:"createImageViewMainThread:" withObject:{posixPath, theLeft, theBottom, viewWidth, viewHeight, imageScale, imageAlignment} waitUntilDone:true
	end if
	return handlerResult
end create image view

on buildAccessoryViewMainThread: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 buildAccessoryViewMainThread:



Any reason you don’t use path to resource?

No good reason.

I just saved a new version improving the quoting for URLs.

I tried to use path to resource, but that kept generating an error in SD.

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.

As always I’m very open to suggestions for improving it!

Edit, the script below must be saved as an applet or a bundle (.scptd) before it runs or PrefsStorageLib will throw an error.


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:- Improved result reporting

I’m having a couple issues with this script and a question.

First issue, each time I add a view to the accessory views I get a variable for the distance from the top of the view to the bottom of the accessory view, right? I use that to determine the bottom of the next view, and the last one added should give me a total height for the accessory view. But if I get that value (theTop in the script above) close to 250, I get an error when I try to build a table saying that the accessory view must be less than 250. First, is theTop as used here not reliable for the height of the accessory view, and is there another way to get the height of the accessory view without trying to display a table and generating an error.

Second issue is pretty simple, I’m not sure how to get results from an image view. It seems I should be able to get the image name and path (possibly more info?) Any suggestions?

And the question: In the samples @ShaneStanley provided there is case where clicking a checkbox actually executes some script while the table is displaying. This is really cool. What I want to do is let the user click a box that replaces text displayed in a field with the clipboard, without closing the window. Is that doable?

That’s right – it’s a hard limit for reasons too complicated to go into here.

As reliable as can be. The system can override these values.

You could use the code in the library to build your own handlers, but otherwise no.

Yes, it can be done. But in many cases you have to build your own modified version of the Dialog Toolkit Plus library. You basically set two other properties of the checkbox: its target, which in this case is likely to be me, and its action, which is the name of the handler to be called.