You can customize the Shogun Post user interface by creating user windows that contain specified tools and commands.
Creating user windows to execute scripts can be useful in these circumstances:
- As you work, you'll develop tools and routines that you use frequently. Turning these tools into user windows makes them easier and faster to use.
- If you train, support, or work with other motion capture pros, creating custom user windows can accelerate production dramatically. Putting the tools people use most often at their fingertips, and ensuring everyone uses the same tools, saves time and money.
Any user windows you create in Shogun Post are just like the Shogun Post panels (docking windows) with the following exceptions:
- Their docking information is not saved when Shogun Post shuts down. They must be recreated from a script every time Shogun Post restarts or any time they get destroyed.
- They appear separately from the standard Shogun Post panels. They are appended as a new custom windows group to the end of the Panels tab on the ribbon.
User windows can hold any number of controls, the standard UI components you are familiar with, such as:
- text boxes
- check boxes
- list boxes
- number fields
All user controls are children of the user window they appear on. You can't parent a control to another control.
The following topics describe how to create user windows to run scripts:
If you are comfortable creating scripts, creating your own user windows is straightforward.
Create user windows and controls
All user windows and controls are identified by an integer value, called a handle. Shogun Post returns this handle whenever a user window or control gets created. This lets Shogun Post keep track of which window is accepting input from a user, and which control is being changed.
Save the handles associated with a window or control in int variables, and in your .ini file if you plan to call the window or control from any script other than one that created it.
The handle is an argument to almost every command in the user window category. For instance, to create a user window with a text box in it, you would write the following script:
// Variables to hold the handles
// Create the user window. Call it "Test User Window"
$dlg = `createWindow "Test User Window"`;
// Create the Text Box User Control, adding it to the
// User Window we just created
$textBox = `createTextBox $dlg`;
That's all that needs to be done to create a user window and add a control to it. Of course, to get any real functionality from the controls, you'll need to add a lot more scripting code.
Notice that the first argument or parameter required by the createTextBox command was the $dlg variable which stores the handle for the window. The $dlg variable tells the createTextBox command which user window to add the text box to.
The following commands provide functionality that is common to all user controls:
For instance, showControl accepts as its first argument a handle for any user control, and it will show/hide/toggle any user type of user control.
Some controls (list boxes, drop lists, number boxes, etc.), have no functional use for setControlText. But for those controls, there are other commands that take its place. For instance, a number box doesn't really have text that is of any concern to the user. It is just the number value held in the control that the user wants. So instead of using getControlText/setControlText with those, you can just use getNumBoxNum/setNumBoxNum.
User windows and controls have scripts that get called when some event happens; these scripts are called "handlers".
For example, user windows have handlers for when the user changes the size of the window, when the user presses the Enter key when typing in a control in the window, or when the window receives an update notification from Shogun Post.
User controls all have handlers for events specific to their functionality. For instance, a drop list control has a selection changed handler that can get called any time the user changes what is selected in the list.
You can set the handler for this event by calling:
|is the ID of a list box you created|
|is the event you want to set a handler to|
|is the name of your script (which must exist in your Scripts directory) that is called any time the list box selection changes.|
These handlers are where you handle a lot of your interaction with the controls. For instance, in a user window, to accept customizable values for a bodyCleaner script, you might have a push button called "Run". You can set a handler for when that button gets clicked.
When it does, your handler script can suck values from all the other controls in the user window and use them in the bodyCleaner script.
Thus, you create a more user-friendly front end to the complex data manipulation scripts that you write.
Lay out windows and controls
Shogun Post uses a framework to allow controls to be placed and sized for whenever a user window is rescaled. This framework lets you keep sets of related controls together, and stretch controls to fit between the walls of other user controls or windows.
The "form" user control can be created just like any other user control. A form, however, is invisible. It has no visual representation other than the invisible rectangle which it occupies. A form is really a container for other controls that wish to be sized/placed relative to it. Controls can get added as sub items, or children, of a form.
Each user window has a form called its top-level form, to which all other controls can be added. The top-level form is sized to the inner rectangle of the user window whenever the window changes. Thus, if you want controls to be aligned to the walls of the user window, create them as components of the top-level form of their user window, as shown in the following example.
// Variables to hold the handles int $dlg; int $textBox; int $parentForm; // This is the 4-element integer array, which represents the // four corners of a rectangle which we'll use to size and // place the controls. // $rect[ 0 ] <--- LEFT // $rect[ 1 ] <--- TOP // $rect[ 2 ] <--- RIGHT // $rect[ 3 ] <--- BOTTOM int $rect[ 4 ]; // Create the user window. Call it "Test User Window" (can't be the // same as any other docking windows) $dlg = `createWindow "Second Test Window"`; // Get a handle to the main user windows main layout form. All controls // will be descendants of this and will be placed/sized relative to it. $parentForm = `getTopLevelForm $dlg`; // Create a static text box. Make it 80 pixels wide and 20 pixels high. // Make it a sub-component of the user windows top level Form. $rect[ 0 ] = 0; $rect[ 2 ] = 80; $rect[ 1 ] = 0; $rect[ 3 ] = 20; int $static = `createStaticBox $dlg -form $parentForm -pos $rect -text "Enter Text Here:"`; // Align 10 pixels from top side of the top level form, which in this // case, is also the wall of the user window setControlAnchor $static "top" "top" 10; // Align 10 pixels from left side of the top level form, which in this // case, is also the wall of the user window setControlAnchor $static "left" "left" 10; // Create a text box and also add it as a sub item of the Top Level // Form. Have its top aligned with the top of the static text, and make // it stretch from the right of the static text to the edge of the form. $textBox = `createTextBox $dlg -form $parentForm`; setControlAnchor $textBox "top" "top" 0 -target $static; setControlAnchor $textBox "left" "right" 5 -target $static; setControlAnchor $textBox "right" "right" 10; // Finally, lay out all the controls with the anchors we added earlier layoutForm $parentForm;
In the example above, you create the user window and then have a handle to its top-level form. We stored the handle in a variable called
$parentForm. Every time we created a control and wanted it to be sub item of the top-level form, we just added the
-form option to the
createXxxxx command which takes a form user control's ID as an argument. Then we called
setControlAnchor which sets the anchors for a control to the side of a form, or optionally, to the side of another target control.
The setControlAnchor command takes these four arguments:
- The control you wish to act on
- A string of which side of the control you want to be anchored
- The side of the parent form you wish to be anchored to This value should always be the same as the first if you are not targeting another control.
- An offset value which is in pixels, unless you specify the
-percentflag, in which case it gets interpreted as a percent value (which must be positive if it's a percentage).
-target flag allows you to specify another control's side to anchor to. So you can anchor the right side of the control to the left side of another control. Note that you can't anchor the top or bottom of a control to the left or right of another: that doesn't make any sense.
Also, forms can contain other forms, so you can, if you want, create a whole hierarchy of forms and controls. A couple of important notes about forms:
- When you call showControl or enableControl on a form, all sub components of the form get shown/hidden or enabled/disabled along with the form. So, for example, you have a group of controls that you want to hide all at once and are all placed relative to each other, just make them components of a form that itself is a sub component of the top-level form.
- Group boxes are not just user controls; they are also forms. Group boxes are the controls that look like rectangles with a text label on the top left. They have no real functionality other than visually demarcating groups of other controls. So, they are really just forms, and we made them such. But remember that forms are really just controls with extended functionality.