add progress scheme

This commit is contained in:
Jinhao
2017-08-05 17:05:49 +08:00
parent 18ba5cb2db
commit a2ba2cfaec
2 changed files with 181 additions and 144 deletions

View File

@@ -1,7 +1,7 @@
/** /**
* A Progress Indicator Implementation * A Progress Indicator Implementation
* Nana C++ Library(http://www.nanapro.org) * Nana C++ Library(http://www.nanapro.org)
* Copyright(C) 2003-2015 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@@ -20,42 +20,37 @@ namespace nana
{ {
namespace progress namespace progress
{ {
class trigger: public drawer_trigger struct scheme
: public widget_geometrics
{
scheme();
color_proxy gradient_bgcolor{ colors::button_face_shadow_start };
color_proxy gradient_fgcolor{ static_cast<color_rgb>(0x6FFFA8) };
};
class substance;
class trigger
: public drawer_trigger
{ {
public: public:
unsigned value() const; trigger();
unsigned value(unsigned); ~trigger();
unsigned inc();
unsigned Max() const; substance* progress() const;
unsigned Max(unsigned);
void unknown(bool);
bool unknown() const;
bool stop(bool s = true);
bool stopped() const;
private: private:
void attached(widget_reference, graph_reference) override; void attached(widget_reference, graph_reference) override;
void refresh(graph_reference) override; void refresh(graph_reference) override;
private: private:
void _m_draw_box(graph_reference); substance* const progress_;
void _m_draw_progress(graph_reference); };
bool _m_check_changing(unsigned) const;
private:
static const unsigned border = 2;
widget * widget_{nullptr};
nana::paint::graphics* graph_{nullptr};
unsigned draw_width_{static_cast<unsigned>(-1)};
bool unknown_{false};
bool stop_{false};
unsigned max_{100};
unsigned value_{0};
}; //end class drawer
} }
}//end namespace drawerbase }//end namespace drawerbase
/// \brief A progressbar widget with two styles: know, and unknow amount value (goal). /// \brief A progressbar widget with two styles: know, and unknow amount value (goal).
/// In unknow style the amount is ignored and the bar is scrolled when value change. /// In unknow style the amount is ignored and the bar is scrolled when value change.
class progress class progress
: public widget_object<category::widget_tag, drawerbase::progress::trigger> : public widget_object<category::widget_tag, drawerbase::progress::trigger, ::nana::general_events, drawerbase::progress::scheme>
{ {
public: public:
progress(); progress();
@@ -69,8 +64,6 @@ namespace nana
unsigned amount(unsigned value); unsigned amount(unsigned value);
void unknown(bool); void unknown(bool);
bool unknown() const; bool unknown() const;
bool stop(bool s=true); ///< request stop or cancel and return previus stop status
bool stopped() const;
}; };
}//end namespace nana }//end namespace nana
#endif #endif

View File

@@ -1,6 +1,6 @@
/* /*
* A Progress Indicator Implementation * A Progress Indicator Implementation
* Copyright(C) 2003-2013 Jinhao(cnjinhao@hotmail.com) * Copyright(C) 2003-2017 Jinhao(cnjinhao@hotmail.com)
* *
* Distributed under the Boost Software License, Version 1.0. * Distributed under the Boost Software License, Version 1.0.
* (See accompanying file LICENSE_1_0.txt or copy at * (See accompanying file LICENSE_1_0.txt or copy at
@@ -17,136 +17,187 @@ namespace nana
{ {
namespace progress namespace progress
{ {
//class trigger scheme::scheme()
void trigger::attached(widget_reference wd, graph_reference graph)
{ {
widget_ = &wd; foreground = static_cast<color_rgb>(0x107515);
graph_ = &graph;
} }
unsigned trigger::value() const class substance
{ {
public:
static const unsigned border_px = 1;
void set_widget(widget& wdg)
{
widget_ = static_cast<nana::progress*>(&wdg);
}
nana::progress* widget_ptr() const
{
return widget_;
}
unsigned inc()
{
auto val = value(nullptr) + 1;
return value(&val);
}
unsigned value(const unsigned* value_ptr)
{
//Sets new value if value_ptr is not a nullptr
if (value_ptr)
{
if (unknown_)
value_ += (*value_ptr ? 5 : 0);
else
value_ = (std::min)(max_, *value_ptr);
_m_try_refresh();
}
return value_; return value_;
} }
unsigned trigger::value(unsigned v) void reset_value()
{ {
internal_scope_guard isg; value_ = 0;
if(false == unknown_)
{
if(value_ != v)
value_ = v > max_?max_:v;
}
else
value_ += (v?10:v);
if(_m_check_changing(value_))
{
refresh(*graph_);
API::update_window(widget_->handle());
}
return v;
} }
unsigned trigger::inc() unsigned maximum(const unsigned * value_ptr)
{ {
internal_scope_guard isg; //Sets new maximum if value_ptr is not a nullptr
if(false == unknown_) if (value_ptr)
{ {
if(value_ < max_) max_ = (*value_ptr > 0 ? *value_ptr : 1);
++value_; _m_try_refresh();
} }
else
value_ += 5;
if(_m_check_changing(value_))
API::refresh_window(widget_->handle());
return value_;
}
unsigned trigger::Max() const
{
return max_; return max_;
} }
unsigned trigger::Max(unsigned value) bool unknown(const bool* state_ptr)
{ {
max_ = value; if (state_ptr)
if(max_ == 0) ++max_; {
unknown_ = *state_ptr;
API::refresh_window(widget_->handle()); if (unknown_)
return max_; value_px_ = 0;
else
value_ = (std::min)(value_, max_);
} }
void trigger::unknown(bool enb)
{
unknown_ = enb;
if(enb)
draw_width_ = static_cast<unsigned>(-1);
}
bool trigger::unknown() const
{
return unknown_; return unknown_;
} }
bool trigger::stopped() const
unsigned value_px() const
{ {
return stop_; return value_px_;
} }
bool trigger::stop(bool s) private:
void _m_try_refresh()
{ {
std::swap(s,stop_); if (nullptr == widget_)
return s; return;
auto value_px = (widget_->size().width - border_px * 2) * value_ / max_;
if (value_px != value_px_)
{
value_px_ = value_px;
API::refresh_window(*widget_);
}
}
private:
nana::progress * widget_{ nullptr };
unsigned max_{ 100 };
unsigned value_{ 0 };
unsigned value_px_{ 0 };
bool unknown_{ false };
};
trigger::trigger()
: progress_(new substance)
{}
trigger::~trigger()
{
delete progress_;
}
substance* trigger::progress() const
{
return progress_;
}
void trigger::attached(widget_reference wdg, graph_reference)
{
progress_->set_widget(wdg);
} }
void trigger::refresh(graph_reference graph) void trigger::refresh(graph_reference graph)
{ {
if (false == unknown_) const unsigned border_px = substance::border_px;
draw_width_ = static_cast<unsigned>((graph.width() - border * 2) * (double(value_) / max_));
_m_draw_box(graph); unsigned width = graph.width() - border_px * 2;
_m_draw_progress(graph); unsigned height = graph.height() - border_px * 2;
}
void trigger::_m_draw_box(graph_reference graph) rectangle rt_val{ graph.size() };
rt_val.pare_off(static_cast<int>(border_px));
auto rt_bground = rt_val;
if (false == progress_->unknown(nullptr))
{ {
rectangle r{ graph.size() }; rt_bground.x = static_cast<int>(progress_->value_px()) + static_cast<int>(border_px);
graph.gradual_rectangle(r, colors::button_face_shadow_end, colors::button_face_shadow_start, true); rt_bground.width -= progress_->value_px();
::nana::color lt{ colors::gray }, rb{colors::white};
graph.frame_rectangle(r, lt, lt, rb, rb);
}
void trigger::_m_draw_progress(graph_reference graph) rt_val.width = progress_->value_px();
{
unsigned width = graph.width() - border * 2;
unsigned height = graph.height() - border * 2;
if(false == unknown_)
{
if(draw_width_)
graph.gradual_rectangle({ static_cast<int>(border), static_cast<int>(border), draw_width_, height }, { 0x6F, 0xFF, 0xA8 }, { 0x10, 0x75, 0x15 }, true);
} }
else else
{ {
unsigned block = width / 3; auto const block = width / 3;
int left = (value_ < block ? 0 : value_ - block) + border; auto const value = progress_->value(nullptr);
int right = (value_ >= width - 1 + border? width - 1 + border: value_);
if(right >= left) auto left = (std::max)(0, static_cast<int>(value - block)) + static_cast<int>(border_px);
graph.gradual_rectangle({ left, static_cast<int>(border), static_cast<unsigned>(right - left + 1), height }, { 0x6F, 0xFF, 0xA8 }, { 0x10, 0x75, 0x15 }, true); auto right = static_cast<int>((std::min)(value, width + border_px -1));
if(value_ >= width + block) value_ = 0; if (right > left)
}
}
bool trigger::_m_check_changing(unsigned newvalue) const
{ {
if(graph_) rt_val.x = left;
return (((graph_->width() - border * 2) * newvalue / max_) != draw_width_); rt_val.width = static_cast<unsigned>(right - left + 1);
return false; }
else
rt_val.width = 0;
if (value >= width + block)
progress_->reset_value();
}
auto & sch = progress_->widget_ptr()->scheme();
//Draw the gradient background if gradient_bgcolor is available.
auto bgcolor = sch.background.get_color();
if (bgcolor.invisible())
bgcolor = colors::button_face;
if (sch.gradient_bgcolor.get_color().invisible())
graph.rectangle(rt_bground, true, bgcolor);
else
graph.gradual_rectangle(rt_bground, bgcolor, sch.gradient_bgcolor.get_color(), true);
//Draw the gradient fgcolor if gradient_fgcolor is available.
auto fgcolor = sch.foreground.get_color();
if (fgcolor.invisible())
fgcolor = static_cast<color_rgb>(0x107515);
if (sch.gradient_fgcolor.get_color().invisible())
graph.rectangle(rt_val, true, fgcolor);
else
graph.gradual_rectangle(rt_val, sch.gradient_fgcolor.get_color(), fgcolor, true);
graph.frame_rectangle(rectangle{ graph.size() }, colors::gray, colors::gray, colors::white, colors::white);
} }
//end class drawer
}//end namespace progress }//end namespace progress
}//end namespace drawerbase }//end namespace drawerbase
@@ -165,49 +216,42 @@ namespace nana
unsigned progress::value() const unsigned progress::value() const
{ {
return get_drawer_trigger().value(); return get_drawer_trigger().progress()->value(nullptr);
} }
unsigned progress::value(unsigned val) unsigned progress::value(unsigned val)
{ {
internal_scope_guard isg; internal_scope_guard lock;
if(API::empty_window(this->handle()) == false) if(API::empty_window(this->handle()) == false)
return get_drawer_trigger().value(val); return get_drawer_trigger().progress()->value(&val);
return 0; return 0;
} }
unsigned progress::inc() unsigned progress::inc()
{ {
internal_scope_guard isg; internal_scope_guard lock;
return get_drawer_trigger().inc(); return get_drawer_trigger().progress()->inc();
} }
unsigned progress::amount() const unsigned progress::amount() const
{ {
return get_drawer_trigger().Max(); return get_drawer_trigger().progress()->maximum(nullptr);
} }
unsigned progress::amount(unsigned value) unsigned progress::amount(unsigned value)
{ {
return get_drawer_trigger().Max(value); return get_drawer_trigger().progress()->maximum(&value);
} }
void progress::unknown(bool enb) void progress::unknown(bool enb)
{ {
get_drawer_trigger().unknown(enb); internal_scope_guard lock;
get_drawer_trigger().progress()->unknown(&enb);
} }
bool progress::unknown() const bool progress::unknown() const
{ {
return get_drawer_trigger().unknown(); return get_drawer_trigger().progress()->unknown(nullptr);
}
bool progress::stop(bool s)
{
return get_drawer_trigger().stop(s);
}
bool progress::stopped() const
{
return get_drawer_trigger().stopped();
} }
//end class progress //end class progress
}//end namespace nana }//end namespace nana