Skip to content

Commit 884bf2f

Browse files
committed
Merge pull request godotengine#108647 from KoBeWi/docking_abyss
Make bottom panel into available dock slot
2 parents 8480b62 + 67735cf commit 884bf2f

30 files changed

+594
-422
lines changed

doc/classes/EditorDock.xml

Lines changed: 30 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,11 +61,22 @@
6161
[/codeblock]
6262
</description>
6363
</method>
64+
<method name="close">
65+
<return type="void" />
66+
<description>
67+
Closes the dock, making its tab hidden.
68+
</description>
69+
</method>
70+
<method name="open">
71+
<return type="void" />
72+
<description>
73+
Opens the dock. It will appear in the last used dock slot. If the dock has no default slot, it will be opened floating.
74+
</description>
75+
</method>
6476
</methods>
6577
<members>
66-
<member name="available_layouts" type="int" setter="set_available_layouts" getter="get_available_layouts" enum="EditorDock.DockLayout" is_bitfield="true" default="1">
67-
The available layouts for this dock, as a bitmask.
68-
If you want to make all layouts available, use [code]available_layouts = DOCK_LAYOUT_VERTICAL | DOCK_LAYOUT_HORIZONTAL[/code].
78+
<member name="available_layouts" type="int" setter="set_available_layouts" getter="get_available_layouts" enum="EditorDock.DockLayout" is_bitfield="true" default="5">
79+
The available layouts for this dock, as a bitmask. By default, the dock allows vertical and floating layouts.
6980
</member>
7081
<member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
7182
<member name="default_slot" type="int" setter="set_default_slot" getter="get_default_slot" enum="EditorPlugin.DockSlot" default="-1">
@@ -78,6 +89,9 @@
7889
<member name="dock_shortcut" type="Shortcut" setter="set_dock_shortcut" getter="get_dock_shortcut">
7990
The shortcut used to open the dock. This property can only be set before this dock is added via [method EditorPlugin.add_dock].
8091
</member>
92+
<member name="global" type="bool" setter="set_global" getter="is_global" default="true">
93+
If [code]true[/code], the dock appears in the [b]Editor &gt; Editor Docks[/b] menu and can be closed. Non-global docks can still be closed using [method close].
94+
</member>
8195
<member name="icon_name" type="StringName" setter="set_icon_name" getter="get_icon_name" default="&amp;&quot;&quot;">
8296
The icon for the dock, as a name from the [code]EditorIcons[/code] theme type in the editor theme. You can find the list of available icons [url=https://godot-editor-icons.github.io/]here[/url].
8397
</member>
@@ -87,14 +101,25 @@
87101
<member name="title" type="String" setter="set_title" getter="get_title" default="&quot;&quot;">
88102
The title of the dock's tab. If empty, the dock's [member Node.name] will be used. If the name is auto-generated (contains [code]@[/code]), the first child's name will be used instead.
89103
</member>
104+
<member name="title_color" type="Color" setter="set_title_color" getter="get_title_color" default="Color(0, 0, 0, 0)">
105+
The color of the dock tab's title. If its alpha is [code]0.0[/code], the default font color will be used.
106+
</member>
107+
<member name="transient" type="bool" setter="set_transient" getter="is_transient" default="false">
108+
If [code]true[/code], the dock is not automatically opened or closed when loading an editor layout, only moved. It also can't be opened using a shortcut. This is meant for docks that are opened and closed in specific cases, such as when selecting a [TileMap] or [AnimationTree] node.
109+
</member>
90110
</members>
91111
<constants>
92112
<constant name="DOCK_LAYOUT_VERTICAL" value="1" enum="DockLayout" is_bitfield="true">
93113
Allows placing the dock in the vertical dock slots on either side of the editor.
94-
[b]Note:[/b] Currently this flag has no effect because the bottom panel is not a proper dock slot. This means that the dock can always be vertical.
95114
</constant>
96115
<constant name="DOCK_LAYOUT_HORIZONTAL" value="2" enum="DockLayout" is_bitfield="true">
97-
Allows placing the dock in the editor's bottom panel. Implement [method _update_layout] to handle changing layouts.
116+
Allows placing the dock in the editor's bottom panel.
117+
</constant>
118+
<constant name="DOCK_LAYOUT_FLOATING" value="4" enum="DockLayout" is_bitfield="true">
119+
Allows making the dock floating (opened as a separate window).
120+
</constant>
121+
<constant name="DOCK_LAYOUT_ALL" value="7" enum="DockLayout" is_bitfield="true">
122+
Allows placing the dock in all available slots.
98123
</constant>
99124
</constants>
100125
</class>

doc/classes/EditorPlugin.xml

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -424,7 +424,7 @@
424424
[b]Note:[/b] A plugin instance can belong only to a single context menu slot.
425425
</description>
426426
</method>
427-
<method name="add_control_to_bottom_panel">
427+
<method name="add_control_to_bottom_panel" deprecated="Use [method add_dock] instead, with [member EditorDock.default_slot] set to [constant DOCK_SLOT_BOTTOM].">
428428
<return type="Button" />
429429
<param index="0" name="control" type="Control" />
430430
<param index="1" name="title" type="String" />
@@ -662,7 +662,7 @@
662662
Removes the specified context menu plugin.
663663
</description>
664664
</method>
665-
<method name="remove_control_from_bottom_panel">
665+
<method name="remove_control_from_bottom_panel" deprecated="Use [method remove_dock] instead.">
666666
<return type="void" />
667667
<param index="0" name="control" type="Control" />
668668
<description>
@@ -910,7 +910,10 @@
910910
<constant name="DOCK_SLOT_RIGHT_BR" value="7" enum="DockSlot">
911911
Dock slot, right side, bottom-right (empty in default layout).
912912
</constant>
913-
<constant name="DOCK_SLOT_MAX" value="8" enum="DockSlot">
913+
<constant name="DOCK_SLOT_BOTTOM" value="8" enum="DockSlot">
914+
Bottom panel.
915+
</constant>
916+
<constant name="DOCK_SLOT_MAX" value="9" enum="DockSlot">
914917
Represents the size of the [enum DockSlot] enum.
915918
</constant>
916919
<constant name="AFTER_GUI_INPUT_PASS" value="0" enum="AfterGUIInput">

editor/debugger/editor_debugger_node.cpp

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -65,12 +65,6 @@ EditorDebuggerNode::EditorDebuggerNode() {
6565
singleton = this;
6666
}
6767

68-
Ref<StyleBox> bottom_panel_margins = EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles));
69-
add_theme_constant_override("margin_top", -bottom_panel_margins->get_margin(SIDE_TOP));
70-
add_theme_constant_override("margin_left", -bottom_panel_margins->get_margin(SIDE_LEFT));
71-
add_theme_constant_override("margin_right", -bottom_panel_margins->get_margin(SIDE_RIGHT));
72-
add_theme_constant_override("margin_bottom", -bottom_panel_margins->get_margin(SIDE_BOTTOM));
73-
7468
tabs = memnew(TabContainer);
7569
tabs->set_tabs_visible(false);
7670
tabs->connect("tab_changed", callable_mp(this, &EditorDebuggerNode::_debugger_changed));
@@ -332,17 +326,19 @@ void EditorDebuggerNode::_notification(int p_what) {
332326
if (tabs->get_tab_count() > 1) {
333327
tabs->add_theme_style_override(SceneStringName(panel), EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));
334328
}
335-
336-
Ref<StyleBox> bottom_panel_margins = EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles));
337-
add_theme_constant_override("margin_top", -bottom_panel_margins->get_margin(SIDE_TOP));
338-
add_theme_constant_override("margin_left", -bottom_panel_margins->get_margin(SIDE_LEFT));
339-
add_theme_constant_override("margin_right", -bottom_panel_margins->get_margin(SIDE_RIGHT));
340-
add_theme_constant_override("margin_bottom", -bottom_panel_margins->get_margin(SIDE_BOTTOM));
329+
_update_margins();
341330

342331
remote_scene_tree->update_icon_max_width();
343332
} break;
344333

345334
case NOTIFICATION_READY: {
335+
// TODO: Replace this hack once EditorDebuggerNode is converted to a dock. It should be in the constructor.
336+
EditorDock *parent = Object::cast_to<EditorDock>(get_parent());
337+
if (parent) {
338+
parent->set_clip_contents(false);
339+
_update_margins();
340+
}
341+
346342
_update_debug_options();
347343
initializing = false;
348344
} break;
@@ -444,35 +440,41 @@ void EditorDebuggerNode::_update_errors() {
444440
last_error_count = error_count;
445441
last_warning_count = warning_count;
446442

447-
// TODO: Replace logic when EditorDock class is merged to be more flexible.
448-
TabContainer *parent = Object::cast_to<TabContainer>(get_parent());
443+
// TODO: Replace this hack once EditorDebuggerNode is converted to a dock.
444+
EditorDock *parent = Object::cast_to<EditorDock>(get_parent());
449445
if (!parent) {
450446
return;
451447
}
452448

453-
int idx = parent->get_tab_idx_from_control(this);
454-
455449
if (error_count == 0 && warning_count == 0) {
456450
set_name(TTR("Debugger"));
457-
parent->set_tab_icon(idx, Ref<Texture2D>());
458-
parent->get_tab_bar()->set_font_color_override_all(idx, Color(0, 0, 0, 0));
451+
parent->set_dock_icon(Ref<Texture2D>());
452+
parent->set_title_color(Color(0, 0, 0, 0));
459453
} else {
460454
set_name(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")");
461455
if (error_count >= 1 && warning_count >= 1) {
462-
parent->set_tab_icon(idx, get_editor_theme_icon(SNAME("ErrorWarning")));
456+
parent->set_dock_icon(get_editor_theme_icon(SNAME("ErrorWarning")));
463457
// Use error color to represent the highest level of severity reported.
464-
parent->get_tab_bar()->set_font_color_override_all(idx, get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
458+
parent->set_title_color(get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
465459
} else if (error_count >= 1) {
466-
parent->set_tab_icon(idx, get_editor_theme_icon(SNAME("Error")));
467-
parent->get_tab_bar()->set_font_color_override_all(idx, get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
460+
parent->set_dock_icon(get_editor_theme_icon(SNAME("Error")));
461+
parent->set_title_color(get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
468462
} else {
469-
parent->set_tab_icon(idx, get_editor_theme_icon(SNAME("Warning")));
470-
parent->get_tab_bar()->set_font_color_override_all(idx, get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
463+
parent->set_dock_icon(get_editor_theme_icon(SNAME("Warning")));
464+
parent->set_title_color(get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
471465
}
472466
}
473467
}
474468
}
475469

470+
void EditorDebuggerNode::_update_margins() {
471+
Ref<StyleBox> bottom_panel_margins = EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles));
472+
add_theme_constant_override("margin_top", -bottom_panel_margins->get_margin(SIDE_TOP));
473+
add_theme_constant_override("margin_left", -bottom_panel_margins->get_margin(SIDE_LEFT));
474+
add_theme_constant_override("margin_right", -bottom_panel_margins->get_margin(SIDE_RIGHT));
475+
add_theme_constant_override("margin_bottom", -bottom_panel_margins->get_margin(SIDE_BOTTOM));
476+
}
477+
476478
void EditorDebuggerNode::_debugger_stopped(int p_id) {
477479
ScriptEditorDebugger *dbg = get_debugger(p_id);
478480
ERR_FAIL_NULL(dbg);

editor/debugger/editor_debugger_node.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,7 @@ class EditorDebuggerNode : public MarginContainer {
121121

122122
ScriptEditorDebugger *_add_debugger();
123123
void _update_errors();
124+
void _update_margins();
124125

125126
friend class DebuggerEditorPlugin;
126127
friend class DebugAdapterParser;

editor/docks/dock_constants.h

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/**************************************************************************/
2+
/* dock_constants.h */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#pragma once
32+
33+
namespace DockConstants {
34+
35+
enum DockSlot {
36+
DOCK_SLOT_NONE = -1,
37+
DOCK_SLOT_LEFT_UL,
38+
DOCK_SLOT_LEFT_BL,
39+
DOCK_SLOT_LEFT_UR,
40+
DOCK_SLOT_LEFT_BR,
41+
DOCK_SLOT_RIGHT_UL,
42+
DOCK_SLOT_RIGHT_BL,
43+
DOCK_SLOT_RIGHT_UR,
44+
DOCK_SLOT_RIGHT_BR,
45+
DOCK_SLOT_BOTTOM,
46+
DOCK_SLOT_MAX
47+
};
48+
49+
enum DockLayout {
50+
DOCK_LAYOUT_VERTICAL = 1,
51+
DOCK_LAYOUT_HORIZONTAL = 2,
52+
DOCK_LAYOUT_FLOATING = 4,
53+
};
54+
55+
}; //namespace DockConstants

editor/docks/editor_dock.cpp

Lines changed: 59 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@
3232

3333
#include "core/input/shortcut.h"
3434
#include "core/io/config_file.h"
35+
#include "editor/docks/editor_dock_manager.h"
3536

3637
void EditorDock::_set_default_slot_bind(EditorPlugin::DockSlot p_slot) {
3738
ERR_FAIL_COND(p_slot < EditorPlugin::DOCK_SLOT_NONE || p_slot >= EditorPlugin::DOCK_SLOT_MAX);
38-
default_slot = (EditorDockManager::DockSlot)p_slot;
39+
default_slot = (DockConstants::DockSlot)p_slot;
3940
}
4041

4142
void EditorDock::_bind_methods() {
43+
ClassDB::bind_method(D_METHOD("open"), &EditorDock::open);
44+
ClassDB::bind_method(D_METHOD("close"), &EditorDock::close);
45+
4246
ClassDB::bind_method(D_METHOD("set_title", "title"), &EditorDock::set_title);
4347
ClassDB::bind_method(D_METHOD("get_title"), &EditorDock::get_title);
4448
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
@@ -47,6 +51,14 @@ void EditorDock::_bind_methods() {
4751
ClassDB::bind_method(D_METHOD("get_layout_key"), &EditorDock::get_layout_key);
4852
ADD_PROPERTY(PropertyInfo(Variant::STRING, "layout_key"), "set_layout_key", "get_layout_key");
4953

54+
ClassDB::bind_method(D_METHOD("set_global", "global"), &EditorDock::set_global);
55+
ClassDB::bind_method(D_METHOD("is_global"), &EditorDock::is_global);
56+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "global"), "set_global", "is_global");
57+
58+
ClassDB::bind_method(D_METHOD("set_transient", "transient"), &EditorDock::set_transient);
59+
ClassDB::bind_method(D_METHOD("is_transient"), &EditorDock::is_transient);
60+
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transient"), "set_transient", "is_transient");
61+
5062
ClassDB::bind_method(D_METHOD("set_icon_name", "icon_name"), &EditorDock::set_icon_name);
5163
ClassDB::bind_method(D_METHOD("get_icon_name"), &EditorDock::get_icon_name);
5264
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "icon_name"), "set_icon_name", "get_icon_name");
@@ -55,6 +67,10 @@ void EditorDock::_bind_methods() {
5567
ClassDB::bind_method(D_METHOD("get_dock_icon"), &EditorDock::get_dock_icon);
5668
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "dock_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_dock_icon", "get_dock_icon");
5769

70+
ClassDB::bind_method(D_METHOD("set_title_color", "color"), &EditorDock::set_title_color);
71+
ClassDB::bind_method(D_METHOD("get_title_color"), &EditorDock::get_title_color);
72+
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "title_color"), "set_title_color", "get_title_color");
73+
5874
ClassDB::bind_method(D_METHOD("set_dock_shortcut", "shortcut"), &EditorDock::set_dock_shortcut);
5975
ClassDB::bind_method(D_METHOD("get_dock_shortcut"), &EditorDock::get_dock_shortcut);
6076
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "dock_shortcut", PROPERTY_HINT_RESOURCE_TYPE, "ShortCut"), "set_dock_shortcut", "get_dock_shortcut");
@@ -65,10 +81,12 @@ void EditorDock::_bind_methods() {
6581

6682
ClassDB::bind_method(D_METHOD("set_available_layouts", "layouts"), &EditorDock::set_available_layouts);
6783
ClassDB::bind_method(D_METHOD("get_available_layouts"), &EditorDock::get_available_layouts);
68-
ADD_PROPERTY(PropertyInfo(Variant::INT, "available_layouts", PROPERTY_HINT_FLAGS, "Vertical:1,Horizontal:2"), "set_available_layouts", "get_available_layouts");
84+
ADD_PROPERTY(PropertyInfo(Variant::INT, "available_layouts", PROPERTY_HINT_FLAGS, "Vertical:1,Horizontal:2,Floating:3"), "set_available_layouts", "get_available_layouts");
6985

7086
BIND_BITFIELD_FLAG(DOCK_LAYOUT_VERTICAL);
7187
BIND_BITFIELD_FLAG(DOCK_LAYOUT_HORIZONTAL);
88+
BIND_BITFIELD_FLAG(DOCK_LAYOUT_FLOATING);
89+
BIND_BITFIELD_FLAG(DOCK_LAYOUT_ALL);
7290

7391
GDVIRTUAL_BIND(_update_layout, "layout");
7492
GDVIRTUAL_BIND(_save_layout_to_config, "config", "section");
@@ -80,6 +98,18 @@ EditorDock::EditorDock() {
8098
add_user_signal(MethodInfo("tab_style_changed"));
8199
}
82100

101+
void EditorDock::open() {
102+
if (!is_open) {
103+
EditorDockManager::get_singleton()->open_dock(this);
104+
}
105+
}
106+
107+
void EditorDock::close() {
108+
if (is_open) {
109+
EditorDockManager::get_singleton()->close_dock(this);
110+
}
111+
}
112+
83113
void EditorDock::set_title(const String &p_title) {
84114
if (title == p_title) {
85115
return;
@@ -88,6 +118,16 @@ void EditorDock::set_title(const String &p_title) {
88118
emit_signal("tab_style_changed");
89119
}
90120

121+
void EditorDock::set_global(bool p_global) {
122+
if (global == p_global) {
123+
return;
124+
}
125+
global = p_global;
126+
if (is_inside_tree()) {
127+
EditorDockManager::get_singleton()->update_docks_menu();
128+
}
129+
}
130+
91131
void EditorDock::set_icon_name(const StringName &p_name) {
92132
if (icon_name == p_name) {
93133
return;
@@ -104,8 +144,23 @@ void EditorDock::set_dock_icon(const Ref<Texture2D> &p_icon) {
104144
emit_signal("tab_style_changed");
105145
}
106146

107-
void EditorDock::set_default_slot(EditorDockManager::DockSlot p_slot) {
108-
ERR_FAIL_INDEX(p_slot, EditorDockManager::DOCK_SLOT_MAX);
147+
void EditorDock::set_title_color(const Color &p_color) {
148+
if (title_color == p_color) {
149+
return;
150+
}
151+
title_color = p_color;
152+
emit_signal("tab_style_changed");
153+
}
154+
155+
void EditorDock::set_dock_shortcut(const Ref<Shortcut> &p_shortcut) {
156+
shortcut = p_shortcut;
157+
if (global && is_inside_tree()) {
158+
EditorDockManager::get_singleton()->update_docks_menu();
159+
}
160+
}
161+
162+
void EditorDock::set_default_slot(DockConstants::DockSlot p_slot) {
163+
ERR_FAIL_INDEX(p_slot, DockConstants::DOCK_SLOT_MAX);
109164
default_slot = p_slot;
110165
}
111166

0 commit comments

Comments
 (0)