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

Script UI issue- Script allows change of W & H of many selected things at once

Contributor ,
Dec 11, 2023 Dec 11, 2023

Hello 

 

I have been working on a script that allows one to select many obects at the same time and change each objects width and height. 

 

SmythWharf_0-1702336045382.png

As you can see from the sample above ID once you select all objects gives you a width for everything slected - no good if you need to change each of these or more objects , you must do it one by one 


So the below is the script which works but has an UGLY ui 

// Function to change the size of a selected object
function changeSize(selection, newWidth, newHeight) {
for (var i = 0; i < selection.length; i++) {
var item = selection[i];

// Calculate the change from the center
var widthChange = (newWidth - (item.geometricBounds[3] - item.geometricBounds[1])) / 2;
var heightChange = (newHeight - (item.geometricBounds[2] - item.geometricBounds[0])) / 2;

// Set the size of the object while keeping it centered
item.geometricBounds = [
item.geometricBounds[0] - heightChange,
item.geometricBounds[1] - widthChange,
item.geometricBounds[2] + heightChange,
item.geometricBounds[3] + widthChange
];
}
}

// Main function to be executed within app.doScript()
function main() {
var doc = app.activeDocument;

// Check if there is any open document
if (doc !== null) {
// Check if there is any selection
if (doc.selection.length > 0) {
var selection = doc.selection;

// Prompt the user for new width and height dimensions
var newWidth = prompt("Enter the new width for the objects:", "100");
var newHeight = prompt("Enter the new height for the objects:", "100");

// Check if the user clicked Cancel or entered empty values
if (newWidth !== null && newWidth !== "" && newHeight !== null && newHeight !== "") {
// Convert the inputs to numbers
newWidth = parseFloat(newWidth);
newHeight = parseFloat(newHeight);

// Check if the inputs are valid numbers
if (!isNaN(newWidth) && !isNaN(newHeight)) {
// Call the function to change the size of selected objects
changeSize(selection, newWidth, newHeight);
} else {
alert("Invalid input. Please enter valid numbers for the new width and height.");
}
}
} else {
alert("Please select at least one object.");
}
} else {
alert("No open document found.");
}
}

// Use app.doScript() to make the script undoable
app.doScript(main, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Change Size");

 

 


And I want a UI to look more like the one below 

// Function to change the size of a selected object
function changeSize(selection, newWidth, newHeight) {
for (var i = 0; i < selection.length; i++) {
var item = selection[i];

// Calculate the change from the center
var widthChange = (newWidth - (item.geometricBounds[3] - item.geometricBounds[1])) / 2;
var heightChange = (newHeight - (item.geometricBounds[2] - item.geometricBounds[0])) / 2;

// Set the size of the object while keeping it centered
item.geometricBounds = [
item.geometricBounds[0] - heightChange,
item.geometricBounds[1] - widthChange,
item.geometricBounds[2] + heightChange,
item.geometricBounds[3] + widthChange
];
}
}

// Main function to be executed within app.doScript()
function main() {
var doc = app.activeDocument;

// Check if there is any open document
if (doc !== null) {
// Check if there is any selection
if (doc.selection.length > 0) {
// Create a dialog box
var myDialog = app.dialogs.add({ name: "Set Width and Height" });

// Create a column for the dialog
var myDialogColumn = myDialog.dialogColumns.add();

// Add a row for width
var widthRow = myDialogColumn.dialogRows.add();
widthRow.staticTexts.add({ staticLabel: "Width:" });
var widthInput = widthRow.textEditboxes.add({ editValue: "100", minWidth: 60 });

// Add a row for height
var heightRow = myDialogColumn.dialogRows.add();
heightRow.staticTexts.add({ staticLabel: "Height:" });
var heightInput = heightRow.textEditboxes.add({ editValue: "100", minWidth: 60 });

// Add OK and Cancel buttons
var myResult = myDialog.show({
name: "OKCancel"
});

// Check if the user clicked OK
if (myResult == true) {
// Get the input values
var newWidth = parseFloat(widthInput.editValue);
var newHeight = parseFloat(heightInput.editValue);

// Check if the inputs are valid numbers
if (!isNaN(newWidth) && !isNaN(newHeight)) {
// Call the function to change the size of selected objects
changeSize(doc.selection, newWidth, newHeight);
} else {
alert("Invalid input. Please enter valid numbers for the new width and height.");
}
}
} else {
alert("Please select at least one object.");
}
} else {
alert("No open document found.");
}
}

// Use app.doScript() to make the script undoable
app.doScript(main, ScriptLanguage.JAVASCRIPT, [], UndoModes.ENTIRE_SCRIPT, "Change Size");

 

 

I have been having issues as the user input values are not being passed through the UI panel to the script

Any ideas on how to fix would be most appreciated

 

Many thanks 

 

Smyth




TOPICS
How to , Scripting , SDK
1.4K
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 3 Correct answers

Contributor , Dec 12, 2023 Dec 12, 2023

Use this

var widthEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.horizontalMeasurementUnits});
var heightEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.verticalMeasurementUnits});
Translate
Contributor , Dec 12, 2023 Dec 12, 2023

Here is the full script:

 

// Wrap the script in app.doScript for a single undoable step
app.doScript(function() {
    // Define the dialog
    var myDialog = app.dialogs.add({name: "Change Object Size"});
    with (myDialog.dialogColumns.add()) {
        with (dialogRows.add()) {
            with (dialogColumns.add()) {
                staticTexts.add({staticLabel: "Width:"});
                staticTexts.add({staticLabel: "Height:"});
            }
            with (dialogColumns.add()) {
       
...
Translate
Community Expert , Dec 13, 2023 Dec 13, 2023

Another way to do this is set your scriptingPreferences meaurement units to points, which I’m doing in my sample above—there could be cases where forcing a unit conversion via unitValue fails. See Marc Auret’s post in this thread:

 

https://community.adobe.com/t5/indesign-discussions/indesign-javascript-document-dimensions-width-and-height-in-pixels-or-any-unit/m-p/14274443#M553125

 

scriptPreferences has the useful measurementUnit setter

 

 

app.scriptPreferences.measurementUnit = MeasurementUn
...
Translate
Contributor ,
Dec 11, 2023 Dec 11, 2023

Try using 'measurementEditboxes' instead of 'textEditboxes'?

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
Contributor ,
Dec 12, 2023 Dec 12, 2023

Hello, 

Thank you Thunder-lightning for your feedback, I have changed the script accordingly and will post soon

 

Many thanks 

 

Smyth

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 ,
Dec 12, 2023 Dec 12, 2023

This is not a ScriptUI problem: you're using InDesign's native dialog system.

In the title of your question, please change 'Script UI issue' to 'Script dialog issue'.

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
Contributor ,
Dec 12, 2023 Dec 12, 2023

Cool, thank you

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 ,
Dec 12, 2023 Dec 12, 2023

Hi @SmythWharf , As @Thunder-Lightning  suggests the built in dialog class has the measurementEditbox, which lets the user enter any unit, and converts the unit to Points, so you need to use points in your main script. Here’s an example where I’ve set the default to Inches and set scriptPreferences.measurmentUnit to Points:

 

 

 

var w, h;
makeDialog();
function makeDialog(){
    var d = app.dialogs.add({name:"Dimensions", canCancel:true});
    with(d.dialogColumns.add()){
        staticTexts.add({staticLabel:"Width:"});
        staticTexts.add({staticLabel:"Height:"});
    }
    with(d.dialogColumns.add()){
        w = measurementEditboxes.add({editUnits:MeasurementUnits.INCHES, editValue:360, minWidth:90});
        h = measurementEditboxes.add({editUnits:MeasurementUnits.INCHES, editValue:216, minWidth:90});
    }

    if(d.show() == true){
        w = w.editValue;
        h = h.editValue;
        main()
        d.destroy();
	}
}


function main(){
    app.activate()
    app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
    alert("Width: " + w + "  Height: " + h)
    app.scriptPreferences.measurementUnit = AutoEnum.AUTO_VALUE;
}

 

 

 

Screen Shot 8.pngScreen Shot 10.png

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
Contributor ,
Dec 12, 2023 Dec 12, 2023

Hello, 

 

I had a look at the code and will take on board the ideas  thank you, 

Smyth

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
Contributor ,
Dec 12, 2023 Dec 12, 2023

Hello all thanks for this 

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
Contributor ,
Dec 12, 2023 Dec 12, 2023

Use this

var widthEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.horizontalMeasurementUnits});
var heightEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.verticalMeasurementUnits});
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
Contributor ,
Dec 12, 2023 Dec 12, 2023

Thank you so much  that worked 

Ugh i have to change so many scripts ha!


// Wrap the script in app.doScript for a single undoable step
app.doScript(function() {
// Define the dialog
var myDialog = app.dialogs.add({name: "Change Object Size"});
with (myDialog.dialogColumns.add()) {
with (dialogRows.add()) {
with (dialogColumns.add()) {
staticTexts.add({staticLabel: "Width:"});
staticTexts.add({staticLabel: "Height:"});
}
with (dialogColumns.add()) {
// Set the measurement units for the edit boxes
var widthEditbox = measurementEditboxes.add({editUnits: app.activeDocument.viewPreferences.horizontalMeasurementUnits});
var heightEditbox = measurementEditboxes.add({editUnits: app.activeDocument.viewPreferences.verticalMeasurementUnits});
}
}
}

// Show the dialog
if (myDialog.show() == true) {
// Get the user input values
var newHeight = widthEditbox.editValue;
var newWidth = heightEditbox.editValue;

// Close the dialog
myDialog.destroy();

// Get the selected objects
var selectedObjects = app.activeDocument.selection;

// Loop through selected objects and change their size from the center
for (var i = 0; i < selectedObjects.length; i++) {
var currentObject = selectedObjects[i];

// Check if the selected object is a valid page item
if (currentObject.hasOwnProperty("geometricBounds")) {
// Get the current geometric bounds
var currentBounds = currentObject.geometricBounds;

// Calculate the center of the current bounds
var centerX = (currentBounds[0] + currentBounds[2]) / 2;
var centerY = (currentBounds[1] + currentBounds[3]) / 2;

// Calculate the new bounds
var newBounds = [
centerX - newWidth / 2,
centerY - newHeight / 2,
centerX + newWidth / 2,
centerY + newHeight / 2
];

// Apply the new geometric bounds
currentObject.geometricBounds = newBounds;
}
}
} else {
// Dialog was canceled
myDialog.destroy();
}
}, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Change Object 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
Contributor ,
Dec 12, 2023 Dec 12, 2023

Ah i was too early to reply 

when I input a value that is based on a document unit measurement the script i think is converting it to points but it seems to mess up the size of what i put in so for example 10mms i want changed to 20mms but the result is 56.693 mm or if i am in pixels i would need 10px to become 20px and so on

// Wrap the script in app.doScript for a single undoable step
app.doScript(function() {
    // Define the dialog
    var myDialog = app.dialogs.add({name: "Change Object Size"});
    with (myDialog.dialogColumns.add()) {
        with (dialogRows.add()) {
            with (dialogColumns.add()) {
                staticTexts.add({staticLabel: "Width:"});
                staticTexts.add({staticLabel: "Height:"});
            }
            with (dialogColumns.add()) {
                var widthEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.horizontalMeasurementUnits});
                var heightEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.verticalMeasurementUnits});
            }
        }
    }

    // Show the dialog
    if (myDialog.show() == true) {
        // Get the user input values
        var newHeight = widthEditbox.editValue;
        var newWidth = heightEditbox.editValue;

        // Close the dialog
        myDialog.destroy();

        // Get the selected objects
        var selectedObjects = app.activeDocument.selection;

        // Loop through selected objects and change their size from the center
        for (var i = 0; i < selectedObjects.length; i++) {
            var currentObject = selectedObjects[i];

            // Check if the selected object is a valid page item
            if (currentObject.hasOwnProperty("geometricBounds")) {
                // Get the current geometric bounds
                var currentBounds = currentObject.geometricBounds;

                // Calculate the center of the current bounds
                var centerX = (currentBounds[0] + currentBounds[2]) / 2;
                var centerY = (currentBounds[1] + currentBounds[3]) / 2;

                // Calculate the new bounds
                var newBounds = [
                    centerX - newWidth / 2,
                    centerY - newHeight / 2,
                    centerX + newWidth / 2,
                    centerY + newHeight / 2
                ];

                // Apply the new geometric bounds
                currentObject.geometricBounds = newBounds;
            }
        }
    } else {
        // Dialog was canceled
        myDialog.destroy();
    }
}, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Change Object Size");

 

 

its something to do to with

var widthEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.horizontalMeasurementUnits});
var heightEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.verticalMeasurementUnits});

 

as

 

var widthEditbox = measurementEditboxes.add(); 
var heightEditbox = measurementEditboxes.add();

 

seems to work but just show the wrong unit...

 

 

RIP 😞 

 

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
Contributor ,
Dec 12, 2023 Dec 12, 2023

Ah sorry. I have missed that while trying it out. Please change the following:

 

// Get the user input values
var newWidth = UnitValue(widthEditbox.editValue, 'pt').as(app.activeDocument.viewPreferences.horizontalMeasurementUnits);
        var newHeight = UnitValue(heightEditbox.editValue, 'pt').as(app.activeDocument.viewPreferences.verticalMeasurementUnits);

 

The result give me the correct numbers but the width and the height of the frames have been swapped around. You might need to check your script on setting the bounding box.

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
Contributor ,
Dec 12, 2023 Dec 12, 2023

Here is the full script:

 

// Wrap the script in app.doScript for a single undoable step
app.doScript(function() {
    // Define the dialog
    var myDialog = app.dialogs.add({name: "Change Object Size"});
    with (myDialog.dialogColumns.add()) {
        with (dialogRows.add()) {
            with (dialogColumns.add()) {
                staticTexts.add({staticLabel: "Width:"});
                staticTexts.add({staticLabel: "Height:"});
            }
            with (dialogColumns.add()) {
                var widthEditbox = measurementEditboxes.add({editUnits:app.activeDocument.viewPreferences.horizontalMeasurementUnits});
                var heightEditbox = measurementEditboxes.add({editUnits:app.activeDocument.viewPreferences.verticalMeasurementUnits});
            }
        }
    }

    // Show the dialog
    if (myDialog.show() == true) {    
        // Get the user input values
     
        var newWidth = UnitValue(widthEditbox.editValue, 'pt').as(app.activeDocument.viewPreferences.horizontalMeasurementUnits);
        var newHeight = UnitValue(heightEditbox.editValue, 'pt').as(app.activeDocument.viewPreferences.verticalMeasurementUnits);

        // Close the dialog
        myDialog.destroy();

        // Get the selected objects
        var selectedObjects = app.activeDocument.selection;

        // Loop through selected objects and change their size from the center
        for (var i = 0; i < selectedObjects.length; i++) {
            var currentObject = selectedObjects[i];

            // Check if the selected object is a valid page item
            if (currentObject.hasOwnProperty("geometricBounds")) {
                // Get the current geometric bounds
                var currentBounds = currentObject.geometricBounds;

                // Calculate the center of the current bounds
                var centerX = (currentBounds[1] + currentBounds[3]) / 2;
                var centerY = (currentBounds[0] + currentBounds[2]) / 2;

                // Calculate the new bounds
                var newBounds = [
                    centerY - newHeight / 2,
                    centerX - newWidth / 2,
                    centerY + newHeight / 2,
                    centerX + newWidth / 2
                ];

                // Apply the new geometric bounds
                currentObject.geometricBounds = newBounds;
            }
        }
    } else {
        // Dialog was canceled
        myDialog.destroy();
    }
}, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Change Object 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
Community Expert ,
Dec 13, 2023 Dec 13, 2023

Another way to do this is set your scriptingPreferences meaurement units to points, which I’m doing in my sample above—there could be cases where forcing a unit conversion via unitValue fails. See Marc Auret’s post in this thread:

 

https://community.adobe.com/t5/indesign-discussions/indesign-javascript-document-dimensions-width-an...

 

scriptPreferences has the useful measurementUnit setter

 

 

app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
        var newWidth = widthEditbox.editValue;
        var newHeight = heightEditbox.editValue;

 

 

I think this should also work with any ruler unit (note that I’m resetting the scriptPreference back to AUTO_VALUE at the end):

 

 

// Wrap the script in app.doScript for a single undoable step
app.doScript(function() {
    // Define the dialog
    var myDialog = app.dialogs.add({name: "Change Object Size"});
    with (myDialog.dialogColumns.add()) {
        with (dialogRows.add()) {
            with (dialogColumns.add()) {
                staticTexts.add({staticLabel: "Width:"});
                staticTexts.add({staticLabel: "Height:"});
            }
            with (dialogColumns.add()) {
                var widthEditbox = measurementEditboxes.add({editUnits:app.activeDocument.viewPreferences.horizontalMeasurementUnits});
                var heightEditbox = measurementEditboxes.add({editUnits:app.activeDocument.viewPreferences.verticalMeasurementUnits});
            }
        }
    }

    // Show the dialog
    if (myDialog.show() == true) {60    
        // Get the user input values
        app.scriptPreferences.measurementUnit = MeasurementUnits.POINTS;
        var newWidth = widthEditbox.editValue;
        var newHeight = heightEditbox.editValue;
        
        // Close the dialog
        myDialog.destroy();

        // Get the selected objects
        var selectedObjects = app.activeDocument.selection;

        // Loop through selected objects and change their size from the center
        for (var i = 0; i < selectedObjects.length; i++) {
            var currentObject = selectedObjects[i];

            // Check if the selected object is a valid page item
            if (currentObject.hasOwnProperty("geometricBounds")) {
                // Get the current geometric bounds
                var currentBounds = currentObject.geometricBounds;

                // Calculate the center of the current bounds
                var centerX = (currentBounds[1] + currentBounds[3]) / 2;
                var centerY = (currentBounds[0] + currentBounds[2]) / 2;

                // Calculate the new bounds
                var newBounds = [
                    centerY - newHeight / 2,
                    centerX - newWidth / 2,
                    centerY + newHeight / 2,
                    centerX + newWidth / 2
                ];

                // Apply the new geometric bounds
                currentObject.geometricBounds = newBounds;
                
                //reset measurement units
                app.scriptPreferences.measurementUnit = AutoEnum.AUTO_VALUE;
            }
        }

    } else {
        // Dialog was canceled
        myDialog.destroy();
    }
}, ScriptLanguage.JAVASCRIPT, undefined, UndoModes.ENTIRE_SCRIPT, "Change Object 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
Contributor ,
Dec 13, 2023 Dec 13, 2023

That's good to know, thanks @rob day 

I have tried it with 'mm' as ruler unit and it didn't give a correct result though. You need to do the measurement units reset outside the for loop.

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 ,
Dec 13, 2023 Dec 13, 2023

Not seeing the problem—with the my example I get this:

 

Screen Shot 16.pngScreen Shot 17.png

 

 

 

 

Or with the ruler units set to Ciceros

 

 

 

Screen Shot 18.pngScreen Shot 19.png

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
Contributor ,
Dec 13, 2023 Dec 13, 2023

When you had selected multiple objects to resize, only the first object would be resized correctly because the measurement units reset happens after the 1st loop.

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 ,
Dec 13, 2023 Dec 13, 2023

Right, I have it in the loop—thanks. I usually write my dialogs as a separate function.

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
Contributor ,
Dec 14, 2023 Dec 14, 2023
LATEST

Hello all, 

 

Thank you both for trying this out - very nice results. 

 

Its a shame that Adobe dont make ID more attractive by including simple features such as this. 

 

Most appreciated thank you, 

 

Smyth

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