Exit
  • Global community
    • Language:
      • Deutsch
      • English
      • Español
      • Français
      • Português
  • 日本語コミュニティ
  • 한국 커뮤니티
0

Script UI - Dynamically autosizing statictext

Engaged ,
Apr 17, 2025 Apr 17, 2025

@Peter Kahrel , @Eugene Tyson , @Marc Autret 

 

I'm sure this has been asked before, but I could not find a solution.

 

I've never been able to post images to this forum. See https://github.com/Marshall-Brooks/Sandbox/issues/2 for images.

 

I created (with help) a custom confimation script here: https://community.adobe.com/t5/indesign-discussions/autoclose-alert-message-and-custom-confirm-messa...

 

I needed the script to dynamically change size. The displayed text might be one line or 3 or 4 paragraphs when the script is called. I added the {multiline=true} parameter. See the link above for the results. If the link vanishes:

 

var msg = win.add("statictext", undefined, message, {multiline: true});

Probably works and autosizes, but the text is wrapping before it gets to half the width of the window.

var msg = win.add("statictext",  [5, 5, 500, 200], message, {multiline: true});

Works fine, but I think the script will not display if it goes beyond the borders, and the message takes up half the screen for a 1-line message.

var msg = win.add("statictext", [5, undefined, 500, undefined], message, {multiline: true});

Didn't display any text at all.

I think the characters property is supposed to allow this, but:

var msg = win.add("statictext",  undefined, message, {characters: 300, multiline: true});

Didn't seem to do anything?

I hope it isn't going to turn into something like having to count the number of characters and line feeds and size the window based on the results.

 

Thanks in advance!!!

 

TOPICS
Scripting
501
Translate
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

correct answers 2 Correct answers

Guide , Apr 18, 2025 Apr 18, 2025
var w = new Window('dialog', 'Autosize Test');
    w.margins = 20;

    // Dialog Width To Be Defined:
    var w_width = 400;

    // Stactic Text To Be Defined:
    w_statictext = 'This is a dynamically sized message. It can be short or it can be very long. \nIt should wrap nicely and the box should grow vertically to fit the text without cutting off or overflowing weirdly. \n\nThis Solution is not mine but written by Marc Autret from Indiscripts in July 2013.';

    var st = w.add('statictext'
...
Translate
Engaged , Apr 23, 2025 Apr 23, 2025

Fixed. Works with non-default font sizes (if allowed). Shows single-line if short enough, or wraps otherwise.

The value in the "if" statement will need to change if you use a wider window or a different font face or size:


EDIT: Had to make a minor change to the "if" statement, the original script would fail (display only one line) if w_statictext was less than 80 characters and had manual line feeds, e.g.:

w_statictext = "Line 1\rLine2";

EDIT2 - Had to update the if statement - not found is -1, not

...
Translate
Community Expert ,
Apr 17, 2025 Apr 17, 2025

Multiline means that text will be wrapped - but it's up to you to define width and height of the area = you'll have to do the math yourself. 

 

Translate
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 ,
Apr 17, 2025 Apr 17, 2025

Hi @Marshall_Brooks, one approach that often works well is to set the edittext's

alignment: ['fill', 'fill']

That should fill the parent container. If it doesn't work, check if you parent container is also set to fill it's container.

 

If that's no good, then it might be worth posting the full code for your simple example dialog here.

- Mark 

Translate
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 ,
Apr 17, 2025 Apr 17, 2025

I don't know if you're aware of this tool - maybe it can help:

https://scriptui.joonas.me/

Translate
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 ,
Apr 18, 2025 Apr 18, 2025

Seems to work ok for me

var message = "This is a long message that should scroll if it overflows. This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows.This is a long message that should scroll if it overflows."

var win = new Window("dialog", "Scrollable Message Box");

// Group to contain the scrollable text
var group = win.add("group");
group.orientation = "column";
group.alignChildren = ["fill", "top"];
group.margins = 10;

// Scrollable EditText instead of statictext
var msg = group.add("edittext", undefined, message, {
    multiline: true,
    readonly: true,
    scrolling: true
});
msg.preferredSize = [400, 200]; // Set dimensions
msg.alignment = ["fill", "top"];

var ok = group.add("button", undefined, "OK", {name: "ok"});

win.defaultElement = ok;
ok.onClick = function () {
    win.close();
};

win.center();
win.show();
Translate
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 ,
Apr 18, 2025 Apr 18, 2025

This also works - but when the message is very long it eats up the screen real estate

 

var message = "This is a dynamically sized message. It can be short or it can be very long.\n\nIt should wrap nicely and the box should grow vertically to fit the text without cutting off or overflowing weirdly. ";

var win = new Window("dialog", "Autosize Test");
var group = win.add("group");
group.orientation = "column";
group.alignChildren = ["fill", "top"];
group.margins = 10;

// Create a statictext that fills width and grows with content
var msg = group.add("statictext", undefined, message, {multiline: true});
msg.maximumSize.width = 400;
msg.minimumSize.width = 400;
msg.alignment = ["fill", "top"];

win.layout.layout(true);
win.center();
win.show();
Translate
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 ,
Apr 18, 2025 Apr 18, 2025

@Marshall_Brooks 

 

A resizable window doesn't see when it gets overset. You'll have to set a minimum size.

Translate
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
Guide ,
Apr 18, 2025 Apr 18, 2025
var w = new Window('dialog', 'Autosize Test');
    w.margins = 20;

    // Dialog Width To Be Defined:
    var w_width = 400;

    // Stactic Text To Be Defined:
    w_statictext = 'This is a dynamically sized message. It can be short or it can be very long. \nIt should wrap nicely and the box should grow vertically to fit the text without cutting off or overflowing weirdly. \n\nThis Solution is not mine but written by Marc Autret from Indiscripts in July 2013.';

    var st = w.add('statictext', undefined, 'X', {multiline: true});
    var X_width = st.preferredSize[0];
    with(st){preferredSize = [-1,-1]; characters = ~~(w_width/X_width); preferredSize[1] = -1;};
    st.text = w_statictext;

    // "Close" Button:
    w.add('button', undefined, 'Close', {name: 'OK'});

w.show();

 

(^/)  The Jedi

Translate
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 ,
Apr 18, 2025 Apr 18, 2025

Excellent! I've bookmarked this - took me a while to find it! 

 

https://indiscripts.com/post/2013/12/indesign-scripting-forum-roundup-5#hd3:~:text=message/5692242%2...

 

 

Translate
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 ,
Apr 18, 2025 Apr 18, 2025

Thanks for the reminder, Michel.

Translate
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 ,
Apr 21, 2025 Apr 21, 2025

@FRIdNGE 

Awesome!!! I ran into one issue with the script and want to make sure it isn't something I did wrong, or if it is something I need to watch out for in the future.

I'm assuming w_width controls the width of the static text window, which in turn controls the window size. In my script, everything worked at w_width 400, or 450, or 600, but at 500, part of the message got cut off. Here's the script (This is at 1920x1200x Resolution, if that matters (Script mainly written by @Eugene Tyson Set Font by @Peter Kahrel :

function AutocloseAlert(message, delaySeconds, title, bgcolor) {
    title = title || "Script Alert";
    delaySeconds = delaySeconds || 0
    bgcolor = bgcolor || "gray";

     if(delaySeconds===0){
            var win = new Window("dialog", title, undefined, {closeButton:false});
    }
    else{
        var win = new Window("palette", title, undefined, {closeButton:false});
    }
    win.margins = 20;
    win.orientation = "column";
    win.alignChildren = "center";
    if(bgcolor==="white"){
        win.graphics.backgroundColor = win.graphics.newBrush (win.graphics.BrushType.SOLID_COLOR, [1.0, 1.0, 1.0]);
    }
    // Dialog Width To Be Defined:
    var w_width = 500;    
    var msg = win.add("statictext", undefined, 'X', {multiline: true});
    var X_width = msg.preferredSize[0];
    with (msg){preferredSize = [-1,-1]; characters = ~~(w_width/X_width); preferredSize[1] = -1;};
    msg.text=message 
    if (delaySeconds>0){
        var btn = win.add("button", undefined, "OK (" + delaySeconds + ")");
    }
    else{
        var btn = win.add("button", undefined, "OK",{name: "ok"});      
    }

    var cancelled = false;

    // Function for button click
    btn.onClick = function () {
        cancelled = true;
        win.close();
        $.writeln("User clicked OK");
    };

    // Show the window
    set_font (win, "Tahoma:14");
    win.show();

    if (delaySeconds>0){
        // Countdown loop
        while (delaySeconds > 0 && !cancelled) {
            $.sleep(1000); // wait 1 second
            delaySeconds--;
            try {
                if(delaySeconds > 0){    
                    btn.text = "OK (" + delaySeconds + ")";
                }
                else {
                    btn.text = "OK";   
                }
                //win.update();  // Force the window to update
            } catch (e) {
                break; // window might be closed already
            }
        }

        // Close window after countdown, unless user clicked OK
        if (!cancelled) {
            win.close();
            $.writeln("Auto-closed after timeout");
        }
    }
} // End AutocloseAlert

function set_font (control, font) {
    for (var i = 0; i < control.children.length; i++) {
    if ("GroupPanel".indexOf (control.children[i].constructor.name) > -1)
    set_font (control.children[i], font);
    else
    control.children[i].graphics.font = font;
    }
}//--end set_font;

AutocloseAlert("This message will close in 5 seconds. Checking for a really long message. Not that it matters.", 5, "Autoclose Alert");

EDIT: This may just be a by-product of Autosizing. I've seen similar things with Enhanced Message Box for MS Access. Doesn't happen often, but I've seen it happen.
EDIT2: I'm not sure if set_font might be affecting the message also ...

 

Translate
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 ,
Apr 21, 2025 Apr 21, 2025

Solved:

var X_width = 1.4*msg.preferredSize[0];

The assumes the default font width is 10 pt and that set_font is changing it to 14 points. Would need a different modifier for different font sizes.

EDIT - Does not seem to work consistently.
@Eugene Tyson - 2nd message that eats up screen real estate seems to not truncate, but leaves several blank lines below the message. It almost seems like it figures out the height of the initial message and then does reduce the height when the window is made wider.

 

Translate
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 ,
Apr 21, 2025 Apr 21, 2025

@Peter Kahrel@Marc Autret@FRIdNGE 

 

Figured out a little bit more. The script seems to drop off the last word (or more) that fits the window if I am using Set Font.

Example:

var w = new Window('dialog', 'Autosize Test');
    w.margins = 20;

    // Dialog Width To Be Defined:
    var w_width = 400;

    // Stactic Text To Be Defined:
    w_statictext = 'This is a dynamically sized message. It can be short or it can be very long. \nIt should wrap nicely and the box should grow vertically to fit the text without cutting off or overflowing weirdly. \n\nThis Solution is not mine but written by Marc Autret from Indiscripts in July 2013.';

    var st = w.add('statictext', undefined, 'X', {multiline: true});
    var X_width = st.preferredSize[0];
    with(st){preferredSize = [-1,-1]; characters = ~~(w_width/X_width); preferredSize[1] = -1;};
    st.text = w_statictext;

    // "Close" Button:
    w.add('button', undefined, 'Close', {name: 'OK'});
set_font (w, "Tahoma:14");
w.show();


function set_font (control, font) {
    for (var i = 0; i < control.children.length; i++) {
    if ("GroupPanel".indexOf (control.children[i].constructor.name) > -1)
    set_font (control.children[i], font);
    else
    control.children[i].graphics.font = font;
    }
}//--end set_font;

If you run this, it truncates "Autret from Indescripts in July 2013."

Empirically, I can get it working fairly well by changing the "with" line to:

with(st){preferredSize = [-1,-1]; characters = ~~(w_width/X_width+20); preferredSize[1] = -1;};

For Font Tahoma 14 and window size 400, but I don't know that that always works or that that would work for other window sizes or for all messages. Really, I'm not sure what that does, but it seems to minimize the errors.

Translate
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 ,
Apr 21, 2025 Apr 21, 2025

Follow up question:

  • The above with the Width +20 seems to work fine for long messages using a 400 px window.
  • For a short message, for example "This is a dynamically sized message", it would work better and be more professional with a shorter window", if I commment out the sizing code, it wraps before it needs to. If I don't, it makes a wide window.
  • If there a way to say "If (w_staticttext.width < w_width){ w_width = w_statictext.width}" For example, for "This is a dynamically sized message." 80 would work best, but I don't know how to figure w_statictext.width.
  • Code would look something like this:

var w = new Window('dialog', 'Autosize Test');
w.margins = 20;

// Dialog Width To Be Defined:
var w_width = 400;

// Stactic Text To Be Defined:
w_statictext = 'This is a dynamically sized message.';
if (w_statictext.width< w_width) { \\ w_statictext.width=width of w_statictext in pixels, but I don't know how to figure this out?

     w_width=w_statictext.width

}

var st = w.add('statictext', undefined, 'X', {multiline: true});
var X_width = st.preferredSize[0];
with(st){preferredSize = [-1,-1]; characters = ~~(w_width/X_width+20); preferredSize[1] = -1;};
st.text = w_statictext;

// "Close" Button:
w.add('button', undefined, 'Close', {name: 'OK'});
set_font (w, "Tahoma:14");
w.show();


function set_font (control, font) {
for (var i = 0; i < control.children.length; i++) {
if ("GroupPanel".indexOf (control.children[i].constructor.name) > -1)
set_font (control.children[i], font);
else
control.children[i].graphics.font = font;
}
}//--end set_font;

Translate
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 ,
Apr 21, 2025 Apr 21, 2025

Back to square 1 - I can't get the script to work CONSISTENLTY with set_font = Tahoma 14 pt.

characters = ~~(w_width/X_width+20) \\ (or 25, or 30, or 35) usually works

characters =  ~~(w_width/X_width/1.4) \\ (or 1.5 or 1.6 or 1.7) sometimes works.

 

ScriptUI supports lenght for string variables and since in the example above, a 36 character string works with an 80 pixel window, something like this should work:

if (w_statictext.length*2.2<w_width){
w_width = w_statictext.length*2.2;
}

But since I can't get it to wrap consistently, it's hard to tell.

Translate
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 ,
Apr 21, 2025 Apr 21, 2025

@Marshall_Brooks

 

Shouldn't this:

 

(w_width/X_width/1.4) 

 

rather be: 

 

((w_width/X_width) * 1.4)

 

?? 

Translate
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 ,
Apr 22, 2025 Apr 22, 2025

@Robert at ID-Tasker - I tried that first and it didn't work either, but you are dividing by the width of X above.

I don't have time to play with it right now, but I think I need to apply the font to the static text first and then the formula should work, and then I can test the length of the message text and use single-line if it is less than one line long.

Translate
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 ,
Apr 22, 2025 Apr 22, 2025

Remember that from InDesign CC you can't set font or point size in ScriptUI windows.

Translate
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 ,
Apr 22, 2025 Apr 22, 2025

@Peter Kahrel - Highly confused. I'm setting font and point size from the set_font function in your guide. It works fine. What doesn't work properly is the line wrapping (perhaps b/c I'm changing the font after the text wrapping is determined) (And the window title, but that's a known issue - as is the standard alert() and confirm() statements, which is why I'm trying to create my own).

(Technically, I'm using this in FrameMaker, not InDesign, if that is what you are referring to, but I was instructed on the Adobe FrameMaker forums to ask Script UI questions here.)

Translate
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 ,
Apr 22, 2025 Apr 22, 2025

There's a note on p. 78 that says that fonts and type size can't be changed in InDesign from CC. But ScriptUI works a bit different in the apps that use it, so if in FrameMaker it works, count yourself lucky!

 

> What doesn't work properly is the line wrapping (perhaps b/c I'm changing the font after the text wrapping is determined)

 

That makes sense. You should change the font, then do the calculations needed for the wrapping.

 

Translate
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 ,
Apr 22, 2025 Apr 22, 2025

@Peter Kahrel - Thanks, I'm used to the inconsistencies, although not being able to change it would drive me nuts.
@Eugene Tyson made an auto-close message box for me and clicking OK works fine in ESTK. Does nothing in FrameMaker ...
I'll report results after I play some more with the font sizing.
Question, while I've got your attention - is there any easy way to calculate the width of W_statictext?

What I want is  the box to wrap if the text is more than one line and auto-shrink if the box is less.
I'm thinking code will be something like:

var w = new Window('dialog', 'Autosize Test');
    w.margins = 20;

    // Dialog Width To Be Defined:
    var w_width = 400;

    // Stactic Text To Be Defined:
    w_statictext = 'This is a dynamically sized message. It can be short or it can be very long. \nIt should wrap nicely and the box should grow vertically to fit the text without cutting off or overflowing weirdly. \n\nThis Solution is not mine but written by Marc Autret from Indiscripts in July 2013.';
// If less than one line, is there a better way to calculate this?
if (w_statictext.length < 31) {
// single line
     var st = w.add('statictext', undefined, 'X');
}
else{
// is this the correct way to set the font?
    var st = w.add('statictext', undefined, 'X', {multiline: true, .graphics.font=Tahoma:14});
    var X_width = st.preferredSize[0];
    with(st){preferredSize = [-1,-1]; characters = ~~(w_width/X_width); preferredSize[1] = -1;};
    st.text = w_statictext;
}
    // "Close" Button:
    w.add('button', undefined, 'Close', {name: 'OK'});

w.show();

The length<31 is just a guess, but I'm thinking I can set length<1 which will force it to multiline, screen shot that, and then increase the length value until the window is wider than the screenshot.

 

Unless you know a better solution?

 

 

Translate
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 ,
Apr 23, 2025 Apr 23, 2025
LATEST

Fixed. Works with non-default font sizes (if allowed). Shows single-line if short enough, or wraps otherwise.

The value in the "if" statement will need to change if you use a wider window or a different font face or size:


EDIT: Had to make a minor change to the "if" statement, the original script would fail (display only one line) if w_statictext was less than 80 characters and had manual line feeds, e.g.:

w_statictext = "Line 1\rLine2";

EDIT2 - Had to update the if statement - not found is -1, not 0. 

Final (???) Script:

var w = new Window('dialog', 'Autosize Test');
    w.margins = 10;

    // Dialog Width To Be Defined:
    var w_width = 450;

    // Stactic Text To Be Defined:
    w_statictext = 'This is a dynamically sized message. It can be short or it can be very long. \nIt should wrap nicely and the box should grow vertically to fit the text without cutting off or overflowing weirdly. \n\nThis Solution is not mine but written by Marc Autret from Indiscripts in July 2013.';
//  80 below is somewhat arbitrary. Run the script and see where the first line ends. Adjust w_static text to a bit longer than that. Uncomment the line below to get the text length, Use that in the "if" statement.
//alert (w_statictext.length)
if (w_statictext.length < 80 && w_statictext.indexOf("\r")===-1 && w_statictext.indexOf("\n")===-1) {
// single line
     var st = w.add('statictext', undefined, w_statictext);
}
else{
// multiline    
    var st = w.add('statictext', undefined, 'X', {multiline: true});
    // if not using standard font size, Font must be defined below, even if using set_font, or the message will truncate unpredictably.
    st.graphics.font="Tahoma:14";
    var X_width = st.preferredSize[0];
    with(st){preferredSize = [-1,-1]; characters = ~~(w_width/X_width); preferredSize[1] = -1;};
    st.text = w_statictext;
}
    // "Close" Button:
    w.add('button', undefined, 'Close', {name: 'OK'});
set_font (w, "Tahoma:14");
w.show();

function set_font (control, font) {
    for (var i = 0; i < control.children.length; i++) {
    if ("GroupPanel".indexOf (control.children[i].constructor.name) > -1)
    set_font (control.children[i], font);
    else
    control.children[i].graphics.font = font;
    }
}//--end set_font;

 

Translate
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