Stdlib.moveLayerContentByIndex doesn't work as expected

Discussion of the xtools Toolkit

Moderators: Tom, Kukurykus

robpat

Stdlib.moveLayerContentByIndex doesn't work as expected

Post by robpat »

Stdlib.moveLayerContentByIndex(doc, idx, dx, dy) moves the selected layers regardless of the value of idx.

The code I used.
Code: Select all#include "/r/xtools/xlib/stdlib.js"
Stdlib.moveLayerContentByIndex(app.activeDocument, 1, 100, 200);


Any fix for this?
Thanks.
xbytor

Stdlib.moveLayerContentByIndex doesn't work as expected

Post by xbytor »

Looks like a bug in PS, at least in PSCS5. I'll check older versions to see if this behaved correctly in earlier revs.
Either that, or doing this in PS is not actually possible.

The simplest solution is to use Layer.translate or Stdlib.moveLayerContent with a Layer object reference instead of an index.

You may also be able to work up a version that uses the Name (if unique) or Id of the layer if you are trying to
avoid using Layer objects.

-X
robpat

Stdlib.moveLayerContentByIndex doesn't work as expected

Post by robpat »

Thanks for your advice.
Yes, I am trying to avoid using Layer objects.
I use Action Manager Index heavily in my code.
layer Id is not my choice unless there is a way to convert index to layer Id.

Now I come up with this workaround.
Code: Select allfunction makeActiveByIndex(idx) {
   var desc = new ActionDescriptor();
   var ref = new ActionReference();
   ref.putIndex(cTID("Lyr "), idx);
   desc.putReference(cTID("null"), ref);
   desc.putBoolean(cTID("MkVs"), false);
   executeAction(cTID("slct"), desc, DialogModes.NO);
}

function moveActiveLayerContent(dx, dy) {
   var desc = new ActionDescriptor();
   var lref = new ActionReference();
   lref.putEnumerated(cTID("Lyr "), cTID("Ordn"), cTID("Trgt"));
   desc.putReference(cTID("null"), lref);
   var pdesc = new ActionDescriptor();
   pdesc.putUnitDouble(cTID('Hrzn'), cTID('#Pxl'), dx);
   pdesc.putUnitDouble(cTID('Vrtc'), cTID('#Pxl'), dy);
   desc.putObject(cTID('T   '), cTID('Ofst'), pdesc);
   executeAction(cTID('move'), desc, DialogModes.NO);
}

makeActiveByIndex(1);
moveActiveLayerContent(100, 200);

makeActiveByIndex is rather slow though.
xbytor

Stdlib.moveLayerContentByIndex doesn't work as expected

Post by xbytor »

layer Id is not my choice unless there is a way to convert index to layer Id.

Use the index to get the layer's descriptor. The layer id is in there. There should be functions for this in stdlib.js.
Mike Hale

Stdlib.moveLayerContentByIndex doesn't work as expected

Post by Mike Hale »

robpat wrote:makeActiveByIndex is rather slow though.

The question is how does the speed of makeActiveByIndex compare with other ways to select a layer. I think you will find that it is much faster than any of the DOM methods. Replacing the cTID calls with the ID numbers will speed up the function a little at the expense of making it even harder to read.

One advantage of using ID is that it does not change when you move, add, or delete layers.
xbytor

Stdlib.moveLayerContentByIndex doesn't work as expected

Post by xbytor »

The question is how does the speed of makeActiveByIndex compare with other ways to select a layer.

Selecting the layer is slow regardless of how you do it :)
robpat

Stdlib.moveLayerContentByIndex doesn't work as expected

Post by robpat »

xbytor wrote:Use the index to get the layer's descriptor. The layer id is in there. There should be functions for this in stdlib.js.
Here is my modified code.
Code: Select allfunction getLayerIDByIndex(index) {
   var ref = new ActionReference();
   ref.putProperty(cTID("Prpr"), cTID("LyrI"));
   ref.putIndex(cTID("Lyr "), index);
   return executeActionGet(ref).getInteger(cTID("LyrI"));
}

function moveLayerContentByLayerID(layerID, dx, dy) {
   var desc = new ActionDescriptor();
   var lref = new ActionReference();
   lref.putIdentifier(cTID("Lyr "), layerID);
   desc.putReference(cTID("null"), lref);
   var pdesc = new ActionDescriptor();
   pdesc.putUnitDouble(cTID('Hrzn'), cTID('#Pxl'), dx);
   pdesc.putUnitDouble(cTID('Vrtc'), cTID('#Pxl'), dy);
   desc.putObject(cTID('T   '), cTID('Ofst'), pdesc);
   executeAction(cTID('move'), desc, DialogModes.NO);
}

moveLayerContentByLayerID(getLayerIDByIndex(1), 100, 200);

Using layer Id cannot solve this problem.
moveLayerContentByLayerID also moves the selected layers instead of the layer specified by layerID.

Mike Hale wrote:The question is how does the speed of makeActiveByIndex compare with other ways to select a layer. I think you will find that it is much faster than any of the DOM methods. Replacing the cTID calls with the ID numbers will speed up the function a little at the expense of making it even harder to read.

One advantage of using ID is that it does not change when you move, add, or delete layers.
makeActiveByIndex is faster than setting doc.activeLayer, but I would prefer not to select the layer before moving it.
xbytor

Stdlib.moveLayerContentByIndex doesn't work as expected

Post by xbytor »

I would prefer not to select the layer before moving it.

It would appear that this is one if those features that can only be invoked on an active layer, unfortunately. I don't know of any other way to attack the problem.
robpat

Stdlib.moveLayerContentByIndex doesn't work as expected

Post by robpat »

Okay, I'll just go with my workaround.
Thank you for your suggestions.