Interface Maker

Anyone, especially newbies, asking for help with Photoshop Scripting and Photoshop Automation - as opposed to those contributing to discussion about an aspect of Photoshop Scripting

Moderators: Tom, Kukurykus

didakov88
Posts: 3
Joined: Sun Sep 25, 2016 7:11 pm

Interface Maker

Post by didakov88 »

Hi guys,
I definitely need help on this one because I`m out of ideas how to accomplish the task.
This script is supposed to generate/read the code for user interface.
The load button doesn`t works for now but that wouldn`t be that hard to figure out.
What bugs me more is that different UI elements have different number of arguments when created (added) and each argument can be different datatype and I can`t seem to structure my thougths on how to solve this.
Bugs:
1.Sometimes when the user inputs params the data is not updated in treeArray.
2.DropDowns on the right don`t seem to update properly.
3.Enabling/Disabling dropDowns doesn`t works.

Any help on how to optimize the code and solve the bugs would be appreciated.

Code: Select all


//Array to display the elements in the elements dropdownlist
var elString = "Window,Panel,Group,StaticText,EditText,Button,IconButton,Image,Checkbox,RadioButton,Slider,Scrollbar,ListBox,DropDownList,TreeView";
var elArray = elString.split ( "," );

var propString = "add,preferredSize,orientation,alignment,alignChildren,spacing";
var propArray = propString.split ( "," );

var alignString = "left,right,center,top,bottom,fill";
var alignArray = alignString.split ( "," );

var orientString = "row,column,fill";
var orientArray = orientString.split ( "," );

//========================================================================
// BUILDING THE INTERFACE
//========================================================================
//{
var w = new Window ( 'dialog', "Interface Maker", undefined );

filePanel = w.add ( 'panel', undefined, 'File' );
filePanel.orientation = "row";
filePanel.alignment = "fill";

//newFile = filePanel.add ( 'button', undefined, 'New File...' );
loadFile = filePanel.add ( 'button', undefined, 'Load File...' );
fileName = filePanel.add ( 'statictext', undefined, '...' );
fileName.alignment = "right";
//fileName.alignment = "right";

//Panel for creating new elements
mainPanel = w.add ( 'panel', undefined, 'Objects' );
mainPanel.orientation = "row";
mainPanel.alignment = "fill";
mainPanel.alignChildren = "fill";

newGroup = mainPanel.add ( 'group', undefined );
newGroup.orientation = "column";
newGroup.alignChildren = "center";
newGroup.spacing = 5;
newText = newGroup.add ( 'statictext', undefined, "New" );
newList = newGroup.add ( 'dropdownlist', undefined, elArray );
newList.preferredSize = [ 150, 20 ]
newList.selection = 1;
newAdd = newGroup.add ( 'button', undefined, "Add" );
newAdd.preferredSize = [ 150, 20 ];
newRemove = newGroup.add ( 'button', undefined, "Remove" );
newRemove.preferredSize = [ 150, 20 ];

childGroup = mainPanel.add ( 'group', undefined );
childGroup.orientation = "column";
childGroup.alignChildren = "center";
childGroup.spacing = 5;
childText = childGroup.add ( 'statictext', undefined, "Child Elements" );
childTree = childGroup.add ( 'treeview', undefined );
childTree.preferredSize = [ 300, 400 ];
childTree.add ( "node", "Window; Window_1" );

nameGroup = mainPanel.add ( 'group', undefined );
nameGroup.orientation = "column";
nameGroup.alignChildren = "center";
nameGroup.spacing = 5;
nameText = nameGroup.add ( 'statictext', undefined, "Var Name" );
nameEdText = nameGroup.add ( 'edittext', undefined, "Window_1" );
nameEdText.preferredSize = [150, 20];
stParam1 = nameGroup.add ( 'statictext', undefined, "Parameter 1" );
edParam1 = nameGroup.add ( 'edittext', undefined, "" );
edParam1.preferredSize = [150, 20];
edParam1.enabled = false;
stParam2 = nameGroup.add ( 'statictext', undefined, "Parameter 2" );
edParam2 = nameGroup.add ( 'edittext', undefined, "" );
edParam2.preferredSize = [150, 20];
stParam3 = nameGroup.add ( 'statictext', undefined, "Parameter 3" );
edParam3 = nameGroup.add ( 'edittext', undefined, "" );
edParam3.preferredSize = [150, 20];
orientText = nameGroup.add ( 'statictext', undefined, "Orientation", {name: "orientation"} );
orientList = nameGroup.add ( 'dropdownlist', undefined, orientArray );
orientList.preferredSize = [ 150, 20 ]
alignText = nameGroup.add ( 'statictext', undefined, "Alignment", {name: "alignment"} );
alignList = nameGroup.add ( 'dropdownlist', undefined, alignArray );
alignList.preferredSize = [ 150, 20 ];
alignChildText = nameGroup.add ( 'statictext', undefined, "Align Children", {name: "alignChildren"} );
alignChildList = nameGroup.add ( 'dropdownlist', undefined, alignArray );
alignChildList.preferredSize = [ 150, 20 ];

funcGroup = w.add ( 'group', undefined );
funcGroup.orientation = "row";
funcGroup.alignment = "right";
save = funcGroup.add ( 'button', undefined, 'Save' );
generate = funcGroup.add ( 'button', undefined, 'Generate' );
exit = funcGroup.add ( 'button', undefined, 'Exit' );
//}
//===============================================
// GLOBAL VARIABLES AND FUNCTIONS
//===============================================
//{
var objectProps = {
orientation: orientList,
alignment: alignList,
alignChildren: alignChildList
};


var windowString = "";
var childEl = childTree.items[0];
var dropDownEl = elArray[1];
var savedOnce = false;

var varNameReg = /^.+; +/;
var typeNameReg = /(; +.+)$/;

//function that will set properties for the given arrays
//every property corresponds to a number
//this way dropdownlists will be selected easily
function populateArrays (){
for ( var i=0; i<arguments.length; i++ ){
for ( var c=0; c<arguments[i].length; c++ ){
arguments[i][arguments[i][c]] = c;
}
}
};

populateArrays ( propArray, alignArray, orientArray );

//This array will contain both object literals to hold data for the tree elements
//and bracketed properties with the var names with the corresponding indexes
//When removing an object from the treeview splice() will be used to remove the literal and delete will be used to remove the property
var treeArray = [];

function updateTreeArray ( stPos, count, elInd, ddEl, treeElm, varname ){

//when removing objects from the array
if ( count > 0 ){
//Decrease all indexes after the starting position
for ( var x=stPos+1; x<treeArray.length; x++ ){
treeArray[treeArray[x].name]--;
};

//remove the property of the array with the given name
delete treeArray[treeArray[stPos].name];
//remove the object from the array
treeArray.splice( stPos, count );

return;
};

var tempObj = {type: ddEl, name: varname, parent: treeElm.text.replace(varNameReg, "")};

for (var i=0; i<propArray.length; i++){
if ( eval ( ddEl + ".hasOwnProperty" + "(" + ("\"" + propArray[i] + "\"") + ")" ) ){
tempObj[propArray[i]] = eval( ddEl + "." + propArray[i] );
};
};

//Set the default parameters for each element
//these paremeters are used when building the string when generate button is cklicked
switch ( ddEl ){
case "Window":
tempObj.param1 = "\"dialog\"";
tempObj.param2 = "\"Window\"";
tempObj.param3 = "undefined";
break;
case "Panel":
tempObj.param1 = "\"panel\"";
tempObj.param2 = "undefined";
tempObj.param3 = "\"" +varname + "\"";
break;
case "Group":
tempObj.param1 = "\"group\"";
tempObj.param2 = "undefined";
break;
case "StaticText":
tempObj.param1 = "\"statictext\"";
tempObj.param2 = "undefined";
tempObj.param3 = "\"...\"";
break;
case "EditText":
tempObj.param1 = "\"edittext\"";
tempObj.param2 = "undefined";
tempObj.param3 = "\"\"";
break;
case "Button":
tempObj.param1 = "\"button\"";
tempObj.param2 = "undefined";
tempObj.param3 = "\"" +varname + "\"";
break;
case "IconButton": //
tempObj.param1 = "\"iconbutton\"";
tempObj.param2 = "undefined";
tempObj.param3 = "\"" +varname + "\"";
break;
case "Image": //
var imageFile = File.openDialog ("Select Image");
if ( imageFile ){
imageFile = imageFile.absoluteURI
}
else{
return;
};
tempObj.param1 = "\"image\"";
tempObj.param2 = "undefined";
tempObj.param3 = "File (" + "\"" +imageFile + "\"" + ")";
break;
case "Checkbox": //
tempObj.param1 = "\"checkbox\"";
tempObj.param2 = "undefined";
tempObj.param3 = "\"" +varname + "\"";
break;
case "RadioButton": //
tempObj.param1 = "\"radiobutton\"";
tempObj.param2 = "undefined";
tempObj.param3 = "\"" +varname + "\"";
break;
case "Slider": //
tempObj.param1 = "\"slider\"";
tempObj.param2 = "undefined";
tempObj.param3 = "undefined";
break;
case "Scrollbar": //
tempObj.param1 = "\"scrollbar\"";
tempObj.param2 = "[0,0,100,20]";
//tempObj.param3 = "\"" +varname + "\"";
break;
case "ListBox": //
tempObj.param1 = "\"listBox\"";
tempObj.param2 = "undefined";
tempObj.param3 = "[]";
break;
case "DropDownList":
tempObj.param1 = "\"dropdownlist\"";
tempObj.param2 = "undefined";
tempObj.param3 = "[]";
break;
case "TreeView":
tempObj.param1 = "\"treeView\"";
tempObj.param2 = "undefined";
//tempObj.param3 = "undefined";
break;
};

treeArray[ varname ] = elInd;
treeArray.splice( stPos, count, tempObj );
};

updateTreeArray ( 0, 0, 0, "Window", childEl, "Window_1");

//Make object with numbers to count the default variables for the generated elements
//Used only when adding new element to the treeview
var count = {};

//set 0 as default number for each element
for ( var i=0; i<elArray.length; i++ ){
count[elArray[i]] = 0;
};

count["Window"]++;

//File associated variables
var sourceFolder = '~';
var jsReg = /(\.jsx)$/;
var checkSave = false;
var currentFile;

//Update dropDowns (select proper values)
function setDropDowns (defVal, typeOfObject, treeArrayObj){
//When setting the default values for objects
//this is needed only when adding objects
if ( defVal ){
if ( eval ( typeOfObject + ".hasOwnProperty" + "(" + ("\"" + "orientation"+ "\"") + ")" ) ){
objectProps["orientation"].enabled = true;
treeArrayObj["orientation"] = eval( typeOfObject + "." + "orientation" );
//objectProps["orientation"].selection = orientArray[treeArrayObj["orientation"]];
}
else{
objectProps["orientation"].enabled = false;
}

if ( eval ( typeOfObject + ".hasOwnProperty" + "(" + ("\"" + "alignment"+ "\"") + ")" ) ){
objectProps["alignment"].enabled = true;
treeArrayObj["alignment"] = eval( typeOfObject + "." + "alignment" );
//objectProps["alignment"].selection = alignArray[treeArrayObj["alignment"]];
}
else{
objectProps["alignment"].enabled = false;
}

if ( eval ( typeOfObject + ".hasOwnProperty" + "(" + ("\"" + "alignChildren"+ "\"") + ")" ) ){
objectProps["alignChildren"].enabled = true;
treeArrayObj["alignChildren"] = eval( typeOfObject + "." + "alignChildren" );
//objectProps["alignChildren"].selection = alignArray[treeArrayObj["alignChildren"]];
}
else{
objectProps["alignChildren"].enabled = false;
}
}
//When setting the values for dropDowns from user input (selecting in treeView)
else{
if ( eval ( typeOfObject + ".hasOwnProperty" + "(" + ("\"" + "orientation"+ "\"") + ")" ) ){
objectProps["orientation"].enabled = true;
objectProps["orientation"].selection = orientArray[ treeArrayObj["orientation"] ];
}
else{
objectProps["orientation"].enabled = false;
}

if ( eval ( typeOfObject + ".hasOwnProperty" + "(" + ("\"" + "alignment"+ "\"") + ")" ) ){
objectProps["alignment"].enabled = true;
objectProps["alignment"].selection = alignArray[ treeArrayObj["alignment"] ];
}
else{
objectProps["alignment"].enabled = false;
}

if ( eval ( typeOfObject + ".hasOwnProperty" + "(" + ("\"" + "alignChildren"+ "\"") + ")" ) ){
objectProps["alignChildren"].enabled = true;
objectProps["alignChildren"].selection = alignArray[ treeArrayObj["alignChildren"] ];
}
else{
objectProps["alignChildren"].enabled = false;
}
}
};

//Set the dropdowns with default for window object as it`s the first object in the treeView
setDropDowns ( true, "Window", treeArray[0] );

//Make string from treeArray data
function generateWindow (){
var windowString = "var " + treeArray[0].name + " = " + "new Window " + " ( " + treeArray[0].param1 + ", " + treeArray[0].param2 + ", " + treeArray[0].param3 + " );" + "\n" ;
var len = treeArray.length;

for ( var i=1; i<len; i++ ){
if ( treeArray[i].type !== "Group" ){
windowString += treeArray[i].name + " = " + treeArray[i].parent + "." + propArray[0] + " ( " + treeArray[i].param1 + ", " + treeArray[i].param2 + ", " + treeArray[i].param3 + " );" + "\n" ;
}
else{
windowString += treeArray[i].name + " = " + treeArray[i].parent + "." + propArray[0] + " ( " + treeArray[i].param1 + ", " + treeArray[i].param2 + " );" + "\n" ;
}

for(var c=1; c<propArray.length; c++){
//assign properties to the elment
if ( treeArray[i].hasOwnProperty (propArray[c]) ){
windowString += treeArray[i].name + "." + propArray[c] + " = " + "\"" + treeArray[i][propArray[c]] +"\"" + ";" + "\n" ;
}
}
}

windowString += treeArray[0].name + ".center ();" + "\n" + treeArray[0].name + ".show ();"

return windowString;
};

function readString ( stringVar ){
var lineArray = stringVar.split ("\n");
alert ( lineArray[0] );

treeArray = [];
};

//}

//===============================================
// INTERFACE ELEMENTS FUNCTIONS
//===============================================
//{
loadFile.onClick = function (){
currentFile = File.openDialog ( "~" );

if ( !jsReg.test ( currentFile.name ) ){

alert ( "Only .jsx files are allowed" )
return;

}

currentFile.open ( "r" );

var windowString = currentFile.read();
windowString = readString ( windowString );
}

newList.onChange = function (){
dropDownEl = this.selection.text;
}

//When selecting element from the child tree view
childTree.onChange = function (){
childEl = this.selection;

var varname = childEl.text.replace( varNameReg, "");
nameEdText.text = varname;

var typeOfObj = childEl.text.replace( typeNameReg, "");
//alert ( treeArray[treeArray[varname]].orientation );
setDropDowns ( false, typeOfObj, treeArray[treeArray[varname]] );

//var bracketProperty = childEl.text.replace( varNameReg, "");

edParam1.text = treeArray[ treeArray[ varname ] ].param1;
edParam2.text = treeArray[ treeArray[ varname ] ].param2;
edParam3.text = treeArray[ treeArray[ varname ] ].param3;
}

nameEdText.onChange = function (){

//Check for incorect input
if ( this.text === "" ){
alert ( "Name must be at least one character and unique for each element!" );
return;
}
else if ( treeArray.hasOwnProperty (this.text) ){
alert ( "Variable already exists!" );
return;
};

//store bracket label in variable
//update the name in the object in treeArray
var bracketProperty = childEl.text.replace( varNameReg, "");
treeArray[ treeArray[bracketProperty] ].name = this.text;

//Store Index in variable
//delete the property with the current name
//set the index for the property with the new name
var indx = treeArray[bracketProperty];
delete treeArray[bracketProperty];
treeArray[this.text] = indx

//update name in treeview
childEl.text = childEl.text.replace ( typeNamereg, " " + this.text );
}

//When adding element to the array and the treeview
newAdd.onClick = function (){

count[ dropDownEl ]++;
var defName = dropDownEl + "_" + count[ dropDownEl ];

//update treeArray
if ( childEl.items.length > 0 ){
//find the index of the selected node in the array
//add the number of items in order to find the position to splice
var arrInd = treeArray[ childEl.text.replace(varNameReg, "") ];
arrInd += childEl.items.length
updateTreeArray ( arrInd+1, 0, arrInd+1, dropDownEl, childEl, defName );
//alert ( treeArray[defName] );
}
else{
//find the index of the selected node in the array
var arrInd = treeArray[ childEl.text.replace(/^.+; /, "") ];
updateTreeArray ( arrInd+1, 0, arrInd+1, dropDownEl, childEl, defName );
}

//if element is of type container make node, else make item
if ( dropDownEl[0] === "W" || dropDownEl[0] === "P" || dropDownEl[0] === "G" ){
//if ( eval( dropDownEl + ".hasOwnProperty" + "(" + ("\"" + "add" + "\"") + ")" ) ){
childEl.add ( "node", dropDownEl + "; " + defName );
setDropDowns ( true, dropDownEl, treeArray[arrInd] );
}
else{
childEl.add ( "item", dropDownEl + "; " + defName );
setDropDowns ( true, dropDownEl, treeArray[arrInd] )
}
}

//When removing element from the treeview
newRemove.onClick = function (){

if ( childEl === childTree.items[0] ){
return;
}

//find starting index and update the array
if ( childEl.hasOwnProperty ("items") && childEl.items.length > 0 ){
var arrInd = treeArray[ childEl.text.replace(varNameReg, "") ]
var count = arrInd + childEl.items.length;
}
else{
var arrInd = treeArray[ childEl.text.replace(varNameReg, "") ]
var count = 1;
};

updateTreeArray ( arrInd, count, 0, dropDownEl, childEl, "" );
childEl.parent.remove (childEl);
childEl = childTree.selection;

var varname = childEl.text.replace( varNameReg, "");
setDropDowns ( false, typeOfObj, treeArray[treeArray[varname]] );
}

edParam1.onChange = function (){
var bracketProperty = childEl.text.replace( varNameReg, "");
treeArray[ treeArray[bracketProperty] ].param1 = this.text;
this.active = false;
}

edParam2.onChange = function (){
var bracketProperty = childEl.text.replace( varNameReg, "");
treeArray[ treeArray[bracketProperty] ].param2 = this.text;
this.active = false;
}

edParam3.onChange = function (){
var bracketProperty = childEl.text.replace( varNameReg, "");
treeArray[ treeArray[bracketProperty] ].param3 = this.text;
this.active = false;
}

orientList.onChange = function (){
var varName = childEl.text.replace( varNameReg, "");
treeArray[ treeArray[varName] ].orientation = this.selection.text;
}

alignList.onChange = function (){
var varName = childEl.text.replace( varNameReg, "");
treeArray[ treeArray[varName] ].alignment = this.selection.text;
}

alignChildList.onChange = function (){
var varName = childEl.text.replace( varNameReg, "");
treeArray[ treeArray[varName] ].alignChildren = this.selection.text;
}


generate.onClick = function (){

alert ( generateWindow () );
eval(generateWindow ())
}

save.onClick = function (){
var saveFolder = Folder.selectDialog("Choose folder", "~");
var fileName = prompt ("File Name", "Interface_1");

if ( !saveFolder || !fileName ){
return;
}

var newFile = new File ( saveFolder.absoluteURI+"/"+ fileName + ".jsx" );
newFile.open ("w");
newFile.write ( generateWindow () );
}

//When clicking on exit button ( closing window )
exit.onClick = function (){ //При излизане от прозореца
w.close ()
}
//}

w.center ();
w.show ();