diff options
Diffstat (limited to 'scene/gui/line_edit.cpp')
-rw-r--r-- | scene/gui/line_edit.cpp | 111 |
1 files changed, 78 insertions, 33 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; } |