mirror of
https://github.com/godotengine/godot.git
synced 2025-12-07 22:00:10 +00:00
Make bottom panel into available dock slot
This commit is contained in:
parent
b79fe2e020
commit
67735cf213
30 changed files with 594 additions and 422 deletions
|
|
@ -61,11 +61,22 @@
|
|||
[/codeblock]
|
||||
</description>
|
||||
</method>
|
||||
<method name="close">
|
||||
<return type="void" />
|
||||
<description>
|
||||
Closes the dock, making its tab hidden.
|
||||
</description>
|
||||
</method>
|
||||
<method name="open">
|
||||
<return type="void" />
|
||||
<description>
|
||||
Opens the dock. It will appear in the last used dock slot. If the dock has no default slot, it will be opened floating.
|
||||
</description>
|
||||
</method>
|
||||
</methods>
|
||||
<members>
|
||||
<member name="available_layouts" type="int" setter="set_available_layouts" getter="get_available_layouts" enum="EditorDock.DockLayout" is_bitfield="true" default="1">
|
||||
The available layouts for this dock, as a bitmask.
|
||||
If you want to make all layouts available, use [code]available_layouts = DOCK_LAYOUT_VERTICAL | DOCK_LAYOUT_HORIZONTAL[/code].
|
||||
<member name="available_layouts" type="int" setter="set_available_layouts" getter="get_available_layouts" enum="EditorDock.DockLayout" is_bitfield="true" default="5">
|
||||
The available layouts for this dock, as a bitmask. By default, the dock allows vertical and floating layouts.
|
||||
</member>
|
||||
<member name="clip_contents" type="bool" setter="set_clip_contents" getter="is_clipping_contents" overrides="Control" default="true" />
|
||||
<member name="default_slot" type="int" setter="set_default_slot" getter="get_default_slot" enum="EditorPlugin.DockSlot" default="-1">
|
||||
|
|
@ -78,6 +89,9 @@
|
|||
<member name="dock_shortcut" type="Shortcut" setter="set_dock_shortcut" getter="get_dock_shortcut">
|
||||
The shortcut used to open the dock. This property can only be set before this dock is added via [method EditorPlugin.add_dock].
|
||||
</member>
|
||||
<member name="global" type="bool" setter="set_global" getter="is_global" default="true">
|
||||
If [code]true[/code], the dock appears in the [b]Editor > Editor Docks[/b] menu and can be closed. Non-global docks can still be closed using [method close].
|
||||
</member>
|
||||
<member name="icon_name" type="StringName" setter="set_icon_name" getter="get_icon_name" default="&""">
|
||||
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].
|
||||
</member>
|
||||
|
|
@ -87,14 +101,25 @@
|
|||
<member name="title" type="String" setter="set_title" getter="get_title" default="""">
|
||||
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.
|
||||
</member>
|
||||
<member name="title_color" type="Color" setter="set_title_color" getter="get_title_color" default="Color(0, 0, 0, 0)">
|
||||
The color of the dock tab's title. If its alpha is [code]0.0[/code], the default font color will be used.
|
||||
</member>
|
||||
<member name="transient" type="bool" setter="set_transient" getter="is_transient" default="false">
|
||||
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.
|
||||
</member>
|
||||
</members>
|
||||
<constants>
|
||||
<constant name="DOCK_LAYOUT_VERTICAL" value="1" enum="DockLayout" is_bitfield="true">
|
||||
Allows placing the dock in the vertical dock slots on either side of the editor.
|
||||
[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.
|
||||
</constant>
|
||||
<constant name="DOCK_LAYOUT_HORIZONTAL" value="2" enum="DockLayout" is_bitfield="true">
|
||||
Allows placing the dock in the editor's bottom panel. Implement [method _update_layout] to handle changing layouts.
|
||||
Allows placing the dock in the editor's bottom panel.
|
||||
</constant>
|
||||
<constant name="DOCK_LAYOUT_FLOATING" value="4" enum="DockLayout" is_bitfield="true">
|
||||
Allows making the dock floating (opened as a separate window).
|
||||
</constant>
|
||||
<constant name="DOCK_LAYOUT_ALL" value="7" enum="DockLayout" is_bitfield="true">
|
||||
Allows placing the dock in all available slots.
|
||||
</constant>
|
||||
</constants>
|
||||
</class>
|
||||
|
|
|
|||
|
|
@ -424,7 +424,7 @@
|
|||
[b]Note:[/b] A plugin instance can belong only to a single context menu slot.
|
||||
</description>
|
||||
</method>
|
||||
<method name="add_control_to_bottom_panel">
|
||||
<method name="add_control_to_bottom_panel" deprecated="Use [method add_dock] instead, with [member EditorDock.default_slot] set to [constant DOCK_SLOT_BOTTOM].">
|
||||
<return type="Button" />
|
||||
<param index="0" name="control" type="Control" />
|
||||
<param index="1" name="title" type="String" />
|
||||
|
|
@ -662,7 +662,7 @@
|
|||
Removes the specified context menu plugin.
|
||||
</description>
|
||||
</method>
|
||||
<method name="remove_control_from_bottom_panel">
|
||||
<method name="remove_control_from_bottom_panel" deprecated="Use [method remove_dock] instead.">
|
||||
<return type="void" />
|
||||
<param index="0" name="control" type="Control" />
|
||||
<description>
|
||||
|
|
@ -910,7 +910,10 @@
|
|||
<constant name="DOCK_SLOT_RIGHT_BR" value="7" enum="DockSlot">
|
||||
Dock slot, right side, bottom-right (empty in default layout).
|
||||
</constant>
|
||||
<constant name="DOCK_SLOT_MAX" value="8" enum="DockSlot">
|
||||
<constant name="DOCK_SLOT_BOTTOM" value="8" enum="DockSlot">
|
||||
Bottom panel.
|
||||
</constant>
|
||||
<constant name="DOCK_SLOT_MAX" value="9" enum="DockSlot">
|
||||
Represents the size of the [enum DockSlot] enum.
|
||||
</constant>
|
||||
<constant name="AFTER_GUI_INPUT_PASS" value="0" enum="AfterGUIInput">
|
||||
|
|
|
|||
|
|
@ -65,12 +65,6 @@ EditorDebuggerNode::EditorDebuggerNode() {
|
|||
singleton = this;
|
||||
}
|
||||
|
||||
Ref<StyleBox> bottom_panel_margins = EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles));
|
||||
add_theme_constant_override("margin_top", -bottom_panel_margins->get_margin(SIDE_TOP));
|
||||
add_theme_constant_override("margin_left", -bottom_panel_margins->get_margin(SIDE_LEFT));
|
||||
add_theme_constant_override("margin_right", -bottom_panel_margins->get_margin(SIDE_RIGHT));
|
||||
add_theme_constant_override("margin_bottom", -bottom_panel_margins->get_margin(SIDE_BOTTOM));
|
||||
|
||||
tabs = memnew(TabContainer);
|
||||
tabs->set_tabs_visible(false);
|
||||
tabs->connect("tab_changed", callable_mp(this, &EditorDebuggerNode::_debugger_changed));
|
||||
|
|
@ -332,17 +326,19 @@ void EditorDebuggerNode::_notification(int p_what) {
|
|||
if (tabs->get_tab_count() > 1) {
|
||||
tabs->add_theme_style_override(SceneStringName(panel), EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("DebuggerPanel"), EditorStringName(EditorStyles)));
|
||||
}
|
||||
|
||||
Ref<StyleBox> bottom_panel_margins = EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles));
|
||||
add_theme_constant_override("margin_top", -bottom_panel_margins->get_margin(SIDE_TOP));
|
||||
add_theme_constant_override("margin_left", -bottom_panel_margins->get_margin(SIDE_LEFT));
|
||||
add_theme_constant_override("margin_right", -bottom_panel_margins->get_margin(SIDE_RIGHT));
|
||||
add_theme_constant_override("margin_bottom", -bottom_panel_margins->get_margin(SIDE_BOTTOM));
|
||||
_update_margins();
|
||||
|
||||
remote_scene_tree->update_icon_max_width();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_READY: {
|
||||
// TODO: Replace this hack once EditorDebuggerNode is converted to a dock. It should be in the constructor.
|
||||
EditorDock *parent = Object::cast_to<EditorDock>(get_parent());
|
||||
if (parent) {
|
||||
parent->set_clip_contents(false);
|
||||
_update_margins();
|
||||
}
|
||||
|
||||
_update_debug_options();
|
||||
initializing = false;
|
||||
} break;
|
||||
|
|
@ -444,35 +440,41 @@ void EditorDebuggerNode::_update_errors() {
|
|||
last_error_count = error_count;
|
||||
last_warning_count = warning_count;
|
||||
|
||||
// TODO: Replace logic when EditorDock class is merged to be more flexible.
|
||||
TabContainer *parent = Object::cast_to<TabContainer>(get_parent());
|
||||
// TODO: Replace this hack once EditorDebuggerNode is converted to a dock.
|
||||
EditorDock *parent = Object::cast_to<EditorDock>(get_parent());
|
||||
if (!parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
int idx = parent->get_tab_idx_from_control(this);
|
||||
|
||||
if (error_count == 0 && warning_count == 0) {
|
||||
set_name(TTR("Debugger"));
|
||||
parent->set_tab_icon(idx, Ref<Texture2D>());
|
||||
parent->get_tab_bar()->set_font_color_override_all(idx, Color(0, 0, 0, 0));
|
||||
parent->set_dock_icon(Ref<Texture2D>());
|
||||
parent->set_title_color(Color(0, 0, 0, 0));
|
||||
} else {
|
||||
set_name(TTR("Debugger") + " (" + itos(error_count + warning_count) + ")");
|
||||
if (error_count >= 1 && warning_count >= 1) {
|
||||
parent->set_tab_icon(idx, get_editor_theme_icon(SNAME("ErrorWarning")));
|
||||
parent->set_dock_icon(get_editor_theme_icon(SNAME("ErrorWarning")));
|
||||
// Use error color to represent the highest level of severity reported.
|
||||
parent->get_tab_bar()->set_font_color_override_all(idx, get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
|
||||
parent->set_title_color(get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
|
||||
} else if (error_count >= 1) {
|
||||
parent->set_tab_icon(idx, get_editor_theme_icon(SNAME("Error")));
|
||||
parent->get_tab_bar()->set_font_color_override_all(idx, get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
|
||||
parent->set_dock_icon(get_editor_theme_icon(SNAME("Error")));
|
||||
parent->set_title_color(get_theme_color(SNAME("error_color"), EditorStringName(Editor)));
|
||||
} else {
|
||||
parent->set_tab_icon(idx, get_editor_theme_icon(SNAME("Warning")));
|
||||
parent->get_tab_bar()->set_font_color_override_all(idx, get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
|
||||
parent->set_dock_icon(get_editor_theme_icon(SNAME("Warning")));
|
||||
parent->set_title_color(get_theme_color(SNAME("warning_color"), EditorStringName(Editor)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorDebuggerNode::_update_margins() {
|
||||
Ref<StyleBox> bottom_panel_margins = EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles));
|
||||
add_theme_constant_override("margin_top", -bottom_panel_margins->get_margin(SIDE_TOP));
|
||||
add_theme_constant_override("margin_left", -bottom_panel_margins->get_margin(SIDE_LEFT));
|
||||
add_theme_constant_override("margin_right", -bottom_panel_margins->get_margin(SIDE_RIGHT));
|
||||
add_theme_constant_override("margin_bottom", -bottom_panel_margins->get_margin(SIDE_BOTTOM));
|
||||
}
|
||||
|
||||
void EditorDebuggerNode::_debugger_stopped(int p_id) {
|
||||
ScriptEditorDebugger *dbg = get_debugger(p_id);
|
||||
ERR_FAIL_NULL(dbg);
|
||||
|
|
|
|||
|
|
@ -121,6 +121,7 @@ private:
|
|||
|
||||
ScriptEditorDebugger *_add_debugger();
|
||||
void _update_errors();
|
||||
void _update_margins();
|
||||
|
||||
friend class DebuggerEditorPlugin;
|
||||
friend class DebugAdapterParser;
|
||||
|
|
|
|||
55
editor/docks/dock_constants.h
Normal file
55
editor/docks/dock_constants.h
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/**************************************************************************/
|
||||
/* dock_constants.h */
|
||||
/**************************************************************************/
|
||||
/* This file is part of: */
|
||||
/* GODOT ENGINE */
|
||||
/* https://godotengine.org */
|
||||
/**************************************************************************/
|
||||
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
|
||||
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
|
||||
/* */
|
||||
/* Permission is hereby granted, free of charge, to any person obtaining */
|
||||
/* a copy of this software and associated documentation files (the */
|
||||
/* "Software"), to deal in the Software without restriction, including */
|
||||
/* without limitation the rights to use, copy, modify, merge, publish, */
|
||||
/* distribute, sublicense, and/or sell copies of the Software, and to */
|
||||
/* permit persons to whom the Software is furnished to do so, subject to */
|
||||
/* the following conditions: */
|
||||
/* */
|
||||
/* The above copyright notice and this permission notice shall be */
|
||||
/* included in all copies or substantial portions of the Software. */
|
||||
/* */
|
||||
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
|
||||
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
|
||||
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
|
||||
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
|
||||
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
|
||||
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
|
||||
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
|
||||
/**************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace DockConstants {
|
||||
|
||||
enum DockSlot {
|
||||
DOCK_SLOT_NONE = -1,
|
||||
DOCK_SLOT_LEFT_UL,
|
||||
DOCK_SLOT_LEFT_BL,
|
||||
DOCK_SLOT_LEFT_UR,
|
||||
DOCK_SLOT_LEFT_BR,
|
||||
DOCK_SLOT_RIGHT_UL,
|
||||
DOCK_SLOT_RIGHT_BL,
|
||||
DOCK_SLOT_RIGHT_UR,
|
||||
DOCK_SLOT_RIGHT_BR,
|
||||
DOCK_SLOT_BOTTOM,
|
||||
DOCK_SLOT_MAX
|
||||
};
|
||||
|
||||
enum DockLayout {
|
||||
DOCK_LAYOUT_VERTICAL = 1,
|
||||
DOCK_LAYOUT_HORIZONTAL = 2,
|
||||
DOCK_LAYOUT_FLOATING = 4,
|
||||
};
|
||||
|
||||
}; //namespace DockConstants
|
||||
|
|
@ -32,13 +32,17 @@
|
|||
|
||||
#include "core/input/shortcut.h"
|
||||
#include "core/io/config_file.h"
|
||||
#include "editor/docks/editor_dock_manager.h"
|
||||
|
||||
void EditorDock::_set_default_slot_bind(EditorPlugin::DockSlot p_slot) {
|
||||
ERR_FAIL_COND(p_slot < EditorPlugin::DOCK_SLOT_NONE || p_slot >= EditorPlugin::DOCK_SLOT_MAX);
|
||||
default_slot = (EditorDockManager::DockSlot)p_slot;
|
||||
default_slot = (DockConstants::DockSlot)p_slot;
|
||||
}
|
||||
|
||||
void EditorDock::_bind_methods() {
|
||||
ClassDB::bind_method(D_METHOD("open"), &EditorDock::open);
|
||||
ClassDB::bind_method(D_METHOD("close"), &EditorDock::close);
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_title", "title"), &EditorDock::set_title);
|
||||
ClassDB::bind_method(D_METHOD("get_title"), &EditorDock::get_title);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "title"), "set_title", "get_title");
|
||||
|
|
@ -47,6 +51,14 @@ void EditorDock::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_layout_key"), &EditorDock::get_layout_key);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING, "layout_key"), "set_layout_key", "get_layout_key");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_global", "global"), &EditorDock::set_global);
|
||||
ClassDB::bind_method(D_METHOD("is_global"), &EditorDock::is_global);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "global"), "set_global", "is_global");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_transient", "transient"), &EditorDock::set_transient);
|
||||
ClassDB::bind_method(D_METHOD("is_transient"), &EditorDock::is_transient);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "transient"), "set_transient", "is_transient");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_icon_name", "icon_name"), &EditorDock::set_icon_name);
|
||||
ClassDB::bind_method(D_METHOD("get_icon_name"), &EditorDock::get_icon_name);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::STRING_NAME, "icon_name"), "set_icon_name", "get_icon_name");
|
||||
|
|
@ -55,6 +67,10 @@ void EditorDock::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("get_dock_icon"), &EditorDock::get_dock_icon);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "dock_icon", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_dock_icon", "get_dock_icon");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_title_color", "color"), &EditorDock::set_title_color);
|
||||
ClassDB::bind_method(D_METHOD("get_title_color"), &EditorDock::get_title_color);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::COLOR, "title_color"), "set_title_color", "get_title_color");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("set_dock_shortcut", "shortcut"), &EditorDock::set_dock_shortcut);
|
||||
ClassDB::bind_method(D_METHOD("get_dock_shortcut"), &EditorDock::get_dock_shortcut);
|
||||
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() {
|
|||
|
||||
ClassDB::bind_method(D_METHOD("set_available_layouts", "layouts"), &EditorDock::set_available_layouts);
|
||||
ClassDB::bind_method(D_METHOD("get_available_layouts"), &EditorDock::get_available_layouts);
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "available_layouts", PROPERTY_HINT_FLAGS, "Vertical:1,Horizontal:2"), "set_available_layouts", "get_available_layouts");
|
||||
ADD_PROPERTY(PropertyInfo(Variant::INT, "available_layouts", PROPERTY_HINT_FLAGS, "Vertical:1,Horizontal:2,Floating:3"), "set_available_layouts", "get_available_layouts");
|
||||
|
||||
BIND_BITFIELD_FLAG(DOCK_LAYOUT_VERTICAL);
|
||||
BIND_BITFIELD_FLAG(DOCK_LAYOUT_HORIZONTAL);
|
||||
BIND_BITFIELD_FLAG(DOCK_LAYOUT_FLOATING);
|
||||
BIND_BITFIELD_FLAG(DOCK_LAYOUT_ALL);
|
||||
|
||||
GDVIRTUAL_BIND(_update_layout, "layout");
|
||||
GDVIRTUAL_BIND(_save_layout_to_config, "config", "section");
|
||||
|
|
@ -80,6 +98,18 @@ EditorDock::EditorDock() {
|
|||
add_user_signal(MethodInfo("tab_style_changed"));
|
||||
}
|
||||
|
||||
void EditorDock::open() {
|
||||
if (!is_open) {
|
||||
EditorDockManager::get_singleton()->open_dock(this);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorDock::close() {
|
||||
if (is_open) {
|
||||
EditorDockManager::get_singleton()->close_dock(this);
|
||||
}
|
||||
}
|
||||
|
||||
void EditorDock::set_title(const String &p_title) {
|
||||
if (title == p_title) {
|
||||
return;
|
||||
|
|
@ -88,6 +118,16 @@ void EditorDock::set_title(const String &p_title) {
|
|||
emit_signal("tab_style_changed");
|
||||
}
|
||||
|
||||
void EditorDock::set_global(bool p_global) {
|
||||
if (global == p_global) {
|
||||
return;
|
||||
}
|
||||
global = p_global;
|
||||
if (is_inside_tree()) {
|
||||
EditorDockManager::get_singleton()->update_docks_menu();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorDock::set_icon_name(const StringName &p_name) {
|
||||
if (icon_name == p_name) {
|
||||
return;
|
||||
|
|
@ -104,8 +144,23 @@ void EditorDock::set_dock_icon(const Ref<Texture2D> &p_icon) {
|
|||
emit_signal("tab_style_changed");
|
||||
}
|
||||
|
||||
void EditorDock::set_default_slot(EditorDockManager::DockSlot p_slot) {
|
||||
ERR_FAIL_INDEX(p_slot, EditorDockManager::DOCK_SLOT_MAX);
|
||||
void EditorDock::set_title_color(const Color &p_color) {
|
||||
if (title_color == p_color) {
|
||||
return;
|
||||
}
|
||||
title_color = p_color;
|
||||
emit_signal("tab_style_changed");
|
||||
}
|
||||
|
||||
void EditorDock::set_dock_shortcut(const Ref<Shortcut> &p_shortcut) {
|
||||
shortcut = p_shortcut;
|
||||
if (global && is_inside_tree()) {
|
||||
EditorDockManager::get_singleton()->update_docks_menu();
|
||||
}
|
||||
}
|
||||
|
||||
void EditorDock::set_default_slot(DockConstants::DockSlot p_slot) {
|
||||
ERR_FAIL_INDEX(p_slot, DockConstants::DOCK_SLOT_MAX);
|
||||
default_slot = p_slot;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -43,30 +43,34 @@ class EditorDock : public MarginContainer {
|
|||
|
||||
public:
|
||||
enum DockLayout {
|
||||
DOCK_LAYOUT_VERTICAL = 1,
|
||||
DOCK_LAYOUT_HORIZONTAL = 2,
|
||||
DOCK_LAYOUT_VERTICAL = DockConstants::DOCK_LAYOUT_VERTICAL,
|
||||
DOCK_LAYOUT_HORIZONTAL = DockConstants::DOCK_LAYOUT_HORIZONTAL,
|
||||
DOCK_LAYOUT_FLOATING = DockConstants::DOCK_LAYOUT_FLOATING,
|
||||
DOCK_LAYOUT_ALL = DOCK_LAYOUT_VERTICAL | DOCK_LAYOUT_HORIZONTAL | DOCK_LAYOUT_FLOATING,
|
||||
};
|
||||
|
||||
private:
|
||||
friend class EditorDockManager;
|
||||
friend class DockContextPopup;
|
||||
friend class DockShortcutHandler;
|
||||
|
||||
String title;
|
||||
String layout_key;
|
||||
StringName icon_name;
|
||||
Ref<Texture2D> dock_icon;
|
||||
Color title_color = Color(0, 0, 0, 0);
|
||||
Ref<Shortcut> shortcut;
|
||||
EditorDockManager::DockSlot default_slot = EditorDockManager::DOCK_SLOT_NONE;
|
||||
DockConstants::DockSlot default_slot = DockConstants::DOCK_SLOT_NONE;
|
||||
bool global = true;
|
||||
bool transient = false;
|
||||
|
||||
BitField<DockLayout> available_layouts = DOCK_LAYOUT_VERTICAL;
|
||||
BitField<DockLayout> available_layouts = DOCK_LAYOUT_VERTICAL | DOCK_LAYOUT_FLOATING;
|
||||
|
||||
bool open = false;
|
||||
bool is_open = false;
|
||||
bool enabled = true;
|
||||
bool at_bottom = false;
|
||||
int previous_tab_index = -1;
|
||||
bool previous_at_bottom = false;
|
||||
WindowWrapper *dock_window = nullptr;
|
||||
int dock_slot_index = EditorDockManager::DOCK_SLOT_NONE;
|
||||
int dock_slot_index = DockConstants::DOCK_SLOT_NONE;
|
||||
|
||||
void _set_default_slot_bind(EditorPlugin::DockSlot p_slot);
|
||||
EditorPlugin::DockSlot _get_default_slot_bind() const { return (EditorPlugin::DockSlot)default_slot; }
|
||||
|
|
@ -81,23 +85,35 @@ protected:
|
|||
public:
|
||||
EditorDock();
|
||||
|
||||
void open();
|
||||
void close();
|
||||
|
||||
void set_title(const String &p_title);
|
||||
String get_title() const { return title; }
|
||||
|
||||
void set_layout_key(const String &p_key) { layout_key = p_key; }
|
||||
String get_layout_key() const { return layout_key; }
|
||||
|
||||
void set_global(bool p_global);
|
||||
bool is_global() const { return global; }
|
||||
|
||||
void set_transient(bool p_transient) { transient = p_transient; }
|
||||
bool is_transient() const { return transient; }
|
||||
|
||||
void set_icon_name(const StringName &p_name);
|
||||
StringName get_icon_name() const { return icon_name; }
|
||||
|
||||
void set_dock_icon(const Ref<Texture2D> &p_icon);
|
||||
Ref<Texture2D> get_dock_icon() const { return dock_icon; }
|
||||
|
||||
void set_dock_shortcut(const Ref<Shortcut> &p_shortcut) { shortcut = p_shortcut; }
|
||||
void set_title_color(const Color &p_color);
|
||||
Color get_title_color() const { return title_color; }
|
||||
|
||||
void set_dock_shortcut(const Ref<Shortcut> &p_shortcut);
|
||||
Ref<Shortcut> get_dock_shortcut() const { return shortcut; }
|
||||
|
||||
void set_default_slot(EditorDockManager::DockSlot p_slot);
|
||||
EditorDockManager::DockSlot get_default_slot() const { return default_slot; }
|
||||
void set_default_slot(DockConstants::DockSlot p_slot);
|
||||
DockConstants::DockSlot get_default_slot() const { return default_slot; }
|
||||
|
||||
void set_available_layouts(BitField<DockLayout> p_layouts) { available_layouts = p_layouts; }
|
||||
BitField<DockLayout> get_available_layouts() const { return available_layouts; }
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ void EditorDockDragHint::drop_data(const Point2 &p_point, const Variant &p_data)
|
|||
if (drop_tabbar->get_rect().has_point(p_point)) {
|
||||
drop_tabbar->_handle_drop_data("tab_container_tab", p_point, p_data, callable_mp(this, &EditorDockDragHint::_drag_move_tab), callable_mp(this, &EditorDockDragHint::_drag_move_tab_from));
|
||||
} else {
|
||||
dock_manager->_move_dock(dock_manager->_get_dock_tab_dragged(), dock_manager->dock_slot[occupied_slot], drop_tabbar->get_tab_count());
|
||||
dock_manager->_move_dock(dock_manager->_get_dock_tab_dragged(), dock_manager->dock_slots[occupied_slot].container, drop_tabbar->get_tab_count());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -78,7 +78,7 @@ void EditorDockDragHint::_drag_move_tab(int p_from_index, int p_to_index) {
|
|||
}
|
||||
|
||||
void EditorDockDragHint::_drag_move_tab_from(TabBar *p_from_tabbar, int p_from_index, int p_to_index) {
|
||||
dock_manager->_move_dock(dock_manager->_get_dock_tab_dragged(), dock_manager->dock_slot[occupied_slot], p_to_index);
|
||||
dock_manager->_move_dock(dock_manager->_get_dock_tab_dragged(), dock_manager->dock_slots[occupied_slot].container, p_to_index);
|
||||
}
|
||||
|
||||
void EditorDockDragHint::gui_input(const Ref<InputEvent> &p_event) {
|
||||
|
|
@ -96,9 +96,9 @@ void EditorDockDragHint::gui_input(const Ref<InputEvent> &p_event) {
|
|||
}
|
||||
}
|
||||
|
||||
void EditorDockDragHint::set_slot(EditorDockManager::DockSlot p_slot) {
|
||||
void EditorDockDragHint::set_slot(DockConstants::DockSlot p_slot) {
|
||||
occupied_slot = p_slot;
|
||||
drop_tabbar = dock_manager->dock_slot[occupied_slot]->get_tab_bar();
|
||||
drop_tabbar = dock_manager->dock_slots[occupied_slot].container->get_tab_bar();
|
||||
}
|
||||
|
||||
void EditorDockDragHint::_notification(int p_what) {
|
||||
|
|
@ -123,12 +123,12 @@ void EditorDockDragHint::_notification(int p_what) {
|
|||
} break;
|
||||
|
||||
case NOTIFICATION_DRAG_BEGIN: {
|
||||
Control *dragged_dock = dock_manager->_get_dock_tab_dragged();
|
||||
EditorDock *dragged_dock = dock_manager->_get_dock_tab_dragged();
|
||||
if (!dragged_dock) {
|
||||
return;
|
||||
}
|
||||
|
||||
can_drop_dock = true;
|
||||
can_drop_dock = dragged_dock->get_available_layouts() & (EditorDock::DockLayout)EditorDockManager::get_singleton()->dock_slots[occupied_slot].layout;
|
||||
|
||||
dock_drop_highlight->set_border_color(valid_drop_color);
|
||||
dock_drop_highlight->set_bg_color(valid_drop_color * Color(1, 1, 1, 0.1));
|
||||
|
|
@ -141,7 +141,7 @@ void EditorDockDragHint::_notification(int p_what) {
|
|||
} break;
|
||||
|
||||
case NOTIFICATION_DRAW: {
|
||||
if (!mouse_inside) {
|
||||
if (!mouse_inside || !can_drop_dock) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -151,6 +151,7 @@ void EditorDockDragHint::_notification(int p_what) {
|
|||
|
||||
// Only display tabbar hint if the mouse is over the tabbar.
|
||||
if (drop_tabbar->get_global_rect().has_point(get_global_mouse_position())) {
|
||||
draw_set_transform(drop_tabbar->get_position()); // The TabBar isn't always on top.
|
||||
drop_tabbar->_draw_tab_drop(get_canvas_item());
|
||||
}
|
||||
} break;
|
||||
|
|
@ -245,7 +246,7 @@ EditorDock *EditorDockManager::_get_dock_tab_dragged() {
|
|||
return dock_tab_dragged;
|
||||
}
|
||||
|
||||
Dictionary dock_drop_data = dock_slot[DOCK_SLOT_LEFT_BL]->get_viewport()->gui_get_drag_data();
|
||||
Dictionary dock_drop_data = dock_slots[DockConstants::DOCK_SLOT_LEFT_BL].container->get_viewport()->gui_get_drag_data();
|
||||
|
||||
// Check if we are dragging a dock.
|
||||
if (dock_drop_data.get("type", "").operator String() != "tab") {
|
||||
|
|
@ -269,10 +270,10 @@ EditorDock *EditorDockManager::_get_dock_tab_dragged() {
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
|
||||
if (dock_slot[i]->is_visible_in_tree()) {
|
||||
dock_drag_rects[i]->set_rect(dock_slot[i]->get_global_rect());
|
||||
dock_drag_rects[i]->show();
|
||||
for (int i = 0; i < DockConstants::DOCK_SLOT_MAX; i++) {
|
||||
if (dock_slots[i].container->is_visible_in_tree()) {
|
||||
dock_slots[i].drag_hint->set_rect(dock_slots[i].container->get_global_rect());
|
||||
dock_slots[i].drag_hint->show();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -334,7 +335,7 @@ void EditorDockManager::update_docks_menu() {
|
|||
int id = 0;
|
||||
const Callable icon_fetch = callable_mp((Window *)docks_menu, &Window::get_editor_theme_native_menu_icon).bind(global_menu, dark_mode);
|
||||
for (EditorDock *dock : all_docks) {
|
||||
if (!dock->enabled) {
|
||||
if (!dock->enabled || !dock->global) {
|
||||
continue;
|
||||
}
|
||||
if (dock->shortcut.is_valid()) {
|
||||
|
|
@ -347,7 +348,7 @@ void EditorDockManager::update_docks_menu() {
|
|||
|
||||
const Ref<Texture2D> icon = _get_dock_icon(dock, icon_fetch);
|
||||
docks_menu->set_item_icon(id, icon.is_valid() ? icon : default_icon);
|
||||
if (!dock->open) {
|
||||
if (!dock->is_open) {
|
||||
docks_menu->set_item_icon_modulate(id, closed_icon_color_mod);
|
||||
docks_menu->set_item_tooltip(id, vformat(TTR("Open the %s dock."), dock->get_display_title()));
|
||||
} else {
|
||||
|
|
@ -362,7 +363,7 @@ void EditorDockManager::_docks_menu_option(int p_id) {
|
|||
EditorDock *dock = docks_menu_docks[p_id];
|
||||
ERR_FAIL_NULL(dock);
|
||||
ERR_FAIL_COND_MSG(!all_docks.has(dock), vformat("Menu option for unknown dock '%s'.", dock->get_display_title()));
|
||||
if (dock->enabled && dock->open) {
|
||||
if (dock->enabled && dock->is_open) {
|
||||
PopupMenu *parent_menu = Object::cast_to<PopupMenu>(docks_menu->get_parent());
|
||||
ERR_FAIL_NULL(parent_menu);
|
||||
parent_menu->hide();
|
||||
|
|
@ -375,8 +376,8 @@ void EditorDockManager::_window_close_request(WindowWrapper *p_wrapper) {
|
|||
EditorDock *dock = _close_window(p_wrapper);
|
||||
ERR_FAIL_COND(!all_docks.has(dock));
|
||||
|
||||
if (dock->previous_at_bottom || dock->dock_slot_index != DOCK_SLOT_NONE) {
|
||||
dock->open = false;
|
||||
if (dock->dock_slot_index != DockConstants::DOCK_SLOT_NONE) {
|
||||
dock->is_open = false;
|
||||
open_dock(dock);
|
||||
focus_dock(dock);
|
||||
} else {
|
||||
|
|
@ -411,10 +412,11 @@ void EditorDockManager::_open_dock_in_window(EditorDock *p_dock, bool p_show_win
|
|||
EditorNode::get_singleton()->get_gui_base()->add_child(wrapper);
|
||||
|
||||
_move_dock(p_dock, nullptr);
|
||||
p_dock->update_layout(EditorDock::DOCK_LAYOUT_FLOATING);
|
||||
wrapper->set_wrapped_control(p_dock);
|
||||
|
||||
p_dock->dock_window = wrapper;
|
||||
p_dock->open = true;
|
||||
p_dock->is_open = true;
|
||||
p_dock->show();
|
||||
|
||||
wrapper->connect("window_close_requested", callable_mp(this, &EditorDockManager::_window_close_request).bind(wrapper));
|
||||
|
|
@ -444,31 +446,6 @@ void EditorDockManager::_restore_dock_to_saved_window(EditorDock *p_dock, const
|
|||
p_window_dump.get("window_screen_rect", Rect2i()));
|
||||
}
|
||||
|
||||
void EditorDockManager::_dock_move_to_bottom(EditorDock *p_dock, bool p_visible) {
|
||||
_move_dock(p_dock, nullptr);
|
||||
|
||||
p_dock->at_bottom = true;
|
||||
p_dock->previous_at_bottom = false;
|
||||
p_dock->update_layout(EditorDock::DOCK_LAYOUT_HORIZONTAL);
|
||||
|
||||
// Force docks moved to the bottom to appear first in the list, and give them their associated shortcut to toggle their bottom panel.
|
||||
EditorNode::get_bottom_panel()->add_item(p_dock->get_display_title(), p_dock, p_dock->shortcut, true);
|
||||
EditorNode::get_bottom_panel()->make_item_visible(p_dock, p_visible);
|
||||
}
|
||||
|
||||
void EditorDockManager::_dock_remove_from_bottom(EditorDock *p_dock) {
|
||||
p_dock->at_bottom = false;
|
||||
p_dock->previous_at_bottom = true;
|
||||
|
||||
EditorNode::get_bottom_panel()->remove_item(p_dock);
|
||||
p_dock->update_layout(EditorDock::DOCK_LAYOUT_VERTICAL);
|
||||
}
|
||||
|
||||
bool EditorDockManager::_is_dock_at_bottom(EditorDock *p_dock) {
|
||||
ERR_FAIL_COND_V(!all_docks.has(p_dock), false);
|
||||
return p_dock->at_bottom;
|
||||
}
|
||||
|
||||
void EditorDockManager::_move_dock_tab_index(EditorDock *p_dock, int p_tab_index, bool p_set_current) {
|
||||
TabContainer *dock_tab_container = Object::cast_to<TabContainer>(p_dock->get_parent());
|
||||
if (!dock_tab_container) {
|
||||
|
|
@ -492,7 +469,7 @@ void EditorDockManager::_move_dock(EditorDock *p_dock, Control *p_target, int p_
|
|||
|
||||
Node *parent = p_dock->get_parent();
|
||||
if (parent == p_target) {
|
||||
if (p_tab_index >= 0 && parent) {
|
||||
if (parent && p_tab_index >= 0) {
|
||||
// Only change the tab index.
|
||||
_move_dock_tab_index(p_dock, p_tab_index, p_set_current);
|
||||
}
|
||||
|
|
@ -503,10 +480,7 @@ void EditorDockManager::_move_dock(EditorDock *p_dock, Control *p_target, int p_
|
|||
if (parent) {
|
||||
if (p_dock->dock_window) {
|
||||
_close_window(p_dock->dock_window);
|
||||
} else if (p_dock->at_bottom) {
|
||||
_dock_remove_from_bottom(p_dock);
|
||||
} else {
|
||||
p_dock->previous_at_bottom = false;
|
||||
TabContainer *parent_tabs = Object::cast_to<TabContainer>(parent);
|
||||
if (parent_tabs) {
|
||||
p_dock->previous_tab_index = parent_tabs->get_tab_idx_from_control(p_dock);
|
||||
|
|
@ -520,13 +494,20 @@ void EditorDockManager::_move_dock(EditorDock *p_dock, Control *p_target, int p_
|
|||
}
|
||||
}
|
||||
|
||||
// Add dock to its new parent, at the given tab index.
|
||||
if (!p_target) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (p_target != closed_dock_parent) {
|
||||
p_dock->update_layout(p_target->get_meta("dock_layout"));
|
||||
p_dock->dock_slot_index = p_target->get_meta("dock_slot");
|
||||
}
|
||||
|
||||
// Add dock to its new parent, at the given tab index.
|
||||
p_target->set_block_signals(true);
|
||||
p_target->add_child(p_dock);
|
||||
p_target->set_block_signals(false);
|
||||
|
||||
TabContainer *dock_tab_container = Object::cast_to<TabContainer>(p_target);
|
||||
if (dock_tab_container) {
|
||||
if (dock_tab_container->is_inside_tree()) {
|
||||
|
|
@ -540,11 +521,11 @@ void EditorDockManager::_move_dock(EditorDock *p_dock, Control *p_target, int p_
|
|||
}
|
||||
|
||||
void EditorDockManager::_update_tab_style(EditorDock *p_dock) {
|
||||
if (!p_dock->enabled || !p_dock->open) {
|
||||
if (!p_dock->enabled || !p_dock->is_open) {
|
||||
return; // Disabled by feature profile or manually closed by user.
|
||||
}
|
||||
if (p_dock->dock_window || p_dock->at_bottom) {
|
||||
return; // Floating or sent to bottom.
|
||||
if (p_dock->dock_window) {
|
||||
return; // Floating.
|
||||
}
|
||||
|
||||
TabContainer *tab_container = get_dock_tab_container(p_dock);
|
||||
|
|
@ -553,6 +534,12 @@ void EditorDockManager::_update_tab_style(EditorDock *p_dock) {
|
|||
int index = tab_container->get_tab_idx_from_control(p_dock);
|
||||
ERR_FAIL_COND(index == -1);
|
||||
|
||||
if (p_dock->global) {
|
||||
update_docks_menu();
|
||||
}
|
||||
|
||||
tab_container->get_tab_bar()->set_font_color_override_all(index, p_dock->title_color);
|
||||
|
||||
const TabStyle style = (TabStyle)EDITOR_GET("interface/editor/dock_tab_style").operator int();
|
||||
const Ref<Texture2D> icon = _get_dock_icon(p_dock, callable_mp((Control *)tab_container, &Control::get_editor_theme_icon));
|
||||
switch (style) {
|
||||
|
|
@ -576,35 +563,34 @@ void EditorDockManager::_update_tab_style(EditorDock *p_dock) {
|
|||
|
||||
void EditorDockManager::save_docks_to_config(Ref<ConfigFile> p_layout, const String &p_section) const {
|
||||
// Save docks by dock slot.
|
||||
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
|
||||
String names;
|
||||
for (int j = 0; j < dock_slot[i]->get_tab_count(); j++) {
|
||||
String name = Object::cast_to<EditorDock>(dock_slot[i]->get_tab_control(j))->get_effective_layout_key();
|
||||
if (!names.is_empty()) {
|
||||
names += ",";
|
||||
}
|
||||
names += name;
|
||||
for (int i = 0; i < DockConstants::DOCK_SLOT_MAX; i++) {
|
||||
const DockSlot &dock_slot = dock_slots[i];
|
||||
|
||||
PackedStringArray names;
|
||||
names.reserve_exact(dock_slot.container->get_tab_count());
|
||||
for (int j = 0; j < dock_slot.container->get_tab_count(); j++) {
|
||||
const String name = Object::cast_to<EditorDock>(dock_slot.container->get_tab_control(j))->get_effective_layout_key();
|
||||
names.append(name);
|
||||
}
|
||||
|
||||
String config_key = "dock_" + itos(i + 1);
|
||||
|
||||
const String config_key = "dock_" + itos(i + 1);
|
||||
if (p_layout->has_section_key(p_section, config_key)) {
|
||||
p_layout->erase_section_key(p_section, config_key);
|
||||
}
|
||||
|
||||
if (!names.is_empty()) {
|
||||
p_layout->set_value(p_section, config_key, names);
|
||||
p_layout->set_value(p_section, config_key, String(",").join(names));
|
||||
}
|
||||
|
||||
int selected_tab_idx = dock_slot[i]->get_current_tab();
|
||||
const String tab_key = config_key + "_selected_tab_idx";
|
||||
|
||||
int selected_tab_idx = dock_slots[i].container->get_current_tab();
|
||||
if (selected_tab_idx >= 0) {
|
||||
p_layout->set_value(p_section, "dock_" + itos(i + 1) + "_selected_tab_idx", selected_tab_idx);
|
||||
p_layout->set_value(p_section, tab_key, selected_tab_idx);
|
||||
} else if (p_layout->has_section_key(p_section, tab_key)) {
|
||||
p_layout->erase_section_key(p_section, tab_key);
|
||||
}
|
||||
}
|
||||
if (p_layout->has_section_key(p_section, "dock_0")) {
|
||||
// Clear the keys where the dock has no slot so it is overridden.
|
||||
p_layout->erase_section_key(p_section, "dock_0");
|
||||
}
|
||||
|
||||
// Save docks in windows.
|
||||
Dictionary floating_docks_dump;
|
||||
|
|
@ -635,22 +621,18 @@ void EditorDockManager::save_docks_to_config(Ref<ConfigFile> p_layout, const Str
|
|||
}
|
||||
p_layout->set_value(p_section, "dock_floating", floating_docks_dump);
|
||||
|
||||
// Save closed and bottom docks.
|
||||
Array bottom_docks_dump;
|
||||
// Save closed docks.
|
||||
Array closed_docks_dump;
|
||||
for (const EditorDock *dock : all_docks) {
|
||||
const String section_name = p_section + "/" + dock->get_effective_layout_key();
|
||||
dock->save_layout_to_config(p_layout, section_name);
|
||||
|
||||
if (!dock->at_bottom && dock->open && (!dock->previous_at_bottom || !dock->dock_window)) {
|
||||
if (dock->is_open) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const String name = dock->get_effective_layout_key();
|
||||
if (dock->at_bottom || (dock->previous_at_bottom && dock->dock_window)) {
|
||||
bottom_docks_dump.push_back(name);
|
||||
}
|
||||
if (!dock->open) {
|
||||
if (!dock->is_open && !dock->transient) {
|
||||
closed_docks_dump.push_back(name);
|
||||
}
|
||||
|
||||
|
|
@ -665,7 +647,6 @@ void EditorDockManager::save_docks_to_config(Ref<ConfigFile> p_layout, const Str
|
|||
}
|
||||
p_layout->set_value(p_section, config_key, names);
|
||||
}
|
||||
p_layout->set_value(p_section, "dock_bottom", bottom_docks_dump);
|
||||
p_layout->set_value(p_section, "dock_closed", closed_docks_dump);
|
||||
|
||||
// Save SplitContainer offsets.
|
||||
|
|
@ -682,7 +663,6 @@ void EditorDockManager::save_docks_to_config(Ref<ConfigFile> p_layout, const Str
|
|||
|
||||
void EditorDockManager::load_docks_from_config(Ref<ConfigFile> p_layout, const String &p_section, bool p_first_load) {
|
||||
Dictionary floating_docks_dump = p_layout->get_value(p_section, "dock_floating", Dictionary());
|
||||
Array dock_bottom = p_layout->get_value(p_section, "dock_bottom", Array());
|
||||
Array closed_docks = p_layout->get_value(p_section, "dock_closed", Array());
|
||||
|
||||
bool allow_floating_docks = EditorNode::get_singleton()->is_multi_window_enabled() && (!p_first_load || EDITOR_GET("interface/multi_window/restore_windows_on_load"));
|
||||
|
|
@ -694,7 +674,7 @@ void EditorDockManager::load_docks_from_config(Ref<ConfigFile> p_layout, const S
|
|||
}
|
||||
|
||||
// Load docks by slot. Index -1 is for docks that have no slot.
|
||||
for (int i = -1; i < DOCK_SLOT_MAX; i++) {
|
||||
for (int i = -1; i < DockConstants::DOCK_SLOT_MAX; i++) {
|
||||
if (!p_layout->has_section_key(p_section, "dock_" + itos(i + 1))) {
|
||||
continue;
|
||||
}
|
||||
|
|
@ -711,32 +691,28 @@ void EditorDockManager::load_docks_from_config(Ref<ConfigFile> p_layout, const S
|
|||
EditorDock *dock = dock_map[name];
|
||||
|
||||
if (!dock->enabled) {
|
||||
// Don't open disabled docks.
|
||||
// Don't is_open disabled docks.
|
||||
dock->load_layout_from_config(p_layout, section_name);
|
||||
continue;
|
||||
}
|
||||
bool at_bottom = false;
|
||||
if (allow_floating_docks && floating_docks_dump.has(name)) {
|
||||
dock->previous_at_bottom = dock_bottom.has(name);
|
||||
_restore_dock_to_saved_window(dock, floating_docks_dump[name]);
|
||||
} else if (dock_bottom.has(name)) {
|
||||
_dock_move_to_bottom(dock, false);
|
||||
at_bottom = true;
|
||||
} else if (i >= 0) {
|
||||
_move_dock(dock, dock_slot[i], 0);
|
||||
if (dock->transient && !dock->is_open) {
|
||||
dock->dock_slot_index = i;
|
||||
} else {
|
||||
_move_dock(dock, dock_slots[i].container, 0);
|
||||
}
|
||||
}
|
||||
dock->load_layout_from_config(p_layout, section_name);
|
||||
|
||||
if (closed_docks.has(name)) {
|
||||
_move_dock(dock, closed_dock_parent);
|
||||
dock->open = false;
|
||||
dock->hide();
|
||||
} else {
|
||||
// Make sure it is open.
|
||||
dock->open = true;
|
||||
// It's important to not update the visibility of bottom panels.
|
||||
// Visibility of bottom panels are managed in EditorBottomPanel.
|
||||
if (!at_bottom) {
|
||||
if (!dock->transient) {
|
||||
if (closed_docks.has(name)) {
|
||||
_move_dock(dock, closed_dock_parent);
|
||||
dock->is_open = false;
|
||||
dock->hide();
|
||||
} else {
|
||||
dock->is_open = true;
|
||||
dock->show();
|
||||
}
|
||||
}
|
||||
|
|
@ -747,16 +723,24 @@ void EditorDockManager::load_docks_from_config(Ref<ConfigFile> p_layout, const S
|
|||
}
|
||||
|
||||
// Set the selected tabs.
|
||||
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
|
||||
if (dock_slot[i]->get_tab_count() == 0 || !p_layout->has_section_key(p_section, "dock_" + itos(i + 1) + "_selected_tab_idx")) {
|
||||
for (int i = 0; i < DockConstants::DOCK_SLOT_MAX; i++) {
|
||||
const DockSlot &dock_slot = dock_slots[i];
|
||||
|
||||
int selected_tab_idx = p_layout->get_value(p_section, "dock_" + itos(i + 1) + "_selected_tab_idx", -1);
|
||||
if (selected_tab_idx <= 0 || selected_tab_idx >= dock_slot.container->get_tab_count()) {
|
||||
if (i == DockConstants::DOCK_SLOT_BOTTOM) {
|
||||
dock_slot.container->set_current_tab(-1);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
int selected_tab_idx = p_layout->get_value(p_section, "dock_" + itos(i + 1) + "_selected_tab_idx");
|
||||
if (selected_tab_idx >= 0 && selected_tab_idx < dock_slot[i]->get_tab_count()) {
|
||||
dock_slot[i]->set_block_signals(true);
|
||||
dock_slot[i]->set_current_tab(selected_tab_idx);
|
||||
dock_slot[i]->set_block_signals(false);
|
||||
|
||||
EditorDock *selected_dock = Object::cast_to<EditorDock>(dock_slot.container->get_tab_control(selected_tab_idx));
|
||||
if (!selected_dock) {
|
||||
continue;
|
||||
}
|
||||
dock_slot.container->set_block_signals(true);
|
||||
dock_slot.container->set_current_tab(selected_tab_idx);
|
||||
dock_slot.container->set_block_signals(false);
|
||||
}
|
||||
|
||||
// Load SplitContainer offsets.
|
||||
|
|
@ -778,22 +762,6 @@ void EditorDockManager::load_docks_from_config(Ref<ConfigFile> p_layout, const S
|
|||
update_docks_menu();
|
||||
}
|
||||
|
||||
void EditorDockManager::bottom_dock_show_placement_popup(const Rect2i &p_position, EditorDock *p_dock) {
|
||||
ERR_FAIL_COND(!all_docks.has(p_dock));
|
||||
|
||||
dock_context_popup->set_dock(p_dock);
|
||||
|
||||
Vector2 popup_pos = p_position.position;
|
||||
popup_pos.y += p_position.size.height;
|
||||
|
||||
if (!EditorNode::get_singleton()->get_gui_base()->is_layout_rtl()) {
|
||||
popup_pos.x -= dock_context_popup->get_size().width;
|
||||
popup_pos.x += p_position.size.width;
|
||||
}
|
||||
dock_context_popup->set_position(popup_pos);
|
||||
dock_context_popup->popup();
|
||||
}
|
||||
|
||||
void EditorDockManager::set_dock_enabled(EditorDock *p_dock, bool p_enabled) {
|
||||
ERR_FAIL_NULL(p_dock);
|
||||
ERR_FAIL_COND_MSG(!all_docks.has(p_dock), vformat("Cannot set enabled unknown dock '%s'.", p_dock->get_display_title()));
|
||||
|
|
@ -814,13 +782,17 @@ void EditorDockManager::close_dock(EditorDock *p_dock) {
|
|||
ERR_FAIL_NULL(p_dock);
|
||||
ERR_FAIL_COND_MSG(!all_docks.has(p_dock), vformat("Cannot close unknown dock '%s'.", p_dock->get_display_title()));
|
||||
|
||||
if (!p_dock->open) {
|
||||
if (!p_dock->is_open) {
|
||||
return;
|
||||
}
|
||||
|
||||
EditorBottomPanel *bottom_panel = EditorNode::get_bottom_panel();
|
||||
if (get_dock_tab_container(p_dock) == bottom_panel && bottom_panel->get_current_tab_control() == p_dock) {
|
||||
bottom_panel->hide_bottom_panel();
|
||||
}
|
||||
_move_dock(p_dock, closed_dock_parent);
|
||||
|
||||
p_dock->open = false;
|
||||
p_dock->is_open = false;
|
||||
p_dock->hide();
|
||||
|
||||
_update_layout();
|
||||
|
|
@ -830,18 +802,16 @@ void EditorDockManager::open_dock(EditorDock *p_dock, bool p_set_current) {
|
|||
ERR_FAIL_NULL(p_dock);
|
||||
ERR_FAIL_COND_MSG(!all_docks.has(p_dock), vformat("Cannot open unknown dock '%s'.", p_dock->get_display_title()));
|
||||
|
||||
if (p_dock->open) {
|
||||
if (p_dock->is_open) {
|
||||
return;
|
||||
}
|
||||
|
||||
p_dock->open = true;
|
||||
p_dock->is_open = true;
|
||||
p_dock->show();
|
||||
|
||||
// Open dock to its previous location.
|
||||
if (p_dock->previous_at_bottom) {
|
||||
_dock_move_to_bottom(p_dock, true);
|
||||
} else if (p_dock->dock_slot_index != DOCK_SLOT_NONE) {
|
||||
TabContainer *slot = dock_slot[p_dock->dock_slot_index];
|
||||
if (p_dock->dock_slot_index != DockConstants::DOCK_SLOT_NONE) {
|
||||
TabContainer *slot = dock_slots[p_dock->dock_slot_index].container;
|
||||
int tab_index = p_dock->previous_tab_index;
|
||||
if (tab_index < 0) {
|
||||
tab_index = slot->get_tab_count();
|
||||
|
|
@ -867,7 +837,7 @@ void EditorDockManager::focus_dock(EditorDock *p_dock) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (!p_dock->open) {
|
||||
if (!p_dock->is_open) {
|
||||
open_dock(p_dock);
|
||||
}
|
||||
|
||||
|
|
@ -876,11 +846,6 @@ void EditorDockManager::focus_dock(EditorDock *p_dock) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (p_dock->at_bottom) {
|
||||
EditorNode::get_bottom_panel()->make_item_visible(p_dock, true, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!docks_visible) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -903,7 +868,7 @@ void EditorDockManager::add_dock(EditorDock *p_dock) {
|
|||
p_dock->connect("tab_style_changed", callable_mp(this, &EditorDockManager::_update_tab_style).bind(p_dock));
|
||||
p_dock->connect("renamed", callable_mp(this, &EditorDockManager::_update_tab_style).bind(p_dock));
|
||||
|
||||
if (p_dock->default_slot != DOCK_SLOT_NONE) {
|
||||
if (p_dock->default_slot != DockConstants::DOCK_SLOT_NONE) {
|
||||
open_dock(p_dock, false);
|
||||
} else {
|
||||
closed_dock_parent->add_child(p_dock);
|
||||
|
|
@ -929,8 +894,8 @@ void EditorDockManager::set_docks_visible(bool p_show) {
|
|||
return;
|
||||
}
|
||||
docks_visible = p_show;
|
||||
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
|
||||
dock_slot[i]->set_visible(docks_visible && dock_slot[i]->get_tab_count() > 0);
|
||||
for (int i = 0; i < DockConstants::DOCK_SLOT_MAX; i++) {
|
||||
dock_slots[i].container->set_visible(docks_visible && dock_slots[i].container->get_tab_count() > 0);
|
||||
}
|
||||
_update_layout();
|
||||
}
|
||||
|
|
@ -946,8 +911,8 @@ void EditorDockManager::update_tab_styles() {
|
|||
}
|
||||
|
||||
void EditorDockManager::set_tab_icon_max_width(int p_max_width) {
|
||||
for (int i = 0; i < DOCK_SLOT_MAX; i++) {
|
||||
TabContainer *tab_container = dock_slot[i];
|
||||
for (int i = 0; i < DockConstants::DOCK_SLOT_MAX; i++) {
|
||||
TabContainer *tab_container = dock_slots[i].container;
|
||||
tab_container->add_theme_constant_override(SNAME("icon_max_width"), p_max_width);
|
||||
}
|
||||
}
|
||||
|
|
@ -962,14 +927,14 @@ void EditorDockManager::add_hsplit(DockSplitContainer *p_split) {
|
|||
p_split->connect("dragged", callable_mp(this, &EditorDockManager::_dock_split_dragged));
|
||||
}
|
||||
|
||||
void EditorDockManager::register_dock_slot(DockSlot p_dock_slot, TabContainer *p_tab_container) {
|
||||
void EditorDockManager::register_dock_slot(DockConstants::DockSlot p_dock_slot, TabContainer *p_tab_container, DockConstants::DockLayout p_layout) {
|
||||
ERR_FAIL_NULL(p_tab_container);
|
||||
ERR_FAIL_INDEX(p_dock_slot, DOCK_SLOT_MAX);
|
||||
ERR_FAIL_INDEX(p_dock_slot, DockConstants::DOCK_SLOT_MAX);
|
||||
|
||||
dock_slot[p_dock_slot] = p_tab_container;
|
||||
DockSlot slot;
|
||||
slot.layout = p_layout;
|
||||
|
||||
p_tab_container->set_custom_minimum_size(Size2(170, 0) * EDSCALE);
|
||||
p_tab_container->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
slot.container = p_tab_container;
|
||||
p_tab_container->set_popup(dock_context_popup);
|
||||
p_tab_container->connect("pre_popup_pressed", callable_mp(dock_context_popup, &DockContextPopup::select_current_dock_in_dock_slot).bind(p_dock_slot));
|
||||
p_tab_container->get_tab_bar()->connect("tab_rmb_clicked", callable_mp(this, &EditorDockManager::_dock_container_popup).bind(p_tab_container));
|
||||
|
|
@ -978,14 +943,23 @@ void EditorDockManager::register_dock_slot(DockSlot p_dock_slot, TabContainer *p
|
|||
p_tab_container->connect("tab_changed", callable_mp(this, &EditorDockManager::_update_layout).unbind(1));
|
||||
p_tab_container->connect("active_tab_rearranged", callable_mp(this, &EditorDockManager::_update_layout).unbind(1));
|
||||
p_tab_container->connect("child_order_changed", callable_mp(this, &EditorDockManager::_dock_container_update_visibility).bind(p_tab_container));
|
||||
p_tab_container->set_use_hidden_tabs_for_min_size(true);
|
||||
p_tab_container->hide();
|
||||
p_tab_container->set_meta("dock_slot", p_dock_slot);
|
||||
p_tab_container->set_meta("dock_layout", p_layout);
|
||||
|
||||
if (p_layout == DockConstants::DOCK_LAYOUT_VERTICAL) {
|
||||
p_tab_container->set_custom_minimum_size(Size2(170, 0) * EDSCALE);
|
||||
p_tab_container->set_v_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
p_tab_container->set_use_hidden_tabs_for_min_size(true);
|
||||
}
|
||||
|
||||
// Create dock dragging hint.
|
||||
dock_drag_rects[p_dock_slot] = memnew(EditorDockDragHint);
|
||||
dock_drag_rects[p_dock_slot]->set_slot(p_dock_slot);
|
||||
dock_drag_rects[p_dock_slot]->hide();
|
||||
EditorNode::get_singleton()->get_gui_base()->add_child(dock_drag_rects[p_dock_slot]);
|
||||
slot.drag_hint = memnew(EditorDockDragHint);
|
||||
slot.drag_hint->hide();
|
||||
EditorNode::get_singleton()->get_gui_base()->add_child(slot.drag_hint);
|
||||
|
||||
dock_slots[p_dock_slot] = slot;
|
||||
slot.drag_hint->set_slot(p_dock_slot);
|
||||
}
|
||||
|
||||
int EditorDockManager::get_hsplit_count() const {
|
||||
|
|
@ -1007,6 +981,7 @@ EditorDockManager::EditorDockManager() {
|
|||
|
||||
dock_context_popup = memnew(DockContextPopup);
|
||||
EditorNode::get_singleton()->get_gui_base()->add_child(dock_context_popup);
|
||||
EditorNode::get_singleton()->add_child(memnew(DockShortcutHandler));
|
||||
|
||||
docks_menu = memnew(PopupMenu);
|
||||
docks_menu->set_hide_on_item_selection(false);
|
||||
|
|
@ -1036,7 +1011,6 @@ void DockContextPopup::_notification(int p_what) {
|
|||
tab_move_left_button->set_tooltip_text(TTR("Move this dock left one tab."));
|
||||
tab_move_right_button->set_tooltip_text(TTR("Move this dock right one tab."));
|
||||
}
|
||||
dock_to_bottom_button->set_button_icon(get_editor_theme_icon(SNAME("ControlAlignBottomWide")));
|
||||
close_button->set_button_icon(get_editor_theme_icon(SNAME("Close")));
|
||||
} break;
|
||||
}
|
||||
|
|
@ -1074,10 +1048,8 @@ void DockContextPopup::_float_dock() {
|
|||
dock_manager->_open_dock_in_window(context_dock);
|
||||
}
|
||||
|
||||
void DockContextPopup::_move_dock_to_bottom() {
|
||||
hide();
|
||||
dock_manager->_dock_move_to_bottom(context_dock, true);
|
||||
dock_manager->_update_layout();
|
||||
bool DockContextPopup::_is_slot_available(int p_slot) const {
|
||||
return context_dock->available_layouts & (EditorDock::DockLayout)EditorDockManager::get_singleton()->dock_slots[p_slot].layout;
|
||||
}
|
||||
|
||||
void DockContextPopup::_dock_select_input(const Ref<InputEvent> &p_input) {
|
||||
|
|
@ -1087,7 +1059,7 @@ void DockContextPopup::_dock_select_input(const Ref<InputEvent> &p_input) {
|
|||
Vector2 point = me->get_position();
|
||||
|
||||
int over_dock_slot = -1;
|
||||
for (int i = 0; i < EditorDockManager::DOCK_SLOT_MAX; i++) {
|
||||
for (int i = 0; i < DockConstants::DOCK_SLOT_MAX; i++) {
|
||||
if (dock_select_rects[i].has_point(point)) {
|
||||
over_dock_slot = i;
|
||||
break;
|
||||
|
|
@ -1104,12 +1076,11 @@ void DockContextPopup::_dock_select_input(const Ref<InputEvent> &p_input) {
|
|||
}
|
||||
|
||||
Ref<InputEventMouseButton> mb = me;
|
||||
TabContainer *target_tab_container = dock_manager->dock_slot[over_dock_slot];
|
||||
TabContainer *target_tab_container = dock_manager->dock_slots[over_dock_slot].container;
|
||||
|
||||
if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
|
||||
if (dock_manager->get_dock_tab_container(context_dock) != target_tab_container) {
|
||||
if (dock_manager->get_dock_tab_container(context_dock) != target_tab_container && _is_slot_available(over_dock_slot)) {
|
||||
dock_manager->_move_dock(context_dock, target_tab_container, target_tab_container->get_tab_count());
|
||||
context_dock->dock_slot_index = over_dock_slot;
|
||||
dock_manager->_update_layout();
|
||||
hide();
|
||||
}
|
||||
|
|
@ -1137,30 +1108,30 @@ void DockContextPopup::_dock_select_draw() {
|
|||
dock_size.x /= 6.0;
|
||||
dock_size.y /= 2.0;
|
||||
|
||||
Size2 center_panel_size = dock_size * 2.0;
|
||||
Rect2 center_panel_rect(center_panel_size.x, 0, center_panel_size.x, center_panel_size.y);
|
||||
real_t center_panel_width = dock_size.x * 2.0;
|
||||
Rect2 center_panel_rect(center_panel_width, 0, center_panel_width, dock_size.y);
|
||||
|
||||
if (dock_select->is_layout_rtl()) {
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_RIGHT_UR] = Rect2(Point2(), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_RIGHT_BR] = Rect2(Point2(0, dock_size.y), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_RIGHT_UL] = Rect2(Point2(dock_size.x, 0), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_RIGHT_BL] = Rect2(dock_size, dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_LEFT_UR] = Rect2(Point2(dock_size.x * 4, 0), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_LEFT_BR] = Rect2(Point2(dock_size.x * 4, dock_size.y), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_LEFT_UL] = Rect2(Point2(dock_size.x * 5, 0), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_LEFT_BL] = Rect2(Point2(dock_size.x * 5, dock_size.y), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_RIGHT_UR] = Rect2(Point2(), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_RIGHT_BR] = Rect2(Point2(0, dock_size.y), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_RIGHT_UL] = Rect2(Point2(dock_size.x, 0), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_RIGHT_BL] = Rect2(dock_size, dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_LEFT_UR] = Rect2(Point2(dock_size.x * 4, 0), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_LEFT_BR] = Rect2(Point2(dock_size.x * 4, dock_size.y), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_LEFT_UL] = Rect2(Point2(dock_size.x * 5, 0), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_LEFT_BL] = Rect2(Point2(dock_size.x * 5, dock_size.y), dock_size);
|
||||
} else {
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_LEFT_UL] = Rect2(Point2(), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_LEFT_BL] = Rect2(Point2(0, dock_size.y), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_LEFT_UR] = Rect2(Point2(dock_size.x, 0), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_LEFT_BR] = Rect2(dock_size, dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_RIGHT_UL] = Rect2(Point2(dock_size.x * 4, 0), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_RIGHT_BL] = Rect2(Point2(dock_size.x * 4, dock_size.y), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_RIGHT_UR] = Rect2(Point2(dock_size.x * 5, 0), dock_size);
|
||||
dock_select_rects[EditorDockManager::DOCK_SLOT_RIGHT_BR] = Rect2(Point2(dock_size.x * 5, dock_size.y), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_LEFT_UL] = Rect2(Point2(), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_LEFT_BL] = Rect2(Point2(0, dock_size.y), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_LEFT_UR] = Rect2(Point2(dock_size.x, 0), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_LEFT_BR] = Rect2(dock_size, dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_RIGHT_UL] = Rect2(Point2(dock_size.x * 4, 0), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_RIGHT_BL] = Rect2(Point2(dock_size.x * 4, dock_size.y), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_RIGHT_UR] = Rect2(Point2(dock_size.x * 5, 0), dock_size);
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_RIGHT_BR] = Rect2(Point2(dock_size.x * 5, dock_size.y), dock_size);
|
||||
}
|
||||
dock_select_rects[DockConstants::DOCK_SLOT_BOTTOM] = Rect2(center_panel_width, dock_size.y, center_panel_width, dock_size.y);
|
||||
|
||||
int max_tabs = 3;
|
||||
int rtl_dir = dock_select->is_layout_rtl() ? -1 : 1;
|
||||
real_t tab_height = 3.0 * EDSCALE;
|
||||
real_t tab_spacing = 1.0 * EDSCALE;
|
||||
|
|
@ -1178,17 +1149,30 @@ void DockContextPopup::_dock_select_draw() {
|
|||
dock_select->draw_rect(center_panel_draw_rect, unusable_dock_color);
|
||||
|
||||
// Draw all dock slots.
|
||||
for (int i = 0; i < EditorDockManager::DOCK_SLOT_MAX; i++) {
|
||||
for (int i = 0; i < DockConstants::DOCK_SLOT_MAX; i++) {
|
||||
int max_tabs = (i == DockConstants::DOCK_SLOT_BOTTOM) ? 6 : 3;
|
||||
const EditorDockManager::DockSlot &dock_slot = dock_manager->dock_slots[i];
|
||||
|
||||
Rect2 dock_slot_draw_rect = dock_select_rects[i].grow_individual(-dock_spacing, -dock_top_spacing, -dock_spacing, -dock_spacing);
|
||||
real_t tab_width = Math::round(dock_slot_draw_rect.size.width / max_tabs);
|
||||
Rect2 tab_draw_rect = Rect2(dock_slot_draw_rect.position.x, dock_select_rects[i].position.y, tab_width - tab_spacing, tab_height);
|
||||
|
||||
real_t max_width = tab_width * max_tabs;
|
||||
// Tabs may not fit perfectly, so they need to be re-centered.
|
||||
if (max_width > dock_slot_draw_rect.size.x) {
|
||||
tab_draw_rect.position.x -= int(max_width - dock_slot_draw_rect.size.x) / 2 * rtl_dir;
|
||||
}
|
||||
if (dock_select->is_layout_rtl()) {
|
||||
tab_draw_rect.position.x += dock_slot_draw_rect.size.x - tab_draw_rect.size.x;
|
||||
}
|
||||
bool is_context_dock = context_tab_container == dock_manager->dock_slot[i];
|
||||
int tabs_to_draw = MIN(max_tabs, dock_manager->dock_slot[i]->get_tab_count());
|
||||
|
||||
if (i == dock_select_rect_over_idx) {
|
||||
int tabs_to_draw = MIN(max_tabs, dock_slot.container->get_tab_count());
|
||||
bool is_context_dock = context_tab_container == dock_slot.container;
|
||||
if (i == context_dock->dock_slot_index) {
|
||||
dock_select->draw_rect(dock_slot_draw_rect, tab_selected_color);
|
||||
} else if (!_is_slot_available(i)) {
|
||||
dock_select->draw_rect(dock_slot_draw_rect, unusable_dock_color);
|
||||
} else if (i == dock_select_rect_over_idx) {
|
||||
dock_select->draw_rect(dock_slot_draw_rect, hovered_dock_color);
|
||||
} else if (tabs_to_draw == 0) {
|
||||
dock_select->draw_rect(dock_slot_draw_rect, unused_dock_color);
|
||||
|
|
@ -1211,23 +1195,36 @@ void DockContextPopup::_dock_select_draw() {
|
|||
|
||||
void DockContextPopup::_update_buttons() {
|
||||
TabContainer *context_tab_container = dock_manager->get_dock_tab_container(context_dock);
|
||||
bool dock_at_bottom = dock_manager->_is_dock_at_bottom(context_dock);
|
||||
if (context_dock->global) {
|
||||
close_button->set_tooltip_text(TTRC("Close this dock."));
|
||||
close_button->set_disabled(false);
|
||||
} else {
|
||||
close_button->set_tooltip_text(TTRC("This dock can't be closed."));
|
||||
close_button->set_disabled(true);
|
||||
}
|
||||
if (EditorNode::get_singleton()->is_multi_window_enabled()) {
|
||||
if (!(context_dock->available_layouts & EditorDock::DOCK_LAYOUT_FLOATING)) {
|
||||
make_float_button->set_tooltip_text(TTRC("This dock does not support floating."));
|
||||
make_float_button->set_disabled(true);
|
||||
} else {
|
||||
make_float_button->set_tooltip_text(TTRC("Make this dock floating."));
|
||||
make_float_button->set_disabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
// Update tab move buttons.
|
||||
tab_move_left_button->set_disabled(true);
|
||||
tab_move_right_button->set_disabled(true);
|
||||
if (!dock_at_bottom && context_tab_container && context_tab_container->get_tab_count() > 0) {
|
||||
if (context_tab_container && context_tab_container->get_tab_count() > 0) {
|
||||
int context_tab_index = context_tab_container->get_tab_idx_from_control(context_dock);
|
||||
tab_move_left_button->set_disabled(context_tab_index == 0);
|
||||
tab_move_right_button->set_disabled(context_tab_index >= context_tab_container->get_tab_count() - 1);
|
||||
}
|
||||
|
||||
dock_to_bottom_button->set_visible(!dock_at_bottom && bool(context_dock->available_layouts & EditorDock::DOCK_LAYOUT_HORIZONTAL));
|
||||
reset_size();
|
||||
}
|
||||
|
||||
void DockContextPopup::select_current_dock_in_dock_slot(int p_dock_slot) {
|
||||
context_dock = Object::cast_to<EditorDock>(dock_manager->dock_slot[p_dock_slot]->get_current_tab_control());
|
||||
context_dock = Object::cast_to<EditorDock>(dock_manager->dock_slots[p_dock_slot].container->get_current_tab_control());
|
||||
_update_buttons();
|
||||
}
|
||||
|
||||
|
|
@ -1262,7 +1259,7 @@ DockContextPopup::DockContextPopup() {
|
|||
header_hb->add_child(tab_move_left_button);
|
||||
|
||||
Label *position_label = memnew(Label);
|
||||
position_label->set_text(TTR("Dock Position"));
|
||||
position_label->set_text(TTRC("Dock Position"));
|
||||
position_label->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
position_label->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_CENTER);
|
||||
header_hb->add_child(position_label);
|
||||
|
|
@ -1285,32 +1282,39 @@ DockContextPopup::DockContextPopup() {
|
|||
dock_select_popup_vb->add_child(dock_select);
|
||||
|
||||
make_float_button = memnew(Button);
|
||||
make_float_button->set_text(TTR("Make Floating"));
|
||||
make_float_button->set_text(TTRC("Make Floating"));
|
||||
if (!EditorNode::get_singleton()->is_multi_window_enabled()) {
|
||||
make_float_button->set_disabled(true);
|
||||
make_float_button->set_tooltip_text(EditorNode::get_singleton()->get_multiwindow_support_tooltip_text());
|
||||
} else {
|
||||
make_float_button->set_tooltip_text(TTR("Make this dock floating."));
|
||||
}
|
||||
make_float_button->set_focus_mode(Control::FOCUS_ACCESSIBILITY);
|
||||
make_float_button->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
make_float_button->connect(SceneStringName(pressed), callable_mp(this, &DockContextPopup::_float_dock));
|
||||
dock_select_popup_vb->add_child(make_float_button);
|
||||
|
||||
dock_to_bottom_button = memnew(Button);
|
||||
dock_to_bottom_button->set_text(TTR("Move to Bottom"));
|
||||
dock_to_bottom_button->set_tooltip_text(TTR("Move this dock to the bottom panel."));
|
||||
dock_to_bottom_button->set_focus_mode(Control::FOCUS_ACCESSIBILITY);
|
||||
dock_to_bottom_button->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
dock_to_bottom_button->connect(SceneStringName(pressed), callable_mp(this, &DockContextPopup::_move_dock_to_bottom));
|
||||
dock_to_bottom_button->hide();
|
||||
dock_select_popup_vb->add_child(dock_to_bottom_button);
|
||||
|
||||
close_button = memnew(Button);
|
||||
close_button->set_text(TTR("Close"));
|
||||
close_button->set_tooltip_text(TTR("Close this dock."));
|
||||
close_button->set_text(TTRC("Close"));
|
||||
close_button->set_focus_mode(Control::FOCUS_ACCESSIBILITY);
|
||||
close_button->set_h_size_flags(Control::SIZE_EXPAND_FILL);
|
||||
close_button->connect(SceneStringName(pressed), callable_mp(this, &DockContextPopup::_close_dock));
|
||||
dock_select_popup_vb->add_child(close_button);
|
||||
}
|
||||
|
||||
void DockShortcutHandler::shortcut_input(const Ref<InputEvent> &p_event) {
|
||||
if (p_event.is_null() || !p_event->is_pressed() || p_event->is_echo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (EditorDock *dock : EditorDockManager::get_singleton()->all_docks) {
|
||||
const Ref<Shortcut> &dock_shortcut = dock->get_dock_shortcut();
|
||||
if (dock_shortcut.is_valid() && dock_shortcut->matches_event(p_event)) {
|
||||
if (dock->is_visible() && dock->get_parent() == EditorNode::get_bottom_panel()) {
|
||||
EditorNode::get_bottom_panel()->hide_bottom_panel();
|
||||
} else if (!dock->transient || dock->is_open) {
|
||||
EditorDockManager::get_singleton()->focus_dock(dock);
|
||||
}
|
||||
get_viewport()->set_input_as_handled();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "editor/docks/dock_constants.h"
|
||||
#include "scene/gui/popup.h"
|
||||
#include "scene/gui/split_container.h"
|
||||
|
||||
|
|
@ -60,30 +61,26 @@ public:
|
|||
DockSplitContainer();
|
||||
};
|
||||
|
||||
class DockShortcutHandler : public Node {
|
||||
GDCLASS(DockShortcutHandler, Node);
|
||||
|
||||
protected:
|
||||
virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
|
||||
|
||||
public:
|
||||
DockShortcutHandler() { set_process_shortcut_input(true); }
|
||||
};
|
||||
|
||||
class DockContextPopup;
|
||||
class EditorDockDragHint;
|
||||
|
||||
class EditorDockManager : public Object {
|
||||
GDCLASS(EditorDockManager, Object);
|
||||
|
||||
public:
|
||||
enum DockSlot {
|
||||
DOCK_SLOT_NONE = -1,
|
||||
DOCK_SLOT_LEFT_UL,
|
||||
DOCK_SLOT_LEFT_BL,
|
||||
DOCK_SLOT_LEFT_UR,
|
||||
DOCK_SLOT_LEFT_BR,
|
||||
DOCK_SLOT_RIGHT_UL,
|
||||
DOCK_SLOT_RIGHT_BL,
|
||||
DOCK_SLOT_RIGHT_UR,
|
||||
DOCK_SLOT_RIGHT_BR,
|
||||
DOCK_SLOT_MAX
|
||||
};
|
||||
|
||||
private:
|
||||
friend class DockContextPopup;
|
||||
friend class EditorDockDragHint;
|
||||
friend class EditorBottomPanel; // TODO: Temporary until DOCK_SLOT_BOTTOM registered. Used to connect signals.
|
||||
friend class DockShortcutHandler;
|
||||
|
||||
static inline EditorDockManager *singleton = nullptr;
|
||||
|
||||
|
|
@ -91,10 +88,16 @@ private:
|
|||
Vector<DockSplitContainer *> vsplits;
|
||||
Vector<DockSplitContainer *> hsplits;
|
||||
|
||||
struct DockSlot {
|
||||
TabContainer *container = nullptr;
|
||||
EditorDockDragHint *drag_hint = nullptr;
|
||||
DockConstants::DockLayout layout = DockConstants::DOCK_LAYOUT_VERTICAL;
|
||||
};
|
||||
|
||||
DockSlot dock_slots[DockConstants::DOCK_SLOT_MAX];
|
||||
Vector<WindowWrapper *> dock_windows;
|
||||
TabContainer *dock_slot[DOCK_SLOT_MAX];
|
||||
EditorDockDragHint *dock_drag_rects[DOCK_SLOT_MAX];
|
||||
LocalVector<EditorDock *> all_docks;
|
||||
|
||||
EditorDock *dock_tab_dragged = nullptr;
|
||||
bool docks_visible = true;
|
||||
|
||||
|
|
@ -117,10 +120,6 @@ private:
|
|||
void _open_dock_in_window(EditorDock *p_dock, bool p_show_window = true, bool p_reset_size = false);
|
||||
void _restore_dock_to_saved_window(EditorDock *p_dock, const Dictionary &p_window_dump);
|
||||
|
||||
void _dock_move_to_bottom(EditorDock *p_dock, bool p_visible);
|
||||
void _dock_remove_from_bottom(EditorDock *p_dock);
|
||||
bool _is_dock_at_bottom(EditorDock *p_dock);
|
||||
|
||||
void _move_dock_tab_index(EditorDock *p_dock, int p_tab_index, bool p_set_current);
|
||||
void _move_dock(EditorDock *p_dock, Control *p_target, int p_tab_index = -1, bool p_set_current = true);
|
||||
|
||||
|
|
@ -135,7 +134,7 @@ public:
|
|||
|
||||
void add_vsplit(DockSplitContainer *p_split);
|
||||
void add_hsplit(DockSplitContainer *p_split);
|
||||
void register_dock_slot(DockSlot p_dock_slot, TabContainer *p_tab_container);
|
||||
void register_dock_slot(DockConstants::DockSlot p_dock_slot, TabContainer *p_tab_container, DockConstants::DockLayout p_layout);
|
||||
int get_hsplit_count() const;
|
||||
int get_vsplit_count() const;
|
||||
PopupMenu *get_docks_menu();
|
||||
|
|
@ -150,8 +149,6 @@ public:
|
|||
|
||||
TabContainer *get_dock_tab_container(Control *p_dock) const;
|
||||
|
||||
void bottom_dock_show_placement_popup(const Rect2i &p_position, EditorDock *p_dock);
|
||||
|
||||
void set_docks_visible(bool p_show);
|
||||
bool are_docks_visible() const;
|
||||
|
||||
|
|
@ -166,7 +163,7 @@ class EditorDockDragHint : public Control {
|
|||
|
||||
private:
|
||||
EditorDockManager *dock_manager = nullptr;
|
||||
EditorDockManager::DockSlot occupied_slot = EditorDockManager::DOCK_SLOT_MAX;
|
||||
DockConstants::DockSlot occupied_slot = DockConstants::DOCK_SLOT_MAX;
|
||||
TabBar *drop_tabbar = nullptr;
|
||||
|
||||
Color valid_drop_color;
|
||||
|
|
@ -186,7 +183,7 @@ protected:
|
|||
void drop_data(const Point2 &p_point, const Variant &p_data) override;
|
||||
|
||||
public:
|
||||
void set_slot(EditorDockManager::DockSlot p_slot);
|
||||
void set_slot(DockConstants::DockSlot p_slot);
|
||||
|
||||
EditorDockDragHint();
|
||||
};
|
||||
|
|
@ -201,10 +198,9 @@ private:
|
|||
Button *tab_move_left_button = nullptr;
|
||||
Button *tab_move_right_button = nullptr;
|
||||
Button *close_button = nullptr;
|
||||
Button *dock_to_bottom_button = nullptr;
|
||||
|
||||
Control *dock_select = nullptr;
|
||||
Rect2 dock_select_rects[EditorDockManager::DOCK_SLOT_MAX];
|
||||
Rect2 dock_select_rects[DockConstants::DOCK_SLOT_MAX];
|
||||
int dock_select_rect_over_idx = -1;
|
||||
|
||||
EditorDock *context_dock = nullptr;
|
||||
|
|
@ -215,7 +211,7 @@ private:
|
|||
void _tab_move_right();
|
||||
void _close_dock();
|
||||
void _float_dock();
|
||||
void _move_dock_to_bottom();
|
||||
bool _is_slot_available(int p_slot) const;
|
||||
|
||||
void _dock_select_input(const Ref<InputEvent> &p_input);
|
||||
void _dock_select_mouse_exited();
|
||||
|
|
|
|||
|
|
@ -614,8 +614,6 @@ void FileSystemDock::_notification(int p_what) {
|
|||
file_list_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
|
||||
file_list_button_sort->set_button_icon(get_editor_theme_icon(SNAME("Sort")));
|
||||
|
||||
button_dock_placement->set_button_icon(get_editor_theme_icon(SNAME("GuiTabMenuHl")));
|
||||
|
||||
if (is_layout_rtl()) {
|
||||
button_hist_next->set_button_icon(get_editor_theme_icon(SNAME("Back")));
|
||||
button_hist_prev->set_button_icon(get_editor_theme_icon(SNAME("Forward")));
|
||||
|
|
@ -2796,10 +2794,6 @@ void FileSystemDock::_rescan() {
|
|||
EditorFileSystem::get_singleton()->scan();
|
||||
}
|
||||
|
||||
void FileSystemDock::_change_bottom_dock_placement() {
|
||||
EditorDockManager::get_singleton()->bottom_dock_show_placement_popup(button_dock_placement->get_screen_rect(), this);
|
||||
}
|
||||
|
||||
void FileSystemDock::_change_split_mode() {
|
||||
DisplayMode next_mode = DISPLAY_MODE_TREE_ONLY;
|
||||
if (display_mode == DISPLAY_MODE_VSPLIT) {
|
||||
|
|
@ -4086,10 +4080,11 @@ MenuButton *FileSystemDock::_create_file_menu_button() {
|
|||
}
|
||||
|
||||
void FileSystemDock::update_layout(EditorDock::DockLayout p_layout) {
|
||||
horizontal = p_layout == EditorDock::DOCK_LAYOUT_HORIZONTAL;
|
||||
if (button_dock_placement->is_visible() == horizontal) {
|
||||
bool new_horizontal = (p_layout == EditorDock::DOCK_LAYOUT_HORIZONTAL);
|
||||
if (horizontal == new_horizontal) {
|
||||
return;
|
||||
}
|
||||
horizontal = new_horizontal;
|
||||
|
||||
if (horizontal) {
|
||||
path_hb->reparent(toolbar_hbc, false);
|
||||
|
|
@ -4119,7 +4114,6 @@ void FileSystemDock::update_layout(EditorDock::DockLayout p_layout) {
|
|||
set_file_list_display_mode(new_file_display_mode);
|
||||
set_custom_minimum_size(Size2(0, 0));
|
||||
}
|
||||
button_dock_placement->set_visible(horizontal);
|
||||
}
|
||||
|
||||
void FileSystemDock::save_layout_to_config(Ref<ConfigFile> &p_layout, const String &p_section) const {
|
||||
|
|
@ -4211,8 +4205,8 @@ FileSystemDock::FileSystemDock() {
|
|||
set_name(TTRC("FileSystem"));
|
||||
set_icon_name("Folder");
|
||||
set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("docks/open_filesystem", TTRC("Open FileSystem Dock"), KeyModifierMask::ALT | Key::F));
|
||||
set_default_slot(EditorDockManager::DOCK_SLOT_LEFT_BR);
|
||||
set_available_layouts(DOCK_LAYOUT_VERTICAL | DOCK_LAYOUT_HORIZONTAL);
|
||||
set_default_slot(DockConstants::DOCK_SLOT_LEFT_BR);
|
||||
set_available_layouts(DOCK_LAYOUT_ALL);
|
||||
|
||||
ProjectSettings::get_singleton()->add_hidden_prefix("file_customization/");
|
||||
|
||||
|
|
@ -4292,13 +4286,6 @@ FileSystemDock::FileSystemDock() {
|
|||
button_toggle_display_mode->set_theme_type_variation("FlatMenuButton");
|
||||
toolbar_hbc->add_child(button_toggle_display_mode);
|
||||
|
||||
button_dock_placement = memnew(Button);
|
||||
button_dock_placement->set_theme_type_variation("FlatMenuButton");
|
||||
button_dock_placement->set_accessibility_name(TTRC("Dock Placement"));
|
||||
button_dock_placement->connect(SceneStringName(pressed), callable_mp(this, &FileSystemDock::_change_bottom_dock_placement));
|
||||
button_dock_placement->hide();
|
||||
toolbar_hbc->add_child(button_dock_placement);
|
||||
|
||||
toolbar2_hbc = memnew(HBoxContainer);
|
||||
top_vbc->add_child(toolbar2_hbc);
|
||||
|
||||
|
|
|
|||
|
|
@ -160,8 +160,6 @@ private:
|
|||
|
||||
HashSet<String> favorites;
|
||||
|
||||
Button *button_dock_placement = nullptr;
|
||||
|
||||
Button *button_toggle_display_mode = nullptr;
|
||||
Button *button_file_list_display_mode = nullptr;
|
||||
Button *button_hist_next = nullptr;
|
||||
|
|
@ -379,8 +377,6 @@ private:
|
|||
void _project_settings_changed();
|
||||
static Vector<String> _remove_self_included_paths(Vector<String> selected_strings);
|
||||
|
||||
void _change_bottom_dock_placement();
|
||||
|
||||
private:
|
||||
inline static FileSystemDock *singleton = nullptr;
|
||||
|
||||
|
|
|
|||
|
|
@ -239,7 +239,7 @@ HistoryDock::HistoryDock() {
|
|||
set_name(TTRC("History"));
|
||||
set_icon_name("History");
|
||||
set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("docks/open_history", TTRC("Open History Dock")));
|
||||
set_default_slot(EditorDockManager::DOCK_SLOT_RIGHT_UL);
|
||||
set_default_slot(DockConstants::DOCK_SLOT_RIGHT_UL);
|
||||
|
||||
ur_manager = EditorUndoRedoManager::get_singleton();
|
||||
ur_manager->connect("history_changed", callable_mp(this, &HistoryDock::on_history_changed));
|
||||
|
|
|
|||
|
|
@ -747,7 +747,7 @@ ImportDock::ImportDock() {
|
|||
set_name(TTRC("Import"));
|
||||
set_icon_name("FileAccess");
|
||||
set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("docks/open_import", TTRC("Open Import Dock")));
|
||||
set_default_slot(EditorDockManager::DOCK_SLOT_LEFT_UR);
|
||||
set_default_slot(DockConstants::DOCK_SLOT_LEFT_UR);
|
||||
|
||||
VBoxContainer *main_vb = memnew(VBoxContainer);
|
||||
add_child(main_vb);
|
||||
|
|
|
|||
|
|
@ -719,7 +719,7 @@ InspectorDock::InspectorDock(EditorData &p_editor_data) {
|
|||
set_name(TTRC("Inspector"));
|
||||
set_icon_name("AnimationTrackList");
|
||||
set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("docks/open_inspector", TTRC("Open Inspector Dock")));
|
||||
set_default_slot(EditorDockManager::DOCK_SLOT_RIGHT_UL);
|
||||
set_default_slot(DockConstants::DOCK_SLOT_RIGHT_UL);
|
||||
|
||||
VBoxContainer *main_vb = memnew(VBoxContainer);
|
||||
add_child(main_vb);
|
||||
|
|
|
|||
|
|
@ -93,7 +93,7 @@ NodeDock::NodeDock() {
|
|||
set_name(TTRC("Node"));
|
||||
set_icon_name("Object");
|
||||
set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("docks/open_node", TTRC("Open Node Dock")));
|
||||
set_default_slot(EditorDockManager::DOCK_SLOT_RIGHT_UL);
|
||||
set_default_slot(DockConstants::DOCK_SLOT_RIGHT_UL);
|
||||
|
||||
VBoxContainer *main_vb = memnew(VBoxContainer);
|
||||
add_child(main_vb);
|
||||
|
|
|
|||
|
|
@ -4716,7 +4716,7 @@ SceneTreeDock::SceneTreeDock(Node *p_scene_root, EditorSelection *p_editor_selec
|
|||
set_name(TTRC("Scene"));
|
||||
set_icon_name("PackedScene");
|
||||
set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("docks/open_scene", TTRC("Open Scene Dock")));
|
||||
set_default_slot(EditorDockManager::DOCK_SLOT_LEFT_UR);
|
||||
set_default_slot(DockConstants::DOCK_SLOT_LEFT_UR);
|
||||
|
||||
singleton = this;
|
||||
editor_data = &p_editor_data;
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "core/object/undo_redo.h"
|
||||
#include "core/os/keyboard.h"
|
||||
#include "core/version.h"
|
||||
#include "editor/docks/editor_dock.h"
|
||||
#include "editor/docks/inspector_dock.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_string_names.h"
|
||||
|
|
@ -42,7 +43,6 @@
|
|||
#include "editor/themes/editor_scale.h"
|
||||
#include "modules/regex/regex.h"
|
||||
#include "scene/gui/separator.h"
|
||||
#include "scene/gui/tab_container.h"
|
||||
#include "scene/main/timer.h"
|
||||
#include "scene/resources/font.h"
|
||||
|
||||
|
|
@ -286,11 +286,10 @@ void EditorLog::add_message(const String &p_msg, MessageType p_type) {
|
|||
}
|
||||
|
||||
void EditorLog::_set_dock_tab_icon(Ref<Texture2D> p_icon) {
|
||||
// This is the sole reason to include "tab_container.h" here.
|
||||
TabContainer *parent = Object::cast_to<TabContainer>(get_parent());
|
||||
// TODO: Remove this hack once EditorLog is converted to a dock.
|
||||
EditorDock *parent = Object::cast_to<EditorDock>(get_parent());
|
||||
if (parent) {
|
||||
int idx = parent->get_tab_idx_from_control(this);
|
||||
parent->set_tab_icon(idx, p_icon);
|
||||
parent->set_dock_icon(p_icon);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -928,6 +928,15 @@ void EditorNode::_notification(int p_what) {
|
|||
case NOTIFICATION_READY: {
|
||||
started_timestamp = Time::get_singleton()->get_unix_time_from_system();
|
||||
|
||||
// Store the default order of bottom docks. It can only be determined dynamically.
|
||||
PackedStringArray bottom_docks;
|
||||
bottom_docks.reserve_exact(bottom_panel->get_tab_count());
|
||||
for (int i = 0; i < bottom_panel->get_tab_count(); i++) {
|
||||
EditorDock *dock = Object::cast_to<EditorDock>(bottom_panel->get_tab_control(i));
|
||||
bottom_docks.append(dock->get_effective_layout_key());
|
||||
}
|
||||
default_layout->set_value("docks", "dock_9", String(",").join(bottom_docks));
|
||||
|
||||
RenderingServer::get_singleton()->viewport_set_disable_2d(get_scene_root()->get_viewport_rid(), true);
|
||||
RenderingServer::get_singleton()->viewport_set_environment_mode(get_viewport()->get_viewport_rid(), RenderingServer::VIEWPORT_ENVIRONMENT_DISABLED);
|
||||
DisplayServer::get_singleton()->screen_set_keep_on(EDITOR_GET("interface/editor/keep_screen_on"));
|
||||
|
|
@ -8231,13 +8240,13 @@ EditorNode::EditorNode() {
|
|||
left_l_vsplit->set_vertical(true);
|
||||
left_l_hsplit->add_child(left_l_vsplit);
|
||||
|
||||
TabContainer *dock_slot[EditorDockManager::DOCK_SLOT_MAX];
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_LEFT_UL] = memnew(TabContainer);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_LEFT_UL]->set_name("DockSlotLeftUL");
|
||||
left_l_vsplit->add_child(dock_slot[EditorDockManager::DOCK_SLOT_LEFT_UL]);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_LEFT_BL] = memnew(TabContainer);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_LEFT_BL]->set_name("DockSlotLeftBL");
|
||||
left_l_vsplit->add_child(dock_slot[EditorDockManager::DOCK_SLOT_LEFT_BL]);
|
||||
TabContainer *dock_slot[DockConstants::DOCK_SLOT_MAX];
|
||||
dock_slot[DockConstants::DOCK_SLOT_LEFT_UL] = memnew(TabContainer);
|
||||
dock_slot[DockConstants::DOCK_SLOT_LEFT_UL]->set_name("DockSlotLeftUL");
|
||||
left_l_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_LEFT_UL]);
|
||||
dock_slot[DockConstants::DOCK_SLOT_LEFT_BL] = memnew(TabContainer);
|
||||
dock_slot[DockConstants::DOCK_SLOT_LEFT_BL]->set_name("DockSlotLeftBL");
|
||||
left_l_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_LEFT_BL]);
|
||||
|
||||
left_r_hsplit = memnew(DockSplitContainer);
|
||||
left_r_hsplit->set_name("DockHSplitLeftR");
|
||||
|
|
@ -8246,12 +8255,12 @@ EditorNode::EditorNode() {
|
|||
left_r_vsplit->set_name("DockVSplitLeftR");
|
||||
left_r_vsplit->set_vertical(true);
|
||||
left_r_hsplit->add_child(left_r_vsplit);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_LEFT_UR] = memnew(TabContainer);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_LEFT_UR]->set_name("DockSlotLeftUR");
|
||||
left_r_vsplit->add_child(dock_slot[EditorDockManager::DOCK_SLOT_LEFT_UR]);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_LEFT_BR] = memnew(TabContainer);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_LEFT_BR]->set_name("DockSlotLeftBR");
|
||||
left_r_vsplit->add_child(dock_slot[EditorDockManager::DOCK_SLOT_LEFT_BR]);
|
||||
dock_slot[DockConstants::DOCK_SLOT_LEFT_UR] = memnew(TabContainer);
|
||||
dock_slot[DockConstants::DOCK_SLOT_LEFT_UR]->set_name("DockSlotLeftUR");
|
||||
left_r_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_LEFT_UR]);
|
||||
dock_slot[DockConstants::DOCK_SLOT_LEFT_BR] = memnew(TabContainer);
|
||||
dock_slot[DockConstants::DOCK_SLOT_LEFT_BR]->set_name("DockSlotLeftBR");
|
||||
left_r_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_LEFT_BR]);
|
||||
|
||||
main_hsplit = memnew(DockSplitContainer);
|
||||
main_hsplit->set_name("DockHSplitMain");
|
||||
|
|
@ -8277,23 +8286,23 @@ EditorNode::EditorNode() {
|
|||
right_l_vsplit->set_name("DockVSplitRightL");
|
||||
right_l_vsplit->set_vertical(true);
|
||||
right_hsplit->add_child(right_l_vsplit);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_UL] = memnew(TabContainer);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_UL]->set_name("DockSlotRightUL");
|
||||
right_l_vsplit->add_child(dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_UL]);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_BL] = memnew(TabContainer);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_BL]->set_name("DockSlotRightBL");
|
||||
right_l_vsplit->add_child(dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_BL]);
|
||||
dock_slot[DockConstants::DOCK_SLOT_RIGHT_UL] = memnew(TabContainer);
|
||||
dock_slot[DockConstants::DOCK_SLOT_RIGHT_UL]->set_name("DockSlotRightUL");
|
||||
right_l_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_RIGHT_UL]);
|
||||
dock_slot[DockConstants::DOCK_SLOT_RIGHT_BL] = memnew(TabContainer);
|
||||
dock_slot[DockConstants::DOCK_SLOT_RIGHT_BL]->set_name("DockSlotRightBL");
|
||||
right_l_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_RIGHT_BL]);
|
||||
|
||||
right_r_vsplit = memnew(DockSplitContainer);
|
||||
right_r_vsplit->set_name("DockVSplitRightR");
|
||||
right_r_vsplit->set_vertical(true);
|
||||
right_hsplit->add_child(right_r_vsplit);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_UR] = memnew(TabContainer);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_UR]->set_name("DockSlotRightUR");
|
||||
right_r_vsplit->add_child(dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_UR]);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_BR] = memnew(TabContainer);
|
||||
dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_BR]->set_name("DockSlotRightBR");
|
||||
right_r_vsplit->add_child(dock_slot[EditorDockManager::DOCK_SLOT_RIGHT_BR]);
|
||||
dock_slot[DockConstants::DOCK_SLOT_RIGHT_UR] = memnew(TabContainer);
|
||||
dock_slot[DockConstants::DOCK_SLOT_RIGHT_UR]->set_name("DockSlotRightUR");
|
||||
right_r_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_RIGHT_UR]);
|
||||
dock_slot[DockConstants::DOCK_SLOT_RIGHT_BR] = memnew(TabContainer);
|
||||
dock_slot[DockConstants::DOCK_SLOT_RIGHT_BR]->set_name("DockSlotRightBR");
|
||||
right_r_vsplit->add_child(dock_slot[DockConstants::DOCK_SLOT_RIGHT_BR]);
|
||||
|
||||
editor_dock_manager = memnew(EditorDockManager);
|
||||
|
||||
|
|
@ -8308,8 +8317,8 @@ EditorNode::EditorNode() {
|
|||
editor_dock_manager->add_hsplit(main_hsplit);
|
||||
editor_dock_manager->add_hsplit(right_hsplit);
|
||||
|
||||
for (int i = 0; i < EditorDockManager::DOCK_SLOT_MAX; i++) {
|
||||
editor_dock_manager->register_dock_slot((EditorDockManager::DockSlot)i, dock_slot[i]);
|
||||
for (int i = 0; i < DockConstants::DOCK_SLOT_BOTTOM; i++) {
|
||||
editor_dock_manager->register_dock_slot((DockConstants::DockSlot)i, dock_slot[i], DockConstants::DOCK_LAYOUT_VERTICAL);
|
||||
}
|
||||
|
||||
editor_layout_save_delay_timer = memnew(Timer);
|
||||
|
|
@ -8774,6 +8783,7 @@ EditorNode::EditorNode() {
|
|||
// Bottom panels.
|
||||
|
||||
bottom_panel = memnew(EditorBottomPanel);
|
||||
editor_dock_manager->register_dock_slot(DockConstants::DOCK_SLOT_BOTTOM, bottom_panel, DockConstants::DOCK_LAYOUT_HORIZONTAL);
|
||||
bottom_panel->set_theme_type_variation("BottomPanel");
|
||||
center_split->add_child(bottom_panel);
|
||||
center_split->set_dragger_visibility(SplitContainer::DRAGGER_HIDDEN);
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@
|
|||
#include "editor_bottom_panel.h"
|
||||
|
||||
#include "editor/debugger/editor_debugger_node.h"
|
||||
#include "editor/docks/editor_dock.h"
|
||||
#include "editor/docks/editor_dock_manager.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_string_names.h"
|
||||
|
|
@ -41,10 +42,15 @@
|
|||
#include "editor/themes/editor_scale.h"
|
||||
#include "scene/gui/box_container.h"
|
||||
#include "scene/gui/button.h"
|
||||
#include "scene/gui/separator.h"
|
||||
#include "scene/gui/split_container.h"
|
||||
|
||||
void EditorBottomPanel::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_READY: {
|
||||
layout_popup = get_popup();
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
pin_button->set_button_icon(get_editor_theme_icon(SNAME("Pin")));
|
||||
expand_button->set_button_icon(get_editor_theme_icon(SNAME("ExpandBottomDock")));
|
||||
|
|
@ -58,6 +64,8 @@ void EditorBottomPanel::_on_tab_changed(int p_idx) {
|
|||
}
|
||||
|
||||
void EditorBottomPanel::_theme_changed() {
|
||||
// Add margin to make space for the right side buttons.
|
||||
icon_spacer->set_custom_minimum_size(Vector2(get_theme_constant("class_icon_size", EditorStringName(Editor)), 0));
|
||||
Ref<StyleBox> bottom_tabbar_style = EditorNode::get_singleton()->get_editor_theme()->get_stylebox("tabbar_background", "BottomPanel")->duplicate();
|
||||
bottom_tabbar_style->set_content_margin(SIDE_RIGHT, bottom_hbox->get_minimum_size().x + bottom_tabbar_style->get_content_margin(SIDE_LEFT));
|
||||
add_theme_style_override("tabbar_background", bottom_tabbar_style);
|
||||
|
|
@ -91,9 +99,16 @@ int EditorBottomPanel::get_bottom_panel_offset() {
|
|||
|
||||
void EditorBottomPanel::_repaint() {
|
||||
bool panel_collapsed = get_current_tab() == -1;
|
||||
if (!panel_collapsed && (get_previous_tab() != -1)) {
|
||||
|
||||
if (panel_collapsed && get_popup()) {
|
||||
set_popup(nullptr);
|
||||
} else if (!panel_collapsed && !get_popup()) {
|
||||
set_popup(layout_popup);
|
||||
}
|
||||
if (!panel_collapsed && (previous_tab != -1)) {
|
||||
return;
|
||||
}
|
||||
previous_tab = get_current_tab();
|
||||
|
||||
DockSplitContainer *center_split = EditorNode::get_center_split();
|
||||
ERR_FAIL_NULL(center_split);
|
||||
|
|
@ -124,23 +139,6 @@ void EditorBottomPanel::load_layout_from_config(Ref<ConfigFile> p_config_file, c
|
|||
String key = name.to_snake_case();
|
||||
dock_offsets[key] = p_config_file->get_value(p_section, "dock_" + key + "_offset", 0);
|
||||
}
|
||||
|
||||
if (p_config_file->has_section_key(p_section, "selected_bottom_panel_item")) {
|
||||
int stored_current_tab = p_config_file->get_value(p_section, "selected_bottom_panel_item");
|
||||
|
||||
if (stored_current_tab >= 0 && stored_current_tab < get_tab_bar()->get_tab_count()) {
|
||||
// Make sure we don't try to open contextual editors which are not enabled in the current context.
|
||||
if (!get_tab_bar()->is_tab_hidden(stored_current_tab)) {
|
||||
set_current_tab(stored_current_tab);
|
||||
|
||||
callable_mp(this, &EditorBottomPanel::_update_center_split_offset).call_deferred();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there is no active tab we need to collapse the panel.
|
||||
set_current_tab(-1);
|
||||
}
|
||||
|
||||
void EditorBottomPanel::make_item_visible(Control *p_item, bool p_visible, bool p_ignore_lock) {
|
||||
|
|
@ -149,11 +147,15 @@ void EditorBottomPanel::make_item_visible(Control *p_item, bool p_visible, bool
|
|||
return;
|
||||
}
|
||||
|
||||
p_item->set_visible(p_visible);
|
||||
EditorDock *dock = _get_dock_from_control(p_item);
|
||||
ERR_FAIL_NULL(dock);
|
||||
dock->set_visible(p_visible);
|
||||
}
|
||||
|
||||
void EditorBottomPanel::move_item_to_end(Control *p_item) {
|
||||
move_child(p_item, -1);
|
||||
EditorDock *dock = _get_dock_from_control(p_item);
|
||||
ERR_FAIL_NULL(dock);
|
||||
move_child(dock, -1);
|
||||
}
|
||||
|
||||
void EditorBottomPanel::hide_bottom_panel() {
|
||||
|
|
@ -164,19 +166,6 @@ void EditorBottomPanel::toggle_last_opened_bottom_panel() {
|
|||
set_current_tab(get_current_tab() == -1 ? get_previous_tab() : -1);
|
||||
}
|
||||
|
||||
void EditorBottomPanel::shortcut_input(const Ref<InputEvent> &p_event) {
|
||||
if (p_event.is_null() || !p_event->is_pressed() || p_event->is_echo()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < dock_shortcuts.size(); i++) {
|
||||
if (dock_shortcuts[i].is_valid() && dock_shortcuts[i]->matches_event(p_event)) {
|
||||
bottom_docks[i]->set_visible(!bottom_docks[i]->is_visible());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EditorBottomPanel::_pin_button_toggled(bool p_pressed) {
|
||||
lock_panel_switching = p_pressed;
|
||||
}
|
||||
|
|
@ -208,59 +197,74 @@ void EditorBottomPanel::_update_center_split_offset() {
|
|||
center_split->set_split_offset(get_bottom_panel_offset());
|
||||
}
|
||||
|
||||
Button *EditorBottomPanel::add_item(String p_text, Control *p_item, const Ref<Shortcut> &p_shortcut, bool p_at_front) {
|
||||
p_item->set_name(p_text);
|
||||
add_child(p_item);
|
||||
if (p_at_front) {
|
||||
move_child(p_item, 0);
|
||||
}
|
||||
bottom_docks.push_back(p_item);
|
||||
dock_shortcuts.push_back(p_shortcut);
|
||||
EditorDock *EditorBottomPanel::_get_dock_from_control(Control *p_control) const {
|
||||
return Object::cast_to<EditorDock>(p_control->get_parent());
|
||||
}
|
||||
|
||||
set_process_shortcut_input(is_processing_shortcut_input() || p_shortcut.is_valid());
|
||||
Button *EditorBottomPanel::add_item(String p_text, Control *p_item, const Ref<Shortcut> &p_shortcut, bool p_at_front) {
|
||||
EditorDock *dock = memnew(EditorDock);
|
||||
dock->add_child(p_item);
|
||||
dock->set_title(p_text);
|
||||
dock->set_dock_shortcut(p_shortcut);
|
||||
dock->set_global(false);
|
||||
dock->set_transient(true);
|
||||
dock->set_default_slot(DockConstants::DOCK_SLOT_BOTTOM);
|
||||
dock->set_available_layouts(EditorDock::DOCK_LAYOUT_HORIZONTAL);
|
||||
EditorDockManager::get_singleton()->add_dock(dock);
|
||||
bottom_docks.push_back(dock);
|
||||
|
||||
p_item->show(); // Compatibility in case it was hidden.
|
||||
|
||||
// Still return a dummy button for compatibility reasons.
|
||||
Button *tb = memnew(Button);
|
||||
tb->set_toggle_mode(true);
|
||||
tb->connect(SceneStringName(visibility_changed), callable_mp(this, &EditorBottomPanel::_on_button_visibility_changed).bind(tb, p_item));
|
||||
tb->connect(SceneStringName(visibility_changed), callable_mp(this, &EditorBottomPanel::_on_button_visibility_changed).bind(tb, dock));
|
||||
legacy_buttons.push_back(tb);
|
||||
return tb;
|
||||
}
|
||||
|
||||
void EditorBottomPanel::remove_item(Control *p_item) {
|
||||
int item_idx = bottom_docks.find(p_item);
|
||||
ERR_FAIL_COND_MSG(item_idx == -1, vformat("Cannot remove unknown dock \"%s\" from the bottom panel.", p_item->get_name()));
|
||||
EditorDock *dock = _get_dock_from_control(p_item);
|
||||
ERR_FAIL_NULL_MSG(dock, vformat("Cannot remove unknown dock \"%s\" from the bottom panel.", p_item->get_name()));
|
||||
|
||||
int item_idx = bottom_docks.find(dock);
|
||||
ERR_FAIL_COND(item_idx == -1);
|
||||
|
||||
bottom_docks.remove_at(item_idx);
|
||||
dock_shortcuts.remove_at(item_idx);
|
||||
|
||||
legacy_buttons[item_idx]->queue_free();
|
||||
legacy_buttons.remove_at(item_idx);
|
||||
|
||||
remove_child(p_item);
|
||||
EditorDockManager::get_singleton()->remove_dock(dock);
|
||||
dock->remove_child(p_item);
|
||||
dock->queue_free();
|
||||
}
|
||||
|
||||
void EditorBottomPanel::_on_button_visibility_changed(Button *p_button, Control *p_control) {
|
||||
int tab_index = get_tab_idx_from_control(p_control);
|
||||
if (tab_index == -1) {
|
||||
return;
|
||||
void EditorBottomPanel::_on_button_visibility_changed(Button *p_button, EditorDock *p_dock) {
|
||||
if (p_button->is_visible()) {
|
||||
p_dock->open();
|
||||
} else {
|
||||
p_dock->close();
|
||||
}
|
||||
|
||||
// Ignore the tab if the button is hidden.
|
||||
get_tab_bar()->set_tab_hidden(tab_index, !p_button->is_visible());
|
||||
}
|
||||
|
||||
EditorBottomPanel::EditorBottomPanel() {
|
||||
get_tab_bar()->connect("tab_rmb_clicked", callable_mp(EditorDockManager::get_singleton(), &EditorDockManager::_dock_container_popup).bind(this));
|
||||
get_tab_bar()->connect("tab_changed", callable_mp(this, &EditorBottomPanel::_on_tab_changed));
|
||||
set_tabs_position(TabPosition::POSITION_BOTTOM);
|
||||
set_deselect_enabled(true);
|
||||
|
||||
bottom_hbox = memnew(HBoxContainer);
|
||||
bottom_hbox->set_mouse_filter(MOUSE_FILTER_IGNORE);
|
||||
bottom_hbox->set_anchors_and_offsets_preset(Control::PRESET_RIGHT_WIDE);
|
||||
bottom_hbox->set_h_grow_direction(Control::GROW_DIRECTION_END);
|
||||
get_tab_bar()->add_child(bottom_hbox);
|
||||
|
||||
icon_spacer = memnew(Control);
|
||||
icon_spacer->set_mouse_filter(MOUSE_FILTER_IGNORE);
|
||||
bottom_hbox->add_child(icon_spacer);
|
||||
|
||||
bottom_hbox->add_child(memnew(VSeparator));
|
||||
|
||||
editor_toaster = memnew(EditorToaster);
|
||||
bottom_hbox->add_child(editor_toaster);
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
|
||||
class Button;
|
||||
class ConfigFile;
|
||||
class EditorDock;
|
||||
class EditorToaster;
|
||||
class HBoxContainer;
|
||||
|
||||
|
|
@ -41,29 +42,31 @@ class EditorBottomPanel : public TabContainer {
|
|||
GDCLASS(EditorBottomPanel, TabContainer);
|
||||
|
||||
HBoxContainer *bottom_hbox = nullptr;
|
||||
Control *icon_spacer = nullptr;
|
||||
EditorToaster *editor_toaster = nullptr;
|
||||
Button *pin_button = nullptr;
|
||||
Button *expand_button = nullptr;
|
||||
Popup *layout_popup = nullptr;
|
||||
|
||||
int previous_tab = -1;
|
||||
bool lock_panel_switching = false;
|
||||
LocalVector<Control *> bottom_docks;
|
||||
LocalVector<Ref<Shortcut>> dock_shortcuts;
|
||||
HashMap<String, int> dock_offsets;
|
||||
|
||||
LocalVector<Button *> legacy_buttons;
|
||||
void _on_button_visibility_changed(Button *p_button, Control *p_control);
|
||||
void _on_button_visibility_changed(Button *p_button, EditorDock *p_dock);
|
||||
|
||||
void _repaint();
|
||||
void _on_tab_changed(int p_idx);
|
||||
void _pin_button_toggled(bool p_pressed);
|
||||
void _expand_button_toggled(bool p_pressed);
|
||||
void _update_center_split_offset();
|
||||
EditorDock *_get_dock_from_control(Control *p_control) const;
|
||||
|
||||
protected:
|
||||
void _notification(int p_what);
|
||||
|
||||
virtual void shortcut_input(const Ref<InputEvent> &p_event) override;
|
||||
|
||||
public:
|
||||
void save_layout_to_config(Ref<ConfigFile> p_config_file, const String &p_section) const;
|
||||
void load_layout_from_config(Ref<ConfigFile> p_config_file, const String &p_section);
|
||||
|
|
|
|||
|
|
@ -81,12 +81,12 @@ void EditorPlugin::remove_autoload_singleton(const String &p_name) {
|
|||
EditorNode::get_singleton()->get_project_settings()->get_autoload_settings()->autoload_remove(p_name);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
Button *EditorPlugin::add_control_to_bottom_panel(Control *p_control, const String &p_title, const Ref<Shortcut> &p_shortcut) {
|
||||
ERR_FAIL_NULL_V(p_control, nullptr);
|
||||
return EditorNode::get_bottom_panel()->add_item(p_title, p_control, p_shortcut);
|
||||
}
|
||||
|
||||
#ifndef DISABLE_DEPRECATED
|
||||
void EditorPlugin::add_control_to_dock(DockSlot p_slot, Control *p_control, const Ref<Shortcut> &p_shortcut) {
|
||||
ERR_FAIL_NULL(p_control);
|
||||
ERR_FAIL_COND(legacy_docks.has(p_control));
|
||||
|
|
@ -94,7 +94,7 @@ void EditorPlugin::add_control_to_dock(DockSlot p_slot, Control *p_control, cons
|
|||
EditorDock *dock = memnew(EditorDock);
|
||||
dock->set_title(p_control->get_name());
|
||||
dock->set_dock_shortcut(p_shortcut);
|
||||
dock->set_default_slot((EditorDockManager::DockSlot)p_slot);
|
||||
dock->set_default_slot((DockConstants::DockSlot)p_slot);
|
||||
dock->add_child(p_control);
|
||||
legacy_docks[p_control] = dock;
|
||||
|
||||
|
|
@ -115,12 +115,12 @@ void EditorPlugin::set_dock_tab_icon(Control *p_control, const Ref<Texture2D> &p
|
|||
ERR_FAIL_COND(!legacy_docks.has(p_control));
|
||||
legacy_docks[p_control]->set_dock_icon(p_icon);
|
||||
}
|
||||
#endif
|
||||
|
||||
void EditorPlugin::remove_control_from_bottom_panel(Control *p_control) {
|
||||
ERR_FAIL_NULL(p_control);
|
||||
EditorNode::get_bottom_panel()->remove_item(p_control);
|
||||
}
|
||||
#endif
|
||||
|
||||
void EditorPlugin::add_dock(EditorDock *p_dock) {
|
||||
EditorDockManager::get_singleton()->add_dock(p_dock);
|
||||
|
|
@ -622,8 +622,6 @@ void EditorPlugin::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("add_dock", "dock"), &EditorPlugin::add_dock);
|
||||
ClassDB::bind_method(D_METHOD("remove_dock", "dock"), &EditorPlugin::remove_dock);
|
||||
ClassDB::bind_method(D_METHOD("add_control_to_container", "container", "control"), &EditorPlugin::add_control_to_container);
|
||||
ClassDB::bind_method(D_METHOD("add_control_to_bottom_panel", "control", "title", "shortcut"), &EditorPlugin::add_control_to_bottom_panel, DEFVAL(Ref<Shortcut>()));
|
||||
ClassDB::bind_method(D_METHOD("remove_control_from_bottom_panel", "control"), &EditorPlugin::remove_control_from_bottom_panel);
|
||||
ClassDB::bind_method(D_METHOD("remove_control_from_container", "container", "control"), &EditorPlugin::remove_control_from_container);
|
||||
ClassDB::bind_method(D_METHOD("add_tool_menu_item", "name", "callable"), &EditorPlugin::add_tool_menu_item);
|
||||
ClassDB::bind_method(D_METHOD("add_tool_submenu_item", "name", "submenu"), &EditorPlugin::add_tool_submenu_item);
|
||||
|
|
@ -636,6 +634,8 @@ void EditorPlugin::_bind_methods() {
|
|||
ClassDB::bind_method(D_METHOD("add_control_to_dock", "slot", "control", "shortcut"), &EditorPlugin::add_control_to_dock, DEFVAL(Ref<Shortcut>()));
|
||||
ClassDB::bind_method(D_METHOD("remove_control_from_docks", "control"), &EditorPlugin::remove_control_from_docks);
|
||||
ClassDB::bind_method(D_METHOD("set_dock_tab_icon", "control", "icon"), &EditorPlugin::set_dock_tab_icon);
|
||||
ClassDB::bind_method(D_METHOD("add_control_to_bottom_panel", "control", "title", "shortcut"), &EditorPlugin::add_control_to_bottom_panel, DEFVAL(Ref<Shortcut>()));
|
||||
ClassDB::bind_method(D_METHOD("remove_control_from_bottom_panel", "control"), &EditorPlugin::remove_control_from_bottom_panel);
|
||||
#endif
|
||||
|
||||
ClassDB::bind_method(D_METHOD("add_autoload_singleton", "name", "path"), &EditorPlugin::add_autoload_singleton);
|
||||
|
|
@ -734,6 +734,7 @@ void EditorPlugin::_bind_methods() {
|
|||
BIND_ENUM_CONSTANT(DOCK_SLOT_RIGHT_BL);
|
||||
BIND_ENUM_CONSTANT(DOCK_SLOT_RIGHT_UR);
|
||||
BIND_ENUM_CONSTANT(DOCK_SLOT_RIGHT_BR);
|
||||
BIND_ENUM_CONSTANT(DOCK_SLOT_BOTTOM);
|
||||
BIND_ENUM_CONSTANT(DOCK_SLOT_MAX);
|
||||
|
||||
BIND_ENUM_CONSTANT(AFTER_GUI_INPUT_PASS);
|
||||
|
|
|
|||
|
|
@ -89,16 +89,17 @@ public:
|
|||
};
|
||||
|
||||
enum DockSlot {
|
||||
DOCK_SLOT_NONE = EditorDockManager::DOCK_SLOT_NONE,
|
||||
DOCK_SLOT_LEFT_UL = EditorDockManager::DOCK_SLOT_LEFT_UL,
|
||||
DOCK_SLOT_LEFT_BL = EditorDockManager::DOCK_SLOT_LEFT_BL,
|
||||
DOCK_SLOT_LEFT_UR = EditorDockManager::DOCK_SLOT_LEFT_UR,
|
||||
DOCK_SLOT_LEFT_BR = EditorDockManager::DOCK_SLOT_LEFT_BR,
|
||||
DOCK_SLOT_RIGHT_UL = EditorDockManager::DOCK_SLOT_RIGHT_UL,
|
||||
DOCK_SLOT_RIGHT_BL = EditorDockManager::DOCK_SLOT_RIGHT_BL,
|
||||
DOCK_SLOT_RIGHT_UR = EditorDockManager::DOCK_SLOT_RIGHT_UR,
|
||||
DOCK_SLOT_RIGHT_BR = EditorDockManager::DOCK_SLOT_RIGHT_BR,
|
||||
DOCK_SLOT_MAX = EditorDockManager::DOCK_SLOT_MAX
|
||||
DOCK_SLOT_NONE = DockConstants::DOCK_SLOT_NONE,
|
||||
DOCK_SLOT_LEFT_UL = DockConstants::DOCK_SLOT_LEFT_UL,
|
||||
DOCK_SLOT_LEFT_BL = DockConstants::DOCK_SLOT_LEFT_BL,
|
||||
DOCK_SLOT_LEFT_UR = DockConstants::DOCK_SLOT_LEFT_UR,
|
||||
DOCK_SLOT_LEFT_BR = DockConstants::DOCK_SLOT_LEFT_BR,
|
||||
DOCK_SLOT_RIGHT_UL = DockConstants::DOCK_SLOT_RIGHT_UL,
|
||||
DOCK_SLOT_RIGHT_BL = DockConstants::DOCK_SLOT_RIGHT_BL,
|
||||
DOCK_SLOT_RIGHT_UR = DockConstants::DOCK_SLOT_RIGHT_UR,
|
||||
DOCK_SLOT_RIGHT_BR = DockConstants::DOCK_SLOT_RIGHT_BR,
|
||||
DOCK_SLOT_BOTTOM = DockConstants::DOCK_SLOT_BOTTOM,
|
||||
DOCK_SLOT_MAX = DockConstants::DOCK_SLOT_MAX
|
||||
};
|
||||
|
||||
enum AfterGUIInput {
|
||||
|
|
@ -150,6 +151,9 @@ protected:
|
|||
void add_control_to_dock(DockSlot p_slot, Control *p_control, const Ref<Shortcut> &p_shortcut = nullptr);
|
||||
void remove_control_from_docks(Control *p_control);
|
||||
void set_dock_tab_icon(Control *p_control, const Ref<Texture2D> &p_icon);
|
||||
|
||||
Button *add_control_to_bottom_panel(Control *p_control, const String &p_title, const Ref<Shortcut> &p_shortcut = nullptr);
|
||||
void remove_control_from_bottom_panel(Control *p_control);
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
|
@ -157,8 +161,6 @@ public:
|
|||
|
||||
void add_control_to_container(CustomControlContainer p_location, Control *p_control);
|
||||
void remove_control_from_container(CustomControlContainer p_location, Control *p_control);
|
||||
Button *add_control_to_bottom_panel(Control *p_control, const String &p_title, const Ref<Shortcut> &p_shortcut = nullptr);
|
||||
void remove_control_from_bottom_panel(Control *p_control);
|
||||
|
||||
void add_dock(EditorDock *p_dock);
|
||||
void remove_dock(EditorDock *p_dock);
|
||||
|
|
|
|||
|
|
@ -1926,10 +1926,10 @@ void ThemeItemEditorDialog::_select_another_theme_cbk(const String &p_path) {
|
|||
|
||||
void ThemeItemEditorDialog::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
case NOTIFICATION_POSTINITIALIZE: {
|
||||
connect("about_to_popup", callable_mp(this, &ThemeItemEditorDialog::_dialog_about_to_show));
|
||||
[[fallthrough]];
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
edit_items_add_color->set_button_icon(get_editor_theme_icon(SNAME("Color")));
|
||||
edit_items_add_constant->set_button_icon(get_editor_theme_icon(SNAME("MemberConstant")));
|
||||
|
|
@ -2271,10 +2271,10 @@ void ThemeTypeDialog::_add_type_confirmed() {
|
|||
|
||||
void ThemeTypeDialog::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
case NOTIFICATION_POSTINITIALIZE: {
|
||||
connect("about_to_popup", callable_mp(this, &ThemeTypeDialog::_dialog_about_to_show));
|
||||
[[fallthrough]];
|
||||
}
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_THEME_CHANGED: {
|
||||
_update_add_type_options();
|
||||
} break;
|
||||
|
|
|
|||
|
|
@ -201,12 +201,14 @@ void ThemeEditorPreview::_reset_picker_overlay() {
|
|||
|
||||
void ThemeEditorPreview::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_POSTINITIALIZE: {
|
||||
connect(SceneStringName(visibility_changed), callable_mp(this, &ThemeEditorPreview::_preview_visibility_changed));
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
if (is_visible_in_tree()) {
|
||||
set_process(true);
|
||||
}
|
||||
|
||||
connect(SceneStringName(visibility_changed), callable_mp(this, &ThemeEditorPreview::_preview_visibility_changed));
|
||||
} break;
|
||||
|
||||
case NOTIFICATION_READY: {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@
|
|||
#include "core/config/project_settings.h"
|
||||
#include "core/io/dir_access.h"
|
||||
#include "core/os/os.h"
|
||||
#include "editor/docks/editor_dock.h"
|
||||
#include "editor/editor_node.h"
|
||||
#include "editor/editor_string_names.h"
|
||||
#include "editor/gui/editor_bottom_panel.h"
|
||||
|
|
@ -1367,6 +1368,18 @@ void FindInFilesContainer::_bind_methods() {
|
|||
ADD_SIGNAL(MethodInfo("close_button_clicked"));
|
||||
}
|
||||
|
||||
void FindInFilesContainer::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_READY: {
|
||||
// TODO: Replace this hack once FindInFilesContainer is converted to a dock. It should be in the constructor.
|
||||
EditorDock *parent = Object::cast_to<EditorDock>(get_parent());
|
||||
if (parent) {
|
||||
parent->set_clip_contents(false);
|
||||
}
|
||||
} break;
|
||||
}
|
||||
}
|
||||
|
||||
void FindInFilesContainer::_on_theme_changed() {
|
||||
const Ref<StyleBox> bottom_panel_style = EditorNode::get_singleton()->get_editor_theme()->get_stylebox(SNAME("BottomPanel"), EditorStringName(EditorStyles));
|
||||
if (bottom_panel_style.is_valid()) {
|
||||
|
|
|
|||
|
|
@ -278,6 +278,7 @@ class FindInFilesContainer : public MarginContainer {
|
|||
|
||||
protected:
|
||||
static void _bind_methods();
|
||||
void _notification(int p_what);
|
||||
|
||||
void _on_find_in_files_result_selected(const String &p_fpath, int p_line_number, int p_begin, int p_end);
|
||||
void _on_find_in_files_modified_files(const PackedStringArray &p_paths);
|
||||
|
|
|
|||
|
|
@ -4555,7 +4555,6 @@ ScriptEditor::ScriptEditor(WindowWrapper *p_wrapper) {
|
|||
find_in_files->connect("result_selected", callable_mp(this, &ScriptEditor::_on_find_in_files_result_selected));
|
||||
find_in_files->connect("files_modified", callable_mp(this, &ScriptEditor::_on_find_in_files_modified_files));
|
||||
find_in_files->connect("close_button_clicked", callable_mp(this, &ScriptEditor::_on_find_in_files_close_button_clicked));
|
||||
find_in_files->hide();
|
||||
find_in_files_button->hide();
|
||||
|
||||
history_pos = -1;
|
||||
|
|
|
|||
|
|
@ -1151,7 +1151,7 @@ VersionControlEditorPlugin::VersionControlEditorPlugin() {
|
|||
version_commit_dock->set_layout_key("VersionCommit");
|
||||
version_commit_dock->set_icon_name("VcsBranches");
|
||||
version_commit_dock->set_dock_shortcut(ED_SHORTCUT_AND_COMMAND("docks/open_version_control", TTRC("Open Version Control Dock")));
|
||||
version_commit_dock->set_default_slot(EditorDockManager::DOCK_SLOT_RIGHT_UL);
|
||||
version_commit_dock->set_default_slot(DockConstants::DOCK_SLOT_RIGHT_UL);
|
||||
|
||||
VBoxContainer *dock_vb = memnew(VBoxContainer);
|
||||
version_commit_dock->add_child(dock_vb);
|
||||
|
|
|
|||
|
|
@ -1184,8 +1184,6 @@ void GridMapEditor::_update_theme() {
|
|||
void GridMapEditor::_notification(int p_what) {
|
||||
switch (p_what) {
|
||||
case NOTIFICATION_ENTER_TREE: {
|
||||
mesh_library_palette->connect(SceneStringName(item_selected), callable_mp(this, &GridMapEditor::_item_selected_cbk));
|
||||
|
||||
const RID scenario = get_tree()->get_root()->get_world_3d()->get_scenario();
|
||||
|
||||
for (int i = 0; i < 3; i++) {
|
||||
|
|
@ -1585,6 +1583,7 @@ GridMapEditor::GridMapEditor() {
|
|||
add_child(mesh_library_palette);
|
||||
mesh_library_palette->set_v_size_flags(SIZE_EXPAND_FILL);
|
||||
mesh_library_palette->connect(SceneStringName(gui_input), callable_mp(this, &GridMapEditor::_mesh_library_palette_input));
|
||||
mesh_library_palette->connect(SceneStringName(item_selected), callable_mp(this, &GridMapEditor::_item_selected_cbk));
|
||||
|
||||
info_message = memnew(Label);
|
||||
info_message->set_focus_mode(FOCUS_ACCESSIBILITY);
|
||||
|
|
|
|||
|
|
@ -284,7 +284,6 @@ void CanvasItem::_enter_canvas() {
|
|||
}
|
||||
}
|
||||
|
||||
pending_update = false;
|
||||
queue_redraw();
|
||||
|
||||
notification(NOTIFICATION_ENTER_CANVAS);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue