api-issue-tracker icon indicating copy to clipboard operation
api-issue-tracker copied to clipboard

Add ability to dock HTML

Open NeilBurkholder opened this issue 6 years ago • 30 comments

For Windows platform...

It would be nice to dock HTMLDialogs to the tray using ruby code. See this: https://forums.sketchup.com/t/add-abilitity-to-dock-htmldialogs/33470/30

NeilBurkholder avatar Dec 02 '19 14:12 NeilBurkholder

For the API implementation, I think it makes sense to register a panel on load and have it shown throughout the session, and then loaded back in the same position in the next session, a bit like how toolbars work.

Also I think it makes sense with a separate class for this as it represents another UI element, even if much of the behavior is the same.

I'm thinking something like this.

module Me
  module MyExtesion
    @panel = UI::Panel.new(EXTENSION.name, height: 200, min_height; 150) 
    @panel.set_url = "#{PLUGIN_ROOT}/panel.html"
    @panel.show # Restores last saved state, or show for the first time.

    # Call this from custom observer.
    def self.on_selection_change(selection)
      names = selection.select { |e| e.respond_to?(&:name) }.map(&:name)
      @panel.execute_script("setNames(#{names.to_json})")
    end
  end
end

Eneroth3 avatar Dec 03 '19 08:12 Eneroth3

I'm hoping docking is made available for all dialogs. The ruby console is one that I would like to be able to dock at the bottom of my window with a flyout, rather than having it floating all over the place.

NeilBurkholder avatar Dec 03 '19 12:12 NeilBurkholder

The ruby console is one that I would like to be able to dock at the bottom of my window with a flyout, rather than having it floating all over the place.

YES! SpaceClaim has it's Python scripting window dockable in a tray and it looks great. (DesignSpark beta had it also but was disabled for release - the brats!)

DanRathbun avatar Dec 04 '19 00:12 DanRathbun

Also I think it makes sense with a separate class for this as it represents another UI element, even if much of the behavior is the same.

A possibility could be a subclass:

class UI::Panel < UI::HtmlDialog

I'm hoping docking is made available for all dialogs.

OR ... a new dockable property is added to UI::HtmlDialog and then it's up to the user to decide when to dock. Any docked Html panels are automatically restored based upon the settings written into the preference JSON files. If the extension "owning" a docked panel is switched off (and so not loaded) then the panel is not opened.

In this scenario, no new specific UI class is needed. The SketchUp core decides what kind of window to wrap the CEF instance within based upon user choices.

DanRathbun avatar Dec 04 '19 01:12 DanRathbun

I prefer it to be a property dockable.

kengey avatar Dec 10 '19 19:12 kengey

If you dock a dialog and restart SketchUp, the dialog wont appear unless it's created and "registered" to SketchUp when the program loads. If this doesn't happen and you don't have persistency I think the point with panels is defeated. I think it's good to make a difference to make it clear how panels should be used.

I'm hoping docking is made available for all dialogs.

A lot of dialogs are not persistent by nature but just shows up to give you a message or offer a choice, and then go away. Docking these would make little sense. Perhaps there could be a parameter to make dialogs optionally dockable. Or we can just think of it the other way; interfaces that by their nature are/can be persistent are implemented as Panels, but there is an option to make individual panels into free windows (e.g. by just dragging them out of the tray). This could be useful even for native panels.

Eneroth3 avatar Dec 10 '19 19:12 Eneroth3

A dockable property could be ok, although I can't really think of a good reason to make the dialog non-dockable. I think it should function just like the toolbars do. So when an extension creates a toolbar on first run, it's floating out in space. One the toolbar docks, it's position is remembered on subsequent runs. There is one scenario when the position is lost/reset. That happens if the extension is disabled the enabled again after restarting SketchUp.

I really don't really care how it is implemented as long as windows can be docked by the end user. I'm tired of thing floating all over my screen I think SketchUp needs to get their act (app) together.

NeilBurkholder avatar Dec 10 '19 19:12 NeilBurkholder

As an example, Eneroth Reference Manager's Reference Manager window would make perfect sense to dock. It is even designed to be usable when narrow, like a panel.

2019-12-10_20h52_25

In contrast, when you select more than one component to relink, you get a question asking how you want to relink (relink them all by selecting a new shared parent folder or browse individually). That question is functionally an inputbox and shouldn't be dockable. It is only valid until that choice is made, while the main Reference Manager can be used throughout the session.

2019-12-10_20h52_44

Eneroth3 avatar Dec 10 '19 19:12 Eneroth3

That's true. I don't think modal dialogs should be dockable. I'm fine with a dockable property.

~~If~~ When this is implemented, I think the default should follow the window style (dockable unless window style is UI::HtmlDialog::STYLE_DIALOG). Of course if the dialog is shown with show_modal, it shouldn't be dockable.

NeilBurkholder avatar Dec 10 '19 20:12 NeilBurkholder

Regardless of whether this is implemented as a new class or a property, there is a quite fundamental difference in how we as developers need to implement something that is intended to be dockable.

What we currently do:

module Me
  module MyExtesion
    def self.my_method
      # HtmlDialog object only created once a user asks for it.
      dialog = UI::HtmlDialog.new(title: "My Dialog")
      dialog.show
    end
  
    # Some kind of load guard to prevent duplicated menu entries if file is
    # reloaded; might be file_loaded? from sketchup.rb.
    unless @loaded
      @loaded = true
      
      UI.menu("Plugins").add_item("Command") { my_method }
    end
  end
end

What we'd have to do:

module Me
  module MyExtesion
    def self.my_method
      dialog.show
    end
  
    # Some kind of load guard to prevent duplicated menu entries if file is
    # reloaded; might be file_loaded? from sketchup.rb.
    unless @loaded
      @loaded = true
      
      # Dialog/panel needs to be created at plugin load, before user interacts
      # with it.
      @dialog = UI::HtmlDialog.new(title: "My Dialog", dockable: true)
      
      # Assume this is the method for restoring the state from the previous
      # session, if the dialog/panel has been shown before.
      @dialog.restore
      
      UI.menu("Plugins").add_item("Command") { my_method }
    end
  end
end

Or even:

module Me
  module MyExtesion
    # Some kind of load guard to prevent duplicated menu entries if file is
    # reloaded; might be file_loaded? from sketchup.rb.
    unless @loaded
      @loaded = true
      
      # Dialog/panel needs to be created at plugin load, before user interacts
      # with it.
      @dialog = UI::HtmlDialog.new(title: "My Dialog", dockable: true)
      
      # Assume this is the method for restoring the state from the previous
      # session, or show the dialog/panel if no previous state was found.
      @dialog.show
    end
  end
end

Since a persistent docked panel requires a bit of code reorganization anyway, not just a property to be switched, I think it makes sense to separate it to its own class.

Eneroth3 avatar Dec 21 '19 11:12 Eneroth3

I would be fine with a separate class. Making it a new class would require writing some version specific code. I was thinking on the other hand if a dockable property was added to the existing class it could be used in older versions. Depending how far back you support you would need to do a platform check to use either WebDialog, or HTMLDialog anyway.

NeilBurkholder avatar Jan 11 '20 16:01 NeilBurkholder

@thomthom Is there any hope of having this looked at soon? I think this would be a game changer for extension developers. It would make it possible to make professional extensions that act like a part of SketchUp rather than a tacky add-on.

NeilBurkholder avatar Jan 11 '20 16:01 NeilBurkholder

I think it's better to focus on learnability than portability this case. It's not like this is just one property that can be turned on in an otherwise identical code base; the dialog version would need to be hooked up to a menu entry to be shown while the panel version would need to create its object at SketchUp start and restore it to its previous state. Since the whole way of setting up the UI would need to differ anyway between using a panel and a dialog, calling the constructor method on different classes (or inhering from different classes) makes a quite small difference to me.

Eneroth3 avatar Jan 11 '20 20:01 Eneroth3

I was thinking on the other hand if a dockable property was added to the existing class it could be used in older versions.

This would not be the case as those older versions contain older version of the API which would ignore the hash property and not do anything with it. These older versions would not have the code to wrap dockable inspector panel windows around the Chromium EF interfaces.

Also any show method would need to allow the specifying of what tray to dock the panel in, and it's position in the tray. But there is not yet a Sketchup::InspectorTrays collection nor Sketchup::InspectorTray class exposed. (Oh I suppose you could just give integers for the tray number, and position in the tray, but that is rather clunky.)

DanRathbun avatar Jan 12 '20 05:01 DanRathbun

I meant that in older versions the docking properties would be ignored, but considering the input I think a new class would be better. I like the option to enumerate the trays and potentially remove panes from trays. That would be better than the current implementation where menu items can't be removed. I'm thinking of cases where you may want an option to turn your extension 'off'.

NeilBurkholder avatar Jan 12 '20 12:01 NeilBurkholder

Ah .. gotcha. I'd think perhaps if a extension owning a panel was switched off, the core could collapse the panel automatically. Upon loading, a greyed out collapsed panel caption bar could be still rendered in it's dock position (so it keeps it's place.)

Hovering over such a collapsed panel could have a mouse tooltip "#{extension.name} is switched off."

DanRathbun avatar Jan 12 '20 12:01 DanRathbun

... but considering the input I think a new class would be better.

It'd likely be a subclass of UI::HtmlDialog as it'd need most of the parent's methods. Some (like show) will need to be overridden.

Unless they just add a special #dock method used in place of #show (the latter for floating, the former for docking) ?

DanRathbun avatar Jan 12 '20 12:01 DanRathbun

There are use cases for reading and setting panel positions, e.g. to sync your setup between machines and versions, but I don't think that is needed for a first release of custom dockable panels. For now they can just show up in the Default panel and the user can use native UI to move it to any other panel if they wish.

I don't see any reason for special handling for disabled extensions either; if the creation and restoration of a panel isn't made, as it isn't when the extension is disabled, the panel simply doesn't show up in the tray.

Eneroth3 avatar Jan 12 '20 12:01 Eneroth3

A big challenge here is the big difference between macOS and Windows UI. And an UI refresh is also being considered for SketchUp which further complicates this. Any UI related API would be highly dependent on the UI framework it uses.

thomthom avatar Jan 22 '20 14:01 thomthom

That's partly why I was for having a single class for both HTMLDialog and 'HTMLPane'. My thinking was if the docking ability was added in such a way that when not docked (ie. on Mac) it would behave the same as a regular HTMLDialog. This would be a great feature for a UI refresh!! This alone could be a the greatest new feature in the next version. And I know it's not too big a challenge for you @thomthom ;)

I would rather see docking only in the UI with out any added properties, than scrapping the whole thing because it's too challenging. That being said, a fully baked fully baked feature with API properties would be desired.

NeilBurkholder avatar Jan 22 '20 14:01 NeilBurkholder

Instead of thinking of it as a docked panel, perhaps we should just think of it as a custom inspector. To me the goal isn't the tray docking itself, but the consistency to native inspectors. On Mac it can be a floating window that sticks to other similar windows, on Windows it could a tray panel. What the exact behavior is doesn't matter to me, as long as it is consistent to SketchUp.

However it would never be just a normal HtmlDialog. It has to be created at startup and remember its position from the last session to be anything like the native inspectors. Otherwise it would feel awkward and broken, even if you can't put your finger on why.

I would personally much rather scrap the feature (or postpone it) than having something that feels awkward and broken. We already have Dynamic Components, Solid Tools, Classifications, and possibly the Advanced Attributes for that.

Eneroth3 avatar Jan 22 '20 14:01 Eneroth3

I would personally much rather scrap the feature (or postpone it)

No! Please!!!

NeilBurkholder avatar Jan 22 '20 14:01 NeilBurkholder

I don't know if we are talking about the same thing, but to me a window that can be docked but jumps back to be a window on each SketchUp start is by far more annoying than not having the ability to dock it at all.

Eneroth3 avatar Jan 22 '20 14:01 Eneroth3

I would rather see docking only in the UI with out any added properties, than scrapping the whole thing because it's too challenging. That being said, a fully baked fully baked feature with API properties would be desired.

Not planning on scrapping it. But we're looking at it in a bigger context of better UI consistency across SketchUp products - taking into accounts extensions.

thomthom avatar Jan 22 '20 15:01 thomthom

...a window that can be docked but jumps back to be a window on each SketchUp start...

That would most certainly be annoying, and worse than nothing. What I meant is that I would rather have the feature implemented without all the proper API methods available than not have it at all.

In other words even though I hope extension developers will eventually be able to create and edit trays using the API, I feel that allowing the user to do so via the UI is the first most important thing. Of course to me it would make sense to do it all right the first time.

NeilBurkholder avatar Jan 22 '20 15:01 NeilBurkholder

Now I'm with you! I agree completely that such extra functionality isn't a requirement.

Eneroth3 avatar Jan 22 '20 15:01 Eneroth3

But we're looking at it in a bigger context of better UI consistency across SketchUp products

It would be great to be able to dock 'built in dialogs' as well, such as the ruby console.

This is what drives me nuts:

image

NeilBurkholder avatar Jan 22 '20 15:01 NeilBurkholder

It would be great to be able to dock 'built in dialogs' as well, such as the ruby console.

And regardless of it being docked or not, it should remember its visibility between sessions.

Eneroth3 avatar Jan 22 '20 16:01 Eneroth3

It would be great to be able to dock 'built in dialogs' as well, such as the ruby console.

If I docked the console I'd likely dock on the top or bottom in autohide mode. We've asked for docking console long ago probably when trays first came out for v2016.

And regardless of it being docked or not, it should remember its visibility between sessions.

I agree with this, and this is also the reason why I think that UI::HtmlDialog could be docked with only a "dockable" style OR'd in it's options. Tray panel positions are automatically restored when the panel is opened. So the "overhead and control" can be all transparent to the Ruby code. Ie, the #show method restores to the last place either floating or docked according to what the user has done last. (Just as toolbars work from the users point of view.)

The only other possible "need" might be a boolean state that the coder can query whether the dialog window is floating or docked so as to apply differing layouts. (They might be able to work around this by sniffing content width.)

DanRathbun avatar Jan 22 '20 16:01 DanRathbun

I just don't get why they would half implement the whole dialog & tray system.

CiberNin avatar Aug 01 '24 10:08 CiberNin