Webdialog scripting issues
-
Hello. I have a problem that i can't solve atm and i could use some help.
I have a sketchup model that contains some component instances that represent sensors. I made a context menu entry that executes a command for a webdialog to be created. This webdialog will retrieve information for the sensor that is attached to it.
How can i create a separate webdialog instance that i can manipulate without interfering with another webdialog from the same command?
here is the code
require "sketchup.rb" module XXX model = Sketchup.active_model # point to the active model selected = model.selection # get the selected entities cmd_settings = UI;;Command.new("Settings") { settings_wd = UI;;WebDialog.new( "Main Settings", false, '', 200, 200, 500, 500, true ) settings_html_path = Sketchup.find_support_file "settings.html", "Plugins/xxx_plugin/" settings_wd.set_file( settings_html_path ) settings_wd.set_position(640,480) settings_wd.set_size(500,300) settings_wd.show } cmd_main = UI;;Command.new("Get Sensor Data") { if selected[1]==nil and selected[0].class==Sketchup;;ComponentInstance and selected[0].name.include?'Sensor' main_wd = UI;;WebDialog.new( "#{selected[0].name}'s Info", false, '', 200, 200, 500, 500, true ) main_html_path = Sketchup.find_support_file "main.html", "Plugins/xxx_plugin/" main_wd.set_file( main_html_path ) main_wd.set_position(800,600) main_wd.set_size(250,250) main_wd.add_action_callback("get_info") { |js_cb, params| main_wd.execute_script("show_selected('#{selected[0].name}', '#{selected[0].class}')") } main_wd.show else UI.messagebox('Selected entity is not a Sensor Component or you have selected more than one entities.') end } unless file_loaded?(__FILE__) # Access SketchUp's Edit menu edit_menu = UI.menu "Plugins" sub_menu = edit_menu.add_submenu("xxx Plugin") item = sub_menu.add_item cmd_settings # Access SketchUp's context menu UI.add_context_menu_handler do |menu| menu.add_separator item = menu.add_item cmd_main end file_loaded(__FILE__) end end
thank you
-
Doesn't that code already create a Webdialog each time the command is executed?
Btw, avoid using .find_support_file for finding your plugin's support folder. Instead base it of the actual location where your file is stored. Makes it more flexible. And under OSX there is often issues where plugins are stored in the machine and user directory - which makes find_support_files fail.
See this article for more: http://www.thomthom.net/thoughts/2012/09/sketchup-plugins-can-be-installed-anywhere/And if you haven't seen it, there is a collection of WebDialog issues and quirks documented here: https://github.com/thomthom/sketchup-webdialogs-the-lost-manual/wiki
And for good measure, general guide to SketchUp plugin development: http://www.thomthom.net/thoughts/2012/01/golden-rules-of-sketchup-plugin-development/
-
thank you for taking the time to answer. yes the above code works generally, but i haven't understood some things about how sketchup handles each webdialog instance.
how can i interact with each webdialog issued from main_wd for instance? how can i access each webdialog's methods,variables,etc. from outside it? eg. the ruby console
-
Dan thanks a lot for this great post. I will study the code and read more on ruby proxy classes and i will come back here to post back.
i see you also check the underlying os, that is very nice. i hadn't thought of that. this way the plugin can be made cross platform.
you are all very helpful, i am in debt. i will also read your sigs info
-
line 75 may be an error
EDIT: Yes it is an error:
%(#004000)[Error: #<LocalJumpError: unexpected return> C:/Program Files/Google/Google SketchUp 8/Plugins/test/sepultribe_sensor.rb:75]
perhaps it should be:
break if selected.empty?
EDIT: NO, not that either:
%(#004000)[Error: #<LocalJumpError: break from proc-closure> C:/Program Files/Google/Google SketchUp 8/Plugins/test/sepultribe_sensor.rb:75:in
call']` -
Just make the command:
@@cmd_main = UI;;Command.new("Get Sensor Data") { selected = Sketchup.active_model.selection unless selected.empty? if selected.single_object? if selected[0].is_a?(Sketchup;;ComponentInstance) and selected[0].name.include?('Sensor') show_sensor_dialog( selected[0] ) else UI.messagebox('Selected entity is not a Sensor Component. ') end else UI.messagebox('You have selected multiple entities. ') end end # unless }
-
will do ty.
may i ask your opinion on a matter?
i will need to change ruby variables via the WD's javascript and vice versa, thus making a single function in each that accepts two arguments, the variable's name and value, handy. i know that ruby and js dont pass variables in arguments by reference, and that it would need some complicated code in each to achieve that.
would the messy way of creating a separate method for each variable i need to modify in ruby and/or javascript be more sensible?
regards
-
FIXED lines :
%(#000000)[**34**, **35**, **41** & **59**]
-
require('sketchup.rb') module SepulTribe module Sensor # RUN ONCE unless file_loaded?(__FILE__) MAC =( RUBY_PLATFORM =~ /(darwin)/i ? true ; false ) WIN = !MAC @@dialogs = {} # Hash to hold sensor dialog refs @@cmd_main = nil @@cmd_settings = nil @@dlg_settings = nil end # RUN ONCE class << self # proxy class def clear_dialogs() @@dialogs.each {|k,v| if v.is_a?(UI;;WebDialog) v.close if v.visible? end } @@dialogs.keys.each {|k| @@dialogs[k]=nil } GC.start # garbage collection end def create_sensor_dialog(obj) wd = UI;;WebDialog.new( "#{obj.name}'s Info", false, '', 200, 200, 500, 500, true ) main_html_path = File.join( File.dirname(__FILE__), "main.html" ) wd.set_file( main_html_path ) wd.set_position(800,600) wd.set_size(250,250) wd.add_action_callback("get_info") { |dlg, params| dlg.execute_script("show_selected('#{obj.name}', '#{obj.class}')") } return wd end # create_sensor_dialog() def create_settings_dialog() wd = UI;;WebDialog.new( "Main Settings", false, '', 200, 200, 500, 500, true ) settings_html_path = File.join( File.dirname(__FILE__), "settings.html" ) wd.set_file( settings_html_path ) wd.set_position(640,480) wd.set_size(500,300) return wd end # create_settings_dialog() def show_sensor_dialog(obj) # dlg = @@dialogs[obj.object_id] if dlg.nil? dlg = create_sensor_dialog(obj) @@dialogs[obj.object_id]= dlg MAC ? dlg.show_modal ; dlg.show else unless dlg.visible? MAC ? dlg.show_modal ; dlg.show end dlg.bring_to_front end # end # show_sensor_dialog() end # proxy class @@cmd_main = UI;;Command.new("Get Sensor Data") { selected = Sketchup.active_model.selection unless selected.empty? if selected.single_object? if selected[0].is_a?(Sketchup;;ComponentInstance) and selected[0].name.include?('Sensor') show_sensor_dialog( selected[0] ) else UI.messagebox('Selected entity is not a Sensor Component. ') end else UI.messagebox('You have selected multiple entities. ') end end # unless } @@cmd_settings = UI;;Command.new("Settings") { if @@dlg_settings.nil? @@dlg_settings = create_settings_dialog() end unless @@dlg_settings.visible? MAC ? @@dlg_settings.show_modal ; @@dlg_settings.show end @@dlg_settings.bring_to_front } # RUN ONCE unless file_loaded?(__FILE__) # Access SketchUp's Edit menu edit_menu = UI.menu "Plugins" sub_menu = edit_menu.add_submenu("xxx Plugin") item = sub_menu.add_item @@cmd_settings # Access SketchUp's context menu UI.add_context_menu_handler do |menu| selected = Sketchup.active_model.selection unless selected.empty? menu.add_separator menu.add_item @@cmd_main end end file_loaded(__FILE__) end # RUN ONCE end # close module Sensor end # close module SepulTribe
FIXED lines :
%(#000000)[**34**, **35**, **41** & **59**]
Advertisement