Ruby code to import component into model from custom HTML pop up box

What is the Ruby code to import a component into a model from a custom HTML pop up box?

The question is much too complex. It requires coding in CSS, HTML, JavaScript and Ruby.

You should seek to see what others have done in open source (non-encrypted) code.

Otherwise you need to break this project down into smaller parts and ask more concise questions.

Have you created the UI::HtmlDialog object yet ?

And in the dialog, when the user clicks on something to make a choice, what will the dialog return to Ruby as a value ? An ID ? A filename ? An absolute path to the file ? What ?

Meaning that the Ruby will eventually need the path to the import file to pass to the DefinitionList#load method. But the dialog HTML does not need the whole path unless you’ll be displaying it to the user. So, the Ruby need only populate the HTML with enough information to allow the user to make a choice. (This might be an index identifier into a Ruby collection that your code has collected.)

Thanks Dan.
I have found a developer who can help me create the pop up box but they want to use nodejis to create it. Will this be compatible with Ruby so I can open it fro within Sketchup and select files etc?
Thanks

Generally speaking, I feel, that nodejs solutions are way too “heavy” for such a simple task.

But you never explained much about the “import” scenario.

Ok thanks for the advice. i’ll try and steer clear of using Nodejs.

Are you selecting the component from a local collection ?

Yes it will be from a local collection, any file selected will open in the current open sketchup model.

Okay, but why is the native Components Browser panel not working for you ?

If you put your local component collection folders in the User Components folder, SketchUp will find them automatically and you can browse your collections with the native panel. You can also open a secondary panel and have two collections open at once.

Okay, but why is the native Components Browser panel not working for you ?

I can understand why you are asking that but the reason is to do with speed of selection and effect on my workflow.

As a freelance kitchen designer, I use Sketchup every day to make my designs and am always looking for ways to make my workflow more efficient. A little improvement in several areas here and there could make a big difference time saving wise for me.

One of these things is component selection, specifically selecting the cabinets which I use in my designs. I have built up a library of several hundred cabinets which I have made myself (saved as components). These comprise about 20 different style / door varieties. My local file directory is organised such that the ‘style’ folders are the parent folders and then the sub folders comprise the base, wall, tall, dresser cabinets etc (there are then further sub folders for different sizes and types).

I also have a large saved library of decorative items, architectural features, lights etc.

The problem with using Setchup’s native browser panel is that it takes too much time flipping back and forth in the directory between the cabinet folders and other items (decorative etc).

What I need is a separate panel JUST for cabinets, which is always open at the last place or folder I was using. Then I would use the native browser for everything else.

I have tried doing this using the secondary panel as you suggest but there isn’t enough room for it to work effectively (I work from a laptop as I travel around a lot and the screen size doesn’t help). It would also be better for me if was laid out like a windows file directory so I can jump to any folder up or down the tree as I need it.

I have tried most of the existing kitchen extensions but none of them works to any benefit.

So I’ll just keep plodding on trying to create the feature myself…

As I had said, there are 2 (two) browser panes.

The browser panel panes should remember and restore what folder was open, in the last session, in each of the browser panes.

Now this aside, yes there are some way that the native component browser is designed that can make it clunky to use.

Back in 2018 I posted an example of an extension that built menus to place components quickly.
That old example needs some updating and cleanup.

@DanRathbun, if you update/cleanup, please let us know. I made a ‘component toolbar’ using code that I found in the forum. Have had no luck with the HTML or Modus.

The ‘component toolbar’ is fun to use:

Yea, will do. It’ll be a couple of days as I’m finishing another example right now.

Yes, my menu builder is similar but uses the component filenames as the menu command captions.

That’d be great.

I took your example (Face Area Sniffer) and tried to modify my ‘component toolbar’ accompanying menu. I broke the submenus, so I don’t have that figured out yet. But it looks like this:

Yes that what it would look like. The folders are menus, the files menu items.

I’ll give you a hint. The update will be using the Ruby’s Find library module for simplicity.
The old version had some clunky homegrown iterator code that would be fragile.

Just an idea…
ComponentFinder – FlexTools?

I sometimes have trouble coming up with clear and concise responses… so in this case I’ll just point out that I chopped about 125 lines of code out of my menu/toolbar after reading this. In other words, thanks.

1 Like

Thanks for that, looks exacty what I need!

Also, Dan, your Facesniffer / Menu finder looks like it would also be useful. Can you post on here when its ready for download?
Will it have a function whereby it will show the most recent folder navigated to as an item on the menu? (That will save a lot of time navigating to a certain folder eg. cabinet style, each time).
Thanks

Menus are permanent for the session. And the Ruby references go out of scope after the file gets done evaluating, so we cannot reuse them, for example to add more submenus or menu commands later on. (By the way, we have for many years pleaded for persistent menu object references.)

So, the folder path(s) need to be known when the extension is loading. In the old version, I had the program path (the distributed components) and the user components path hardcoded as the only two paths.

I was thinking of adding two more. Ie, the user can change the normal user path via the Preferences Files panel to point somewhere else (and this is usually done when keeping a collection independent of SketchUp versions.) I had not parsed the settings file to see if the user did this in that old quick and dirty example.
The second path (or extra paths) can be added at any time by having the user select a directory.

I also never dealt specifically with MacOS paths in that version.


Now, I can put a “Get Component from Last Folder” command that leverages MS Windows Most Recently Used paths that get automatically saved because SketchUp API’s file browser panels use the system file browse dialogs. The method for such a command might look like this:

module SomeAuthor::SomePlugin # <--<<< within your extension submodule

  extend self

  def get_component( multi = false )
    if defined?(@mru_skp_path)
      filepath = UI.openpanel(
        'Choose Component', @mru_skp_path, 'SketchUp Model|*.skp||'
      )
    else # Let MS Windows open the last path used for .skp files.
      filepath = UI.openpanel('Choose Component', '*.skp')
    end
    return unless filepath
    # UI::openpanel still returns paths with backslashes!
    slash(filepath)
    # At this point we could also save a reference to this path.
    # Sort of our own Most Recently used path:
    @mru_skp_path = File.dirname(filepath)
    model = Sketchup.active_model
    deflist = model.definitions
    comp = deflist.find {|cdef|
      next false if cdef.group?
      slash(cdef.path) == filepath 
    }
    if comp # already loaded into DefinitionList
      model.place_component(comp, multi)
    else
      begin
        comp = deflist.load(filepath)
      rescue => err
        UI.messagebox(
          'Error loading component:'<<
          "\n#{File.basename(filepath)}\n\n"<<err.message
        )
      else
        model.place_component(comp, multi)
      end
    end
  end

  def slash(filepath)
    filepath.gsub!(/\\\\|\\/,'/')
  end

end

Try creating a “Get Component” UI::Command for this and assign it to a toolbar button.

Let me know how it works for ya’

@DanRathbun Something ‘clicked’ with one of your comments above. I was building a menu and a toolbar, either of which redundantly opened DCs. I prefer the toolbar for usability… but it was going get too big as I built it out. So, I fiddled around and built toolbar launchers from the menu. I also added a “Tools” activator… featuring the Face Area Sniffer and @dezmo tag by component name. Thanks to both of you for posting the helpful examples.

2 Likes

Oh, … now that’s a good idea!

You could also have floating child toolbars launched from parent toolbar buttons. Each of the commands on the child could close it’s toolbar, so it functions similar to a flyout toolbar. (Which by the way, API consumers also asked for many years ago.)

@DanRathbun I gave it a shot:

That little bit of goofing around reminds me of one thing that I mean to go back to (because I can’t get it to work): the show DC Options and Attributes. My results with that have been hit or miss but having the panels pop-up when DCs are grabbed from the menus would be handy. I wonder if that could be a toggle option.