summaryrefslogtreecommitdiff
path: root/scene/gui
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui')
-rw-r--r--scene/gui/file_dialog.cpp87
-rw-r--r--scene/gui/file_dialog.h8
-rw-r--r--scene/gui/item_list.cpp27
-rw-r--r--scene/gui/item_list.h2
-rw-r--r--scene/gui/text_edit.cpp38
-rw-r--r--scene/gui/tree.cpp25
-rw-r--r--scene/gui/tree.h2
-rw-r--r--scene/gui/video_player.cpp1
8 files changed, 166 insertions, 24 deletions
diff --git a/scene/gui/file_dialog.cpp b/scene/gui/file_dialog.cpp
index 6aba535572..9bfb70bf42 100644
--- a/scene/gui/file_dialog.cpp
+++ b/scene/gui/file_dialog.cpp
@@ -47,6 +47,7 @@ void FileDialog::_notification(int p_what) {
if (p_what == NOTIFICATION_ENTER_TREE) {
refresh->set_icon(get_icon("reload"));
+ dir_up->set_icon(get_icon("ArrowUp", "EditorIcons"));
}
if (p_what == NOTIFICATION_DRAW) {
@@ -85,6 +86,10 @@ void FileDialog::_unhandled_input(const Ref<InputEvent> &p_event) {
invalidate();
} break;
+ case KEY_BACKSPACE: {
+
+ _dir_entered("..");
+ } break;
default: { handled = false; }
}
@@ -118,6 +123,9 @@ void FileDialog::update_dir() {
if (drives->is_visible()) {
drives->select(dir_access->get_current_drive());
}
+
+ // Deselect any item, to make "Select Current Folder" button text by default.
+ deselect_items();
}
void FileDialog::_dir_entered(String p_dir) {
@@ -152,6 +160,10 @@ void FileDialog::_post_popup() {
tree->grab_focus();
set_process_unhandled_input(true);
+
+ // For open dir mode, deselect all items on file dialog open.
+ if (mode == MODE_OPEN_DIR)
+ deselect_items();
}
void FileDialog::_action_pressed() {
@@ -189,7 +201,7 @@ void FileDialog::_action_pressed() {
TreeItem *item = tree->get_selected();
if (item) {
Dictionary d = item->get_metadata(0);
- if (d["dir"]) {
+ if (d["dir"] && d["name"] != "..") {
path = path.plus_file(d["name"]);
}
}
@@ -272,6 +284,57 @@ void FileDialog::_cancel_pressed() {
hide();
}
+bool FileDialog::_is_open_should_be_disabled() {
+
+ if (mode == MODE_OPEN_ANY || mode == MODE_SAVE_FILE)
+ return false;
+
+ TreeItem *ti = tree->get_selected();
+ // We have something that we can't select?
+ if (!ti)
+ return true;
+
+ Dictionary d = ti->get_metadata(0);
+
+ // Opening a file, but selected a folder? Forbidden.
+ if (((mode == MODE_OPEN_FILE || mode == MODE_OPEN_FILES) && d["dir"]) || // Flipped case, also forbidden.
+ (mode == MODE_OPEN_DIR && !d["dir"]))
+ return true;
+
+ return false;
+}
+
+void FileDialog::_go_up() {
+
+ dir_access->change_dir("..");
+ update_file_list();
+ update_dir();
+}
+
+void FileDialog::deselect_items() {
+
+ // Clear currently selected items in file manager.
+ tree->deselect_all();
+
+ // And change get_ok title.
+ if (!tree->is_anything_selected()) {
+ get_ok()->set_disabled(_is_open_should_be_disabled());
+
+ switch (mode) {
+
+ case MODE_OPEN_FILE:
+ case MODE_OPEN_FILES:
+ get_ok()->set_text(TTR("Open"));
+ get_ok()->set_disabled(false);
+ break;
+
+ case MODE_OPEN_DIR:
+ get_ok()->set_text(TTR("Select Current Folder"));
+ get_ok()->set_disabled(false);
+ break;
+ }
+ }
+}
void FileDialog::_tree_selected() {
TreeItem *ti = tree->get_selected();
@@ -282,7 +345,11 @@ void FileDialog::_tree_selected() {
if (!d["dir"]) {
file->set_text(d["name"]);
+ } else if (mode == MODE_OPEN_DIR) {
+ get_ok()->set_text(TTR("Select this Folder"));
}
+
+ get_ok()->set_disabled(_is_open_should_be_disabled());
}
void FileDialog::_tree_dc_selected() {
@@ -323,7 +390,7 @@ void FileDialog::update_file_list() {
while ((item = dir_access->get_next(&isdir)) != "") {
- if (item == ".")
+ if (item == "." || item == "..")
continue;
ishidden = dir_access->current_is_hidden();
@@ -336,11 +403,6 @@ void FileDialog::update_file_list() {
}
}
- if (dirs.find("..") == NULL) {
- //may happen if lacking permissions
- dirs.push_back("..");
- }
-
dirs.sort_custom<NaturalNoCaseComparator>();
files.sort_custom<NaturalNoCaseComparator>();
@@ -563,7 +625,7 @@ void FileDialog::set_mode(Mode p_mode) {
makedir->hide();
break;
case MODE_OPEN_DIR:
- get_ok()->set_text(RTR("Open"));
+ get_ok()->set_text(RTR("Select Current Folder"));
set_title(RTR("Open a Directory"));
makedir->show();
break;
@@ -716,6 +778,8 @@ void FileDialog::_bind_methods() {
ClassDB::bind_method(D_METHOD("_make_dir_confirm"), &FileDialog::_make_dir_confirm);
ClassDB::bind_method(D_METHOD("_update_file_list"), &FileDialog::update_file_list);
ClassDB::bind_method(D_METHOD("_update_dir"), &FileDialog::update_dir);
+ ClassDB::bind_method(D_METHOD("_go_up"), &FileDialog::_go_up);
+ ClassDB::bind_method(D_METHOD("deselect_items"), &FileDialog::deselect_items);
ClassDB::bind_method(D_METHOD("invalidate"), &FileDialog::invalidate);
@@ -763,6 +827,12 @@ FileDialog::FileDialog() {
set_title(RTR("Save a File"));
HBoxContainer *hbc = memnew(HBoxContainer);
+
+ dir_up = memnew(ToolButton);
+ dir_up->set_tooltip(TTR("Go to parent folder"));
+ hbc->add_child(dir_up);
+ dir_up->connect("pressed", this, "_go_up");
+
hbc->add_child(memnew(Label(RTR("Path:"))));
dir = memnew(LineEdit);
hbc->add_child(dir);
@@ -807,6 +877,7 @@ FileDialog::FileDialog() {
//cancel->connect("pressed", this,"_cancel_pressed");
tree->connect("cell_selected", this, "_tree_selected", varray(), CONNECT_DEFERRED);
tree->connect("item_activated", this, "_tree_db_selected", varray());
+ tree->connect("nothing_selected", this, "deselect_items");
dir->connect("text_entered", this, "_dir_entered");
file->connect("text_entered", this, "_file_entered");
filter->connect("item_selected", this, "_filter_selected");
diff --git a/scene/gui/file_dialog.h b/scene/gui/file_dialog.h
index 34cecfe4d0..ca3d9f54b2 100644
--- a/scene/gui/file_dialog.h
+++ b/scene/gui/file_dialog.h
@@ -33,7 +33,6 @@
#include "box_container.h"
#include "os/dir_access.h"
#include "scene/gui/dialogs.h"
-#include "scene/gui/dialogs.h"
#include "scene/gui/line_edit.h"
#include "scene/gui/option_button.h"
#include "scene/gui/tool_button.h"
@@ -87,6 +86,8 @@ private:
DirAccess *dir_access;
ConfirmationDialog *confirm_save;
+ ToolButton *dir_up;
+
ToolButton *refresh;
Vector<String> filters;
@@ -112,11 +113,14 @@ private:
void _filter_selected(int);
void _make_dir();
void _make_dir_confirm();
+ void _go_up();
void _update_drives();
void _unhandled_input(const Ref<InputEvent> &p_event);
+ bool _is_open_should_be_disabled();
+
virtual void _post_popup();
protected:
@@ -155,6 +159,8 @@ public:
void invalidate();
+ void deselect_items();
+
FileDialog();
~FileDialog();
};
diff --git a/scene/gui/item_list.cpp b/scene/gui/item_list.cpp
index 51ab49e643..197e474fd6 100644
--- a/scene/gui/item_list.cpp
+++ b/scene/gui/item_list.cpp
@@ -257,6 +257,20 @@ void ItemList::unselect(int p_idx) {
}
update();
}
+
+void ItemList::unselect_all() {
+
+ if (items.size() < 1)
+ return;
+
+ for (int i = 0; i < items.size(); i++) {
+
+ items[i].selected = false;
+ }
+
+ update();
+}
+
bool ItemList::is_selected(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx, items.size(), false);
@@ -530,6 +544,9 @@ void ItemList::_gui_input(const Ref<InputEvent> &p_event) {
return;
}
+
+ // Since closest is null, more likely we clicked on empty space, so send signal to interested controls. Allows, for example, implement items deselecting.
+ emit_signal("nothing_selected");
}
if (mb.is_valid() && mb->get_button_index() == BUTTON_WHEEL_UP && mb->is_pressed()) {
@@ -1249,6 +1266,15 @@ Vector<int> ItemList::get_selected_items() {
return selected;
}
+bool ItemList::is_anything_selected() {
+ for (int i = 0; i < items.size(); i++) {
+ if (items[i].selected)
+ return true;
+ }
+
+ return false;
+}
+
void ItemList::_set_items(const Array &p_items) {
ERR_FAIL_COND(p_items.size() % 3);
@@ -1409,6 +1435,7 @@ void ItemList::_bind_methods() {
ADD_SIGNAL(MethodInfo("multi_selected", PropertyInfo(Variant::INT, "index"), PropertyInfo(Variant::BOOL, "selected")));
ADD_SIGNAL(MethodInfo("item_activated", PropertyInfo(Variant::INT, "index")));
ADD_SIGNAL(MethodInfo("rmb_clicked", PropertyInfo(Variant::VECTOR2, "at_position")));
+ ADD_SIGNAL(MethodInfo("nothing_selected"));
GLOBAL_DEF("gui/timers/incremental_search_max_interval_msec", 2000);
}
diff --git a/scene/gui/item_list.h b/scene/gui/item_list.h
index ccdd705325..b1e1e5eeb0 100644
--- a/scene/gui/item_list.h
+++ b/scene/gui/item_list.h
@@ -156,8 +156,10 @@ public:
void select(int p_idx, bool p_single = true);
void unselect(int p_idx);
+ void unselect_all();
bool is_selected(int p_idx) const;
Vector<int> get_selected_items();
+ bool is_anything_selected();
void set_current(int p_current);
int get_current() const;
diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp
index b5e809fd03..166b55d6f3 100644
--- a/scene/gui/text_edit.cpp
+++ b/scene/gui/text_edit.cpp
@@ -1712,12 +1712,12 @@ void TextEdit::_get_mouse_pos(const Point2i &p_mouse, int &r_row, int &r_col) co
rows -= cache.style_normal->get_margin(MARGIN_TOP);
rows /= get_row_height();
int lsp = get_line_scroll_pos(true);
- int row = cursor.line_ofs + (rows + (v_scroll->get_value() - lsp));
+ int row = cursor.line_ofs + (rows + (round(v_scroll->get_value()) - lsp));
if (is_hiding_enabled()) {
// row will be offset by the hidden rows
int f_ofs = num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), MIN(rows + 1, text.size() - cursor.line_ofs)) - 1;
- row = cursor.line_ofs + (f_ofs + (v_scroll->get_value() - lsp));
+ row = cursor.line_ofs + (f_ofs + (round(v_scroll->get_value()) - lsp));
row = CLAMP(row, 0, text.size() - num_lines_from(text.size() - 1, -1));
}
@@ -3475,11 +3475,13 @@ void TextEdit::adjust_viewport_to_cursor() {
int num_rows = num_lines_from(CLAMP(cursor.line_ofs, 0, text.size() - 1), MIN(visible_rows, text.size() - 1 - cursor.line_ofs));
// make sure the cursor is on the screen
+ // above the caret
if (cursor.line > (cursor.line_ofs + MAX(num_rows, visible_rows))) {
cursor.line_ofs = cursor.line - num_lines_from(cursor.line, -visible_rows) + 1;
}
- if (cursor.line < cursor.line_ofs) {
- cursor.line_ofs = cursor.line;
+ // below the caret
+ if (cursor.line_ofs == cursor.line) {
+ cursor.line_ofs = cursor.line - 2;
}
int line_ofs_max = text.size() - 1;
if (!scroll_past_end_of_file_enabled) {
@@ -3499,17 +3501,17 @@ void TextEdit::adjust_viewport_to_cursor() {
if (cursor_x < cursor.x_ofs)
cursor.x_ofs = cursor_x;
+ updating_scrolls = true;
h_scroll->set_value(cursor.x_ofs);
update_line_scroll_pos();
- v_scroll->set_value(get_line_scroll_pos());
+ double new_v_scroll = get_line_scroll_pos();
+ // keep offset if smooth scroll is enabled
+ if (smooth_scroll_enabled) {
+ new_v_scroll += fmod(v_scroll->get_value(), 1.0);
+ }
+ v_scroll->set_value(new_v_scroll);
+ updating_scrolls = false;
update();
- /*
- get_range()->set_max(text.size());
-
- get_range()->set_page(get_visible_rows());
-
- get_range()->set((int)cursor.line_ofs);
-*/
}
void TextEdit::center_viewport_to_cursor() {
@@ -3540,10 +3542,16 @@ void TextEdit::center_viewport_to_cursor() {
if (cursor_x < cursor.x_ofs)
cursor.x_ofs = cursor_x;
+ updating_scrolls = true;
h_scroll->set_value(cursor.x_ofs);
update_line_scroll_pos();
- v_scroll->set_value(get_line_scroll_pos());
-
+ double new_v_scroll = get_line_scroll_pos();
+ // keep offset if smooth scroll is enabled
+ if (smooth_scroll_enabled) {
+ new_v_scroll += fmod(v_scroll->get_value(), 1.0);
+ }
+ v_scroll->set_value(new_v_scroll);
+ updating_scrolls = false;
update();
}
@@ -3666,7 +3674,7 @@ void TextEdit::_scroll_moved(double p_to_val) {
cursor.x_ofs = h_scroll->get_value();
if (v_scroll->is_visible_in_tree()) {
double val = v_scroll->get_value();
- cursor.line_ofs = num_lines_from(0, (int)floor(val)) - 1;
+ cursor.line_ofs = num_lines_from(0, (int)floor(val));
line_scroll_pos = (int)floor(val);
}
update();
diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp
index 9213296c55..ab12d123ba 100644
--- a/scene/gui/tree.cpp
+++ b/scene/gui/tree.cpp
@@ -2599,6 +2599,11 @@ void Tree::_gui_input(Ref<InputEvent> p_event) {
if (drag_touching) {
set_physics_process(true);
}
+
+ if (b->get_button_index() == BUTTON_LEFT) {
+ if (get_item_at_position(b->get_position()) == NULL && !b->get_shift() && !b->get_control() && !b->get_command())
+ emit_signal("nothing_selected");
+ }
}
} break;
@@ -3043,6 +3048,25 @@ void Tree::set_select_mode(SelectMode p_mode) {
select_mode = p_mode;
}
+void Tree::deselect_all() {
+
+ TreeItem *item = get_next_selected(get_root());
+ while (item) {
+ item->deselect(selected_col);
+ item = get_next_selected(get_root());
+ }
+
+ selected_item = NULL;
+ selected_col = -1;
+
+ update();
+}
+
+bool Tree::is_anything_selected() {
+
+ return (selected_item != NULL);
+}
+
void Tree::clear() {
if (blocked > 0) {
@@ -3750,6 +3774,7 @@ void Tree::_bind_methods() {
ADD_SIGNAL(MethodInfo("custom_popup_edited", PropertyInfo(Variant::BOOL, "arrow_clicked")));
ADD_SIGNAL(MethodInfo("item_activated"));
ADD_SIGNAL(MethodInfo("column_title_pressed", PropertyInfo(Variant::INT, "column")));
+ ADD_SIGNAL(MethodInfo("nothing_selected"));
BIND_ENUM_CONSTANT(SELECT_SINGLE);
BIND_ENUM_CONSTANT(SELECT_ROW);
diff --git a/scene/gui/tree.h b/scene/gui/tree.h
index 64d6016942..112de3165f 100644
--- a/scene/gui/tree.h
+++ b/scene/gui/tree.h
@@ -546,6 +546,8 @@ public:
int get_selected_column() const;
int get_pressed_button() const;
void set_select_mode(SelectMode p_mode);
+ void deselect_all();
+ bool is_anything_selected();
void set_columns(int p_columns);
int get_columns() const;
diff --git a/scene/gui/video_player.cpp b/scene/gui/video_player.cpp
index c7157d539d..8f567f9796 100644
--- a/scene/gui/video_player.cpp
+++ b/scene/gui/video_player.cpp
@@ -490,6 +490,7 @@ VideoPlayer::VideoPlayer() {
expand = true;
audio_track = 0;
+ bus_index = 0;
buffering_ms = 500;
server_mix_rate = 44100;