summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/io/resource_loader.cpp16
-rw-r--r--core/io/resource_loader.h3
-rw-r--r--drivers/gles3/shaders/canvas.glsl2
-rw-r--r--editor/doc_tools.cpp2
-rw-r--r--editor/editor_dock_manager.cpp175
-rw-r--r--editor/editor_dock_manager.h7
-rw-r--r--editor/editor_node.cpp39
-rw-r--r--editor/editor_node.h3
-rw-r--r--editor/filesystem_dock.cpp110
-rw-r--r--editor/filesystem_dock.h7
-rw-r--r--editor/gui/editor_run_bar.cpp3
-rw-r--r--editor/plugins/sprite_frames_editor_plugin.cpp2
-rw-r--r--editor/plugins/texture_region_editor_plugin.cpp7
-rw-r--r--editor/plugins/texture_region_editor_plugin.h2
-rw-r--r--scene/gui/control.cpp110
-rw-r--r--scene/theme/theme_db.cpp30
-rw-r--r--scene/theme/theme_db.h11
17 files changed, 378 insertions, 151 deletions
diff --git a/core/io/resource_loader.cpp b/core/io/resource_loader.cpp
index ba11d84bce..d0494a29fd 100644
--- a/core/io/resource_loader.cpp
+++ b/core/io/resource_loader.cpp
@@ -509,20 +509,20 @@ Ref<ResourceLoader::LoadToken> ResourceLoader::_load_start(const String &p_path,
float ResourceLoader::_dependency_get_progress(const String &p_path) {
if (thread_load_tasks.has(p_path)) {
ThreadLoadTask &load_task = thread_load_tasks[p_path];
+ float current_progress = 0.0;
int dep_count = load_task.sub_tasks.size();
if (dep_count > 0) {
- float dep_progress = 0;
for (const String &E : load_task.sub_tasks) {
- dep_progress += _dependency_get_progress(E);
+ current_progress += _dependency_get_progress(E);
}
- dep_progress /= float(dep_count);
- dep_progress *= 0.5;
- dep_progress += load_task.progress * 0.5;
- return dep_progress;
+ current_progress /= float(dep_count);
+ current_progress *= 0.5;
+ current_progress += load_task.progress * 0.5;
} else {
- return load_task.progress;
+ current_progress = load_task.progress;
}
-
+ load_task.max_reported_progress = MAX(load_task.max_reported_progress, current_progress);
+ return load_task.max_reported_progress;
} else {
return 1.0; //assume finished loading it so it no longer exists
}
diff --git a/core/io/resource_loader.h b/core/io/resource_loader.h
index 3c32a19066..0ab81cd0a8 100644
--- a/core/io/resource_loader.h
+++ b/core/io/resource_loader.h
@@ -167,7 +167,8 @@ private:
String remapped_path;
String dependent_path;
String type_hint;
- float progress = 0.0;
+ float progress = 0.0f;
+ float max_reported_progress = 0.0f;
ThreadLoadStatus status = THREAD_LOAD_IN_PROGRESS;
ResourceFormatLoader::CacheMode cache_mode = ResourceFormatLoader::CACHE_MODE_REUSE;
Error error = OK;
diff --git a/drivers/gles3/shaders/canvas.glsl b/drivers/gles3/shaders/canvas.glsl
index c517fcb8ae..69cb888c9d 100644
--- a/drivers/gles3/shaders/canvas.glsl
+++ b/drivers/gles3/shaders/canvas.glsl
@@ -9,7 +9,7 @@ mode_instanced = #define USE_ATTRIBUTES \n#define USE_INSTANCING
#[specializations]
-DISABLE_LIGHTING = false
+DISABLE_LIGHTING = true
USE_RGBA_SHADOWS = false
SINGLE_INSTANCE = false
diff --git a/editor/doc_tools.cpp b/editor/doc_tools.cpp
index 952c093eb6..b650a2196d 100644
--- a/editor/doc_tools.cpp
+++ b/editor/doc_tools.cpp
@@ -634,7 +634,7 @@ void DocTools::generate(BitField<GenerateFlags> p_flags) {
// Theme items.
{
List<ThemeDB::ThemeItemBind> theme_items;
- ThemeDB::get_singleton()->get_class_own_items(cname, &theme_items);
+ ThemeDB::get_singleton()->get_class_items(cname, &theme_items);
Ref<Theme> default_theme = ThemeDB::get_singleton()->get_default_theme();
for (const ThemeDB::ThemeItemBind &theme_item : theme_items) {
diff --git a/editor/editor_dock_manager.cpp b/editor/editor_dock_manager.cpp
index 54789bdef1..0a13377857 100644
--- a/editor/editor_dock_manager.cpp
+++ b/editor/editor_dock_manager.cpp
@@ -113,6 +113,8 @@ void EditorDockManager::_dock_select_popup_theme_changed() {
dock_tab_move_left->set_icon(dock_select_popup->get_editor_theme_icon(SNAME("Back")));
dock_tab_move_right->set_icon(dock_select_popup->get_editor_theme_icon(SNAME("Forward")));
}
+
+ dock_to_bottom->set_icon(dock_select_popup->get_editor_theme_icon(SNAME("ControlAlignBottomWide")));
}
void EditorDockManager::_dock_popup_exit() {
@@ -122,6 +124,19 @@ void EditorDockManager::_dock_popup_exit() {
void EditorDockManager::_dock_pre_popup(int p_dock_slot) {
dock_popup_selected_idx = p_dock_slot;
+ dock_bottom_selected_idx = -1;
+
+ if (bool(dock_slot[p_dock_slot]->get_current_tab_control()->call("_can_dock_horizontal"))) {
+ dock_to_bottom->show();
+ } else {
+ dock_to_bottom->hide();
+ }
+
+ if (dock_float) {
+ dock_float->show();
+ }
+ dock_tab_move_right->show();
+ dock_tab_move_left->show();
}
void EditorDockManager::_dock_move_left() {
@@ -179,23 +194,43 @@ void EditorDockManager::_dock_select_input(const Ref<InputEvent> &p_input) {
Ref<InputEventMouseButton> mb = me;
- if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed() && dock_popup_selected_idx != nrect) {
- dock_slot[nrect]->move_tab_from_tab_container(dock_slot[dock_popup_selected_idx], dock_slot[dock_popup_selected_idx]->get_current_tab(), dock_slot[nrect]->get_tab_count());
+ if (mb.is_valid() && mb->get_button_index() == MouseButton::LEFT && mb->is_pressed()) {
+ if (dock_bottom_selected_idx != -1) {
+ EditorNode::get_singleton()->remove_bottom_panel_item(bottom_docks[dock_bottom_selected_idx]);
- if (dock_slot[dock_popup_selected_idx]->get_tab_count() == 0) {
- dock_slot[dock_popup_selected_idx]->hide();
- } else {
- dock_slot[dock_popup_selected_idx]->set_current_tab(0);
+ bottom_docks[dock_bottom_selected_idx]->call("_set_dock_horizontal", false);
+
+ dock_slot[nrect]->add_child(bottom_docks[dock_bottom_selected_idx]);
+ dock_slot[nrect]->show();
+ bottom_docks.remove_at(dock_bottom_selected_idx);
+ dock_bottom_selected_idx = -1;
+ dock_popup_selected_idx = nrect; // Move to dock popup selected.
+ dock_select->queue_redraw();
+
+ update_dock_slots_visibility(true);
+
+ _edit_current();
+ emit_signal(SNAME("layout_changed"));
}
- dock_popup_selected_idx = nrect;
- dock_slot[nrect]->show();
- dock_select->queue_redraw();
+ if (dock_popup_selected_idx != nrect) {
+ dock_slot[nrect]->move_tab_from_tab_container(dock_slot[dock_popup_selected_idx], dock_slot[dock_popup_selected_idx]->get_current_tab(), dock_slot[nrect]->get_tab_count());
+
+ if (dock_slot[dock_popup_selected_idx]->get_tab_count() == 0) {
+ dock_slot[dock_popup_selected_idx]->hide();
+ } else {
+ dock_slot[dock_popup_selected_idx]->set_current_tab(0);
+ }
- update_dock_slots_visibility(true);
+ dock_popup_selected_idx = nrect;
+ dock_slot[nrect]->show();
+ dock_select->queue_redraw();
- _edit_current();
- emit_signal(SNAME("layout_changed"));
+ update_dock_slots_visibility(true);
+
+ _edit_current();
+ emit_signal(SNAME("layout_changed"));
+ }
}
}
}
@@ -327,6 +362,44 @@ void EditorDockManager::_dock_make_selected_float() {
_edit_current();
}
+void EditorDockManager::bottom_dock_show_placement_popup(const Rect2i &p_position, Control *p_dock) {
+ dock_bottom_selected_idx = bottom_docks.find(p_dock);
+ ERR_FAIL_COND(dock_bottom_selected_idx == -1);
+ dock_popup_selected_idx = -1;
+ dock_to_bottom->hide();
+
+ 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_select_popup->get_size().width;
+ popup_pos.x += p_position.size.width;
+ }
+ dock_select_popup->set_position(popup_pos);
+ dock_select_popup->popup();
+ if (dock_float) {
+ dock_float->hide();
+ }
+ dock_tab_move_right->hide();
+ dock_tab_move_left->hide();
+}
+
+void EditorDockManager::_dock_move_selected_to_bottom() {
+ Control *dock = dock_slot[dock_popup_selected_idx]->get_current_tab_control();
+ dock_slot[dock_popup_selected_idx]->remove_child(dock);
+
+ dock->call("_set_dock_horizontal", true);
+
+ bottom_docks.push_back(dock);
+ EditorNode::get_singleton()->add_bottom_panel_item(dock->get_name(), dock, true);
+ dock_select_popup->hide();
+ update_dock_slots_visibility(true);
+ _edit_current();
+ emit_signal(SNAME("layout_changed"));
+
+ EditorNode::get_singleton()->make_bottom_panel_item_visible(dock);
+}
+
void EditorDockManager::_dock_make_float(Control *p_dock, int p_slot_index, bool p_show_window) {
ERR_FAIL_NULL(p_dock);
@@ -434,6 +507,16 @@ void EditorDockManager::save_docks_to_config(Ref<ConfigFile> p_layout, const Str
p_layout->set_value(p_section, "dock_floating", floating_docks_dump);
+ Array bottom_docks_dump;
+
+ for (Control *bdock : bottom_docks) {
+ Control *dock = bdock;
+ String name = dock->get_name();
+ bottom_docks_dump.push_back(name);
+ }
+
+ p_layout->set_value(p_section, "dock_bottom", bottom_docks_dump);
+
for (int i = 0; i < vsplits.size(); i++) {
if (vsplits[i]->is_visible_in_tree()) {
p_layout->set_value(p_section, "dock_split_" + itos(i + 1), vsplits[i]->get_split_offset());
@@ -464,6 +547,7 @@ void EditorDockManager::load_docks_from_config(Ref<ConfigFile> p_layout, const S
// FIXME: Find it, in a horribly inefficient way.
int atidx = -1;
+ int bottom_idx = -1;
Control *node = nullptr;
for (int k = 0; k < DOCK_SLOT_MAX; k++) {
if (!dock_slot[k]->has_node(name)) {
@@ -492,6 +576,18 @@ void EditorDockManager::load_docks_from_config(Ref<ConfigFile> p_layout, const S
}
}
}
+
+ if (atidx == -1) {
+ // Try bottom docks.
+ for (Control *bdock : bottom_docks) {
+ if (bdock->get_name() == name) {
+ node = bdock;
+ bottom_idx = bottom_docks.find(node);
+ break;
+ }
+ }
+ }
+
if (!node) {
// Well, it's not anywhere.
continue;
@@ -505,6 +601,11 @@ void EditorDockManager::load_docks_from_config(Ref<ConfigFile> p_layout, const S
dock_slot[i]->move_tab_from_tab_container(dock_slot[atidx], dock_slot[atidx]->get_tab_idx_from_control(node), 0);
dock_slot[i]->set_block_signals(false);
dock_slot[atidx]->set_block_signals(false);
+ } else if (bottom_idx != -1) {
+ bottom_docks.erase(node);
+ EditorNode::get_singleton()->remove_bottom_panel_item(node);
+ dock_slot[i]->add_child(node);
+ node->call("_set_dock_horizontal", false);
}
WindowWrapper *wrapper = Object::cast_to<WindowWrapper>(node);
@@ -527,6 +628,46 @@ void EditorDockManager::load_docks_from_config(Ref<ConfigFile> p_layout, const S
}
}
+ Array dock_bottom = p_layout->get_value(p_section, "dock_bottom", Array());
+ for (int i = 0; i < dock_bottom.size(); i++) {
+ const String &name = dock_bottom[i];
+ // FIXME: Find it, in a horribly inefficient way.
+ int atidx = -1;
+ Control *node = nullptr;
+ for (int k = 0; k < DOCK_SLOT_MAX; k++) {
+ if (!dock_slot[k]->has_node(name)) {
+ continue;
+ }
+ node = Object::cast_to<Control>(dock_slot[k]->get_node(name));
+ if (!node) {
+ continue;
+ }
+ atidx = k;
+ break;
+ }
+
+ if (atidx == -1) {
+ // Try floating docks.
+ for (WindowWrapper *wrapper : floating_docks) {
+ if (wrapper->get_meta("dock_name") == name) {
+ atidx = wrapper->get_meta("dock_slot");
+ node = wrapper->get_wrapped_control();
+ wrapper->set_window_enabled(false);
+ break;
+ }
+ }
+ }
+
+ if (node) {
+ dock_slot[atidx]->remove_child(node);
+
+ node->call("_set_dock_horizontal", true);
+
+ bottom_docks.push_back(node);
+ EditorNode::get_singleton()->add_bottom_panel_item(node->get_name(), node, true);
+ }
+ }
+
for (int i = 0; i < vsplits.size(); i++) {
if (!p_layout->has_section_key(p_section, "dock_split_" + itos(i + 1))) {
continue;
@@ -711,9 +852,17 @@ EditorDockManager::EditorDockManager() {
dock_float->set_tooltip_text(TTR("Make this dock floating."));
}
dock_float->set_focus_mode(Control::FOCUS_NONE);
- dock_float->set_h_size_flags(Control::SIZE_SHRINK_CENTER);
+ dock_float->set_h_size_flags(Control::SIZE_EXPAND_FILL);
dock_float->connect("pressed", callable_mp(this, &EditorDockManager::_dock_make_selected_float));
dock_vb->add_child(dock_float);
+ dock_to_bottom = memnew(Button);
+ dock_to_bottom->set_text(TTR("Move to Bottom"));
+ dock_to_bottom->set_focus_mode(Control::FOCUS_NONE);
+ dock_to_bottom->set_h_size_flags(Control::SIZE_EXPAND_FILL);
+ dock_to_bottom->connect("pressed", callable_mp(this, &EditorDockManager::_dock_move_selected_to_bottom));
+ dock_to_bottom->hide();
+ dock_vb->add_child(dock_to_bottom);
+
dock_select_popup->reset_size();
}
diff --git a/editor/editor_dock_manager.h b/editor/editor_dock_manager.h
index e685fe1380..cc1a6634bc 100644
--- a/editor/editor_dock_manager.h
+++ b/editor/editor_dock_manager.h
@@ -77,17 +77,20 @@ private:
Vector<DockSplitContainer *> hsplits;
Vector<WindowWrapper *> floating_docks;
+ Vector<Control *> bottom_docks;
TabContainer *dock_slot[DOCK_SLOT_MAX];
bool docks_visible = true;
PopupPanel *dock_select_popup = nullptr;
Button *dock_float = nullptr;
+ Button *dock_to_bottom = nullptr;
Button *dock_tab_move_left = nullptr;
Button *dock_tab_move_right = nullptr;
Control *dock_select = nullptr;
Rect2 dock_select_rect[DOCK_SLOT_MAX];
int dock_select_rect_over_idx = -1;
int dock_popup_selected_idx = -1;
+ int dock_bottom_selected_idx = -1;
void _dock_select_popup_theme_changed();
void _dock_popup_exit();
@@ -106,6 +109,8 @@ private:
void _dock_make_float(Control *p_control, int p_slot_index, bool p_show_window = true);
void _restore_floating_dock(const Dictionary &p_dock_dump, Control *p_wrapper, int p_slot_index);
+ void _dock_move_selected_to_bottom();
+
protected:
static void _bind_methods();
@@ -121,6 +126,8 @@ public:
void load_docks_from_config(Ref<ConfigFile> p_layout, const String &p_section);
void update_dock_slots_visibility(bool p_keep_selected_tabs = false);
+ void bottom_dock_show_placement_popup(const Rect2i &p_position, Control *p_dock);
+
void close_all_floating_docks();
void set_docks_visible(bool p_show);
diff --git a/editor/editor_node.cpp b/editor/editor_node.cpp
index a51717bedd..e676d24c67 100644
--- a/editor/editor_node.cpp
+++ b/editor/editor_node.cpp
@@ -5160,16 +5160,36 @@ void EditorNode::_scene_tab_closed(int p_tab) {
scene_tabs->update_scene_tabs();
}
-Button *EditorNode::add_bottom_panel_item(String p_text, Control *p_item) {
- Button *tb = memnew(Button);
+class EditorBottomDockButton : public Button {
+ GDCLASS(EditorBottomDockButton, Button)
+
+ static void _bind_methods() {
+ ADD_SIGNAL(MethodInfo("dropping"));
+ }
+
+public:
+ virtual bool can_drop_data(const Point2 &p_point, const Variant &p_data) const override {
+ if (!is_pressed()) {
+ const_cast<EditorBottomDockButton *>(this)->emit_signal("dropping");
+ }
+ return false;
+ }
+};
+
+Button *EditorNode::add_bottom_panel_item(String p_text, Control *p_item, bool p_at_front) {
+ Button *tb = memnew(EditorBottomDockButton);
tb->set_flat(true);
- tb->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch).bind(bottom_panel_items.size()));
+ tb->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch_by_control).bind(p_item));
+ tb->connect("dropping", callable_mp(this, &EditorNode::_bottom_panel_switch_by_control).bind(true, p_item));
tb->set_text(p_text);
tb->set_toggle_mode(true);
tb->set_focus_mode(Control::FOCUS_NONE);
bottom_panel_vb->add_child(p_item);
bottom_panel_hb->move_to_front();
bottom_panel_hb_editors->add_child(tb);
+ if (p_at_front) {
+ bottom_panel_hb_editors->move_child(tb, 0);
+ }
p_item->set_v_size_flags(Control::SIZE_EXPAND_FILL);
p_item->hide();
BottomPanelItem bpi;
@@ -5207,11 +5227,6 @@ void EditorNode::raise_bottom_panel_item(Control *p_item) {
break;
}
}
-
- for (int i = 0; i < bottom_panel_items.size(); i++) {
- bottom_panel_items[i].button->disconnect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch));
- bottom_panel_items[i].button->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch).bind(i));
- }
}
void EditorNode::remove_bottom_panel_item(Control *p_item) {
@@ -5227,10 +5242,14 @@ void EditorNode::remove_bottom_panel_item(Control *p_item) {
break;
}
}
+}
+void EditorNode::_bottom_panel_switch_by_control(bool p_enable, Control *p_control) {
for (int i = 0; i < bottom_panel_items.size(); i++) {
- bottom_panel_items[i].button->disconnect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch));
- bottom_panel_items[i].button->connect("toggled", callable_mp(this, &EditorNode::_bottom_panel_switch).bind(i));
+ if (bottom_panel_items[i].control == p_control) {
+ _bottom_panel_switch(p_enable, i);
+ return;
+ }
}
}
diff --git a/editor/editor_node.h b/editor/editor_node.h
index 014b72c580..7d6123d04b 100644
--- a/editor/editor_node.h
+++ b/editor/editor_node.h
@@ -654,6 +654,7 @@ private:
void _immediate_dialog_confirmed();
void _select_default_main_screen_plugin();
+ void _bottom_panel_switch_by_control(bool p_enable, Control *p_control);
void _bottom_panel_switch(bool p_enable, int p_idx);
void _bottom_panel_raise_toggled(bool);
@@ -866,7 +867,7 @@ public:
bool is_exiting() const { return exiting; }
- Button *add_bottom_panel_item(String p_text, Control *p_item);
+ Button *add_bottom_panel_item(String p_text, Control *p_item, bool p_at_front = false);
void make_bottom_panel_item_visible(Control *p_item);
void raise_bottom_panel_item(Control *p_item);
void hide_bottom_panel();
diff --git a/editor/filesystem_dock.cpp b/editor/filesystem_dock.cpp
index ecbfe4bec5..facc3c3bb5 100644
--- a/editor/filesystem_dock.cpp
+++ b/editor/filesystem_dock.cpp
@@ -39,6 +39,7 @@
#include "core/templates/list.h"
#include "editor/create_dialog.h"
#include "editor/directory_create_dialog.h"
+#include "editor/editor_dock_manager.h"
#include "editor/editor_feature_profile.h"
#include "editor/editor_node.h"
#include "editor/editor_resource_preview.h"
@@ -494,43 +495,22 @@ void FileSystemDock::_update_display_mode(bool p_force) {
void FileSystemDock::_notification(int p_what) {
switch (p_what) {
- case NOTIFICATION_TRANSLATION_CHANGED:
- case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_ENTER_TREE: {
if (initialized) {
return;
}
initialized = true;
- EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &FileSystemDock::_feature_profile_changed));
+ EditorFeatureProfileManager::get_singleton()->connect("current_feature_profile_changed", callable_mp(this, &FileSystemDock::_feature_profile_changed));
EditorFileSystem::get_singleton()->connect("filesystem_changed", callable_mp(this, &FileSystemDock::_fs_changed));
EditorResourcePreview::get_singleton()->connect("preview_invalidated", callable_mp(this, &FileSystemDock::_preview_invalidated));
- button_reload->set_icon(get_editor_theme_icon(SNAME("Reload")));
button_file_list_display_mode->connect("pressed", callable_mp(this, &FileSystemDock::_toggle_file_display));
-
files->connect("item_activated", callable_mp(this, &FileSystemDock::_file_list_activate_file));
button_hist_next->connect("pressed", callable_mp(this, &FileSystemDock::_fw_history));
button_hist_prev->connect("pressed", callable_mp(this, &FileSystemDock::_bw_history));
-
- tree_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
- tree_search_box->set_clear_button_enabled(true);
- tree_button_sort->set_icon(get_editor_theme_icon(SNAME("Sort")));
-
- file_list_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
- file_list_search_box->set_clear_button_enabled(true);
- file_list_button_sort->set_icon(get_editor_theme_icon(SNAME("Sort")));
-
- if (is_layout_rtl()) {
- button_hist_next->set_icon(get_editor_theme_icon(SNAME("Back")));
- button_hist_prev->set_icon(get_editor_theme_icon(SNAME("Forward")));
- } else {
- button_hist_next->set_icon(get_editor_theme_icon(SNAME("Forward")));
- button_hist_prev->set_icon(get_editor_theme_icon(SNAME("Back")));
- }
file_list_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_file_list_rmb_option));
tree_popup->connect("id_pressed", callable_mp(this, &FileSystemDock::_tree_rmb_option));
-
current_path_line_edit->connect("text_submitted", callable_mp(this, &FileSystemDock::_navigate_to_path).bind(false));
always_show_folders = bool(EDITOR_GET("docks/filesystem/always_show_folders"));
@@ -582,16 +562,11 @@ void FileSystemDock::_notification(int p_what) {
}
} break;
+ case NOTIFICATION_TRANSLATION_CHANGED:
+ case NOTIFICATION_LAYOUT_DIRECTION_CHANGED:
case NOTIFICATION_THEME_CHANGED: {
- overwrite_dialog_scroll->add_theme_style_override("panel", get_theme_stylebox("panel", "Tree"));
+ _update_display_mode(true);
- if (is_visible_in_tree()) {
- _update_display_mode(true);
- }
- } break;
-
- case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
- // Update icons.
button_reload->set_icon(get_editor_theme_icon(SNAME("Reload")));
StringName mode_icon = "Panels1";
@@ -602,13 +577,6 @@ void FileSystemDock::_notification(int p_what) {
}
button_toggle_display_mode->set_icon(get_editor_theme_icon(mode_icon));
- if (is_layout_rtl()) {
- button_hist_next->set_icon(get_editor_theme_icon(SNAME("Back")));
- button_hist_prev->set_icon(get_editor_theme_icon(SNAME("Forward")));
- } else {
- button_hist_next->set_icon(get_editor_theme_icon(SNAME("Forward")));
- button_hist_prev->set_icon(get_editor_theme_icon(SNAME("Back")));
- }
if (file_list_display_mode == FILE_LIST_DISPLAY_LIST) {
button_file_list_display_mode->set_icon(get_editor_theme_icon(SNAME("FileThumbnail")));
} else {
@@ -616,13 +584,25 @@ void FileSystemDock::_notification(int p_what) {
}
tree_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
- tree_search_box->set_clear_button_enabled(true);
tree_button_sort->set_icon(get_editor_theme_icon(SNAME("Sort")));
file_list_search_box->set_right_icon(get_editor_theme_icon(SNAME("Search")));
- file_list_search_box->set_clear_button_enabled(true);
file_list_button_sort->set_icon(get_editor_theme_icon(SNAME("Sort")));
+ button_dock_placement->set_icon(get_editor_theme_icon(SNAME("GuiTabMenu")));
+
+ if (is_layout_rtl()) {
+ button_hist_next->set_icon(get_editor_theme_icon(SNAME("Back")));
+ button_hist_prev->set_icon(get_editor_theme_icon(SNAME("Forward")));
+ } else {
+ button_hist_next->set_icon(get_editor_theme_icon(SNAME("Forward")));
+ button_hist_prev->set_icon(get_editor_theme_icon(SNAME("Back")));
+ }
+
+ overwrite_dialog_scroll->add_theme_style_override("panel", get_theme_stylebox("panel", "Tree"));
+ } break;
+
+ case EditorSettings::NOTIFICATION_EDITOR_SETTINGS_CHANGED: {
// Update editor dark theme & always show folders states from editor settings, redraw if needed.
bool do_redraw = false;
@@ -2561,6 +2541,10 @@ 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) {
@@ -3634,6 +3618,43 @@ MenuButton *FileSystemDock::_create_file_menu_button() {
return button;
}
+bool FileSystemDock::_can_dock_horizontal() const {
+ return true;
+}
+
+void FileSystemDock::_set_dock_horizontal(bool p_enable) {
+ if (button_dock_placement->is_visible() == p_enable) {
+ return;
+ }
+
+ if (p_enable) {
+ set_meta("_dock_display_mode", get_display_mode());
+ set_meta("_dock_file_display_mode", get_file_list_display_mode());
+
+ FileSystemDock::DisplayMode new_display_mode = FileSystemDock::DisplayMode(int(get_meta("_bottom_display_mode", int(FileSystemDock::DISPLAY_MODE_HSPLIT))));
+ FileSystemDock::FileListDisplayMode new_file_display_mode = FileSystemDock::FileListDisplayMode(int(get_meta("_bottom_file_display_mode", int(FileSystemDock::FILE_LIST_DISPLAY_THUMBNAILS))));
+
+ set_display_mode(new_display_mode);
+ set_file_list_display_mode(new_file_display_mode);
+ set_custom_minimum_size(Size2(0, 200) * EDSCALE);
+ } else {
+ set_meta("_bottom_display_mode", get_display_mode());
+ set_meta("_bottom_file_display_mode", get_file_list_display_mode());
+
+ FileSystemDock::DisplayMode new_display_mode = FileSystemDock::DISPLAY_MODE_TREE_ONLY;
+ FileSystemDock::FileListDisplayMode new_file_display_mode = FileSystemDock::FILE_LIST_DISPLAY_LIST;
+
+ new_display_mode = FileSystemDock::DisplayMode(int(get_meta("_dock_display_mode", new_display_mode)));
+ new_file_display_mode = FileSystemDock::FileListDisplayMode(int(get_meta("_dock_file_display_mode", new_file_display_mode)));
+
+ set_display_mode(new_display_mode);
+ set_file_list_display_mode(new_file_display_mode);
+ set_custom_minimum_size(Size2(0, 0));
+ }
+
+ button_dock_placement->set_visible(p_enable);
+}
+
void FileSystemDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("_file_list_thumbnail_done"), &FileSystemDock::_file_list_thumbnail_done);
ClassDB::bind_method(D_METHOD("_tree_thumbnail_done"), &FileSystemDock::_tree_thumbnail_done);
@@ -3643,6 +3664,9 @@ void FileSystemDock::_bind_methods() {
ClassDB::bind_method(D_METHOD("add_resource_tooltip_plugin", "plugin"), &FileSystemDock::add_resource_tooltip_plugin);
ClassDB::bind_method(D_METHOD("remove_resource_tooltip_plugin", "plugin"), &FileSystemDock::remove_resource_tooltip_plugin);
+ ClassDB::bind_method(D_METHOD("_set_dock_horizontal", "enable"), &FileSystemDock::_set_dock_horizontal);
+ ClassDB::bind_method(D_METHOD("_can_dock_horizontal"), &FileSystemDock::_can_dock_horizontal);
+
ADD_SIGNAL(MethodInfo("inherit", PropertyInfo(Variant::STRING, "file")));
ADD_SIGNAL(MethodInfo("instantiate", PropertyInfo(Variant::PACKED_STRING_ARRAY, "files")));
@@ -3796,6 +3820,12 @@ FileSystemDock::FileSystemDock() {
button_toggle_display_mode->set_flat(true);
toolbar_hbc->add_child(button_toggle_display_mode);
+ button_dock_placement = memnew(Button);
+ button_dock_placement->set_flat(true);
+ button_dock_placement->connect("pressed", callable_mp(this, &FileSystemDock::_change_bottom_dock_placement));
+ button_dock_placement->hide();
+ toolbar_hbc->add_child(button_dock_placement);
+
toolbar2_hbc = memnew(HBoxContainer);
toolbar2_hbc->add_theme_constant_override("separation", 0);
top_vbc->add_child(toolbar2_hbc);
@@ -3803,6 +3833,7 @@ FileSystemDock::FileSystemDock() {
tree_search_box = memnew(LineEdit);
tree_search_box->set_h_size_flags(SIZE_EXPAND_FILL);
tree_search_box->set_placeholder(TTR("Filter Files"));
+ tree_search_box->set_clear_button_enabled(true);
tree_search_box->connect("text_changed", callable_mp(this, &FileSystemDock::_search_changed).bind(tree_search_box));
toolbar2_hbc->add_child(tree_search_box);
@@ -3852,6 +3883,7 @@ FileSystemDock::FileSystemDock() {
file_list_search_box = memnew(LineEdit);
file_list_search_box->set_h_size_flags(SIZE_EXPAND_FILL);
file_list_search_box->set_placeholder(TTR("Filter Files"));
+ file_list_search_box->set_clear_button_enabled(true);
file_list_search_box->connect("text_changed", callable_mp(this, &FileSystemDock::_search_changed).bind(file_list_search_box));
path_hb->add_child(file_list_search_box);
diff --git a/editor/filesystem_dock.h b/editor/filesystem_dock.h
index 6c69acb953..d161a3bd15 100644
--- a/editor/filesystem_dock.h
+++ b/editor/filesystem_dock.h
@@ -154,6 +154,8 @@ private:
HashSet<String> favorites;
+ Button *button_dock_placement = nullptr;
+
Button *button_toggle_display_mode = nullptr;
Button *button_reload = nullptr;
Button *button_file_list_display_mode = nullptr;
@@ -360,6 +362,11 @@ private:
void _feature_profile_changed();
static Vector<String> _remove_self_included_paths(Vector<String> selected_strings);
+ void _change_bottom_dock_placement();
+
+ bool _can_dock_horizontal() const;
+ void _set_dock_horizontal(bool p_enable);
+
private:
static FileSystemDock *singleton;
diff --git a/editor/gui/editor_run_bar.cpp b/editor/gui/editor_run_bar.cpp
index 54fb60d074..a79dced69e 100644
--- a/editor/gui/editor_run_bar.cpp
+++ b/editor/gui/editor_run_bar.cpp
@@ -273,12 +273,13 @@ void EditorRunBar::play_main_scene(bool p_from_native) {
}
void EditorRunBar::play_current_scene(bool p_reload) {
+ String last_current_scene = run_current_filename; // This is necessary to have a copy of the string.
+
EditorNode::get_singleton()->save_default_environment();
stop_playing();
current_mode = RunMode::RUN_CURRENT;
if (p_reload) {
- String last_current_scene = run_current_filename; // This is necessary to have a copy of the string.
_run_scene(last_current_scene);
} else {
_run_scene();
diff --git a/editor/plugins/sprite_frames_editor_plugin.cpp b/editor/plugins/sprite_frames_editor_plugin.cpp
index 3672142b35..2476d28986 100644
--- a/editor/plugins/sprite_frames_editor_plugin.cpp
+++ b/editor/plugins/sprite_frames_editor_plugin.cpp
@@ -2178,7 +2178,7 @@ SpriteFramesEditor::SpriteFramesEditor() {
min_thumbnail_zoom = 0.1f * MAX(1.0f, EDSCALE);
// Default the zoom to match the editor scale, but don't dezoom on editor scales below 100% to prevent pixel art from looking bad.
sheet_zoom = MAX(1.0f, EDSCALE);
- max_sheet_zoom = 16.0f * MAX(1.0f, EDSCALE);
+ max_sheet_zoom = 128.0f * MAX(1.0f, EDSCALE);
min_sheet_zoom = 0.01f * MAX(1.0f, EDSCALE);
_zoom_reset();
diff --git a/editor/plugins/texture_region_editor_plugin.cpp b/editor/plugins/texture_region_editor_plugin.cpp
index 09f6bf884e..2a8b357559 100644
--- a/editor/plugins/texture_region_editor_plugin.cpp
+++ b/editor/plugins/texture_region_editor_plugin.cpp
@@ -698,7 +698,7 @@ void TextureRegionEditor::_set_snap_sep_y(float p_val) {
}
void TextureRegionEditor::_zoom_on_position(float p_zoom, Point2 p_position) {
- if (p_zoom < 0.25 || p_zoom > 8) {
+ if (p_zoom < min_draw_zoom || p_zoom > max_draw_zoom) {
return;
}
@@ -1166,6 +1166,11 @@ TextureRegionEditor::TextureRegionEditor() {
hb_grid->hide();
+ // Default the zoom to match the editor scale, but don't dezoom on editor scales below 100% to prevent pixel art from looking bad.
+ draw_zoom = MAX(1.0f, EDSCALE);
+ max_draw_zoom = 128.0f * MAX(1.0f, EDSCALE);
+ min_draw_zoom = 0.01f * MAX(1.0f, EDSCALE);
+
texture_preview = memnew(PanelContainer);
vb->add_child(texture_preview);
texture_preview->set_v_size_flags(Control::SIZE_EXPAND_FILL);
diff --git a/editor/plugins/texture_region_editor_plugin.h b/editor/plugins/texture_region_editor_plugin.h
index eeae9dc205..fb2b547bed 100644
--- a/editor/plugins/texture_region_editor_plugin.h
+++ b/editor/plugins/texture_region_editor_plugin.h
@@ -76,6 +76,8 @@ class TextureRegionEditor : public AcceptDialog {
Vector2 draw_ofs;
float draw_zoom = 1.0;
+ float min_draw_zoom = 1.0;
+ float max_draw_zoom = 1.0;
bool updating_scroll = false;
SnapMode snap_mode = SNAP_NONE;
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp
index 3f48f04d4b..fcdbdb4edb 100644
--- a/scene/gui/control.cpp
+++ b/scene/gui/control.cpp
@@ -370,80 +370,60 @@ bool Control::_get(const StringName &p_name, Variant &r_ret) const {
void Control::_get_property_list(List<PropertyInfo> *p_list) const {
ERR_MAIN_THREAD_GUARD;
- Ref<Theme> default_theme = ThemeDB::get_singleton()->get_default_theme();
+ List<ThemeDB::ThemeItemBind> theme_items;
+ ThemeDB::get_singleton()->get_class_items(get_class_name(), &theme_items, true);
p_list->push_back(PropertyInfo(Variant::NIL, GNAME("Theme Overrides", "theme_override_"), PROPERTY_HINT_NONE, "theme_override_", PROPERTY_USAGE_GROUP));
- {
- List<StringName> names;
- default_theme->get_color_list(get_class_name(), &names);
- for (const StringName &E : names) {
- uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.theme_color_override.has(E)) {
- usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
- }
+ for (const ThemeDB::ThemeItemBind &E : theme_items) {
+ uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- p_list->push_back(PropertyInfo(Variant::COLOR, PNAME("theme_override_colors") + String("/") + E, PROPERTY_HINT_NONE, "", usage));
- }
- }
- {
- List<StringName> names;
- default_theme->get_constant_list(get_class_name(), &names);
- for (const StringName &E : names) {
- uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.theme_constant_override.has(E)) {
- usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
- }
+ switch (E.data_type) {
+ case Theme::DATA_TYPE_COLOR: {
+ if (data.theme_color_override.has(E.item_name)) {
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
+ p_list->push_back(PropertyInfo(Variant::COLOR, PNAME("theme_override_colors") + String("/") + E.item_name, PROPERTY_HINT_NONE, "", usage));
+ } break;
- p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_constants") + String("/") + E, PROPERTY_HINT_RANGE, "-16384,16384", usage));
- }
- }
- {
- List<StringName> names;
- default_theme->get_font_list(get_class_name(), &names);
- for (const StringName &E : names) {
- uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.theme_font_override.has(E)) {
- usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
- }
+ case Theme::DATA_TYPE_CONSTANT: {
+ if (data.theme_constant_override.has(E.item_name)) {
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
+ p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_constants") + String("/") + E.item_name, PROPERTY_HINT_RANGE, "-16384,16384", usage));
+ } break;
- p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_fonts") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage));
- }
- }
- {
- List<StringName> names;
- default_theme->get_font_size_list(get_class_name(), &names);
- for (const StringName &E : names) {
- uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.theme_font_size_override.has(E)) {
- usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
- }
+ case Theme::DATA_TYPE_FONT: {
+ if (data.theme_font_override.has(E.item_name)) {
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
+ p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_fonts") + String("/") + E.item_name, PROPERTY_HINT_RESOURCE_TYPE, "Font", usage));
+ } break;
- p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_font_sizes") + String("/") + E, PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px", usage));
- }
- }
- {
- List<StringName> names;
- default_theme->get_icon_list(get_class_name(), &names);
- for (const StringName &E : names) {
- uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.theme_icon_override.has(E)) {
- usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
- }
+ case Theme::DATA_TYPE_FONT_SIZE: {
+ if (data.theme_font_size_override.has(E.item_name)) {
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
+ p_list->push_back(PropertyInfo(Variant::INT, PNAME("theme_override_font_sizes") + String("/") + E.item_name, PROPERTY_HINT_RANGE, "1,256,1,or_greater,suffix:px", usage));
+ } break;
- p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_icons") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage));
- }
- }
- {
- List<StringName> names;
- default_theme->get_stylebox_list(get_class_name(), &names);
- for (const StringName &E : names) {
- uint32_t usage = PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_CHECKABLE;
- if (data.theme_style_override.has(E)) {
- usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
- }
+ case Theme::DATA_TYPE_ICON: {
+ if (data.theme_icon_override.has(E.item_name)) {
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
+ p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_icons") + String("/") + E.item_name, PROPERTY_HINT_RESOURCE_TYPE, "Texture2D", usage));
+ } break;
+
+ case Theme::DATA_TYPE_STYLEBOX: {
+ if (data.theme_style_override.has(E.item_name)) {
+ usage |= PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_CHECKED;
+ }
+ p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_styles") + String("/") + E.item_name, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage));
+ } break;
- p_list->push_back(PropertyInfo(Variant::OBJECT, PNAME("theme_override_styles") + String("/") + E, PROPERTY_HINT_RESOURCE_TYPE, "StyleBox", usage));
+ default: {
+ // Silences warning.
+ } break;
}
}
}
diff --git a/scene/theme/theme_db.cpp b/scene/theme/theme_db.cpp
index 6841a9e1d4..711630d09e 100644
--- a/scene/theme/theme_db.cpp
+++ b/scene/theme/theme_db.cpp
@@ -337,6 +337,7 @@ void ThemeDB::bind_class_item(Theme::DataType p_data_type, const StringName &p_c
bind.setter = p_setter;
theme_item_binds[p_class_name][p_prop_name] = bind;
+ theme_item_binds_list[p_class_name].push_back(bind);
}
void ThemeDB::bind_class_external_item(Theme::DataType p_data_type, const StringName &p_class_name, const StringName &p_prop_name, const StringName &p_item_name, const StringName &p_type_name, ThemeItemSetter p_setter) {
@@ -351,6 +352,7 @@ void ThemeDB::bind_class_external_item(Theme::DataType p_data_type, const String
bind.setter = p_setter;
theme_item_binds[p_class_name][p_prop_name] = bind;
+ theme_item_binds_list[p_class_name].push_back(bind);
}
void ThemeDB::update_class_instance_items(Node *p_instance) {
@@ -371,7 +373,7 @@ void ThemeDB::update_class_instance_items(Node *p_instance) {
}
}
-void ThemeDB::get_class_own_items(const StringName &p_class_name, List<ThemeItemBind> *r_list) {
+void ThemeDB::get_class_items(const StringName &p_class_name, List<ThemeItemBind> *r_list, bool p_include_inherited) {
List<StringName> class_hierarchy;
StringName class_name = p_class_name;
while (class_name != StringName()) {
@@ -381,23 +383,32 @@ void ThemeDB::get_class_own_items(const StringName &p_class_name, List<ThemeItem
HashSet<StringName> inherited_props;
for (const StringName &theme_type : class_hierarchy) {
- HashMap<StringName, HashMap<StringName, ThemeItemBind>>::Iterator E = theme_item_binds.find(theme_type);
+ HashMap<StringName, List<ThemeItemBind>>::Iterator E = theme_item_binds_list.find(theme_type);
if (E) {
- for (const KeyValue<StringName, ThemeItemBind> &F : E->value) {
- if (inherited_props.has(F.value.item_name)) {
+ for (const ThemeItemBind &F : E->value) {
+ if (inherited_props.has(F.item_name)) {
continue; // Skip inherited properties.
}
- if (F.value.external || F.value.class_name != p_class_name) {
- inherited_props.insert(F.value.item_name);
- continue; // Track properties defined in parent classes, and skip them.
+ if (F.external || F.class_name != p_class_name) {
+ inherited_props.insert(F.item_name);
+
+ if (!p_include_inherited) {
+ continue; // Track properties defined in parent classes, and skip them.
+ }
}
- r_list->push_back(F.value);
+ r_list->push_back(F);
}
}
}
}
+void ThemeDB::_sort_theme_items() {
+ for (KeyValue<StringName, List<ThemeDB::ThemeItemBind>> &E : theme_item_binds_list) {
+ E.value.sort_custom<ThemeItemBind::SortByType>();
+ }
+}
+
// Object methods.
void ThemeDB::_bind_methods() {
@@ -435,6 +446,9 @@ ThemeDB *ThemeDB::get_singleton() {
ThemeDB::ThemeDB() {
singleton = this;
+ if (MessageQueue::get_singleton()) { // May not exist in tests etc.
+ callable_mp(this, &ThemeDB::_sort_theme_items).call_deferred();
+ }
}
ThemeDB::~ThemeDB() {
diff --git a/scene/theme/theme_db.h b/scene/theme/theme_db.h
index e472f4e935..d9428ad213 100644
--- a/scene/theme/theme_db.h
+++ b/scene/theme/theme_db.h
@@ -107,10 +107,19 @@ public:
bool external = false;
ThemeItemSetter setter;
+
+ struct SortByType {
+ _FORCE_INLINE_ bool operator()(const ThemeItemBind &l, const ThemeItemBind &r) const {
+ return l.data_type < r.data_type;
+ }
+ };
};
private:
HashMap<StringName, HashMap<StringName, ThemeItemBind>> theme_item_binds;
+ HashMap<StringName, List<ThemeItemBind>> theme_item_binds_list; // Used for listing purposes.
+
+ void _sort_theme_items();
protected:
static void _bind_methods();
@@ -162,7 +171,7 @@ public:
void bind_class_external_item(Theme::DataType p_data_type, const StringName &p_class_name, const StringName &p_prop_name, const StringName &p_item_name, const StringName &p_type_name, ThemeItemSetter p_setter);
void update_class_instance_items(Node *p_instance);
- void get_class_own_items(const StringName &p_class_name, List<ThemeItemBind> *r_list);
+ void get_class_items(const StringName &p_class_name, List<ThemeItemBind> *r_list, bool p_include_inherited = false);
// Memory management, reference, and initialization.