From 000367893ad3594b8e9318b98bd96e1a6bf0f94a Mon Sep 17 00:00:00 2001 From: Juan Linietsky Date: Mon, 29 Jan 2024 14:36:10 +0100 Subject: [PATCH] Ability to move FileSystem dock to bottom * Allows moving the filesystem dock to the bottom * Added ability to drag resources across bottom docks --- editor/editor_dock_manager.cpp | 175 ++++++++++++++++++++++++++++++--- editor/editor_dock_manager.h | 7 ++ editor/editor_node.cpp | 39 ++++++-- editor/editor_node.h | 3 +- editor/filesystem_dock.cpp | 110 +++++++++++++-------- editor/filesystem_dock.h | 7 ++ 6 files changed, 278 insertions(+), 63 deletions(-) diff --git a/editor/editor_dock_manager.cpp b/editor/editor_dock_manager.cpp index 54789bdef18c..0a133778577c 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 &p_input) { Ref 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 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 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 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 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(node); @@ -527,6 +628,46 @@ void EditorDockManager::load_docks_from_config(Ref 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(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 e685fe1380bc..cc1a6634bc2f 100644 --- a/editor/editor_dock_manager.h +++ b/editor/editor_dock_manager.h @@ -77,17 +77,20 @@ class EditorDockManager : public Object { Vector hsplits; Vector floating_docks; + Vector 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 @@ class EditorDockManager : public Object { 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 @@ class EditorDockManager : public Object { void load_docks_from_config(Ref 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 a51717bedd30..e676d24c67ea 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(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 014b72c5808f..7d6123d04b12 100644 --- a/editor/editor_node.h +++ b/editor/editor_node.h @@ -654,6 +654,7 @@ class EditorNode : public Node { 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 @@ class EditorNode : public Node { 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 ecbfe4bec5c4..facc3c3bb595 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 6c69acb953bb..d161a3bd15b3 100644 --- a/editor/filesystem_dock.h +++ b/editor/filesystem_dock.h @@ -154,6 +154,8 @@ class FileSystemDock : public VBoxContainer { HashSet 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 @@ class FileSystemDock : public VBoxContainer { void _feature_profile_changed(); static Vector _remove_self_included_paths(Vector selected_strings); + void _change_bottom_dock_placement(); + + bool _can_dock_horizontal() const; + void _set_dock_horizontal(bool p_enable); + private: static FileSystemDock *singleton;