diff options
-rw-r--r-- | core/io/resource_loader.cpp | 16 | ||||
-rw-r--r-- | core/io/resource_loader.h | 3 | ||||
-rw-r--r-- | drivers/gles3/shaders/canvas.glsl | 2 | ||||
-rw-r--r-- | editor/doc_tools.cpp | 2 | ||||
-rw-r--r-- | editor/editor_dock_manager.cpp | 175 | ||||
-rw-r--r-- | editor/editor_dock_manager.h | 7 | ||||
-rw-r--r-- | editor/editor_node.cpp | 39 | ||||
-rw-r--r-- | editor/editor_node.h | 3 | ||||
-rw-r--r-- | editor/filesystem_dock.cpp | 110 | ||||
-rw-r--r-- | editor/filesystem_dock.h | 7 | ||||
-rw-r--r-- | editor/gui/editor_run_bar.cpp | 3 | ||||
-rw-r--r-- | editor/plugins/sprite_frames_editor_plugin.cpp | 2 | ||||
-rw-r--r-- | editor/plugins/texture_region_editor_plugin.cpp | 7 | ||||
-rw-r--r-- | editor/plugins/texture_region_editor_plugin.h | 2 | ||||
-rw-r--r-- | scene/gui/control.cpp | 110 | ||||
-rw-r--r-- | scene/theme/theme_db.cpp | 30 | ||||
-rw-r--r-- | scene/theme/theme_db.h | 11 |
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. |