diff options
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/file_dialog.cpp | 87 | ||||
-rw-r--r-- | scene/gui/file_dialog.h | 8 | ||||
-rw-r--r-- | scene/gui/item_list.cpp | 27 | ||||
-rw-r--r-- | scene/gui/item_list.h | 2 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 38 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 25 | ||||
-rw-r--r-- | scene/gui/tree.h | 2 | ||||
-rw-r--r-- | scene/gui/video_player.cpp | 1 |
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; |