Is it possible to dynamically update an
UI.add_context_menu_handler
depending on the element selected? I wanted to change the name of submenu items with information of selection item. (for example it’s name)
Is it possible to dynamically update an
UI.add_context_menu_handler
depending on the element selected? I wanted to change the name of submenu items with information of selection item. (for example it’s name)
perhaps something like this…
module Dezmo
module Dezmo_test
extend self
@@loaded = false unless defined?(@@loaded)
def get_name()
mod = Sketchup.active_model
sel = mod.selection
return unless (sel.single_object? && sel.first.respond_to?(:definition))
sel.first.definition.name
end
def do_somthing()
# do something
end
unless @@loaded
UI.add_context_menu_handler do |context_menu|
context_menu.add_item("Test.. name: #{get_name} "){
do_somthing()
} if get_name
end
@@loaded = true
end
end
end
It works perfectly. If I want to stop the behaviour, what should I do?
Restart SU.
Give us an idea on what condition you want to stop the “behavior” ?
My idea of stopping it is in case it consumes a lot of resources because it is always analyzing the selection.
Okay then this is actually easy.
You use an extension variable to decide whether or not to modify the context menu:
At the top of your extension submodule:
@@feature = true unless defined?(@@feature)
At the bottom of your extension submodule, in the run once at startup block:
unless @@loaded
UI.add_context_menu_handler do |context_menu|
#
break unless @@feature
#
name = get_name()
if name # nil otherwise
context_item = "Test.. name: #{name} "
context_menu.add_item(context_item) { do_somthing() }
end
end
@@loaded = true
end
do_somthing()
You decide what the “feature” variable is named and whether it is initially true
or false
. The reference can be set false
or true
any number of times during a session. For example a submenu for the extension could have a menu item that allows the user to switch the feature “on” and “off” at will.
The @@feature
object can be an instance variable, like @feature
(because a module is an instance of class Module
,) … or it could be a member of an options hash, like @options[:feature]
or OPTIONS[:feature]
depending upon how you control extension options. (I find the hash easiest because it is simple to save them out to JSON files and load them from JSON files.)
Again, the word “feature” in the above discussion and snippets is just a placeholder for the name you choose.
FYI, it is not “always analyzing the selection” …
The block only executes when the context menu needs to be built after the mouse right-click (or hitting SHIFT+F10.)
I thought, you want to stop the test code… but in this case Dan is right, but partly, because:
This will give an error:
Error: #<LocalJumpError: break from proc-closure>
So, perhaps this could be better:
module Dezmo
module Dezmo_test_a
extend self
@@loaded = false unless defined?(@@loaded)
@@show_popup = false unless defined?(@@show_popup)
def get_name()
mod = Sketchup.active_model
sel = mod.selection
return unless (sel.single_object? && sel.first.respond_to?(:definition))
sel.first.definition.name
end
def toggle_popup()
@@show_popup = !@@show_popup
end
def do_something()
# do something
end
unless @@loaded
cmd = UI::Command.new("Toggle My 'Test...' Contex menu"){ toggle_popup() }
cmd.set_validation_proc {
@@show_popup ? MF_CHECKED : MF_UNCHECKED
}
UI.menu("PlugIns").add_item(cmd)
UI.add_context_menu_handler do |context_menu|
if @@show_popup
name = get_name()
if name
context_item = "Test.. name: #{name} "
context_menu.add_item(context_item) { do_something() }
end
end
end
@@loaded = true
end
end
end
…at least almost consistently (Corrected in my new snippet.)
Sorry, did not test that. Yes, it can be replaced with an if
statement.