Copy link to clipboard
Copied
I tried to toggle the select-tool and the move-tool with a script. Seems simple enough. Something like:
var toggleState;
if (toggleState == true){
activateMoveTool();
toggleState = false;
}
if (toggleState == false){
activateSelectTool();
toggleState = true;
}
should do it (well, beside the "activateMoveTool" and "activateSelectTool" functions, which are not a problem).
But how to rember the variable toggleState? I tried to make it global, but did not find a way. Is there any?
Or could I just have an objekt(or funktion) running in the background that would keep track of variables like that one?
Copy link to clipboard
Copied
There are several ways to store a value. One easy way is to write it to a text file somewhere and have your script read that text file for the value on the next run.
Copy link to clipboard
Copied
Thank you, Mister Hale!
This might workt well enough for this script - I could even write a function / class that stores a group of values in the file and opens it only when needed (well, for more complex scripts, that is).
But I am really intrieged what other "several ways" there are. I am sure I will encounter that problem again, and in some situations the opening of an external file might be to time consuming. It does need to read/write on the hard-disk after all...
Copy link to clipboard
Copied
Don't worry about the file I/O in this case. Unless you're doing a lot of I/O, it won't have any effect on overall performance.
The Application.get/setCustomOptions (sp?) are another way of doing this.
Copy link to clipboard
Copied
X is right. You do not have to worry about the file I/O when only reading/writting a small text file. And writing a text file is not only easy but works with all versions of Photoshop.
I don't use putCustomOptions but I think it only works in CS4 and as I understand it the data has to be stored as actionDescriptors. The other methods I know of such as scriptStore( CS2 only? ) are just variations on the text/ini file method.
Copy link to clipboard
Copied
customOptions work in CS3 and CS4. Here is an example of how to store your togglestate
var toggleState = true;// the value you wish to store
// to store use these lines
var desc = new ActionDescriptor();// create a descriptor to hold value
desc.putBoolean ( 0 , toggleState );// store the data by type
app.putCustomOptions( 'mhScript', desc, true );// store the descritor by unique name
// to retrive the stored value
var desc = app.getCustomOptions ( 'mhScript' );// retrive by name
var toggleState = desc.getBoolean(0);// retrive the data by type
// some point later
app.eraseCustomOptions( 'mhScript' );// delete when no longer needed
Copy link to clipboard
Copied
Hi everyone (forgive my bad english)
I'm having the same issues than the creator of this post. I'm making some 'toggle keys' too. I'm using JavaScript on Photoshop CS3.
At first I stored the information about the 'toogle state' on a text layer. This was very ugly and a little slow, hehehe.
After that, I stored my 'toogle state' on the Document metadata. I used the 'app.activeDocument.info.instructions' property for storing the value. This was 'less ugly' and faster than the first method. I think this is a good option for 'kick and dirty' scripting only.
Reading this post I learned about this 'app.putCustomOptions' and it worked nicely on my 'toogles'. But I have two questions yet ( only for my 'theoretical curiosity').
1- I needed to make an 'initializing script' to set the 'toggle variables', because I can't check if a variable exists whitout generate an error warning. So, is there a way of check if a variable is defined or not whitout generate an error?
I think this question is more abouta JavaScript itself than about 'Adobe Extended Scripts', but maybe someone here can help whit this...
2- Is there a way of retrieve the information about the current selected tool on Photoshop? This possibility would be great inside the scripts.
Thank you for the attention
Copy link to clipboard
Copied
You can set the current tool. You cannot determine what the current tool is.
Copy link to clipboard
Copied
You could test for your variable in a try/catch block. Something like this:
try{ toggleState }// will throw error if toggleState is not defined
catch(e){
var toggleState = true;// so we now define it
}
And if you have CS3 or CS4 you can find the current tool with these lines:
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var cTool = typeIDToStringID(executeActionGet(ref).getEnumerationType(stringIDToTypeID('tool')));
alert( cTool );
Copy link to clipboard
Copied
Need to read my own code some time . From stdlib.js:
// maybe this works. maybe it doesn't
// function findCurrentTool(){
// var ref = new ActionReference();
// ref.putEnumerated(cTID("capp"), cTID("Ordn"), cTID("Trgt") );
// var desc = executeActionGet(ref);
// var tid = desc.getEnumerationType(sTID('tool'));
// return typeIDToStringID(tid);
// }
Copy link to clipboard
Copied
Both problems solved.
1- I had tried the 'try/catch' statement before, and got an error. When I tried it again, after read your post, I realized that the error was generated after the 'try' block, on other call to the inexistent variable. Sorry... it was 'dumbness' of mine. The 'try/catch' really prevents the error message and takes the correct handling.
2- Your code to retrieve the current selected tool works fine! I don't understand it exactly (yet), but it's working.
Thank you very much!
Copy link to clipboard
Copied
I am still working through all the code sampels provided here, so my real answer will come later. For now: everybody trying out the code snippets for finding out the current tool has to change the following things:
In Michaels L. Hales example, there is a "space" that must be removed. Instead of
var cTool = typeIDToStringID(executeActionGet(ref).getEnumerationType(stringIDToTypeID('too l')));
it must be
...(stringIDToTypeID('tool')));
I did not get this at first, since I misinterpreted the errormessage. [edit: by posting I found out that the space was inserted by the forum-software. No Idea why.]
In xbytor2's tool, the following functions need to be added:
function cTID(stringToConvert){
return charIDToTypeID(stringToConvert);
}
function sTID(stringToConvert){
return stringIDToTypeID('tool');
}
Copy link to clipboard
Copied
I saw that Michael L. Hale code worked for me. But it worked after I deleted the suplus white-space. I tought that it was accidentally inserted by me on my editing process.
Copy link to clipboard
Copied
First: Thank you all for your contributions. They helped me faar beyond just solving my problem at hand.
Second: Mr Hale and xbytor, your scripts to get the current tool intruige me. I researched about ActionReferences, -Descriptors and -Lists. I learned a lot (and think I do understand actionDescriptors and -Lists now), but I have still problems understanding actionReferences as a whole and the following line in particular:
ref.putEnumerated(cTID("capp"), cTID("Ordn"), cTID("Trgt") );
This list: http://www.pcpix.com/Photoshop/enum.htm told me what capp, Prdn and Trgt means:
phClassApplication -> 1667330160 -> "capp" application
phTypeOrdinal -> 1332896878 -> "Ordn" ordinal
phEnumTarget -> 1416783732 -> "Trgt" targetEnum
The documentation tells me that .putEnumerated
Puts an enumeration type and ID
into a reference along with the
desired class for the reference.
But somehow, I still do not get it. In the context of the scripts, it seems possible that you are "recording" a small action just to read it thereafter and get the active tool out of it. Hm...
By the way, how did you gain your impressive skills with ActionReferences and the like? Did I miss some part of Documentation? Are there paralells to other programming languages I am missing?
Highly impressive, anyway.
Copy link to clipboard
Copied
Descriptors are like dictionaries.
Lists are lists (obviously) of identically typed things.
References are like linked lists. You can repeatedly add stuff to a reference (of the types permitted) and retrieve them back in the same order. Trying to think of them as anything else just gave me headaches.
The arguments the the various 'put' methods are the same. It's just that with Descriptors, the key is explicit.
With Lists, the key is the next index. With References, there really is no key, just the next slot.
Actions are (in essence) an ActionDescriptor full of data and an EventID (like 'Dspl') which indicates what to do with that data.
The parallel I'm most familiar with is when using CORBA without IDL. That may or may not be helpful
There are no real docs beyond what is in the pdfs provided by Adobe. There is a lot of information at ps-scripts.com and in the xtools code. I've implemented code there that can read and write .atn files which means that all of the gorey details for handling ActionDescriptor/List/Reference objects are there.
For me, the magic moment was when I finally realized that steps in an action are defined as ActionDescriptors. Once I got confirmation of this from someone at Adobe (probably Chris Cox) my mental model for all of this quickly fell into place. Working out all of the file formats, etc... has just be filling in the details.
Copy link to clipboard
Copied
Not having X's programing background I think of an action reference as something that tells Photoshop what to do. And yes it is like a little action that you write instead of record. For example the code that I and X posted could also be written like this
var ref = new ActionReference();
ref.putProperty( charIDToTypeID( "Prpr" ), stringIDToTypeID('tool') );// what key to get
ref.putEnumerated( charIDToTypeID("capp"), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );// where to get it from
var cTool = executeActionGet(ref);// in this case returns a one key descriptor
var cToolTypeID = cTool.getEnumerationType( stringIDToTypeID('tool') );// get the value of that key
alert( typeIDToStringID( cToolTypeID ) );// make that value readable
Most of the ordinals you will see will be target as Photoshop likes whatever you are working on to be active. You sometimes see next or previous. I can't recall seeing a 'normal ordinal' like first or second.
There is not much in the way of documentation. Most of what I know comes from looking at the scriptlistner log, xtools and X himself, and a little bit of code I put together for exploring action descriptors and action list. It's not as nice as X's getterdemo but works more the way I think. It sends it's output to the ESTK console window
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID("Lyr "), charIDToTypeID("Ordn"), charIDToTypeID("Trgt") );
var desc = executeActionGet(ref)
var c = desc.count ;
//for(var i=0;i<c;i++){ // to enumerate list
// $.writeln('Key '+i+' = '+desc.getType(i))
//}
for(var i=0;i<c;i++){ //enumerate descriptor's keys
$.writeln('Key '+i+' = '+typeIDToStringID(desc.getKey(i))+': '+desc.getType(desc.getKey(i)))
}