Skip to content

Commit bf926c2

Browse files
committed
Merge pull request #106503 from KoBeWi/docker_exe
Rework editor docks
2 parents 4594de6 + 97b398c commit bf926c2

26 files changed

+804
-385
lines changed

doc/classes/EditorDock.xml

Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
<class name="EditorDock" inherits="MarginContainer" experimental="" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
3+
<brief_description>
4+
Dockable container for the editor.
5+
</brief_description>
6+
<description>
7+
EditorDock is a [Container] node that can be docked in one of the editor's dock slots. Docks are added by plugins to provide space for controls related to an [EditorPlugin]. The editor comes with a few built-in docks, such as the Scene dock, FileSystem dock, etc.
8+
You can add a dock by using [method EditorPlugin.add_dock]. The dock can be customized by changing its properties.
9+
[codeblock]
10+
@tool
11+
extends EditorPlugin
12+
13+
# Dock reference.
14+
var dock
15+
16+
# Plugin initialization.
17+
func _enter_tree():
18+
dock = EditorDock.new()
19+
dock.title = "My Dock"
20+
dock.dock_icon = preload("./dock_icon.png")
21+
dock.default_slot = EditorPlugin.DOCK_SLOT_RIGHT_UL
22+
var dock_content = preload("./dock_content.tscn").instantiate()
23+
dock.add_child(dock_content)
24+
add_dock(dock)
25+
26+
# Plugin clean-up.
27+
func _exit_tree():
28+
remove_dock(dock)
29+
dock.queue_free()
30+
dock = null
31+
[/codeblock]
32+
</description>
33+
<tutorials>
34+
<link title="Making plugins">$DOCS_URL/tutorials/plugins/editor/making_plugins.html</link>
35+
</tutorials>
36+
<methods>
37+
<method name="_load_layout_from_config" qualifiers="virtual">
38+
<return type="void" />
39+
<param index="0" name="config" type="ConfigFile" />
40+
<param index="1" name="section" type="String" />
41+
<description>
42+
Implement this method to handle loading this dock's layout. It's equivalent to [method EditorPlugin._set_window_layout]. [param section] is a unique section based on [member layout_key].
43+
</description>
44+
</method>
45+
<method name="_save_layout_to_config" qualifiers="virtual const">
46+
<return type="void" />
47+
<param index="0" name="config" type="ConfigFile" />
48+
<param index="1" name="section" type="String" />
49+
<description>
50+
Implement this method to handle saving this dock's layout. It's equivalent to [method EditorPlugin._get_window_layout]. [param section] is a unique section based on [member layout_key].
51+
</description>
52+
</method>
53+
<method name="_update_layout" qualifiers="virtual">
54+
<return type="void" />
55+
<param index="0" name="layout" type="int" />
56+
<description>
57+
Implement this method to handle the layout switching for this dock. [param layout] is one of the [enum DockLayout] constants.
58+
[codeblock]
59+
_update_layout(layout):
60+
box_container.vertical = (layout == DOCK_LAYOUT_VERTICAL)
61+
[/codeblock]
62+
</description>
63+
</method>
64+
</methods>
65+
<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].
69+
</member>
70+
<member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
71+
<member name="default_slot" type="int" setter="set_default_slot" getter="get_default_slot" enum="EditorPlugin.DockSlot" default="-1">
72+
The default dock slot used when adding the dock with [method EditorPlugin.add_dock].
73+
After the dock is added, it can be moved to a different slot and the editor will automatically remember its position between sessions. If you remove and re-add the dock, it will be reset to default.
74+
</member>
75+
<member name="dock_icon" type="Texture2D" setter="set_dock_icon" getter="get_dock_icon">
76+
The icon for the dock, as a texture. If specified, it will override [member icon_name].
77+
</member>
78+
<member name="dock_shortcut" type="Shortcut" setter="set_dock_shortcut" getter="get_dock_shortcut">
79+
The shortcut used to open the dock. This property can only be set before this dock is added via [method EditorPlugin.add_dock].
80+
</member>
81+
<member name="icon_name" type="StringName" setter="set_icon_name" getter="get_icon_name" default="&amp;&quot;&quot;">
82+
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].
83+
</member>
84+
<member name="layout_key" type="String" setter="set_layout_key" getter="get_layout_key" default="&quot;&quot;">
85+
The key representing this dock in the editor's layout file. If empty, the dock's displayed name will be used instead.
86+
</member>
87+
<member name="title" type="String" setter="set_title" getter="get_title" default="&quot;&quot;">
88+
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.
89+
</member>
90+
</members>
91+
<constants>
92+
<constant name="DOCK_LAYOUT_VERTICAL" value="1" enum="DockLayout" is_bitfield="true">
93+
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.
95+
</constant>
96+
<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.
98+
</constant>
99+
</constants>
100+
</class>

doc/classes/EditorPlugin.xml

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -430,7 +430,7 @@
430430
When your plugin is deactivated, make sure to remove your custom control with [method remove_control_from_container] and free it with [method Node.queue_free].
431431
</description>
432432
</method>
433-
<method name="add_control_to_dock">
433+
<method name="add_control_to_dock" deprecated="Use [method add_dock] instead.">
434434
<return type="void" />
435435
<param index="0" name="slot" type="int" enum="EditorPlugin.DockSlot" />
436436
<param index="1" name="control" type="Control" />
@@ -464,6 +464,14 @@
464464
Adds a [Script] as debugger plugin to the Debugger. The script must extend [EditorDebuggerPlugin].
465465
</description>
466466
</method>
467+
<method name="add_dock">
468+
<return type="void" />
469+
<param index="0" name="dock" type="EditorDock" />
470+
<description>
471+
Adds a new dock.
472+
When your plugin is deactivated, make sure to remove your custom dock with [method remove_dock] and free it with [method Node.queue_free].
473+
</description>
474+
</method>
467475
<method name="add_export_platform">
468476
<return type="void" />
469477
<param index="0" name="platform" type="EditorExportPlatform" />
@@ -655,7 +663,7 @@
655663
Removes the control from the specified container. You have to manually [method Node.queue_free] the control.
656664
</description>
657665
</method>
658-
<method name="remove_control_from_docks">
666+
<method name="remove_control_from_docks" deprecated="Use [method remove_dock] instead.">
659667
<return type="void" />
660668
<param index="0" name="control" type="Control" />
661669
<description>
@@ -676,6 +684,13 @@
676684
Removes the debugger plugin with given script from the Debugger.
677685
</description>
678686
</method>
687+
<method name="remove_dock">
688+
<return type="void" />
689+
<param index="0" name="dock" type="EditorDock" />
690+
<description>
691+
Removes [param dock] from the available docks. You should manually call [method Node.queue_free] to free it.
692+
</description>
693+
</method>
679694
<method name="remove_export_platform">
680695
<return type="void" />
681696
<param index="0" name="platform" type="EditorExportPlatform" />
@@ -753,7 +768,7 @@
753768
Removes a callback previously added by [method add_undo_redo_inspector_hook_callback].
754769
</description>
755770
</method>
756-
<method name="set_dock_tab_icon">
771+
<method name="set_dock_tab_icon" deprecated="Use [member EditorDock.dock_icon] instead.">
757772
<return type="void" />
758773
<param index="0" name="control" type="Control" />
759774
<param index="1" name="icon" type="Texture2D" />
@@ -854,6 +869,9 @@
854869
<constant name="CONTAINER_PROJECT_SETTING_TAB_RIGHT" value="11" enum="CustomControlContainer">
855870
Tab of Project Settings dialog, to the right of other tabs.
856871
</constant>
872+
<constant name="DOCK_SLOT_NONE" value="-1" enum="DockSlot">
873+
The dock is closed.
874+
</constant>
857875
<constant name="DOCK_SLOT_LEFT_UL" value="0" enum="DockSlot">
858876
Dock slot, left side, upper-left (empty in default layout).
859877
</constant>

doc/classes/FileSystemDock.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<?xml version="1.0" encoding="UTF-8" ?>
2-
<class name="FileSystemDock" inherits="VBoxContainer" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
2+
<class name="FileSystemDock" inherits="EditorDock" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../class.xsd">
33
<brief_description>
44
Godot editor's dock for managing files in the project.
55
</brief_description>

editor/docks/editor_dock.cpp

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/**************************************************************************/
2+
/* editor_dock.cpp */
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+
#include "editor_dock.h"
32+
33+
#include "core/input/shortcut.h"
34+
#include "core/io/config_file.h"
35+
36+
void EditorDock::_set_default_slot_bind(EditorPlugin::DockSlot p_slot) {
37+
ERR_FAIL_COND(p_slot < EditorPlugin::DOCK_SLOT_NONE || p_slot >= EditorPlugin::DOCK_SLOT_MAX);
38+
default_slot = (EditorDockManager::DockSlot)p_slot;
39+
}
40+
41+
void EditorDock::_bind_methods() {
42+
ClassDB::bind_method(D_METHOD("set_title", "title"), &EditorDock::set_title);
43+
ClassDB::bind_method(D_METHOD("get_title"), &EditorDock::get_title);
44+
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
45+
46+
ClassDB::bind_method(D_METHOD("set_layout_key", "layout_key"), &EditorDock::set_layout_key);
47+
ClassDB::bind_method(D_METHOD("get_layout_key"), &EditorDock::get_layout_key);
48+
ADD_PROPERTY(PropertyInfo(Variant::STRING, "layout_key"), "set_layout_key", "get_layout_key");
49+
50+
ClassDB::bind_method(D_METHOD("set_icon_name", "icon_name"), &EditorDock::set_icon_name);
51+
ClassDB::bind_method(D_METHOD("get_icon_name"), &EditorDock::get_icon_name);
52+
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "icon_name"), "set_icon_name", "get_icon_name");
53+
54+
ClassDB::bind_method(D_METHOD("set_dock_icon", "icon"), &EditorDock::set_dock_icon);
55+
ClassDB::bind_method(D_METHOD("get_dock_icon"), &EditorDock::get_dock_icon);
56+
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "dock_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_dock_icon", "get_dock_icon");
57+
58+
ClassDB::bind_method(D_METHOD("set_dock_shortcut", "shortcut"), &EditorDock::set_dock_shortcut);
59+
ClassDB::bind_method(D_METHOD("get_dock_shortcut"), &EditorDock::get_dock_shortcut);
60+
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "dock_shortcut", PROPERTY_HINT_RESOURCE_TYPE, "ShortCut"), "set_dock_shortcut", "get_dock_shortcut");
61+
62+
ClassDB::bind_method(D_METHOD("set_default_slot", "slot"), &EditorDock::_set_default_slot_bind);
63+
ClassDB::bind_method(D_METHOD("get_default_slot"), &EditorDock::_get_default_slot_bind);
64+
ADD_PROPERTY(PropertyInfo(Variant::INT, "default_slot"), "set_default_slot", "get_default_slot");
65+
66+
ClassDB::bind_method(D_METHOD("set_available_layouts", "layouts"), &EditorDock::set_available_layouts);
67+
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");
69+
70+
BIND_BITFIELD_FLAG(DOCK_LAYOUT_VERTICAL);
71+
BIND_BITFIELD_FLAG(DOCK_LAYOUT_HORIZONTAL);
72+
73+
GDVIRTUAL_BIND(_update_layout, "layout");
74+
GDVIRTUAL_BIND(_save_layout_to_config, "config", "section");
75+
GDVIRTUAL_BIND(_load_layout_from_config, "config", "section");
76+
}
77+
78+
EditorDock::EditorDock() {
79+
set_clip_contents(true);
80+
add_user_signal(MethodInfo("tab_style_changed"));
81+
}
82+
83+
void EditorDock::set_title(const String &p_title) {
84+
if (title == p_title) {
85+
return;
86+
}
87+
title = p_title;
88+
emit_signal("tab_style_changed");
89+
}
90+
91+
void EditorDock::set_icon_name(const StringName &p_name) {
92+
if (icon_name == p_name) {
93+
return;
94+
}
95+
icon_name = p_name;
96+
emit_signal("tab_style_changed");
97+
}
98+
99+
void EditorDock::set_dock_icon(const Ref<Texture2D> &p_icon) {
100+
if (dock_icon == p_icon) {
101+
return;
102+
}
103+
dock_icon = p_icon;
104+
emit_signal("tab_style_changed");
105+
}
106+
107+
void EditorDock::set_default_slot(EditorDockManager::DockSlot p_slot) {
108+
ERR_FAIL_INDEX(p_slot, EditorDockManager::DOCK_SLOT_MAX);
109+
default_slot = p_slot;
110+
}
111+
112+
String EditorDock::get_display_title() const {
113+
if (!title.is_empty()) {
114+
return title;
115+
}
116+
117+
const String sname = get_name();
118+
if (sname.contains_char('@')) {
119+
// Auto-generated name, try to use something better.
120+
const Node *child = get_child_count() > 0 ? get_child(0) : nullptr;
121+
if (child) {
122+
// In user plugins, the child will usually be dock's content and have a proper name.
123+
return child->get_name();
124+
}
125+
}
126+
return sname;
127+
}
128+
129+
String EditorDock::get_effective_layout_key() const {
130+
return layout_key.is_empty() ? get_display_title() : layout_key;
131+
}

0 commit comments

Comments
 (0)