Photoshop 脚本 - 尝试引用在不同文件中的函数中创建的 UI 元素
Photoshop scripting - trying to reference an UI element created in a funtion that is in a different file
我正在创建一个脚本,用户必须从多个下拉列表中 select 才能命名他们的图像。由于 ui 中的每一行都是相同的并且功能相同(它包含一个下拉列表、一个用于编辑列表的 select 离子框、一个编辑文本框和 add/edit/remove 按钮) ,我创建了一个函数来添加这些 ui 元素,而不是将每个元素都写出来。这个函数也在一个单独的文件中。一切正常,直到这一点。我现在需要做的是在下拉列表中获取用户 select 编辑的任何内容,并从中创建一个文件名。但是,我无法访问该列表。我猜是因为函数是最后一位被调用的。
我创建了一个构造文件名的函数。然后我尝试在不同位置以不同方式调用下拉列表。
var dlg = new Window('dialog', 'Material to Library');
//Material category panel, used to select which material dialogue option appears
dlg.grp0 = dlg.add('group');
dlg.grp0.addCatPnl = dlg.grp0.add('panel', [10, 110, 705, 170], 'Assign a type of material');
panelOption(0, dlg.grp0.addCatPnl.matCatTitle, 'Material Category:', dlg.grp0.addCatPnl.matCat, dlg.grp0.addCatPnl.matCatAddBox, dlg.grp0.addCatPnl.matCatNew, dlg.grp0.addCatPnl.matCatEditText, dlg.grp0.addCatPnl.matCatAddButt, dlg.grp0.addCatPnl.matCatEdtButt, dlg.grp0.addCatPnl.matCatRmvButt, dlg.grp0.addCatPnl, 15, 40, false);
//2)Create a panel for the option
dlg.swap = dlg.add ('group');
dlg.swap.visible = true;
dlg.swap.orientation = 'stack';
//panel swaps in
dlg.swap.asgnPnlV = dlg.swap.add('panel', [10, 200, 705, 450], 'Assign material name');
dlg.swap.asgnPnlV.visible = false;
var ddlName = dlg.swap.asgnPnlV.veneerMfg;
panelOption(1, dlg.swap.asgnPnlV.veneerMfgTitle, 'Manufacturer:', dlg.swap.asgnPnlV.veneerMfg, dlg.swap.asgnPnlV.veneerMfgAddBox, dlg.swap.asgnPnlV.veneerMfgNew, dlg.swap.asgnPnlV.veneerMfgEditText, dlg.swap.asgnPnlV.veneerMfgAddButt, dlg.swap.asgnPnlV.veneerMfgEdtButt, dlg.swap.asgnPnlV.veneerMfgRmvButt, dlg.swap.asgnPnlV, 15, 40, true);
panelOption(1, dlg.swap.asgnPnlV.veneerSpeciesTitle, 'Species', dlg.swap.asgnPnlV.veneerSpecies, dlg.swap.asgnPnlV.veneerSpeciesAddBox, dlg.swap.asgnPnlV.veneerSpeciesNew, dlg.swap.asgnPnlV.veneerSpeciesEditText, dlg.swap.asgnPnlV.veneerSpeciesAddButt, dlg.swap.asgnPnlV.veneerSpeciesEdtButt, dlg.swap.asgnPnlV.veneerSpeciesRmvButt, dlg.swap.asgnPnlV, 50, 75, true);
panelOption(1, dlg.swap.asgnPnlV.veneerCutTitle, 'Cut', dlg.swap.asgnPnlV.veneerCut, dlg.swap.asgnPnlV.veneerCutsAddBox, dlg.swap.asgnPnlV.veneerCutNew, dlg.swap.asgnPnlV.veneerCutEditText, dlg.swap.asgnPnlV.veneerCutAddButt, dlg.swap.asgnPnlV.veneerCutEdtButt, dlg.swap.asgnPnlV.veneerCutRmvButt, dlg.swap.asgnPnlV, 85, 110, true);
panelOption(1, dlg.swap.asgnPnlV.veneerStainTitle, 'Stain', dlg.swap.asgnPnlV.veneerStain, dlg.swap.asgnPnlV.veneerStainAddBox, dlg.swap.asgnPnlV.veneerStainNew, dlg.swap.asgnPnlV.veneerStainEditText, dlg.swap.asgnPnlV.veneerStainAddButt, dlg.swap.asgnPnlV.veneerStainEdtButt, dlg.swap.asgnPnlV.veneerStainRmvButt, dlg.swap.asgnPnlV, 120, 145, false);
panelOption(1, dlg.swap.asgnPnlV.veneerMapTitle, 'Map', dlg.swap.asgnPnlV.veneerMap, dlg.swap.asgnPnlV.veneerMapAddBox, dlg.swap.asgnPnlV.veneerMapNew, dlg.swap.asgnPnlV.veneerMapEditText, dlg.swap.asgnPnlV.veneerMapAddButt, dlg.swap.asgnPnlV.veneerMapEdtButt, dlg.swap.asgnPnlV.veneerMapRmvButt, dlg.swap.asgnPnlV, 155, 180, false);
//This one works(below), but this is not what I want
//materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, 'sel1', 'sel2', 'sel3', 'sel4', 'sel5');
//This one (below) is what I actually want Error 21, undefined is not an object line 25....
materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, dlg.swap.asgnPnlV.veneerMfg.selection, dlg.swap.asgnPnlV.veneerSpecies.selection, dlg.swap.asgnPnlV.veneerCut.selection, dlg.swap.asgnPnlV.veneerStain.selection, dlg.swap.asgnPnlV.veneerMap.selection);
//Other panels to swap in
////
dlg.show();
////
function panelOption(panelPosition, title, titleText, name, nameAddbox, nameNew, nameEditText, nameAddButt, nameEdtButt, nameRmvButt, pnlNm, x1, x2, isUpperCase){
var listArray = ['test1', 'test2', 'test3', 'veneer'];
title = pnlNm.add('StaticText', [15, x1, 110, x2], titleText.toString());
name = pnlNm.add('DropDownList', [120, x1, 230, x2], listArray);
nameAddbox = pnlNm.add('checkbox', [240, x1, 260, x2], 'Edit List');
nameAddbox.value = false;
nameNew = pnlNm.add('StaticText', [330, x1, 360, x2], 'New:');
nameEditText = pnlNm.add('EditText', [360, x1, 480, x2],);
nameEditText.enabled = false;
nameAddButt = pnlNm.add('button', [490, x1, 545, x2], ' add ');
nameAddButt.enabled = false;
nameEdtButt = pnlNm.add('button', [555, x1, 610, x2], 'edit');
nameEdtButt.enabled = false;
nameRmvButt = pnlNm.add('button', [620, x1, 675, x2], 'remove');
nameRmvButt.enabled = false;
if (panelPosition == 0){
name.onChange = function(){
var x = name.selection;
switch (x.toString()){
case 'veneer':
dlg.swap.asgnPnlV.visible = true;
dlg.swap.asgnPnlSS.visible = false;
break;
default:
dlg.swap.asgnPnlV.visible = false;
}
}
}
}
function materialName(matName, pnlNm, nom1, nom2, nom3, nom4, nom5){
var temp = 'material name here build as it goes';
var nomenclature1 = nom1;
var nomenclature2 = nom2;
var nomenclature3 = nom3;
var nomenclature4 = nom4;
var nomenclature5 = nom5;
var temp = nomenclature1 + '_' + nomenclature2 + '_' + nomenclature3 + '_' + nomenclature4 + '_' + nomenclature5;
matName = pnlNm.add('StaticText', [15, 205, 310, 230], temp);
if (pnlNm.visible == true){
dlg.findElement ('veneerMfg').onChange = function() {
//var nomenclature1 = Nom1.selection;
//return nomenclature1;
alert ('found element');
}
}
}
我需要的是 name.selection 成为用户 select 编辑的下拉列表中的值之一。
每当我调用使用它给出的函数创建的 name.selection 元素时,它就是 'undefined'。我试过 dlg.findElement ('veneerMfg') 这给了我 'null',我猜这意味着它找到了元素,但我需要能够在用户更改 select离子在下拉框中。
我认为访问下拉菜单的最简单方法是通过 dlg.swap.asgnPnlV
面板的 children
,如下所示:
var myButton = dlg.add('button',undefined,'Test');
myButton.onClick = function() {
var k = 1; // there're 40 children, each 8th is the dropdown, starting from index 1
var names = [];
for (var i = 0; i < dlg.swap.asgnPnlV.children.length; i++) {
// add only every 8th element
if ((i-k)%8 == 0) {
names.push(dlg.swap.asgnPnlV.children[i].selection)
}
}
alert(names);
}
所以你的函数看起来像这样:
materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, dlg.swap.asgnPnlV.children[1].selection, dlg.swap.asgnPnlV.children[9].selection, dlg.swap.asgnPnlV.children[17].selection, dlg.swap.asgnPnlV.children[25].selection, dlg.swap.asgnPnlV.children[33].selection);
然而,这不是很通用。更好的办法是将所有这些面板添加到一个循环中,这样就可以动态修改我的 names
对象而无需请求所有子项。请注意我用来确保所有下拉菜单都会正确更改 names
的闭包。
var panelData = [
{
name: 'Manufacturer',
list: ['m1', 'm2', 'm3'],
coords: [15, 40]
},
{
name: 'Species',
list: ['s1', 's2'],
coords: [50, 75]
},
{
name: 'Cut',
list: ['cut1', 'cut2', 'cut3', 'cut4', 'cut5'],
coords: [85, 110]
},
{
name: 'Stain',
list: ['stain1', 'stain2', 'stain3', 'stain4'],
coords: [120, 145]
},
{
name: 'Map',
list: ['map1', 'map2', 'map3', 'map4', 'map5', 'map6'],
coords: [155, 180]
}];
var mygroup;
var names = {};
for (var i = 0; i < panelData.length; i++)
{
(function(item)
{
var mygroup = dlg.swap.asgnPnlV.add('group', [15, item.coords[0], 410, item.coords[1]]);
mygroup.add('statictext', [0, 0, 110, 20], item.name);
var myDropDown = mygroup.add('DropDownList', [110, 0, 230, 20], item.list);
myDropDown.onChange = function()
{
names[item.name] = String(this.selection)
}
})(panelData[i])
}
var myB = dlg.add('button', undefined, 'Test');
myB.onClick = function()
{
alert(JSON.stringify(names));
}
所以你的函数看起来像这样:
materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, names['Manufacturer'], names['Species'], names['Cut'], names['Stain'], names['Map']);
我正在创建一个脚本,用户必须从多个下拉列表中 select 才能命名他们的图像。由于 ui 中的每一行都是相同的并且功能相同(它包含一个下拉列表、一个用于编辑列表的 select 离子框、一个编辑文本框和 add/edit/remove 按钮) ,我创建了一个函数来添加这些 ui 元素,而不是将每个元素都写出来。这个函数也在一个单独的文件中。一切正常,直到这一点。我现在需要做的是在下拉列表中获取用户 select 编辑的任何内容,并从中创建一个文件名。但是,我无法访问该列表。我猜是因为函数是最后一位被调用的。
我创建了一个构造文件名的函数。然后我尝试在不同位置以不同方式调用下拉列表。
var dlg = new Window('dialog', 'Material to Library');
//Material category panel, used to select which material dialogue option appears
dlg.grp0 = dlg.add('group');
dlg.grp0.addCatPnl = dlg.grp0.add('panel', [10, 110, 705, 170], 'Assign a type of material');
panelOption(0, dlg.grp0.addCatPnl.matCatTitle, 'Material Category:', dlg.grp0.addCatPnl.matCat, dlg.grp0.addCatPnl.matCatAddBox, dlg.grp0.addCatPnl.matCatNew, dlg.grp0.addCatPnl.matCatEditText, dlg.grp0.addCatPnl.matCatAddButt, dlg.grp0.addCatPnl.matCatEdtButt, dlg.grp0.addCatPnl.matCatRmvButt, dlg.grp0.addCatPnl, 15, 40, false);
//2)Create a panel for the option
dlg.swap = dlg.add ('group');
dlg.swap.visible = true;
dlg.swap.orientation = 'stack';
//panel swaps in
dlg.swap.asgnPnlV = dlg.swap.add('panel', [10, 200, 705, 450], 'Assign material name');
dlg.swap.asgnPnlV.visible = false;
var ddlName = dlg.swap.asgnPnlV.veneerMfg;
panelOption(1, dlg.swap.asgnPnlV.veneerMfgTitle, 'Manufacturer:', dlg.swap.asgnPnlV.veneerMfg, dlg.swap.asgnPnlV.veneerMfgAddBox, dlg.swap.asgnPnlV.veneerMfgNew, dlg.swap.asgnPnlV.veneerMfgEditText, dlg.swap.asgnPnlV.veneerMfgAddButt, dlg.swap.asgnPnlV.veneerMfgEdtButt, dlg.swap.asgnPnlV.veneerMfgRmvButt, dlg.swap.asgnPnlV, 15, 40, true);
panelOption(1, dlg.swap.asgnPnlV.veneerSpeciesTitle, 'Species', dlg.swap.asgnPnlV.veneerSpecies, dlg.swap.asgnPnlV.veneerSpeciesAddBox, dlg.swap.asgnPnlV.veneerSpeciesNew, dlg.swap.asgnPnlV.veneerSpeciesEditText, dlg.swap.asgnPnlV.veneerSpeciesAddButt, dlg.swap.asgnPnlV.veneerSpeciesEdtButt, dlg.swap.asgnPnlV.veneerSpeciesRmvButt, dlg.swap.asgnPnlV, 50, 75, true);
panelOption(1, dlg.swap.asgnPnlV.veneerCutTitle, 'Cut', dlg.swap.asgnPnlV.veneerCut, dlg.swap.asgnPnlV.veneerCutsAddBox, dlg.swap.asgnPnlV.veneerCutNew, dlg.swap.asgnPnlV.veneerCutEditText, dlg.swap.asgnPnlV.veneerCutAddButt, dlg.swap.asgnPnlV.veneerCutEdtButt, dlg.swap.asgnPnlV.veneerCutRmvButt, dlg.swap.asgnPnlV, 85, 110, true);
panelOption(1, dlg.swap.asgnPnlV.veneerStainTitle, 'Stain', dlg.swap.asgnPnlV.veneerStain, dlg.swap.asgnPnlV.veneerStainAddBox, dlg.swap.asgnPnlV.veneerStainNew, dlg.swap.asgnPnlV.veneerStainEditText, dlg.swap.asgnPnlV.veneerStainAddButt, dlg.swap.asgnPnlV.veneerStainEdtButt, dlg.swap.asgnPnlV.veneerStainRmvButt, dlg.swap.asgnPnlV, 120, 145, false);
panelOption(1, dlg.swap.asgnPnlV.veneerMapTitle, 'Map', dlg.swap.asgnPnlV.veneerMap, dlg.swap.asgnPnlV.veneerMapAddBox, dlg.swap.asgnPnlV.veneerMapNew, dlg.swap.asgnPnlV.veneerMapEditText, dlg.swap.asgnPnlV.veneerMapAddButt, dlg.swap.asgnPnlV.veneerMapEdtButt, dlg.swap.asgnPnlV.veneerMapRmvButt, dlg.swap.asgnPnlV, 155, 180, false);
//This one works(below), but this is not what I want
//materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, 'sel1', 'sel2', 'sel3', 'sel4', 'sel5');
//This one (below) is what I actually want Error 21, undefined is not an object line 25....
materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, dlg.swap.asgnPnlV.veneerMfg.selection, dlg.swap.asgnPnlV.veneerSpecies.selection, dlg.swap.asgnPnlV.veneerCut.selection, dlg.swap.asgnPnlV.veneerStain.selection, dlg.swap.asgnPnlV.veneerMap.selection);
//Other panels to swap in
////
dlg.show();
////
function panelOption(panelPosition, title, titleText, name, nameAddbox, nameNew, nameEditText, nameAddButt, nameEdtButt, nameRmvButt, pnlNm, x1, x2, isUpperCase){
var listArray = ['test1', 'test2', 'test3', 'veneer'];
title = pnlNm.add('StaticText', [15, x1, 110, x2], titleText.toString());
name = pnlNm.add('DropDownList', [120, x1, 230, x2], listArray);
nameAddbox = pnlNm.add('checkbox', [240, x1, 260, x2], 'Edit List');
nameAddbox.value = false;
nameNew = pnlNm.add('StaticText', [330, x1, 360, x2], 'New:');
nameEditText = pnlNm.add('EditText', [360, x1, 480, x2],);
nameEditText.enabled = false;
nameAddButt = pnlNm.add('button', [490, x1, 545, x2], ' add ');
nameAddButt.enabled = false;
nameEdtButt = pnlNm.add('button', [555, x1, 610, x2], 'edit');
nameEdtButt.enabled = false;
nameRmvButt = pnlNm.add('button', [620, x1, 675, x2], 'remove');
nameRmvButt.enabled = false;
if (panelPosition == 0){
name.onChange = function(){
var x = name.selection;
switch (x.toString()){
case 'veneer':
dlg.swap.asgnPnlV.visible = true;
dlg.swap.asgnPnlSS.visible = false;
break;
default:
dlg.swap.asgnPnlV.visible = false;
}
}
}
}
function materialName(matName, pnlNm, nom1, nom2, nom3, nom4, nom5){
var temp = 'material name here build as it goes';
var nomenclature1 = nom1;
var nomenclature2 = nom2;
var nomenclature3 = nom3;
var nomenclature4 = nom4;
var nomenclature5 = nom5;
var temp = nomenclature1 + '_' + nomenclature2 + '_' + nomenclature3 + '_' + nomenclature4 + '_' + nomenclature5;
matName = pnlNm.add('StaticText', [15, 205, 310, 230], temp);
if (pnlNm.visible == true){
dlg.findElement ('veneerMfg').onChange = function() {
//var nomenclature1 = Nom1.selection;
//return nomenclature1;
alert ('found element');
}
}
}
我需要的是 name.selection 成为用户 select 编辑的下拉列表中的值之一。 每当我调用使用它给出的函数创建的 name.selection 元素时,它就是 'undefined'。我试过 dlg.findElement ('veneerMfg') 这给了我 'null',我猜这意味着它找到了元素,但我需要能够在用户更改 select离子在下拉框中。
我认为访问下拉菜单的最简单方法是通过 dlg.swap.asgnPnlV
面板的 children
,如下所示:
var myButton = dlg.add('button',undefined,'Test');
myButton.onClick = function() {
var k = 1; // there're 40 children, each 8th is the dropdown, starting from index 1
var names = [];
for (var i = 0; i < dlg.swap.asgnPnlV.children.length; i++) {
// add only every 8th element
if ((i-k)%8 == 0) {
names.push(dlg.swap.asgnPnlV.children[i].selection)
}
}
alert(names);
}
所以你的函数看起来像这样:
materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, dlg.swap.asgnPnlV.children[1].selection, dlg.swap.asgnPnlV.children[9].selection, dlg.swap.asgnPnlV.children[17].selection, dlg.swap.asgnPnlV.children[25].selection, dlg.swap.asgnPnlV.children[33].selection);
然而,这不是很通用。更好的办法是将所有这些面板添加到一个循环中,这样就可以动态修改我的 names
对象而无需请求所有子项。请注意我用来确保所有下拉菜单都会正确更改 names
的闭包。
var panelData = [
{
name: 'Manufacturer',
list: ['m1', 'm2', 'm3'],
coords: [15, 40]
},
{
name: 'Species',
list: ['s1', 's2'],
coords: [50, 75]
},
{
name: 'Cut',
list: ['cut1', 'cut2', 'cut3', 'cut4', 'cut5'],
coords: [85, 110]
},
{
name: 'Stain',
list: ['stain1', 'stain2', 'stain3', 'stain4'],
coords: [120, 145]
},
{
name: 'Map',
list: ['map1', 'map2', 'map3', 'map4', 'map5', 'map6'],
coords: [155, 180]
}];
var mygroup;
var names = {};
for (var i = 0; i < panelData.length; i++)
{
(function(item)
{
var mygroup = dlg.swap.asgnPnlV.add('group', [15, item.coords[0], 410, item.coords[1]]);
mygroup.add('statictext', [0, 0, 110, 20], item.name);
var myDropDown = mygroup.add('DropDownList', [110, 0, 230, 20], item.list);
myDropDown.onChange = function()
{
names[item.name] = String(this.selection)
}
})(panelData[i])
}
var myB = dlg.add('button', undefined, 'Test');
myB.onClick = function()
{
alert(JSON.stringify(names));
}
所以你的函数看起来像这样:
materialName(dlg.swap.asgnPnlV.veneerMatName, dlg.swap.asgnPnlV, names['Manufacturer'], names['Species'], names['Cut'], names['Stain'], names['Map']);