From 822a762804345a7ac0a9bdd0d67e27ba63a231dc Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 16 Jul 2017 21:42:24 +0800 Subject: [PATCH] fix bug that textbox::caret_pos() doesn't move the caret --- .../gui/widgets/skeletons/text_editor.hpp | 7 ++-- include/nana/gui/widgets/textbox.hpp | 3 ++ source/gui/widgets/skeletons/text_editor.cpp | 38 ++++++++++++++----- source/gui/widgets/textbox.cpp | 10 +++++ 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/include/nana/gui/widgets/skeletons/text_editor.hpp b/include/nana/gui/widgets/skeletons/text_editor.hpp index fbd4d428..9e91712c 100644 --- a/include/nana/gui/widgets/skeletons/text_editor.hpp +++ b/include/nana/gui/widgets/skeletons/text_editor.hpp @@ -149,12 +149,13 @@ namespace nana{ namespace widgets void text(std::wstring, bool end_caret); std::wstring text() const; - /// Sets caret position through text coordinate. + /// Moves the caret at specified position /** * @param pos the text position - * @param reset indicates whether to reset the text position by the pos. If this parameter is true, the text position is set by pos. If the parameter is false, it only moves the UI caret to the specified position. + * @param stay_in_view Indicates whether to adjust the view to make the caret in view. This parameter is ignored if the caret is already in view. + * @return true indicates a refresh is required. */ - bool move_caret(const upoint& pos, bool reset = false); + bool move_caret(upoint pos, bool stay_in_view = false); void move_caret_end(bool update); void reset_caret_pixels() const; void reset_caret(bool stay_in_view = false); diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index 71c23e0d..ad4a1b2f 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -175,6 +175,9 @@ namespace nana /// Returns true if the caret is in the area of display, false otherwise. bool caret_pos(point& pos, bool text_coordinate) const; + /// Gets the caret position, in text coordinate + upoint caret_pos() const; + /// Sets the caret position with a text position textbox& caret_pos(const upoint&); diff --git a/source/gui/widgets/skeletons/text_editor.cpp b/source/gui/widgets/skeletons/text_editor.cpp index fad04de2..038cdf49 100644 --- a/source/gui/widgets/skeletons/text_editor.cpp +++ b/source/gui/widgets/skeletons/text_editor.cpp @@ -234,7 +234,7 @@ namespace nana{ namespace widgets } } - editor_.move_caret(editor_.points_.caret); + editor_.reset_caret(); } }; @@ -302,7 +302,7 @@ namespace nana{ namespace widgets editor_.select_.b = sel_b_; } } - editor_.move_caret(editor_.points_.caret); + editor_.reset_caret(); } private: std::wstring text_; @@ -1273,7 +1273,7 @@ namespace nana{ namespace widgets if (impl_->cview->content_size().empty() || this->attributes_.line_wrapped) _m_reset_content_size(true); - move_caret(points_.caret); + reset_caret(); return true; } @@ -1564,7 +1564,6 @@ namespace nana{ namespace widgets { //no move occurs select(false); - move_caret(_m_coordinate_to_caret(arg.pos)); } @@ -1700,10 +1699,29 @@ namespace nana{ namespace widgets return str; } - bool text_editor::move_caret(const upoint& crtpos, bool reset_caret) + bool text_editor::move_caret(upoint crtpos, bool stay_in_view) { const unsigned line_pixels = line_height(); + if (crtpos != points_.caret) + { + //Check and make the crtpos available + if (crtpos.y < impl_->textbase.lines()) + { + crtpos.x = (std::min)(impl_->textbase.getline(crtpos.y).size(), crtpos.x); + } + else + { + crtpos.y = impl_->textbase.lines(); + if (crtpos.y > 0) + --crtpos.y; + + crtpos.x = impl_->textbase.getline(crtpos.y).size(); + } + + points_.caret = crtpos; + } + //The coordinate of caret auto coord = _m_caret_to_coordinate(crtpos); @@ -1734,9 +1752,11 @@ namespace nana{ namespace widgets caret->position(coord); //Adjust the caret into screen when the caret position is modified by this function - if (reset_caret && (!hit_text_area(coord))) + if (stay_in_view && (!hit_text_area(coord))) { - this->_m_adjust_view(); + if (_m_adjust_view()) + impl_->cview->sync(false); + impl_->try_refresh = sync_graph::refresh; caret->visible(true); return true; @@ -1751,7 +1771,7 @@ namespace nana{ namespace widgets points_.caret.x = static_cast(impl_->textbase.getline(points_.caret.y).size()); if (update) - this->move_caret(points_.caret, false); + this->reset_caret(); } void text_editor::reset_caret_pixels() const @@ -2465,7 +2485,7 @@ namespace nana{ namespace widgets if (stay_in_view && this->_m_adjust_view()) impl_->try_refresh = sync_graph::refresh; - move_caret(points_.caret); + reset_caret(); return points_.caret; } diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index 8343b7ca..3366d84b 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -390,6 +390,16 @@ namespace drawerbase { return editor->hit_text_area(scr_pos); } + upoint textbox::caret_pos() const + { + auto editor = get_drawer_trigger().editor(); + internal_scope_guard lock; + if (editor) + return editor->caret(); + + return{}; + } + textbox& textbox::caret_pos(const upoint& pos) { auto editor = get_drawer_trigger().editor();