Getting all selected layers from layer list

edited August 2015 in Ruby Scripting

Hi,

To get one selected layer we can do

cl = lv.current_layer
if cl.is_null? || cl.current.layer_index < 0
  raise "Please select exactly one layer"
end
input_layer = cl.current.layer_index

How do we instead get an array of all the layer indices that are selected in the layer list?

Let's say we select three layers in the layers list. Then there are three LayerPropertiesIterators that are returned from LayoutView#selected_layers. Why three LayerPropertiesIterators, why not three LayerInfo objects or three layer_indices?

I tried to use the resultant LayerPropertiesIterators like iterators, but unfortunately this:

cl = lv.selected_layers
if cl.length == 0
  raise "Please select at least one layer"
end
input_layers = []
cl.each { |c|
  while !c.at_end?
    input_layers << c.current.layer_index
    c.next
  end
}
p "input_layers = #{input_layers}"

...gives the result

input_layers = [0,1,2,1,2,2]

(Notice the repeats.)

Thanks,

David

Comments

  • edited August 2015

    OK I see now that LayerPropertiesIterator is appropriate, because I forgot that layers in the layer tree can have complicated hierarchical grouping structure, so this handles the case where the user selects the parent group for instance.

    So to just get the selected layers, this seems to work:

    cl = lv.selected_layers
    if cl.length == 0
      raise "Please select at least one layer"
    end
    input_layers = cl.map { |c| c.current.layer_index } 
    p "input_layers = #{input_layers}"
    

    ...gives the result

    input_layers = [0,1,2]
    
  • edited August 2015

    yes, that's exactly, how it is meant :-)

    Please note that in general the selection can contain layers from different layouts if there is more than one layout loaded into the view. You'll find different values of c.current.cellview then, so you should check whether that value is the expected one (I'd suggest matching against lv.active_cellview_index).

    There may also be nodes which don't have a valid layer_index (for example group nodes), so you should skip values less than zero.

    And finally, different layer properties nodes may refer to the same layout layer (maybe with different transformations or styles), hence you could add a final input_layers = input_layers.uniq.

    Or in a single line:

    input_layers = cl.select { |c| c.current.cellview == lv.active_cellview_index && c.current.layer_index >= 0 }.map { |c| c.current.layer_index }.uniq
    

    Matthias

Sign In or Register to comment.