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:
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.
This is what your code produces on Windows 10 & SketchUp 2018 …
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 ?
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.
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.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.
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.
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.
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.
Did you ever get this working completely on macOS? I’m also finding that it only partially works. I can’t get both cmd.tooltip and cmd.status_bar_text to show up—only one or the other. cmd.status_bar_text only displays if there is no cmd.tooltip; otherwise, only cmd.tooltip displays.
On Windows, both show up just fine, with the horizontal line separator between them. But on macOS, I don’t see any toolbar items for any extension that seem to show more than one field.
I just re-read this topic based on seeing @fleawig’s post and it struck me that maybe in the older posts there is confusion about what cmd.status_bar_text is supposed to do. The Ruby API docs say
The text that will appear on the status bar when the cursor is over the command’s menu item.
They do not say it will appear when you hover over a toolbar item (they say that for the tooltip). None of the code samples earlier involve a menu item, only toolbars. I don’t think I’ve ever seen a status text appear when hovering over a menu item, so it may be that this feature is broken. But I’ve also never seen a second line appear in the tooltip on MacOS X. Based on the API docs I’d think it was a bug if it did.
My post is based on different behavior between macOS and Windows, in a plugin that uses the same code and values for both platforms. It’s just like the difference you see between @DanRathbun’s result (An icon floated left, a title, a horizontal rule, and then a text field) and @mateusgondimlima’s result (just the tooltip string, with nothing else.) You’ll notice they’re quite different.
Now that I look at this in more detail, though, it looks as if, on macOS, the status_bar_text attribute only works for tools that can be selected, not for toolbar items that trigger an alert or open a dialog. It seems that perhaps this was just implemented differently between the two platforms.
…and it does appear that on macOS, the status_bar_text attribute does nothing at all for the example case given in the API. On Windows it works perfectly fine—the example string appears in the status bar when the cursor is over the toolbar button—but on macOS, nothing appears in the status bar.
And, in our plugin, hovering over the command’s menu item in macOS doesn’t produce any result in the status bar either.
Anything related to UI might yield different results between the platforms. It could be differences in the platform itself of inconsistencies. I’m not that familiar with how the statusbar update code works to say anything of the top of my head on this one.
But I do know that validation procs in Mac’s toolbars isn’t working properly. (I’ve ended up disabling them in my own extensions - leaving the validation procs in for Windows only.) We have an open issue on that one. (Though if I recall it was a non-trivial issue to address.)
Another note on this—I found the same thing, that it only half-works. I attempted to add a UI.refresh call to my proc, since this did produce the desired behavior when I did it manually, but this UI call makes SketchUp immediately crash.
Here’s the code I tried:
cmd_browse.set_validation_proc do
if Core.asset_dialog && Core.asset_dialog.visible?
MF_DISABLED
# This causes an immediate crash
UI.refresh_toolbars
else
MF_ENABLED
end
end
The reason for the crash is that this in a infinite loop. The UI refresh routine will call the validation procs on all the toolbar buttons, and yours starts another UI refresh in the midst of one in progress.
Every validation proc should return one of the MF constant integer values. Your example may not as the UI.refresh_toolbars() method returns nil, not one of the integers that the OS is expecting. … that is if it doesn’t crash.