summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/control.cpp18
-rw-r--r--scene/gui/file_dialog.cpp78
-rw-r--r--scene/gui/file_dialog.h6
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;