Which Observer to use, when a locked group is selected?


Do Ruby Sketchup API have an observer which fire, when selecting a locked group?

I have tried with Class: Sketchup::SelectionObserver, which dont seem to work in this case.

thanks in advance…

You need to edit the standard SelectionObserver example class, to filter the selection for groups that are locked and then call some action[s] you want…

class MySelectionObserver < Sketchup::SelectionObserver
  def onSelectionBulkChange(ss)
    locked = ss.grep(Sketchup::Group).find_all{|e| e.locked? }
    if locked[0]
      p locked ### To see the selection
      ### Do your stuff...
### Attach the observer to the model's selection.

I would tweak that slightly to not iterate the whole selection (grep) first to get all group and then collect all locked groups into another temporary array when you only care if there is or is not any locked groups.

locked = ss.any? { |e| e.is_a?(Sketchup::Group) && e.locked? }

It’s in particular in observer events, tool events and command procs that it’d good to minimize the amount of work done. Just a general guideline.


Thank you both of you.

I have been working around with your solution for some time now.

TIG’s solution seems to work, with a but. And tt_su’s solution I cant get to work.

In this sequence there seems to be a problem:

  1. ruby is loading and instantiate MySelectionObserver
  2. ruby generates a face inside a locked group
  3. I try to select it, but no observer fires
  4. I draw a line/face manually, and now the observer fires
  5. I select a locked group, and the observer fire.

The problem is that I have to draw an entity (line/face) manually before i works. Is there a way to work around that problem?

I think in the past we’ve tested and found that #grep is very fast compared to repeated calls to #is_a?.

So I also favor first filtering with #grep.

It wasn’t a solution, … it was a “nitpick” that uses the wrong reference name.
Ie, TT’s "locked" is not an array of locked objects, it a boolean state of whether there are "any_locked".

He meant that it would be inserted as the first line of TIG’s method (and let’s assume the reference name is any_locked instead of locked,) and then another line added afterward, thus …

return [] unless any_locked

But, … TT’s idea, means that if indeed there are any locked objects, the collection needs to be iterated again to select the locked objects.

SO … I must favor TIG’s solution as either way you’d end up iterating twice if there are locked objects.

1 Like

Thank you, for clearing that up for me.

Do you have any idea why the selection observer don’t fire when a group has been added by a ruby script, unless you draw eg. a line or a face?

EDIT: It didnt fire, because of a bug in my script. The observer works fine now!

For component and group instances, the callback that gets called is onSelectionAdded

  def onSelectionAdded(selection, entity)
    puts "onSelectionAdded: #{entity}"
1 Like