Copy link to clipboard
Copied
There is a few script that move objects, but a job i’m doing can benefits if I can move all objects across multiple layers (visible or not) with a specific script label name using x, y value. A small dialog with list of labeled object an a x & y value would be awesome.
As usual, I’m lost...
Jean-Claude
Copy link to clipboard
Copied
Jean-Claude,
sometimes a screenshot before / after or a idml says more than 1000 words 😉
Copy link to clipboard
Copied
@Jean-Claude – to a specific x/y value or by a specific x/y value?
Cannot promise, that I have time writing it for you.
Uwe
Copy link to clipboard
Copied
Ah. I should have read the title more closely. You mean moving the duplicate by a specific x/y value.
The information can be given:
1. By (re)naming the selected page item
2. By a Script Label
The name or the label can read something like this:
"100 mm;50mm"
or:
"-20.5 mm;+20mm"
For ease of use do the decimal sign with a dot and the divider character should be unique over all labels or names.
Uwe
Copy link to clipboard
Copied
And it would be best to use a script snippet to name or to label a selected page item.
With a little interface where you can type in the values and the meassurement system you prefer.
Uwe
Copy link to clipboard
Copied
Uwe, how does someone add a name using a script snippet? The document I’m thinking about using such script I need to add a name (so I was thinking about the script label panel). Then this document will be reopen only from time to time and this particular object might need to be move by a specific amount. This particular object will be on many layers on the document.
Attached a quickmock up...
Thanks!
Copy link to clipboard
Copied
JC, why not use the normal name, that is displayed in the layers panel? Since it is not clear to me, how you label your items, just a first idea. The script assumes, that you have various items with names (in the layers panel).
Be careful for a first test: The script will not move anything. It will color your named frames 😉
Sadly I have no idea from Script-UI. So you can get only a old-school dialog from me. Otherwise maybe Uwe or Theunis can write a script-ui-dialog.
So tell us, how you want to identify your items (due naming or labeling).
var curDoc = app.documents[0];
var allPItems = curDoc.allPageItems;
var labelList = ["Select"];
for ( var i = 0; i < allPItems.length; i++ ) {
var curItem = allPItems;
if ( curItem.name != "" ) {
var labelName = curItem.name;
var okay = _checkList( labelName );
if (okay == false) {
labelList.push(labelName);
}
}
}
// eventuell vorhandene Dialoge entfernen
try {
app.dialogs.everyItem().destroy();
}
catch (e) {
}
// den Dialog vorbereiten ...
var aDialog = app.dialogs.add({ name: "Move Labeled Object", canCancel: true });
var dialogCol = aDialog.dialogColumns.add();
var drop = dialogCol.dropdowns.add({ minWidth: 100, stringList: labelList });
drop.stringList = labelList;
drop.selectedIndex = 0;
// ... anzeigen und die Wahl des Anwenders anwenden
if ( aDialog.show() == true ) {
var strChoice = drop.stringList[ drop.selectedIndex ];
for ( var i = 0; i < allPItems.length; i++ ) {
var curItem = allPItems;
if ( curItem.name == strChoice ) {
curItem.fillColor = "Cyan";
}
}
aDialog.destroy();
}
else {
aDialog.destroy();
}
// prüft, ob der aktuelle Name schon in der Liste vorhanden ist
function _checkList(x) {
var okay = false;
for ( var i = 0; i < labelList.length; i++ ) {
// der Name des aktuellen Labels wird mit dem aus der aktuellen Liste verglichen
if ( labelList == x ) {
okay = true;
break;
}
}
return okay;
}
–Kai
Copy link to clipboard
Copied
Kai, your script teach me something. I was thinking of naming my object with Script Label Panel, but now I realize that if I name them in the layer panel they can be selected via scripting. Like your script do. Much better, much easier!
Copy link to clipboard
Copied
Hi,
...
Much better, much easier!
... much effective
From this point one can use itemByName() method to refer directly (however be aware: many items can have the same names).
Jarek
Copy link to clipboard
Copied
@ JC: Ok, so I will try today or tomorrow the next steps.
@ Jarek, am I correct, that I must loop since CS5 through every item and check, if the name is xy, so it is not possible to refer directly any longer (if we have more than one item) ?
Kai
Copy link to clipboard
Copied
Hm,
Thinking over this..., in this specific case maybe "label" is a better way.
User is able to select many items and label it at once.
Listing labels instead of names in UI dialog looks better as well.
Both ways need iterating, I guess.
Jarek
Copy link to clipboard
Copied
@Jarek, Jean-Claude and Kai:
Easier? Yes and no.
Sometimes it's more cumbersome to name or rename objects in the Layers panel. Here is why:
1. The Layers panel is showing all objects in a tree view-like fashion. If there are a lot of layers or nested objects like groups in groups, pasted inside objects, it's sometimes time intensive to get to the one object you have selected or to the one object you like to name, if a large group is selected.
Disadvantage: You cannot name more than one page item in one go.
There is no tree view of named objects only.
2. On the other hand, if you have selected one single page item: The Scripts Label panel is just showing the one.
Disadvantage and advantage here: If you have selected more than one item, you can apply the same label in one go.
Disadvantage: There is no itemByLabel() method (once there was something like that way back in CS4 and before, but this is a different story)
Disadvantage: There is no tree view of objects for the label string (that would be another opportunity for ScriptUI developers; but unfortunately some tree view building mechanisms in ScriptUI are buggy since DarkUI was introduced)
3. itemByName() will only get the first instance of a named object in dependence of the class of objects you are using this method on. All other instances are not be found. You have to loop through all instances and check the value of the name property. CS5 and above.
Naming and labeling problems in the UI:
Naming objects sometimes could be difficult in the Layers panel.
First you have to open the tree view to see the object.
Then you have to be patient and click two times to invoke the editing mode. Don't do it too fast. A double-click will not work.
The Scripts Label panel has also its issues. Simply typing in a name is not sufficient to apply that label or to make an overwritten string sticky. You have to do an extra step: Hit the tab key for highlighting the typed in label after editing for showing the panel, that you are done with editing.
Uwe
Copy link to clipboard
Copied
3. itemByName() will only get the first instance of a named object in dependence of the class of objects you are using this method on. All other instances are not be found. You have to loop through all instances and check the value of the name property. CS5 and above.
That’s my understanding too. Thanks for confirmation. Since I want to learn scripting, I will first script the naming in the layers panel and then do maybe a second version.
Copy link to clipboard
Copied
Hi Guys,
find attached my second version. Any feedback is welcome
// MoveNamedObjects.jsx Version 01
//© 07.03.15 / Kai Rübsamen, www.ruebiarts.de
//DESCRIPTION:Move objects with a name by a specified value
// vorbeugenderweise das Anzeigen von Dialogen aktivieren
app.scriptPreferences.userInteractionLevel = UserInteractionLevels.interactWithAll;
// prüfen, ob ein Dokument geöffnet ist
if ( app.documents.length == 0 ) {
alert ( "Open a document!" );
exit();
}
var curDoc = app.documents[0];
// die aktuellen Masseinheiten speichern
var curXUnits = curDoc.viewPreferences.horizontalMeasurementUnits;
var curYUnits = curDoc.viewPreferences.verticalMeasurementUnits;
var labelList = [ "Select" ];
var allPItems = curDoc.allPageItems;
for ( var i = 0; i < allPItems.length; i++ ) {
var curItem = allPItems;
if ( curItem.name != "" ) {
var labelName = curItem.name;
var okay = _checkList( labelName );
if (okay == false) {
labelList.push( labelName );
}
}
}
// den Dialog aufrufen
var res = get_input();
if ( res != null ) {
// die Masseinheiten in Points festlegen
curDoc.viewPreferences.horizontalMeasurementUnits = MeasurementUnits.points;
curDoc.viewPreferences.verticalMeasurementUnits = MeasurementUnits.points;
for ( var i = 0; i < allPItems.length; i++ ) {
var curItem = allPItems;
if ( curItem.name == res.itemName ) {
curItem.move( undefined, [res.hValue, res.vValue] );
}
}
}
// die Masseinheiten zurücksetzen
curDoc.viewPreferences.horizontalMeasurementUnits = curXUnits;
curDoc.viewPreferences.verticalMeasurementUnits = curYUnits;
// - - - - - - - - FUNKTIONEN - - - - - - - - - -
// prüfen, ob der aktuelle Name schon in der Liste vorhanden ist
function _checkList(x) {
var okay = false;
for ( var i = 0; i < labelList.length; i++ ) {
// der Name des aktuellen Labels wird mit dem aus der aktuellen Liste verglichen
if ( labelList == x ) {
okay = true;
break;
}
}
return okay;
}
// Infos vom User sammeln
function get_input() {
// eventuell vorhandene Dialoge entfernen
try {
app.dialogs.everyItem().destroy();
}
catch (e) {
}
// den Dialog vorbereiten ...
var dlg = app.dialogs.add({ name: "Move named objects" });
var minWidthLeft = 70;
var minWidthRight = 130;
with (dlg) {
with (dialogColumns.add()) {
with (dialogRows.add()) {
staticTexts.add({ staticLabel: "Choose name and values" });
}
with (borderPanels.add()) {
with (dialogColumns.add()) {
staticTexts.add({ staticLabel: "Name:", minWidth: minWidthLeft });
}
with (dialogColumns.add()) {
var d = dropdowns.add({ stringList: labelList, selectedIndex: 0, minWidth: minWidthRight });
} // col
} // border
with (borderPanels.add()) {
with (dialogColumns.add()) {
staticTexts.add({ staticLabel: "Horizontal:", minWidth: minWidthLeft });
staticTexts.add({ staticLabel: "Vertical:", minWidth: minWidthLeft });
}
with (dialogColumns.add()) {
var h = measurementEditboxes.add({ editValue: 0, smallNudge: 1, largeNudge: 1, editUnits: curXUnits, minWidth: minWidthRight });
var v = measurementEditboxes.add({ editValue: 0, smallNudge: 1, largeNudge: 1, editUnits: curXUnits, minWidth: minWidthRight});
} // col
} // border
} // col
} // dlg
// den Dialog zeigen und auswerten
if ( dlg.show() == false ) {
dlg.destroy();
return null;
}
else {
var o = new Object();
if ( d.selectedIndex != 0 ) {
o.itemName = d.stringList[ d.selectedIndex ];
}
else {
alert ( "STOP!\rYou must choose a name" );
exit();
}
o.hValue = h.editValue;
o.vValue = v.editValue;
return o;
dlg.destroy();
}
}
– Kai
Copy link to clipboard
Copied
Kai,
A quick test before leaving for the day. It works perfectly, but fail (at line 44, see picture) if the named object is on a locked layer visible or not.
Awesome job... Thanks!
Copy link to clipboard
Copied
Hi JC,
I’m busy at the moment and scripting is’nt easy for me. So give me one or two days. The next version will have two or four checkboxes, where you can choose, what should happen with locked or invisible layers (and maybe items).
–Kai
Copy link to clipboard
Copied
Kai, absolutely no rush my friend. What you have one so far is already useful. Improve it only if you have some joy doing it! 😉
Copy link to clipboard
Copied
Uwe, I read it as that J-C already has various frames labeled, and he wants to move the ones with a specific name. So step 1 would be to build a list of all unique labels, let the user pick one, ask the distance, then move these only.