4 Replies Latest reply on Mar 16, 2017 8:57 AM by pencilking2002

    Access to layers in onClick event handler

    pencilking2002 Level 1

      Hi. I'm trying to access all the layers in the current document when I click a button in a custom window that I am made. Here's my code so far:

       

      var doc = app.activeDocument;  
      var palette = new Window("palette");
      var button = palette.add("button", undefined, "Play");
      palette.show();
      
      
      button.onClick = function() {
          var numLayers = doc.layers.length;
          $.writeln(numLayers.toString());
      };
      

       

      The problem I am having is that the "layers" collection doesn't seem to exist in the active document when I try to access it in the onClick event. Perhaps there is something I don't understand about button event handlers?

        • 1. Re: Access to layers in onClick event handler
          Silly-V Adobe Community Professional

          This is because with palettes, this gets infinitely more complicated because you have to send the code as a string through the BridgeTalk object. See this thread for an explanation: Re: Calling functions from UI palette

          • 2. Re: Access to layers in onClick event handler
            pencilking2002 Level 1

            Thanks Silly-V. I was able to make illustrator send a message to itself. Here's the code if anyone else needs it:

             

            #target illustrator
            var loadCode = '$.writeln(app.activeDocument.layers.length);';
            var animPalette = new Window("palette");
            var button = animPalette.add("button", undefined, "Play");
            
            
            animPalette.show();
            
            
            // When button is clicked, create the BridgeTalk Object so we can send a message
            // to an application (in this case its illustrator sending  a message to itself)
            button.onClick = function() {
                var bt = new BridgeTalk;
                bt.target = "illustrator";
                bt.body = loadCode;
                bt.send();
            };
            
            
            // Callback for when illustrator recieves the message
            // We use eval to read the message string and evaluate it as JS code
            BridgeTalk.onRecieve = function( message )
            {
                eval(message.body);
            };
            

             

            I'm curious though, is there a way to extract the script you want to run, into its own file as opposed to sending it as a string?

            • 3. Re: Access to layers in onClick event handler
              Silly-V Adobe Community Professional

              Hmm, I think using a palette, you have to send anything in a string regardless - but there may be more easier ways to do this.

              You could, for example, try to send a simple message that points to a .jsx file and use the file.execute() on it.

              In my case, I typically read in external .jsx files as text and send them through BT. There's a BridgeTalkEncode function floating around here, which is essential to ensure your script string stays intact and no comments or gotchas cause syntax errors.

              1 person found this helpful
              • 4. Re: Access to layers in onClick event handler
                pencilking2002 Level 1

                Here's something I just threw together. This way of doing things allows you to encapsulate your logic in a method instead of writing it as a string. It still gets turned into a string when you send it to BridgeTalk but at least this way you don't have to write code in a nasty nasty string

                 

                // This method takes in a function
                // and returns that function as a string + the function name and parenthesis
                // so in the end it spits out a function declaration and invokation: "myMethod() {} myMethod()"
                function strMethod(fn)
                {
                    return fn.toString() + fn.name + "()";
                }
                
                // The method we want to "stringify"
                function addLayer()
                {
                    app.activeDocument.layers.add();
                }
                
                var message = strMethod(addLayer);
                var animPalette = new Window("palette");
                var button = animPalette.add("button", undefined, "Play");
                
                
                animPalette.show();
                
                
                // When button is clicked, create the BridgeTalk Object so we can send a message 
                // to an application (in this case its illustrator sending  a message to itself)
                button.onClick = function() {
                    var bt = new BridgeTalk;
                    bt.target = "illustrator";
                    bt.body = message;
                    bt.send();
                };