Example of Extendscript PALETTE and colored BUTTONS (revised)

Engaged ,
Mar 02, 2020 Mar 02, 2020

Copy link to clipboard

Copied

Below is a script for use in Photoshop which uses the window type "palette".  It is opened by locating the jsx file in File>Scripts>...   It will remain open until closed by the user even while applying operations to an image.  The script also demonstrates a way of creating rectangular buttons with colored background and text.

 

Thanks to r-bin and Kukurykus for supplying the information for building this script.

 

This script can  be used as input for creating a jsxbin file.  To create a jsxbin file, remove the last six lines of code (BridgeTalk lines) and run save binary in ESTK.   With the jsxbin file, run the code from r-bin below in the thread to run the jsxbin file.

 

 

 

 

 

//#script "palette3.jsx"
//@target photoshop
/* 
    This routine is a combined effort based on information supplied 
    by r-bin and Kukurykus of Adobe Community.
*/

paletteFunction();
function paletteFunction()
{
    var paletteTitle = "RONC 02Mar2020";

    var winTest, win;
    var bridgeTalk, photoShop;

    var b1, b2, b3;
    var g0, g1, g2, g3;

    try
    {
        winTest = Window.find("palette", paletteTitle);
        if (winTest)
        {
            beep();
            winTest.show();
            return;
        }

        win = new Window("palette", paletteTitle);
        win.spacing = 0;
        win.margins = 0;

        var font = ScriptUI.newFont("Arial", ScriptUI.FontStyle.BOLD, 20);

        g0 = win.add("group");
        g0.orientation = "row";
        g0.alignment = "center";
        g0.spacing = 0;
        g0.margins = 0;


        g1 = g0.add("group");
        g1.spacing = 0;
        g1.margins = 0;
        g1.preferredSize = [150, 60];

        g1.graphics.backgroundColor = g1.graphics.newBrush(g1.graphics.BrushType.SOLID_COLOR, [1, 0, 0, 1]);
        b1 = g1.add("statictext", undefined, "Test1");
        b1.justify = "center";
        b1.alignment = ["fill", "fill"];
        b1.graphics.foregroundColor = b1.graphics.newPen(b1.graphics.PenType.SOLID_COLOR, [0, 1, 0, 1], 1);
        b1.graphics.font = font;
        b1.onClick = function () { alert(this.text); };

        g3 = g0.add("group");
        g3.spacing = 0;
        g3.margins = 0;
        g3.preferredSize = [150, 60];

        g3.graphics.backgroundColor = g3.graphics.newBrush(g3.graphics.BrushType.SOLID_COLOR, [1, 1, 0, 1]);
        b3 = g3.add("statictext", undefined, "Test3");
        b3.justify = "center";
        b3.alignment = ["fill", "fill"];
        b3.graphics.foregroundColor = b3.graphics.newPen(b3.graphics.PenType.SOLID_COLOR, [0, 1, 1, 1], 1);
        b3.graphics.font = font;
        b3.onClick = function () { alert(this.text); };


        g2 = win.add("group");
        g2.spacing = 0;
        g2.margins = 0;
        g2.preferredSize = [150, 60];

        g2.graphics.backgroundColor = g2.graphics.newBrush(g2.graphics.BrushType.SOLID_COLOR, [0, 0, 1, 1]);
        b2 = g2.add("statictext", undefined, "Test2 - Close");
        b2.justify = "center";
        b2.alignment = ["fill", "fill"];
        b2.graphics.foregroundColor = b2.graphics.newPen(b2.graphics.PenType.SOLID_COLOR, [1, 1, 0, 1], 1);
        b2.graphics.font = font;
        b2.onClick = function () { alert(this.text); win.close(); };

        win.show();
    }
    catch (e)
    {
        alert(e);
    }
}

bridgeTalk = new BridgeTalk();

var photoShop = BridgeTalk.getSpecifier("photoshop");

if (!photoShop) photoShop = "photoshop-60.064"; // need redone
bridgeTalk.target = photoShop;

bridgeTalk.body = "var f=" + paletteFunction.toSource() + ";f();";
bridgeTalk.send();

 

 

 

This is what the "palette and colored buttons" should look like:

palette and colored buttonspalette and colored buttons

RONC

 

TOPICS
Actions and scripting , SDK

Views

1.9K

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 02, 2020 Mar 02, 2020

Copy link to clipboard

Copied

I like to position dialogs not centered so I added a littlt code to your script to position the dialog foe  ny 1K display.

//#script "palette3.jsx"
//@target photoshop
/* 
    This routine is a combined effort based on information supplied 
    by r-bin and Kukurykus of Adobe Community.
*/

function paletteFunction()
{
    var paletteTitle = "RONC 02Mar2020";

    var winTest, win;
    var bridgeTalk, photoShop;

    var b1, b2, b3;
    var g0, g1, g2, g3;

    try
    {
        winTest = Window.find("palette", paletteTitle);
        if (winTest)
        {
            beep();
			winTest.onShow = function() {
				var ww = winTest.bounds.width;  
				var hh = winTest.bounds.height;  
				winTest.bounds.x  = 1870 - ww;  
				winTest.bounds.y  = 100;  
				winTest.bounds.width  = ww;  
				winTest.bounds.height  = hh;  
			}	
            winTest.show();
            return;
        }

        win = new Window("palette", paletteTitle);
        win.spacing = 0;
        win.margins = 0;

        var font = ScriptUI.newFont("Arial", ScriptUI.FontStyle.BOLD, 20);

        g0 = win.add("group");
        g0.orientation = "row";
        g0.alignment = "center";
        g0.spacing = 0;
        g0.margins = 0;


        g1 = g0.add("group");
        g1.spacing = 0;
        g1.margins = 0;
        g1.preferredSize = [150, 60];

        g1.graphics.backgroundColor = g1.graphics.newBrush(g1.graphics.BrushType.SOLID_COLOR, [1, 0, 0, 1]);
        b1 = g1.add("statictext", undefined, "Test1");
        b1.justify = "center";
        b1.alignment = ["fill", "fill"];
        b1.graphics.foregroundColor = b1.graphics.newPen(b1.graphics.PenType.SOLID_COLOR, [0, 1, 0, 1], 1);
        b1.graphics.font = font;
        b1.onClick = function () { alert(this.text); };

        g3 = g0.add("group");
        g3.spacing = 0;
        g3.margins = 0;
        g3.preferredSize = [150, 60];

        g3.graphics.backgroundColor = g3.graphics.newBrush(g3.graphics.BrushType.SOLID_COLOR, [1, 1, 0, 1]);
        b3 = g3.add("statictext", undefined, "Test3");
        b3.justify = "center";
        b3.alignment = ["fill", "fill"];
        b3.graphics.foregroundColor = b3.graphics.newPen(b3.graphics.PenType.SOLID_COLOR, [0, 1, 1, 1], 1);
        b3.graphics.font = font;
        b3.onClick = function () { alert(this.text); };


        g2 = win.add("group");
        g2.spacing = 0;
        g2.margins = 0;
        g2.preferredSize = [150, 60];

        g2.graphics.backgroundColor = g2.graphics.newBrush(g2.graphics.BrushType.SOLID_COLOR, [0, 0, 1, 1]);
        b2 = g2.add("statictext", undefined, "Test2 - Close");
        b2.justify = "center";
        b2.alignment = ["fill", "fill"];
        b2.graphics.foregroundColor = b2.graphics.newPen(b2.graphics.PenType.SOLID_COLOR, [1, 1, 0, 1], 1);
        b2.graphics.font = font;
        b2.onClick = function () { alert(this.text); win.close(); };


        win.show();
    }
    catch (e)
    {
        alert(e);
    }
}

bridgeTalk = new BridgeTalk();

var photoShop = BridgeTalk.getSpecifier("photoshop");

if (!photoShop) photoShop = "photoshop-60.064"; // need redone
bridgeTalk.target = photoShop;

bridgeTalk.body = "var f=" + paletteFunction.toSource() + ";f();";
bridgeTalk.send();
JJMack

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 02, 2020 Mar 02, 2020

Copy link to clipboard

Copied

JJ,

Thanks for the addition. 

 

I intentionally didn't put anything in my code that doesn't relate directly to the "palette and colored buttons" so that those people trying to learn and use the code don't have to wade through extraneous code.

 

RONC

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

JJ,

I was asked by the users to include your positioning code in the palette as an option and have done it.  It works well except on vertical monitors.  Can you add code to adapt to the actual monitor size instead of using 1870, 100?  They also asked for the default to be a lower right side.

 

Thanks,

RONC

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

Adobe re-implemented ScriptUI is Photoshop CC 2015 or 2015.5 I can not remember which one I had Problems with changes Adobe made in that time frame   There here always be problems in ScriptUI  Adobe did not care to fix and the new implementation works somewhat differently then the original old version and there were problems in the new implementation Some have been fixed.  Photoshop Supports multiple display and it is possible withs scriot  get information about the number of displays current in use and Photoshop's displays bounds, Windows  can be located on any via ScriptUI.  I stopped positioning window on display other than Photoshop main display a simply hard code thye location  for my main display.  On one machine  a 1K  1920x1080 one my other a 4lk Display 3840x2160 I normally locate windows near the the top left or top right below Photoshop Tool Option bar and to the right of the Tool Bar or left of my pallets bar.  Photoshop displays mounds does not includes Windows task bar.

 

 

//alert($.screens)
PaletteDisplay = 0; // Photoshop's First Display
//PaletteDisplay = $.screens.length-1; // Photoshop's Last Display
PaletteTop = $.screens[PaletteDisplay].top + 100; // Relative to Top of display
PaletteLeft = $.screens[PaletteDisplay].right - ww - 46 ; // Relative to Right of side not Left side of display
p.bounds.x = PaletteLeft;
p.bounds.y = PaletteTop;
p.bounds.width = ww;
p.bounds.height = hh;

JJMack

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

JJ,

Thanks.  I tried $.screens but couldn't get it to work.  I didn't know that it should have been $.screens[] with the monitor number in the brackets.

 

I made this an option and with code from r-bin the palette actually remembers where the user left it the last and uses that location.

 

I'll upload a new version of the palette with the new changes tomorrow.

 

RONC

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

JJ or someone else,

 

Another query.  The place where you added your code

            beep();
			winTest.onShow = function() {
				var ww = winTest.bounds.width;  
				var hh = winTest.bounds.height;  
				winTest.bounds.x  = 1870 - ww;  
				winTest.bounds.y  = 100;  
				winTest.bounds.width  = ww;  
				winTest.bounds.height  = hh;  
			}	
            winTest.show();

is for bypassing duplicate versions of the script from being in memory.  Shouldn't you place the code after the palette is declared?  After:

win = new Window("palette", paletteTitle);

I have tested and that seems OK but I know nothing about this stuff.

 

Thanks,

RONC 

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

I did not understand the question at all. Can you reformulate?
By the way, why do you need beep()?
 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

Look at the very first code listing in this thread.  It was built by putting together suggestions from you and K.  This piece of code was supplied by you I believe.

 

try
    {
        winTest = Window.find("palette", paletteTitle);
        if (winTest)
        {
            beep();
            winTest.show();
            return;
        }

        win = new Window("palette", paletteTitle);

MUCH MORE CODE FOLLOWING.

 

has the beep();  call.    This piece of code is for catching whether the palette is already resident in the memory.   That is what my notes tell me.  Am I correct?

 

When JJ inserted his code, he inserted it between beep()   and   winTest.show().  His code is to relocate the palette to a position on the screen.  His code is not applied when the palette is run the first time so that the palette is located at the center of the screen.  After closing and reopening the palette it is located in the new location.   I'm asking whether JJ's code should be placed after where the palette is actually declared later in the code.

 

RONC

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

This code, which changes the bounds, needs to be inserted into the onShow function.
Then you do not need to use it when the window has already been formed. Before the very first win.show(), this code (which changes bounds) will not work. There is no point in inserting it there.

Your script is built in such a way that if you run the script at least once, and then make changes to the script, you need to restart Photoshop to see them (the changes).

P.S. In CS6, this code is not necessary at all, since the window retains its position, unlike CC, which calls the center() method without demand.
 
P.P.S. I put beep() for debugging so that it was clear what place the code is executing.
 
 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

r-bin,

Thanks.

 

I'll remove the beep();

 

I'll move the code to after where the window is declared as I was suggesting.  

 

I was going to mention that palette would not load if previously executed until Photoshop was restarted.  Thanks for verifying that.

 

How do I change the x and y for the location to take into account of the screen dimensions?  

RONC

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

        win.onShow = function()
            {
            try {
                if (win.my_location) 
                    {
                    win.location = win.my_location;
                    }
                else
                    {
                    var x = $.screens[0].right - win.size.width - 30;
                    var y = 50;
                
                    win.location = [x, y];
                    }
                }
            catch (e) { alert(e); }    
            }

        win.onClose = function()
            {
            try {
                win.my_location = win.location; /* remember user defined location (if user move window) */
                }
            catch (e) { alert(e); }    
            }

 

P.S.

I would suggest using  frameLocation instead of location, but it was broken after CS6 and was never repaired.
 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

r-bin,

Thanks.  Works real well.

 

I'll put frameLocation in my notes but I'm about to close this project as it is working for the users and I have image processing methods to get to.

 

RONC

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
LEGEND ,
Mar 07, 2020 Mar 07, 2020

Copy link to clipboard

Copied

LATEST

One strange thing I found is if you install the palettes using a Script event manager start Photoshop event.  If you use Photoshop UI top right icon for social media the Pallet window stops being displayed till you finish being social.

 

function fnctn()  {
    try {
		var paletteName = "PS Button Palette";
		var top = 90;
		var right =1880;			
        var w = Window.find("palette", paletteName );
        if (w) {
            beep();
			w.onShow = function() {
				var ww = w.bounds.width;  
				var hh = w.bounds.height;  
				w.bounds.y  = top; 				
				w.bounds.x  = right - ww;  
				w.bounds.width  = ww;  
				w.bounds.height  = hh;  
			}	
            w.show();
            return;
        }
    
		win = new Window("palette");
		win.text = paletteName; 
		win.orientation = "column"; 
		win.alignChildren = ["center","top"]; 
		win.spacing = 0;
        win.margins = [0,0,0,0];
		function wa(v) {return win.add('button', undefined, v)}
	
		buttons = ['Actual px', 'Zoom out', 'Zoom   in', '2x2 Guides', '3x3 Guides', '4x4 Guides', '5x5 Guides', 'AxA Guides', 'Close Palette'];
		for(i = 0; i < buttons.length; i++){
			wa(buttons[i]).onClick = function() {
				if (this.text == buttons[0] & documents.length!=0) {runMenuItem(app.charIDToTypeID("ActP"));}	
				if (this.text == buttons[1] & documents.length!=0) {runMenuItem(app.charIDToTypeID("ZmOt"));}
				if (this.text == buttons[2] & documents.length!=0) {runMenuItem(app.charIDToTypeID("ZmIn"));}
				if (this.text == buttons[3] & documents.length!=0) {AdobeScriptAutomationScripts("Toggle2x2Guides", "undefined");}
				if (this.text == buttons[4] & documents.length!=0) {AdobeScriptAutomationScripts("ToggleTickTocToe", "undefined");}
				if (this.text == buttons[5] & documents.length!=0) {AdobeScriptAutomationScripts("ToggleCenterGuides", "undefined");}
				if (this.text == buttons[6] & documents.length!=0) {AdobeScriptAutomationScripts("Toggle5x5Guides", "undefined");}
				if (this.text == buttons[7] & documents.length!=0) {AdobeScriptAutomationScripts("Toggle10x10Guides", "undefined");}
				if (this.text == buttons[8])  win.close();				
			}
		}
		
		function AdobeScriptAutomationScripts(javaScriptName, javaScriptMessage) {
			var descriptor = new ActionDescriptor();
			descriptor.putString( stringIDToTypeID( "javaScriptName" ), javaScriptName );
			descriptor.putString( stringIDToTypeID( "javaScriptMessage" ), javaScriptMessage );
			executeAction( stringIDToTypeID( "AdobeScriptAutomation Scripts" ), descriptor, DialogModes.NO );
		}
	
		win.onShow = function() {
			var ww = win.bounds.width;  
			var hh = win.bounds.height;  
			win.bounds.y  = top;  
			win.bounds.x  = right - ww;  
			win.bounds.width  = ww;  
			win.bounds.height  = hh;  
		}	
        win.show();
        } 
    catch (e) { alert(e); }
}

var bt = new BridgeTalk();
var ph = BridgeTalk.getSpecifier("photoshop");

if (!ph) ph = "photoshop-60.064" // need redone
bt.target = ph;
bt.body = "var f="+fnctn.toSource()+";f();"; 
bt.send();

 

 

JJMack

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 02, 2020 Mar 02, 2020

Copy link to clipboard

Copied

Make all the main code in a separate file. Compile it in JSXBIN. Place the JSXBIN file in the same folder as the main script.

Use this code.
 

 

 

 

var bt = new BridgeTalk();

var ph = BridgeTalk.getSpecifier("photoshop");

if (!ph) ph = "photoshop-60.064" // only for CS6x64, need redone
bt.target = ph;

var jsxbin = "aaaa.jsxbin"; // your jsxbin name here

var pth = new File($.fileName).parent.fullName + "/" + jsxbin;
bt.body = "$.evalFile(" + pth.toSource() + ")"; 
bt.send();

 

 

 

P.S. JSXBIN will not save you from hackers. ))

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 02, 2020 Mar 02, 2020

Copy link to clipboard

Copied

r-bin,

I removed the 6 lines related to BridgeTalk at bottom of original source above save as palette3.jsx and created a jsxbin file from that source.  Plugged the name of the file palette3.jsxbin into your code from above (see below also) and saved as paletteBT.jsx.  I ran that file from Photoshop and nothing happened.

 

Your code with my changes:

var bt = new BridgeTalk();

var ph = BridgeTalk.getSpecifier("photoshop");

if (!ph) ph = "photoshop-60.064" // only for CS6x64, need redone
bt.target = ph;

var jsxbin = "palette3.jsxbin"; // your jsxbin name here

var pth = new File($.fileName).parent.fullName + "/" + jsxbin;

//var pth = "C:/Users/RECHM/Dropbox/$$-SYNC/$$-Scripts/__SC-Save/palette3.jsxbin";
alert(pth);
bt.body = "$.evalFile(" + pth.toSource() + ")";
alert(bt.body);
bt.send();
/*

location  of  jsxbin:
C:\Users\RECHM\Dropbox\$$-SYNC\$$-Scripts\__SC-Save\palette3.jsxbin

---------------------------
pth  Script Alert
---------------------------
~/Dropbox/$$-SYNC/$$-Scripts/__SC-Save/palette3.jsxbin
---------------------------
OK
---------------------------

---------------------------
bt.body  Script Alert  try with actual code
---------------------------
$.evalFile((new String("~/Dropbox/$$-SYNC/$$-Scripts/__SC-Save/palette3.jsxbin")))
---------------------------
OK
---------------------------

---------------------------
---------------------------
bt.body  Script Alert  try with inputing complete address.
---------------------------
$.evalFile((new String("C:/Users/RECHM/Dropbox/$$-SYNC/$$-Scripts/__SC-Save/palette3.jsxbin")))
---------------------------
OK
---------------------------


*/

 I tried two ways.  First just using your code and the filename and a second where I put the complete path and filename and both did nothing.

 

Did I need to remove more that the last lines for making the jsxbin?

 

I'm lost.

RONC

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Community Expert ,
Mar 02, 2020 Mar 02, 2020

Copy link to clipboard

Copied

>>>I removed the 6 lines related to BridgeTalk at bottom of original source above

>>>save as palette3.jsx and created a jsxbin file from that source.

>>>Plugged the name of the file palette3.jsxbin into your code from above (see below

>>>also) and saved as paletteBT.jsx. I ran that file from Photoshop and nothing happened.

 

Did you insert a function call into this new script? )

 

 

paletteFunction();

 

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
Engaged ,
Mar 02, 2020 Mar 02, 2020

Copy link to clipboard

Copied

r-bin,

You asked "Did you insert a function call into this new script? )".

 

I hadn't as it didn't occur to me.

 

I did now and it works.

 

Thanks for setting me straight,

RONC

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines
New Here ,
Mar 04, 2020 Mar 04, 2020

Copy link to clipboard

Copied

ใส่มาเยอะๆ

Likes

Translate

Translate

Report

Report
Community guidelines
Be kind and respectful, give credit to the original source of content, and search for duplicates before posting. Learn more
community guidelines