I’m developing an extension that uses a WebDialog to input its parameters. I use an AppObserver to watch for when a new model opens up, or if the user changes focus from one model to another (I’m on MAC). But if I have a single model open and I close it, without exiting the application, I can’t find any observer event to notify my webdialog that its time to close.
Specifically, AppObserver has no “onClose” method. This wouldn’t manifest on windows, assuming sketchup just closes itself on that platform. But on MAC it would be a big help.
Anyone know if there is a better way to accomplish this?
Also, during the application shutdown cycle (after the user is prompted to save the model if it’s modified flag is true,) the model object is then destroyed and the Sketchup::ModelObserver#onDeleteModel or Sketchup::ModelObserver#onEraseAll callback will probably fire. (I think it was the latter on PC, but I do not have a Mac, so test for both.)
EDIT: Should perhaps apply also when just closing just a document child window on Mac’s MDI interface.
The problem is that on a Mac you can close all of the open models without quitting the app (and then use File->New to start a new model). When the app shutdown causes events to fire, the original question is moot because the web dialogs are going away along with SketchUp anyway!
All true, but how does the OP’s ruby detect when to make one of these tests? I’m still struggling to find an event that will fire so he knows to check what happened.
And for the benefit of Windows users who may be wondering what the heck we’re talking about, on the Mac the app can be running a) with no model open at all, b) with just one model open and active, or c) with multiple models open and one of them the active_model. Closing a model, even the last one open, does not cause the SketchUp app to quit.
I installed a model observer but no luck. With this class:
class AttrModObserver < Sketchup::ModelObserver
def initialize(dialog)
@dialog = dialog
printf("Registering Mod:%s\n", dialog)
end
def onEraseAll(model)
printf("Erasing:%s self:%s\n", model, self)
end
def onDeleteModel(model)
printf("Deleting:%s self:%s\n", model, self)
end
def onExplode(model)
printf("Exploding:%s self:%s\n", model, self)
end
end #AttrModObserver
I see the correct output when the observer is instantiated. I can also fire an event when I explode a component. But sadly, I don’t get events for onEraseAll or onDeleteModel when the model window is closed. Strangely, I don’t even get onEraseAll when I do select-all, followed by a delete. Maybe that’s because there are still unseen component definitions in the model though.
bit messy but works…
type proof to run after pasting into ‘Ruby Console’…
open a new window or close current skp to close the dialog…
#Sketchup.send_action("openRubyConsole:")
def proof # just type proof after loading
su_Id = true
def cur_title
begin
model = Sketchup.active_model()
su_Id = model.definitions.object_id()
has_title = model.title()
add_title = "Unsaved_" + su_Id.to_s
# First check if there's an active model name
if has_title.length > 1 then
current_title = has_title
else
current_title = add_title
end
rescue
# .. handle error
# UI.messagebox("You need an open .skp for this to work")
puts "You need an open .skp for this to work"
else
#check
puts "model name is: " + current_title.to_s
ensure
# puts "current_title " + "is a " + defined? current_title
# puts "Congratulations no errors!"
end
current_title
end
current_title = cur_title
#--------------------------------------------------------------------
# tls_dlg =
u_top = <<U_TOP
<html><head>
<title>
U_TOP
my_string = <<MY_STRING
</title>
</head>
<body>
<div class="" id="">
MY_STRING
u_tail = <<U_TAIL
</div>
<script>
myVar = setInterval(function(){window.location='skp:auto2ruby@' + document.title;}, 1000);
</script>
</body>
</html>
U_TAIL
all = u_top + current_title + my_string + current_title + u_tail
@dlg = UI::WebDialog.new(current_title, false,
"9th", 400, 600, 15, 15, false, true)
# @dlg.set_background_color("rgba(127, 127, 127, 0.3)")
@dlg.set_html(all)
@dlg.add_action_callback("auto2ruby") {|d,params|
id = cur_title
if id != params
# p id == params
# else
@dlg.execute_script("clearInterval(myVar); window.close();")
end
}
@dlg.show_modal
end
The AppObserver method: onActivateModel(model)
only works on MAC.
It is different from: onOpenModel(model)
It kicks in when the ‘focus’ changes from one model to another inside one SketchUp.
On a PC models always open each in a single instance of SketchUp.
So for MAC only…
Unfortunately onActivateModel only takes the newly activated model as the argument.
However, what you could do is set up an Array [let’s say called @models] that has each new model added to it.
When the user changes their active model you know the previously active model - it’s @models[-1]
If the user changes their active model you delete any reference to it in @models and then push that now active model onto the end of the Array.
So if there’s data associated with that model you can access it at that changeover.
You could store data on a model by model basis using a hash that’s shared by all models [instead of a simple ‘array’]… @models_hash[model1] >>> some data @models_hash[model2] >>> some different data
etc ?
Thanks for taking the time, John. Being a bit of a javascript noob, seeing how setInterval works was very helpful. Although I hate polling in general, this method does work and all my dialogs eventually get cleaned up regardless of whether the user closes the webdialog first or closed the model window first.
I think the correct answer would be for SU to add a method to call when the user closes a model window. That seems like a sensible event for cleanup hooks, in general.
I am also amazed that users on Windows can only have one model open at a time. That seems very limiting coming from a MAC, Linux background.
Are you sure about this? I thought observers were event-driven, i.e. that the event engine distributes method calls to observers that are registered. Vastly more efficient than having them poll to see if anything has happened.
It’s not true about number of models open on PC being limited to one.
On a MAC every model’s SKP is opened in one instance of SketchUp.
On a PC each model’s SKP is opened in a separate instance of SketchUp.
However, when opened in the same session the ‘ruby’ side can be contrived to carry over between SKPs…