From f943673d3de9739a563061460607393dafe221f0 Mon Sep 17 00:00:00 2001 From: Jinhao Date: Sun, 26 Apr 2015 00:50:28 +0800 Subject: [PATCH] update scroll.hpp --- include/nana/basic_types.hpp | 6 +- include/nana/gui/widgets/listbox.hpp | 1 + include/nana/gui/widgets/scroll.hpp | 81 ++++++------ source/basic_types.cpp | 28 ++-- source/gui/place.cpp | 22 ++-- source/gui/widgets/scroll.cpp | 185 ++++++++++++--------------- 6 files changed, 144 insertions(+), 179 deletions(-) diff --git a/include/nana/basic_types.hpp b/include/nana/basic_types.hpp index 6e129e89..a48d9ece 100644 --- a/include/nana/basic_types.hpp +++ b/include/nana/basic_types.hpp @@ -434,10 +434,10 @@ namespace nana unsigned height; }; - class area_rotator + class rectangle_rotator { public: - area_rotator(bool rotated, const ::nana::rectangle& area); + rectangle_rotator(bool rotated, const ::nana::rectangle& area); int x() const; int & x_ref(); @@ -454,7 +454,7 @@ namespace nana private: bool rotated_; ::nana::rectangle area_; - };//end class area_rotator + };//end class rectangle_rotator enum class arrange { diff --git a/include/nana/gui/widgets/listbox.hpp b/include/nana/gui/widgets/listbox.hpp index 1827a585..1c93bdda 100644 --- a/include/nana/gui/widgets/listbox.hpp +++ b/include/nana/gui/widgets/listbox.hpp @@ -8,6 +8,7 @@ * http://www.boost.org/LICENSE_1_0.txt) * * @file: nana/gui/widgets/listbox.hpp + * @contributors: Ariel Vina-Rodriguez * */ diff --git a/include/nana/gui/widgets/scroll.hpp b/include/nana/gui/widgets/scroll.hpp index 143836e6..39491da6 100644 --- a/include/nana/gui/widgets/scroll.hpp +++ b/include/nana/gui/widgets/scroll.hpp @@ -8,6 +8,7 @@ * http://www.boost.org/LICENSE_1_0.txt) * * @file: nana/gui/widgets/scroll.hpp + * @contributors: Ariel Vina-Rodriguez */ #ifndef NANA_GUI_WIDGET_SCROLL_HPP #define NANA_GUI_WIDGET_SCROLL_HPP @@ -49,7 +50,7 @@ namespace nana struct metrics_type { - using size_type = std::size_t ; + using size_type = std::size_t; size_type peak; ///< the whole total size_type range; ///< how many is shonw on a page, that is, How many to scroll after click on first or second @@ -70,10 +71,10 @@ namespace nana public: struct states { - enum{none, highlight, actived, selected}; + enum{ none, highlight, actived, selected }; }; - typedef nana::paint::graphics& graph_reference; + using graph_reference = paint::graphics&; const static unsigned fixedsize = 16; // make it part of a new "metric" in the widget_scheme drawer(metrics_type& m); @@ -114,7 +115,7 @@ namespace nana void peak(size_type s) { - if(graph_ && (metrics_.peak != s)) + if (graph_ && (metrics_.peak != s)) { metrics_.peak = s; API::refresh_window(widget_->handle()); @@ -123,10 +124,10 @@ namespace nana void value(size_type s) { - if(s + metrics_.range > metrics_.peak) + if (s + metrics_.range > metrics_.peak) s = metrics_.peak - metrics_.range; - if(graph_ && (metrics_.value != s)) + if (graph_ && (metrics_.value != s)) { metrics_.value = s; _m_emit_value_changed(); @@ -137,7 +138,7 @@ namespace nana void range(size_type s) { - if(graph_ && (metrics_.range != s)) + if (graph_ && (metrics_.range != s)) { metrics_.range = s; API::refresh_window(widget_->handle()); @@ -151,31 +152,31 @@ namespace nana bool make_step(bool forward, unsigned multiple) { - if(graph_) + if (graph_) { size_type step = (multiple > 1 ? metrics_.step * multiple : metrics_.step); size_type value = metrics_.value; - if(forward) + if (forward) { size_type maxv = metrics_.peak - metrics_.range; - if(metrics_.peak > metrics_.range && value < maxv) + if (metrics_.peak > metrics_.range && value < maxv) { - if(maxv - value >= step) + if (maxv - value >= step) value += step; else value = maxv; } } - else if(value) + else if (value) { - if(value > step) + if (value > step) value -= step; else value = 0; } size_type cmpvalue = metrics_.value; metrics_.value = value; - if(value != cmpvalue) + if (value != cmpvalue) { _m_emit_value_changed(); return true; @@ -221,24 +222,24 @@ namespace nana void mouse_move(graph_reference graph, const ::nana::arg_mouse& arg) override { bool redraw = false; - if(metrics_.pressed && (metrics_.what == buttons::scroll)) + if (metrics_.pressed && (metrics_.what == buttons::scroll)) { size_type cmpvalue = metrics_.value; drawer_.scroll_delta_pos(graph, (Vertical ? arg.pos.y : arg.pos.x)); - if(cmpvalue != metrics_.value) + if (cmpvalue != metrics_.value) _m_emit_value_changed(); redraw = true; } else { buttons what = drawer_.what(graph, arg.pos); - if(metrics_.what != what) + if (metrics_.what != what) { redraw = true; metrics_.what = what; } } - if(redraw) + if (redraw) { drawer_.draw(graph, metrics_.what); API::lazy_refresh(); @@ -247,11 +248,11 @@ namespace nana void mouse_down(graph_reference graph, const arg_mouse& arg) override { - if(arg.left_button) + if (arg.left_button) { metrics_.pressed = true; metrics_.what = drawer_.what(graph, arg.pos); - switch(metrics_.what) + switch (metrics_.what) { case buttons::first: case buttons::second: @@ -265,13 +266,13 @@ namespace nana break; case buttons::forward: case buttons::backward: - { - size_type cmpvalue = metrics_.value; - drawer_.auto_scroll(); - if(cmpvalue != metrics_.value) - _m_emit_value_changed(); - } - break; + { + size_type cmpvalue = metrics_.value; + drawer_.auto_scroll(); + if (cmpvalue != metrics_.value) + _m_emit_value_changed(); + } + break; default: //Ignore buttons::none break; } @@ -294,7 +295,7 @@ namespace nana void mouse_leave(graph_reference graph, const arg_mouse&) override { - if(metrics_.pressed) return; + if (metrics_.pressed) return; metrics_.what = buttons::none; drawer_.draw(graph, buttons::none); @@ -303,7 +304,7 @@ namespace nana void mouse_wheel(graph_reference graph, const arg_wheel& arg) override { - if(make_step(arg.upwards == false, 3)) + if (make_step(arg.upwards == false, 3)) { drawer_.draw(graph, metrics_.what); API::lazy_refresh(); @@ -367,7 +368,7 @@ namespace nana auto & m = this->get_drawer_trigger().metrics(); return (for_less ? (0 != m.value) : (m.value < m.peak - m.range)); } - /// the whole total (peak) + /// the whole total (peak) size_type amount() const { return this->get_drawer_trigger().metrics().peak; @@ -422,9 +423,9 @@ 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) { - if(this->get_drawer_trigger().make_step(forward, steps)) + if (this->get_drawer_trigger().make_step(forward, steps)) { API::refresh_window(this->handle()); return true; @@ -437,25 +438,15 @@ namespace nana /// @return true if the vlaue is changed. bool make_scroll(bool forward) { - if(this->get_drawer_trigger().make_step(forward, 3)) // set this 3 in the metrics of the widget scheme ? - { - API::refresh_window(this->handle()); - return true; - } - return false; + return this->make_step(forward, 3); // set this 3 in the metrics of the widget scheme ? } - /// \brief Increase/decrease values by a page as if it is scrolled page up. + /// \brief Increase/decrease values by a page as if it is scrolled page up. /// @param forward it determines whether increase or decrease. /// @return true if the vlaue is changed. bool make_page_scroll(bool forward) { - if(this->get_drawer_trigger().make_step(forward, range()-1)) - { - API::refresh_window(this->handle()); - return true; - } - return false; + return this->make_step(forward, range() - 1); } };//end class scroll diff --git a/source/basic_types.cpp b/source/basic_types.cpp index c2e1a9aa..c8bd2c34 100644 --- a/source/basic_types.cpp +++ b/source/basic_types.cpp @@ -765,65 +765,65 @@ namespace nana } //end struct rectangle - //class area_rotator - area_rotator::area_rotator(bool rotated, const ::nana::rectangle& area) + //class rectangle_rotator + rectangle_rotator::rectangle_rotator(bool rotated, const ::nana::rectangle& area) : rotated_(rotated), area_(area) {} - int area_rotator::x() const + int rectangle_rotator::x() const { return (rotated_ ? area_.y : area_.x); } - int & area_rotator::x_ref() + int & rectangle_rotator::x_ref() { return (rotated_ ? area_.y : area_.x); } - int area_rotator::y() const + int rectangle_rotator::y() const { return (rotated_ ? area_.x : area_.y); } - int & area_rotator::y_ref() + int & rectangle_rotator::y_ref() { return (rotated_ ? area_.x : area_.y); } - unsigned area_rotator::w() const + unsigned rectangle_rotator::w() const { return (rotated_ ? area_.height : area_.width); } - unsigned & area_rotator::w_ref() + unsigned & rectangle_rotator::w_ref() { return (rotated_ ? area_.height : area_.width); } - unsigned area_rotator::h() const + unsigned rectangle_rotator::h() const { return (rotated_ ? area_.width : area_.height); } - unsigned & area_rotator::h_ref() + unsigned & rectangle_rotator::h_ref() { return (rotated_ ? area_.width : area_.height); } - int area_rotator::right() const + int rectangle_rotator::right() const { return (rotated_ ? area_.y + static_cast(area_.height) : area_.x + static_cast(area_.width)); } - int area_rotator::bottom() const + int rectangle_rotator::bottom() const { return (rotated_ ? area_.x + static_cast(area_.width) : area_.y + static_cast(area_.height)); } - const ::nana::rectangle& area_rotator::result() const + const ::nana::rectangle& rectangle_rotator::result() const { return area_; } - //end class area_rotator + //end class rectangle_rotator } diff --git a/source/gui/place.cpp b/source/gui/place.cpp index f3be7d8a..c643993a 100644 --- a/source/gui/place.cpp +++ b/source/gui/place.cpp @@ -985,7 +985,7 @@ namespace nana const bool vert = (kind::arrange != kind_of_division); auto area_margined = margin_area(); - area_rotator area(vert, area_margined); + rectangle_rotator area(vert, area_margined); auto area_px = area.w(); auto fa = _m_fixed_and_adjustable(kind_of_division, area_px); @@ -1001,7 +1001,7 @@ namespace nana if(!child->display) //Ignore the division if the corresponding field is not displayed. continue; - area_rotator child_area(vert, child->field_area); + rectangle_rotator child_area(vert, child->field_area); child_area.x_ref() = static_cast(position); child_area.y_ref() = area.y(); child_area.h_ref() = area.h(); @@ -1591,7 +1591,7 @@ namespace nana return; const bool vert = (::nana::cursor::size_we != splitter_cursor_); - auto area_px = area_rotator(vert, div_owner->margin_area()).w(); + auto area_px = rectangle_rotator(vert, div_owner->margin_area()).w(); int delta = (vert ? splitter_.pos().y - begin_point_.y : splitter_.pos().x - begin_point_.x); int total_pixels = static_cast(left_pixels_ + right_pixels_); @@ -1632,8 +1632,8 @@ namespace nana { const bool vert = (::nana::cursor::size_we != splitter_cursor_); - area_rotator left(vert, leaf_left_->field_area); - area_rotator right(vert, leaf_right_->field_area); + rectangle_rotator left(vert, leaf_left_->field_area); + rectangle_rotator right(vert, leaf_right_->field_area); auto area_px = right.right() - left.x(); auto right_px = static_cast(limit_px(leaf_right_, init_weight_.get_value(area_px), static_cast(area_px))); @@ -1643,7 +1643,7 @@ namespace nana else if (pos > limited_range.right()) pos = limited_range.right(); - area_rotator sp_r(vert, field_area); + nana::rectangle_rotator sp_r(vert, field_area); sp_r.x_ref() = pos; left.w_ref() = static_cast(pos - left.x()); @@ -1659,7 +1659,7 @@ namespace nana leaf_right_->collocate(wd); //Set the leafs' weight - area_rotator area(vert, div_owner->field_area); + rectangle_rotator area(vert, div_owner->field_area); double imd_rate = 100.0 / static_cast(area.w()); leaf_left_->weight.assign_percent(imd_rate * static_cast(left.w())); @@ -1674,14 +1674,14 @@ namespace nana splitter_.move(this->field_area); } private: - area_rotator _m_update_splitter_range() + rectangle_rotator _m_update_splitter_range() { const bool vert = (cursor::size_ns == splitter_cursor_); - area_rotator area(vert, div_owner->margin_area()); + rectangle_rotator area(vert, div_owner->margin_area()); - area_rotator left(vert, leaf_left_->field_area); - area_rotator right(vert, leaf_right_->field_area); + rectangle_rotator left(vert, leaf_left_->field_area); + rectangle_rotator right(vert, leaf_right_->field_area); const int left_base = left.x(), right_base = right.right(); int pos = left_base; diff --git a/source/gui/widgets/scroll.cpp b/source/gui/widgets/scroll.cpp index 32638261..b6d466fb 100644 --- a/source/gui/widgets/scroll.cpp +++ b/source/gui/widgets/scroll.cpp @@ -52,20 +52,11 @@ namespace nana pos = screen_pos.x; } - if(scale >= fixedsize * 2) - { - if(pos < static_cast(fixedsize)) - return buttons::first; - if(pos > static_cast(scale - fixedsize)) - return buttons::second; - } - else - { - if(pos < static_cast(scale / 2)) - return buttons::first; - if(pos > static_cast(scale / 2)) - return buttons::second; - } + const auto bound_pos = static_cast(scale >= fixedsize * 2 ? fixedsize : scale / 2); + if (pos < bound_pos) + return buttons::first; + if (pos > static_cast(scale) - bound_pos) + return buttons::second; if(metrics_.scroll_length) { @@ -100,7 +91,7 @@ namespace nana metrics_.scroll_pos = pos; auto value_max = metrics_.peak - metrics_.range; metrics_.value = pos * value_max / scroll_area; - if(metrics_.value < metrics_.peak - metrics_.range) + if(metrics_.value < value_max) { int selfpos = static_cast(metrics_.value * scroll_area / value_max); int nextpos = static_cast((metrics_.value + 1) * scroll_area / value_max); @@ -115,22 +106,22 @@ namespace nana void drawer::auto_scroll() { - if(_m_check()) + if (!_m_check()) + return; + + if(buttons::forward == metrics_.what) + { //backward + if(metrics_.value <= metrics_.range) + metrics_.value = 0; + else + metrics_.value -= (metrics_.range-1); + } + else if(buttons::backward == metrics_.what) { - if(buttons::forward == metrics_.what) - { //backward - if(metrics_.value <= metrics_.range) - metrics_.value = 0; - else - metrics_.value -= (metrics_.range-1); - } - else if(buttons::backward == metrics_.what) - { - if(metrics_.peak - metrics_.range - metrics_.value <= metrics_.range) - metrics_.value = metrics_.peak - metrics_.range; - else - metrics_.value += (metrics_.range-1); - } + if(metrics_.peak - metrics_.range - metrics_.value <= metrics_.range) + metrics_.value = metrics_.peak - metrics_.range; + else + metrics_.value += (metrics_.range-1); } } @@ -141,26 +132,20 @@ namespace nana _m_background(graph); - ::nana::rectangle r(graph.size()); - if(vertical_) - { - r.y = r.height - fixedsize; - r.height = fixedsize; - } - else - { - r.x = r.width - fixedsize; - r.width = fixedsize; - } + rectangle_rotator r(vertical_, graph.size()); + r.x_ref() = static_cast(r.w() - fixedsize); + r.w_ref() = fixedsize; int state = ((_m_check() == false || what == buttons::none) ? states::none : states::highlight); int moused_state = (_m_check() ? (metrics_.pressed ? states::selected : states::actived) : states::none); + auto result = r.result(); + //draw first - _m_draw_button(graph, { 0, 0, r.width, r.height }, buttons::first, (buttons::first == what ? moused_state : state)); + _m_draw_button(graph, { 0, 0, result.width, result.height }, buttons::first, (buttons::first == what ? moused_state : state)); //draw second - _m_draw_button(graph, r, buttons::second, (buttons::second == what ? moused_state : state)); + _m_draw_button(graph, result, buttons::second, (buttons::second == what ? moused_state : state)); //draw scroll _m_draw_scroll(graph, (buttons::scroll == what ? moused_state : states::highlight)); @@ -171,64 +156,61 @@ namespace nana { graph.rectangle(true, {0xf0, 0xf0, 0xf0}); - if(metrics_.pressed && _m_check()) + if (!metrics_.pressed || !_m_check()) + return; + + nana::rectangle_rotator r(vertical_, graph.size()); + if(metrics_.what == buttons::forward) { - int x = 0, y = 0; - unsigned width = graph.width(), height = graph.height(); - - if(metrics_.what == buttons::forward) - { - *(vertical_ ? &y : &x) = fixedsize; - *(vertical_ ? &height: &width) = metrics_.scroll_pos; - } - else if(buttons::backward == metrics_.what) - { - *(vertical_ ? &y : &x) = static_cast(fixedsize + metrics_.scroll_pos + metrics_.scroll_length); - *(vertical_ ? &height: &width) = static_cast((vertical_ ? graph.height() : graph.width()) - (fixedsize * 2 + metrics_.scroll_pos + metrics_.scroll_length)); - } - else - return; - - if(width && height) - graph.rectangle({ x, y, width, height }, true, {0xDC, 0xDC, 0xDC}); + r.x_ref() = static_cast(fixedsize); + r.w_ref() = metrics_.scroll_pos; } + else if(buttons::backward == metrics_.what) + { + r.x_ref() = static_cast(fixedsize + metrics_.scroll_pos + metrics_.scroll_length); + r.w_ref() = static_cast((vertical_ ? graph.height() : graph.width()) - (fixedsize * 2 + metrics_.scroll_pos + metrics_.scroll_length)); + } + else + return; + + auto result = r.result(); + if (!result.empty()) + graph.rectangle(result, true, static_cast(0xDCDCDC)); } void drawer::_m_button_frame(graph_reference graph, rectangle r, int state) { - if(state) + if (!state) + return; + + ::nana::color clr{0x97, 0x97, 0x97}; //highlight + switch(state) { - ::nana::color clr{0x97, 0x97, 0x97}; //highlight - switch(state) - { - case states::actived: - clr.from_rgb(0x86, 0xD5, 0xFD); break; - case states::selected: - clr.from_rgb(0x3C, 0x7F, 0xB1); break; - } - - graph.rectangle(r, false, clr); - - clr = clr.blend(colors::white, 0.5); - graph.set_color(clr); - - r.pare_off(2); - - if(vertical_) - { - unsigned half = r.width / 2; - graph.rectangle({ r.x + static_cast(r.width - half), r.y, half, r.height }, true); - r.width -= half; - } - else - { - unsigned half = r.height / 2; - graph.rectangle({r.x, r.y + static_cast(r.height - half), r.width, half}, true); - r.height -= half; - } - //graph.shadow_rectangle(x, y, width, height, 0xFFFFFF, color_x, !vertical_); - graph.gradual_rectangle(r, colors::white, clr, !vertical_); + case states::actived: + clr.from_rgb(0x86, 0xD5, 0xFD); break; + case states::selected: + clr.from_rgb(0x3C, 0x7F, 0xB1); break; } + + graph.rectangle(r, false, clr); + + clr = clr.blend(colors::white, 0.5); + graph.set_color(clr); + + r.pare_off(2); + if(vertical_) + { + unsigned half = r.width / 2; + graph.rectangle({ r.x + static_cast(r.width - half), r.y, half, r.height }, true); + r.width -= half; + } + else + { + unsigned half = r.height / 2; + graph.rectangle({r.x, r.y + static_cast(r.height - half), r.width, half}, true); + r.height -= half; + } + graph.gradual_rectangle(r, colors::white, clr, !vertical_); } bool drawer::_m_check() const @@ -271,20 +253,11 @@ namespace nana { if(_m_check()) { - ::nana::rectangle r(graph.size()); + rectangle_rotator r(vertical_, graph.size()); + r.x_ref() = static_cast(fixedsize + metrics_.scroll_pos); + r.w_ref() = static_cast(metrics_.scroll_length); - if(vertical_) - { - r.y = fixedsize + metrics_.scroll_pos; - r.height = static_cast(metrics_.scroll_length); - } - else - { - r.x = fixedsize + metrics_.scroll_pos; - r.width = static_cast(metrics_.scroll_length); - } - - _m_button_frame(graph, r, state); + _m_button_frame(graph, r.result(), state); } }