Skip navigation
Currently Being Moderated

Calling functions from UI palette

Nov 12, 2012 12:19 PM

Hello,

From what I understand, you can't call complex functions from a scripted UI palette, only from "dialog" windows (which are usless in my case) because I need the persistance of a palette.

 

I have a series of scripts in use now that are  accessed from the usual "file-scripts folder" within Illustrator itself (about 27 of them).  I want to script a palette window so users can acces them without the usual mouse clicks down the menu system.

 

I'm able to call a simple "Hello World" type function using the "onClick()" method from a button of a scripted palette window, but I cannot use my regular working scripts inside a function that's called from the button.  In X-Code, I was able to write my scripts individually, then just add them to a main floating window via a separate function when they were completed.  But, I'm finding Javascript a little more tricky.

 

If I copy my other's script code into the function in the palette window script, it runs, but it runs before I click the button! --  After in runs, then the palette window is displayed(?).  If I try to use the execute() method with "onClick", the script just opens in the SDK, it will not and does run in Illustrator.

 

I take both of these as clear indications that I have no clue what I'm doing (or that I'm trying to do the impossible).

 

I did find someone with a similar problem, but they were scripting After Effects and were offered this solution:

 

system.callSystem ('afterfx -r "/C/Program Files/Adobe/Adobe After Effects CS3/Support Files/Scripts/GlobalVars.jsx"');

 

 

Is there anything I can do in Illustrator that will allow me to call (or execute) my other scripts/functions and have them execute within Illustrator?

 

Thanks for any and all help!

 
Replies 1 2 Previous Next
  • Currently Being Moderated
    Nov 12, 2012 12:41 PM   in reply to klemango

    the feature has always been broken, and for the longest I thought it was impossible to overcome, we finally found out a way to make it work, look here for an interesting reading about the topic and a script by Moluapple

    http://forums.adobe.com/message/4402921#4402921

     

    and here another script by me

    http://forums.adobe.com/message/4820011#4820011

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 12, 2012 1:10 PM   in reply to CarlosCanto

    Broken… Im not sure on that… Dialog is modal so it blocks out focus until cancel or ok… The problem with palette is getting current document/app status and the only way is through bridgetalk messaging… In your case the called script should be able to do this… Also look at the bridgetalk class cross DOM functions like run script… These should read and bridgetalk for you but I have heard of issues with these…

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 12, 2012 1:55 PM   in reply to Muppet Mark

    The problem with palette is getting current document/app status

    that sounds like broken ,  in the sence that it can not communicate with the application directly, it has to BridgeTalk to itself.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 12, 2012 1:58 PM   in reply to klemango

    kemango, your existing functions and scripts will certainly not work, you'll have tweak them a little bit to make them BridgeTalk ready.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 12, 2012 2:24 PM   in reply to CarlosCanto

    In PS it won't even persist… Now that be not playing ball at all…

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 12, 2012 2:32 PM   in reply to Muppet Mark

    not at all Mark, Adobe doesn't play ball, from the guide:

     

    Floating palette: Also called modeless dialog, allows activity in other application windows. (Adobe

    Photoshop® does not support script creation of palette windows.)

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 12, 2012 8:14 PM   in reply to klemango

    klemango wrote:

     

    I have a series of scripts in use now that are  accessed from the usual "file-scripts folder" within Illustrator itself (about 27 of them).  I want to script a palette window so users can acces them without the usual mouse clicks down the menu system.

     

    Not sure if I am on the right track in interpreting your request, but would Script Bay offer any viable solutions for your needs? I am however not sure if it works from a network drive/server (not sure why it wouldn't as its just pointers to folders it seems). Anyway if I am way off base then I apologize, otherwise maybe it will be helpful in some way as a more direct way for handling scripts if thats indeed what your after?

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 13, 2012 7:33 AM   in reply to klemango

    Ok, I see. Well I wont try and talk above my current comprehension (still learning myself) and your already in good hands with Muppet Mark and CarlosCanto.

     

    klemango wrote:

     

    I'm able to call a simple "Hello World" type function using the "onClick()" method from a button of a scripted palette window, but I cannot use my regular working scripts inside a function that's called from the button.  In X-Code, I was able to write my scripts individually, then just add them to a main floating window via a separate function when they were completed.  But, I'm finding Javascript a little more tricky. If I copy my other's script code into the function in the palette window script, it runs, but it runs before I click the button! --  After in runs, then the palette window is displayed(?).  If I try to use the execute() method with "onClick", the script just opens in the SDK, it will not and does run in Illustrator.

     

    That sounds weird that it would execute before the onClick is called? I will say that I have scripted window palettes using onClick() which then reference an #include to another JS file to execute and it works fine, I have also nested other #include's inside these files being called as well. So I guess you could build a palette window which executes scripts on user interaction (click a button) and even daisy chains scripts together using #include's? But then thats why I suggested ScriptBay as it already eloquently does this. How one gets to building something like ScriptBay is beyond me however, it's really impressive by Harbs.

     

    klemango wrote:

     

    Yes, it does help.  And, several of the artists at work use it all day.  They group several of the scripts into specific folders and just double click the folder.  The scripts inside that folder will then run in order.  It's a huge time saver! That's exactly what got me interested in learing about scripting the UI.  When there was just a few scripts, it wasn't such a big problem.  But, as their numbers grew, I began looking for a long-term solution to funneling down through folders of scripts in the Illustrator File menu.  We use a two monitor set-up at work and it would be great to having a floating palette just sitting on one of them waiting for commands.

    Hmmm... that sounds perfect for Scriptbay and what it was intended for.

     

    ----

     

    I gotta be honest though I might not be accurately understanding the full scope of what your trying to accomplish (plus obviously your trying to just learn as well), and if your wanting to get into BridgeTalk then thats beyond myself at this point. So again I refer you back to Muppet Mark, CarlosCanto and others for sound advice. ;-)

     

    Sorry if I added any confusion and noise to your thread, I just found it to be an interesting topic. I am probably approaching it from a too basic level however, sorry if I misunderstood.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 13, 2012 9:06 AM   in reply to klemango

    To force Illustrator as the operative app, put #target illustrator at the start of the script.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 13, 2012 9:53 AM   in reply to klemango

    kemango, I like what you're doing, we've told you since the beginning regular calls don't work, and still you're trying to find out how to make it work. I did the exact same thing, I thought "hmm...maybe there's something so simple that everyone before me just missed", but no, I couldn't find anything...but at the end, it's all good, you'll learn a lot by trying a bunch of different things, and who knows, you might find a way.

     

    in the mean time, look at my code in the selectLayers script, that's as basic as it gets, it does not return values, it just sends a request to select items in a layer.

     

    ...ok that code is not the most basic, let me make you a similar sample with a basic call..

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 13, 2012 10:23 AM   in reply to CarlosCanto

    here a simple script to select the top object

     

    #target Illustrator
    #targetengine main
     
     
    var win = new Window('palette', 'Select Top Object');
    var btnSelect = win.add('button', undefined, 'Select');
     
     
    btnSelect.onClick = function(){
        var bt = new BridgeTalk;
        bt.target = "illustrator"; 
            var script = "\n" +
            "app.activeDocument.pageItems[0].selected = true;\n" +
            "app.refresh();\n" 
     
     
        bt.body = script;
        bt.send(); 
    }
     
     
    win.center();
    win.show();
    
     
    |
    Mark as:
  • Currently Being Moderated
    Nov 13, 2012 10:54 AM   in reply to klemango

    #target Illustrator - if you run from the ESTK or double click on the file, #target tells the appropriate app to run the file, ignored if you run the script directly from Illustrator

     

    #targetengine - don't have a proper technical definition but without it a 'palette' window won't persist.

     

    as you see in the example, the script needs to be serialized as a text string and sent to illustrator. Illustrator receives the text string, puts it back into code (probably using eval() internally) and executed.

     

    Now, is there a way to load a script from an external library and run it (to keep the main code to a minimum)?

    I would say yes, as long as it gets properly serialized before it gets sent to illustrator.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 13, 2012 10:57 AM   in reply to CarlosCanto

    ....as you can see in my selectLayers script I have a separate function that gets sent to illustrator, I think that function could live in a separate file and get loaded with #include

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 13, 2012 11:12 AM   in reply to klemango

    don't worry,

     

    the + is the concatenation operand, "a" + "b" = "ab";

     

    I just added them at the end of each line, to make the code somewhat readable, same as this

     

    "app.activeDocument.pageItems[0].selected = true; app.refresh();"

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 13, 2012 11:17 AM   in reply to klemango

    the message is sent as one string, as long as it may be, functions and everything in between, and just like a regular script, functions will get executed as they are called.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 13, 2012 3:22 PM   in reply to klemango

    You mean like this

     

    Screen shot 2012-11-13 at 3.20.00 PM.png

     

    Corrected the two extra spaces and added the #target illustrator at the head of the script to get the ESTK to force it into Illustrator. In back is the original selection I made.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 13, 2012 3:51 PM   in reply to klemango

    do baby steps...start by making a small script to add new a layer and reame that layer...show us your bridge talk code, we'll help you make it work, once you get the hang of it, you can go on to bigger things.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 14, 2012 2:28 PM   in reply to klemango

    thanks for the link, it'll come handy, just for educational purposes here's your script, I ended up moving the function to the beginning, also the function is still a string, it needs to be converted back into a function with 'eval()'

     

    #target illustrator;
     
    #targetengine main;
     
     
     
    var win = new Window('palette', 'Copy Objects');
     
    var btnSelect = win.add('button', undefined, 'Copy');
     
     
     
    btnSelect.onClick = function(){
     
     
     
        var bt = new BridgeTalk;
     
        bt.target = "illustrator";
     
     
     
        var script =
        "main();" +
    "function main() {" +
     
     "var drawBasicDie = function (textstring){"+
        "alert('hola '+textstring);" +
           "alert('Hello');" +
      "}" + 
     
            "var thisDoc = app.activeDocument;" +
     
            "var artSel = thisDoc.selection;"+
     
            "var selLen = artSel.length;"+
     
     
            "brown = new CMYKColor();"+
     
            "brown.black = 50;"+
     
            "brown.yellow = 100;"+
     
            "brown.magenta = 67.065;"+
     
            "brown.cyan =0;"+
     
     
     
            "black = new CMYKColor();"+
     
            "black.black = 100;"+
     
            "black.yellow = 0;"+
     
            "black.magenta = 0;"+
     
            "black.cyan = 0;" +
     
     
            "if (thisDoc.selection.length >0){"+
     
     
                    "copy();"+
     
                    "paste();"  +
     
     
     
                    "thisDoc.rulerOrigin = [0,0]; "+
     
                    "thisDoc.pageOrigin = [0,0];"+
     
                    "var pageWidth = thisDoc.width/2;"+
     
                    "var pageHeight = thisDoc.height/2;"+
     
     
     
                    "var newLayer = thisDoc.layers.add();" +
     
                    "newLayer.name = 'Die Layer';" +
     
     
     
                    "var artGroup = thisDoc.groupItems.add();"+
     
                    "artGroup.name = 'Art Group Build';"+
     
     
     
                    "for(i=0;i<selLen;i++) {"+
                    "artSel[i].moveToEnd(artGroup);" +
                    "}"+
                    "var artGroupWidth = artGroup.width;"+
                    "var artGroupHeight = artGroup.height;"+
                    "var funct = eval(drawBasicDie);" +
                    "funct('Carlos');" +
     
             "}" +
     
            "else {" +
                "alert('Please select the artwork');}" +
     
     
     
    "}"
     
     
             bt.body = script;
     
        bt.send();
     
           }// end function
     
     
    win.center();
     
    win.show();
    
     
    |
    Mark as:
  • Currently Being Moderated
    Nov 15, 2012 8:31 AM   in reply to klemango

    you're welcome

    yeah, BT is a little bit obscure at first, once you get one or two scripts going, it starts to make sense.

     

    I don't have formal training, all by experimentation, I noticed when you call your function it returned 'undefined' when it is at the bottom, as you noticed this is not a problem if you run your script normally in the ESTK, I tried a couple of things and moving it to to top worked. I kind of remember that in C++ one has to 'declare' a function so it registers before it is called, otherwise the compiler doesn't know it exist.

     

    all that must be some weird BT implementation, you also noticed for (....) alert(...) does not work as it should, same with else alert(...), one liners must be enclosed in {}

     

    ...so, I keep my functions at the bottom too, as much as I'm allowed.

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 15, 2012 10:34 AM   in reply to klemango

    Great thread/work everyone, this has been an interesting and enlightening thread.

     

    I was curious are ScriptUI window palettes able to be saved as part of a workspace and thus dockable so with each start they will be part of the users workspace? If not then what is the best way to execute or initialize such scripts, as startup scripts? I am just trying to get my head around this as klemango mentioned a bunch of artists/designers using this and I was curious in such a case how it would then be implemented for use and deployment as part of their workflows?

     
    |
    Mark as:
  • Currently Being Moderated
    Nov 15, 2012 10:47 AM   in reply to W_J_T

    very interesting topic

     

    are ScriptUI window palettes able to be saved as part of a workspace and thus dockable so with each start they will be part of the users workspace?

    No

     

    startup scripts?

    I would say yes, but if you have several runing at the same time, I'm not sure how resource demanding that would be. The other option would be to start them up on demand as they're needed, just like other window-less scripts.

     
    |
    Mark as:
1 2 Previous Next
Actions

More Like This

  • Retrieving data ...

Bookmarked By (1)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points