Is there a way to select the SU selection tool?

I’d like to have a fallback that would jump to the selection tool in case of some fairly severe failure. Is that possible?

Sketchup::Model#select_tool() says:

The select tool is activated if you pass nil to the select_tool method.

Ex:

Sketchup.active_model.select_tool(nil)

There is also the non-preferred #send_action:

Sketchup.send_action("selectSelectionTool:")

These “actions” are really meant for toolbar buttons or menu item commands, and act asynchronously just as if the user had clicked a button or fired a keyboard shortcut.

So prefer other API methods (when possible) especially if you need a return status from an action.
The #send_action module method only returns a boolean indication of whether it “knows” the requested action on a given platform, and does not block. (Ie, your next code statement could be evaluated before the application finishes doing all it should do for the requested action.)

Okay, let’s talk about in what situations you might think this is necessary.

Generally it is frowned upon to change the user’s tool choice unless they are expecting a change.

Also such change should only be done from an active Ruby Tool of your own design. This might be done for a “one shot” tool such as moving or stretching some object that was previously chosen with the Selection Tool.

It is also generally more acceptable to pop your tool instance off the toolstack so as to reactivate whatever the previous tool was.

Sketchup.active_model.tools.pop_tool

More Info …


When something goes wrong, it is best to inform the user perhaps with a UI.messagebox and either allow them to try again, to cancel the operation, or reset the tool to it’s initial state.

2 Likes

Pushing and popping the tool stack (at least in my mind) should only be done if your tool is changing the view, not modifying the model. Otherwise, I would think that you could get some strange behaviour when the tool attempts to do something that it was expecting to be there but is not anymore.

One reason that I wanted to change the tool to the standard selection one was because my tool expects that a component is selected prior to starting my tool. Currently, it displays an error message box and then continues on. I guess I can force my own selection to stop this issue from happening. I was just being lazy (well, to be frank, there is just a lot of stuff to iron out already and I didn’t want to bother).

Thanks for the UX Guidelines though. That’ll be helpful.

No. You pop the tool off the toolstack in order to do what it does, which has the effect of activating the previous tool, whatever it was. It is matter of etiquette. (ie, the “U” in GUI stands for “user”. It’s the user’s interface.)

This does not have anything specific to do with the view.

And a Ruby tool does not need to do anything crazy or weird to allow SketchUp’s built-in view manipulation tools to empower the user to change view in the midst of a custom tool.
These tools (Orbit, Pan and Zoom) operate in interrupter mode and suspend active tools.
All a tool need usually do is define the resume and suspend callback methods properly so that they can happily resume operation from the state where they were suspended by the native view manipulation tools.

Okay, but this is poor design practice.

What we encourage instead is that you attach a validation proc to the menu item (or UI::Command) that only enables the command or tool if the selection is not empty and it contains a component instance.
Ex:

some_menu = UI.menu("Plugins")
cmd_id = some_menu.add_item("My Task") { do_my_task_method_call() }
some_menu.set_validation_proc(cmd_id) {
  selset = Sketchup.active_model.selection
  if !selset.empty? && selset.single_item? &&
  selset[0].is_a?(Sketchup::ComponentInstance)
    MF_ENABLED
  else
    MF_DISABLED|MF_GRAYED
  end
}

Yes I understand coding a picker is tricky. ThomThom had to create a whole guide on how do it.

What you could do rather than the validation proc is have a branching statement that implements your own picker state. (Ie, if a component is pre-picked, your tool would skip the picking state.)

You would need to implement a Sketchup::PickHelper object for your tool’s own pick state.

1 Like

Its a matter of etiquette not to cause the application to crash or do random or not very intuitive things because it wasn’t designed to deal with cases that it shouldn’t have to deal with. Complicating the SW by taking into consideration nonsensical use cases is a waste of dev time and frustrates the user when things go aerie.

If you will notice with the pan, orbit and zoom tools (view changing tools), if you got there while you were using a tool that edits the model (editing tools), it will allow popping back to the editing mode when done, not back to one of its other the view modes (i.e. if you went from edit to zoom to pan to orbit, leaving orbit you go back to edit). There is no harm in doing so, but this makes sense as it would be a waste of the users time to go back through those other view modes when you really would rather be editing.

When going from a view tool to an edit tool, you cannot pop back to your view tool. There is also not too much harm in doing that as when done editing, the workflow would more likely be to edit something else, not changing your view.

However, when you are in an editing tool and you go to another editing tool, there is no tool that just pops back to the previous editing tool. There would be too much confusion on the user’s side. Just what does it mean to rotate and half way though that you decide to move, delete, stretch or do some other editing task. What would it then mean to go back to the previous editing mode, which in this case was to rotate? What are you now rotating? Why would you be rotating?

You can’t just blindly say that you must do only one thing because “It is matter of etiquette.” It’s a matter of usability, intuitiveness and being sensical.

I’m well aware, but there are certain priorities that I have to consider. Just like all SW design and implementation, you have to triage.

I actually agree and was dumbfounded when I read somewhere the suggestion that error boxes were a “preferred” way. I don’t remember where I saw it, but I do remember seeing it. I think the reasoning is that you can’t get any help information from a disabled control.

Yes, I will be getting to that eventually.

That was probably me mention that. By disabling UI elements it’s harder for a user to learn why it’s disabled. But if you rather provide feedback when a command is invoked in invalid pre-conditions there is an opportunity for the user to explicitly learn why.

I experienced this myself with one of my extensions where the original version would disable the toolbar buttons for when the selection was invalid. I got a constant trickle of users contacting me for support, wondering why the button was disabled. When I changed it to not be disabled and instead present a message explaining why they all went away.

Disabled items is a common convention that goes back a long time. But being a long time convention doesn’t mean they are ideal conventions in terms of UX.

Some related UX articles on this topic:

Why you shouldn’t include disabled interaction elements in your design system | by Chris Atherton | UX Collective (uxdesign.cc)

Why You Shouldn’t Gray Out Disabled Buttons (uxmovement.com)

1 Like

API docs says:
The select tool is activated if you pass nil to the select_tool method. You must implement the SketchUp Tool interface to create a tool, prior to calling this method,

Hum… How do you interpret this?
Does the first sentence mean
…select_tool(nil)
activates the native Selection Tool?
Even if the next one says there is a prior condition: create a tool? (actually for the second time since the same sentence is also in the paragraph above)

This method definition has numerous problems, grammatical errors, run on sentences that make it confusing, … no doubt.

(1) The first confusing thing is the choice of method name. It should have been named activate_tool() from the beginning.

Yes. However, even though I myself always referred to the native tool as the “Selection Tool”, the interface tooltip and menu item refer to it as “Select” tool.

Because of this, the wording of the docstring for the method is very confusing.

Yes. (3) The whole docstring needs revamping. It is a duel use method. The main use is to activate a custom Ruby tool instance that implements an abstract Sketchup::Tool class interface.

So, (4) The Parameters list is incorrect as it also accepts nil as an argument. So it should say:

  • tool (Object,nil) – A Ruby tool instance object to activate, or nil to activate the native Select tool.

Ah much clearer.Thanks
I am trying to make most of my commands go back to Select right after they finished. So was hoping to have it easy using this.
But here (Mac M1), the tool is indeed selected, but somehow not activated.
The arrow cursor is displayed and, having included a puts in my code, I can see the correct tool name in the console, SelectionTool.
But clicking the mouse does not select anything. I have to hit the spacebar to be able to select again.
Annoying to have a command ending this way.
update: Just checked, same on PC.

Is this a command (utility) or a Ruby tool you are “finishing” ?

I can see that if your code causes a change in what tool is active, it is fine to restore the previous tool.

But normally true tools go through a cycle of states and when done, return to the initial state.
(The user should be able to hit ESC anytime to cancel and reset the tool to the initial state.)

Normally a plugin shouldn’t activate the Select tool. There is already spacebar and the toolbar icon if the user want to switch to it. If your extension uses a tool, the convention is that it goes back to the initial state after being used, like how you can draw rectangle after rectangle after rectangle in Rectangle tool.

Like I said, I want it to go back to Select tool, the initial state. One has to select a component and then use the command.
Strange to have the Select cursor not selecting, (until hit spacebar)
I have to check (again) if this is made as a true tool.

What kind of tool is your command activating that takes the user out of Select to begin with?

1 Like

Ok, finally got it to work.

…model.selet_tool(nil)

had to be added in the right spot. That is in the calling method, after the call. Not in the called tool.
And for calling direct from menu cmd, I added

Sketchup.send_action(“selectSelectionTool:”)

after the call.

You shouldn’t need to activate Select from a menu command. SketchUp already adds its own commands for activating Select.

Yes I agree. And for this extension, that happens for half the commands. I have yet to find why not in the others. So in the meantime …

If you avoid calling Sketchup.select_tool in cases when you implement the tool interface, you don’t need to reset SketchUp to any particular tool when the user is done with your dialogs.

Ok, will try that.
I guess I will have to suffix every method with ‘self.’

1 Like

Activating an object as a tool doesn’t have any effect on the Ruby syntax. What it does is that it replaces the already active tool (Select, rectangle, Pan etc) with this Ruby object. If the Ruby object implements the Tool interface, it allows you to create custom tools that behaves like native ones, but if it doesn’t do this, it just puts SketchUp in an odd state where you have a different mouse cursor and can’t click anywhere.

It’s the initialization of an object from a class (.new) that makes the difference to the Ruby syntax. This can still be called without activating the newly created object as a tool. That said, if you don’t want to store any per instance states inside of the object (like how a Face has a very specific set of vertices, or how a Color has specific RGB values), it’s usually cleaner to work with modules and static (self.) methods.

1 Like