diff options
Diffstat (limited to 'scene/gui')
-rw-r--r-- | scene/gui/line_edit.cpp | 16 | ||||
-rw-r--r-- | scene/gui/line_edit.h | 2 | ||||
-rw-r--r-- | scene/gui/text_edit.cpp | 29 | ||||
-rw-r--r-- | scene/gui/text_edit.h | 2 | ||||
-rw-r--r-- | scene/gui/tree.cpp | 25 | ||||
-rw-r--r-- | scene/gui/tree.h | 4 |
6 files changed, 72 insertions, 6 deletions
diff --git a/scene/gui/line_edit.cpp b/scene/gui/line_edit.cpp index 2b3be1d5c2..11e08b231e 100644 --- a/scene/gui/line_edit.cpp +++ b/scene/gui/line_edit.cpp @@ -946,6 +946,17 @@ void LineEdit::paste_text() { } } +bool LineEdit::has_undo() const { + if (undo_stack_pos == nullptr) { + return undo_stack.size() > 1; + } + return undo_stack_pos != undo_stack.front(); +} + +bool LineEdit::has_redo() const { + return undo_stack_pos != nullptr && undo_stack_pos != undo_stack.back(); +} + void LineEdit::undo() { if (!editable) { return; @@ -2277,6 +2288,11 @@ void LineEdit::_ensure_menu() { menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO); menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_LTR), text_direction == TEXT_DIRECTION_LTR); menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_RTL), text_direction == TEXT_DIRECTION_RTL); + + if (editable) { + menu->set_item_disabled(menu->get_item_index(MENU_UNDO), !has_undo()); + menu->set_item_disabled(menu->get_item_index(MENU_REDO), !has_redo()); + } } LineEdit::LineEdit() { diff --git a/scene/gui/line_edit.h b/scene/gui/line_edit.h index c5c92d60aa..0e9c032e88 100644 --- a/scene/gui/line_edit.h +++ b/scene/gui/line_edit.h @@ -285,6 +285,8 @@ public: void copy_text(); void cut_text(); void paste_text(); + bool has_undo() const; + bool has_redo() const; void undo(); void redo(); diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index a2c5769947..87f06445ac 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -2963,6 +2963,18 @@ void TextEdit::end_complex_operation() { undo_stack.back()->get().chain_backward = true; } +bool TextEdit::has_undo() const { + if (undo_stack_pos == nullptr) { + int pending = current_op.type == TextOperation::TYPE_NONE ? 0 : 1; + return undo_stack.size() + pending > 0; + } + return undo_stack_pos != undo_stack.front(); +} + +bool TextEdit::has_redo() const { + return undo_stack_pos != nullptr; +} + void TextEdit::undo() { if (!editable) { return; @@ -4482,6 +4494,8 @@ void TextEdit::_bind_methods() { ClassDB::bind_method(D_METHOD("begin_complex_operation"), &TextEdit::begin_complex_operation); ClassDB::bind_method(D_METHOD("end_complex_operation"), &TextEdit::end_complex_operation); + ClassDB::bind_method(D_METHOD("has_undo"), &TextEdit::has_undo); + ClassDB::bind_method(D_METHOD("has_redo"), &TextEdit::has_redo); ClassDB::bind_method(D_METHOD("undo"), &TextEdit::undo); ClassDB::bind_method(D_METHOD("redo"), &TextEdit::redo); ClassDB::bind_method(D_METHOD("clear_undo_history"), &TextEdit::clear_undo_history); @@ -4906,6 +4920,11 @@ void TextEdit::_backspace() { return; } + if (has_selection()) { + delete_selection(); + return; + } + int cc = get_caret_column(); int cl = get_caret_line(); @@ -4913,11 +4932,6 @@ void TextEdit::_backspace() { return; } - if (has_selection()) { - delete_selection(); - return; - } - int prev_line = cc ? cl : cl - 1; int prev_column = cc ? (cc - 1) : (text[cl - 1].length()); @@ -5070,6 +5084,11 @@ void TextEdit::_generate_context_menu() { menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_AUTO), text_direction == TEXT_DIRECTION_AUTO); menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_LTR), text_direction == TEXT_DIRECTION_LTR); menu_dir->set_item_checked(menu_dir->get_item_index(MENU_DIR_RTL), text_direction == TEXT_DIRECTION_RTL); + + if (editable) { + menu->set_item_disabled(menu->get_item_index(MENU_UNDO), !has_undo()); + menu->set_item_disabled(menu->get_item_index(MENU_REDO), !has_redo()); + } } int TextEdit::_get_menu_action_accelerator(const String &p_action) { diff --git a/scene/gui/text_edit.h b/scene/gui/text_edit.h index da322a7bcd..69468978ab 100644 --- a/scene/gui/text_edit.h +++ b/scene/gui/text_edit.h @@ -659,6 +659,8 @@ public: void begin_complex_operation(); void end_complex_operation(); + bool has_undo() const; + bool has_redo() const; void undo(); void redo(); void clear_undo_history(); diff --git a/scene/gui/tree.cpp b/scene/gui/tree.cpp index 09db3205d9..d9892b53fc 100644 --- a/scene/gui/tree.cpp +++ b/scene/gui/tree.cpp @@ -167,6 +167,18 @@ TreeItem::TreeCellMode TreeItem::get_cell_mode(int p_column) const { void TreeItem::set_checked(int p_column, bool p_checked) { ERR_FAIL_INDEX(p_column, cells.size()); cells.write[p_column].checked = p_checked; + cells.write[p_column].indeterminate = false; + _changed_notify(p_column); +} + +void TreeItem::set_indeterminate(int p_column, bool p_indeterminate) { + ERR_FAIL_INDEX(p_column, cells.size()); + // Prevent uncheck if indeterminate set to false twice + if (p_indeterminate == cells[p_column].indeterminate) { + return; + } + cells.write[p_column].indeterminate = p_indeterminate; + cells.write[p_column].checked = false; _changed_notify(p_column); } @@ -175,6 +187,11 @@ bool TreeItem::is_checked(int p_column) const { return cells[p_column].checked; } +bool TreeItem::is_indeterminate(int p_column) const { + ERR_FAIL_INDEX_V(p_column, cells.size(), false); + return cells[p_column].indeterminate; +} + void TreeItem::set_text(int p_column, String p_text) { ERR_FAIL_INDEX(p_column, cells.size()); cells.write[p_column].text = p_text; @@ -1042,7 +1059,9 @@ void TreeItem::_bind_methods() { ClassDB::bind_method(D_METHOD("get_cell_mode", "column"), &TreeItem::get_cell_mode); ClassDB::bind_method(D_METHOD("set_checked", "column", "checked"), &TreeItem::set_checked); + ClassDB::bind_method(D_METHOD("set_indeterminate", "column", "indeterminate"), &TreeItem::set_indeterminate); ClassDB::bind_method(D_METHOD("is_checked", "column"), &TreeItem::is_checked); + ClassDB::bind_method(D_METHOD("is_indeterminate", "column"), &TreeItem::is_indeterminate); ClassDB::bind_method(D_METHOD("set_text", "column", "text"), &TreeItem::set_text); ClassDB::bind_method(D_METHOD("get_text", "column"), &TreeItem::get_text); @@ -1228,6 +1247,7 @@ void Tree::update_cache() { cache.checked = get_theme_icon(SNAME("checked")); cache.unchecked = get_theme_icon(SNAME("unchecked")); + cache.indeterminate = get_theme_icon(SNAME("indeterminate")); if (is_layout_rtl()) { cache.arrow_collapsed = get_theme_icon(SNAME("arrow_collapsed_mirrored")); } else { @@ -1721,10 +1741,13 @@ int Tree::draw_item(const Point2i &p_pos, const Point2 &p_draw_ofs, const Size2 case TreeItem::CELL_MODE_CHECK: { Ref<Texture2D> checked = cache.checked; Ref<Texture2D> unchecked = cache.unchecked; + Ref<Texture2D> indeterminate = cache.indeterminate; Point2i check_ofs = item_rect.position; check_ofs.y += Math::floor((real_t)(item_rect.size.y - checked->get_height()) / 2); - if (p_item->cells[i].checked) { + if (p_item->cells[i].indeterminate) { + indeterminate->draw(ci, check_ofs); + } else if (p_item->cells[i].checked) { checked->draw(ci, check_ofs); } else { unchecked->draw(ci, check_ofs); diff --git a/scene/gui/tree.h b/scene/gui/tree.h index be711b4c4f..c207737cc0 100644 --- a/scene/gui/tree.h +++ b/scene/gui/tree.h @@ -82,6 +82,7 @@ private: int icon_max_w = 0; bool expr = false; bool checked = false; + bool indeterminate = false; bool editable = false; bool selected = false; bool selectable = true; @@ -209,7 +210,9 @@ public: /* check mode */ void set_checked(int p_column, bool p_checked); + void set_indeterminate(int p_column, bool p_indeterminate); bool is_checked(int p_column) const; + bool is_indeterminate(int p_column) const; void set_text(int p_column, String p_text); String get_text(int p_column) const; @@ -491,6 +494,7 @@ private: Ref<Texture2D> checked; Ref<Texture2D> unchecked; + Ref<Texture2D> indeterminate; Ref<Texture2D> arrow_collapsed; Ref<Texture2D> arrow; Ref<Texture2D> select_arrow; |