Move Layer To The Top

I am wanting to move a layer to the top of all the layers in the document.
I am thinking that I am going to have to write some kind of function to count the layers and then move it by its index value.

Does this sound right or is there an easier way

ian

Think I managed to figure this out

  const currentDocument = app.activeDocument;
  const layers = currentDocument.activeLayers;
  const SelectedLayer = layers[0];
  SelectedLayer.moveAbove(currentDocument.layerTree[0]);

There’s also a command to move it to the front:

Related ActionDescriptor:

{
   "_obj": "move",
   "_target": {
      "_ref": "layer",
      "_enum": "ordinal",
      "_value": "targetEnum"
      },
   "to": {
      "_ref": "layer",
      "_enum": "ordinal",
      "_value": "front"
   }
}
1 Like

Thanks Simon, I like your way better as it cleaner with less code.
I never knew that option was there under the Layers menu :slight_smile:

Hello!
I have been using both approach a lot in my scripts, and I feel like sharing one thing or two about moving a layer to the top.

Option #1:

var currentDocument = app.activeDocument;
var layers = currentDocument.activeLayers;
var SelectedLayer = layers[0];
SelectedLayer.moveAbove(currentDocument.layerTree[0]);

Option #2:

batchPlay(
[
   {
      "_obj": "move",
      "_target": [
         {
            "_ref": "layer",
            "_enum": "ordinal",
            "_value": "targetEnum"
         }
      ],
      "to": {
         "_ref": "layer",
         "_enum": "ordinal",
         "_value": "front"
      },
      "_isCommand": true,
      "_options": {
         "dialogOptions": "dontDisplay"
      }
   }
],{ });

In fact, both options seems to be equivalent at first, but they yeild different results, especially if you have nested Groups & Layers in the PS layers stack.
Let’s have a closer look.
.
.

Case 1
PS stack with a bunch of layers, one group and a layer inside:
Screenshot 2021-03-03 at 13.39.22

Let’s say we want to move the Yellow layer “Layer 3” to the top.

Using Option #1 or Option #2 will give the same result:
Screenshot 2021-03-03 at 13.39.26
Indeed, moving the yellow “Layer 3” to the top is done in the same fashion with either Option #1 or Option #2.
That’s good :slight_smile:

.
.

Now, let’s examine the case where Option #1 and Option #2 begins to show different results.

Case 2
Consider this layer stack with nested groups:
Screenshot 2021-03-03 at 13.29.13

Let’s say we want to move the Red layer “Layer 3” to the top.

This is the result when using Option #1
Screenshot 2021-03-03 at 13.29.40

.

And this is the result when using Option #2
Screenshot 2021-03-03 at 13.29.20

A-ha! :sweat_smile:
As you can see, Option #1 and Option #2 are not equivalent anymore.
Beware of nested Groups & Layers structure.
.
.

Conculsion:

  • Option #2 moves “Layer 3” to the top, yes, but to the top of the group it was contained in. Note: If you’d wat to move it at the very top of the PS stack, you’d have to call batchPlay Option#2 twice (in this particular case because of nested levels).

  • On the other hand, Option #1 moves “Layer 3” to the top of the layer stack itself.
    If you want to be extra-sure that “Layer 3” will be move to the top regardless of the PS stack structure, then Option #1 is probably your best friend.

Personally, I consider Option #1 to be the safest. It does what it should be doing: move the layer to the (very) top, no matter how the PS stack looks like.

Finally, it depends on your particular need and expectations.

Hope this helps :slight_smile:

Interesting findings @Pierre_G . Nested Groups is not something I normally do but I must take them into account

Talking of the Top Layer, do you know of a way to select it.
I know I can use this code below but if there is already a layer named levels 1 it’s not going to work.

    "_obj": "select",
    "_target": [
       {
          "_ref": "layer",
          "_name": "Levels 1"
       }
    ],
    "makeVisible": false,
    "_isCommand": true,
    "_options": {
       "dialogOptions": "dontDisplay"
    }

   }

Thanks !

One way of doing it: just relpace
"_name": "Levels 1"
by
"_name": app.activeDocument.layers[0].name
.
.

batchPlay(
    [{
        "_obj": "select",
        "_target": [{
            "_ref": "layer",
            "_name": app.activeDocument.layers[0].name
        }],
        "_isCommand": true,
        "_options": {}
    }], {});

That is, if you want to select the top layer by getting its name and passing it to batchPlay.
.

If you want you can pass it’s id instead:

batchPlay(
    [{
        "_obj": "select",
        "_target": [{
            "_ref": "layer",
            "_id": app.activeDocument.layers[0]._id
        }],
        "_isCommand": true,
        "_options": {}
    }], {});

@Pierre_G You’re right, the front enum seems to reference the front of the parent node only, not of the whole layerstack.

The Photoshop DOM approach works fine I guess, but one limitation of it is that you can’t group it together with multiple operations like in batchPlay, to generate only one history state.

The BatchPlay alternative would look like this:

const layerCount = photoshop.action.batchPlay([{
  _obj: 'get',
  _target: [{ _property: 'numberOfLayers' }, { _ref: 'document', _enum: 'ordinal', _value: 'targetEnum' }],
}], { synchronousExecution: true })[0].numberOfLayers

photoshop.action.batchPlay([{
  _obj: 'select',
  _target: { _ref: 'layer', _index: layerCount }
},], {})

However, this is still not a perfect solution since you need to get the layerCount before your batchPlay call (in which you do multiple things). If you add or delete layers during this script, the layerCount won’t be correct anymore, so you’d have to manually count the added / deleted layers.

Curious, what happens if layers[0] = layerTree[0] in Option #1?

Not much. In that case you have the top layer selected and asking to move it to the top :wink: