Enabling the VCB after onMouseMove

I’d like to be able to update the enabled state of the VCB in response to mouse move events, but it seems that SketchUp only calls Tool::enableVCB? under certain circumstances.

The example below demonstrates the issue (I’m using Sketchup 2021). I’d like to allow the user to move the mouse in a direction and then use the VCB to indicate a length along that vector. Before the mouse has moved, the vector is zero and so an entered length would be ambiguous. So I try to enable the input box only after the mouse is moved.

class LineToolTest
  def initialize(pt1)
    @pt1 = pt1
  end
  
  def activate
    puts 'LineToolTest.activate'
    @pt2_ip = Sketchup::InputPoint.new(@pt1)
    @inference_ip = Sketchup::InputPoint.new(@pt1)
    Sketchup.vcb_label = 'Distance'
  end
  
  def enableVCB?
    puts 'LineToolTest.enableVCB?'
    !@vector.nil? && @vector.length > 0.to_l
  end
  
  def onMouseMove(_flags, x, y, view)
    puts 'LineToolTest.onMouseMove'
    if @pt2_ip.pick(view, x, y, @inference_ip)
      @vector = @pt1.vector_to(@pt2_ip.position)
      Sketchup.vcb_value = @vector.length
      view.invalidate
    end
  end
  
  def onUserText(text, view)
    puts 'LineToolTest.onUserText'
  end
end

Sketchup.active_model.select_tool LineToolTest.new(Geom::Point3d.new(0, 0, 0))

Running this snippet and then moving the mouse results in this output sequence. I notice the VCB value is updated with the distance, but getter is not called again and the enabled state of the box is never changed.

LineToolTest.activate
LineToolTest.enableVCB?
LineToolTest.onMouseMove
LineToolTest.onMouseMove
LineToolTest.onMouseMove
...

There are at least a few events that do seem to cause the getter to be invoked. Mouse down and mouse up both trigger it, at least for the left button. (I’ll see the LineToolTest.enableVCB? log message and then the input box will be enabled.) Key down and key up don’t seem to, and neither does temporarily switching to another tool like orbit.

Is this just a limitation of the implementation? Is there a way to force SketchUp to enable the VCB other than in response to clicks and tool activation?

1 Like
 def enableVCB?
  ###

This method only enables / disables the VCB input…
You do not normally need to affect it ??
Unless you have to !!

Oh yes, in my similar experience, enableVCB? will fire on start and left mouse up/down. (Among others, it is not the best documented… )
Therefore, it is better to link to the status of the tool or whether the first point is picked or not…or similar.

Then in onUserText you can check that the vector has non zero length e.g.:

def onUserText(text, view)
  if @vector && @vector.valid?
     #  do the stuff
  else
    #inform user to move mouse 
    return
  end
end

Ps:

  1. Istened of: if !@vector.nil? better to use: if @vector
  2. The #valid? method is used to verify if a vector is valid. A vector is valid if its length is not zero.
  3. https://github.com/SketchUp/sketchup-ruby-api-tutorials/tree/master/examples

While I agree it sounds more logical to wait to enable the VCB until there is a defined direction, I looked at how native tool handles it and they enable the VCB on the mouse click. I would think the reason for this is that it makes sense to have the visual change of the VCB at the same time as the status text changes. If the VCB waited to be activated some fraction of a second until the mouse starts moving, although technically more logical, it could feel like it’s lagging behind. If you make a click and stop to read the tool instructions, you could see the VCB being disabled and wrongly draw the conclusion that the tool doesn’t support it.

I would activate the VCB based on the general stage the tool is in, and validate the vector isn’t zero length on text input.

2 Likes

…similar as someone mentioned in a previous post. :innocent: :grinning: :peace_symbol:

1 Like

Which is the major oversight of the native LineTool. We’ve asked (as some Ruby tools have) to implement the VCB accepting an entered point in addition to accepting a mouse click for the 1st point.

@markb_seattle You can solve this by having your initial tool state accept an entered point in the VCB for @pt1. It is good to follow established convention with regard to coordinate delimiters. See:


As @dezmo mentioned, there is a complete Ruby linetool example (#02 “custom tool”) posted at GitHub by the SketchUp Extensibility Team. There are 2 editions. The “examples” path without comments and the “tutorials” path with extensive code commenting.

As I tried to explain, it seems to be deliberate design choice for a better user experience.

I may have been deliberate, but IMO the “U” in GUI is “User”, meaning that users feel that it is their interface. They wish to use it the way they want.

Limiting the user’s choice in using the interface is not a “better experience”.

I have to agree with Dan. The Line tool, at least have to show the coordinates in a “Select start point” stage, similar as the native Tape Measure tool do. Accepting an entered point coordinates in addition will be:

…for me. :wink:

1 Like