improve picture widget stretchable mode
This commit is contained in:
parent
d7a0d6f7d3
commit
022f7168c0
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
|
class picture;
|
||||||
|
|
||||||
namespace drawerbase
|
namespace drawerbase
|
||||||
{
|
{
|
||||||
namespace picture
|
namespace picture
|
||||||
@ -25,6 +27,7 @@ namespace nana
|
|||||||
|
|
||||||
class drawer : public drawer_trigger
|
class drawer : public drawer_trigger
|
||||||
{
|
{
|
||||||
|
friend class ::nana::picture;
|
||||||
public:
|
public:
|
||||||
drawer();
|
drawer();
|
||||||
~drawer();
|
~drawer();
|
||||||
@ -32,7 +35,7 @@ namespace nana
|
|||||||
private:
|
private:
|
||||||
void refresh(graph_reference) override;
|
void refresh(graph_reference) override;
|
||||||
void _m_draw_background();
|
void _m_draw_background();
|
||||||
public:
|
private:
|
||||||
implement * const impl_;
|
implement * const impl_;
|
||||||
};
|
};
|
||||||
}//end namespace picture
|
}//end namespace picture
|
||||||
@ -47,12 +50,19 @@ namespace nana
|
|||||||
picture(window, bool visible);
|
picture(window, bool visible);
|
||||||
picture(window, const rectangle& ={}, bool visible = true);
|
picture(window, const rectangle& ={}, bool visible = true);
|
||||||
|
|
||||||
void load(nana::paint::image);
|
void load(::nana::paint::image, const rectangle& valid_area = {});
|
||||||
|
|
||||||
|
/// Sets the align of image.
|
||||||
|
void align(align, align_v);
|
||||||
|
|
||||||
|
/// Enables the image to be stretched to the widget size.
|
||||||
void stretchable(unsigned left, unsigned top, unsigned right, unsigned bottom);
|
void stretchable(unsigned left, unsigned top, unsigned right, unsigned bottom);
|
||||||
|
|
||||||
|
/// Enables/disable the image to be stretched without changing aspect ratio.
|
||||||
|
void stretchable(bool);
|
||||||
|
|
||||||
/// Fills a gradual-change color in background. If One of colors is invisible or clr_from is equal to clr_to, it draws background in bgcolor.
|
/// Fills a gradual-change color in background. If One of colors is invisible or clr_from is equal to clr_to, it draws background in bgcolor.
|
||||||
void set_gradual_background(const ::nana::color& clr_from, const ::nana::color& clr_to, bool horizontal);
|
void set_gradual_background(const color& clr_from, const color& clr_to, bool horizontal);
|
||||||
void transparent(bool);
|
void transparent(bool);
|
||||||
bool transparent() const;
|
bool transparent() const;
|
||||||
};
|
};
|
||||||
|
@ -246,6 +246,19 @@ namespace nana
|
|||||||
result_s = ref_s;
|
result_s = ref_s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size fit_zoom(const size& input_s, size ref_s)
|
||||||
|
{
|
||||||
|
double rate_input = double(input_s.width) / double(input_s.height);
|
||||||
|
double rate_ref = double(ref_s.width) / double(ref_s.height);
|
||||||
|
|
||||||
|
if (rate_input < rate_ref)
|
||||||
|
ref_s.width = static_cast<unsigned>(ref_s.height * rate_input);
|
||||||
|
else if (rate_input > rate_ref)
|
||||||
|
ref_s.height = static_cast<unsigned>(ref_s.width / rate_input);
|
||||||
|
|
||||||
|
return ref_s;
|
||||||
|
}
|
||||||
|
|
||||||
void zoom(const rectangle& ref, const rectangle& scaled, const rectangle& ref_dst, rectangle& r)
|
void zoom(const rectangle& ref, const rectangle& scaled, const rectangle& ref_dst, rectangle& r)
|
||||||
{
|
{
|
||||||
double rate_x = (scaled.x - ref.x) / double(ref.width);
|
double rate_x = (scaled.x - ref.x) / double(ref.width);
|
||||||
|
@ -38,7 +38,11 @@ namespace nana
|
|||||||
struct back_image_tag
|
struct back_image_tag
|
||||||
{
|
{
|
||||||
paint::image image;
|
paint::image image;
|
||||||
std::unique_ptr<element::bground> bground;
|
rectangle valid_area;
|
||||||
|
::nana::align align_horz{ ::nana::align::left };
|
||||||
|
::nana::align_v align_vert{ ::nana::align_v::top };
|
||||||
|
std::unique_ptr<element::bground> bground; //If it is not a null ptr, the widget is stretchable mode
|
||||||
|
bool stretchable{ false }; //If it is true, the widget is stretchable mode without changing aspect ratio.
|
||||||
}backimg;
|
}backimg;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -63,13 +67,92 @@ namespace nana
|
|||||||
if (!graph.changed())
|
if (!graph.changed())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!impl_->backimg.bground)
|
auto graphsize = graph.size();
|
||||||
|
|
||||||
|
auto & backimg = impl_->backimg;
|
||||||
|
|
||||||
|
if (!backimg.bground)
|
||||||
{
|
{
|
||||||
_m_draw_background();
|
auto valid_area = backimg.valid_area;
|
||||||
impl_->backimg.image.paste(graph, 0, 0);
|
if (valid_area.empty())
|
||||||
|
valid_area = backimg.image.size();
|
||||||
|
|
||||||
|
if (backimg.stretchable)
|
||||||
|
{
|
||||||
|
auto fit_size = fit_zoom({ valid_area.width, valid_area.height }, graphsize);
|
||||||
|
//::nana::point pos{ int(graphsize.width - fit_size.width), int(graphsize.height - fit_size.height) };
|
||||||
|
::nana::point pos;
|
||||||
|
|
||||||
|
if (fit_size.width != graphsize.width)
|
||||||
|
{
|
||||||
|
switch (backimg.align_horz)
|
||||||
|
{
|
||||||
|
case ::nana::align::left: break;
|
||||||
|
case ::nana::align::center:
|
||||||
|
pos.x = (int(graphsize.width) - int(fit_size.width)) / 2;
|
||||||
|
break;
|
||||||
|
case ::nana::align::right:
|
||||||
|
pos.x = int(graphsize.width) - int(fit_size.width);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (fit_size.height != graphsize.height)
|
||||||
|
{
|
||||||
|
switch (backimg.align_vert)
|
||||||
|
{
|
||||||
|
case ::nana::align_v::top: break;
|
||||||
|
case ::nana::align_v::center:
|
||||||
|
pos.y = (int(graphsize.height) - int(fit_size.height)) / 2;
|
||||||
|
break;
|
||||||
|
case ::nana::align_v::bottom:
|
||||||
|
pos.y = int(graphsize.height) - int(fit_size.height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fit_size.width < graphsize.width || fit_size.height < graphsize.height)
|
||||||
|
_m_draw_background();
|
||||||
|
|
||||||
|
backimg.image.stretch(valid_area, graph, { pos, fit_size });
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//The point in which position the image to be drawn.
|
||||||
|
::nana::point pos;
|
||||||
|
|
||||||
|
switch (backimg.align_horz)
|
||||||
|
{
|
||||||
|
case ::nana::align::left: break;
|
||||||
|
case ::nana::align::center:
|
||||||
|
pos.x = (int(graphsize.width) - int(valid_area.width)) / 2;
|
||||||
|
break;
|
||||||
|
case ::nana::align::right:
|
||||||
|
pos.x = int(graphsize.width) - int(valid_area.width);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (backimg.align_vert)
|
||||||
|
{
|
||||||
|
case ::nana::align_v::top: break;
|
||||||
|
case ::nana::align_v::center:
|
||||||
|
pos.y = (int(graphsize.height) - int(valid_area.height)) / 2;
|
||||||
|
break;
|
||||||
|
case ::nana::align_v::bottom:
|
||||||
|
pos.y = int(graphsize.height) - int(valid_area.height);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (valid_area.width < graphsize.width || valid_area.height < graphsize.height)
|
||||||
|
_m_draw_background();
|
||||||
|
|
||||||
|
backimg.image.paste(valid_area, graph, pos);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
impl_->backimg.bground->draw(graph, {}, {}, graph.size(), element_state::normal);
|
{
|
||||||
|
color invalid_clr_for_call;
|
||||||
|
backimg.bground->draw(graph, invalid_clr_for_call, invalid_clr_for_call, graphsize, element_state::normal);
|
||||||
|
}
|
||||||
|
|
||||||
graph.setsta();
|
graph.setsta();
|
||||||
}
|
}
|
||||||
@ -105,16 +188,40 @@ namespace nana
|
|||||||
create(wd, r, visible);
|
create(wd, r, visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
void picture::load(nana::paint::image img)
|
void picture::load(::nana::paint::image img, const ::nana::rectangle& valid_area)
|
||||||
{
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
auto& backimg = get_drawer_trigger().impl_->backimg;
|
auto& backimg = get_drawer_trigger().impl_->backimg;
|
||||||
backimg.image = std::move(img);
|
backimg.image = std::move(img);
|
||||||
|
backimg.valid_area = valid_area;
|
||||||
|
|
||||||
if (backimg.bground)
|
if (backimg.bground)
|
||||||
backimg.bground->image(backimg.image, true, {});
|
backimg.bground->image(backimg.image, true, valid_area);
|
||||||
|
|
||||||
get_drawer_trigger().impl_->graph_ptr->set_changed();
|
if (handle())
|
||||||
API::refresh_window(*this);
|
{
|
||||||
|
get_drawer_trigger().impl_->graph_ptr->set_changed();
|
||||||
|
API::refresh_window(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void picture::align(::nana::align horz, align_v vert)
|
||||||
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
|
|
||||||
|
auto& backimg = get_drawer_trigger().impl_->backimg;
|
||||||
|
|
||||||
|
if (backimg.align_horz == horz && backimg.align_vert == vert)
|
||||||
|
return;
|
||||||
|
|
||||||
|
backimg.align_horz = horz;
|
||||||
|
backimg.align_vert = vert;
|
||||||
|
|
||||||
|
if (handle())
|
||||||
|
{
|
||||||
|
get_drawer_trigger().impl_->graph_ptr->set_changed();
|
||||||
|
API::refresh_window(*this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void picture::stretchable(unsigned left, unsigned top, unsigned right, unsigned bottom)
|
void picture::stretchable(unsigned left, unsigned top, unsigned right, unsigned bottom)
|
||||||
@ -122,17 +229,37 @@ namespace nana
|
|||||||
if (!handle())
|
if (!handle())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
internal_scope_guard lock;
|
||||||
auto & backimg = get_drawer_trigger().impl_->backimg;
|
auto & backimg = get_drawer_trigger().impl_->backimg;
|
||||||
if (!backimg.bground)
|
if (!backimg.bground)
|
||||||
{
|
{
|
||||||
backimg.bground.reset(new element::bground);
|
backimg.bground.reset(new element::bground);
|
||||||
backimg.bground->states({ element_state::normal });
|
backimg.bground->states({ element_state::normal });
|
||||||
backimg.bground->image(backimg.image, true, {});
|
backimg.bground->image(backimg.image, true, backimg.valid_area);
|
||||||
}
|
}
|
||||||
|
|
||||||
backimg.bground->stretch_parts(left, top, right, bottom);
|
backimg.bground->stretch_parts(left, top, right, bottom);
|
||||||
get_drawer_trigger().impl_->graph_ptr->set_changed();
|
backimg.stretchable = false;
|
||||||
API::refresh_window(*this);
|
if (handle())
|
||||||
|
{
|
||||||
|
get_drawer_trigger().impl_->graph_ptr->set_changed();
|
||||||
|
API::refresh_window(*this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void picture::stretchable(bool enables)
|
||||||
|
{
|
||||||
|
internal_scope_guard lock;
|
||||||
|
|
||||||
|
auto & backimg = get_drawer_trigger().impl_->backimg;
|
||||||
|
backimg.bground.reset();
|
||||||
|
|
||||||
|
backimg.stretchable = enables;
|
||||||
|
if (handle())
|
||||||
|
{
|
||||||
|
get_drawer_trigger().impl_->graph_ptr->set_changed();
|
||||||
|
API::refresh_window(*this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void picture::set_gradual_background(const ::nana::color& from, const ::nana::color& to, bool horizontal)
|
void picture::set_gradual_background(const ::nana::color& from, const ::nana::color& to, bool horizontal)
|
||||||
@ -141,8 +268,11 @@ namespace nana
|
|||||||
bground.gradual_from = from;
|
bground.gradual_from = from;
|
||||||
bground.gradual_to = to;
|
bground.gradual_to = to;
|
||||||
bground.horizontal = horizontal;
|
bground.horizontal = horizontal;
|
||||||
get_drawer_trigger().impl_->graph_ptr->set_changed();
|
if (handle())
|
||||||
API::refresh_window(*this);
|
{
|
||||||
|
get_drawer_trigger().impl_->graph_ptr->set_changed();
|
||||||
|
API::refresh_window(*this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void picture::transparent(bool enabled)
|
void picture::transparent(bool enabled)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user