Copy link to clipboard
Copied
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.
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
Use this
var widthEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.horizontalMeasurementUnits});
var heightEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.verticalMeasurementUnits});
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()) {
...
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:
scriptPreferences has the useful measurementUnit setter
app.scriptPreferences.measurementUnit = MeasurementUn
...
Copy link to clipboard
Copied
Try using 'measurementEditboxes' instead of 'textEditboxes'?
Copy link to clipboard
Copied
Hello,
Thank you Thunder-lightning for your feedback, I have changed the script accordingly and will post soon
Many thanks
Smyth
Copy link to clipboard
Copied
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'.
Copy link to clipboard
Copied
Cool, thank you
Copy link to clipboard
Copied
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;
}
Copy link to clipboard
Copied
Hello,
I had a look at the code and will take on board the ideas thank you,
Smyth
Copy link to clipboard
Copied
Hello all thanks for this
Copy link to clipboard
Copied
Use this
var widthEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.horizontalMeasurementUnits});
var heightEditbox = measurementEditboxes.add({editUnits:app.documents[0].viewPreferences.verticalMeasurementUnits});
Copy link to clipboard
Copied
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");
Copy link to clipboard
Copied
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 😞
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
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");
Copy link to clipboard
Copied
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:
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");
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Not seeing the problem—with the my example I get this:
Or with the ruler units set to Ciceros
Copy link to clipboard
Copied
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.
Copy link to clipboard
Copied
Right, I have it in the loop—thanks. I usually write my dialogs as a separate function.
Copy link to clipboard
Copied
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
Find more inspiration, events, and resources on the new Adobe Community
Explore Now