Apologies, I am not a programmer but wondered if someone knew a way to close the Component Option and Component Attribute windows using a ruby script. It will be added to another piece of script where the resulting function falls over with these windows open. It would prevent this happening in the case where the windows are left open accidentally.
This is not possible. But you can use the SketchUp Ruby API to open the components inspector and the preferences window (which I think you meant by “options”). But they neither toggle, nor can you hide them programmatically.
This sounds rather the other piece of script tries to solve a problem the wrong (unsafe) way, or it tries to achieve something that is not possible to do.
Why not explain what you want to achieve on a higher abstract level to get several suggested solutions, than asking for implementation steps of your specific approach?
thanks for the reply. I mean the ‘Component Option’ and ‘Component Attribute’ windows. Apologies for the confusion. Is this also the case for these windows?
In general, you cannot easily interact with or use/modify other tools/windows if they are not your own. The API is more focussed on automating geometry creation or building new tools, than a macro language for automating the user interface.
All true, … however there are some public instance methods can can be used with disclaimer.
DISCLAIMER: Use at own risk. The Dynamic Components extension is a Trimble internal extension (that is almost part of the core.) It’s internal functionality and method names could change at any time without warning. This could cause your code “in the wild” to fail, resulting in you needing to patch your code and re-release it.
module AuthorNamespace
module ThisPlugin # defined only if DC extension is pre-loaded !
extend self
DC ||= $dc_observers.get_latest_class
# Test whether the DC Component Attributes dialog is open.
def component_attributes_dialog_open?
DC.manager_dialog_is_visible()
end
# Test whether the DC Component Options dialog is open.
def component_options_dialog_open?
DC.configure_dialog_is_visible()
end
# Closes the DC Component Attributes dialog.
def close_component_attributes_dialog
DC.close_manager_dialog()
end
# Closes the DC Component Options dialog.
def close_component_options_dialog
DC.close_configure_dialog()
end
# Refreshes the DC Component Attributes dialog.
def refresh_component_attributes_dialog
DC.refresh_manager_dialog()
end
# Refreshes the DC Component Options dialog.
def refresh_component_options_dialog
DC.refresh_configure_dialog()
end
# Refreshes both dialogs, clearing the highlight if arg is true.
def refresh_dynamic_component_dialogs(clear_highlight = false)
DC.refresh_dialogs(clear_highlight)
end
# Opens the DC Component Attributes dialog.
def show_component_attributes_dialog
model = Sketchup.active_model
entity = model.selection.empty? ? model : model.selection[0]
DC.show_manager_dialog(entity)
end
# Opens the DC Component Options dialog.
def show_component_options_dialog
DC.show_configure_dialog()
end
# --------------------
# A block form method that closes the DC dialog windows,
# evaluates the given block (passing in any arguments,)
# then restores the dialogs if they were previously open.
def do_with_DC_dialogs_closed(*args)
return nil unless block_given?
atts_was_open = component_attributes_dialog_open?
opts_was_open = component_options_dialog_open?
close_component_attributes_dialog() if atts_was_open
close_component_options_dialog() if opts_was_open
#
result = yield *args # eval the block
#
show_component_attributes_dialog() if atts_was_open
show_component_options_dialog() if opts_was_open
return result
end
end if defined?($dc_observers)
end
Using local method wrappers would allow adapting the DC method calls if they change in future releases, using conditional statements that “duck-type” the DC observer instance using #respond_to?().
Thanks DanRathbun. I’m not writing a plugin, I’m using a script that Eneroth3 posted to select all child instances. It’s a work around for an issue discussed here:
Aerillus, I agree the script is not strictly safe but it solves my problem until Trimble rectify the issue. If the component option and component attribute windows are accidentally left open it throws up an alert “Merging multiple items might be slow. Do you want to continue”. This requires each instance to be either OK’d or cancelled, in the case of my drawings too many times. I tend to force quit at this point.
I was hoping to add a few lines to the script to force these windows shut if they are left open. I’m not sure if this is possible with what you have very kindly posted DanRathbun but that is the aim.
… I wasn’t entirely aware that he was using someone else’s code.
Well all of what I posted is needed. It’s not “a few lines”.
BUT … I also added near the end, a block form method that will do what you wish (provided all the dialog control methods are added.) The method name is “do_with_DC_dialogs_closed” and you’d use it to wrap calls to Eneroth’s code.
# within the plugin module ...
do_with_DC_dialogs_closed {
# call the code / methods to perform whilst DC dialogs are closed
}
Of course, in the example, you’d either add the methods I defined into Eneroth’s module, or rename the two nested module’s to something of your own unique names. Ie "AuthorNamespace" and "ThisPlugin" are just place holder names.
If adding all the wrapper methods are too confusing, you can “lift” some code from the “do_with_DC_dialogs_closed” method, and replace calls to the “wrapper” methods with direct calls to the DC object …
DC ||= $dc_observers.get_latest_class
atts_was_open = DC.manager_dialog_is_visible()
opts_was_open = DC.configure_dialog_is_visible()
DC.close_manager_dialog() if atts_was_open
DC.close_configure_dialog() if opts_was_open
#
# call Eneroth's code HERE
#
model = Sketchup.active_model
entity = model.selection.empty? ? model : model.selection[0]
DC.show_manager_dialog(entity) if atts_was_open
DC.show_configure_dialog() if opts_was_open
… but again, if these DC method names or functionality change, your “workaround” will break and need to be updated.
Thank you @DanRathbun and @eneroth3. This combined code worked for me. I removed the re-opening as this was causing an issue for drawings with many components. Thanks again
DC ||= $dc_observers.get_latest_class
atts_was_open = DC.manager_dialog_is_visible()
opts_was_open = DC.configure_dialog_is_visible()
DC.close_manager_dialog() if atts_was_open
DC.close_configure_dialog() if opts_was_open
def select_children(instance)
children = instance.definition.entities.select { |e| e.respond_to?(:definition) }
instance.model.selection.add(children)
children.each { |c| select_children(c) }
end
select_children(Sketchup.active_model.selection.first)
model = Sketchup.active_model
entity = model.selection.empty? ? model : model.selection[0]
Just in summary for anyone that might stumble across this. The code solves an issue where generate report does not see copied components. It allows you to select all child components within a component including copies. Selecting ‘current selection’ in the report window will now include copied components.
This will be cleaner for you, and will not create constants nor methods globally …
module SBJ
module SelectAllCopiedDynamicSubComponents
extend self
DC ||= $dc_observers.get_latest_class
@@loaded = false unless defined?(@@loaded)
def select_children(instance) # recursive method
children = instance.definition.entities.select { |e| e.respond_to?(:definition) }
instance.model.selection.add(children)
children.each { |c| select_children(c) }
end
def select_DC_children_command(instance)
return if instance.nil? # selection was empty
atts_was_open = DC.manager_dialog_is_visible()
opts_was_open = DC.configure_dialog_is_visible()
DC.close_manager_dialog() if atts_was_open
DC.close_configure_dialog() if opts_was_open
select_children(instance)
end
if not @@loaded
# Create a menu item so a shortcut keychord can be used ...
topmenu = UI.menu('Plugins')
item = topmenu.add_item("Select DC Children") {
select_DC_children_command(Sketchup.active_model.selection.first)
}
topmenu.set_validation_proc(item) {
Sketchup.active_model.selection.empty? ? MF_DISABLED : MF_ENABLED
}
@@loaded = true
end
end
end
Allows setting a shortcut keychord once the menu item is created.