Custom Dialogs with swiftDialog App

I recently learned of the open-source swiftDialog app in a post in the Late Night Software forum (thanks laughingtiger). This app takes a place somewhere between the basic dialogs included with AppleScript and the full-featured dialogs in Shane’s Dialog Toolkit Plus script library. The swiftDialog app is a command-line utility and is generally easy to configure.

A few links:

There are two basic approaches that can be used to display a swiftDialog in an AppleScript. The following are simple examples of stop/proceed dialogs:

--Approach One
try
	do shell script "/usr/local/bin/dialog --title 'Test Title' --titlefont 'size=15' --message 'Test Message' --messagefont size=14 --button2 --width 350 --height 130 --hideicon"
on error
	error number -128
end try

--Approach Two
set userInput to do shell script "/usr/local/bin/dialog --title 'Test Title' --titlefont 'size=15' --message 'Test Message' --messagefont 'size=14' --button2 --width 350 --height 130 --hideicon; echo $?"
if userInput is "2" then error number -128

The following are some additional swiftDialog examples:

--Dialog with three buttons
set userInput to do shell script "/usr/local/bin/dialog --title 'Test Title' --titlefont size=15 --message 'Test Message' --messagefont size=14 --button1text 'Button One' --button2text 'Cancel' --infobuttontext 'Button Two' --width 350 --height 130 --hideicon --moveable; echo $?" --button one returns "0" and button two returns "3"
if userInput is "2" then error number -128

--Timer with one button
set userInput to do shell script "/usr/local/bin/dialog --title 'Test Title' --titlefont size=15 --message 'Test Message' --messagefont size=14 --button1text 'Cancel'  --width 350 --height 150 --hideicon --moveable --timer 8; echo $?"
if userInput is "0" then error number -128

--Text fields
try
	set userInput to do shell script "/usr/local/bin/dialog --title 'Test Title' --titlefont size=15 --message 'Test Message' --messagefont size=14 --button2 --width 320 --height 210 --hideicon --moveable --textfield 'Text One',value='Value One' --textfield 'Text Two',value='Value Two'"
on error
	error number -128
end try
set {TID, text item delimiters} to {text item delimiters, {return, " : "}} --use whatever approach desired
set theTextItems to text items of userInput
set variableOne to item 2 of theTextItems --> "Value One"
set variabletwo to item 4 of theTextItems --> "Value two"
set text item delimiters to TID

The following is an example of a swiftDialog that contains both text fields and check boxes and that uses ASObjC to parse the dialog output:

use framework "Foundation"
use scripting additions

set {searchString, replaceString, searchOption, wordOption, caseOption} to displayDialog()

on displayDialog()
	try
		set userInput to do shell script "/usr/local/bin/dialog --title none --message '' --messagefont size=14 --button2 --width 320 --height 230 --hideicon --moveable --textfield 'Search String',prompt='search for…' --textfield 'Replace String',prompt='replace with…' --checkbox 'Search Entire Script' --checkbox 'Match Whole Words Only' --checkbox 'Make Search Case-Sensitive' --vieworder 'textfield, checkbox'"
	on error
		error number -128
	end try
	set userInput to current application's NSMutableString's stringWithString:userInput
	(userInput's replaceOccurrencesOfString:"(?m)^.* : (.*)$" withString:"$1" options:1024 range:{0, userInput's |length|()})
	return (userInput's componentsSeparatedByString:return) as list
end displayDialog

The swiftDialog app can do a lot of other stuff. I use the following to view markdown tables:

set theFile to POSIX path of (choose file of type {"md"})
do shell script "/usr/local/bin/dialog --title 'Markdown Table Viewer' --titlefont 'size=16' --message " & quoted form of theFile & "  --messagefont 'size=14' --hideicon --position top --windowbuttons --moveable"

BTW, the swiftDialog PKG installer contains 7 MB and the installed executable contains 2 KB. Also, a Dialog folder is created with an application file containing 17.1 MB and a small log file. Other files may be created.

I thought I would add a few miscellaneous notes on issues that I have not been able to resolve. Two of these items are discussed as a known issue and a requested enhancement on the developer’s GitHub site:

  • A font name cannot be set for a dialog message, although font size and color work as expected (known issue).

  • Stdout is not returned when an infobutton is selected. This means that the result returned by textfields, checkboxes, and the like cannot be processed when an infobutton is selected.

  • An AppleScript display dialog dialog expands and contracts to accommodate the specified text message, but a swiftDialog does not.

  • When a dialog contains a textfield, the width of the box in which the text is entered is truncated at about half the width of the entire field (requested enhancement).

JSON can be used to set swiftDialog options (documentation here). For example:

set theJSON to "{ \"title\" : \"Test Title\", \"titlefont\" : \"colour=blue,size=16\", \"message\" : \"Test Message\",  \"messagefont\" : \"size=14\", \"button2\" : true, \"width\" : 350, \"height\" : 130, \"hideicon\" : true}"
set userInput to do shell script "/usr/local/bin/dialog --jsonstring " & quoted form of theJSON & "; echo $?"
if userInput is "2" then error number -128

The JSON options can be set one per line, but the line endings must be a return.

I made a version that uses an AppleScript list that get converted to json string.

set theJSONList to {"title", "Test Title", "titlefont", "colour=blue,size=16", "message", "Test Message", "messagefont", "size=14", "button2", true, "width", 350, "height", 130, "hideicon", true}
set theJSON to get_JSON(theJSONList)
set userInput to do shell script "/usr/local/bin/dialog  --jsonstring " & quoted form of theJSON & "; echo $?"
if userInput is "2" then error number -128

on get_JSON(JSONList)
	local tid, JSON_string
	set JSON_string to {}
	repeat with i from 2 to count JSONList by 2
		if class of item i of JSONList is text then
			set end of JSON_string to "\"" & item (i - 1) of JSONList & "\" : \"" & item i of JSONList & "\""
		else
			set end of JSON_string to "\"" & item (i - 1) of JSONList & "\" : " & (item i of JSONList) as text
		end if
	end repeat
	set tid to text item delimiters
	set text item delimiters to ", "
	set JSON_string to ("{ " & JSON_string as text) & " }"
	set text item delimiters to tid
	return JSON_string
end get_JSON
1 Like

I thought I would add simple examples of dropdown lists and radio buttons:

# Dropdown Lists
try
	set userInput to do shell script "/usr/local/bin/dialog --title 'Test Title' --titlefont 'size=15' --message 'Test Message' --messagefont 'size=14' --button2 --width 350 --height 210 --hideicon --selecttitle 'Subtitle 1' --selectvalues 'Item 1,Item 2, Item 3' --selectdefault 'Item 1' --selecttitle 'Subtitle 2' --selectvalues 'Item 1,Item 2, Item 3' --selectdefault 'Item 1'"
on error
	error number -128
end try

# Radio Buttons
try
	set userInput to do shell script "/usr/local/bin/dialog --title 'Test Title' --titlefont 'size=15' --message 'Test Message' --messagefont 'size=14' --button2 --width 350 --height 250 --hideicon --selecttitle 'Test Radio buttons',radio --selectvalues 'Item 1,Item 2, Item 3' --selectdefault 'Item 1'"
on error
	error number -128
end try

A screenshot of the dropdown list: