3 Replies Latest reply on Jul 1, 2013 6:53 AM by alanomaly

    How to access app.activeDocument from a palette button?

    alanomaly Level 1

      I'm trying to debug a script that silently fails (I've got a seperate "How best to debug?" question here).

       

      Through brute force trial and error I've established that I can't access app.activeDocument in a function called by a button in a palette, and that any attempt to even look at app.activeDocument within the scope of this function causes the script to fall over and fail silently with no errors - even something that should be safe like if (!app.activeDocument){}.

       

      So, how do I access the active document - and specifically, app.activeDocument.selection - from within the scope of a function called by a button on a palette window?

       

      I've looked in the Javascript tools guide, the Illustrator CS6 scripting guide and Peter Kahrell's ScriptUI docs, and found nothing. I've googled around and found worrying long long threads linking to things referring to "The holy grail of Illustrator scripting", lots of "You can't" comments, something I didn't understand about refreshing the connection to the app, something about #targetengine another which seems to involve writing a seperate javascript file to the hard disk then running it (?!?!) and something else called BridgeTalk which seems to involve actionscript.

       

      Is it really this complicated? This is literally my first Illustrator script, and all I want is a palette (yes, it has to be a palette, not a dialog) that gets information about the current selection when you press a button.

       

      So, simple question, (hopefully) simple answer! How do you access data about the current selection from a palette button?

        • 1. Re: How to access app.activeDocument from a palette button?
          alanomaly Level 1

          With a lot of trial and error and ploughing through vague, unclear articles and non-existent docs, I figured it out.

           

          • It seems like palettes don't actually know what app they're in. They just sit there.
          • To get anything from your app, you need to throw javascript at it using the seemingly completely undocumented BridgeTalk, giving BridgeTalk a callback function if you need anything to happen in the palette once it's finished

           

          This actually isn't half as difficult as it looks when you're wading through the mountains of noise on the topic. Basically, anything you want to write like this:

           

           

           

          function someFunction() {

             // get data from the application and write it in the palette

             palette.info.text = app.activeDocument.selection.length;

          }

          palette.button.onclick = someFunction;

           

           

           

          ...you have to write like this...

           

           

           

          function someFunction() {

            // get data from the application

            return app.activeDocument.selection.length;

          }

           

          palette.button.onclick = function(){

           

          // make a BridgeTalk object to throw the script

            var bt = new BridgeTalk();

            bt.target = "illustrator";

           

          // a string containing javascript code to execute in Illustrator

            bt.body = someFunction.toString()+'someFunction();';

           

          // a function that recieves whatever the body JS above returns

            bt.onResult = function(result){

                palette.info.text = result;

          };

           

            bt.send();

          }

           

           

           

           

          This sort of structure should work for essentially anything - the only tricky case I can think of is if you need Illustrator to read some data that is in your palette - since the code you throw can't access any variables in the rest of your script - in which case you can do something like this:

           

           

           

           

          bt.body = 'var = '+someVariable.toString()+'; '+someFunction.toString()+'someFunction();';

           

           

           

           

          Or if you need to parameters to someFunction:

           

           

           

          bt.body = someFunction.toString()+'someFunction('+someVariable.toString()+');';

          • 2. Re: How to access app.activeDocument from a palette button?
            CarlosCanto Adobe Community Professional & MVP

            correct, you have to use BridgeTalk to make a palette talk with Illustrator, it is all documented in the Tools Guide

             

            look at this two script I posted here

            selectLayers

             

            alignText

            • 3. Re: How to access app.activeDocument from a palette button?
              alanomaly Level 1

              I made a mistake in the code above - it should be     palette.info.text = result.body;

               

              Not      palette.info.text = result;

               

              So annoying I can't edit it...