diff --git a/include/nana/gui/widgets/scroll.hpp b/include/nana/gui/widgets/scroll.hpp index 28ac3326..f09b2046 100644 --- a/include/nana/gui/widgets/scroll.hpp +++ b/include/nana/gui/widgets/scroll.hpp @@ -149,36 +149,35 @@ namespace nana bool make_step(bool forward, unsigned multiple) { - if (graph_) - { - size_type step = (multiple > 1 ? metrics_.step * multiple : metrics_.step); - size_type value = metrics_.value; - if (forward) - { - size_type maxv = metrics_.peak - metrics_.range; - if (metrics_.peak > metrics_.range && value < maxv) - { - if (maxv - value >= step) - value += step; - else - value = maxv; - } - } - else if (value) - { - if (value > step) - value -= step; - else - value = 0; - } - size_type cmpvalue = metrics_.value; - metrics_.value = value; - if (value != cmpvalue) - { - _m_emit_value_changed(); - return true; - } + if (!graph_) return false; + + size_type step = (multiple > 1 ? metrics_.step * multiple : metrics_.step); + size_type value = metrics_.value; + if (forward) + { + size_type maxv = metrics_.peak - metrics_.range; + if (metrics_.peak > metrics_.range && value < maxv) + { + if (maxv - value >= step) + value += step; + else + value = maxv; + } + } + else if (value) + { + if (value > step) + value -= step; + else + value = 0; + } + size_type cmpvalue = metrics_.value; + metrics_.value = value; + if (value != cmpvalue) + { + _m_emit_value_changed(); + return true; } return false; } @@ -334,14 +333,61 @@ namespace nana }//end namespace scroll }//end namespace drawerbase + class scroll_interface + { + public: + using size_type = std::size_t; + + virtual ~scroll_interface() = default; + + /// \brief Determines whether it is scrollable. + /// @param for_less whether it can be scrolled for a less value (backward or "up" if true, forward or "down" if false). + virtual bool scrollable(bool for_less) const = 0; + + /// the whole total (peak) + virtual size_type amount() const = 0; + + virtual void amount(size_type peak) = 0; + + /// Get the range of the widget (how many is shonw on a page, that is, How many to scroll after click on first or second) + virtual size_type range() const = 0; + + /// Set the range of the widget. + virtual void range(size_type r) = 0; + + /// \brief Get the value (current offset calculated from the very beginnig) + /// @return the value. + virtual size_type value() const = 0; + + /// \brief Set the value. + /// @param s a new value. + virtual void value(size_type s) = 0; + + + /// \brief Get the step of the sroll widget. The step indicates a variation of the value. + /// @return the step. + virtual size_type step() const = 0; + + /// \brief Set the step. + /// @param s a value for step. + virtual void step(size_type s) = 0; + + /// \brief Increase/decrease values by a step (alternativelly by some number of steps). + /// @param forward it determines whether increase or decrease. + /// @return true if the value is changed. + virtual bool make_step(bool forward, unsigned steps = 1) = 0; + + virtual window window_handle() const = 0; + }; + /// Provides a way to display an object which is larger than the window's client area. template class scroll // add a widget scheme? - : public widget_object, drawerbase::scroll::scroll_events> + : public widget_object, drawerbase::scroll::scroll_events>, + public scroll_interface { typedef widget_object > base_type; public: - typedef std::size_t size_type; /// \brief The default constructor without creating the widget. scroll(){} @@ -365,59 +411,58 @@ namespace nana /// \brief Determines whether it is scrollable. /// @param for_less whether it can be scrolled for a less value (backward or "up" if true, forward or "down" if false). - bool scrollable(bool for_less) const + bool scrollable(bool for_less) const override { auto & m = this->get_drawer_trigger().metrics(); return (for_less ? (0 != m.value) : (m.value < m.peak - m.range)); } /// the whole total (peak) - size_type amount() const + size_type amount() const override { return this->get_drawer_trigger().metrics().peak; } - void amount(size_type Max) + void amount(size_type peak) override { - return this->get_drawer_trigger().peak(Max); + return this->get_drawer_trigger().peak(peak); } /// Get the range of the widget (how many is shonw on a page, that is, How many to scroll after click on first or second) - size_type range() const + size_type range() const override { return this->get_drawer_trigger().metrics().range; } /// Set the range of the widget. - void range(size_type r) + void range(size_type r) override { return this->get_drawer_trigger().range(r); } /// \brief Get the value (current offset calculated from the very beginnig) /// @return the value. - size_type value() const + size_type value() const override { return this->get_drawer_trigger().metrics().value; } /// \brief Set the value. /// @param s a new value. - void value(size_type s) + void value(size_type s) override { return this->get_drawer_trigger().value(s); } - /// \brief Get the step of the sroll widget. The step indicates a variation of the value. /// @return the step. - size_type step() const + size_type step() const override { return this->get_drawer_trigger().metrics().step; } /// \brief Set the step. /// @param s a value for step. - void step(size_type s) + void step(size_type s) override { return this->get_drawer_trigger().step(s); } @@ -425,7 +470,7 @@ namespace nana /// \brief Increase/decrease values by a step (alternativelly by some number of steps). /// @param forward it determines whether increase or decrease. /// @return true if the value is changed. - bool make_step(bool forward, unsigned steps = 1) + bool make_step(bool forward, unsigned steps = 1) override { if (this->get_drawer_trigger().make_step(forward, steps)) { @@ -435,6 +480,11 @@ namespace nana return false; } + window window_handle() const override + { + return this->handle(); + } + /// \brief Increase/decrease values by steps as if it is scrolled through mouse wheel. /// @param forward it determines whether increase or decrease. /// @return true if the vlaue is changed. diff --git a/include/nana/gui/widgets/textbox.hpp b/include/nana/gui/widgets/textbox.hpp index 16236081..f0d8ff02 100644 --- a/include/nana/gui/widgets/textbox.hpp +++ b/include/nana/gui/widgets/textbox.hpp @@ -132,7 +132,7 @@ namespace nana /// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter. /// @param generator generates text for identing a line. If it is empty, textbox indents the line according to last line. - void enable_indent(bool, std::function generator = {}); + textbox& indention(bool, std::function generator = {}); //A workaround for reset, explicit default constructor syntax, because VC2013 incorrectly treats {} as {0}. textbox& reset(nana::string = nana::string()); ///< discard the old text and set a new text @@ -153,8 +153,12 @@ namespace nana bool getline(std::size_t pos, nana::string&) const; /// Gets the caret position + /// Returns true if the caret is in the area of display, false otherwise. bool caret_pos(point& pos, bool text_coordinate) const; + /// Sets the caret position with a text position + textbox& caret_pos(const upoint&); + /// Appends an string. If `at_caret` is `true`, the string is inserted at the position of caret, otherwise, it is appended at end of the textbox. textbox& append(const nana::string& text, bool at_caret); diff --git a/source/gui/widgets/textbox.cpp b/source/gui/widgets/textbox.cpp index 10e07bd7..31602540 100644 --- a/source/gui/widgets/textbox.cpp +++ b/source/gui/widgets/textbox.cpp @@ -249,12 +249,13 @@ namespace drawerbase { /// Enables/disables the textbox to indent a line. Idents a new line when it is created by pressing enter. /// @param generator generates text for identing a line. If it is empty, textbox indents the line according to last line. - void textbox::enable_indent(bool enb, std::function generator) + textbox& textbox::indention(bool enb, std::function generator) { internal_scope_guard lock; auto editor = get_drawer_trigger().editor(); if (editor) editor->indent(enb, generator); + return *this; } textbox& textbox::reset(nana::string str) @@ -314,8 +315,10 @@ namespace drawerbase { /// Gets the caret position bool textbox::caret_pos(point& pos, bool text_coordinate) const { - internal_scope_guard lock; auto editor = get_drawer_trigger().editor(); + internal_scope_guard lock; + if (!editor) + return false; auto scr_pos = editor->caret_screen_pos(); @@ -331,6 +334,16 @@ namespace drawerbase { return editor->hit_text_area(scr_pos); } + textbox& textbox::caret_pos(const upoint& pos) + { + auto editor = get_drawer_trigger().editor(); + internal_scope_guard lock; + if (editor) + editor->move_caret(pos); + + return *this; + } + textbox& textbox::append(const nana::string& text, bool at_caret) { internal_scope_guard lock;