12 Replies Latest reply on Feb 27, 2014 7:30 AM by Marc Autret

    Getting page items in correct Z-order

    svenax

      We have a rather complex Indesign plugin that I want to port to Javascript for increased maintainability. Unfortunately the SDK is pretty different from the Scripting API in many ways. One thing that has me stumped is this:

       

      spread->GetItemsOnPage(pageIndex, &itemsOnPage);
      Arranger::SortItemsBackToFront(&itemsOnPage);
      

       

      ... and then I can loop through the page items in the correct order. How do I do the equivalent with the Scripting API?

        • 1. Re: Getting page items in correct Z-order
          Laubender Adobe Community Professional & MVP

          @svenax – the property index of the pageItem, which is of type integer, from 0 to n (top => bottom) will give you the z-order.

           

          Simple example for nearly* all pageItems on spread one of a document:

           

          var myDoc = app.documents[0];
          var mySpread = myDoc.spreads[0];
          var myArray = new Array();
          
          //Store pageItem by index number in array:
          
          for(var n=0;n<mySpread.allPageItems.length;n++){
          
              myArray[mySpread.allPageItems[n].index] = mySpread.allPageItems[n];
          
              };
          

           

          *MSOs with their hidden states are special objects where allPageItems will only detect the ones in active states.

           

          Uwe

          • 2. Re: Getting page items in correct Z-order
            Laubender Adobe Community Professional & MVP

            And if you want to sort back to front simply reverse the array:

             

            myArrayBackToForth = myArray.reverse();
            

             

            Uwe

            • 3. Re: Getting page items in correct Z-order
              Laubender Adobe Community Professional & MVP

              Sorry. I was wrong.

              Nested objects get their own index number starting from zero with reference to their parent object.

               

              So mySpread.allPageItems is no starting point for you!

              You can only work with the plain mySpread.pageItems here:

               

              var myDoc = app.documents[0];
              var mySpread = myDoc.spreads[0];
              var myArray = new Array();
              
              //Store pageItem by index number in array:
              
              for(var n=0;n<mySpread.pageItems.length;n++){
              
                  myArray[mySpread.pageItems[n].index] = mySpread.pageItems[n];
              
                  };
              
              var myBackToForthInZArray = myArray.reverse();
              
              

               

              Uwe

              • 4. Re: Getting page items in correct Z-order
                Laubender Adobe Community Professional & MVP

                Still I'm wrong… (sigh!)

                 

                The index number of a pageItem refers to the object's class index.

                TextFrames.index, Rectangles.index, Ovals.index etc.pp.

                 

                Example:

                If you have exactly three objects on a spread:

                1 Oval, 1 Rectangle, 1 TextFrame, ALL these pageItems have the index value 0.

                 

                So it's not quite trivial to get the stacking order…

                (InDesign CS5.5)

                 

                Uwe

                • 5. Re: Getting page items in correct Z-order
                  svenax Level 1

                  Great, I am not the only one who has problems with this.

                   

                  Yes, I started looking at the index property, but, as you say, that restarts from zero for nested items and items of different types.Maybe there's actually no way of doing this with scripting, but since it is possible with the SDK, I'm still hoping for some solution.

                  • 6. Re: Getting page items in correct Z-order
                    Laubender Adobe Community Professional & MVP

                    It's a bit confusing, yes.

                     

                    Currently I do some tests with a very simple document:

                    Just one spread with one page. Two layers with simple objects.

                     

                    On the bottom layer:

                    One yellow text frame with a green anchored text frame.

                    On top of the text frame a magenta oval.

                     

                    On the top layer:

                    A cyan rectangle.

                     

                    app.documents[0].spreads[0].pageItems.everyItem().getElements();
                    //result: [object Oval],[object Rectangle],[object TextFrame]
                    

                     

                    does not give the right stacking order.

                     

                    However, if we loop through allPageItems of the spread, we get the right stacking order.

                    Unfortunately in the case of the anchored text frame on the bottom layer, this is not the case (because it's parent is counted first).

                     

                    Result is:

                     

                    [object Rectangle]Cyan
                    [object Oval]Magenta
                    [object TextFrame]Yellow
                    [object TextFrame]C=75 M=5 Y=100 K=0

                     

                    Uwe

                    • 7. Re: Getting page items in correct Z-order
                      Laubender Adobe Community Professional & MVP

                      Ok.

                      We could go from layer to layer with the pageItems (neglecting nested ones) to get the right order, but that means, we first have to sort out the right spread, because "layer" is no property of a spread, but of the whole document.

                       

                      In a one spread document this will work:

                       

                      var objectsByZorder = new Array();
                      
                      for(var n=0;n<app.documents[0].layers.length;n++){
                          objectsByZorder = objectsByZorder.concat(app.documents[0].layers[n].pageItems.everyItem().getElements());
                          };
                      
                      $.writeln(objectsByZorder);
                      //result: [object Rectangle],[object Oval],[object TextFrame]
                      

                       

                      Uwe

                      • 8. Re: Getting page items in correct Z-order
                        Laubender Adobe Community Professional & MVP

                        What I forgot: here a screenshot of my simple document:

                         

                        StackingOrderOfPageItemsWithTwoLayers.png

                         

                        Uwe

                        • 9. Re: Getting page items in correct Z-order
                          Laubender Adobe Community Professional & MVP

                          Hm, just tried a *very exotic* workaround that is "normalizing" all pageItems to the "Groups" class, so counting in z-order is easy:

                           

                          var myDoc = app.documents[0];
                          var mySpread = myDoc.spreads[0];
                          var zIndex = new Array();
                          
                          for(var n=mySpread.pageItems.length-1;n>=0;n--){
                              
                              var myItem = mySpread.pageItems[n];
                              var myDup = myItem.duplicate();
                              
                              var myGroup = mySpread.groups.add([myItem,myDup]);
                              myGroup.pageItems[1].remove();
                              };
                          
                          
                          zIndex = mySpread.groups.everyItem().pageItems[0].getElements();
                          
                          mySpread.groups.everyItem().ungroup();
                          
                          $.writeln(zIndex);
                          //result: [object Rectangle],[object Oval],[object TextFrame]
                          

                           

                          Have fun!

                           

                          Uwe

                          • 10. Re: Getting page items in correct Z-order
                            Laubender Adobe Community Professional & MVP

                            Just found out, that I was not the only one with that idea:

                             

                            (Ben_J.D)

                            [JS] :: [CSX] - PageItem Stacking Order

                            01.01.2009

                             

                            http://forums.adobe.com/message/1109544#1109544

                             

                            See also Harb's solution in the same thread:

                             

                            http://forums.adobe.com/message/1109555#1109555

                             

                            Uwe

                             

                            Message was edited by: Laubender | link edited…

                            1 person found this helpful
                            • 11. Re: Getting page items in correct Z-order
                              svenax Level 1

                              Thank you! Harb's solution linked above almost does it. However, when I have items nested in groups more than two levels deep, the  items are apparently not found in the pageItems.everyItem() list. I'm probably doing something wrong somewhere in my code and will check this further. The application I need this for is pretty time critical, so I want to avoid duplicating and deleting items if possible.