diff options
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/control.cpp | 18 | ||||
-rw-r--r-- | scene/gui/file_dialog.cpp | 78 | ||||
-rw-r--r-- | scene/gui/file_dialog.h | 6 |
3 files changed, 69 insertions, 33 deletions
diff --git a/scene/gui/control.cpp b/scene/gui/control.cpp index 118e77c009..6e2db68db0 100644 --- a/scene/gui/control.cpp +++ b/scene/gui/control.cpp @@ -2344,7 +2344,7 @@ void Control::set_focus_mode(FocusMode p_focus_mode) { static Control *_next_control(Control *p_from) { if (p_from->is_set_as_top_level()) { - return nullptr; // can't go above + return nullptr; // Can't go above. } Control *parent = Object::cast_to<Control>(p_from->get_parent()); @@ -2364,7 +2364,7 @@ static Control *_next_control(Control *p_from) { return c; } - //no next in parent, try the same in parent + // No next in parent, try the same in parent. return _next_control(parent); } @@ -2388,7 +2388,7 @@ Control *Control::find_next_valid_focus() const { } } - // find next child + // Find next child. Control *next_child = nullptr; @@ -2404,7 +2404,7 @@ Control *Control::find_next_valid_focus() const { if (!next_child) { next_child = _next_control(from); - if (!next_child) { //nothing else.. go up and find either window or subwindow + if (!next_child) { // Nothing else. Go up and find either window or subwindow. next_child = const_cast<Control *>(this); while (next_child && !next_child->is_set_as_top_level()) { next_child = cast_to<Control>(next_child->get_parent()); @@ -2422,7 +2422,7 @@ Control *Control::find_next_valid_focus() const { } } - if (next_child == this) { // no next control-> + if (next_child == from || next_child == this) { // No next control. return (get_focus_mode() == FOCUS_ALL) ? next_child : nullptr; } if (next_child) { @@ -2454,7 +2454,7 @@ static Control *_prev_control(Control *p_from) { return p_from; } - //no prev in parent, try the same in parent + // No prev in parent, try the same in parent. return _prev_control(child); } @@ -2478,12 +2478,12 @@ Control *Control::find_prev_valid_focus() const { } } - // find prev child + // Find prev child. Control *prev_child = nullptr; if (from->is_set_as_top_level() || !Object::cast_to<Control>(from->get_parent())) { - //find last of the children + // Find last of the children. prev_child = _prev_control(from); @@ -2506,7 +2506,7 @@ Control *Control::find_prev_valid_focus() const { } } - if (prev_child == this) { // no prev control-> + if (prev_child == from || prev_child == this) { // No prev control. return (get_focus_mode() == FOCUS_ALL) ? prev_child : nullptr; } diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp index 0e0f8bde83..73effa6c4b 100644 --- a/scene/gui/file_dialog.cpp +++ b/scene/gui/file_dialog.cpp @@ -170,7 +170,11 @@ Vector<String> FileDialog::get_selected_files() const { }; void FileDialog::update_dir() { - dir->set_text(dir_access->get_current_dir(false)); + if (root_prefix.is_empty()) { + dir->set_text(dir_access->get_current_dir(false)); + } else { + dir->set_text(dir_access->get_current_dir(false).trim_prefix(root_prefix).trim_prefix("/")); + } if (drives->is_visible()) { if (dir_access->get_current_dir().is_network_share_path()) { @@ -188,10 +192,8 @@ void FileDialog::update_dir() { } void FileDialog::_dir_submitted(String p_dir) { - dir_access->change_dir(p_dir); + _change_dir(root_prefix.plus_file(p_dir)); file->set_text(""); - invalidate(); - update_dir(); _push_history(); } @@ -378,9 +380,7 @@ bool FileDialog::_is_open_should_be_disabled() { } void FileDialog::_go_up() { - dir_access->change_dir(".."); - update_file_list(); - update_dir(); + _change_dir(".."); _push_history(); } @@ -390,9 +390,7 @@ void FileDialog::_go_back() { } local_history_pos--; - dir_access->change_dir(local_history[local_history_pos]); - update_file_list(); - update_dir(); + _change_dir(local_history[local_history_pos]); dir_prev->set_disabled(local_history_pos == 0); dir_next->set_disabled(local_history_pos == local_history.size() - 1); @@ -404,9 +402,7 @@ void FileDialog::_go_forward() { } local_history_pos++; - dir_access->change_dir(local_history[local_history_pos]); - update_file_list(); - update_dir(); + _change_dir(local_history[local_history_pos]); dir_prev->set_disabled(local_history_pos == 0); dir_next->set_disabled(local_history_pos == local_history.size() - 1); @@ -465,12 +461,10 @@ void FileDialog::_tree_item_activated() { Dictionary d = ti->get_metadata(0); if (d["dir"]) { - dir_access->change_dir(d["name"]); + _change_dir(d["name"]); if (mode == FILE_MODE_OPEN_FILE || mode == FILE_MODE_OPEN_FILES || mode == FILE_MODE_OPEN_DIR || mode == FILE_MODE_OPEN_ANY) { file->set_text(""); } - call_deferred(SNAME("_update_file_list")); - call_deferred(SNAME("_update_dir")); _push_history(); } else { _action_pressed(); @@ -704,9 +698,7 @@ String FileDialog::get_current_path() const { } void FileDialog::set_current_dir(const String &p_dir) { - dir_access->change_dir(p_dir); - update_dir(); - invalidate(); + _change_dir(p_dir); _push_history(); } @@ -732,6 +724,27 @@ void FileDialog::set_current_path(const String &p_path) { } } +void FileDialog::set_root_subfolder(const String &p_root) { + root_subfolder = p_root; + ERR_FAIL_COND_MSG(!dir_access->dir_exists(p_root), "root_subfolder must be an existing sub-directory."); + + local_history.clear(); + local_history_pos = -1; + + dir_access->change_dir(root_subfolder); + if (root_subfolder.is_empty()) { + root_prefix = ""; + } else { + root_prefix = dir_access->get_current_dir(); + } + invalidate(); + update_dir(); +} + +String FileDialog::get_root_subfolder() const { + return root_subfolder; +} + void FileDialog::set_mode_overrides_title(bool p_override) { mode_overrides_title = p_override; } @@ -810,6 +823,8 @@ void FileDialog::set_access(Access p_access) { } break; } access = p_access; + root_prefix = ""; + root_subfolder = ""; _update_drives(); invalidate(); update_filters(); @@ -832,10 +847,8 @@ FileDialog::Access FileDialog::get_access() const { void FileDialog::_make_dir_confirm() { Error err = dir_access->make_dir(makedirname->get_text().strip_edges()); if (err == OK) { - dir_access->change_dir(makedirname->get_text().strip_edges()); - invalidate(); + _change_dir(makedirname->get_text().strip_edges()); update_filters(); - update_dir(); _push_history(); } else { mkdirerr->popup_centered(Size2(250, 50)); @@ -850,11 +863,25 @@ void FileDialog::_make_dir() { void FileDialog::_select_drive(int p_idx) { String d = drives->get_item_text(p_idx); - dir_access->change_dir(d); + _change_dir(d); file->set_text(""); + _push_history(); +} + +void FileDialog::_change_dir(const String &p_new_dir) { + if (root_prefix.is_empty()) { + dir_access->change_dir(p_new_dir); + } else { + String old_dir = dir_access->get_current_dir(); + dir_access->change_dir(p_new_dir); + if (!dir_access->get_current_dir(false).begins_with(root_prefix)) { + dir_access->change_dir(old_dir); + return; + } + } + invalidate(); update_dir(); - _push_history(); } void FileDialog::_update_drives(bool p_select) { @@ -904,6 +931,8 @@ void FileDialog::_bind_methods() { ClassDB::bind_method(D_METHOD("get_line_edit"), &FileDialog::get_line_edit); ClassDB::bind_method(D_METHOD("set_access", "access"), &FileDialog::set_access); ClassDB::bind_method(D_METHOD("get_access"), &FileDialog::get_access); + ClassDB::bind_method(D_METHOD("set_root_subfolder", "dir"), &FileDialog::set_root_subfolder); + ClassDB::bind_method(D_METHOD("get_root_subfolder"), &FileDialog::get_root_subfolder); ClassDB::bind_method(D_METHOD("set_show_hidden_files", "show"), &FileDialog::set_show_hidden_files); ClassDB::bind_method(D_METHOD("is_showing_hidden_files"), &FileDialog::is_showing_hidden_files); ClassDB::bind_method(D_METHOD("_update_file_name"), &FileDialog::update_file_name); @@ -916,6 +945,7 @@ void FileDialog::_bind_methods() { ADD_PROPERTY(PropertyInfo(Variant::BOOL, "mode_overrides_title"), "set_mode_overrides_title", "is_mode_overriding_title"); ADD_PROPERTY(PropertyInfo(Variant::INT, "file_mode", PROPERTY_HINT_ENUM, "Open File,Open Files,Open Folder,Open Any,Save"), "set_file_mode", "get_file_mode"); ADD_PROPERTY(PropertyInfo(Variant::INT, "access", PROPERTY_HINT_ENUM, "Resources,User Data,File System"), "set_access", "get_access"); + ADD_PROPERTY(PropertyInfo(Variant::STRING, "root_subfolder"), "set_root_subfolder", "get_root_subfolder"); ADD_PROPERTY(PropertyInfo(Variant::PACKED_STRING_ARRAY, "filters"), "set_filters", "get_filters"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_hidden_files"), "set_show_hidden_files", "is_showing_hidden_files"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "current_dir", PROPERTY_HINT_DIR, "", PROPERTY_USAGE_NONE), "set_current_dir", "get_current_dir"); diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h index 2e326d2949..8b8d93920c 100644 --- a/scene/gui/file_dialog.h +++ b/scene/gui/file_dialog.h @@ -101,6 +101,8 @@ private: void _push_history(); bool mode_overrides_title = true; + String root_subfolder; + String root_prefix; static bool default_show_hidden_files; bool show_hidden_files = false; @@ -131,6 +133,7 @@ private: void _go_back(); void _go_forward(); + void _change_dir(const String &p_new_dir); void _update_drives(bool p_select = true); virtual void shortcut_input(const Ref<InputEvent> &p_event) override; @@ -162,6 +165,9 @@ public: void set_current_file(const String &p_file); void set_current_path(const String &p_path); + void set_root_subfolder(const String &p_root); + String get_root_subfolder() const; + void set_mode_overrides_title(bool p_override); bool is_mode_overriding_title() const; |