Hi all,
For some tools that I’ve written, I’m loading a specific cursor icon. Everything always runs fine on Windows but some of the tools icons doesn’t load on MacOSX, I just get the bascic arrow icon without any ruby console error message…
Here is the code I’m running in the activate method of the tools:.
def activate
# Grab tool cursor icon file
tool_cursor_file = File.dirname(__FILE__) + "/images/cursor_drawing.png"
# Create the cursor if it doesn't exists yet
if @@cursor_id.nil?
@@cursor_id = UI.create_cursor(tool_cursor_file, 4, 27)
end
end
What is really strange is that for the same code on two different tools it works for one and doesn’t for another.
So I’ve started the check the icon file but I can’t find differences, both are 24x24px, are RGB 8bits png files BUT when, for a tool that doesn’t load the icon, I’m switching the images it works. That means the problem is linked to the image use.
So MacOSX seems to be more sensitive than Windows to the file encoding type. Does anyone knows what are the recommanded cursor image settings ?
Is there something else that I’m missing ?
Thanks for your help.
Jérémie
Assorted thoughts:
I have found that SU on the Mac is fussy about the png image files used for cursors. In particular, it will sometimes silently reject a file that was created on Windows. I’ve never figured out why, but the fix can be as simple as opening the image in a Mac image editor and then saving it to a new name. I’ve never found the reverse to be true: a Mac png has always worked on Windows SU.
The preferred file format changed as of SU 2016 when scalable images were enabled, so for 2016 and 2017 on Mac the preferred form is pdf (on Windows it is svg). But for older versions you still need to use png.
I have also found that SU on the Mac sometimes delays showing a Tool’s cursor until the first user-click after the Tool is activated. Some of my Tools do this, and others show the cursor every time, with no pattern that I can find in the Tool code to explain the difference. Typically this happens only the first time the Tool is used in a SU session, so I suspect it has something to do with OS X caching the cursor, but I’ve never found a workaround. I just warn users it may happen…
Finally, in the code snippet you shared you never invoked UI.set_cursor(). I believe that has to be done somewhere in your Tool (typically in the onSetCursor callback), merely calling UI.create_cursor() is not sufficient.
1 Like
Each tool class MUST have this callback (so the SketchUp engine can call it, whenever it thinks the cursor needs to be changed.)
def onSetCursor
# You would set your cursor here.
UI.set_cursor(@@cursor_id)
end
You could just go ahead and create the cursor at load time, near the top of your Tool class:
@@cursor_id ||= UI.create_cursor(
File.join(File.dirname(__FILE__),"/images/cursor_drawing.png"),
4, 27
)
… and then the cursor will be ready whenever the tool is activated.
(Ie, there will be no delay because there will be no slow string manipulation in the activate()
callback.)
As an alternative to what @DanRathbun showed, I usually create the cursor as a class constant at the top of the file (same principle, different mechanism). Here’s a sample with the branching code to handle all releases of SketchUp:
if(Sketchup.version.to_i >= 16)
if(RUBY_PLATFORM =~ /darwin/)
IN_ICON = File.join(IMGPATH, 'inside.pdf') unless defined? IN_ICON
OUT_ICON = File.join(IMGPATH, 'outside.pdf') unless defined? OUT_ICON
else
IN_ICON = File.join(IMGPATH, 'inside.svg') unless defined? IN_ICON
OUT_ICON = File.join(IMGPATH, 'outside.svg') unless defined? OUT_ICON
end
else
IN_ICON = File.join(IMGPATH, 'interior2.png') unless defined? IN_ICON
OUT_ICON = File.join(IMGPATH, 'exterior2.png') unless defined? OUT_ICON
end
IN_CURSOR = UI::create_cursor(IN_ICON, 0, 31) unless defined? IN_CURSOR
OUT_CURSOR = UI::create_cursor(OUT_ICON, 0, 31) unless defined? OUT_CURSOR
I have also noticed issues similar to @slbaumgartner. For Sketchup versions needing “png” files, I suggest using a resultion of 32x32 only. At least keep it square, and keep the resolution to an intregral power of 2.
Hi all,
Thanks for your feedbacks.
For sure I’m using the onSetCursor Method either it wouldn’t work anywhere. As I said it’s working on Windows but not on MacOSX. Here is the onSetCursor code I’m using, this is exactly the same that Dan shared :
def onSetCursor
UI.set_cursor(@@cursor_id)
end
Anyway thanks slbaumgartner for sharing your experience, I’ll try to open and save the icons on MacOSX, either I’ll move to vector cursors.
Again, thank for all the answers.
Jérémie
Hi Bruce,
That what I’m doing recentlty, I’m now much more using 32px images instead of 24px images. I tried that too for my actual problem but it didn’t worked better…
Thanks for your suggestion.
Jérémie
I have no luck on macOS no matter what I try (I haven’t yet tested on Windows). The onSetCursor
method is not even getting called… Any reason as to why this is happening? I even shrank the image from 128x128 to 32x32 and still no luck. Even tried a pdf from an existing tool and that doesn’t work either. I’m so disappointed…
Update: I’ve tested using the LineTool from Github and the cursor does indeed change according to the image I supply. However, my Tool is activated when opening a HtmlDialog
, like this:
UI.menu("Plugins").add_item("My Item") {
dialog = UI::HtmlDialog.new(...)
Sketchup.active_model.tools.push_tool(MyTool.new)
dialog.set_on_closed { Sketchup.active_model.tools.pop_tool }
}
Why is this causing onSetCursor
to not get called? Callbacks like onLButtonDown
or draw
work as expected…
I wonder if the HTMLDialog is getting focus and that is preventing your cursor from being shown? What happens if you click in the model view?
I discovered what was happening: first, I accidentally put 2 versions of onSetCursor
inside my Tool
class; secondly, the puts
instruction I added prevented the cursor from showing up when clicking in the model view (just me trying to debug things). I removed the printing line and everything is now smooth.
Now I hope that my code will also work on Windows .
Console IO is slow … ie, using puts
. Callbacks for UI like onSetCursor
and command validation procs can get called very often. They should have a minimum of statements and code.
It’s a good lesson learned.
You’ll need a SVG cursor for Windows platform.
1 Like