I am creating a custom tool in SketchUp Ruby and would like to be able to set custom cursors to help the user identify which tool they're using. Below is the current code I have incase you would like to see what I have so far.
#Some presets
system "clear"
model = Sketchup.active_model
entities = model.active_entities
selection=Sketchup.active_model.selection
materials=Sketchup.active_model.materials
layer_array=Sketchup.active_model.layers
module Examples
module CustomTool
class LineTool
def activate
@mouse_ip = Sketchup::InputPoint.new
@picked_first_ip = Sketchup::InputPoint.new
#num = "2"
#UI.messagebox((num))
update_ui
end
def deactivate(view)
view.invalidate
end
def resume(view)
update_ui
view.invalidate
end
def suspend(view)
view.invalidate
end
def onCancel(reason, view)
reset_tool
view.invalidate
end
def onMouseMove(flags, x, y, view)
if picked_first_point?
@mouse_ip.pick(view, x, y, @picked_first_ip)
UI.messagebox("One")
else
@mouse_ip.pick(view, x, y)
UI.messagebox("Two")
end
view.tooltip = @mouse_ip.tooltip if @mouse_ip.valid?
view.invalidate
end
def onLButtonDown(flags, x, y, view)
if picked_first_point? && create_edge > 0
reset_tool
else
@picked_first_ip.copy!(@mouse_ip)
#UI.messagebox("Test")
end
update_ui
view.invalidate
end
#CURSOR_PENCIL = 641
#def onSetCursor
#UI.set_cursor(CURSOR_PENCIL)
#end
cursor_id = nil
cursor_path = Sketchup.find_support_file("Pointer.png", "Plugins")
if cursor_path
cursor_id = UI.create_cursor(cursor_path, 0, 0)
end
def onSetCursor
UI.set_cursor(cursor_id)
end
end # class LineTool
def self.activate_line_tool
Sketchup.active_model.select_tool(LineTool.new)
end
unless file_loaded?(__FILE__)
menu = UI.menu('Plugins')
menu.add_item('Darrian\'s Point Maker Tool') {
self.activate_line_tool
}
file_loaded(__FILE__)
end
end # module CustomTool
end # module Examples
This originally came from an example on github where a kind user was demonstrating how to create custom tools. I tried to add a spin to it but have gotten myself entangled severely. The bit of code I would like to focus on however, is this piece shown below...
cursor_id = nil
cursor_path = Sketchup.find_support_file("Pointer.png", "Plugins")
if cursor_path
cursor_id = UI.create_cursor(cursor_path, 0, 0)
end
def onSetCursor
UI.set_cursor(cursor_id)
end
With this section of code, I am trying to set the custom cursor to 'Pointer.png'. The image is in the plugins folder on my computer, I have an image to verify that.
https://i.sstatic.net/6aGGD.png
When I run the full code, I get an additional tool being added to my extensions tab at the top of my SketchUp window named, "Darrian's Point Maker Tool". When I click on this tool, I would expect the cursor to change to the image that is on 'Pointer.png'. Instead however, it stays as a white arrow cursor.
If you're curious, the image is a diamond sword from minecraft (I'm in a experimenting phase at the moment). I got the image from here...
https://minecraft.fandom.com/wiki/Sword
What is the problem I am facing and how can I correct it?
Your example code uses PNG file format for your cursor graphic, and that is ok, but I recommend using vector graphics instead.
In the future, SketchUp will adopt SVG format on both 'Mac' and 'Windows'. But, as of today we developers need to use PDF for Mac and SVG for Windows.
I changed the icon path to be relative to your '.rb' file, and not the Plugins folder path.
It is recommended to create a folder and add your assets inside. I did not include this in the 'Possible solution' code example below.
Plugins Folder
↓
_____________________________________
↓ ↓
set-cursor.rb (Folder)
set-cursor
↓
(Folder)
assets
↓
_______________________________________
↓ ↓ ↓
(Folder) (Folder) (Folder)
pdf svg png
↓ ↓ ↓
Pointer.pdf Pointer.svg Pointer.png
# Example on how to get cursor path for PNG format
# If you follow the file structure in the above example.
# -------------------------------------------------------
# Finds path relative to your ruby script file.
path = File.dirname(__FILE__)
cursor_path = File.join(path, 'set-cursor/assets/png/Pointer.png')
Also, when calling the following UI.create_cursor(cursor_path, 8, 0)
make sure you tweak the parameter values for x,y to work well with the cursor graphic.
Possible Solution:
How to test code below:
Plugins or Extension Menu
-> Darrian's Point Maker Tool
module Examples
module CustomTool
MAC = RUBY_PLATFORM =~ /(darwin)/i ? true : false
WIN = RUBY_PLATFORM =~ /(mswin|mingw)/i ? true : false
class LineTool
def activate
# Using PDF format for Mac and SVG format for Windows.
if MAC
icon_format = '.pdf'
else
icon_format = '.svg'
end
# Option for use Vector graphics for the icon.
cursor_name = "Pointer#{icon_format}"
# OR use PNG, but I recomend using PDF for MAC & SVG for Windows.
cursor_name = 'Pointer.png'
# Finds path relative to your ruby script file.
path = File.dirname(__FILE__)
# Pointer.png needs to be in same path as your .rb file
cursor_path = File.join(path, cursor_name)
@result = File.file?(cursor_path)
unless @result
msg = "Can't find the 'cursor icon' path"
UI.messagebox(msg, MB_OK)
return
end
# ----------------------------------------------------------------------
# The create_cursor method is used to create a cursor from an image
# file at the specified location. This must be called from within a
# custom Tool.
# ----------------------------------------------------------------------
# Since SketchUp 2016 it is possible to provide vector images
# for the cursors. SVG format for Windows and PDF format for OS X.
# ----------------------------------------------------------------------
# .create_cursor(filename, hot_x, hot_y) # => Integer
@cursor_id = UI.create_cursor(cursor_path, 8, 0)
end
def onSetCursor
# ----------------------------------------------------------------------
# The 'set_cursor' method is used to change the cursor to a new cursor
# with a given cursor id. See UI.create_cursor and the Tool class for
# details on creating your own tools with arbitrary cursors.
UI.set_cursor(@cursor_id) if @result
end
# # #
end # class LineTool
unless defined?(@loaded)
UI.menu('Plugins').add_item('Darrian\'s Point Maker Tool') do
Sketchup.active_model.select_tool(Examples::CustomTool::LineTool.new)
end
@loaded = true
end
end # module CustomTool
end # module Examples