If a layer is applied Clipping mask, How let JavaScript know ??
I have search "Clipping mask" in Reference Guide, but there was nothing.
Thanks.
About Clipping mask
About Clipping mask
I'm not sure if you want to test for a channel mask or vector mask so here are functions for both. The layer you want to test for a mask must be the active layer
Code: Select allfunction hasChannelMask() {
var ref = new ActionReference();
ref.putEnumerated( stringIDToTypeID( "layer" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ));
var desc= executeActionGet( ref );
return desc.hasKey(charIDToTypeID('Usrs'));
};
function hasVectorMask(){
var res = false;
for(i=0;i<activeDocument.pathItems.length;i++){
if(activeDocument.pathItems.name.match(/Vector Mask/)) res = true;
};
return res;
};
Code: Select allfunction hasChannelMask() {
var ref = new ActionReference();
ref.putEnumerated( stringIDToTypeID( "layer" ), charIDToTypeID( "Ordn" ), charIDToTypeID( "Trgt" ));
var desc= executeActionGet( ref );
return desc.hasKey(charIDToTypeID('Usrs'));
};
function hasVectorMask(){
var res = false;
for(i=0;i<activeDocument.pathItems.length;i++){
if(activeDocument.pathItems.name.match(/Vector Mask/)) res = true;
};
return res;
};
About Clipping mask
Thaks Mike Hale.
My problem is " Clipping mask", neither channel mask nor vector mask.
The "Creat Clipping mask" command below "Vector Mask" in "Layer" menu, its shortkey is Alt+Ctrl+G. You can try it and you'll understand my meaning.
My problem is " Clipping mask", neither channel mask nor vector mask.
The "Creat Clipping mask" command below "Vector Mask" in "Layer" menu, its shortkey is Alt+Ctrl+G. You can try it and you'll understand my meaning.
About Clipping mask
I never noticed that Photoshop call that a clipping mask. I have always have always called it a clipping layer.
This should do the job. The layer to be tested still needs to be the active layer
Code: Select allfunction isClippingLayer(){
var layer = activeDocument.activeLayer;
return (layer.grouped == true && layer.kind == LayerKind.NORMAL)
};
This should do the job. The layer to be tested still needs to be the active layer
Code: Select allfunction isClippingLayer(){
var layer = activeDocument.activeLayer;
return (layer.grouped == true && layer.kind == LayerKind.NORMAL)
};
About Clipping mask
Hey Mike,
There wouldn't, by chance, happen to be an easier way of testing to see if the selected layer IS actually the clipping layer (or bottommost layer to which a group of higher layers are all grouped), would there? Other than to check if the layer immediately above it is a clipped or grouped layer, I mean, of course.
And wouldn't your function provided, be better named, "isClippedLayer"? Or is my logic off? Also, why are you even bothering with LayerKind.NORMAL? In my experience, we have many different types of layers such as curves, hue/sat, even text, so they aren't always "normal" when we decide to merge() down, etc. Is there something in particular that I should NOT be looking for, instead of checking for NORMAL?
The reason, I'm asking all of this, is in my current particular project, I've written something that's auto merging a group if the layer exists, but I'm noticing a problem if the selected layer actually doesn't have anything grouped to it, being that it ends up merging down to the layer below it. So, in my case, I need to see if the layer in question IS the clipping layer to which any layers above it are grouped. If not, avoid the merge().
Thanks,
Izz
[quote][quote="Mike Hale"]This should do the job. The layer to be tested still needs to be the active layer
Code: Select allfunction isClippingLayer(){
var layer = activeDocument.activeLayer;
return (layer.grouped == true && layer.kind == LayerKind.NORMAL)
};
There wouldn't, by chance, happen to be an easier way of testing to see if the selected layer IS actually the clipping layer (or bottommost layer to which a group of higher layers are all grouped), would there? Other than to check if the layer immediately above it is a clipped or grouped layer, I mean, of course.
And wouldn't your function provided, be better named, "isClippedLayer"? Or is my logic off? Also, why are you even bothering with LayerKind.NORMAL? In my experience, we have many different types of layers such as curves, hue/sat, even text, so they aren't always "normal" when we decide to merge() down, etc. Is there something in particular that I should NOT be looking for, instead of checking for NORMAL?
The reason, I'm asking all of this, is in my current particular project, I've written something that's auto merging a group if the layer exists, but I'm noticing a problem if the selected layer actually doesn't have anything grouped to it, being that it ends up merging down to the layer below it. So, in my case, I need to see if the layer in question IS the clipping layer to which any layers above it are grouped. If not, avoid the merge().
Thanks,
Izz
[quote][quote="Mike Hale"]This should do the job. The layer to be tested still needs to be the active layer
Code: Select allfunction isClippingLayer(){
var layer = activeDocument.activeLayer;
return (layer.grouped == true && layer.kind == LayerKind.NORMAL)
};
About Clipping mask
Would something like this work?
It tests the active layer...
Code: Select allfunction isClippingLayer(){
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '),charIDToTypeID('Ordn'),charIDToTypeID('Trgt') );
var desc = executeActionGet(ref);
var idx = desc.getInteger (stringIDToTypeID('itemIndex'));
var group = desc.getBoolean(stringIDToTypeID('group'));
var clipInfo=false;
if(group) clipInfo = 'topClippingLayer';
try{
var ref = new ActionReference();
ref.putIndex(charIDToTypeID( 'Lyr ' ), (idx + 1) );
desc = executeActionGet(ref);
}catch(e){return clipInfo;}
group = desc.getBoolean(stringIDToTypeID('group'));
if(group && clipInfo == 'topClippingLayer' ) clipInfo = 'middleClippingLayer';
if(group && clipInfo == false ) clipInfo = 'bottomClippingLayer';
return clipInfo;
};
alert(isClippingLayer());
It tests the active layer...
Code: Select allfunction isClippingLayer(){
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '),charIDToTypeID('Ordn'),charIDToTypeID('Trgt') );
var desc = executeActionGet(ref);
var idx = desc.getInteger (stringIDToTypeID('itemIndex'));
var group = desc.getBoolean(stringIDToTypeID('group'));
var clipInfo=false;
if(group) clipInfo = 'topClippingLayer';
try{
var ref = new ActionReference();
ref.putIndex(charIDToTypeID( 'Lyr ' ), (idx + 1) );
desc = executeActionGet(ref);
}catch(e){return clipInfo;}
group = desc.getBoolean(stringIDToTypeID('group'));
if(group && clipInfo == 'topClippingLayer' ) clipInfo = 'middleClippingLayer';
if(group && clipInfo == false ) clipInfo = 'bottomClippingLayer';
return clipInfo;
};
alert(isClippingLayer());
About Clipping mask
Hey Paul,
Thanks for cooking up that function! I'm still not very proficient with modifying the listener/action manager codeset, so this is a big help!
I'm noticing that "topClippingLayer" doesn't seem to ever return (as "middleClippingLayer" returns in it's place, as well as for all middle clipping layers), but "bottomClippingLayer" seems consistent which is mainly what I was looking for.
I tried tinkering around with it to see if I could get topClippingLayer working as well, but the part inside of the try{} which I'm guess was examining the layer above the selected layer (hence the idx + 1) always returned false for group if i select a middle or top clipped layer. When selected the bottommost clipping layer or even the layer below it, I noticed I got a true for group.
Thanks again!
Izz
Thanks for cooking up that function! I'm still not very proficient with modifying the listener/action manager codeset, so this is a big help!
I'm noticing that "topClippingLayer" doesn't seem to ever return (as "middleClippingLayer" returns in it's place, as well as for all middle clipping layers), but "bottomClippingLayer" seems consistent which is mainly what I was looking for.
I tried tinkering around with it to see if I could get topClippingLayer working as well, but the part inside of the try{} which I'm guess was examining the layer above the selected layer (hence the idx + 1) always returned false for group if i select a middle or top clipped layer. When selected the bottommost clipping layer or even the layer below it, I noticed I got a true for group.
Thanks again!
Izz
About Clipping mask
Hey Paul,
I think I've figured out part of the problem, but can't quite explain it. Theoretically when you used "idx + 1", you would imagine you'd be specifying one index higher than the selected layer's index. The number adds up correctly. However, when you try to return the value based off of desc.getInteger(stringIDToTypeID('itemIndex')) on the new layer you're fetching data from, you interestingly get 2 numbers higher than the original idx value, not 1. The fix is to not add +1 to the idx, but my spidey sense is telling me this is only a band-aid.
I'm using CS4, btw. I'm guessing this has something to do with the background layer and Photoshop versions, and my fix might not actually be a fix to everyone, but this is a wild guess.
Izz
I think I've figured out part of the problem, but can't quite explain it. Theoretically when you used "idx + 1", you would imagine you'd be specifying one index higher than the selected layer's index. The number adds up correctly. However, when you try to return the value based off of desc.getInteger(stringIDToTypeID('itemIndex')) on the new layer you're fetching data from, you interestingly get 2 numbers higher than the original idx value, not 1. The fix is to not add +1 to the idx, but my spidey sense is telling me this is only a band-aid.
I'm using CS4, btw. I'm guessing this has something to do with the background layer and Photoshop versions, and my fix might not actually be a fix to everyone, but this is a wild guess.
Izz
About Clipping mask
Anyway, my amended version of your provided code is below.
Code: Select allfunction isClippingLayer(){
var ref = new ActionReference()
ref.putEnumerated( charIDToTypeID('Lyr '),charIDToTypeID('Ordn'),charIDToTypeID('Trgt'))
var desc = executeActionGet(ref)
var idx = desc.getInteger(stringIDToTypeID('itemIndex'))
var group = desc.getBoolean(stringIDToTypeID('group'))
var clipInfo = false
if ( group ) clipInfo = 'middle'
try{
var ref = new ActionReference()
ref.putIndex(charIDToTypeID( 'Lyr ' ), (idx))
desc = executeActionGet(ref)
group = desc.getBoolean(stringIDToTypeID('group'))
if ( !group && clipInfo == 'middle' ) clipInfo = 'top'
} catch (e) { return false }
if ( group && clipInfo == false ) clipInfo = 'bottom'
clipInfo = ( clipInfo == 'bottom' ? true : false )
return clipInfo
}
My version removes the +1 and since I'm only looking for the bottommost clipping layer to return true, I added the below line. Otherwise, without my line, it returns either, middle, top, bottom or false, for anyone else looking to use this. Oh, also, I started with middle being the default and then switching to top, if applicable, instead of vice versa.
Code: Select allclipInfo = ( clipInfo == 'bottom' ? true : false )
Code: Select allfunction isClippingLayer(){
var ref = new ActionReference()
ref.putEnumerated( charIDToTypeID('Lyr '),charIDToTypeID('Ordn'),charIDToTypeID('Trgt'))
var desc = executeActionGet(ref)
var idx = desc.getInteger(stringIDToTypeID('itemIndex'))
var group = desc.getBoolean(stringIDToTypeID('group'))
var clipInfo = false
if ( group ) clipInfo = 'middle'
try{
var ref = new ActionReference()
ref.putIndex(charIDToTypeID( 'Lyr ' ), (idx))
desc = executeActionGet(ref)
group = desc.getBoolean(stringIDToTypeID('group'))
if ( !group && clipInfo == 'middle' ) clipInfo = 'top'
} catch (e) { return false }
if ( group && clipInfo == false ) clipInfo = 'bottom'
clipInfo = ( clipInfo == 'bottom' ? true : false )
return clipInfo
}
My version removes the +1 and since I'm only looking for the bottommost clipping layer to return true, I added the below line. Otherwise, without my line, it returns either, middle, top, bottom or false, for anyone else looking to use this. Oh, also, I started with middle being the default and then switching to top, if applicable, instead of vice versa.
Code: Select allclipInfo = ( clipInfo == 'bottom' ? true : false )
About Clipping mask
I'm sorry but your amended version will fail if your document does not have a background layer, this was the mistake I made with the example, here is the corrected code...
Code: Select allfunction isClippingLayer(){
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '),charIDToTypeID('Ordn'),charIDToTypeID('Trgt') );
var desc = executeActionGet(ref);
var idx = desc.getInteger (stringIDToTypeID('itemIndex'));
var group = desc.getBoolean(stringIDToTypeID('group'));
var clipInfo=false;
if(group) clipInfo = 'topClippingLayer';
try{
activeDocument.backgroundLayer;
IDX = idx;
}catch(e){IDX = ++idx;}
try{
var ref = new ActionReference();
ref.putIndex(charIDToTypeID( 'Lyr ' ), IDX );
desc = executeActionGet(ref);
}catch(e){return clipInfo;}
group = desc.getBoolean(stringIDToTypeID('group'));
if(group && clipInfo == 'topClippingLayer' ) clipInfo = 'middleClippingLayer';
if(group && clipInfo == false ) clipInfo = 'bottomClippingLayer';
return clipInfo;
};
alert(isClippingLayer());
Code: Select allfunction isClippingLayer(){
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '),charIDToTypeID('Ordn'),charIDToTypeID('Trgt') );
var desc = executeActionGet(ref);
var idx = desc.getInteger (stringIDToTypeID('itemIndex'));
var group = desc.getBoolean(stringIDToTypeID('group'));
var clipInfo=false;
if(group) clipInfo = 'topClippingLayer';
try{
activeDocument.backgroundLayer;
IDX = idx;
}catch(e){IDX = ++idx;}
try{
var ref = new ActionReference();
ref.putIndex(charIDToTypeID( 'Lyr ' ), IDX );
desc = executeActionGet(ref);
}catch(e){return clipInfo;}
group = desc.getBoolean(stringIDToTypeID('group'));
if(group && clipInfo == 'topClippingLayer' ) clipInfo = 'middleClippingLayer';
if(group && clipInfo == false ) clipInfo = 'bottomClippingLayer';
return clipInfo;
};
alert(isClippingLayer());