godotengine / godot-proposals

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

Add an easy way to get controls of the bottom panel #5297

Open me2beats opened 2 years ago

me2beats commented 2 years ago

Describe the project you are working on

GDScript editor plugins (Godot 3 - but Godot 4 needs this too)

Describe the problem or limitation you are having in your project

I want to show the Output with a plugin, but this is not trivial. Currently I do it this way.

tool
extends EditorPlugin

func _enter_tree():
    var output_control = get_log(get_editor_interface().get_base_control())
    if not output_control:return
    make_bottom_panel_item_visible(output_control)

func _exit_tree():
    pass

static func get_log(base:Control)->VBoxContainer:
    var result: VBoxContainer = find_node_by_class_path(
        base, [
            'VBoxContainer', 
            'HSplitContainer',
            'HSplitContainer',
            'HSplitContainer',
            'VBoxContainer',
            'VSplitContainer',
            'PanelContainer',
            'VBoxContainer',
            'EditorLog'
        ]
    )
    return result

static func find_node_by_class_path(node:Node, class_path:Array)->Node:
    var res:Node

    var stack = []
    var depths = []

    var first = class_path[0]
    for c in node.get_children():
        if c.get_class() == first:
            stack.push_back(c)
            depths.push_back(0)

    if not stack: return res

    var max_ = class_path.size()-1

    while stack:
        var d = depths.pop_back()
        var n = stack.pop_back()

        if d>max_:
            continue
        if n.get_class() == class_path[d]:
            if d == max_:
                res = n
                return res

            for c in n.get_children():
                stack.push_back(c)
                depths.push_back(d+1)

    return res

this just looks ugly.

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

An ability to easily get bottom panel controls especially built-in controls such as Output (should return the control with type EditorLog), Debugger, Audio, Animation etc, would solve the problem.

Then if I want to show it, I just make_bottom_panel_item_visible(control)

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

I suggest adding 2 functions to EditorPlugin:

  1. Control get_bottom_panel_control(control_name) control name means kinda like control id, localization insensitive: is Output for Output, Debugger for Debugger etc (not "title" because the title is different in different language localizations).

For controls added by plugins (add_control_to_bottom_panel) name could be just a plugin title, later it is better to allow plugin developers to pass plugin custom id as an argument add_control_to_bottom_panel(control: Control, title: String, id: String)

  1. Array get_bottom_panel_controls_names() returns an array with all controls names(ids) (Output, Debugger etc) including controls added by plugins.

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

See the problem section above - you can get the bottom panel controls but the way is ugly.

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

This is for making plugins easier, so this should be core

TamerSoup625 commented 2 years ago

I also ran into this problem when making a small plugin for the Output tab. This was my workaround for getting both the Output control and the ToolButton that opens it.

# This method is still quite hacky
var bottom_control = Control.new()
var bottom_btn = add_control_to_bottom_panel(bottom_control, "")
# Get editor log relative to the "dummy" control
editor_log = bottom_control.get_parent().get_child(0)
# Same with the ToolButton
tool_btn = bottom_btn.get_parent().get_child(0)