SVG toolbar icons are rendered all black

Yes, and I always used it then and still do.

I’ve always avoided Sketchup::version_number as it was bugged. Think about it, how do you use a version method that can give you a bad or good return value that depends upon the version.
It is ridiculous that you’d need to check the version to know if the method returning the version was correct or not !

1 Like

Haha agreed, its something like:

I find seeing a version comparison before doing something to be much clearer than the check for unrelated features that happened to be released with the same version.

Speed in this particular context is negligible. If anything you can define a feature constant:

SUPPORTS_VECTOR_ICONS = Sketchup.version.to_i >= 16

Then you get the code describing the logic along for the ride.

Yea, I’ve never used Sketchup.version_number. But Sketchup.version has been reliable and around since the beginning of the API.

Worrying about the relative speed of these tests is misplaced energy, as none of them should ever need to be used in a tight loop in your code.

True, as it’s one-time definition pattern.

Well, as said, there is a version constant …

… I just didn’t think about it earlier.


NOTE: I’ve again edited my example above to a version check using this constant, but also have a code comment.

1 Like

Just need to say that I am totally against defining a page full of constants that will only be used during the loading of an extension and then never get used again or removed. They sit around taking up space in the user’s RAM.

This “personal policy” is what leads me to look for a condition that already exists that my code can exploit.

So if we agree on a version check (however it’s done) then I’d still say it should be commented.

We can also do no check at all :slight_smile:

toolbar = UI::Toolbar.new "Test"
cmd = UI::Command.new("Test") {UI.messagebox "Hello World"}
cmd.tooltip = "Tooltip"
cmd.status_bar_text = "Status_bar"
cmd.menu_text = "Menu_text"

Extension = File.extname Dir.entries(File.dirname(Sketchup.find_support_file("SketchUp.exe"))+"/Images")[3]
cmd.small_icon = File.join(__dir__,'icons',"help#{Extension}")
cmd.large_icon = File.join(__dir__,'icons',"help#{Extension}")

toolbar = toolbar.add_item cmd
toolbar.show

Description1: It looks what icon SU is using and use it too.
Description2: Uses the extension of 4th file inside images folder.

Limitations:
1- Idk how slow is it compared to “if” condition along with “defined?” or “.version” method.
2- It relies on the images folder would be there.
3- Would use the same image for .png (small/large). Could workaround with “case”

How bad is it? :joy:

I actually think my approach is not that dumb.
Both version check methods assumes things will always be like that.
what if SU switch to .EPS on both Win and Mac on future? (its possible)
To copy SU behavior is both past, future and platform proof!

There should be a constant from beginning of times:

::Sketchup::Recommended_Icon_Extension

but since it has never been a thing… how can we know wich icons are official toolbars using?

So we could use:

Extension = File.extname(Drawing_Toolbar.small_icon)

But this also assumes no other image format type would ever be placed in the "images" subfolder.

It’s Windows only as you are testing for "SketchUp.exe".

Mac uses an app bundle. And the hierarchy to it’s images subfolder is much different that it is on Windows.

Introducing platform dependent test for this is complicating the code.

FYI: Back in the 2016 cycle I proposed that there be a new separate method to assign vector icons to a command so we would not have to do the double assignment.

But this was shot down because they wanted old extensions to still load using icon assignments with raster files. I argued that this would still happen and newer extensions could use duck typing like:

if cmd.respond_to?(:vector_icon=)
  # use vector icon:
  cmd.vector_icon= File.join(__dir__,'images',"vector_icon.#{type}")
else
  # use raster icons:
  cmd.small_icon= File.join(__dir__,'images',"small_icon.png")
  cmd.large_icon= File.join(__dir__,'images',"large_icon.png")
end

The excuse was (if I remember correctly) that we’d need to use a conditional expression anyway so one test is good as another … and a version check doesn’t need a new method.

Well, I really wish my advice was taken back then and this whole debate would now be moot.

1 Like

yeah it should be best planned from start :confused:

it could work for any file format as long as you also ships this type on your extension. (got it, hope they keep only icons there)
and I change the plan a bit… instead of searching “manually” for that folder, is there a way to get it from inside SU?
I mean, some way of listing the official toolbars, then choosing any icon on any toolbar and getting the icon path such “.small_icon” method
then it would give the correct path no matter win/mac/linux (btw linux when?, offtopic)
I bet Lord of Toolbars (from Fredo) can access such information, but its encrypted so cant study it :l

There are all kinds of GUI images in that folder, incl. cursors, inspector buttons, messagebox icons and I think Outliner tree icons.

However … in older versions before vector support, there was no "Images" subfolder. The icons and other images were resources embedded inside the sketchup.exe file on Windows.

The other problem is that you are relying upon the folder hierarchy not changing for both platforms in future versions.

I know that dark mode support is planned and will likely appear first in the web editions. But later, for the desktop edition this would likely mean a different folder hierarchy or image folders having different names (one for light mode, another for dark mode.)

Anyway for later versions … you would not do:

File.dirname(Sketchup.find_support_file("SketchUp.exe"))+"/Images")

… you’d want to do …

Sketchup.find_support_file("Images")

… which works on Windows.

We would hope that it is cross-platform, but one of the Mac users would need to try on Mac.

But you should never assume a path is existing without checking it. (Your proposed statement never checks to see if the path to the images folder is valid.)

But again, it’s more fragile than just a version check.

What if in a future version all the light mode images are moved into "Images/Normal" and a "Images/DarkMode" folder is added ? Your extension will be broken as soon as a user upgrades SketchUp.

The API does not make a contract out of where the application subfolders are or what they are named.

No. The native toolbars and their commands are not Ruby objects.

In some cases his code is using system OS APIs and in some cases for Ruby his code is (or was) actually doing some “naughty” modification of API UI classes. It is not distributed via the SketchUp Extension Warehouse where (I assume) it would be rejected for these modifications.

With recent API additions to the command class it should become less necessary to “hijack” API classes to create a toolbar editor extension.

very well noticed, I didnt had a clear view at first. no way to stably find the path “manually” :confused:

so also no way to identify the usage directly, what a shame. I give up on it.

Thanks for clarifying it in details, to better understand SU is to prevent bad approaches on also other cases.


So they still the best possible solutions, ok:

if defined?(::Sketchup::Model::VERSION_2016)
if Sketchup.version.to_i >= 16

Thanks again yall who helped me here :v:

Well, if the path and folder names remain as is, (which is not guaranteed,) then …

Sketchup.find_support_file("Images")

… would be expected to return the images path on both platforms.

But the API does not define a “future-proof” method like SketchUp.get_images_path because these images are internal to the SketchUp application and are not meant to be used by extensions. Ie, they are proprietary.

Unless some other extension loads before yours and you can sniff out a UI::Command that has already been loaded, and check what kind of image file it uses.

But this is also fragile. Because as we have seen in many forum posts, many extension developers still have not upgraded to vector icons even though they have been supported for 6 years now.

So you would need to check the command of an extension that is known to use vector icons. Is this fragile? Yes, because the user can switch off any extension that they wish.

Agreed. Would be nice to have such neighborhood behavior tho.
I’m gonna study UI::Command, guess it can be handy on such unusual situations.
thanks :slight_smile: