Copy link to clipboard
Copied
I found Scriptui code to change the color of a button but there is one part that is not working correctly. To place the text on the button, the text width is computed by graphics.measureString routine. Then the (button width - that value) / 2 should give the coordinate where the upper left corner of the text will be placed. I find that the 2 (I call it factor) in the divisor is not correct always. Position error of 1 or 2 pixel would be OK but it is way off. Italic and Bold need to be taken into account also.
Anyone have a solution that is good within a pixel or two?
The code below is first my version of older code referred to by web links.
I appreciate any help.
RONC
my code *******************************
// color button scriptui
// http://forums.adobe.com/message/2327073
// https://gist.github.com/milligramme/1353791#file-color_scriptui_button-js-L2
var u;
var dlg = new Window('dialog', 'Test');
var btn1 = dlg.add('button', u, 'OK', { name: 'ok' });
var btn2 = dlg.add('iconbutton', u, u, { name: 'gray', style: 'toolbutton' });
var factor = 2;
btn2.size = [120, 30];
btn2.text = "Test1";
btn2Graphics = btn2.graphics;
btn2.fillBrush = btn2Graphics.newBrush(btn2Graphics.BrushType.SOLID_COLOR, [0.5, 0.5, 0.5, 1.0]);
btn2Graphics.font = ScriptUI.newFont("ARIAL", ScriptUI.FontStyle.BOLD, 20);
btn2.textPen = btn2Graphics.newPen(btn2Graphics.PenType.SOLID_COLOR, [1.0, 1.0, 1.0, 1], 1);
btn2.onDraw = function ()
{
with (this)
{
graphics.drawOSControl();
// controlObj.graphics.rectPath (left, top[, width, height])
graphics.rectPath(0, 0, size[0], size[1]);
graphics.fillPath(fillBrush);
if (text)
{
// controlObj.graphics.measureString (text, font[, boundingWidth])
var x = (size[0] - graphics.measureString(text, graphics.font, size[0])[0]) / factor;
var y = 3;
// controlObj.graphics.drawString (text, pen, x, y, font)
graphics.drawString(text, textPen, x, y, graphics.font);
}
}
};
dlg.show();
Original code ***********************************
/*
var u;
var dlg = new Window('dialog', 'Test');
var pnl = dlg.add('panel', u, 'My Panel');
var btn = pnl.add('button', u, 'My Button', {name:'ok'});
var btn2 = pnl.add('iconbutton', u, u, {name:'orange', style: 'toolbutton'});
btn2.size = [200,20];
btn2.fillBrush = btn2.graphics.newBrush( btn2.graphics.BrushType.SOLID_COLOR, [1, 0.7, 0, 0.5] );
btn2.text = "Hello, Harbs";
btn2.textPen = btn2.graphics.newPen (btn2.graphics.PenType.SOLID_COLOR,[0,0.5,0,1], 1);
btn2.onDraw = function(){
with( this ) {
graphics.drawOSControl();
graphics.rectPath(0,0,size[0],size[1]);
graphics.fillPath(fillBrush);
if( text ) graphics.drawString(text,textPen,(size[0]-graphics.measureString (text,graphics.font,size[0])[0])/2,3,graphics.font);
}
};
dlg.show();
*/
function _keyDraw(i)
{
keyNo[i].onDraw = function ()
{
try
{
this.graphics.rectPath(0, 0, this.size.width, this.size.height);
this.graphics.fillPath(keyNo[i].brush);
var tmp = "___________________________
...
Copy link to clipboard
Copied
The button will automatically adjust to accommodate the text label.
Copy link to clipboard
Copied
Not if I declare the button size beforehand. Please look at the attached code.
RONC
Copy link to clipboard
Copied
Do not use size, use preferredSize as Adobe recommends.
Copy link to clipboard
Copied
Thanks.
Does preferredSize give me the exact size as the code attached is just for one button but the idea will be used in a calculator type dialog where all the buttons are the same "size"?
RONC
Copy link to clipboard
Copied
Also be aware that Adobe has been fixing bugs with ScruptUI graphics, your code will work differently in different apps and versions.
Copy link to clipboard
Copied
I only plan on using with Photoshop. The major problem is with:
var x = (size[0] - graphics.measureString(text, graphics.font, size[0])[0]) / 2;
var y = 3;
graphics.drawString(text, textPen, x, y, graphics.font);
This should center whatever is in text but it does not. I have looked at the values for x, y, size[0], size[1] and they seem correct but the image is not.
RONC
Copy link to clipboard
Copied
That's not the best way to do it, for one, and for two its probably your units. Type is in points and screen elements are in pixels.
Copy link to clipboard
Copied
I'll byte! How should I do it? Please share.
I agree that pixels and points probably are a problem. Documentation doesn't mention what units to use.
RONC
Copy link to clipboard
Copied
You can either use the auto layout engine or code actual size. I don't get how you are going to make buttons a custom size and the same size, you have to pick one of the other. Adobe's ScriptUI documentation goes in depth into layout.
You can specify ruler units in Photoshop, I'd look at that if you end up needing them.
Copy link to clipboard
Copied
Have a look at the code fragment in https://community.adobe.com/t5/photoshop/need-help-with-onclick-in-new-extendscript-for-ps/m-p/10941... for how I build the buttons. They are all the same custom size.
I have looked at the ruler units docs and find one piece missing. The screen PPI or PixelsPerInch is not discernable from Extendscript or Javascript.
Thanks for the response.
RONC
Copy link to clipboard
Copied
I don't understand what the problem is? You have this fragmentted across multiple threadsa and your code has changed several times. What SPECIFICALLY are you trying to do that isn't working?
Copy link to clipboard
Copied
After the first thread, I was able to get the following:
Everything works. Previous thread was because I didn't understand how onClick worked.
I gave this version to the users and the first comment was that the keys should be different shapes of gray or even colors. That is when I wrote the this thread as there is no direct way to "color" a button. Placing a statement declaring a button Background color do not work!!! So I found the code discussed in this thread. It uses iconbutton and colors the button very well but when adding text to the button I hit another wall as the text needs help to be centered on the button and no one knows how to do it, Do you? Scriptui is broken starting with not having a simple background color for the normal buttons.
I'm open to suggestions. Please.
RONC
Copy link to clipboard
Copied
Use a PNG graphic instead of text? That way you can size it exactly.
Copy link to clipboard
Copied
Thanks for the response.
I guess I can't see the trees for the forest. I did the prototype in html/js and used images but started with the hard approach in Extendscript because it looked so easy. It was until coloring the buttons entered the picture.
With iconbutton where does the png reside? Can it be included in the jsxbin file? I'm getting an error: Error 509: Invalid image data Line: 25 -> dlg.add("iconbutton", undefined, f,{style: "toolbutton", toggle: true});
<
var u;
var dlg = new Window('dialog', 'Test');
var btn1 = dlg.add('button', u, 'OK', { name: 'ok' });
//var btn2 = dlg.add('iconbutton', u, u, { name: 'gray', style: 'toolbutton' });
var f= File ("\Test-1.png")
dlg.add("iconbutton", undefined, f,{style: "toolbutton", toggle: true});
dlg.show();
/>
I have the file in the same folder as the jsx file.
Thanks again.
RONC
Copy link to clipboard
Copied
Solved the location of the image. \ vs / in the file location.
Otherwise inserting an image in iconbutton seems to work. I will try over weekend to use in the sciCALC script.
I also found how to take a png and make into txt so that I can embed in the jsxbin file. Kind of a pain but I modified the image to text script to remove the unnecessary text. Will check it somemore and then upload the script here.
Thanks for help.
RONC
Copy link to clipboard
Copied
Something I didn't mention is that what is shown here is only part of what the user sees. This is a simple calculator but the user gets it plus 70 other buttons (today) with info from external sources that help in processing the images in PS. "Coloring" the keys will be extremely help to the users.
I need to make it run as a palette rather than dialog next. Have some info on Bridgetalk but haven't made it so the palette stays on screen yet. Suggested example script??
RONC
Copy link to clipboard
Copied
var d = new Window("dialog");
d.orientation = "row";
d.alignChildren = "top";
var font = ScriptUI.newFont("Arial", ScriptUI.FontStyle.BOLD, 20);
var text = "Test 123 Test";
var sz0 = [250, 60];
with (d.add("group"))
{
orientation = "column";
d.b1 = add("button", undefined, text);
d.b1.preferredSize = sz0;
d.b1.graphics.font = font;
d.b2 = add("button", undefined, text);
d.b2.preferredSize = sz0;
d.b2.graphics.font = font;
}
with (d.add("group"))
{
orientation = "column";
d.b4 = add("button", undefined, text);
d.b4.preferredSize = sz0;
d.b4.graphics.font = font;
}
var brush = d.graphics.newBrush(d.graphics.BrushType.SOLID_COLOR, [1, 0.7, 0, 0.5] );
var pen = d.graphics.newPen(d.graphics.PenType.SOLID_COLOR,[0,0.5,0,1], 1);
d.b1.onDraw = function()
{
try {
this.graphics.rectPath(0,0,this.size.width,this.size.height);
this.graphics.fillPath(brush);
var sz = this.graphics.measureString(this.text, this.graphics.font);
this.graphics.drawString(this.text, pen, (this.size.width - sz.width)/2, (this.size.height - sz.height)/2);
}
catch(e) { alert(e); }
}
d.show();
Copy link to clipboard
Copied
Thanks for your response.
I don't think I can trust the present Scriptui code. We are using PS 21.1.0 20200212.r.106 2020/02/12: 4dd027efb58 x64 so what you did is of no help other to show problems between 6 and 20. Also I noticed that the button color was set to white on your cc2018-20 version. Hopefully someone with Adobe will fix these problems at some time.
I think that I'm going to insert image files for each button. I have control over the color and actual use other than standard font symbols which will make things cleaner and more user understandable.
RONC
Copy link to clipboard
Copied
Copy link to clipboard
Copied
Can you set the color of each button? The PS6 shows as gray in the rightmost but is white in the 20.
You said the alignment fails also.
RONC
Copy link to clipboard
Copied
I modified your code and it works fine in ESTK but the alignment is wrong in PS 21.
var d = new Window("dialog");
d.orientation = "row";
d.spacing = 0;
d.alignChildren = "top";
var font = ScriptUI.newFont("Arial", ScriptUI.FontStyle.BOLD, 20);
var text = "Test"; // "Test 123 Test";
var sz0 = [90, 30]; // [250, 60];
var text1, text2, text4;
text1 = "tan";
text2 = " ⁿ√X ";
text4 = " Xⁿ ";
with (d.add("group"))
{
orientation = "column";
spacing = 0;
d.b1 = add("button", undefined, text);
d.b1.text = text1;
d.b1.preferredSize = sz0;
d.b1.graphics.font = font;
d.b2 = add("button", undefined, text);
d.b2.text = text2;
d.b2.preferredSize = sz0;
d.b2.graphics.font = font;
}
with (d.add("group"))
{
orientation = "column";
spacing = 0;
d.b4 = add("button", undefined, text);
d.b4.text = text4;
d.b4.preferredSize = sz0;
d.b4.graphics.font = font;
}
var brush1 = d.graphics.newBrush(d.graphics.BrushType.SOLID_COLOR, [1, 0, 0, 1]);
var pen1 = d.graphics.newPen(d.graphics.PenType.SOLID_COLOR, [0, 1, 1, 1], 1);
d.b1.onDraw = function ()
{
try
{
this.graphics.rectPath(0, 0, this.size.width, this.size.height);
this.graphics.fillPath(brush1);
var sz = this.graphics.measureString(this.text, this.graphics.font);
this.graphics.drawString(this.text, pen1, (this.size.width - sz.width) / 2, (this.size.height - sz.height) / 2);
}
catch (e)
{
alert(e);
}
}
var brush2 = d.graphics.newBrush(d.graphics.BrushType.SOLID_COLOR, [0, 1, 0, 1]);
var pen2 = d.graphics.newPen(d.graphics.PenType.SOLID_COLOR, [1, 0, 1, 1], 1);
d.b2.onDraw = function ()
{
try
{
this.graphics.rectPath(0, 0, this.size.width, this.size.height);
this.graphics.fillPath(brush2);
var sz = this.graphics.measureString(this.text, this.graphics.font);
this.graphics.drawString(this.text, pen2, (this.size.width - sz.width) / 2, (this.size.height - sz.height) / 2);
}
catch (e)
{
alert(e);
}
}
var brush4 = d.graphics.newBrush(d.graphics.BrushType.SOLID_COLOR, [0, 0, 1, 1]);
var pen4 = d.graphics.newPen(d.graphics.PenType.SOLID_COLOR, [1, 1, 0, 1], 1);
d.b4.onDraw = function ()
{
try
{
this.graphics.rectPath(0, 0, this.size.width, this.size.height);
this.graphics.fillPath(brush4);
var sz = this.graphics.measureString(this.text, this.graphics.font);
this.graphics.drawString(this.text, pen4, (this.size.width - sz.width) / 2, (this.size.height - sz.height) / 2);
}
catch (e)
{
alert(e);
}
}
d.show();
Color seems to be OK but look at the positioning of tan in PS21. ESTK looks better but it isn't what the user sees.
I'm so lost with all of this. I'm an image handling guy.
Thanks,
RONC
Copy link to clipboard
Copied
If you take the last code I sent and modify the 3 areas that contain the first code below to be like the later code.
Set var fudge = 1.5;
Make this code:
this.graphics.drawString(this.text, pen1, (this.size.width - sz.width) / 2, (this.size.height - sz.height) / 2);
to be:
var ln = text.length;
var scx = (ln + fudge) / ln;
this.graphics.drawString(this.text, pen1, (this.size.width - sz.width / scx) / 2, (this.size.height - sz.height) / 2);
It looks like the Extendscript code has an error in estimating the string length by an amount something like (length + 1.5) / length. Looks pretty good to me. I made the font size like 200 and the button 600 x 400 and measured the error now and it is way smaller. Enough for me to clone your code.
RONC
Copy link to clipboard
Copied
d.b1.onDraw = function()
{
try {
this.graphics.rectPath(0,0,this.size.width,this.size.height);
this.graphics.fillPath(brush);
var tmp = "_________________________________________________________________________________________________________________";
var sz1 = this.graphics.measureString(tmp+this.text+tmp, this.graphics.font);
var sz2 = this.graphics.measureString(tmp+tmp, this.graphics.font);
var sz = { width: sz1.width-sz2.width, height:sz1.height };
this.graphics.drawString(this.text, pen, (this.size.width - sz.width)/2, (this.size.height - sz.height)/2);
}
catch(e) { alert(e); }
}
Copy link to clipboard
Copied
I think we have a different meaning of alignment. You were looking at the alignment between rows. Because the text will differ from button to button, my biggest concern is whether the text is centered within the button. This is why I came up with the fudge parameter. With using it, most of my tests get the text centered to reasonable degree with kerning involve.
I have two ways to go. Use my latest version of your code or use images for the buttons. I have think more about it but I need to get back to doing my science on images and forget about Extendscript and all of its bugs.
My latest version of your code:
// rbin.jsx from r-bin
/**
* @@@BUILDINFO@@@ rbin.jsx !Version! Sat Feb 29 2020 06:47:50 GMT-0600
*/
var keyGroup = [];
var keyNo = [];
var i, j;
var dlg = new Window("dialog");
dlg.orientation = "row";
dlg.spacing = 0;
dlg.alignChildren = "top";
var fontSize = 150;
var font = ScriptUI.newFont("Arial", ScriptUI.FontStyle.BOLD, fontSize);
var text = "Test"; // "Test 123 Test";
//var sz0 = [90, 30]; // [250, 60];
var sz0 = [fontSize * 4.5, fontSize * 1.5];
dlg.preferredSize = sz0;
var fudge = 1.5;
var keyText = ["tan", "ⁿ√X", "Xⁿ", "████"]; // "█ýM█"
j = 0;
i = 0;
keyGroup[j] = dlg.add("group");
keyGroup[j].orientation = "column";
keyGroup[j].spacing = 0;
keyNo[i] = keyGroup[j].add("button", undefined, text);
keyNo[i].text = keyText[i];
keyNo[i].preferredSize = sz0;
keyNo[i].graphics.font = font;
keyNo[i].brush = dlg.graphics.newBrush(dlg.graphics.BrushType.SOLID_COLOR, [1, 0, 0, 1]);
keyNo[i].pen = dlg.graphics.newPen(dlg.graphics.PenType.SOLID_COLOR, [0, 1, 1, 1], 1);
keyDraw(i);
i++;
keyNo[i] = keyGroup[j].add("button", undefined, text);
keyNo[i].text = keyText[i];
keyNo[i].preferredSize = sz0;
keyNo[i].graphics.font = font;
keyNo[i].brush = dlg.graphics.newBrush(dlg.graphics.BrushType.SOLID_COLOR, [0, 1, 0, 1]);
keyNo[i].pen = dlg.graphics.newPen(dlg.graphics.PenType.SOLID_COLOR, [1, 0, 1, 1], 1);
keyDraw(i);
j++;
keyGroup[j] = dlg.add("group");
keyGroup[j].orientation = "column";
keyGroup[j].spacing = 0;
i++;
keyNo[i] = keyGroup[j].add("button", undefined, text);
keyNo[i].text = keyText[i];
keyNo[i].preferredSize = sz0;
keyNo[i].graphics.font = font;
keyNo[i].brush = dlg.graphics.newBrush(dlg.graphics.BrushType.SOLID_COLOR, [0, 0, 1, 1]);
keyNo[i].pen = dlg.graphics.newPen(dlg.graphics.PenType.SOLID_COLOR, [1, 1, 0, 1], 1);
keyDraw(i);
i++;
keyNo[i] = keyGroup[j].add("button", undefined, text);
keyNo[i].text = keyText[i];
keyNo[i].preferredSize = sz0;
keyNo[i].graphics.font = font;
keyNo[i].brush = dlg.graphics.newBrush(dlg.graphics.BrushType.SOLID_COLOR, [1, 0, 1, 1]);
keyNo[i].pen = dlg.graphics.newPen(dlg.graphics.PenType.SOLID_COLOR, [1, 1, 1, 1], 1);
keyDraw(i);
dlg.show();
function keyDraw(i)
{
keyNo[i].onDraw = function ()
{
try
{
this.graphics.rectPath(0, 0, this.size.width, this.size.height);
this.graphics.fillPath(keyNo[i].brush);
var sz = this.graphics.measureString(this.text, this.graphics.font);
if (sz.width >= this.size.width)
{
alert(sz.width + " " + this.size.width);
e = -1;
}
var ln = text.length;
var scx = (ln + fudge) / ln;
this.graphics.drawString(this.text, keyNo[i].pen, (this.size.width - sz.width / scx) / 2, (this.size.height - sz.height) / 2);
}
catch (e)
{
alert(e);
}
};
}
How should I handle the error if the text is bigger than the button? I have an if statement and alert message but how do cancel the run?
RONC