[Code Example]
Quiet DC Interact Tool (subclass with tooltip toggle)
This is an example of tool subclassing. It subclasses the DCInteractTool
to wipe out any tooltips that it’s onMouseMove
callback may set. But the hover messages will still show up on the status bar.
- By default the “Show tooltips” toggle is set false (unchecked.)
- Users can change this by checking the option in the submenu.
- The submenu appears at the bottom of the main “Tools” menu.
This example tool came by request for allowing toggling the tootips that might be annoying whilst recording anmiated tutorials and hovering over DCs.
License: MIT License
su_quiet_dc_interact_tool_1.0.3.rbz (2.8 KB) UPDATED 2021-02-12
It isn’t a full extension example, if installed it will just be a lone file in the “Plugins” menu.
It will not load unless the Dynamic Components extension is switched on.
A good exercise ...
A good exercise might be to wrap this example into a full extension within an author module and an extension submodule, then put it in an extension subfolder and lastly create a registrar script for the “Plugins” folder.
# encoding: UTF-8
#
# File: "su_quiet_dc_interact_tool.rb"
# Author: Dan Rathbun, AUG 2020.
# License: MIT License
#
# This is an example of tool subclassing. It subclasses the DCInteractTool
# to wipe out any tooltips that it's onMouseMove callback may set.
# But the hover messages will still show up on the status bar.
#
# By default the "Show tooltips" toggle is set false (unchecked.)
# Users can change this by checking the option in the submenu.
# The submenu appears at the bottom of the main "Tools" menu.
#
# This example tool came by request for allowing toggling the tootips
# that might be annoying whilst recording anmiated tutorials and
# hovering over DCs.
#
# Revisions:
#
# 1.0.0 2020-08-20 initial
# 1.0.1 2020-08-21 (no feature or compatability change)
# Corrected class docstring: "We will only" was "Will Will only".
# 1.0.2 2020-08-25 Replaced lazy boolean check of instance var @loaded
# with test using the defined? operator. Added menu item validation
# proc for the tool reference (to avoid unused warning.)
# 1.0.3 2021-02-12 Define constants for localized UI strings.
# Define persistent saving of user's tooltip toggle setting.
# Request that the Dynamic Components extension be loaded:
require "su_dynamiccomponents.rb"
# Users might switch it off via the Extension Manager, so we test if
# it was loaded, specifically the superclass tool that we need to
# subclass for this example:
if !defined? DCInteractTool
# WARN THE USER IF DC EXTENSION IS NOT LOADED: (translate if not English.)
warn("\nWARNING: Dynamic Components extension is switched off.\n"+
" QuietDCInteractTool could not be loaded.\n")
else
module Example
# We first declare a subclass of DCInteractTool.
#
# There is no reason to modify how the tool is instantiated, so
# we will not be overriding the class constructor :new, nor the
# instance method :initialize. The superclass will handle this.
#
# We will need to hold the state of tooltip display in a variable
# and define a getter and a toggle method for this state variable.
#
# We will only need to override the onMouseMove callback method,
# first calling the superclass' implementation, then wiping out the
# tooltip text if our tooltip display state variable is not true.
#
# Lastly, we will setup a submenu with items to activate the tool
# and another to toggle the tooltip display state.
#
class QuietDCInteractTool < DCInteractTool
VERSION ||= '1.0.3'
OPTS_KEY ||= Module.nesting[0].name.gsub('::','_')
# Text for user interface (translate if not English.)
TEXT ||= Hash[
:submenu, "Quiet DC Interact",
:activate, "Activate tool",
:tooltips, "Show tooltips",
]
### CLASS METHODS
#
# This method saves the DC tooltip display settings so
# it can be restored when SketchUp is started again.
def self.save_toggle_setting
Sketchup.write_default(OPTS_KEY,'Tooltip',@@tooltip)
end
if !defined? @loaded
# Declare a class variable to hold tooltip display state,
# and read it's value from stored preference files:
@@tooltip = Sketchup.read_default(OPTS_KEY,'Tooltip',nil)
if @@tooltip.nil? # First load of extension per user:
@@tooltip = false
self.save_toggle_setting() # Save it the 1st time
end
end
# This method returns the tooltip display state.
def self.tooltip?
@@tooltip
end
# This method toggles the tooltip display state.
def self.toggle_tooltip
@@tooltip = !@@tooltip
self.save_toggle_setting()
end
private
# This method gets the tool id.
def self.tool_id
@tool_id
end
# This method sets the tool id.
def self.tool_id=(id)
@tool_id = id
end
### INSTANCE METHODS
#
# Override the class initializer so we can initialize a set of instance
# variables (whose referencing before assignment) is causing repeated
# warnings to be output to $stdout (and so the console) when $VERBOSE is
# true. (This is not part of the example, just something necessary.)
def initialize(*args)
# Pass the singleton DCObservers instance to superclass constructor:
super($dc_observers)
# Add this tool as a ToolsObserver watching the tools collection:
@model = Sketchup.active_model
@model.tools.add_observer(self)
# Initialize a few superclass instance variables that were not:
@dc = @dcobservers.get_latest_class
@timer = nil
@onclick_action = ''
@is_in_timer_handler = false
end
public
# This a ToolsObserver callback method that fires when the active
# model's tool changes. We use it to get this tool's ID for use in
# the tool activation menu item's validation proc.
def onActiveToolChanged(tools, tool_name, tool_id)
self.class.tool_id= tool_id
end
# Called when the user first deactivates the tool. We override this so
# we can remove the tool as a ToolsObserver watching the tools collection.
def deactivate(view)
super
# Remove this tool as a ToolsObserver watching the tools collection:
@model.tools.remove_observer(self)
self.class.tool_id= 21022 # Set to a safe Selection Tool ID
end
# Override the onMouseMove callback method inherited from superclass.
# In the superclass determinations are made about what is below the
# cursor, and if it is a DC, then it retreives translated help text
# to display as a tooltip and on the status bar.
def onMouseMove(flags, x, y, view)
# Call the superclass' method passing along ALL arguments:
super
# Conditionally, wipe out any tooltip set in the superclass:
view.tooltip = '' unless @@tooltip
end
# MENU SETUP
if !defined? @loaded
@loaded = true # so this block only evals once at startup:
tools = UI.menu("Tools")
# Add a submenu for our new tool:
quiet_menu = tools.add_submenu(TEXT[:submenu])
# Add an item to activate our new "quieter" tool:
tool = quiet_menu.add_item(TEXT[:activate]) {
Sketchup.active_model.select_tool(self.new)
}
quiet_menu.set_validation_proc(tool) {
if Sketchup.active_model.tools.active_tool_id == self.tool_id()
MF_CHECKED | MF_DISABLED | MF_GRAYED
else
MF_ENABLED
end
}
# Add an item to toggle the tooltip display state:
toggle = quiet_menu.add_item(TEXT[:tooltips]) {
self.toggle_tooltip()
}
quiet_menu.set_validation_proc(toggle) {
self.tooltip?() ? MF_CHECKED : MF_UNCHECKED
}
end
end # class
end # extension module
end # if defined? DCInteractTool