Pashua 0.11 Documentation

Table of Contents

Introduction

What is Pashua?

Pashua ist a tool for creating native dialog windows on macOS. It can be invoked from the shell / Terminal and therefore is particularly useful for creating GUIs from programming languages that do not offer graphic user interfaces natively, for instance PHP or Python.

Pashua was written by Carsten Blüm and released as Open Source software under the 3-Clause BSD License. Being Open Source, it is of course free to use, but nonetheless, donations are welcome. Pashua’s website is www.bluem.net/en/projects/pashua/.

Usage overview

Creating a dialog

Basically, Pashua is used like many command-line programs: you call it from your application and pass the path to a configuration file as argument (or let Pashua read the configuration string from stdin by passing - as the filename). Pashua will display a dialog that is created according to the description in the configuration file / string, while typically your application will wait for the dialog to close.

Getting values back from Pashua

Pashua will quit when the user clicks the “OK” button (or presses the Return key), clicks the “Cancel” button or hits Escape (provided there is a cancelbutton in the window). In the first case, for every element defined in the dialog configuration, the value is returned. Let’s say, the window contains a textfield named city that holds the string “Hamburg”, then the result (written to stdout by Pashua) would contain a line city=Hamburg. Your application could read Pashua’s output and parse each of the lines to get the value for the element.

In the latter case (“Cancel” button), no values are returned, except the cancel button itself, which is returned as 1. This means: if your configuration string contains a definition like cb.type = cancelbutton and the button will be pressed, then Pashua’s output will contain cb=1.

Using the example scripts

However, you don’t have to deal with calling Pashua and interpreting the result manually – the example scripts included in the distribution do that for you. In most of these scripts, you only have to pass the configuration string to a function or method and that’s it.

Of course, if you have special needs or don’t like the way the example scripts work, you are free to write your own code; it’s completely up to you.

The window configuration

As mentioned above, the dialog window to be created is described in a configuration file or string. For this purpose, Pashua uses a very simple and light-weight configuration syntax which describes the GUI elements to display, their properties (e.g. default values) und their order in the window.

The following part of the documentation will describe the basics of the configuration syntax, the GUI elements available and the attributes that can be set for these elements.

Basic configuration syntax rules

Pashua’s configuration syntax is pretty simple. Basic rules are:

A first example

Let’s have a look at a simple example:

# Add a text field
tx.type = textfield
tx.label = Example textfield
tx.default = Textfield content
tx.width = 310

These lines would simply mean:

The above lines would suffice to display the following window:

Or, if you like to keep things really simple, the dialog configuration …

tx.type = textfield

… would result in this window:

Note: Pashua uses the standard UI elements of the macOS / OS X version on which it is running. All the screenshots in this documentation were taken on macOS 10.12; if, for instance, you would run the examples on OS X 10.9, you would therefore see the older, less flat window and button look.

Window attributes

Window attributes are defined similar to element attributes. The only difference (apart from the fact that of course windows have other attributes than, let’s say, textfields) is the fact that you don’t have to specify an element name before the attribute, but simply an asterisk, for instance *.title = My windowtitle

Window attributes
Name Purpose Required Default
appearance Only allowed value is metal, which will create a “brushed metal” window No -
autoclosetime If set to an integer number larger than 1, the dialog will automatically close after the specified number of seconds have passed. The timer starts in the very moment when Pashua has finished parsing the configuration string and everything is set up. No -
autosavekey Can be used to preserve the window position between launches. To let Pashua differentiate between applications, you have to set this to an arbitrary string. I.e.: one application can set this to “abc” and another one to “def”, and for both applications, the window position will be saved and restored separately. No -
floating Setting floating to 1 will result in the window floating above other windows. No 0
title Sets the window title No Pashua
transparency Sets the window’s transparency, decimal value from 0 (invisible) to 1 (opaque) No 1
x Sets the horizontal position where the window should be opened on the screen (0 is the left border of the screen) No Window will be positioned automatically
y Sets the vertical position where the window should be opened on the screen (0 is the upper border of the screen) No Window will be positioned automatically

Example: Setting window attributes

*.title = A window title
*.transparency = 0.95
*.x = 50
*.y = 60

Element type: button

A button works similar to the default button: when clicked, it closes the window and returns all elements’ values, but additionally, the button’s own value is returned as 1. Buttons (“regular” buttons, not the cancel button or the default button) are always positioned in the lower left area of the window, though you can position them absolutely using attributes x and y

Attributes for elements of type button
Name Purpose Required Default
label Sets the button’s text Yes
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No

Return value: Either 1 (button clicked) or 0 (button not clicked)

Example: Using button

b.type = button
b.label = My button

Element type: cancelbutton

A cancelbutton can be triggered using Escape and closes the window without returning any values, except the cancelbutton’s own variable, which will be returned as 1. The cancel button is always positioned to the left of the default button and can not be moved to any other position.

Attributes for elements of type cancelbutton
Name Purpose Required Default
label Sets the button title No Depends on the localization.
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No

Return value: Either 1 (button clicked / user pressed Escape / user pressed Cmd-W) or 0 (button not clicked)

Example: Using cancelbutton

cb.type = cancelbutton
cb.label = Close this dialog
cb.tooltip = Closes this window without returning the values entered

Element type: checkbox

Displays a checkbox

Attributes for elements of type checkbox
Name Purpose Required Default
label Creates a label / title next to the checkbox Yes
default Set this to 1 if you want the checkbox to be checked by default. No
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Return value: Either 1 (checkbox checked) or 0 (checkbox not checked)

Example: Using checkbox

chk.type = checkbox
chk.label = If you like, you can use a really long label, as the window will scale accordingly
chk.tooltip = Yes, it’s that simple!

Element type: combobox

A combo box is a combination of a popup menu and a textfield: the user can either choose a value from a list or enter any string.

Attributes for elements of type combobox
Name Purpose Required Default
labelCreates a label above this elementNo
option Adds a value to the list of values. Can (usually should) be used more than once. Yes (one option attribute is required, others are optional)
completion Controls if and how autocompletion is performed. Possible values are 0 (no completion), 1 (completes the first item in the completion list which matches the entered string, case-sensitive), or 2 (ditto, but case-insensitive). No 1
mandatory If set to a true value (everything other than 0, “n”, “no”, empty), input is mandatory. No No
rows If set to an integer > 0, sets the number of visible items/rows. No – (decision left to system)
placeholderIf present, this string will be as the field’s placeholder string.No
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No
width Width in pixels No 200
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Return value: String contents (may be an empty string)

Example: Using combobox

cb.type = combobox
cb.label = My combobox label
cb.default = Gromit
cb.option = Wallace
cb.option = Harold
cb.option = Maude
cb.width = 220
cb.tooltip = Choose from the list or enter another name

Element type: date

The date element lets the user choose a date, a time or both. It can be displayed in textual or graphical style.

Attributes for elements of type date
Name Purpose Required Default
label Sets the date picker’s label (displayed above) No
textual Should the textual display style be used instead of the graphical style? No 0 (No)
date Should the user be able to chose a date? No 1 (Yes)
time Should the user be able to chose the time? No 0 (No)
default Default date and/or time that should be selected when the dialog is opened. The only string format that is guaranteed to work is “yyyy-mm-dd [hh:mm]”, for instance “2011-11-29 12:34” or “2011-11-29”. Other string formats such as “12/24/2004”, “next wednesday” or “tomorrow” may work, too. No Current date and/or time
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
y Absolute vertical position in the window, measured from the lower border of the content area No
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No

Return value: Depends on the values of attributes date and time. If only a date can be selected, it will be a date string in yyyy-mm-dd format, if only a time can be selected, the format will be hh:mm. If both are enabled, you will get a date and time string in yyyy-mm-dd hh:mm format. If you only need part of this information, you have to extract the desired substrings yourself.

Example: Using date

d.type = date
d.label = Example date
d.default = 2017-06-23 14:38
d.time = 1

Element type: defaultbutton

When the default button is pressed, the window is closed and all elements’ values are returned to the calling script. The default button is always located in the lower right corner of the window and can’t be moved to any other position.

A default button is added to each window automatically – you only have to specify it explicitly, if you want to set the label or a tooltip or need the return value (i.e.: has it been clicked?) of this button.

Attributes for elements of type defaultbutton
Name Purpose Required Default
label Sets the button title No OK
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No

Return value: Either 1 (button clicked / user pressed Return) or 0 (button not clicked)

Example: Using defaultbutton

db.type = defaultbutton
db.label = Click here to close the window and save the values

Element type: image

This element displays an image (or a PDF file), optionally scaling it to a maximum width or height. Pashua can handle any image type that is supported by NSImage. This includes TIFF, GIF, JPEG, PNG, PDF, PICT and EPS.

Attributes for elements of type image
Name Purpose Required Default
labelCreates a label above this elementNo
path Filesystem path to the image Yes
border Set this to 1 to display a border for the image No 0
width If this attribute is set to some integer number, the image’s width will be set to this width (including border) No
height If this attribute is set to some integer number, the image’s height will be set to this value (including border) No
maxwidth If this attribute is set to some integer number, the image will be scaled down to this width (including border), if it’s wider No Calculated from window’s width
maxheight If this attribute is set to some integer number, the image will be scaled down to this height (including border), if it’s higher No Calculated from window’s height
upscale Set this to 1 to allow the image to be upscaled (which will only have an effect if setting width or height) No 0
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Please note that you can either specify width/height or maxwidth/maxheight – otherwise, you will get an error.

On the other hand, it is valid to specify only a width without a height or vice versa (and the same is true for maxwidth and maxheight). In this case, Pashua will try to make the best of the situation and either calulcate the missing value based on the image ratio from the given value (if without “max” prefix) or set the missing value based on the main window’s resolution (if with “max” prefix).

Return value: None

Example: Using image

img.type = image
img.label = This is Pashua’s icon, scaled down a little bit
img.path = /Applications/Pashua.app/Contents/Resources/AppIcon.icns
img.maxwidth = 64
img.border = 1

Element type: openbrowser

An openbrowser is used for choosing a filesystem path. It consists of a textfield, a button and (optionally) a label. The textfield holds the actual element value (the file path), while the button (which is localized) is used to invoke a file selector sheet. Moreover, a file can be dragged & dropped onto the textfield.

Attributes for elements of type openbrowser
Name Purpose Required Default
labelCreates a label above this elementNo
width Sets the width (overall width of texfield and button) No 300
default Default path No
filetype File types that can be selected in the open dialog or dropped onto the textfield; takes a space-delimited list of filename extensions (such as jpg gif tif etc.). In addition to filename extensions, you can use directory to let the user choose directories. If only directory is specified, the user won’t be able to choose any files. If only filename extensions are specified, the user won’t be able to choose directories. If you don’t specify filetype at all, the user will be able to choose anything in the open dialog box. No
mandatory If set to a true value (everything other than 0, “n”, “no”, empty), input is mandatory. No No
placeholderIf present, this string will be as the field’s placeholder string.No
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Return value: Full filesystem path for the selected item (may be an empty string)

Example: Using openbrowser

opb.type = openbrowser
opb.label = Please select an image
opb.default = /a/very/long/path/to/a/file.jpg
opb.filetype = jpg tiff tif gif png psd
opb.width = 300

Element type: password

This element is identical to a textfield, except that it hides whatever is typed into it. Moreover, you can’t copy or drag text from a password element.

Attributes for elements of type password
Name Purpose Required Default
label Creates a label/title above this element No
width The textfield’s width in pixels No 200
default The textfield’s initial contents No
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
mandatory If set to a true value (everything other than 0, “n”, “no”, empty), input is mandatory. No No
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Return value: String contents (may be an empty string)

Example: Using password

pw.type = password
pw.label = Please enter your password
pw.default = Secret!
pw.width = 120

Element type: popup

A popup is an element that lets the user choose one value from a list of possible values

Attributes for elements of type popup
Name Purpose Required Default
option Any string that should appear as an entry in the popup, can (and probably should) be used more than once Yes (at least one option is required)
default Default value (should match one of the option attributes No
labelCreates a label above this elementNo
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No
mandatory If set to a true value (everything other than 0, “n”, “no”, empty), input is mandatory. No No
width Width in pixels No 200
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Return value: Selected item as string (may be an empty string)

Example: Using popup

p.type = popup
p.label = Example popup menu
p.width = 310
p.option = Popup menu item #1
p.option = Popup menu item #2
p.option = Popup menu item #3
p.default = Popup menu item #2

Element type: radiobutton

A radiobutton element lets the user choose a value from a pre-defined list of values.

Attributes for elements of type radiobutton
Name Purpose Required Default
labelCreates a label above this elementNo
option Any string that should be used as a selectable value. Should be used more than once. Yes (at least one option is required)
default The value that should be selected by default. Of course, this must be one of the option values to work. No
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No
mandatory If set to a true value (everything other than 0, “n”, “no”, empty), input is mandatory. No No
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Return value: Selected radiobutton’s label as string (may be an empty string)

Example: Using radiobutton

radio.type = radiobutton
radio.label = How would you like your coffee?
radio.option = Black
radio.option = With milk
radio.option = With milk and sugar
radio.option = Only sugar, no milk
radio.default = With milk

Element type: savebrowser

A savebrowser can be used for setting a path and name for a new file. It consists of a textfield, a button and (optionally) a label. The textfield holds the actual element value (the file path and name), while the button (which is localized) is used to invoke a file selector sheet.

Attributes for elements of type savebrowser
Name Purpose Required Default
labelCreates a label above this elementNo
width Sets the width (overall width of texfield and button) No 300
default Default path No
filetype File extension to use for the save dialog box; if this attribute is used, the user will be forced to use that extension for the name No
mandatory If set to a true value (everything other than 0, “n”, “no”, empty), input is mandatory. No No
placeholderIf present, this string will be as the field’s placeholder string.No
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Return value: Full filesystem path (may be an empty string, if no path chosen by user)

Example: Using savebrowser

svb.type = savebrowser
svb.label = Please set the destination path
svb.default = /tmp/foo
svb.filetype = jpg
svb.width = 360

Element type: text

This element displays multi-line, wrapping text. The width of the element does not adapt automatically to the content, but uses the given width (or the default width, if no width is specified.) On the other hand, the height is automatically set to the minimum height needed to display the text using the given (or default) width.

Attributes for elements of type text
Name Purpose Required Default
labelCreates a label above this elementNo
width Sets the width of the text (in pixels) No 280
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No
default The text to display (alias for text). You can use the string [return] to insert a linebreak. Yes (either default or text must be set)
text The text to display (synonym for default). You can use the string [return] to insert a linebreak. Yes (either default or text must be set)
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Return value: None

Example: Using text

txt.type = text
txt.default = Paragraph one, demo text[return][return]Paragraph two

Element type: textbox

A textbox is a scrollable, multi-line text container. The scrollbar will appear automatically if needed. Note: If you have changed the system’s scrollbar behaviour to display both arrows at both ends (e.g. using TinkerTool), the scrollbar might not appear for small heights.

Attributes for elements of type textbox
Name Purpose Required Default
labelCreates a label above this elementNo
width Sets the width of the textbox (in pixels) No 250
height Sets the height of the text (in pixels) No 52
default Sets the initial contents. You can use the string [return] to insert a linebreak. No
fontsize Size of the text inside the textbox. There are three sizes available, which conform to the system’s standard sizes: regular, small, or mini. No regular
fonttype Set this to fixed if the text should be displayed using a monospace font. No
mandatory If set to a true value (everything other than 0, “n”, “no”, empty), input is mandatory. No No
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Return value: String contents (may be an empty string)

Example: Using textbox

tb.type = textbox
tb.default = Line 1[return]Line 2[return]Line 3
tb.width = 300
tb.height = 60

Element type: textfield

A textfield is a simple, one-line text input field with an optional label displayed above the textfield.

Attributes for elements of type textfield
Name Purpose Required Default
labelCreates a label above this elementNo
width The textfield’s width in pixels No 200
default The textfield’s initial contents No
disabled If set to 1, the element will be disabled, so that the default value cannot be changed. No 0
mandatory If set to a true value (everything other than 0, “n”, “no”, empty), input is mandatory. No No
placeholderIf present, this string will be as the field’s placeholder string.No
tooltipString to use as tooltip for the button. Use \n to insert a linebreak.No
xAbsolute horizontal position in the window, measured from the left border of the content areaNo
yAbsolute vertical position in the window, measured from the lower border of the content areaNo
relxHorizontal offset, relative to the position the element would have if relx was not used (e.g.: relx specifies the distance from the left window border). Any integer can be used as relx value.No0
relyRelative vertical distance to the next element below (“relative” means that the value is added to the default distance). Any integer larger than -20 can be used as rely value.No0

Return value: String contents (may be an empty string)

Example: Using textfield

txf.type = textfield
txf.label = Enter placeholder text
txf.default = Lorem ipsum dolor sit amet
txf.width = 300

FAQ

I can’t open Pashua, as it is from an “unidentified developer”

If your Mac tells you that Pashua cannot be opened, as it is an application by an unidentified developer, this is nothing to worry about. On my website, you can find more detailed information on this, but the short summary is: simply use the contextual menu (right-click or Ctrl-clic on Pashua’s icon), then choose item “Open” and confirm that you want to open it.

What is new in version [XY]?

Please take a look at the version history.

What text encodings does Pashua support?

For some time, Pashua had offered specifying the text encoding of the configuration string, as there were languages which had limited or no support for UTF-8. Today, UTF-8 is ubiquitous, so this option was removed. Pashua will auto-detect the encoding of a configuration file and return the values in the same encoding. This implies that command-line option -e, which was used to set the encoding, is now completely ignored. Please note: Guessing the encoding only works with configuration files. If you pass the configuration via STDIN, Pashua will expect it to be UTF-8.

How can I dynamically configure a dialog at runtime?

The dialog configuration which is passed to Pashua is a string. Often, this string will be static, but sometimes it can be useful or necessary to have either dynamic parts in it or even completely construct it at runtime. A simple example would be a tool which, for some reason, contains a date field which should be pre-filled with the current date. Let’s imagine that this tool is based on a Bash script – this script could get the date from the date command-line tool and save it in a variable using TODAY=$(date '+%Y-%m-%d') and then insert it into the dialog configuration, using something like datefield.default ${TODAY}. This is only a very simple example, but hopefully you get the point: Pashua does not care how the dialog configuration string was created – it only has to fulfill the syntax rules. Pashua will not even know if the configuration is static or if and how it was created at runtime.

If you take a look at the example scripts, you will see that they make use of dynamic configuration strings: Pashua’s icon is added to the example dialog, and this is done by locating the path to Pashua.app at runtime and deriving the icon’s path from that location.

How does Pashua handle mandatory fields?

Some of the element types (those for which it makes sense) can be defined as mandatory. This means that the dialog cannot be closed as long as the element is empty. Here, “empty” means that the element does not have a string value or that the string value contains only whitespace; the digit zero (0) is not regarded as empty. Radio buttons are regarded as empty as long as none of the buttons has been clicked.

This screenshot shows visual marker which is displayed next to a mandatory element when the “OK” button is clicked:

Can I localize my Pashua-based application?

Pashua itself is localized in English, German and French. The localizations are used for the menu bar, the application about box, button titles ( defaultbutton, cancelbutton, savebrowser and openbrowser buttons) and of course for error messages. It’s your application’s responsibility to provide localization by passing an appropriate configuration string to Pashua for anything else that should be localized. Hint: if you want to build a multi-language application and need to detect the user’s preferred language from the shell, you can use defaults read -g AppleLocale

How do I display 2 or more windows one after another?

You can call Pashua multiple times, but this will result in successive application launches (with the icon moving in and out of the Dock), which is annoying. Hiding the Dock icon helps a lot in this case, but it’s only a remedy – not a real solution.

When will Pashua support multiple checkboxes/radiobuttons…?

You can use any GUI element as often as you like; the only exceptions are the cancelbutton and the defaultbutton. You only have to make sure that the names are unique:

chk1.type = checkbox
chk1.label = Checkbox 1

chk2.type = checkbox
chk2.label = A second checkbox

chk3.type = checkbox
chk3.label = Checkbox #3

When will Pashua support programming language [XY]?

The question is not, when Pashua will support the programming language, but rather vice versa. Pashua does not care (and does not even know) from which programming language it was invoked. It gets a dialog configuration, it does its job, it returns the resulting values and quits. That’s all. Basically you can use Pashua from any language that is able to write a file or write to a Unix pipe, call an application with command line arguments, manipulate strings and declare variables dynamically or handle associative arrays. If code for your favourite language is not included in the Pashua distribution or in the Pashua Bindings Repository, simply go ahead and write the code yourself.

May I distribute applications based on Pashua?

Starting with version 0.11, Pashua is Open Source Software, licensed under the 3-Clause BSD License. As long as you comply with the license, any usage of the source code, part of the source or use (including redistribution) of the compiled binary is permitted.

When will Pashua support progress bars?

Progress bars are a UI element I am asked for regularly. The problem with progress bars is that they conceptually differ from Pashua’s approach. When Pashua gets a dialog description and puts the dialog on screen, it is in control and runs independently from the process from which it was started. A progress bar, on the other hand, would require continuous (or at least periodic) interaction with that process, as Pashua would need to receive updates – at the very least least to be informed when the operation which the progress bar represents has been finished, or maybe also to display the current length of the bar, in case it is a determinate progress indicator.

As you can see, the “Fire and forget” approach and the “Start and control Pashua” approach are two different kettles of fish, and this is why progress bars won’t be needed in the foreseeable future. If you really need a progress bar and you need it now, you can still use cocoaDialog.

How can I hide the dock icon?

Most Cocoa applications can be modified so that the Dock icon and the application-specific menu bar are hidden – and Pashua is no exception to this rule. You can achieve this by opening the file Info.plist inside Pashua’s application bundle and changing the line below the one containing LSUIElement from <false/> to <true/>. If you don’t notice any change in Pashua’s behaviour, you should log out and back in.

Can I build “real” applications with Pashua?

Native OS X applications are nothing like folders with a name that ends with “.app” (invisible in the Finder by default) and that have a specific directory structure in them. You can examine such a folder (called an “application bundle”) by context-clicking on the name and choosing the appropriate option from the contextual menu (in English it is “Show Package Contents”, in German it is “Paketinhalt zeigen”).

As a starting point, an example for a doubleclickable, “real” application with a Pashua GUI is provided. When you play around with the application bundle, there are a few things to keep in mind:

What does “Pashua” mean?

Naming things is not easy, and while searching for a name, at some point I started to play around with acronyms from “Perl”, “and”, “shell” (actually, at the beginning – 2003 – I only thought of Perl and shell scripts) and “UI” – and eventually came up with “Pashua”. So, basically, it does not mean anything.

Version information

Pashua 0.11 was released on 04/14/2018.

For information on changes and the complete version history, please take a look at the website.