Command's tooltip and status bar text are not displaying

sketchup
ruby

#1

Hello there, i’m trying to implement a toolbar with multiple commands for my extension. I’ve tried using this simple example from the API documentation to create and add my commands to the toolbar:

toolbar = UI::Toolbar.new "Test"
cmd = UI::Command.new("Test") {
 UI.messagebox "Hello World"
}
cmd.small_icon = "ToolPencilSmall.png"
cmd.large_icon = "ToolPencilLarge.png"
cmd.tooltip = "Test Toolbars"
cmd.status_bar_text = "Testing the toolbars class"
cmd.menu_text = "Test"
toolbar = toolbar.add_item cmd
toolbar.show

What happens is that the toolbar and the commands are created but, neither the tooltip or the status bar text are displaying. I’ve tried getting this to work, and searched the forums for a similar problem, but did not find any. I was hoping someone could help me solve this problem.


#2

This is what your code produces on Windows 10 & SketchUp 2018 …

image

This is how it works since the tooltips were changed for SketchUp 2013 and higher. With that release there were new icons and the tooltip boxes became this 2 line style where the bold title is the “tooltip()” and the description is the “status_bar_text()”.

Once the UI::Command object has been added to a toolbar object, the “tooltip()” property can no longer be changed. (Prior to this in v8 and earlier we could change the tooltip “on the fly”, but no longer from v2013 and higher.)

The “status_bar_text()” property still CAN be changed at any time to reflect a tool state, etc., if you wish.

Obviously the status_bar_text() also appears on the status bar, when the mouse is hovering over the toolbar button, AND when the tool is activated. So if the button activates a Ruby Tool, and you change the status text as the tool state changes, then do not forget to reset the status_bar_text() to the default inside the tool’s deactivate() callback method.


You are on Mac so I’ll see what Steve says about the differences in the interface. @slbaumgartner ?


#3

Thanks for the reply Dan. It’s really weird, i’ve tried running my code snippet on the Ruby editor extension, and it worked. The code i was running was basically the same thing, but the command created a input box.
I started from scratch and got it running. I really don’t understand what was going on yet, now i have basically the same code as before, but with the tooltip working.

screenshot


#4

Was your code running within a module namespace ?
When you paste code into the console it usually evaluates within Object, which means all references become global (since everything is a subclass of Object.)


Since you’ll be using multiple command objects, I’d suggest using either constant or module var references.

module Author
  module SomePlugin

   # At top of 1st file to load ...
    @@loaded = false unless defined?(@@loaded)

    # A bunch of code ... perhaps several files of code ...

    # At bottom of last file to load ...
    unless @@loaded

      CMD ||= {} # hash to hold command object references

      # Each command ...
      CMD[:some_tool]= UI::Command.new("Tool Name") {
        # Always implement command code in a separate method
        # so you can redfine the method as you tweak, reload and test
        tool_name_command_method()
      }.set_validation_proc {
        # Optional validation proc if you want button to gray or show checked state
        some_tool_boolean_method?() ? MF_ENABLED : MF_GRAYED
      }
      CMD[:some_tool].instance_eval %{
        self.small_icon = "ToolPencilSmall.png"
        self.large_icon = "ToolPencilLarge.png"
        self.tooltip = "Test Toolbars"
        self.status_bar_text = "Testing the toolbars class"
      }

      # ... more commands ...

      # Load your plugin submenu using the command objects here ...

      TOOLBAR ||= UI::Toolbar.new("SomeTools")

      CMD.each do |key,cmd|
        TOOLBAR = toolbar.add_item( cmd )
      end
      TOOLBAR.show if TOOLBAR.get_last_state != TB_HIDDEN

      @@loaded = true
    end

  end
end

You might see quickly that a factory method for defining commands might make code a bit cleaner.


#5

Hi Dan, thanks for the tip! Yeah i was running my code inside a module function, like this:

module Company
  module Plugin
    def self.create_commands
       #code that was creating the toolbar and the commands 
    end
    
    unless file_loaded?(__FILE__)
      self.create_commands
      file_loaded(__FILE__)
    end
  end
end

I gotta say, i’m having some difficulties organizing my plugin code, not only i’m new to Ruby, but i found the tutorials/examples on extension development to simple. Is there some resource on extension development that you can recommend me?
P.S. Again, thank you very much for all the help you are giving me.


#6

I’ve not had time to look carefully at the specific issues in this code, and I’ll avoid questions about coding style, structure, factory methods, etc. But here is some info based on my understanding and what works in my extensions:

I always use full paths to the icon and cursor files. With bare filenames as in the example I am not sure where Ruby will look for the files. The result is possibly different on the Ruby Console than when an extension is loading as SketchUp starts. The strange icon with the sick face is the “file not found” one that SketchUp substitutes when it can’t find the file. I set up module-level constants for where the extension is loading (based on FILE in my base loader) and do a File.join to assemble paths to specific files as needed. That makes it easily relocatable.

As you know, SketchUp 2016 added support for scalable icons and cursors (pdf on Mac, svg on Windows). I haven’t checked whether png images will even work on these versions, but certainly the icons and cursor won’t scale properly on your display. I think they just get embedded as tiny things in a larger box?

I’ve had no problems with Command#tooltip working. I’ve never used Command#status_bar_text (don’t really see the need for it anyway) so I can’t comment on how it works on Mac.


#7

Yes this wasn’t really about the icon. It is about the toolitip, so I didn’t bother having any icons load.

Re, the icon. Absolute paths are always good. At one time there was a “path rule”,… perhaps the paths were relative to the ruby file being loaded, but I never remember (and always have the feeling that it differed by platform,) … so like you, I started just using absolute paths.