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']);