Skip to main content
rechmbrs
Inspiring
February 26, 2020
Answered

Color a button in Scriptui and text positioning.

  • February 26, 2020
  • 2 replies
  • 8317 views

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();
*/

This topic has been closed for replies.
Correct answer r-bin

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


Alignment is the center of the button.
The top window is your code. Mean is my code. Bottom is the native button alignment without onDraw.
As you can see, my alignment is the same as my native one and without any obscure coefficients.
 
 

 

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 = "_________________________________________________________________________________________________________________";
        
            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, keyNo[i].pen, (this.size.width - sz.width)/2, (this.size.height - sz.height)/2);
        }            
        catch (e)
        {
            alert(e);
        }
    };
}

 

2 replies

Brainiac
February 29, 2020
I don’t know what your problem is, maybe I misunderstood.
I never drew user controls in the interface.
Here is a code made from yours that seems to align correctly on CS6.
 

 

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();

 

 


On CC2018-20, alignment fails.
It is also seen that the font on the standard button is different from what is in CS6. In addition, in CC2018-20, the font size differs on the drawn button and the standard one. There is no such difference in CS6.
 
rechmbrs
rechmbrsAuthor
Inspiring
February 29, 2020

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

Brainiac
February 29, 2020
Explain the problem again. What does not suit the code and where are the problems.
The buttons on my PS 21.1 are white because I like it and I use a bright theme.
 
Brainiac
February 26, 2020

The button will automatically adjust to accommodate the text label.

rechmbrs
rechmbrsAuthor
Inspiring
February 26, 2020

Not if I declare the button size beforehand.  Please look at the attached code. 

RONC 

Brainiac
February 26, 2020

Do not use size, use preferredSize as Adobe recommends.