diff options
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/line_edit.cpp | 111 | ||||
-rw-r--r-- | scene/gui/line_edit.h | 14 | ||||
-rw-r--r-- | scene/gui/nine_patch_rect.cpp (renamed from scene/gui/patch_9_rect.cpp) | 4 | ||||
-rw-r--r-- | scene/gui/nine_patch_rect.h (renamed from scene/gui/patch_9_rect.h) | 8 | ||||
-rw-r--r-- | scene/gui/tab_container.cpp | 7 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 31 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 4 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 2 | ||||
-rw-r--r-- | scene/gui/viewport_container.cpp | 35 | ||||
-rw-r--r-- | scene/gui/viewport_container.h | 4 |
10 files changed, 173 insertions, 47 deletions
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index ed8eff436c..40e2dba6c2 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -161,13 +161,14 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { } break; - case (KEY_Z): { // Simple One level undo - + case (KEY_Z): { // undo / redo if (editable) { - - undo(); + if (k->get_shift()) { + redo(); + } else { + undo(); + } } - } break; case (KEY_U): { // Delete from start to cursor @@ -175,7 +176,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { if (editable) { selection_clear(); - undo_text = text; text = text.substr(cursor_pos, text.length() - cursor_pos); Ref<Font> font = get_font("font"); @@ -205,7 +205,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { if (editable) { selection_clear(); - undo_text = text; text = text.substr(0, cursor_pos); _text_changed(); } @@ -245,7 +244,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { break; if (selection.enabled) { - undo_text = text; selection_delete(); break; } @@ -276,7 +274,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { set_cursor_position(cc); } else { - undo_text = text; delete_char(); } @@ -382,7 +379,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { } if (selection.enabled) { - undo_text = text; selection_delete(); break; } @@ -417,7 +413,6 @@ void LineEdit::_gui_input(Ref<InputEvent> p_event) { delete_text(cursor_pos, cc); } else { - undo_text = text; set_cursor_position(cursor_pos + 1); delete_char(); } @@ -778,7 +773,6 @@ void LineEdit::copy_text() { void LineEdit::cut_text() { if (selection.enabled) { - undo_text = text; OS::get_singleton()->set_clipboard(text.substr(selection.begin, selection.end - selection.begin)); selection_delete(); } @@ -798,23 +792,33 @@ void LineEdit::paste_text() { } void LineEdit::undo() { - - int old_cursor_pos = cursor_pos; - text = undo_text; - - Ref<Font> font = get_font("font"); - - cached_width = 0; - for (int i = 0; i < text.length(); i++) - cached_width += font->get_char_size(text[i]).width; - - if (old_cursor_pos > text.length()) { - set_cursor_position(text.length()); - } else { - set_cursor_position(old_cursor_pos); + if (undo_stack_pos == NULL) { + if (undo_stack.size() <= 1) { + return; + } + undo_stack_pos = undo_stack.back(); + } else if (undo_stack_pos == undo_stack.front()) { + return; } + undo_stack_pos = undo_stack_pos->prev(); + TextOperation op = undo_stack_pos->get(); + text = op.text; + set_cursor_position(op.cursor_pos); + _emit_text_change(); +} - _text_changed(); +void LineEdit::redo() { + if (undo_stack_pos == NULL) { + return; + } + if (undo_stack_pos == undo_stack.back()) { + return; + } + undo_stack_pos = undo_stack_pos->next(); + TextOperation op = undo_stack_pos->get(); + text = op.text; + set_cursor_position(op.cursor_pos); + _emit_text_change(); } void LineEdit::shift_selection_check_pre(bool p_shift) { @@ -947,8 +951,6 @@ void LineEdit::delete_char() { void LineEdit::delete_text(int p_from_column, int p_to_column) { - undo_text = text; - if (text.size() > 0) { Ref<Font> font = get_font("font"); if (font != NULL) { @@ -1036,9 +1038,11 @@ void LineEdit::set_cursor_position(int p_pos) { Ref<StyleBox> style = get_stylebox("normal"); Ref<Font> font = get_font("font"); - if (cursor_pos < window_pos) { + if (cursor_pos <= window_pos) { /* Adjust window if cursor goes too much to the left */ - set_window_pos(cursor_pos); + if (window_pos > 0) + set_window_pos(window_pos - 1); + } else if (cursor_pos > window_pos) { /* Adjust window if cursor goes too much to the right */ int window_width = get_size().width - style->get_minimum_size().width; @@ -1086,8 +1090,6 @@ void LineEdit::append_at_cursor(String p_text) { if ((max_length <= 0) || (text.length() + p_text.length() <= max_length)) { - undo_text = text; - Ref<Font> font = get_font("font"); if (font != NULL) { for (int i = 0; i < p_text.length(); i++) @@ -1105,6 +1107,7 @@ void LineEdit::append_at_cursor(String p_text) { void LineEdit::clear_internal() { + _clear_undo_stack(); cached_width = 0; cursor_pos = 0; window_pos = 0; @@ -1275,6 +1278,11 @@ void LineEdit::menu_option(int p_option) { undo(); } } break; + case MENU_REDO: { + if (editable) { + redo(); + } + } } } @@ -1312,10 +1320,43 @@ void LineEdit::_text_changed() { if (expand_to_text_length) minimum_size_changed(); + _emit_text_change(); + _clear_redo(); +} + +void LineEdit::_emit_text_change() { emit_signal("text_changed", text); _change_notify("text"); } +void LineEdit::_clear_redo() { + _create_undo_state(); + if (undo_stack_pos == NULL) { + return; + } + + undo_stack_pos = undo_stack_pos->next(); + while (undo_stack_pos) { + List<TextOperation>::Element *elem = undo_stack_pos; + undo_stack_pos = undo_stack_pos->next(); + undo_stack.erase(elem); + } + _create_undo_state(); +} + +void LineEdit::_clear_undo_stack() { + undo_stack.clear(); + undo_stack_pos = NULL; + _create_undo_state(); +} + +void LineEdit::_create_undo_state() { + TextOperation op; + op.text = text; + op.cursor_pos = cursor_pos; + undo_stack.push_back(op); +} + void LineEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("_toggle_draw_caret"), &LineEdit::_toggle_draw_caret); @@ -1369,6 +1410,7 @@ void LineEdit::_bind_methods() { BIND_ENUM_CONSTANT(MENU_CLEAR); BIND_ENUM_CONSTANT(MENU_SELECT_ALL); BIND_ENUM_CONSTANT(MENU_UNDO); + BIND_ENUM_CONSTANT(MENU_REDO); BIND_ENUM_CONSTANT(MENU_MAX); ADD_PROPERTYNZ(PropertyInfo(Variant::STRING, "text"), "set_text", "get_text"); @@ -1388,6 +1430,8 @@ void LineEdit::_bind_methods() { LineEdit::LineEdit() { + undo_stack_pos = NULL; + _create_undo_state(); align = ALIGN_LEFT; cached_width = 0; cursor_pos = 0; @@ -1421,6 +1465,7 @@ LineEdit::LineEdit() { menu->add_item(TTR("Clear"), MENU_CLEAR); menu->add_separator(); menu->add_item(TTR("Undo"), MENU_UNDO, KEY_MASK_CMD | KEY_Z); + menu->add_item(TTR("Redo"), MENU_REDO, KEY_MASK_CMD | KEY_MASK_SHIFT | KEY_Z); menu->connect("id_pressed", this, "menu_option"); expand_to_text_length = false; } diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index 661f9b60b9..bece29a37d 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -56,6 +56,7 @@ public: MENU_CLEAR, MENU_SELECT_ALL, MENU_UNDO, + MENU_REDO, MENU_MAX }; @@ -92,10 +93,22 @@ private: bool drag_attempt; } selection; + struct TextOperation { + int cursor_pos; + String text; + }; + List<TextOperation> undo_stack; + List<TextOperation>::Element *undo_stack_pos; + + void _clear_undo_stack(); + void _clear_redo(); + void _create_undo_state(); + Timer *caret_blink_timer; static void _ime_text_callback(void *p_self, String p_text, Point2 p_selection); void _text_changed(); + void _emit_text_change(); bool expand_to_text_length; bool caret_blink_enabled; @@ -166,6 +179,7 @@ public: void cut_text(); void paste_text(); void undo(); + void redo(); void set_editable(bool p_editable); bool is_editable() const; diff --git a/scene/gui/patch_9_rect.cpp b/scene/gui/nine_patch_rect.cpp index 92c34dd3f9..c02d80bba8 100644 --- a/scene/gui/patch_9_rect.cpp +++ b/scene/gui/nine_patch_rect.cpp @@ -1,5 +1,5 @@ /*************************************************************************/ -/* patch_9_rect.cpp */ +/* nine_patch_rect.cpp */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,7 +27,7 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#include "patch_9_rect.h" +#include "nine_patch_rect.h" #include "servers/visual_server.h" diff --git a/scene/gui/patch_9_rect.h b/scene/gui/nine_patch_rect.h index 808b7a1f5d..809daf9db3 100644 --- a/scene/gui/patch_9_rect.h +++ b/scene/gui/nine_patch_rect.h @@ -1,5 +1,5 @@ /*************************************************************************/ -/* patch_9_rect.h */ +/* nine_patch_rect.h */ /*************************************************************************/ /* This file is part of: */ /* GODOT ENGINE */ @@ -27,8 +27,8 @@ /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /*************************************************************************/ -#ifndef PATCH_9_FRAME_H -#define PATCH_9_FRAME_H +#ifndef NINE_PATCH_RECT_H +#define NINE_PATCH_RECT_H #include "scene/gui/control.h" /** @@ -81,4 +81,4 @@ public: }; VARIANT_ENUM_CAST(NinePatchRect::AxisStretchMode) -#endif // PATCH_9_FRAME_H +#endif // NINE_PATCH_RECT_H diff --git a/scene/gui/tab_container.cpp b/scene/gui/tab_container.cpp index cfe924ecd4..581034ddee 100644 --- a/scene/gui/tab_container.cpp +++ b/scene/gui/tab_container.cpp @@ -90,6 +90,10 @@ void TabContainer::_gui_input(const Ref<InputEvent> &p_event) { return; } + // Do not activate tabs when tabs is empty + if (get_tab_count() == 0) + return; + Vector<Control *> tabs = _get_tabs(); // Handle navigation buttons. @@ -298,6 +302,8 @@ void TabContainer::_notification(int p_what) { } int TabContainer::_get_tab_width(int p_index) const { + + ERR_FAIL_INDEX_V(p_index, get_tab_count(), 0); Control *control = Object::cast_to<Control>(_get_tabs()[p_index]); if (!control || control->is_set_as_toplevel()) return 0; @@ -669,6 +675,7 @@ void TabContainer::_bind_methods() { TabContainer::TabContainer() { first_tab_cache = 0; + last_tab_cache = 0; buttons_visible_cache = false; tabs_ofs_cache = 0; current = 0; diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 977ba2da7c..ee7762b668 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -734,7 +734,7 @@ void TextEdit::_notification(int p_what) { if (str.length() == 0) { // draw line background if empty as we won't loop at at all - if (line == cursor.line) { + if (line == cursor.line && highlight_current_line) { VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, xmargin_end, get_row_height()), cache.current_line_color); } @@ -965,7 +965,7 @@ void TextEdit::_notification(int p_what) { //current line highlighting bool in_selection = (selection.active && line >= selection.from_line && line <= selection.to_line && (line > selection.from_line || j >= selection.from_column) && (line < selection.to_line || j < selection.to_column)); - if (line == cursor.line) { + if (line == cursor.line && highlight_current_line) { // if its the first char draw behind line numbers if (j == 0) { VisualServer::get_singleton()->canvas_item_add_rect(ci, Rect2(0, ofs_y, (char_ofs + char_margin), get_row_height()), cache.current_line_color); @@ -2188,7 +2188,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } } } - + begin_complex_operation(); bool first_line = false; if (k->get_command()) { if (k->get_shift()) { @@ -2204,8 +2204,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { } } - _insert_text_at_cursor(ins); - _push_current_op(); + insert_text_at_cursor(ins); if (first_line) { cursor_set_line(0); @@ -2213,7 +2212,7 @@ void TextEdit::_gui_input(const Ref<InputEvent> &p_gui_input) { cursor_set_line(cursor.line - 1); cursor_set_column(text[cursor.line].length()); } - + end_complex_operation(); } break; case KEY_ESCAPE: { if (completion_hint != "") { @@ -4489,7 +4488,13 @@ void TextEdit::_update_completion_candidates() { completion_index = 0; completion_base = s; Vector<float> sim_cache; + bool single_quote = s.begins_with("'"); + for (int i = 0; i < completion_strings.size(); i++) { + if (single_quote && completion_strings[i].is_quoted()) { + completion_strings[i] = completion_strings[i].unquote().quote("'"); + } + if (s == completion_strings[i]) { // A perfect match, stop completion _cancel_completion(); @@ -4732,6 +4737,15 @@ int TextEdit::get_breakpoint_gutter_width() const { return cache.breakpoint_gutter_width; } +void TextEdit::set_highlight_current_line(bool p_enabled) { + highlight_current_line = p_enabled; + update(); +} + +bool TextEdit::is_highlight_current_line_enabled() const { + return highlight_current_line; +} + bool TextEdit::is_text_field() const { return true; @@ -4859,6 +4873,9 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("set_syntax_coloring", "enable"), &TextEdit::set_syntax_coloring); ClassDB::bind_method(D_METHOD("is_syntax_coloring_enabled"), &TextEdit::is_syntax_coloring_enabled); + ClassDB::bind_method(D_METHOD("set_highlight_current_line", "enabled"), &TextEdit::set_highlight_current_line); + ClassDB::bind_method(D_METHOD("is_highlight_current_line_enabled"), &TextEdit::is_highlight_current_line_enabled); + ClassDB::bind_method(D_METHOD("set_smooth_scroll_enable", "enable"), &TextEdit::set_smooth_scroll_enabled); ClassDB::bind_method(D_METHOD("is_smooth_scroll_enabled"), &TextEdit::is_smooth_scroll_enabled); ClassDB::bind_method(D_METHOD("set_v_scroll_speed", "speed"), &TextEdit::set_v_scroll_speed); @@ -4870,6 +4887,7 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("menu_option", "option"), &TextEdit::menu_option); ClassDB::bind_method(D_METHOD("get_menu"), &TextEdit::get_menu); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_current_line"), "set_highlight_current_line", "is_highlight_current_line_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "syntax_highlighting"), "set_syntax_coloring", "is_syntax_coloring_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "show_line_numbers"), "set_show_line_numbers", "is_show_line_numbers_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled"); @@ -4991,6 +5009,7 @@ TextEdit::TextEdit() { auto_brace_completion_enabled = false; brace_matching_enabled = false; highlight_all_occurrences = false; + highlight_current_line = false; indent_using_spaces = false; space_indent = " "; auto_indent = false; diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index 03f412729d..b4b14d0139 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -253,6 +253,7 @@ class TextEdit : public Control { bool scroll_past_end_of_file_enabled; bool auto_brace_completion_enabled; bool brace_matching_enabled; + bool highlight_current_line; bool auto_indent; bool cut_copy_line; bool insert_mode; @@ -514,6 +515,9 @@ public: void set_show_line_numbers(bool p_show); bool is_show_line_numbers_enabled() const; + void set_highlight_current_line(bool p_enabled); + bool is_highlight_current_line_enabled() const; + void set_line_numbers_zero_padded(bool p_zero_padded); void set_show_line_length_guideline(bool p_show); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 931dcfed91..5c6f2b0d01 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -1126,7 +1126,7 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 if (p_item->cells[i].selected && select_mode != SELECT_ROW) { - Rect2i r(item_rect.position, item_rect.size); + Rect2i r(cell_rect.position, cell_rect.size); if (p_item->cells[i].text.size() > 0) { float icon_width = p_item->cells[i].get_icon_size().width; r.position.x += icon_width; diff --git a/scene/gui/viewport_container.cpp b/scene/gui/viewport_container.cpp index c321b873fd..9244d8de2f 100644 --- a/scene/gui/viewport_container.cpp +++ b/scene/gui/viewport_container.cpp @@ -62,6 +62,34 @@ bool ViewportContainer::is_stretch_enabled() const { return stretch; } +void ViewportContainer::set_stretch_shrink(int p_shrink) { + + ERR_FAIL_COND(p_shrink < 1); + if (shrink == p_shrink) + return; + + shrink = p_shrink; + + if (!stretch) + return; + + for (int i = 0; i < get_child_count(); i++) { + + Viewport *c = Object::cast_to<Viewport>(get_child(i)); + if (!c) + continue; + + c->set_size(get_size() / shrink); + } + + update(); +} + +int ViewportContainer::get_stretch_shrink() const { + + return shrink; +} + void ViewportContainer::_notification(int p_what) { if (p_what == NOTIFICATION_RESIZED) { @@ -75,7 +103,7 @@ void ViewportContainer::_notification(int p_what) { if (!c) continue; - c->set_size(get_size()); + c->set_size(get_size() / shrink); } } @@ -115,10 +143,15 @@ void ViewportContainer::_bind_methods() { ClassDB::bind_method(D_METHOD("set_stretch", "enable"), &ViewportContainer::set_stretch); ClassDB::bind_method(D_METHOD("is_stretch_enabled"), &ViewportContainer::is_stretch_enabled); + ClassDB::bind_method(D_METHOD("set_stretch_shrink", "amount"), &ViewportContainer::set_stretch_shrink); + ClassDB::bind_method(D_METHOD("get_stretch_shrink"), &ViewportContainer::get_stretch_shrink); + ADD_PROPERTY(PropertyInfo(Variant::BOOL, "stretch"), "set_stretch", "is_stretch_enabled"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "stretch_shrink"), "set_stretch_shrink", "get_stretch_shrink"); } ViewportContainer::ViewportContainer() { stretch = false; + shrink = 1; } diff --git a/scene/gui/viewport_container.h b/scene/gui/viewport_container.h index 630523b5fb..ebf5869ed9 100644 --- a/scene/gui/viewport_container.h +++ b/scene/gui/viewport_container.h @@ -37,6 +37,7 @@ class ViewportContainer : public Container { GDCLASS(ViewportContainer, Container); bool stretch; + int shrink; protected: void _notification(int p_what); @@ -46,6 +47,9 @@ public: void set_stretch(bool p_enable); bool is_stretch_enabled() const; + void set_stretch_shrink(int p_shrink); + int get_stretch_shrink() const; + virtual Size2 get_minimum_size() const; ViewportContainer(); |