SVG toolbar icons are rendered all black

Mac SketchUp uses pdf for icons, not svg, so it won’t see that specific issue.

What about extensions? I’m using svg icons on mine.
Toolbar API states only .png on its examples :l
Tell me svg works on SU(mac) too, its just not the standard :pray:

Aerilius has also stated some useful info about it.
but it was for win only, and 2019 so not sure how to proceed.
Will svg1.1 work SU17+ on Win and Mac? is it future proof? (about extensions)

NO.

As stated …

I also wondered how on Windows I could save icons for Mac use, so I asked and got a good answer (which I never imagined could be so easy) …

1 Like

Thanks :v:

I think I’ll just stay at .png then so no worries about versions and/or platforms.
Easier to draw and easier to code.

I was using 32x32 and 64x64. Worked fine.
Let me know if there is better resolutions to use. (24x24 - 48x48?)

Which is why your SVG files should probably always include the <!DOCTYPE> declaration that indicates what SVG version the parser should use to read the file.

As long as you use ver 1.1 and stick to style attributes and stay away from inline stylesheets using a <style> element.

But, again it all depends upon whether SketchUp stays with the limited external library it is using now.

Not really. Raster icons do not scale well with display scaling. And coding for vector icons is not much more work at all.

# Test for vector icon support (v2016+) ...
if defined?(::Sketchup::Model::VERSION_2016) # use vector icons
  type = Sketchup.platform == :platform_osx ? 'pdf' : 'svg'
  icon_path = File.join(__dir__,'images',"vector_icon.#{type}")
  cmd.small_icon= icon_path
  cmd.large_icon= icon_path
else # use raster
  type = 'png'
  cmd.small_icon= File.join(__dir__,'images',"small_icon.#{type}")
  cmd.large_icon= File.join(__dir__,'images',"large_icon.#{type}")
end

NOTE: I’m using that fact that the ::Layout module was not defined until SketchUp 2016 as the test for raster vs vector.
CORRECTION: It was the LayOut C API that was released with v16. The ::Layout Ruby API did not come out till 2018. (Changing the above test to Sketchup::Axes.)
CORRECTION (2): The consensus of comments below are for using a version check, so I’m changing the above example, once again (just so future readers seeing only the example are not led astray.)


Thomas just answered this …

2 Likes

Great! thanks, gonna implement it.

We can make it a method so no need to re code for all toolbar icons: (yet to test)

#Saved icon files would be:
#- Help.vec.pdf
#- Help.vec.svg
#- Help.sm.png
#- Help.lr.png

module Taxsola
  def define_icon(item, name, Tooltip, Status_bar, Menu_text)
    # Test for vector icon support (v2016+) ...
    if defined?(::Sketchup::Model::VERSION_2016)
      #use vector icons
      type = Sketchup.platform == :platform_osx ? 'pdf' : 'svg'
      icon_path = File.join(__dir__,'images',"#{name}.vec.#{type}")
      item.small_icon= icon_path
      item.large_icon= icon_path
    else
      #use raster
      type = 'png'
      item.small_icon= File.join(__dir__,'images',"#{name}.sm.#{type}")
      item.large_icon= File.join(__dir__,'images',"#{name}.lr.#{type}")
    end

    item.tooltip = Tooltip
    item.status_bar_text = Status_bar
    item.menu_text = Menu_text
  end


toolbar = UI::Toolbar.new "Test"
cmd = UI::Command.new("Test") {UI.messagebox "Hello World"}

Taxsola.define_icon(cmd, "Help", "Tooltip", "Status_bar", "Menu_text") #Define all in one

toolbar = toolbar.add_item cmd
toolbar.show
end
2 Likes

Sure, and it “travels well” … ie, becomes a library method you can use for multiple extensions.

1 Like

Vector images still have to be rendered to pixels. So when you create vector images it’s worth using a pixel grid to ensure that shapes line up precisely on the pixel grid. At least if you are using shapes that have horizontal or vertical lines. Otherwise you’ll find that edges can look blurry when the anti-aliasing kicks in.

The documentation for UI::Command explains in better details: Class: UI::Command — SketchUp Ruby API Documentation

If you use bitmaps then they won’t scale on high DPI monitors.

That’s what I do for my own extensions as well.

Do you support anything older than SU2017? If you don’t then there’s no need to include bitmap versions and logic.

That’s some confusing logic, using the Layout namespace to determine to use vector images or not. I like detecting features whenever possible, but in this case I’d argue it’s clearer to do a version check: if Sketchup.version.to_i >= 17. Vector support has no relationship with LayOut.

He got this from me. The desire was to determine when vector icon support began which was v16. (Not >= 17) I however made a mistake … ::Layout in Ruby was defined with the 2018 release. I confused this with the Layout C API which was released in v16. (Again, as I’ve said before, having C API features listed in amongst the Ruby API Release Notes is confusing.)

So what I was trying to do is “duck typing” the ObjectSpace. For v16 we could better test for the existence of the Sketchup::Axes class which definitely was defined first with the 2016 release.

@Taxsola I corrected the example above and added a code comment to explain the conditional.

I’d rather do the define check, (which I believe is fast compared to calling 3 methods) to compare against a major version number.

I would argue that neither pattern explains the “why” of the test is without a code comment.


If the API had defined a boolean UI.vector_icon_support? for the 16.0 release we’d have something self explanatory for a “duck type” test …

if UI.respond_to?(:vector_icon_support?)

… too late now. So we use other means for our test.

1 Like

I suppose another valid test could be …

if defined?(::Sketchup::Model::VERSION_2016)
  # use vector
else
  # use raster
end

Makes sense now, thanks

No I’m about SU17+, good to know. (its nice to share all versions practices tho)

Rlly smart to check released features :100:
Same docs also states “Sketchup.version_number” to have been fixed in 2016, it was returning wrong values. So I guess it would be another reason to avoid using it for check purposes, right?
or was it a rlly different method? was “Sketchup.version” a thing back then?

I’m also gonna change my code to use “Sketchup::Axes” as u did. :v:

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)