Skip to main content
Inspiring
December 10, 2023
Answered

Simulate shortcut Option/Alt+] select next group up

  • December 10, 2023
  • 8 replies
  • 1405 views

Hi!

This script simulates Option/Alt+] , hides active group and select the next one

https://screenpal.com/watch/c0l6qDVmGJf )
I need help for scripting - simulating the opposite, select next group up and make it visible, can anyone help ?

(only groups should be selected)

 

cTID = function(s) { return app.charIDToTypeID(s); };
sTID = function(s) { return app.stringIDToTypeID(s); };  


// =============Toggle visbility ==============
var idHd = charIDToTypeID( "Hd  " );
    var desc170 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var list54 = new ActionList();
            var ref127 = new ActionReference();
            var idLyr = charIDToTypeID( "Lyr " );
            var idOrdn = charIDToTypeID( "Ordn" );
            var idTrgt = charIDToTypeID( "Trgt" );
            ref127.putEnumerated( idLyr, idOrdn, idTrgt );
        list54.putReference( ref127 );
    desc170.putList( idnull, list54 );
executeAction( idHd, desc170, DialogModes.NO );



// ========== Simulate shortcut Option/Alt+[  select next goup==================

var idslct = charIDToTypeID( "slct" );
    var desc117 = new ActionDescriptor();
    var idnull = charIDToTypeID( "null" );
        var ref83 = new ActionReference();
        var idLyr = charIDToTypeID( "Lyr " );
        var idOrdn = charIDToTypeID( "Ordn" );
        var idBckw = charIDToTypeID( "Bckw" );
        ref83.putEnumerated( idLyr, idOrdn, idBckw );
    desc117.putReference( idnull, ref83 );
    var idMkVs = charIDToTypeID( "MkVs" );
    desc117.putBoolean( idMkVs, false );
    var idLyrI = charIDToTypeID( "LyrI" );
        var list33 = new ActionList();
        list33.putInteger( 10 );
    desc117.putList( idLyrI, list33 );
executeAction( idslct, desc117, DialogModes.NO );

 

 

This topic has been closed for replies.
Correct answer r-bin

A little crooked but it seems to work )

 

var layer = activeDocument.activeLayer;

// remember the visibility of layers

var d = new ActionDescriptor();
var r = new ActionReference();
r.putClass(stringIDToTypeID("compsClass"));
d.putReference(stringIDToTypeID("null"), r);
var d1 = new ActionDescriptor();
d1.putBoolean(stringIDToTypeID("useVisibility"), true);
d1.putBoolean(stringIDToTypeID("usePosition"), false);
d1.putBoolean(stringIDToTypeID("useAppearance"), false);
d.putObject(stringIDToTypeID("using"), stringIDToTypeID("compsClass"), d1);
executeAction(stringIDToTypeID("make"), d, DialogModes.NO);

// select all layers and turn on visibility for all

var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("selectAllLayers"), d, DialogModes.NO);

var d = new ActionDescriptor();
var list = new ActionList();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
list.putReference(r);
d.putList(stringIDToTypeID("null"), list);
executeAction(stringIDToTypeID("show"), d, DialogModes.NO);

// restoring the current active layer

var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("selectNoLayers"), d, DialogModes.NO);

activeDocument.activeLayer = layer;

// execute the command Alt+]

var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("forwardEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("select"), d, DialogModes.NO);

// restoring the visibility of layers

var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("compsClass"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("applyComp"), d, DialogModes.NO);
executeAction(stringIDToTypeID("delete"), d, DialogModes.NO);

// make the current layer visible anyway

activeDocument.activeLayer.visible = true;

 

 

8 replies

Stephen Marsh
Community Expert
Community Expert
December 13, 2023

The following code is getting there, perhaps somebody with better scripting knowledge than I possess can make something of it? It only selects layer sets, regardless of visibility. Ideally it would cycle either up or down (2 scripts) from the current active layer or layer group to the next layer group. I'm only looking at top-level layers at the moment, the extra complexity of going through nested groups is even more challenging.

 

/*
based on:
https://www.autohotkey.com/board/topic/94621-photoshop-cycle-through-layers-script/
*/

var doc = app.activeDocument;
var currentLayer = doc.activeLayer;

for (i = 0; i < doc.layerSets.length;) {
    if (doc.layerSets[i] == currentLayer) {
        a = i;
        i = doc.layerSets.length;
    } else {
        i++;
    }
}

try {
    var nextLayer = doc.layerSets[a + 1];
    var check = nextLayer.visible;
} catch (e) {
    var nextLayer = doc.layerSets[0];
    var check = nextLayer.visible;
}

doc.activeLayer = nextLayer;
if (check == false)
    doc.activeLayer.visible = false;

 

Joonass
Inspiring
December 13, 2023

If you are interested, this uses pretty much the same idea, but adds a few key things to it.

Stephen Marsh
Community Expert
Community Expert
December 13, 2023

Thanks @Joonass – the original request has now been clarified, only groups should be selected, not any other layerKind.

 

Looking at the screen recording, this is for top-level groups inside groups, however for flexibility it would be better to just cycle through all top level layer groups.

r-binCorrect answer
Legend
December 13, 2023

A little crooked but it seems to work )

 

var layer = activeDocument.activeLayer;

// remember the visibility of layers

var d = new ActionDescriptor();
var r = new ActionReference();
r.putClass(stringIDToTypeID("compsClass"));
d.putReference(stringIDToTypeID("null"), r);
var d1 = new ActionDescriptor();
d1.putBoolean(stringIDToTypeID("useVisibility"), true);
d1.putBoolean(stringIDToTypeID("usePosition"), false);
d1.putBoolean(stringIDToTypeID("useAppearance"), false);
d.putObject(stringIDToTypeID("using"), stringIDToTypeID("compsClass"), d1);
executeAction(stringIDToTypeID("make"), d, DialogModes.NO);

// select all layers and turn on visibility for all

var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("selectAllLayers"), d, DialogModes.NO);

var d = new ActionDescriptor();
var list = new ActionList();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
list.putReference(r);
d.putList(stringIDToTypeID("null"), list);
executeAction(stringIDToTypeID("show"), d, DialogModes.NO);

// restoring the current active layer

var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("selectNoLayers"), d, DialogModes.NO);

activeDocument.activeLayer = layer;

// execute the command Alt+]

var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("layer"), stringIDToTypeID("ordinal"), stringIDToTypeID("forwardEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("select"), d, DialogModes.NO);

// restoring the visibility of layers

var d = new ActionDescriptor();
var r = new ActionReference();
r.putEnumerated(stringIDToTypeID("compsClass"), stringIDToTypeID("ordinal"), stringIDToTypeID("targetEnum"));
d.putReference(stringIDToTypeID("null"), r);
executeAction(stringIDToTypeID("applyComp"), d, DialogModes.NO);
executeAction(stringIDToTypeID("delete"), d, DialogModes.NO);

// make the current layer visible anyway

activeDocument.activeLayer.visible = true;

 

 

c.pfaffenbichler
Community Expert
Community Expert
December 11, 2023

Could you please post screenshots with the pertinent Panels (Toolbar, Layers, Options Bar, …) visible to illustrate the process? 

Stephen Marsh
Community Expert
Community Expert
December 11, 2023

Yet another option for selecting the next visible/invisible layer. You would need to add an activeDocument.activeLayer.visible = true; line to make the selected layer or group visible or use code to toggle the visibility from off/on or on/off.

 

/*
https://superuser.com/questions/255506/select-forward-layer-keyboard-shortcut-include-invisible-layers
Select previous/backward layer
*/

var doc = app.activeDocument;
var currentLayer = doc.activeLayer;


for(i=0; i < doc.layers.length; )
{         
  if(doc.layers[i]==currentLayer)
  {
      a=i;
      //alert(a);
      i = doc.layers.length;
  }
  else{ i++; }
}


try
{
  var nextLayer = doc.layers[a+1];
  var check = nextLayer.visible;
}
catch(e)
{
  var nextLayer = doc.layers[0];
  var check = nextLayer.visible;
}  

doc.activeLayer = nextLayer;
if (check == false)
    doc.activeLayer.visible = false;

 

 

or

 

/*
https://superuser.com/questions/255506/select-forward-layer-keyboard-shortcut-include-invisible-layers
Select next/forward layer
*/

var doc = app.activeDocument;
var currentLayer = doc.activeLayer;


for(i=0; i < doc.layers.length; )
{         
  if(doc.layers[i]==currentLayer)
  {
      a=i;
      //alert(a);
      i = doc.layers.length;
  }
  else{ i++; }
}


try
{
  var nextLayer = doc.layers[a-1];
  var check = nextLayer.visible;
}
catch(e)
{
  var nextLayer = doc.layers[doc.layers.length-1];
  var check = nextLayer.visible;
}  

doc.activeLayer = nextLayer;
if (check == false)
  doc.activeLayer.visible = false;
Stephen Marsh
Community Expert
Community Expert
December 10, 2023

@siomosp 

 

The following isn’t pretty, but it does do what you want (it's based on the action method above):

 

activeDocument.suspendHistory("Select Layer...", "selectLayerMakeVisible('forwardEnum')"); // 'forwardEnum' or 'backwardEnum'


function selectLayerMakeVisible(forwardORbackward) {

	toggleShow();

	function s2t(s) {
		return app.stringIDToTypeID(s);
	}
	var descriptor = new ActionDescriptor();
	var list = new ActionList();
	var reference = new ActionReference();
	reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t(forwardORbackward));
	descriptor.putReference(s2t("null"), reference);
	descriptor.putBoolean(s2t("makeVisible"), false);
	list.putInteger(3);
	descriptor.putList(s2t("layerID"), list);
	executeAction(s2t("select"), descriptor, DialogModes.NO);

	toggleShow();

	activeDocument.activeLayer.visible = true;
	//activeDocument.activeLayer.visible ^= 1; // toggle visibility

	
	function toggleShow() {
		function s2t(s) {
			return app.stringIDToTypeID(s);
		}
		var descriptor = new ActionDescriptor();
		var list = new ActionList();
		var reference = new ActionReference();
		reference.putEnumerated(s2t("layer"), s2t("ordinal"), s2t("targetEnum"));
		list.putReference(reference);
		descriptor.putList(s2t("null"), list);
		descriptor.putBoolean(s2t("toggleOptionsPalette"), true);
		executeAction(s2t("show"), descriptor, DialogModes.NO);
	}
}

 

Note: It makes the layer visible (there is commented placeholder code to toggle the visibility from off/on or on/off).

 

Stephen Marsh
Community Expert
Community Expert
December 10, 2023

It's also possible to select the next invisible layer/group with an action, it just takes a little more work than one might expect:

 

 

https://www.dropbox.com/s/vpttyyi6gpedrwm/Select%20Forward%20or%20Backward%20Invisible%20Layer.atn?dl=0

 

Again, you would need to add a "show current layer" step to make the selected layer or group visible.

siomospAuthor
Inspiring
December 12, 2023

@Stephen Marsh , The action is not selecting forward invisible layer, dont know why 😞

Stephen Marsh
Community Expert
Community Expert
December 10, 2023

One option to select the next invisible layer/group here from @Joonass 

 

https://gist.github.com/joonaspaakko/048c9b58ccbb6e6f44c894bf4ce30b68

 

You must add the code to set the active layer visibility to true.

Joonass
Inspiring
December 12, 2023

I had planned to expand on the layer selection script that @Stephen Marsh linked to, but I never finished it or put online... They're a little redundant unless you really care about selecting hidden layers. I just added it to my existing layer selection repo... Maybe there's something helpful there. There is a config that finds the next group (the two test scripts that start with "Select next layer group..."), but I'm not certain they operate with the same logic as that native shortcut. @siomosp, if you want the same exact functionality as in your scripting listener code, but  you also want to make the group visible at the same time, there's an example here on line 263 that should make the layer visible if set to true. That should work in the scripting listener code you posted too.

siomospAuthor
Inspiring
December 12, 2023

The "Cycle-up" script at this 10 years old post works fine, but it is slow... and expands subgroups

https://superuser.com/questions/255506/select-forward-layer-keyboard-shortcut-include-invisible-layers
screen recording

(The "buttons" I click are  shortcuts to specific scripts, using an extension)

https://screenpal.com/watch/c0llDcVmssj

Stephen Marsh
Community Expert
Community Expert
December 10, 2023

@siomosp 

 

Does this have to be for the next invisible group? Or could it just be for the next invisible layer or group?

 

I don't have a copy of the code (I wish I did), however, I think that it may have been either @c.pfaffenbichler or perhaps @Chuck Uebele who posted a script to select the forward or backward visible/invisible layer. The great thing about that script was that it behaved just like the keyboard shortcut in that once it hit the top or bottom of the layers panel, it would then cycle through and keep going through the stack again (not sticking at the top or bottom).

 

EDIT: Your original script only works for visible layers, do you also wish for it to work with invisible layers as well?

siomospAuthor
Inspiring
December 12, 2023

Hi,
you are right, it have to work with the  next up invisible group

I want to select groups, not layers
Bellow it is a screen recording of my workflow

(The "buttons" I click are  shortcuts to specific scripts, form an extension)

https://screenpal.com/watch/c0l6qDVmGJf

Stephen Marsh
Community Expert
Community Expert
December 13, 2023

@Manan Joshi wrote a script to select the next group within a selected group, but this isn't exactly what you are looking for and it is too advanced for me to edit.

 

https://community.adobe.com/t5/photoshop-ecosystem-discussions/select-layer-group-below-the-currently-selected-group/m-p/13135586