WebDialog return params to calling method


#1

Hi everyone, I’ve got an HtmlDialog feature for which I’d like to offer a WebDialog fallback, but I’m having a little trouble with what seems to be different behavior between the two.

The dialog is created with a line that expects parameters returned, like this:

params = message_box(title, key, JSON.generate(hash))

My message_box() method sets up the dialog properties, accounts for differences between HtmlDialog and WebDialog, and adds a couple of callbacks. (I’m leaving out those differences in what I’ve pasted here, for now, in favor of the original method, which is clearer for now.) With HtmlDialog, it returns a params variable to the calling method when the dialog is closed. In other words, it doesn’t execute the last parts of the method until after the dialog has closed. But, with WebDialog, this fires out of sequence: the message_box() method goes right on down to the bottom, returns something to the calling method, and only executes the callbacks afterwards.

Somehow, I’m trying to get this method to return a params value with WebDialog as well, but no matter what I try, the method always returns something too soon, before we are ready with params from the callback… Trying an explicit return params from the callback gives me a LocalJumpError, for example. Anyone have any ideas?

Many thanks in advance!

(I should note also that the method def below doesn’t reflect other changes I’ve made to accommodate WebDialog, such as that set_can_close is not called, etc.)

def self.message_box(title, key, json)
    loaded_json = JSON.load(json)
    width = Global::get_messagebox_width
    height = Global::get_messagebox_height
    html_path = File.join(File.expand_path(File.dirname(__FILE__)), '/html/messagebox.html')
    @messagebox = UI::HtmlDialog.new({
            :dialog_title => title,
            :preferences_key => key,
            :scrollable => false,
            :resizable => false,
            :width => width,
            :height => height,
            :center => true,
            :min_width => width,
            :min_height => height,
            :max_width => width,
            :max_height => height,
            :style => UI::HtmlDialog::STYLE_DIALOG
        })
    @messagebox.set_file(html_path)
    params = nil
    @messagebox.set_size(width, height)

    @messagebox.add_action_callback("dialogReady") { |wd, param|
        @messagebox.execute_script('skpCallbackReceived()')
        js_command = 'setup('+ json.to_s + ')'
        @messagebox.execute_script(js_command)
        params = param.split(' ')
        adjust_dialog_size(@messagebox, params[0].to_i, params[1].to_i, params[2].to_i)
    }
    
    @messagebox.add_action_callback("buttonResponse") { |wd, param|
        @messagebox.execute_script('skpCallbackReceived()')
        params = param.split(' ')
        @messagebox.set_can_close { true }
        @messagebox.close
    }

    @messagebox.set_can_close { true }
    @messagebox.center
    @messagebox.show_modal
    # we end up here on when the window closes..
    return params
end

#2

Web dialogs doesn’t pause the execution og the Ruby code until closed. In theory HTML dialogs should be able to do this but there is a bug that changes focus away from SketchUp to a different window when the dialog is closed. In practise I prefer sending a code block to my method and have that block called (or yielded) when the dialog closes.


#3

Many thanks for the reply. The method I posted did work with HtmlDialog, pausing execution, but I’d much rather use one method that works with both dialogs, of course.

So, when you mention passing a block and then calling it, do you mean, for example, a proc or lambda? Not 100% sure I’m catching that.

Thanks!


#4

Meanwhile, I’ve restructured this from the other direction. Now, neither case depends on params returning on dialog close. Instead, both dialogs call other methods from the buttonResponse callback, using blocks passed by set_on_close and set_can_close. This is better in terms of abstraction, for the different uses of this particular dialog, but I still liked the simplicity of just getting the params back to the calling method…so, further suggestions are still welcome.