- Modules
- Harmony Scripting Resources
- Activity 1: Creating a Simple Script
Activity 1: Creating a Simple Script
T-HSCP-001-005
In this topic, you will see how to write a simple script for Harmony. From this point forward, you will be then be able to explore and practice scripting in Harmony. Once you feel ready and comfortable working with the Toon Boom scripting API, you can move on to the next module about Master Controllers.
To create your scripts, you can either use your favourite external scripting editor or use the Script Editor window in Harmony. Make sure to also keep handy the Toon Boom API scripting resources.
*.xstage
file. When opening the file in a text or script editor, you can see all layers, nodes, values, and parameters used in the project. When looking for a specific value, you can add a layer or node in your project, set the parameter in the UI and save the project. Following the save operation, you can then open the *.xstage
file in your text editor and look at all the provided values.In this exercise, you will learn to write a script to create 4 drawing layers and connected them to an existing Composite node. This will require you to access the selection information, get the position of the selected instance, add new nodes, find the string matching the node type, and link nodes.
Material
To complete this topic, you will need the following from the sample material you downloaded:
- MO-HSCP-001/Create_Drawing_Nodes.js
- MO-HSCP-001/Create_Drawing_Nodes-Composite-Validation.js
How to write a script to add Drawing nodes and link them to a Composite node
- Create a blank Harmony project containing only the default Drawing, Composite, Display, and Write nodes.
- Open the Script Editor view or your favourite external editor. If you are using an external editor, link it to the Script Editor view.
- In the Script Editor View menu, select File > New Script.
- In the New Script dialog box, name your new script
Create_Drawing_Nodes
. - In the Script Editor script list, select your new script.
- Create the
createDrawingNodes()
function, by typing:
function createDrawingNodes() { }
- Since the script will work based on a selection, the first information to get is the node selection using the
selection
class. It requires to use the following two public slots. You can read more about them in the scripting API references.numberOfNodesSelected
()selectedNode
(int i)
- Type the following code in your function to get the number of nodes selected and to loop through these nodes to access the specific parameters for each instance in the loop.
function createDrawingNodes()
{
var selectedNodes = selection.numberOfNodesSelected();
for(var n = 0; n < selectedNodes; n++){
var currentNode = selection.selectedNode(n);
}
}
- To make sure there is only one node selected, add a condition making sure
selectedNodes()
is equal to1
or else return a warning message with theMessageBox
class to only select one node. Later on, you can decide to also validate that the selected node is of Composite type.
function createDrawingNodes()
{
var selectedNodes = selection.numberOfNodesSelected();
if(selectedNodes == 1){
for(var n = 0; n < selectedNodes; n++){
var currentNode = selection.selectedNode(n);
}
}else{
MessageBox.information("You must select only 1 Composite node.");
}
}
- Press the Script Editor view Save button.
- Once you have access to the currently selected node, you can then use the
node
class to affect it or gain information from it. Using thecoordX()
andcoordY()
functions in thenode
class, you will get the X and Y position of the selected node in the Node view. You will be able to use this information to position your new nodes not too far from the selected Composite node.
function createDrawingNodes()
{
var selectedNodes = selection.numberOfNodesSelected();
if(selectedNodes == 1){
for(var n = 0; n < selectedNodes; n++){
var currentNode = selection.selectedNode(n);
var posX = node.coordX(currentNode);
var posY = node.coordY(currentNode);
}
}else{
MessageBox.information("You must select only 1 Composite node.");
}
}
- Now that you have the information of your selected node, you can now create new drawing nodes and link them to your selected Composite. To add new nodes, the fasted and most efficient way to do so is by using a loop. In this loop, we will add 4 new drawing nodes. Create the loop after the coordinate information.
function createDrawingNodes()
{
var selectedNodes = selection.numberOfNodesSelected();
if(selectedNodes == 1){
for(var n = 0; n < selectedNodes; n++){
var currentNode = selection.selectedNode(n);
var posX = node.coordX(currentNode);
var posY = node.coordY(currentNode);
w
for(var i = 0; i < 4; i++){
}
}
}else{
MessageBox.information("You must select only 1 Composite node.");
}
}
- To add a new node, you need to use the
add()
function from thenode
class:add (String parentGroup, String name, String type, int x, int y, int z)
. The first argument is the group in which to add the node. For this, you will need to get the group information in which your selected Composite is. The second argument is the name to give to the node. The third argument is the type of node to add. Here, you will be adding drawing nodes. Drawing node have a particular type string. This is where you will use the*.xstage
file information to find it. and finally, the last arguments are for coordinates. We will use theposX
andposY
values as reference. Let's start with writing theadd
function and inserting the arguments we know. Based on the selected Composite coordinates, you can use the looping value to increment the X value and increase the Y to be above the composite.
function createDrawingNodes()
{
var selectedNodes = selection.numberOfNodesSelected();
if(selectedNodes == 1){
for(var n = 0; n < selectedNodes; n++){
var currentNode = selection.selectedNode(n);
var posX = node.coordX(currentNode);
var posY = node.coordY(currentNode);
for(var i = 0; i < 4; i++){
var newNode = node.add("", "drawing_" + (i + 1), "", posX + (120 * i), posY + 100, 0);
}
}
}else{
MessageBox.information("You must select only 1 Composite node.");
}
}
- You can get the group information from your selected node using the
parentNode()
function.
function createDrawingNodes()
{
var selectedNodes = selection.numberOfNodesSelected();
if(selectedNodes == 1){
for(var n = 0; n < selectedNodes; n++){
var currentNode = selection.selectedNode(n);
var posX = node.coordX(currentNode);
var posY = node.coordY(currentNode);
for(var i = 0; i < 4; i++){
var newNode = node.add(node.parentNode(currentNode), "drawing_" + (i + 1), "", posX + (120 * i), posY + 100, 0);
}
}
}else{
MessageBox.information("You must select only 1 Composite node.");
}
}
- Finally, to get the last argument about the node type, you need to open the project
*.xstage
file and look at the module elements. You will see a type argument. Some modules are typeCOMPOSITE
,DISPLAY
,WRITE
, orREAD
. If you add more nodes to your Node view such as effects, mode types will appear in the*.xstage
file. Since the backend information doesn't always match the user interface strings, it's always important to verify it. The drawing node type isREAD
.
function createDrawingNodes()
{
var selectedNodes = selection.numberOfNodesSelected();
if(selectedNodes == 1){
for(var n = 0; n < selectedNodes; n++){
var currentNode = selection.selectedNode(n);
var posX = node.coordX(currentNode);
var posY = node.coordY(currentNode);
for(var i = 0; i < 4; i++){
var newNode = node.add(node.parentNode(currentNode), "drawing_" + (i + 1), "READ", posX + (120 * i), posY + 100, 0);
}
}
}else{
MessageBox.information("You must select only 1 Composite node.");
}
}
- Press the Script Editor view Save button.
- Next, to link the new nodes to the selected Composite, you need to use the
link()
function:link (String srcNode, int srcPort, String dstNode, int dstPort)
. This function requires the source node, which port number to connect from, the destination node, and which port number to connect it in.
function createDrawingNodes()
{
var selectedNodes = selection.numberOfNodesSelected();
if(selectedNodes == 1){
for(var n = 0; n < selectedNodes; n++){
var currentNode = selection.selectedNode(n);
var posX = node.coordX(currentNode);
var posY = node.coordY(currentNode);
for(var i = 0; i < 4; i++){
var newNode = node.add(node.parentNode(currentNode), "drawing_" + (i + 1), "READ", posX + (120 * i), posY + 100, 0);
node.link(newNode, 0, currentNode, 0);
}
}
}else{
MessageBox.information("You must select only 1 Composite node.");
}
}
- At this point, the script is functional, but if you undo the action, you will have to undo the link and additional of every single node, which can be taxing. You can use the
beginUndoRedoAccum()
andendUndoRedoAccum()
functions in thescene
class to undo the entire list of operations in one action.
function createDrawingNodes()
{
var selectedNodes = selection.numberOfNodesSelected();
if(selectedNodes == 1){
scene.beginUndoRedoAccum("Create Drawing Nodes");
for(var n = 0; n < selectedNodes; n++){
var currentNode = selection.selectedNode(n);
var posX = node.coordX(currentNode);
var posY = node.coordY(currentNode);
for(var i = 0; i < 4; i++){
var newNode = node.add(node.parentNode(currentNode), "drawing_" + (i + 1), "READ", posX + (120 * i), posY + 100, 0);
node.link(newNode, 0, currentNode, 0);
}
}
scene.endUndoRedoAccum();
}else{
MessageBox.information("You must select only 1 Composite node.");
}
}
- Press the Script Editor view Save button.
- You can add comments to your script to remember what the various lines of code do using // at the beginning of the line.
- Execute your script, either by using the Run button or importing it in the Scripting toolbar.
- Now that you are more familiar with scripting in Harmony, try to add a second condition validating if the type of the selected node is indeed a composite.
Time Estimated 45 mins
Difficulty Level Advanced
Topics List
- About Scripting
- Scripting Reference
- Creating Qt Scripts
- Debugging Qt Scripts
- Importing Scripts
- Using External Script Editors
- Activity 1: Creating a Simple Script
Support
Help and FAQ
Toon Boom Forum
Contact us