new vfit/hfit for place
added fit-content support for button/picture/combox/label
This commit is contained in:
parent
f43d54d7e2
commit
f0dc62cc21
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Combox Implementation
|
* A Combox Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2016 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
|
||||||
@ -68,7 +68,7 @@ namespace nana
|
|||||||
void key_press(graph_reference, const arg_keyboard&) override;
|
void key_press(graph_reference, const arg_keyboard&) override;
|
||||||
void key_char(graph_reference, const arg_keyboard&) override;
|
void key_char(graph_reference, const arg_keyboard&) override;
|
||||||
private:
|
private:
|
||||||
drawer_impl * drawer_;
|
drawer_impl * const drawer_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class item_proxy
|
class item_proxy
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/**
|
/**
|
||||||
* A Picture Implementation
|
* A Picture 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
|
||||||
|
@ -56,7 +56,7 @@ namespace nana
|
|||||||
enum class token
|
enum class token
|
||||||
{
|
{
|
||||||
div_start, div_end, splitter,
|
div_start, div_end, splitter,
|
||||||
identifier, dock, fit, fit_s, vert, grid, number, array, reparray,
|
identifier, dock, fit, hfit, vfit, vert, grid, number, array, reparray,
|
||||||
weight, gap, margin, arrange, variable, repeated, min_px, max_px, left, right, top, bottom, undisplayed, invisible,
|
weight, gap, margin, arrange, variable, repeated, min_px, max_px, left, right, top, bottom, undisplayed, invisible,
|
||||||
collapse, parameters,
|
collapse, parameters,
|
||||||
equal,
|
equal,
|
||||||
@ -249,17 +249,22 @@ namespace nana
|
|||||||
return token::dock;
|
return token::dock;
|
||||||
else if ("fit" == idstr_)
|
else if ("fit" == idstr_)
|
||||||
return token::fit;
|
return token::fit;
|
||||||
else if ("fit_s" == idstr_)
|
|
||||||
return token::fit_s;
|
|
||||||
else if ("vertical" == idstr_ || "vert" == idstr_)
|
else if ("vertical" == idstr_ || "vert" == idstr_)
|
||||||
return token::vert;
|
return token::vert;
|
||||||
else if ("variable" == idstr_ || "repeated" == idstr_)
|
else if ("variable" == idstr_ || "repeated" == idstr_)
|
||||||
return ('v' == idstr_[0] ? token::variable : token::repeated);
|
return ('v' == idstr_[0] ? token::variable : token::repeated);
|
||||||
else if ("arrange" == idstr_ || "gap" == idstr_)
|
else if ("arrange" == idstr_ || "hfit" == idstr_ || "vfit" == idstr_ || "gap" == idstr_)
|
||||||
{
|
{
|
||||||
auto ch = idstr_[0];
|
auto ch = idstr_[0];
|
||||||
_m_attr_reparray();
|
_m_attr_reparray();
|
||||||
return ('a' == ch ? token::arrange : token::gap);
|
switch (ch)
|
||||||
|
{
|
||||||
|
case 'a': return token::arrange;
|
||||||
|
case 'h': return token::hfit;
|
||||||
|
case 'v': return token::vfit;
|
||||||
|
case 'g': return token::gap;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if ("grid" == idstr_ || "margin" == idstr_)
|
else if ("grid" == idstr_ || "margin" == idstr_)
|
||||||
{
|
{
|
||||||
@ -722,7 +727,8 @@ namespace nana
|
|||||||
{
|
{
|
||||||
none, //Doesn't fit the content
|
none, //Doesn't fit the content
|
||||||
both, //Fits both width and height of content
|
both, //Fits both width and height of content
|
||||||
single //Fits only width or height of content
|
horz, //Fits width of content with a specified height
|
||||||
|
vert //Fits height of content with a specified width
|
||||||
};
|
};
|
||||||
|
|
||||||
class place::implement::division
|
class place::implement::division
|
||||||
@ -767,6 +773,7 @@ namespace nana
|
|||||||
std::pair<double, double> calc_weight_floor()
|
std::pair<double, double> calc_weight_floor()
|
||||||
{
|
{
|
||||||
std::pair<double, double> floor;
|
std::pair<double, double> floor;
|
||||||
|
run_.fit_extents.clear();
|
||||||
|
|
||||||
run_.weight_floor = floor;
|
run_.weight_floor = floor;
|
||||||
|
|
||||||
@ -789,8 +796,9 @@ namespace nana
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
auto const vert = (this->div_owner && (this->div_owner->kind_of_division == kind::vertical_arrange));
|
auto const vert_fields = (kind::vertical_arrange == this->kind_of_division);
|
||||||
double& fv = (vert ? floor.second : floor.first);
|
auto const vert_div = (this->div_owner && (kind::vertical_arrange == this->div_owner->kind_of_division));
|
||||||
|
double& fv = (vert_div ? floor.second : floor.first);
|
||||||
|
|
||||||
if((ratio > 0.001) && (fv > 0))
|
if((ratio > 0.001) && (fv > 0))
|
||||||
fv /= ratio;
|
fv /= ratio;
|
||||||
@ -804,34 +812,49 @@ namespace nana
|
|||||||
{
|
{
|
||||||
if (fit_policy::none != this->fit)
|
if (fit_policy::none != this->fit)
|
||||||
{
|
{
|
||||||
unsigned limited_px = 0;
|
|
||||||
bool limit_width = false;
|
|
||||||
|
|
||||||
std::size_t fit_count = 0;
|
std::size_t fit_count = 0;
|
||||||
|
|
||||||
unsigned max_value = 0;
|
unsigned max_value = 0;
|
||||||
|
auto const fit_horz = (fit_policy::vert == this->fit);
|
||||||
|
|
||||||
|
std::size_t pos = 0;
|
||||||
for (auto & elm : this->field->elements)
|
for (auto & elm : this->field->elements)
|
||||||
{
|
{
|
||||||
auto extent = API::content_extent(elm.handle, 0, false);
|
++pos;
|
||||||
|
|
||||||
|
unsigned edge_px = 0;
|
||||||
|
if (fit_policy::both != this->fit)
|
||||||
|
{
|
||||||
|
auto fit_val = this->fit_parameters.at(pos - 1);
|
||||||
|
if (fit_val.empty())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
edge_px = fit_val.integer();
|
||||||
|
}
|
||||||
|
|
||||||
|
auto extent = API::content_extent(elm.handle, edge_px, fit_horz);
|
||||||
if (extent)
|
if (extent)
|
||||||
{
|
{
|
||||||
|
run_.fit_extents[elm.handle] = extent->second;
|
||||||
++fit_count;
|
++fit_count;
|
||||||
if (vert)
|
if (vert_fields)
|
||||||
floor.second += extent->second.height;
|
floor.second += extent->second.height;
|
||||||
else
|
else
|
||||||
floor.first += extent->second.width;
|
floor.first += extent->second.width;
|
||||||
|
|
||||||
max_value = (std::max)(max_value, (vert ? extent->second.width : extent->second.height));
|
max_value = (std::max)(max_value, (vert_fields ? extent->second.width : extent->second.height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (max_value)
|
if (max_value)
|
||||||
{
|
{
|
||||||
if (vert)
|
if (vert_fields)
|
||||||
floor.first = max_value;
|
floor.first = max_value;
|
||||||
else
|
else
|
||||||
floor.second = max_value;
|
floor.second = max_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (fit_count > 1)
|
if (fit_count > 1)
|
||||||
{
|
{
|
||||||
double percent = 0;
|
double percent = 0;
|
||||||
@ -1005,6 +1028,7 @@ namespace nana
|
|||||||
bool display{ true };
|
bool display{ true };
|
||||||
bool visible{ true };
|
bool visible{ true };
|
||||||
fit_policy fit{ fit_policy::none };
|
fit_policy fit{ fit_policy::none };
|
||||||
|
repeated_array fit_parameters; //it is ignored when fit is not fit_policy::horz or fit_policy::vert
|
||||||
::nana::direction dir{::nana::direction::west};
|
::nana::direction dir{::nana::direction::west};
|
||||||
std::string name;
|
std::string name;
|
||||||
std::vector<std::unique_ptr<division>> children;
|
std::vector<std::unique_ptr<division>> children;
|
||||||
@ -1022,6 +1046,7 @@ namespace nana
|
|||||||
struct run_data
|
struct run_data
|
||||||
{
|
{
|
||||||
std::pair<double, double> weight_floor;
|
std::pair<double, double> weight_floor;
|
||||||
|
std::map<window, ::nana::size> fit_extents;
|
||||||
}run_;
|
}run_;
|
||||||
};//end class division
|
};//end class division
|
||||||
|
|
||||||
@ -1069,6 +1094,7 @@ namespace nana
|
|||||||
child_px = adjustable_px;
|
child_px = adjustable_px;
|
||||||
|
|
||||||
child_px = limit_px(child, child_px, area_px);
|
child_px = limit_px(child, child_px, area_px);
|
||||||
|
|
||||||
auto npx = static_cast<unsigned>(child_px);
|
auto npx = static_cast<unsigned>(child_px);
|
||||||
precise_px = child_px - npx;
|
precise_px = child_px - npx;
|
||||||
child_px = npx;
|
child_px = npx;
|
||||||
@ -1109,9 +1135,23 @@ namespace nana
|
|||||||
unsigned px = 0;
|
unsigned px = 0;
|
||||||
|
|
||||||
auto move_r = element_r.result();
|
auto move_r = element_r.result();
|
||||||
if (fit_policy::both == this->fit)
|
if (fit_policy::none != this->fit)
|
||||||
{
|
{
|
||||||
auto extent = API::content_extent(el.handle, 0, false);
|
auto i = run_.fit_extents.find(el.handle);
|
||||||
|
if (run_.fit_extents.end() != i)
|
||||||
|
{
|
||||||
|
move_r.dimension(i->second);
|
||||||
|
|
||||||
|
if (vert)
|
||||||
|
move_r.x += place_parts::differ(area_margined.width, move_r.width) / 2;
|
||||||
|
else
|
||||||
|
move_r.y += place_parts::differ(area_margined.height, move_r.height) / 2;
|
||||||
|
|
||||||
|
px = (vert ? move_r.height : move_r.width);
|
||||||
|
moved = true;
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
auto extent = API::content_extent(el.handle, 0, false); //deprecated
|
||||||
if (extent)
|
if (extent)
|
||||||
{
|
{
|
||||||
move_r.dimension(extent->second);
|
move_r.dimension(extent->second);
|
||||||
@ -1124,6 +1164,7 @@ namespace nana
|
|||||||
px = (vert ? move_r.height : move_r.width);
|
px = (vert ? move_r.height : move_r.width);
|
||||||
moved = true;
|
moved = true;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!moved)
|
if (!moved)
|
||||||
@ -1178,12 +1219,26 @@ namespace nana
|
|||||||
std::pair<unsigned, std::size_t> result;
|
std::pair<unsigned, std::size_t> result;
|
||||||
if (field && (kind_of_division == match_kind))
|
if (field && (kind_of_division == match_kind))
|
||||||
{
|
{
|
||||||
|
auto const vert = (kind_of_division == kind::vertical_arrange);
|
||||||
|
|
||||||
//Calculate fixed and adjustable of elements
|
//Calculate fixed and adjustable of elements
|
||||||
double precise_px = 0;
|
double precise_px = 0;
|
||||||
auto count = field->elements.size();
|
auto count = field->elements.size();
|
||||||
for (decltype(count) i = 0; i < count; ++i)
|
for (decltype(count) i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
auto fa = _m_calc_fa(arrange_.at(i), area_px, precise_px);
|
auto fa = _m_calc_fa(arrange_.at(i), area_px, precise_px);
|
||||||
|
|
||||||
|
//The fit-content element is like a fixed element
|
||||||
|
if (fit_policy::none != this->fit)
|
||||||
|
{
|
||||||
|
auto fi = this->run_.fit_extents.find(field->elements[i].handle);
|
||||||
|
if (this->run_.fit_extents.cend() != fi)
|
||||||
|
{
|
||||||
|
fa.first = (vert ? fi->second.height : fi->second.width);
|
||||||
|
fa.second = 0; //This isn't an adjustable element
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
result.first += fa.first;
|
result.first += fa.first;
|
||||||
result.second += fa.second;
|
result.second += fa.second;
|
||||||
|
|
||||||
@ -2515,6 +2570,7 @@ namespace nana
|
|||||||
std::unique_ptr<division> div;
|
std::unique_ptr<division> div;
|
||||||
token div_type = token::eof;
|
token div_type = token::eof;
|
||||||
auto fit = fit_policy::none;
|
auto fit = fit_policy::none;
|
||||||
|
place_parts::repeated_array fit_parameters;
|
||||||
|
|
||||||
//These variables stand for the new division's attributes
|
//These variables stand for the new division's attributes
|
||||||
std::string name;
|
std::string name;
|
||||||
@ -2542,8 +2598,10 @@ namespace nana
|
|||||||
case token::fit:
|
case token::fit:
|
||||||
fit = fit_policy::both;
|
fit = fit_policy::both;
|
||||||
break;
|
break;
|
||||||
case token::fit_s:
|
case token::hfit:
|
||||||
fit = fit_policy::single;
|
case token::vfit:
|
||||||
|
fit = (token::hfit == tk ? fit_policy::horz : fit_policy::vert);
|
||||||
|
fit_parameters = tknizer.reparray();
|
||||||
break;
|
break;
|
||||||
case token::splitter:
|
case token::splitter:
|
||||||
//Ignore the splitter when there is not a division.
|
//Ignore the splitter when there is not a division.
|
||||||
@ -2809,6 +2867,8 @@ namespace nana
|
|||||||
div->display = !undisplayed;
|
div->display = !undisplayed;
|
||||||
div->visible = !(undisplayed || invisible);
|
div->visible = !(undisplayed || invisible);
|
||||||
div->fit = fit;
|
div->fit = fit;
|
||||||
|
div->fit_parameters = std::move(fit_parameters);
|
||||||
|
|
||||||
return div;
|
return div;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,10 @@ namespace nana{ namespace drawerbase
|
|||||||
|
|
||||||
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
|
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
|
||||||
{
|
{
|
||||||
|
//Button doesn't provide a support of vfit and hfit
|
||||||
|
if (limit_pixels)
|
||||||
|
return{};
|
||||||
|
|
||||||
wchar_t shortkey;
|
wchar_t shortkey;
|
||||||
std::string::size_type shortkey_pos;
|
std::string::size_type shortkey_pos;
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* A Combox Implementation
|
* A Combox Implementation
|
||||||
* Nana C++ Library(http://www.nanapro.org)
|
* Nana C++ Library(http://www.nanapro.org)
|
||||||
* Copyright(C) 2003-2016 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,8 +17,10 @@
|
|||||||
#include <nana/gui/widgets/float_listbox.hpp>
|
#include <nana/gui/widgets/float_listbox.hpp>
|
||||||
#include <nana/gui/widgets/skeletons/text_editor.hpp>
|
#include <nana/gui/widgets/skeletons/text_editor.hpp>
|
||||||
#include <nana/gui/widgets/skeletons/textbase_export_interface.hpp>
|
#include <nana/gui/widgets/skeletons/textbase_export_interface.hpp>
|
||||||
|
#include <nana/gui/detail/widget_content_measurer_interface.hpp>
|
||||||
|
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -80,6 +82,46 @@ namespace nana
|
|||||||
|
|
||||||
class drawer_impl
|
class drawer_impl
|
||||||
{
|
{
|
||||||
|
class content_measurer
|
||||||
|
: public dev::widget_content_measurer_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
content_measurer(drawer_impl* drwimpl)
|
||||||
|
: drw_{ drwimpl }
|
||||||
|
{}
|
||||||
|
|
||||||
|
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
|
||||||
|
{
|
||||||
|
//Button doesn't provide a support of vfit and hfit
|
||||||
|
if (limit_pixels)
|
||||||
|
return{};
|
||||||
|
|
||||||
|
size content_size;
|
||||||
|
for (auto i = 0; i < drw_->the_number_of_options(); ++i)
|
||||||
|
{
|
||||||
|
auto & m = drw_->at(i);
|
||||||
|
auto sz = graph.text_extent_size(m.item_text);
|
||||||
|
|
||||||
|
content_size.width = (std::max)(content_size.width, sz.width);
|
||||||
|
content_size.height = (std::max)(content_size.height, sz.height);
|
||||||
|
}
|
||||||
|
|
||||||
|
return content_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
size extension() const override
|
||||||
|
{
|
||||||
|
auto text_size = drw_->editor()->text_area(false).dimension();
|
||||||
|
auto wdg_size = drw_->widget_ptr()->size();
|
||||||
|
|
||||||
|
return{
|
||||||
|
wdg_size.width > text_size.width ? wdg_size.width - text_size.width : 0,
|
||||||
|
wdg_size.height > text_size.height ? wdg_size.height - text_size.height : 0
|
||||||
|
};
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
drawer_impl* const drw_;
|
||||||
|
};
|
||||||
public:
|
public:
|
||||||
using graph_reference = paint::graphics&;
|
using graph_reference = paint::graphics&;
|
||||||
using widget_reference = widget&;
|
using widget_reference = widget&;
|
||||||
@ -92,6 +134,8 @@ namespace nana
|
|||||||
state_.button_state = element_state::normal;
|
state_.button_state = element_state::normal;
|
||||||
state_.pointer_where = parts::none;
|
state_.pointer_where = parts::none;
|
||||||
state_.lister = nullptr;
|
state_.lister = nullptr;
|
||||||
|
|
||||||
|
measurer_.reset(new content_measurer{this});
|
||||||
}
|
}
|
||||||
|
|
||||||
void renderer(drawerbase::float_listbox::item_renderer* ir)
|
void renderer(drawerbase::float_listbox::item_renderer* ir)
|
||||||
@ -111,6 +155,8 @@ namespace nana
|
|||||||
|
|
||||||
evt_agent_.reset(new event_agent{ static_cast<nana::combox&>(wd) });
|
evt_agent_.reset(new event_agent{ static_cast<nana::combox&>(wd) });
|
||||||
editor_->textbase().set_event_agent(evt_agent_.get());
|
editor_->textbase().set_event_agent(evt_agent_.get());
|
||||||
|
|
||||||
|
API::dev::set_measurer(wd, measurer_.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void detached()
|
void detached()
|
||||||
@ -528,6 +574,8 @@ namespace nana
|
|||||||
unsigned image_pixels_{ 16 };
|
unsigned image_pixels_{ 16 };
|
||||||
widgets::skeletons::text_editor * editor_{ nullptr };
|
widgets::skeletons::text_editor * editor_{ nullptr };
|
||||||
std::unique_ptr<event_agent> evt_agent_;
|
std::unique_ptr<event_agent> evt_agent_;
|
||||||
|
|
||||||
|
std::unique_ptr<content_measurer> measurer_;
|
||||||
struct state_type
|
struct state_type
|
||||||
{
|
{
|
||||||
bool focused;
|
bool focused;
|
||||||
@ -537,188 +585,191 @@ namespace nana
|
|||||||
nana::float_listbox * lister;
|
nana::float_listbox * lister;
|
||||||
std::size_t item_index_before_selection;
|
std::size_t item_index_before_selection;
|
||||||
}state_;
|
}state_;
|
||||||
};
|
|
||||||
|
|
||||||
|
}; //end class drawer_impl
|
||||||
|
|
||||||
|
|
||||||
//class trigger
|
//class trigger
|
||||||
trigger::trigger()
|
trigger::trigger() :
|
||||||
: drawer_(new drawer_impl)
|
drawer_(new drawer_impl)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
trigger::~trigger()
|
trigger::~trigger()
|
||||||
{
|
{
|
||||||
delete drawer_;
|
delete drawer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
drawer_impl& trigger::get_drawer_impl()
|
drawer_impl& trigger::get_drawer_impl()
|
||||||
{
|
{
|
||||||
return *drawer_;
|
return *drawer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
const drawer_impl& trigger::get_drawer_impl() const
|
const drawer_impl& trigger::get_drawer_impl() const
|
||||||
{
|
{
|
||||||
return *drawer_;
|
return *drawer_;
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::attached(widget_reference wdg, graph_reference graph)
|
void trigger::attached(widget_reference wdg, graph_reference graph)
|
||||||
{
|
{
|
||||||
wdg.bgcolor(colors::white);
|
wdg.bgcolor(colors::white);
|
||||||
drawer_->attached(wdg, graph);
|
drawer_->attached(wdg, graph);
|
||||||
|
|
||||||
API::effects_edge_nimbus(wdg, effects::edge_nimbus::active);
|
API::effects_edge_nimbus(wdg, effects::edge_nimbus::active);
|
||||||
API::effects_edge_nimbus(wdg, effects::edge_nimbus::over);
|
API::effects_edge_nimbus(wdg, effects::edge_nimbus::over);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::detached()
|
void trigger::detached()
|
||||||
{
|
{
|
||||||
drawer_->detached();
|
drawer_->detached();
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::refresh(graph_reference)
|
void trigger::refresh(graph_reference)
|
||||||
|
{
|
||||||
|
drawer_->draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::focus(graph_reference, const arg_focus& arg)
|
||||||
|
{
|
||||||
|
drawer_->set_focused(arg.getting);
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
{
|
{
|
||||||
drawer_->draw();
|
drawer_->draw();
|
||||||
|
drawer_->editor()->reset_caret();
|
||||||
|
API::dev::lazy_refresh();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void trigger::focus(graph_reference, const arg_focus& arg)
|
void trigger::mouse_enter(graph_reference, const arg_mouse&)
|
||||||
|
{
|
||||||
|
drawer_->set_button_state(element_state::hovered, true);
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
{
|
{
|
||||||
drawer_->set_focused(arg.getting);
|
drawer_->draw();
|
||||||
if(drawer_->widget_ptr()->enabled())
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::mouse_leave(graph_reference, const arg_mouse&)
|
||||||
|
{
|
||||||
|
drawer_->set_button_state(element_state::normal, true);
|
||||||
|
drawer_->editor()->mouse_enter(false);
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
|
{
|
||||||
|
drawer_->draw();
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::mouse_down(graph_reference, const arg_mouse& arg)
|
||||||
|
{
|
||||||
|
//drawer_->set_mouse_press(true);
|
||||||
|
drawer_->set_button_state(element_state::pressed, false);
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
|
{
|
||||||
|
auto * editor = drawer_->editor();
|
||||||
|
editor->mouse_pressed(arg);
|
||||||
|
drawer_->open_lister_if_push_button_positioned();
|
||||||
|
|
||||||
|
drawer_->draw();
|
||||||
|
if(editor->attr().editable)
|
||||||
|
editor->reset_caret();
|
||||||
|
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::mouse_up(graph_reference, const arg_mouse& arg)
|
||||||
|
{
|
||||||
|
if (drawer_->widget_ptr()->enabled() && !drawer_->has_lister())
|
||||||
|
{
|
||||||
|
drawer_->editor()->mouse_pressed(arg);
|
||||||
|
drawer_->set_button_state(element_state::hovered, false);
|
||||||
|
drawer_->draw();
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
|
||||||
|
{
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
|
{
|
||||||
|
bool redraw = drawer_->calc_where(graph, arg.pos.x, arg.pos.y);
|
||||||
|
redraw |= drawer_->editor()->mouse_move(arg.left_button, arg.pos);
|
||||||
|
|
||||||
|
if(redraw)
|
||||||
{
|
{
|
||||||
drawer_->draw();
|
drawer_->draw();
|
||||||
drawer_->editor()->reset_caret();
|
drawer_->editor()->reset_caret();
|
||||||
API::dev::lazy_refresh();
|
API::dev::lazy_refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void trigger::mouse_enter(graph_reference, const arg_mouse&)
|
void trigger::mouse_wheel(graph_reference, const arg_wheel& arg)
|
||||||
|
{
|
||||||
|
if(drawer_->widget_ptr()->enabled())
|
||||||
{
|
{
|
||||||
drawer_->set_button_state(element_state::hovered, true);
|
if(drawer_->has_lister())
|
||||||
if(drawer_->widget_ptr()->enabled())
|
drawer_->scroll_items(arg.upwards);
|
||||||
{
|
|
||||||
drawer_->draw();
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::mouse_leave(graph_reference, const arg_mouse&)
|
|
||||||
{
|
|
||||||
drawer_->set_button_state(element_state::normal, true);
|
|
||||||
drawer_->editor()->mouse_enter(false);
|
|
||||||
if(drawer_->widget_ptr()->enabled())
|
|
||||||
{
|
|
||||||
drawer_->draw();
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::mouse_down(graph_reference, const arg_mouse& arg)
|
|
||||||
{
|
|
||||||
//drawer_->set_mouse_press(true);
|
|
||||||
drawer_->set_button_state(element_state::pressed, false);
|
|
||||||
if(drawer_->widget_ptr()->enabled())
|
|
||||||
{
|
|
||||||
auto * editor = drawer_->editor();
|
|
||||||
editor->mouse_pressed(arg);
|
|
||||||
drawer_->open_lister_if_push_button_positioned();
|
|
||||||
|
|
||||||
drawer_->draw();
|
|
||||||
if(editor->attr().editable)
|
|
||||||
editor->reset_caret();
|
|
||||||
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::mouse_up(graph_reference, const arg_mouse& arg)
|
|
||||||
{
|
|
||||||
if (drawer_->widget_ptr()->enabled() && !drawer_->has_lister())
|
|
||||||
{
|
|
||||||
drawer_->editor()->mouse_pressed(arg);
|
|
||||||
drawer_->set_button_state(element_state::hovered, false);
|
|
||||||
drawer_->draw();
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::mouse_move(graph_reference graph, const arg_mouse& arg)
|
|
||||||
{
|
|
||||||
if(drawer_->widget_ptr()->enabled())
|
|
||||||
{
|
|
||||||
bool redraw = drawer_->calc_where(graph, arg.pos.x, arg.pos.y);
|
|
||||||
redraw |= drawer_->editor()->mouse_move(arg.left_button, arg.pos);
|
|
||||||
|
|
||||||
if(redraw)
|
|
||||||
{
|
|
||||||
drawer_->draw();
|
|
||||||
drawer_->editor()->reset_caret();
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::mouse_wheel(graph_reference, const arg_wheel& arg)
|
|
||||||
{
|
|
||||||
if(drawer_->widget_ptr()->enabled())
|
|
||||||
{
|
|
||||||
if(drawer_->has_lister())
|
|
||||||
drawer_->scroll_items(arg.upwards);
|
|
||||||
else
|
|
||||||
drawer_->move_items(arg.upwards, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void trigger::key_press(graph_reference, const arg_keyboard& arg)
|
|
||||||
{
|
|
||||||
if(!drawer_->widget_ptr()->enabled())
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool call_other_keys = false;
|
|
||||||
if(drawer_->editable())
|
|
||||||
{
|
|
||||||
bool is_move_up = false;
|
|
||||||
switch(arg.key)
|
|
||||||
{
|
|
||||||
case keyboard::os_arrow_left:
|
|
||||||
case keyboard::os_arrow_right:
|
|
||||||
drawer_->editor()->respond_key(arg);
|
|
||||||
drawer_->editor()->reset_caret();
|
|
||||||
break;
|
|
||||||
case keyboard::os_arrow_up:
|
|
||||||
is_move_up = true;
|
|
||||||
case keyboard::os_arrow_down:
|
|
||||||
drawer_->move_items(is_move_up, true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
call_other_keys = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
drawer_->move_items(arg.upwards, false);
|
||||||
bool is_move_up = false;
|
|
||||||
switch(arg.key)
|
|
||||||
{
|
|
||||||
case keyboard::os_arrow_left:
|
|
||||||
case keyboard::os_arrow_up:
|
|
||||||
is_move_up = true;
|
|
||||||
case keyboard::os_arrow_right:
|
|
||||||
case keyboard::os_arrow_down:
|
|
||||||
drawer_->move_items(is_move_up, true);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
call_other_keys = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (call_other_keys)
|
|
||||||
drawer_->editor()->respond_key(arg);
|
|
||||||
|
|
||||||
API::dev::lazy_refresh();
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void trigger::key_char(graph_reference, const arg_keyboard& arg)
|
void trigger::key_press(graph_reference, const arg_keyboard& arg)
|
||||||
|
{
|
||||||
|
if(!drawer_->widget_ptr()->enabled())
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool call_other_keys = false;
|
||||||
|
if(drawer_->editable())
|
||||||
{
|
{
|
||||||
if (drawer_->editor()->respond_char(arg))
|
bool is_move_up = false;
|
||||||
API::dev::lazy_refresh();
|
switch(arg.key)
|
||||||
|
{
|
||||||
|
case keyboard::os_arrow_left:
|
||||||
|
case keyboard::os_arrow_right:
|
||||||
|
drawer_->editor()->respond_key(arg);
|
||||||
|
drawer_->editor()->reset_caret();
|
||||||
|
break;
|
||||||
|
case keyboard::os_arrow_up:
|
||||||
|
is_move_up = true;
|
||||||
|
case keyboard::os_arrow_down:
|
||||||
|
drawer_->move_items(is_move_up, true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
call_other_keys = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bool is_move_up = false;
|
||||||
|
switch(arg.key)
|
||||||
|
{
|
||||||
|
case keyboard::os_arrow_left:
|
||||||
|
case keyboard::os_arrow_up:
|
||||||
|
is_move_up = true;
|
||||||
|
case keyboard::os_arrow_right:
|
||||||
|
case keyboard::os_arrow_down:
|
||||||
|
drawer_->move_items(is_move_up, true);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
call_other_keys = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (call_other_keys)
|
||||||
|
drawer_->editor()->respond_key(arg);
|
||||||
|
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
|
|
||||||
|
void trigger::key_char(graph_reference, const arg_keyboard& arg)
|
||||||
|
{
|
||||||
|
if (drawer_->editor()->respond_char(arg))
|
||||||
|
API::dev::lazy_refresh();
|
||||||
|
}
|
||||||
//end class trigger
|
//end class trigger
|
||||||
|
|
||||||
//class item_proxy
|
//class item_proxy
|
||||||
|
@ -184,10 +184,10 @@ namespace nana
|
|||||||
rs.text_align = th;
|
rs.text_align = th;
|
||||||
rs.text_align_v = tv;
|
rs.text_align_v = tv;
|
||||||
|
|
||||||
for(auto i = dstream_.begin(), end = dstream_.end(); i != end; ++i)
|
for(auto & line: dstream_)
|
||||||
{
|
{
|
||||||
rs.pixels.clear();
|
rs.pixels.clear();
|
||||||
unsigned w = _m_line_pixels(*i, def_line_pixels, rs);
|
unsigned w = _m_line_pixels(line, def_line_pixels, rs);
|
||||||
|
|
||||||
if(limited && (w > limited))
|
if(limited && (w > limited))
|
||||||
w = limited;
|
w = limited;
|
||||||
@ -366,7 +366,8 @@ namespace nana
|
|||||||
sz.height = max_ascent + max_descent;
|
sz.height = max_ascent + max_descent;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(w + sz.width <= rs.allowed_width)
|
//Check if the content is displayed in a new line.
|
||||||
|
if((0 == rs.allowed_width) || (w + sz.width <= rs.allowed_width))
|
||||||
{
|
{
|
||||||
w += sz.width;
|
w += sz.width;
|
||||||
|
|
||||||
@ -620,7 +621,7 @@ namespace nana
|
|||||||
|
|
||||||
widget * wd{nullptr};
|
widget * wd{nullptr};
|
||||||
paint::graphics * graph{nullptr};
|
paint::graphics * graph{nullptr};
|
||||||
class measurer * measurer{ nullptr };
|
std::unique_ptr<measurer> msr_ptr{ nullptr };
|
||||||
|
|
||||||
align text_align{align::left};
|
align text_align{align::left};
|
||||||
align_v text_align_v;
|
align_v text_align_v;
|
||||||
@ -657,9 +658,10 @@ namespace nana
|
|||||||
|
|
||||||
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
|
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
|
||||||
{
|
{
|
||||||
if (graph)
|
//Label now doesn't support to measure content with a specified height.
|
||||||
|
if (graph && ((0 == limit_pixels) || limit_width))
|
||||||
{
|
{
|
||||||
|
return impl_->renderer.measure(graph, limit_pixels, impl_->text_align, impl_->text_align_v);
|
||||||
}
|
}
|
||||||
return{};
|
return{};
|
||||||
}
|
}
|
||||||
@ -674,7 +676,9 @@ namespace nana
|
|||||||
|
|
||||||
trigger::trigger()
|
trigger::trigger()
|
||||||
:impl_(new implement)
|
:impl_(new implement)
|
||||||
{}
|
{
|
||||||
|
impl_->msr_ptr.reset(new trigger::implement::measurer{impl_});
|
||||||
|
}
|
||||||
|
|
||||||
trigger::~trigger()
|
trigger::~trigger()
|
||||||
{
|
{
|
||||||
@ -690,6 +694,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
impl_->graph = &graph;
|
impl_->graph = &graph;
|
||||||
impl_->wd = &widget;
|
impl_->wd = &widget;
|
||||||
|
API::dev::set_measurer(widget, impl_->msr_ptr.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void trigger::mouse_move(graph_reference, const arg_mouse& arg)
|
void trigger::mouse_move(graph_reference, const arg_mouse& arg)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
/*
|
/*
|
||||||
* A Picture Implementation
|
* A Picture 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
|
||||||
@ -16,6 +16,7 @@
|
|||||||
#include <nana/gui/layout_utility.hpp>
|
#include <nana/gui/layout_utility.hpp>
|
||||||
#include <nana/paint/image.hpp>
|
#include <nana/paint/image.hpp>
|
||||||
#include <nana/gui/element.hpp>
|
#include <nana/gui/element.hpp>
|
||||||
|
#include <nana/gui/detail/widget_content_measurer_interface.hpp>
|
||||||
|
|
||||||
namespace nana
|
namespace nana
|
||||||
{
|
{
|
||||||
@ -23,11 +24,13 @@ namespace nana
|
|||||||
{
|
{
|
||||||
namespace picture
|
namespace picture
|
||||||
{
|
{
|
||||||
|
class content_measurer;
|
||||||
|
|
||||||
struct implement
|
struct implement
|
||||||
{
|
{
|
||||||
widget* wdg_ptr{nullptr};
|
widget* wdg_ptr{nullptr};
|
||||||
paint::graphics* graph_ptr{nullptr};
|
paint::graphics* graph_ptr{nullptr};
|
||||||
|
std::unique_ptr<content_measurer> measurer;
|
||||||
|
|
||||||
struct gradual_bground_tag
|
struct gradual_bground_tag
|
||||||
{
|
{
|
||||||
@ -47,9 +50,37 @@ namespace nana
|
|||||||
}backimg;
|
}backimg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class content_measurer
|
||||||
|
: public dev::widget_content_measurer_interface
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
content_measurer(implement* impl)
|
||||||
|
: impl_{impl}
|
||||||
|
{}
|
||||||
|
|
||||||
|
optional<size> measure(graph_reference graph, unsigned limit_pixels, bool limit_width) const override
|
||||||
|
{
|
||||||
|
//Button doesn't provide a support of vfit and hfit
|
||||||
|
if (!limit_pixels)
|
||||||
|
{
|
||||||
|
if (impl_->backimg.valid_area.empty())
|
||||||
|
return impl_->backimg.image.size();
|
||||||
|
}
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
|
||||||
|
size extension() const override
|
||||||
|
{
|
||||||
|
return{};
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
implement* const impl_;
|
||||||
|
};
|
||||||
|
|
||||||
//class drawer
|
//class drawer
|
||||||
drawer::drawer() :impl_(new implement)
|
drawer::drawer() :impl_(new implement)
|
||||||
{
|
{
|
||||||
|
impl_->measurer.reset(new content_measurer{impl_});
|
||||||
}
|
}
|
||||||
|
|
||||||
drawer::~drawer()
|
drawer::~drawer()
|
||||||
@ -61,6 +92,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
impl_->wdg_ptr = &wdg;
|
impl_->wdg_ptr = &wdg;
|
||||||
impl_->graph_ptr = &graph;
|
impl_->graph_ptr = &graph;
|
||||||
|
API::dev::set_measurer(wdg, impl_->measurer.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
void drawer::refresh(graph_reference graph)
|
void drawer::refresh(graph_reference graph)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user