ScriptUI programming model¶
ScriptUI defines Window
objects that represent platform-specific windows, and various control elements
such as Button
and StaticText
, that represent user-interface controls. These objects share a common set
of properties and methods that allow you to query the type, move the element around, set the title,
caption or content, and so on. Many element types also have properties unique to that class of elements.
Creating a window¶
ScriptUI defines the following types of windows:
Modal dialog box: Holds focus when shown, does not allow activity in other application windows until dismissed.
Floating palette: Also called modeless dialog, allows activity in other application windows. (Adobe Photoshop® does not support script creation of palette windows.)
Main window: Suitable for use as an application’s main window. (Main windows are not normally created by script developers for Adobe applications. Photoshop does not support script creation of main windows.)
To create a new window, use the Window
constructor function. The constructor takes the desired type of
the window. The type is "dialog"
for a modal dialog, or "palette"
for a modeless dialog or floating
palette. You can supply optional arguments to specify an initial window title and bounds; or you can set
the location and size separately.
The following example creates an empty dialog with the variable name dlg, which is used in subsequent examples:
// Create an empty dialog window near the upper left of the screen
var dlg = new Window( "dialog", "Alert Box Builder" );
dlg.frameLocation = [ 100, 100 ];
Initially, new windows are hidden. The show method makes them visible and responsive to user interaction; for example:
dlg.show();
Container elements¶
All Windows are containers-that is, they contain other elements within their bounds. Within a Window, you can create other types of container elements: Panels and Groups. These can contain control elements, and can also contain other Panel and Group containers. However, a Window cannot be added to any container.
A
Group
is the simplest container used to visually organize related controls. You would typically define a group and populate it with related elements, for instance an edittext box and its descriptive statictext label.A
Panel
is a frame object, also typically used to visually organize related controls. It has a text property to specify a title, and can have a border to visually separate the collection of elements from other elements of a dialog.A
TabbedPanel
is a frame that contains only Tab elements. Each Tab is a frame with a localizable title in the selection tab, which contains a set of controls. When a tab is active, the Tab object is the value of the TabbedPanel.selection property.
You might create a Panel
and populate it with several Groups
, each with their own elements. You can
create nested containers, with different layout properties for different containers, in order to define a
relatively complex layout without any explicit placement.
You can add elements to any container using the add method (see Adding elements to containers). An element added to a container is considered a child of that container. Certain operations on a container apply to its children; for example, when you hide a container, its children are also hidden.
Window layout¶
When a script creates a Window
and adds various user-interface elements to it, the locations and sizes of
elements and spacing between elements is known as the layout of the window. Each user-interface
element has properties which define its location and dimensions: location
, size
, and bounds
. These
properties are initially undefined, and a script that employs Automatic layout should leave them
undefined for the main window as well as its contained elements, allowing the automatic layout
mechanism to set their values.
Your script can access these values, and (if not using auto-layout) set them as follows:
The
location
of a window is defined by aPoint
object containing a pair of coordinates (x
andy
) for the top left corner (the origin), specified in the screen coordinate system. The location of an element within a window or other container is defined as the origin point specified in the container’s coordinate system. That is, the x and y values are relative to the origin of the container. The following examples show equivalent ways of placing the content region of an existing window at screen coordinates [10, 50]:win.location = [ 10, 50 ]; win.location = { x: 10, y: 50 }; win.location = "x:10, y:50";
The
size
of an element’s region is defined by aDimension
object containing awidth
andheight
in pixels. The following examples show equivalent ways of changing an existing window’s width and height to 200 and 100:win.size = [ 200, 100 ]; win.size = { width: 200, height: 100 }; win.size = "width:200, height:100";
This example shows how to change a window’s height to 100, leaving its location and width unchanged:
win.size.height = 100;
The
bounds
of an element are defined by aBounds
object containing both the origin point (x
,y
) and size (width
,height
) To define the size and location of windows and controls in one step, use the bounds property.The value of the
bounds
property can be a string with appropriate contents, an inline JavaScriptBounds
object, or a four-element array. The following examples show equivalent ways of placing a 380 by 390 pixel window near the upper left corner of the screen:var dlg = new Window( "dialog", "Alert Box Builder", [ 100, 100, 480, 490] ); dlg.bounds = [ 100, 100, 480, 490 ]; dlg.bounds = { x: 100, y: 100, width: 380, height: 390 }; dlg.bounds = { left: 100, top: 100, right: 480, bottom: 490 }; dlg.bounds = "left:100, top:100, right:480, bottom:490";
The window
dimensions define the size of the content region of the window, or that portion of the window
that a script can directly control. The actual window size is typically larger, because the host platform’s
window system typically adds title bars and borders. The bounds
property for a Window
refers only to its
content region. To determine the bounds of the frame surrounding the content region of a window, use
the Window.frameBounds
property.
Adding elements to containers¶
To add elements to a window
, panel
, or group
, use the container’s add
method. This method accepts the
type of the element to be created and some optional parameters, depending on the element type. It
creates and returns an object of the specified type.
In additions to windows, ScriptUI defines the following user-interface elements and controls:
Panels (frames) and groups, to collect and organize other control types
Push buttons with text or icons, radio buttons, checkbox buttons
Static text or images, edit text
Progress bars, scrollbars, sliders
Lists, which include list boxes, drop-down (also called popup) lists, and tree views. Each item in a list is a control of type
item
, and the parent list’sitems
property contains an array of child items. Tree views can also have collapsiblenode
-type items, which contain child items. You can add list items with the parent’sadd
method.
You can specify the initial size and position of any new element relative to the working area of the parent
container, in an optional bounds
parameter. Different types of elements have different additional
parameters. For elements which display text, for example, you can specify the initial text. See the ScriptUI
Classes dictionary in the ExtendScript Toolkit’s Object Model Viewer for details.
The order of optional parameters must be maintained. Use the value undefined
for a parameter you do
not wish to set. For example, if you want to use automatic layout to determine the bounds, but still set the
title and text in a panel and button, the following creates Panel
and Button
elements with an initial text
value, but no bounds
value:
dlg.btnPnl = dlg.add('panel', undefined, 'Build it');
dlg.btnPnl.testBtn = dlg.btnPnl.add('button', undefined, 'Test');
Tip
This example creates a dynamic property, btnPnl, on the parent window object, which contains the returned reference to the child control object. This is not required, but provides a useful way to access your controls.
A new element is initially set to be visible, but is not shown unless its parent object is shown.
Creation properties¶
Some element types have attributes that can only be specified when the element is created. These are not normal properties of the element, in that they cannot be changed during the element’s lifetime, and they are only needed once. For these element types, you can supply an optional creation-properties argument to the add method. This argument is an object with one or more properties that control aspects of the element’s appearance, or special functions such as whether an edit text element is editable or Read only. See Control object constructors for details.
You can also specify the creation properties for new objects using the resource specification format; for details, see Resource specifications.
All user-interface elements have an optional creation property called name, which assigns a name for identifying that element. For example, the following creates a new Button element with the name ok:
dlg.btnPnl.buildBtn = dlg.btnPnl.add('button', undefined, 'Build', {name:'ok'});
Note
In Photoshop CS, panel coordinates were measured from outside the frame (including the title bar), but in Photoshop CS2, panel coordinates are measured from the inside the frame (the content area). This means that if you use the same values to set the vertical positions of child controls in a panel, the positions are slightly different in the two versions. When you add a panel to a window, you can choose to set a creation property (su1PanelCoordinates), which causes that panel to automatically adjust the positions of its children; see the add method for panel. When automatic adjustment is enabled, you provide position values that were correct for Photoshop CS, and the result is the same in Photoshop CS2, CS3, CS4, CS5, or CC. You can also set automatic adjustment for a window; in this case, it applies to all child panels of that window unless it is explicitly disabled in the child panel. See Window object constructor.
Accessing child elements¶
A reference to each element added to a container is appended to the container’s children
property. You
can access the child elements through this array, using a 0-based index. For controls that are not
containers, the children
collection is empty.
In this example, the msgPnl
panel was the first element created in dlg, so the script can access the panel
object at index 0 of the parent’s children
property to set the text for the title:
var dlg = new Window( "dialog", "Alert Box Builder" );
dlg.msgPnl = dlg.add( "panel" );
dlg.children[ 0 ].text = "Messages";
If you use a creation property to assign a name to a newly created element, you can access that child by its
name, either in the children
array of its parent, or directly as a property of its parent. For example, the
Button
in a previous example was named ok, so it can be referenced as follows:
dlg.btnPnl.children[ "ok" ].text = "Build";
dlg.btnPnl.ok.text = "Build";
You can also access named elements through the parent window’s findElement()
method:
var myOkButton = dlg.findElement( "ok" );
For list controls (type list
and dropdown
), you can access the child list-item objects through the items
array.
Removing elements¶
To remove elements from a Window
, Panel
, or Group
, use the container’s remove
method. This method
accepts an object representing the element to be removed, or the name of the element, or the index of the
element in the container’s children
collection (see Accessing child elements).
The specified element is removed from view if it was currently visible, and it is no longer accessible from the container or window. The results of any further references by a script to the object representing the element are undefined.
To remove list items from a list, use the parent list control’s remove method in the same way. It removes the
item from the parent’s items
list, hides it from view, and deletes the item object.