Получить выбранные слои

В отличие от этого вопроса, существует ли способ вернуть массив текущих выбранных слоев, без необходимости перебирать все слои и, следовательно, удалять/перенастраивать этот выбор?

function get_selected_layers()
{
  var layers = app.activeDocument.activeLayer;
 // only works with *last* selected layer
 // not *all* selected layers
}

var thelayers = get_selected_layers;
alert(thelayers);

person Ghoul Fool    schedule 17.08.2020    source источник


Ответы (1)


Вроде, но не совсем. Не существует собственного способа получения массива выбранных объектов artLayer. Но есть способ получения дескрипторов выбранных слоев с помощью диспетчера действий — и из дескрипторов вы можете получить все, что захотите. Вот фрагмент, который возвращает массив имен, индексов и идентификаторов выбранных слоев — используя разные геттеры для дескриптора слоя (desc), можно получить все остальное. В качестве бонуса функция выбора artLayers по идентификаторам, если вы хотите получить artLayer объектов DOM. И да, это работает с группами и артбордами.

var layers = getSelectedLayersInfo();

// if we _really_ want to get artLayers we can select them one by one with IDs
for (var i = 0; i < layers.length; i++) {
  selectByID(layers[i].id);
  alert(activeDocument.activeLayer.name);
}

// and reselecting everything back
for (var i = 0; i < layers.length; i++) {
  selectByID(layers[i].id, true);
}


function getSelectedLayersInfo()
{
  var lyrs = [];
  var lyr;
  var ref = new ActionReference();
  var desc;
  var tempIndex = 0;
  var ref2;
  ref.putProperty(stringIDToTypeID("property"), stringIDToTypeID("targetLayers"));
  ref.putEnumerated(charIDToTypeID('Dcmn'), charIDToTypeID('Ordn'), charIDToTypeID('Trgt'));

  var targetLayers = executeActionGet(ref).getList(stringIDToTypeID("targetLayers"));
  for (var i = 0; i < targetLayers.count; i++)
  {
    ref2 = new ActionReference();

    // if there's a background layer in the document, AM indices start with 1, without it from 0. ¯\_(ツ)_/¯ 
    try
    {
      activeDocument.backgroundLayer;
      ref2.putIndex(charIDToTypeID('Lyr '), targetLayers.getReference(i).getIndex());
      desc = executeActionGet(ref2);
      tempIndex = desc.getInteger(stringIDToTypeID("itemIndex")) - 1;

    }
    catch (o)
    {
      ref2.putIndex(charIDToTypeID('Lyr '), targetLayers.getReference(i).getIndex() + 1);
      desc = executeActionGet(ref2);
      tempIndex = desc.getInteger(stringIDToTypeID("itemIndex"));
    }

    lyr = {};
    lyr.index = tempIndex;
    lyr.id = desc.getInteger(stringIDToTypeID("layerID"));
    lyr.name = desc.getString(charIDToTypeID("Nm  "));
    lyrs.push(lyr);
  }

  return lyrs;
}

function selectByID(id, add) {
    if (add == undefined) add = false;
    var desc1 = new ActionDescriptor();
    var ref1 = new ActionReference();
    ref1.putIdentifier(charIDToTypeID('Lyr '), id);
    desc1.putReference(charIDToTypeID('null'), ref1);
    if (add) desc1.putEnumerated(stringIDToTypeID("selectionModifier"), stringIDToTypeID("selectionModifierType"), stringIDToTypeID("addToSelection"));
    executeAction(charIDToTypeID('slct'), desc1, DialogModes.NO);
} // end of selectByID()
person Sergey Kritskiy    schedule 19.08.2020
comment
Этот скрипт не работает, если выбран только один слой (активный). По крайней мере, в Photoshop CS6. - person Zax; 11.06.2021
comment
@Zax, ты также тестировал это в CS2? - person Sergey Kritskiy; 11.06.2021
comment
Нет простите. У меня только CS6. Я не понимаю синтаксиса AM, но я думаю, что try-catch следует добавить с определенным кодом AM, если выбран только один слой. - person Zax; 11.06.2021