improve place fit when margin is given
This commit is contained in:
parent
58cb215f7b
commit
0511a300d6
@ -807,80 +807,107 @@ namespace nana
|
|||||||
if((ratio > 0.001) && (fv > 0))
|
if((ratio > 0.001) && (fv > 0))
|
||||||
fv /= ratio;
|
fv /= ratio;
|
||||||
|
|
||||||
|
int set_weight = 0;
|
||||||
|
|
||||||
|
if ((fit_policy::none != this->fit) && this->field)
|
||||||
|
{
|
||||||
|
std::size_t fit_count = 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)
|
||||||
|
{
|
||||||
|
++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)
|
||||||
|
{
|
||||||
|
run_.fit_extents[elm.handle] = extent->second;
|
||||||
|
++fit_count;
|
||||||
|
if (vert_fields)
|
||||||
|
floor.second += extent->second.height;
|
||||||
|
else
|
||||||
|
floor.first += extent->second.width;
|
||||||
|
|
||||||
|
max_value = (std::max)(max_value, (vert_fields ? extent->second.width : extent->second.height));
|
||||||
|
|
||||||
|
if (0 == set_weight)
|
||||||
|
set_weight = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
set_weight = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max_value)
|
||||||
|
{
|
||||||
|
if (vert_fields)
|
||||||
|
floor.first = max_value;
|
||||||
|
else
|
||||||
|
floor.second = max_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
//reverse deduction with gap
|
||||||
|
if (fit_count > 1)
|
||||||
|
{
|
||||||
|
double percent = 0;
|
||||||
|
for (std::size_t i = 0; i < fit_count - 1; ++i)
|
||||||
|
{
|
||||||
|
auto gap_value = gap.at(i);
|
||||||
|
if (gap_value.kind_of() == number_t::kind::percent)
|
||||||
|
{
|
||||||
|
percent += gap_value.real();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double precise_px = 0;
|
||||||
|
fv += calc_number(gap_value, 100, 0, precise_px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fv *= (1 + percent);
|
||||||
|
}
|
||||||
|
|
||||||
|
//reverse deduction with margin
|
||||||
|
double margin_per = _m_extend_with_margin(0, floor.second);
|
||||||
|
margin_per += _m_extend_with_margin(2, floor.second);
|
||||||
|
|
||||||
|
if (margin_per < 1)
|
||||||
|
floor.second /= (1 - margin_per);
|
||||||
|
|
||||||
|
margin_per = _m_extend_with_margin(1, floor.first);
|
||||||
|
margin_per += _m_extend_with_margin(3, floor.first);
|
||||||
|
if (margin_per < 1)
|
||||||
|
floor.first /= (1 - margin_per);
|
||||||
|
}
|
||||||
|
|
||||||
if (!this->weight.empty())
|
if (!this->weight.empty())
|
||||||
{
|
{
|
||||||
if(!this->is_percent())
|
if (!this->is_percent())
|
||||||
fv = this->weight.real();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (fit_policy::none != this->fit)
|
|
||||||
{
|
{
|
||||||
std::size_t fit_count = 0;
|
//Cancel to set weight
|
||||||
|
if (fv <= this->weight.real())
|
||||||
unsigned max_value = 0;
|
set_weight = -1;
|
||||||
auto const fit_horz = (fit_policy::vert == this->fit);
|
|
||||||
|
|
||||||
std::size_t pos = 0;
|
|
||||||
for (auto & elm : this->field->elements)
|
|
||||||
{
|
|
||||||
++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)
|
|
||||||
{
|
|
||||||
run_.fit_extents[elm.handle] = extent->second;
|
|
||||||
++fit_count;
|
|
||||||
if (vert_fields)
|
|
||||||
floor.second += extent->second.height;
|
|
||||||
else
|
|
||||||
floor.first += extent->second.width;
|
|
||||||
|
|
||||||
max_value = (std::max)(max_value, (vert_fields ? extent->second.width : extent->second.height));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max_value)
|
|
||||||
{
|
|
||||||
if (vert_fields)
|
|
||||||
floor.first = max_value;
|
|
||||||
else
|
|
||||||
floor.second = max_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
if (fit_count > 1)
|
|
||||||
{
|
|
||||||
double percent = 0;
|
|
||||||
for (std::size_t i = 0; i < fit_count - 1; ++i)
|
|
||||||
{
|
|
||||||
auto gap_value = gap.at(i);
|
|
||||||
if (gap_value.kind_of() == number_t::kind::percent)
|
|
||||||
{
|
|
||||||
percent += gap_value.real();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
double precise_px = 0;
|
|
||||||
fv += calc_number(gap_value, 100, 0, precise_px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fv *= (1 + percent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
run_.weight_floor = floor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (1 == set_weight)
|
||||||
|
this->weight.assign(static_cast<int>(fv));
|
||||||
|
|
||||||
|
run_.weight_floor = floor;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return floor;
|
return floor;
|
||||||
@ -1014,6 +1041,19 @@ namespace nana
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
public:
|
public:
|
||||||
|
double _m_extend_with_margin(std::size_t edge, double & extended)
|
||||||
|
{
|
||||||
|
auto margin_edge = margin.get_edge(edge);
|
||||||
|
if (!margin_edge.empty())
|
||||||
|
{
|
||||||
|
if (margin_edge.kind_of() != number_t::kind::percent)
|
||||||
|
extended += margin_edge.real();
|
||||||
|
else
|
||||||
|
return margin_edge.real();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static void _m_visible_for_child(division * div, bool vsb) noexcept
|
static void _m_visible_for_child(division * div, bool vsb) noexcept
|
||||||
{
|
{
|
||||||
for (auto & child : div->children)
|
for (auto & child : div->children)
|
||||||
@ -1104,7 +1144,9 @@ namespace nana
|
|||||||
child_px = npx;
|
child_px = npx;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
child_px = static_cast<unsigned>(child->weight.integer());
|
child_px = static_cast<unsigned>(child->weight.integer());
|
||||||
|
}
|
||||||
|
|
||||||
//Use 'endpos' to calc width is to avoid deviation
|
//Use 'endpos' to calc width is to avoid deviation
|
||||||
int endpos = static_cast<int>(position + child_px);
|
int endpos = static_cast<int>(position + child_px);
|
||||||
@ -2813,10 +2855,9 @@ namespace nana
|
|||||||
if ((!max_px.empty()) && (!weight.empty()) && (weight.get_value(100) > max_px.get_value(100)))
|
if ((!max_px.empty()) && (!weight.empty()) && (weight.get_value(100) > max_px.get_value(100)))
|
||||||
weight.reset();
|
weight.reset();
|
||||||
|
|
||||||
if(!weight.empty())
|
if (!weight.empty())
|
||||||
div->weight = weight;
|
div->weight = weight;
|
||||||
|
|
||||||
|
|
||||||
div->gap = std::move(gap);
|
div->gap = std::move(gap);
|
||||||
|
|
||||||
//attach the field to the division
|
//attach the field to the division
|
||||||
|
@ -591,6 +591,45 @@ namespace nana
|
|||||||
margins_ = v;
|
margins_ = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
number_t get_edge(std::size_t edge) const
|
||||||
|
{
|
||||||
|
int il{ -1 }, ir{ -1 }, it{ -1 }, ib{ -1 }; //index of four corners in margin
|
||||||
|
switch (margins_.size())
|
||||||
|
{
|
||||||
|
case 0: break;
|
||||||
|
case 1: //top
|
||||||
|
il = ir = it = ib = 0;
|
||||||
|
break;
|
||||||
|
case 2://top,bottom and left,right
|
||||||
|
it = ib = 0;
|
||||||
|
il = ir = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
il = 3; //left
|
||||||
|
case 3: //top, right, bottom
|
||||||
|
it = 0;
|
||||||
|
ir = 1;
|
||||||
|
ib = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
int pos = 0;
|
||||||
|
switch (edge)
|
||||||
|
{
|
||||||
|
case 0: //top
|
||||||
|
pos = it; break;
|
||||||
|
case 1: //right
|
||||||
|
pos = ir; break;
|
||||||
|
case 2: //bottom
|
||||||
|
pos = ib; break;
|
||||||
|
case 3: //left
|
||||||
|
pos = il; break;
|
||||||
|
default:
|
||||||
|
return number_t{};
|
||||||
|
}
|
||||||
|
|
||||||
|
return (-1 == pos ? number_t{} : margins_[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
nana::rectangle area(const ::nana::rectangle& field_area) const
|
nana::rectangle area(const ::nana::rectangle& field_area) const
|
||||||
{
|
{
|
||||||
if (margins_.empty())
|
if (margins_.empty())
|
||||||
@ -613,7 +652,7 @@ namespace nana
|
|||||||
{
|
{
|
||||||
case 0: break;
|
case 0: break;
|
||||||
case 1: //top
|
case 1: //top
|
||||||
it = 0;
|
il = ir = it = ib = 0;
|
||||||
break;
|
break;
|
||||||
case 2://top,bottom and left,right
|
case 2://top,bottom and left,right
|
||||||
it = ib = 0;
|
it = ib = 0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user