improve place fit when margin is given

This commit is contained in:
Jinhao 2017-04-29 11:24:35 +08:00
parent 58cb215f7b
commit 0511a300d6
2 changed files with 152 additions and 72 deletions

View File

@ -807,14 +807,9 @@ namespace nana
if((ratio > 0.001) && (fv > 0))
fv /= ratio;
if (!this->weight.empty())
{
if(!this->is_percent())
fv = this->weight.real();
}
else
{
if (fit_policy::none != this->fit)
int set_weight = 0;
if ((fit_policy::none != this->fit) && this->field)
{
std::size_t fit_count = 0;
@ -822,6 +817,7 @@ namespace nana
auto const fit_horz = (fit_policy::vert == this->fit);
std::size_t pos = 0;
for (auto & elm : this->field->elements)
{
++pos;
@ -847,7 +843,12 @@ namespace nana
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)
@ -858,7 +859,7 @@ namespace nana
floor.second = max_value;
}
//reverse deduction with gap
if (fit_count > 1)
{
double percent = 0;
@ -878,9 +879,35 @@ namespace nana
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->is_percent())
{
//Cancel to set weight
if (fv <= this->weight.real())
set_weight = -1;
}
}
if (1 == set_weight)
this->weight.assign(static_cast<int>(fv));
run_.weight_floor = floor;
}
}
return floor;
@ -1014,6 +1041,19 @@ namespace nana
return nullptr;
}
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
{
for (auto & child : div->children)
@ -1104,7 +1144,9 @@ namespace nana
child_px = npx;
}
else
{
child_px = static_cast<unsigned>(child->weight.integer());
}
//Use 'endpos' to calc width is to avoid deviation
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)))
weight.reset();
if(!weight.empty())
if (!weight.empty())
div->weight = weight;
div->gap = std::move(gap);
//attach the field to the division

View File

@ -591,6 +591,45 @@ namespace nana
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
{
if (margins_.empty())
@ -613,7 +652,7 @@ namespace nana
{
case 0: break;
case 1: //top
it = 0;
il = ir = it = ib = 0;
break;
case 2://top,bottom and left,right
it = ib = 0;