776 lines
18 KiB
C++
776 lines
18 KiB
C++
|
|
#include <nana/gui/widgets/slider.hpp>
|
|
|
|
namespace nana
|
|
{
|
|
arg_slider::arg_slider(slider& wdg)
|
|
: widget(wdg)
|
|
{}
|
|
|
|
namespace drawerbase
|
|
{
|
|
namespace slider
|
|
{
|
|
|
|
class interior_renderer
|
|
: public renderer
|
|
{
|
|
private:
|
|
virtual void background(window wd, graph_reference graph, bool isglass)
|
|
{
|
|
if(!isglass)
|
|
graph.rectangle(true, API::bgcolor(wd));
|
|
}
|
|
|
|
virtual void bar(window, graph_reference graph, const bar_t& bi)
|
|
{
|
|
//draw border
|
|
::nana::color lt(0x83, 0x90, 0x97), rb(0x9d,0xae,0xc2);
|
|
graph.frame_rectangle(bi.r, lt, lt, rb, rb);
|
|
}
|
|
|
|
virtual void adorn(window, graph_reference graph, const adorn_t& ad)
|
|
{
|
|
auto len = static_cast<const unsigned>(ad.bound.y - ad.bound.x);
|
|
const auto upperblock = ad.block - ad.block / 2;
|
|
|
|
::nana::color clr_from(0x84, 0xc5, 0xff), clr_trans(0x0f, 0x41, 0xcd), clr_to(0x6e, 0x96, 0xff);
|
|
if(ad.horizontal)
|
|
{
|
|
graph.gradual_rectangle({ ad.bound.x, ad.fixedpos, len, upperblock }, clr_from, clr_trans, true);
|
|
graph.gradual_rectangle({ ad.bound.x, ad.fixedpos + static_cast<int>(upperblock), len, ad.block - upperblock }, clr_trans, clr_to, true);
|
|
}
|
|
else
|
|
{
|
|
graph.gradual_rectangle({ ad.fixedpos, ad.bound.x, upperblock, len }, clr_from, clr_trans, false);
|
|
graph.gradual_rectangle({ ad.fixedpos + static_cast<int>(upperblock), ad.bound.x, ad.block - upperblock, len }, clr_trans, clr_to, false);
|
|
}
|
|
}
|
|
|
|
virtual void adorn_textbox(window, graph_reference graph, const nana::string& str, const nana::rectangle & r)
|
|
{
|
|
graph.rectangle(r, false, colors::white);
|
|
graph.string({ r.x + 2, r.y + 1 }, str, colors::white);
|
|
}
|
|
|
|
virtual void slider(window, graph_reference graph, const slider_t& s)
|
|
{
|
|
nana::rectangle r{ graph.size() };
|
|
if(s.horizontal)
|
|
{
|
|
r.x = s.pos;
|
|
r.width = s.scale;
|
|
}
|
|
else
|
|
{
|
|
r.y = s.pos;
|
|
r.height = s.scale;
|
|
}
|
|
graph.round_rectangle(r, 3, 3, colors::black, true, static_cast<color_rgb>(0xf0f0f0));
|
|
}
|
|
};
|
|
|
|
class controller
|
|
{
|
|
public:
|
|
enum class style{horizontal, vertical};
|
|
enum class parts{none, bar, slider};
|
|
|
|
typedef drawer_trigger::graph_reference graph_reference;
|
|
|
|
controller()
|
|
{
|
|
other_.wd = nullptr;
|
|
other_.widget = nullptr;
|
|
other_.graph = nullptr;
|
|
|
|
proto_.renderer = pat::cloneable<renderer>(interior_renderer());
|
|
|
|
attr_.skdir = seekdir::bilateral;
|
|
attr_.dir = style::horizontal;
|
|
attr_.vcur = 0;
|
|
attr_.vmax = 10;
|
|
attr_.slider_scale = 8;
|
|
attr_.border = 1;
|
|
attr_.is_draw_adorn = false;
|
|
}
|
|
|
|
void seek(seekdir sd)
|
|
{
|
|
attr_.skdir = sd;
|
|
}
|
|
|
|
window handle() const
|
|
{
|
|
return other_.wd;
|
|
}
|
|
|
|
void attached(nana::slider& wd, graph_reference graph)
|
|
{
|
|
other_.wd = wd.handle();
|
|
other_.widget = &wd;
|
|
|
|
other_.graph = &graph;
|
|
_m_mk_slider_pos_by_value();
|
|
}
|
|
|
|
void detached()
|
|
{
|
|
other_.graph = nullptr;
|
|
}
|
|
|
|
pat::cloneable<renderer>& ext_renderer()
|
|
{
|
|
return proto_.renderer;
|
|
}
|
|
|
|
void ext_renderer(const pat::cloneable<renderer>& rd)
|
|
{
|
|
proto_.renderer = rd;
|
|
}
|
|
|
|
void ext_provider(const pat::cloneable<provider>& pd)
|
|
{
|
|
proto_.provider = pd;
|
|
}
|
|
|
|
void draw()
|
|
{
|
|
if(other_.graph && !other_.graph->size().empty())
|
|
{
|
|
bool is_transparent = (bground_mode::basic == API::effects_bground_mode(other_.wd));
|
|
proto_.renderer->background(other_.wd, *other_.graph, is_transparent);
|
|
_m_draw_objects();
|
|
}
|
|
}
|
|
|
|
void vertical(bool v)
|
|
{
|
|
auto dir = (v ? style::vertical : style::horizontal);
|
|
|
|
if(dir != attr_.dir)
|
|
{
|
|
attr_.dir = dir;
|
|
this->draw();
|
|
}
|
|
}
|
|
|
|
bool vertical() const
|
|
{
|
|
return (style::vertical == attr_.dir);
|
|
}
|
|
|
|
void vmax(unsigned m)
|
|
{
|
|
if(m == 0) m = 1;
|
|
|
|
if(attr_.vmax != m)
|
|
{
|
|
attr_.vmax = m;
|
|
if(attr_.vcur > m)
|
|
{
|
|
attr_.vcur = m;
|
|
_m_emit_value_changed();
|
|
}
|
|
|
|
_m_mk_slider_pos_by_value();
|
|
draw();
|
|
}
|
|
}
|
|
|
|
unsigned vmax() const
|
|
{
|
|
return attr_.vmax;
|
|
}
|
|
|
|
void vcur(unsigned v)
|
|
{
|
|
if(attr_.vmax < v)
|
|
v = attr_.vmax;
|
|
|
|
if(attr_.vcur != v)
|
|
{
|
|
attr_.vcur = v;
|
|
this->_m_mk_slider_pos_by_value();
|
|
draw();
|
|
}
|
|
}
|
|
|
|
unsigned vcur() const
|
|
{
|
|
return static_cast<unsigned>(attr_.vcur);
|
|
}
|
|
|
|
void resize()
|
|
{
|
|
_m_mk_slider_pos_by_value();
|
|
attr_.adorn_pos = attr_.pos;
|
|
}
|
|
|
|
parts seek_where(::nana::point pos) const
|
|
{
|
|
nana::rectangle r = _m_bar_area();
|
|
if(style::vertical == attr_.dir)
|
|
{
|
|
std::swap(pos.x, pos.y);
|
|
std::swap(r.width, r.height);
|
|
}
|
|
|
|
int sdpos = _m_slider_pos();
|
|
if (sdpos <= pos.x && pos.x < sdpos + static_cast<int>(attr_.slider_scale))
|
|
return parts::slider;
|
|
|
|
sdpos = static_cast<int>(attr_.slider_scale) / 2;
|
|
|
|
if (sdpos <= pos.x && pos.x < sdpos + static_cast<int>(r.width))
|
|
{
|
|
if(pos.y < r.y + static_cast<int>(r.height))
|
|
return parts::bar;
|
|
}
|
|
return parts::none;
|
|
}
|
|
|
|
//set_slider_pos
|
|
//move the slider to a position where a mouse click on WhereBar.
|
|
bool set_slider_pos(::nana::point pos)
|
|
{
|
|
if(style::vertical == attr_.dir)
|
|
std::swap(pos.x, pos.y);
|
|
|
|
pos.x -= _m_slider_refpos();
|
|
if(pos.x < 0)
|
|
return false;
|
|
|
|
if(pos.x > static_cast<int>(_m_scale()))
|
|
pos.x = static_cast<int>(_m_scale());
|
|
|
|
double attr_pos = attr_.pos;
|
|
double dx = _m_evaluate_by_seekdir(pos.x);
|
|
|
|
attr_.pos = dx;
|
|
attr_.adorn_pos = dx;
|
|
_m_mk_slider_value_by_pos();
|
|
|
|
return (attr_.pos != attr_pos);
|
|
}
|
|
|
|
void set_slider_refpos(::nana::point pos)
|
|
{
|
|
if(style::vertical == attr_.dir)
|
|
std::swap(pos.x, pos.y);
|
|
|
|
slider_state_.trace = slider_state_.TraceCapture;
|
|
slider_state_.snap_pos = static_cast<int>(attr_.pos);
|
|
slider_state_.refpos = pos;
|
|
API::capture_window(other_.wd, true);
|
|
}
|
|
|
|
bool release_slider()
|
|
{
|
|
if(slider_state_.trace == slider_state_.TraceCapture)
|
|
{
|
|
API::capture_window(other_.wd, false);
|
|
if(other_.wd != API::find_window(API::cursor_position()))
|
|
{
|
|
slider_state_.trace = slider_state_.TraceNone;
|
|
attr_.is_draw_adorn = false;
|
|
}
|
|
else
|
|
slider_state_.trace = slider_state_.TraceOver;
|
|
|
|
_m_mk_slider_value_by_pos();
|
|
_m_mk_slider_pos_by_value();
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool if_trace_slider() const
|
|
{
|
|
return (slider_state_.trace == slider_state_.TraceCapture);
|
|
}
|
|
|
|
bool move_slider(const ::nana::point& pos)
|
|
{
|
|
int mpos = (style::horizontal == attr_.dir ? pos.x : pos.y);
|
|
int adorn_pos = slider_state_.snap_pos + (mpos - slider_state_.refpos.x);
|
|
|
|
if (adorn_pos > 0)
|
|
{
|
|
int scale = static_cast<int>(_m_scale());
|
|
if (adorn_pos > scale)
|
|
adorn_pos = scale;
|
|
}
|
|
else
|
|
adorn_pos = 0;
|
|
|
|
double dstpos = _m_evaluate_by_seekdir(adorn_pos);
|
|
attr_.is_draw_adorn = true;
|
|
|
|
if(dstpos != attr_.pos)
|
|
{
|
|
attr_.pos = dstpos;
|
|
attr_.adorn_pos = dstpos;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool move_adorn(const ::nana::point& pos)
|
|
{
|
|
double xpos = (style::horizontal == attr_.dir ? pos.x : pos.y);
|
|
|
|
xpos -= _m_slider_refpos();
|
|
if(xpos > static_cast<int>(_m_scale()))
|
|
xpos = static_cast<int>(_m_scale());
|
|
|
|
int adorn_pos = static_cast<int>(attr_.adorn_pos);
|
|
xpos = _m_evaluate_by_seekdir(xpos);
|
|
|
|
attr_.adorn_pos = xpos;
|
|
attr_.is_draw_adorn = true;
|
|
|
|
if(slider_state_.trace == slider_state_.TraceNone)
|
|
slider_state_.trace = slider_state_.TraceOver;
|
|
|
|
return (adorn_pos != static_cast<int>(xpos));
|
|
}
|
|
|
|
unsigned move_step(bool forward)
|
|
{
|
|
unsigned cmpvalue = static_cast<unsigned>(attr_.vcur);
|
|
auto value = cmpvalue;
|
|
if(forward)
|
|
{
|
|
if (value)
|
|
--value;
|
|
}
|
|
else if (value < attr_.vmax)
|
|
++value;
|
|
|
|
attr_.vcur = value;
|
|
if (cmpvalue != value)
|
|
{
|
|
_m_mk_slider_pos_by_value();
|
|
draw();
|
|
_m_emit_value_changed();
|
|
}
|
|
|
|
return cmpvalue;
|
|
}
|
|
|
|
unsigned adorn() const
|
|
{
|
|
return _m_value_by_pos(attr_.adorn_pos);
|
|
}
|
|
|
|
bool reset_adorn()
|
|
{
|
|
//Test if the slider is captured, the operation should be ignored. Because the mouse_leave always be generated even through
|
|
//the slider is captured.
|
|
if(slider_state_.trace == slider_state_.TraceCapture && (nana::API::capture_window() == this->other_.wd))
|
|
return false;
|
|
|
|
slider_state_.trace = slider_state_.TraceNone;
|
|
attr_.is_draw_adorn = false;
|
|
if(attr_.adorn_pos != attr_.pos)
|
|
{
|
|
attr_.adorn_pos = attr_.pos;
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
private:
|
|
void _m_emit_value_changed() const
|
|
{
|
|
other_.widget->events().value_changed.emit(::nana::arg_slider{ *other_.widget });
|
|
}
|
|
|
|
nana::rectangle _m_bar_area() const
|
|
{
|
|
auto sz = other_.graph->size();
|
|
nana::rectangle r{ sz };
|
|
if(style::horizontal == attr_.dir)
|
|
{
|
|
r.x = attr_.slider_scale / 2 - attr_.border;
|
|
r.width = (static_cast<int>(sz.width) > (r.x << 1) ? sz.width - (r.x << 1) : 0);
|
|
}
|
|
else
|
|
{
|
|
r.y = attr_.slider_scale / 2 - attr_.border;
|
|
r.height = (static_cast<int>(sz.height) > (r.y << 1) ? sz.height - (r.y << 1) : 0);
|
|
}
|
|
return r;
|
|
}
|
|
|
|
unsigned _m_scale() const
|
|
{
|
|
nana::rectangle r = _m_bar_area();
|
|
return ((style::horizontal == attr_.dir ? r.width : r.height) - attr_.border * 2);
|
|
}
|
|
|
|
double _m_evaluate_by_seekdir(double pos) const
|
|
{
|
|
switch(attr_.skdir)
|
|
{
|
|
case seekdir::backward:
|
|
if(pos < attr_.pos)
|
|
pos = attr_.pos;
|
|
break;
|
|
case seekdir::forward:
|
|
if(pos > attr_.pos)
|
|
pos = attr_.pos;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
int _m_slider_refpos() const
|
|
{
|
|
return static_cast<int>(attr_.slider_scale / 2);
|
|
}
|
|
|
|
int _m_slider_pos() const
|
|
{
|
|
return static_cast<int>(_m_scale() * attr_.vcur / attr_.vmax);
|
|
}
|
|
|
|
void _m_mk_slider_value_by_pos()
|
|
{
|
|
if(_m_scale())
|
|
{
|
|
auto cmpvalue = static_cast<int>(attr_.vcur);
|
|
attr_.vcur = (attr_.pos * attr_.vmax / _m_scale());
|
|
if (cmpvalue != static_cast<int>(attr_.vcur))
|
|
_m_emit_value_changed();
|
|
}
|
|
}
|
|
|
|
void _m_mk_slider_pos_by_value()
|
|
{
|
|
attr_.pos = double(_m_scale()) * attr_.vcur / attr_.vmax;
|
|
|
|
if(slider_state_.trace == slider_state_.TraceNone)
|
|
attr_.adorn_pos = attr_.pos;
|
|
}
|
|
|
|
unsigned _m_value_by_pos(double pos) const
|
|
{
|
|
if(_m_scale())
|
|
return static_cast<unsigned>(pos * attr_.vmax / _m_scale());
|
|
return 0;
|
|
}
|
|
|
|
void _m_draw_objects()
|
|
{
|
|
renderer::bar_t bar;
|
|
|
|
bar.horizontal = (style::horizontal == attr_.dir);
|
|
bar.border_size = attr_.border;
|
|
bar.r = _m_bar_area();
|
|
|
|
if (bar.r.empty())
|
|
return;
|
|
|
|
proto_.renderer->bar(other_.wd, *other_.graph, bar);
|
|
|
|
//adorn
|
|
renderer::adorn_t adorn;
|
|
adorn.horizontal = bar.horizontal;
|
|
adorn.bound.x = (bar.horizontal ? bar.r.x : bar.r.y) + attr_.border;
|
|
adorn.bound.y = adorn.bound.x + static_cast<int>(attr_.adorn_pos);
|
|
adorn.vcur_scale = static_cast<unsigned>(attr_.pos);
|
|
adorn.block = (bar.horizontal ? bar.r.height : bar.r.width) - attr_.border * 2;
|
|
adorn.fixedpos = static_cast<int>((bar.horizontal ? bar.r.y : bar.r.x) + attr_.border);
|
|
|
|
proto_.renderer->adorn(other_.wd, *other_.graph, adorn);
|
|
|
|
_m_draw_slider();
|
|
|
|
//adorn textbox
|
|
if(proto_.provider && attr_.is_draw_adorn)
|
|
{
|
|
unsigned vadorn = _m_value_by_pos(attr_.adorn_pos);
|
|
nana::string str = proto_.provider->adorn_trace(attr_.vmax, vadorn);
|
|
if(str.size())
|
|
{
|
|
nana::size ts = other_.graph->text_extent_size(str);
|
|
ts.width += 6;
|
|
ts.height += 2;
|
|
|
|
int x, y;
|
|
const int room = static_cast<int>(attr_.adorn_pos);
|
|
if(bar.horizontal)
|
|
{
|
|
y = adorn.fixedpos + static_cast<int>(adorn.block - ts.height) / 2;
|
|
x = (room > static_cast<int>(ts.width + 2) ? room - static_cast<int>(ts.width + 2) : room + 2) + _m_slider_refpos();
|
|
}
|
|
else
|
|
{
|
|
x = (other_.graph->width() - ts.width) / 2;
|
|
y = (room > static_cast<int>(ts.height + 2) ? room - static_cast<int>(ts.height + 2) : room + 2) + _m_slider_refpos();
|
|
}
|
|
proto_.renderer->adorn_textbox(other_.wd, *other_.graph, str, {x, y, ts.width, ts.height});
|
|
}
|
|
}
|
|
}
|
|
|
|
void _m_draw_slider()
|
|
{
|
|
renderer::slider_t s;
|
|
s.pos = static_cast<int>(attr_.pos);
|
|
s.horizontal = (style::horizontal == attr_.dir);
|
|
s.scale = attr_.slider_scale;
|
|
s.border = attr_.border;
|
|
proto_.renderer->slider(other_.wd, *other_.graph, s);
|
|
}
|
|
private:
|
|
struct other_tag
|
|
{
|
|
window wd;
|
|
nana::slider * widget;
|
|
paint::graphics * graph;
|
|
}other_;
|
|
|
|
struct prototype_tag
|
|
{
|
|
pat::cloneable<slider::renderer> renderer;
|
|
pat::cloneable<slider::provider> provider;
|
|
}proto_;
|
|
|
|
struct attr_tag
|
|
{
|
|
seekdir skdir;
|
|
style dir;
|
|
unsigned border;
|
|
unsigned vmax;
|
|
double vcur;
|
|
double pos;
|
|
bool is_draw_adorn;
|
|
double adorn_pos;
|
|
unsigned slider_scale;
|
|
}attr_;
|
|
|
|
struct slider_state_tag
|
|
{
|
|
enum t{TraceNone, TraceOver, TraceCapture};
|
|
|
|
t trace; //true if the mouse press on slider.
|
|
int snap_pos;
|
|
nana::point refpos; //a point for slider when the mouse was clicking on slider.
|
|
|
|
slider_state_tag(): trace(TraceNone){}
|
|
}slider_state_;
|
|
};
|
|
|
|
//class trigger
|
|
trigger::trigger()
|
|
: impl_(new controller_t)
|
|
{}
|
|
|
|
trigger::~trigger()
|
|
{
|
|
delete impl_;
|
|
}
|
|
|
|
trigger::controller_t* trigger::ctrl() const
|
|
{
|
|
return impl_;
|
|
}
|
|
|
|
void trigger::attached(widget_reference widget, graph_reference graph)
|
|
{
|
|
impl_->attached(static_cast<nana::slider&>(widget), graph);
|
|
}
|
|
|
|
void trigger::detached()
|
|
{
|
|
impl_->detached();
|
|
}
|
|
|
|
void trigger::refresh(graph_reference)
|
|
{
|
|
impl_->draw();
|
|
}
|
|
|
|
void trigger::mouse_down(graph_reference, const arg_mouse& arg)
|
|
{
|
|
using parts = controller_t::parts;
|
|
auto what = impl_->seek_where(arg.pos);
|
|
if(parts::bar == what || parts::slider == what)
|
|
{
|
|
bool mkdir = impl_->set_slider_pos(arg.pos);
|
|
impl_->set_slider_refpos(arg.pos);
|
|
if(mkdir)
|
|
{
|
|
impl_->draw();
|
|
API::lazy_refresh();
|
|
}
|
|
}
|
|
}
|
|
|
|
void trigger::mouse_up(graph_reference, const arg_mouse&)
|
|
{
|
|
bool mkdraw = impl_->release_slider();
|
|
if(mkdraw)
|
|
{
|
|
impl_->draw();
|
|
API::lazy_refresh();
|
|
}
|
|
}
|
|
|
|
void trigger::mouse_move(graph_reference, const arg_mouse& arg)
|
|
{
|
|
bool mkdraw = false;
|
|
if(impl_->if_trace_slider())
|
|
{
|
|
mkdraw = impl_->move_slider(arg.pos);
|
|
}
|
|
else
|
|
{
|
|
auto what = impl_->seek_where(arg.pos);
|
|
if(controller_t::parts::none != what)
|
|
mkdraw = impl_->move_adorn(arg.pos);
|
|
else
|
|
mkdraw = impl_->reset_adorn();
|
|
}
|
|
|
|
if(mkdraw)
|
|
{
|
|
impl_->draw();
|
|
API::lazy_refresh();
|
|
}
|
|
}
|
|
|
|
void trigger::mouse_leave(graph_reference, const arg_mouse&)
|
|
{
|
|
if(impl_->reset_adorn())
|
|
{
|
|
impl_->draw();
|
|
API::lazy_refresh();
|
|
}
|
|
}
|
|
|
|
void trigger::resized(graph_reference, const arg_resized&)
|
|
{
|
|
impl_->resize();
|
|
impl_->draw();
|
|
API::lazy_refresh();
|
|
}
|
|
//end class trigger
|
|
}//end namespace slider
|
|
}//end namespace drawerbase
|
|
|
|
//class slider
|
|
slider::slider(){}
|
|
|
|
slider::slider(window wd, bool visible)
|
|
{
|
|
create(wd, rectangle(), visible);
|
|
}
|
|
|
|
slider::slider(window wd, const rectangle& r, bool visible)
|
|
{
|
|
create(wd, r, visible);
|
|
}
|
|
|
|
void slider::seek(slider::seekdir sd)
|
|
{
|
|
get_drawer_trigger().ctrl()->seek(sd);
|
|
}
|
|
|
|
void slider::vertical(bool v)
|
|
{
|
|
get_drawer_trigger().ctrl()->vertical(v);
|
|
API::update_window(this->handle());
|
|
}
|
|
|
|
bool slider::vertical() const
|
|
{
|
|
return get_drawer_trigger().ctrl()->vertical();
|
|
}
|
|
|
|
void slider::vmax(unsigned m)
|
|
{
|
|
if(this->handle())
|
|
{
|
|
get_drawer_trigger().ctrl()->vmax(m);
|
|
API::update_window(handle());
|
|
}
|
|
}
|
|
|
|
unsigned slider::vmax() const
|
|
{
|
|
if(handle())
|
|
return get_drawer_trigger().ctrl()->vmax();
|
|
return 0;
|
|
}
|
|
|
|
void slider::value(unsigned v)
|
|
{
|
|
if(handle())
|
|
{
|
|
get_drawer_trigger().ctrl()->vcur(v);
|
|
API::update_window(handle());
|
|
}
|
|
}
|
|
|
|
unsigned slider::value() const
|
|
{
|
|
if(handle())
|
|
return get_drawer_trigger().ctrl()->vcur();
|
|
return 0;
|
|
}
|
|
|
|
unsigned slider::move_step(bool forward)
|
|
{
|
|
if(handle())
|
|
{
|
|
drawerbase::slider::controller* ctrl = this->get_drawer_trigger().ctrl();
|
|
unsigned val = ctrl->move_step(forward);
|
|
if(val != ctrl->vcur())
|
|
API::update_window(handle());
|
|
return val;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
unsigned slider::adorn() const
|
|
{
|
|
if(empty()) return 0;
|
|
return get_drawer_trigger().ctrl()->adorn();
|
|
}
|
|
|
|
pat::cloneable<slider::renderer>& slider::ext_renderer()
|
|
{
|
|
return get_drawer_trigger().ctrl()->ext_renderer();
|
|
}
|
|
|
|
void slider::ext_renderer(const pat::cloneable<slider::renderer>& di)
|
|
{
|
|
get_drawer_trigger().ctrl()->ext_renderer(di);
|
|
}
|
|
|
|
void slider::ext_provider(const pat::cloneable<slider::provider>& pi)
|
|
{
|
|
get_drawer_trigger().ctrl()->ext_provider(pi);
|
|
}
|
|
|
|
void slider::transparent(bool enabled)
|
|
{
|
|
if(enabled)
|
|
API::effects_bground(*this, effects::bground_transparent(0), 0.0);
|
|
else
|
|
API::effects_bground_remove(*this);
|
|
}
|
|
|
|
bool slider::transparent() const
|
|
{
|
|
return (bground_mode::basic == API::effects_bground_mode(*this));
|
|
}
|
|
//end class slider
|
|
}//end namespace nana
|