[DEV] continue good integration of gravity in sizer ...

This commit is contained in:
Edouard DUPIN 2016-02-01 21:26:21 +01:00
parent 46699c20b6
commit 5b93b312f3
2 changed files with 193 additions and 74 deletions

View File

@ -41,90 +41,206 @@ void ewol::widget::Sizer::calculateSize(const vec2& _availlable) {
ewol::Widget::calculateSize(_availlable);
vec2 tmpBorderSize = m_borderSize->getPixel();
EWOL_VERBOSE("[" << getId() << "] update size : " << _availlable << " nbElement : " << m_subWidget.size() << " borderSize=" << tmpBorderSize << " from border=" << m_borderSize);
m_size -= tmpBorderSize*2;
// calculate unExpandable size :
float unexpandableSize=0.0;
ivec2 nbWidgetNotFixedSize = ivec2(0,0);
for (auto &it : m_subWidget) {
if (it == nullptr) {
continue;
}
vec2 tmpSize = it->getCalculateMinSize();
if (m_mode == ewol::widget::Sizer::modeVert) {
unexpandableSize += tmpSize.y();
if (it->canExpand().y() == true) {
nbWidgetNotFixedSize+=ivec2(0,1);
#if 1
vec2 localWidgetSize = m_size - tmpBorderSize*2.0f;
// -1- calculate min-size and expand requested:
vec2 minSize(0.0f, 0.0f);
ivec2 nbWidgetExpand(0,0);
for (auto &it : m_subWidget) {
if (it == nullptr) {
continue;
}
} else {
unexpandableSize += tmpSize.x();
if (it->canExpand().x() == true) {
nbWidgetNotFixedSize+=ivec2(1,0);
}
}
}
// 2 cases : 1 or more can Expand, or all is done ...
float sizeToAddAtEveryOne = 0;
// 2 cases : 1 or more can Expand, or all is done ...
if (nbWidgetNotFixedSize != ivec2(0,0)) {
if (m_mode == ewol::widget::Sizer::modeVert) {
sizeToAddAtEveryOne = (m_size.y() - unexpandableSize) / float(nbWidgetNotFixedSize.y());
} else {
sizeToAddAtEveryOne = (m_size.x() - unexpandableSize) / float(nbWidgetNotFixedSize.x());
}
if (sizeToAddAtEveryOne<0.0) {
sizeToAddAtEveryOne=0;
}
}
// TODO : Need manage gravity ...
vec2 tmpOrigin = m_origin + tmpBorderSize;
for (auto &it : m_subWidget) {
if (it != nullptr) {
vec2 tmpSize = it->getCalculateMinSize();
// set the origin :
EWOL_VERBOSE("[" << getId() << "] set ORIGIN : " << tmpOrigin << " & offset=" << m_offset);
it->setOrigin(vec2ClipInt32(tmpOrigin+m_offset));
// Now update his size his size in X and the curent sizer size in Y:
if (m_mode == ewol::widget::Sizer::modeVert) {
if (it->canExpand().y() == true) {
vec2 expectedSize = vec2ClipInt32(vec2(m_size.x(), tmpSize.y()+sizeToAddAtEveryOne));
it->calculateSize(expectedSize);
vec2 underSize = it->getSize();
if (it->canExpand().x() == true) {
if (underSize.x() < expectedSize.x()) {
EWOL_WARNING("Subwidget request exapnd and does not expand ... ==> rules impose it ...");
//it->setSize(vec2(expectedSize.x(), underSize.y());
//underSize = it->getSize();
minSize = vec2(std::max(minSize.x(), tmpSize.x()),
minSize.x() + tmpSize.y());
} else {
minSize = vec2(minSize.y() + tmpSize.y(),
std::max(minSize.y(), tmpSize.y()));
}
bvec2 expand = it->canExpand();
nbWidgetExpand += ivec(expand.x()==true?1:0,
expand.y()==true?1:0);
}
// -2- Calculate the size to add at every elements...
float deltaExpandSize = 0.0f;
if (nbWidgetNotFixedSize != ivec2(0,0)) {
if (m_mode == ewol::widget::Sizer::modeVert) {
deltaExpandSize = (localWidgetSize.y() - minSize.y()) / float(nbWidgetExpand.y());
} else {
deltaExpandSize = (localWidgetSize.x() - minSize.x()) / float(nbWidgetExpand.x());
}
if (deltaExpandSize<0.0) {
deltaExpandSize=0;
}
}
// -3- Configure all at the min size ...
for (auto &it : m_subWidget) {
if (it == nullptr) {
continue;
}
it->ParrentSetSize(it->getCalculateMinSize());
}
// -4- For each element we apply the minmax range and update if needed
while (deltaExpandSize > 0.0001f) {
float residualNext = 0.0f;
// get the number of element that need to devide...
int32_t countCalculation = nbWidgetExpand.x();
if (m_mode == ewol::widget::Sizer::modeVert) {
countCalculation = nbWidgetExpand.y();
}
// -4.1- Update every subWidget size
for (auto &it : m_subWidget) {
if (it == nullptr) {
continue;
}
vec2 tmpSizeMin = it->getSize();
vec2 tmpSizeMax = it->getCalculateMaxSize();
// Now update his size his size in X and the curent sizer size in Y:
if (m_mode == ewol::widget::Sizer::modeVert) {
if (it->canExpand().y() == true) {
float sizeExpand = tmpSizeMin.y() + deltaExpandSize;
if (sizeExpand > tmpSizeMax.y()) {
residualNext += (sizeExpand - tmpSizeMax.y());
sizeExpand = tmpSizeMax.y();
countCalculation--;
}
tmpSizeMin.setY(sizeExpand);
}
if (it->canExpand().x() == true) {
float sizeExpand = etk::avg(tmpSizeMin.x(), minSize.x(), tmpSizeMax.x());
tmpSizeMin.setX(sizeExpand);
}
it->parrentSetSize(tmpSizeMin);
} else {
if (it->canExpand().x() == true) {
float sizeExpand = tmpSizeMin.x() + deltaExpandSize;
if (sizeExpand > tmpSizeMax.x()) {
residualNext += (sizeExpand - tmpSizeMax.x());
sizeExpand = tmpSizeMax.x();
countCalculation--;
}
tmpSizeMin.setX(sizeExpand);
}
if (it->canExpand().y() == true) {
if (underSize.y() < expectedSize.y()) {
EWOL_WARNING("Subwidget request exapnd and does not expand ... ==> rules impose it ...");
//it->setSize(vec2(underSize.y(), expectedSize.x());
}
float sizeExpand = etk::avg(tmpSizeMin.y(), minSize.y(), tmpSizeMax.y());
tmpSizeMin.setY(sizeExpand);
}
tmpOrigin.setY(tmpOrigin.y() + tmpSize.y()+sizeToAddAtEveryOne);
} else {
it->calculateSize(vec2ClipInt32(vec2(m_size.x(), tmpSize.y())));
tmpOrigin.setY(tmpOrigin.y() + tmpSize.y());
it->parrentSetSize(tmpSizeMin);
}
}
// Reset size add ...
deltaExpandSize = 0.0f;
if (residualNext < 0.0001f) {
break;
}
if (countCalculation <= 0) {
break;
}
if (m_mode == ewol::widget::Sizer::modeVert) {
deltaExpandSize = residualNext / float(countCalculation);
} else {
deltaExpandSize = residualNext / float(countCalculation);
}
if (deltaExpandSize<0.0f) {
deltaExpandSize=0.0f;
break;
}
}
// -5- Set the origin for every element with the gravity update:
for (auto &it : m_subWidget) {
if (it == nullptr) {
continue;
}
// TODO : Set origin with the correct gravity
}
#else
m_size -= tmpBorderSize*2.0f;
// calculate unExpandable size :
float unexpandableSize=0.0;
ivec2 nbWidgetNotFixedSize = ivec2(0,0);
for (auto &it : m_subWidget) {
if (it == nullptr) {
continue;
}
vec2 tmpSize = it->getCalculateMinSize();
if (m_mode == ewol::widget::Sizer::modeVert) {
unexpandableSize += tmpSize.y();
if (it->canExpand().y() == true) {
nbWidgetNotFixedSize+=ivec2(0,1);
}
} else {
unexpandableSize += tmpSize.x();
if (it->canExpand().x() == true) {
it->calculateSize(vec2ClipInt32(vec2(tmpSize.x()+sizeToAddAtEveryOne, m_size.y())));
tmpOrigin.setX(tmpOrigin.x() + tmpSize.x()+sizeToAddAtEveryOne);
} else {
it->calculateSize(vec2ClipInt32(vec2(tmpSize.x(), m_size.y())));
int32_t subSize = it->getSize().y();
if (subSize <= m_size.y()) {
// move localy of half needed
it->setOrigin(it->getOrigin() + ivec2(0, (m_size.y()-subSize)/2));
}
tmpOrigin.setX(tmpOrigin.x() + tmpSize.x());
nbWidgetNotFixedSize+=ivec2(1,0);
}
}
}
}
m_size += tmpBorderSize*2;
// 2 cases : 1 or more can Expand, or all is done ...
float sizeToAddAtEveryOne = 0;
// 2 cases : 1 or more can Expand, or all is done ...
if (nbWidgetNotFixedSize != ivec2(0,0)) {
if (m_mode == ewol::widget::Sizer::modeVert) {
sizeToAddAtEveryOne = (m_size.y() - unexpandableSize) / float(nbWidgetNotFixedSize.y());
} else {
sizeToAddAtEveryOne = (m_size.x() - unexpandableSize) / float(nbWidgetNotFixedSize.x());
}
if (sizeToAddAtEveryOne<0.0) {
sizeToAddAtEveryOne=0;
}
}
// TODO : Need manage gravity ...
vec2 tmpOrigin = m_origin + tmpBorderSize;
for (auto &it : m_subWidget) {
if (it != nullptr) {
vec2 tmpSize = it->getCalculateMinSize();
// set the origin :
EWOL_VERBOSE("[" << getId() << "] set ORIGIN : " << tmpOrigin << " & offset=" << m_offset);
it->setOrigin(vec2ClipInt32(tmpOrigin+m_offset));
// Now update his size his size in X and the curent sizer size in Y:
if (m_mode == ewol::widget::Sizer::modeVert) {
if (it->canExpand().y() == true) {
vec2 expectedSize = vec2ClipInt32(vec2(m_size.x(), tmpSize.y()+sizeToAddAtEveryOne));
it->calculateSize(expectedSize);
vec2 underSize = it->getSize();
if (it->canExpand().x() == true) {
if (underSize.x() < expectedSize.x()) {
EWOL_WARNING("Subwidget request exapnd and does not expand ... ==> rules impose it ...");
//it->setSize(vec2(expectedSize.x(), underSize.y());
//underSize = it->getSize();
}
}
if (it->canExpand().y() == true) {
if (underSize.y() < expectedSize.y()) {
EWOL_WARNING("Subwidget request exapnd and does not expand ... ==> rules impose it ...");
//it->setSize(vec2(underSize.y(), expectedSize.x());
}
}
tmpOrigin.setY(tmpOrigin.y() + tmpSize.y()+sizeToAddAtEveryOne);
} else {
it->calculateSize(vec2ClipInt32(vec2(m_size.x(), tmpSize.y())));
tmpOrigin.setY(tmpOrigin.y() + tmpSize.y());
}
} else {
if (it->canExpand().x() == true) {
it->calculateSize(vec2ClipInt32(vec2(tmpSize.x()+sizeToAddAtEveryOne, m_size.y())));
tmpOrigin.setX(tmpOrigin.x() + tmpSize.x()+sizeToAddAtEveryOne);
} else {
it->calculateSize(vec2ClipInt32(vec2(tmpSize.x(), m_size.y())));
int32_t subSize = it->getSize().y();
if (subSize <= m_size.y()) {
// move localy of half needed
it->setOrigin(it->getOrigin() + ivec2(0, (m_size.y()-subSize)/2));
}
tmpOrigin.setX(tmpOrigin.x() + tmpSize.x());
}
}
}
}
m_size += tmpBorderSize*2;
#endif
markToRedraw();
}

View File

@ -139,9 +139,9 @@ namespace ewol {
// -- Widget size:
// ----------------------------------------------------------------------------------------------------------------
protected:
vec2 m_size; //!< internal : current size of the widget
vec2 m_minSize; //!< internal : minimum size of the widget
vec2 m_maxSize; //!< internal : maximum size of the widget
vec2 m_size; //!< internal: current size of the widget
vec2 m_minSize; //!< internal: minimum size of the widget
vec2 m_maxSize; //!< internal: maximum size of the widget
public:
/**
* @brief convert the absolute position in the local Position (Relative)
@ -162,6 +162,9 @@ namespace ewol {
* @note : INTERNAL EWOL SYSTEM
*/
virtual vec2 getSize();
virtual void parrentSetSize(const vec2& _value) {
m_size = _value;
}
/**
* @brief calculate the minimum and maximum size (need to estimate expend properties of the widget)
* @note : INTERNAL EWOL SYSTEM