2

By using the simple array app.selection[x], you can apply a transformation to any object in the selection, independently. But how do I apply a transformation to the entire selection together?

For example: inside InDesign, I can select two side-by-side objects and flip them horizontally, causing them to switch places and flip.

InDesign Screenshot: Example 1

Inside a script, I can target each object in the selection, but they will not switch places; they will remain in the same place and flip.

for ( var x = 0; x < app.selection.length; x++ ){
    app.selection[x].absoluteFlip = Flip.HORIZONTAL;
}

InDesign Screenshot: Example 2

I could possibly group the selection, apply a transformation, then ungroup when finished, but this seems like unnecessary bulk that could slow down the code. I can easily do it manually inside InDesign, so it should follow that there's some way to access app.selection as a single object instead of an array. Does such an object exist?

Jongware
  • 22,200
  • 8
  • 54
  • 100

2 Answers2

1

Not really a solution, but it's worth noting that I don't think absoluteFlip is the action being performed, but a state indicating if the item has ben flipped. It's writable so you can set the state, but I think what's happening when using the menu to flip is flipItem: http://jongware.mit.edu/idcs6js/pc_PageItem.html#flipItem, in which you can set "around" coordinates. Now getting the origin of the selection box isn't straightforward for some reason (or maybe it is but I don't know how), but you can either use first object coordinates to set the origin so you can flip it around different coordinates depending on order of selection. Or you can sort the array to find left most coordinates (or whichever is needed), like this:

    var selection_array = app.selection;
    selection_array.sort(function(a, b){return a.visibleBounds[1]-b.visibleBounds[1]})
    var flip_origin = [selection_array[0].visibleBounds[1],selection_array[0].visibleBounds[0]]
    for(i=0;i<app.selection.length;i++){
        app.selection[i].flipItem(Flip.HORIZONTAL, flip_origin);
    }

Not sure it's easier or faster than grouping and ungrouping though.

Julien Grégoire
  • 16,864
  • 4
  • 32
  • 57
  • Nice! I would guess the 'center point' needs to be the center of the entire selection, so you have to loop over all of the items first. (... Me, I would take a shortcut here and group everything and read *its* center, then ungroup. But that makes the rest of this routine rather pointless.) – Jongware May 22 '15 at 14:52
  • @Jongware Yes, I think that through the menu, it takes the coordinates appearing in the toolbar which are basically the coordinates of the "selection group". But, for some reason I can't manage to get them from javascript. It must be somewhere, but I don't know where. So, yep probably easier to group. – Julien Grégoire May 22 '15 at 14:57
  • It's funny, when I need a solution to an InDesign question like this, I always end up searching for "jongware" as one of my keywords. :P Anyway, thank you Julien for that flipItem explanation, I was kind of wondering about that. MUCH better alternative to writing a few "if" statements setting the state of absoluteFlip to the opposite of its current state. And your solution to avoid grouping is very clever, whether or not it turns out to be faster. I'll give it a go! –  May 22 '15 at 18:05
0

Consider resize. It has a "individual/global" parameter : void resize (in: varies, from: varies, by: ResizeMethods, values: Array of varies[, resizeIndividually: bool=true][, consideringRulerUnits: bool=false]) Resize the page item.

Loic
  • 2,173
  • 10
  • 13
  • 1
    If I understand it correctly, resize is a prototype function of the page items. This means I would have to target the item first, then apply the function, like this: `app.selection[x].resize()` ...which leaves me back at square one. –  May 21 '15 at 20:47
  • You can temporarly group the objects, apply transformation then ungroup… – Loic May 22 '15 at 14:34