godotengine / godot-proposals

Godot Improvement Proposals (GIPs)
MIT License
1.16k stars 97 forks source link

Refactor editor API to allow deep editor customizations #2537

Open trollodel opened 3 years ago

trollodel commented 3 years ago

Related to #300, #1761, #2276 See also godotengine/godot#47520

Glossary

Describe the project you are working on

Unrelated to the proposal.

Describe the problem or limitation you are having in your project

Currently, the editor API are quite limited.

  1. You can't access all the components using properly getters. Instead, you have to walk the editor scene tree to get the desired component.
  2. Even if you can access to the desired component with a proper API, often it doesn't expose proper getters to subcomponents.
  3. EditorPlugin is quite monolithic and manages most of the interactions with the editor. While this is a good point in usability as everything is there, it creates a giant class with tons of methods.
  4. Properly plugin interfaces are missing in some components.

Describe the feature / enhancement and how it helps to overcome the problem or limitation

Provide simplified access for most parts of the UI

The idea is to provide different levels of access to the components:

  1. Access components through getters in EditorPlugin or in a proper singleton.
  2. Access from getters in the component to complex subcomponents or specific (complex) nodes that represents the predominant part of the UI (e.g. trees in the Scene dock and in the FileSystem dock). The granularity of getters should be discussed, but the intention is not to expose every button or worse.
  3. Access though node names. Mostly for containers with homogeneous kind of node (e.g. containers of buttons). See #1018
  4. Access walking the tree. Mostly for labels, buttons, containers or other component that are only used for aesthetics, or they are too dynamic to be accessed directly.
Group editor components in singletons

In a complex UI like the Godot Editor, it is necessary to split and group all the component interfaces. So I propose to have several singletons, obtainable though EditorPlugin.

Other enhancement

Describe how your proposal will work, with code, pseudo-code, mock-ups, and/or diagrams

Most was described above, but an editor plugin entry point should look like this (in GDScript):


@tool
extends EditorPlugin

const import_plugin = preload("res://addon/mybigaddon/import_plugin.gd")
const dock =  preload("res://addon/mybigaddon/dock.gd")
const top_level_control = preload("res://addon/mybigaddon/top_level_control.gd")

func _enter_tree():
    var editor_docks = get_editor_docks()
    editor_docks.add_control(dock.new())

    var editor_comp_plugin_interface = get_editor_component_plugin_interface()
    editor_comp_plugin_interface.add_import_plugin(import_plugin.new())
    # or
    var import_dock = get_editor_docks().get_import_dock()
    import_dock.add_plugin(import_plugin.new())

    var editor_interface = get_editor_interface()
    editor_interface.add_top_level_plugin(top_level_plugin.new())

If this enhancement will not be used often, can it be worked around with a few lines of script?

Not always, while it is possible to get every node navigating the scene tree, some nodes have internal objects to manage their status and appearance, and they are not available mostly.

Is there a reason why this should be core and not an add-on in the asset library?

Requires changes in the editor.

Unrelated to the proposal

me2beats commented 3 years ago

As for the docks and bottom panels in general, I think that calling the components "docks" or "bottom panels" is kinda short-sighted, since in the future these components might be floating, or be located on a main screen, etc.

Dock, panel, floating window etc are just options for the arrangement of components/plugins/editors imo.

I think it would be more sensible to have a Components and Plugins singletons.

trollodel commented 3 years ago

As for the docks and bottom panels in general, I think that calling the components "docks" or "bottom panels" is kinda short-sighted, since in the future these components might be floating, or be located on a main screen, etc. ,Dock, panel, floating window etc are just options for the arrangement of components/plugins/editors imo.

This would be nice when it happens, but unfortunately this is not the case right now. Each place has a different API, and they are not trivial to merge in a unified API, especially the main screen/workspace one.

I think it would be more sensible to have a Components and Plugins singletons.

I had though about having a Plugins singletons (I'm always talking about editor plugins, as other kind of addons should be separated IMO), but it is a bit out of scope of this proposal. However, Plugins should not contain methods like add_component_plugin() as they are mostly a convenient shortcut for get_component_dock().add_plugin().

Instead, a Components singleton would become a giant class with dozens of methods (to give you some numbers, there are 6 docks, 14 bottom panels and 4 workspaces, and I'm missing other components such as the main menu) and it's something that I want to avoid as, in the current state, there is a hard separation between component "types".

get_component(component_name - String or enum)

I prefer having separated getters as each component has a dedicated API for its customization, and for type safety/autocompletion stuff.

trollodel commented 3 years ago

All the linked PRs were rejected, but I'm not going to close this because the listed issues still exist and an alternative solution (but related) was discussed in the Godot contributor chat. Also, this is the only existing proposal where there is a generic solution for the listed issues.