Using HtmlDialog.set_file(filename)

I want to use an existing HTML file (test1.html) in an HtmlDialog.

I’ve got it to work using the Ruby heredoc construct and cut and pasted the html file contents into the Ruby file that way.

It works fine on its own when opening in Chrome, and did work just as well inside SU when included as a heredoc.

I’m using a slightly adapted version of an HtmlDialog example from the Sketchup GitHub pages (the Step03 example).

But I can’t see how to use the file itself using dialog.set_file(filename)

The ruby file that loads the example dialog is:

module JWMPlugins
module Test2

  # Window fully reusable.

  def self.create_dialog
    options = {
      :dialog_title => "Example",
      :preferences_key => "example.htmldialog.test",
      :style => UI::HtmlDialog::STYLE_DIALOG
    }
    dialog = UI::HtmlDialog.new(options)
    dialog.center
    dialog
  end

  def self.show_dialog
     if @dialog && @dialog.visible?
      @dialog.bring_to_front
    else
      # Attach content and callbacks when showing the dialog,
      # not when creating it, to be able to use the same dialog again.

      @dialog ||= self.create_dialog
      @dialog.add_action_callback('poke') { |action_context, name, num_pokes|
        self.on_poke(name, num_pokes)
        nil
      }
      @dialog.set_file("test1.html")
      @dialog.show
     end
  end

  def self.on_poke(name, num_pokes)
    num_pokes.times {
      puts "Poke #{name}!"
    }
  end

end # Test2
end # JWMPlugins

The test1.html file is in the Sketchup Plugins/test folder, the same folder as test2.rb, and there’s nothing else in the test folder.

But I can’t get the dialog code to open this file.

All that shows is a blank white window with (as set up in options) the window title Example.

image

I’ve tried @dialog.set_file("./test1") and @dialog.set_file("test/test1") but that neither of those works either.

And there are no errors in the Ruby console.

I expect it’s something simple that I’m misunderstanding or just ‘doing wrong’ but I can’t see what it is myself.

Any suggestions please?

The API Docs example shows a full path to the file, but is that necessary?

@dialog.set_file(File.dirname( __FILE__ ) + "/test1.html")

Many thanks for such a quick response, @dezmo.

That works, and I can see why, though not quite why my code didn’t.

Why does Ruby not default to looking the current directory? I’d expect it to look in either the Plugins, or Plugins/test folders.

As far as I remember Ruby will use this directories to try to look for files:

ENV["PATH"]

Normally the Plugins are not in that list.
Why is this so? Because that’s how someone created it … :innocent:

But if I remember, ruby require doesn’t need to be told the directory, just a file path relative to Plugins.

That is right the require first start to look for relative path. Again, I’m not sure why it is like this…
Maybe someone else will explain… :blush:

It does, but the “Plugins” directory or any possible extension subdirectory, is not the current working directory. When SketchUp loads up it sets the current directory to the user’s HOME or Documents path. (The former in older versions, the latter since ~v2014.)

To see the current working directory path use:

Dir.pwd

… or …

Dir.getwd

But any extension might change the current working directory and forget to change it back, so never rely upon what you think it should be. Instead temporarily change it using the block form of Dir::chdir so that it is restored to what it was before.

  def self.show_dialog
    if @dialog && @dialog.visible?
      @dialog.bring_to_front
    else
      # Attach content and callbacks when showing the dialog,
      # not when creating it, to be able to use the same dialog again.

      @dialog ||= self.create_dialog
      @dialog.add_action_callback('poke') { |action_context, name, num_pokes|
        self.on_poke(name, num_pokes)
        nil
      }
      # Temporarily change the working directory:
      Dir::chdir(__dir__) {
        @dialog.set_file("test1.html")
      }
      @dialog.show
     end
  end

Ruby does not know anything specific about SketchUp, any of it’s various “Plugins” paths nor any of it’s extensions or resources paths. Ruby has basically been “shoehorned” into SketchUp.

Ah, this is where you are confusing yourself. Ruby’s Kernel#require checks the paths listed in it’s $LOAD_PATH array. In order to make Ruby work with SketchUp, the startup cycle pushes various SketchUp extension paths onto the end of the $LOAD_PATH array, before it begins processing any of the various “Plugins” folders.


So the bottom line is, either use full absolute paths, use File.join(__dir__, "somefile.ext") or temporarily change the working directory as shown above.

Dan, many thanks for your clear explanation.

If I don’t need the directory for any other reason than to load the test1.html file, do I need to know the working directory?

Not really, if you use the block form of Dir::chdir, it restores it to whatever it was before.

But also you can just forego the working dir altogether and use an absolute full path …

@dialog.set_file(File.join(__dir__, 'test1.html'))

The changing of the working directory is good when code would be doing several to many file reads and writes to the same path.

1 Like

Understood. Tx again Dan

1 Like

+1 to resolving absolute paths from the current source file using __FILE__ or __dir__ over changing working directory. I’ve long recommended that over anything else. Some often use Sketchup.find_support_file, but that also have potential problems. Old blog post: http://www.thomthom.net/thoughts/2012/09/sketchup-plugins-can-be-installed-anywhere/

1 Like