refactor layout code

This commit is contained in:
王劲鹏 2021-04-19 19:22:10 +08:00 committed by osborn
parent 00528a3ce5
commit 77e32d1f08
3 changed files with 58 additions and 66 deletions

View File

@ -97,7 +97,7 @@ void DoricScrollerNode::requestLayout() {
->property("doricLayout") ->property("doricLayout")
.toULongLong()); .toULongLong());
if (layout != nullptr) { if (layout != nullptr) {
layout->apply(mView->width(), mView->height()); layout->apply(QSizeF(mView->width(), mView->height()));
mView->setProperty("contentWidth", layout->getMeasuredWidth()); mView->setProperty("contentWidth", layout->getMeasuredWidth());
mView->setProperty("contentHeight", layout->getMeasuredHeight()); mView->setProperty("contentHeight", layout->getMeasuredHeight());

View File

@ -108,25 +108,25 @@ void DoricLayouts::setMinHeight(qreal minHeight) {
this->minHeight = minHeight; this->minHeight = minHeight;
} }
void DoricLayouts::apply(qreal targetWidth, qreal targetHeight) { void DoricLayouts::apply(QSizeF frameSize) {
this->resolved = false; this->resolved = false;
this->measure(targetWidth, targetHeight); this->measure(frameSize);
this->setFrame(); this->setFrame();
this->resolved = true; this->resolved = true;
} }
void DoricLayouts::apply() { void DoricLayouts::apply() {
this->apply(this->view->width(), this->view->height()); this->apply(QSizeF(this->view->width(), this->view->height()));
} }
void DoricLayouts::measure(qreal targetWidth, qreal targetHeight) { void DoricLayouts::measure(QSizeF targetSize) {
this->measureSelf(targetWidth, targetHeight); this->measureSelf(targetSize);
this->layout(); this->layout();
} }
void DoricLayouts::measureSelf(qreal targetWidth, qreal targetHeight) { void DoricLayouts::measureSelf(QSizeF targetSize) {
// measure width // measure width
qreal width; qreal width;
if (this->widthSpec == DoricLayoutSpec::DoricLayoutMost) { if (this->widthSpec == DoricLayoutSpec::DoricLayoutMost) {
@ -138,14 +138,14 @@ void DoricLayouts::measureSelf(qreal targetWidth, qreal targetHeight) {
width = 0; width = 0;
setMeasuredWidth(0); setMeasuredWidth(0);
} else { } else {
width = targetWidth; width = targetSize.width();
setMeasuredWidth(targetWidth); setMeasuredWidth(targetSize.width());
} }
} else if (this->widthSpec == DoricLayoutSpec::DoricLayoutJust) { } else if (this->widthSpec == DoricLayoutSpec::DoricLayoutJust) {
width = this->width; width = this->width;
setMeasuredWidth(this->width); setMeasuredWidth(this->width);
} else { } else {
width = targetWidth; width = targetSize.width();
} }
// measure height // measure height
@ -159,46 +159,45 @@ void DoricLayouts::measureSelf(qreal targetWidth, qreal targetHeight) {
height = 0; height = 0;
setMeasuredHeight(0); setMeasuredHeight(0);
} else { } else {
height = targetHeight; height = targetSize.height();
setMeasuredHeight(targetHeight); setMeasuredHeight(targetSize.height());
} }
} else if (this->heightSpec == DoricLayoutSpec::DoricLayoutJust) { } else if (this->heightSpec == DoricLayoutSpec::DoricLayoutJust) {
height = this->height; height = this->height;
setMeasuredHeight(this->height); setMeasuredHeight(this->height);
} else { } else {
height = targetHeight; height = targetSize.height();
} }
// measure content // measure content
this->measureContent(QSizeF(width - this->paddingLeft - this->paddingRight,
this->measureContent(width - this->paddingLeft - this->paddingRight, height - this->paddingTop - this->paddingBottom));
height - this->paddingTop - this->paddingBottom);
if (this->restrainSize()) { if (this->restrainSize()) {
this->measureContent( this->measureContent(
this->measuredWidth - this->paddingLeft - this->paddingRight, QSizeF(this->measuredWidth - this->paddingLeft - this->paddingRight,
this->measuredHeight - this->paddingTop - this->paddingBottom); this->measuredHeight - this->paddingTop - this->paddingBottom));
} }
this->restrainSize(); this->restrainSize();
} }
void DoricLayouts::measureContent(qreal targetWidth, qreal targetHeight) { void DoricLayouts::measureContent(QSizeF targetSize) {
qCritical() << "measureContent: " << tag << this->view->property("uuid"); qCritical() << "measureContent: " << tag << this->view->property("uuid");
switch (this->layoutType) { switch (this->layoutType) {
case DoricLayoutType::DoricStack: { case DoricLayoutType::DoricStack: {
this->measureStackContent(targetWidth, targetHeight); this->measureStackContent(targetSize);
break; break;
} }
case DoricLayoutType::DoricVLayout: { case DoricLayoutType::DoricVLayout: {
this->measureVLayoutContent(targetWidth, targetHeight); this->measureVLayoutContent(targetSize);
break; break;
} }
case DoricLayoutType::DoricHLayout: { case DoricLayoutType::DoricHLayout: {
this->measureHLayoutContent(targetWidth, targetHeight); this->measureHLayoutContent(targetSize);
break; break;
} }
default: { default: {
this->measureUndefinedContent(targetWidth, targetHeight); this->measureUndefinedContent(targetSize);
break; break;
} }
} }
@ -211,27 +210,26 @@ void DoricLayouts::measureContent(qreal targetWidth, qreal targetHeight) {
if (parentDoricLayout->layoutType != DoricLayoutType::DoricUndefined && if (parentDoricLayout->layoutType != DoricLayoutType::DoricUndefined &&
parentDoricLayout->widthSpec == DoricLayoutSpec::DoricLayoutFit && parentDoricLayout->widthSpec == DoricLayoutSpec::DoricLayoutFit &&
this->widthSpec == DoricLayoutSpec::DoricLayoutMost) { this->widthSpec == DoricLayoutSpec::DoricLayoutMost) {
setMeasuredWidth(targetWidth); setMeasuredWidth(targetSize.width());
} }
if (parentDoricLayout->layoutType != DoricLayoutType::DoricUndefined && if (parentDoricLayout->layoutType != DoricLayoutType::DoricUndefined &&
parentDoricLayout->heightSpec == DoricLayoutSpec::DoricLayoutFit && parentDoricLayout->heightSpec == DoricLayoutSpec::DoricLayoutFit &&
this->heightSpec == DoricLayoutSpec::DoricLayoutMost) { this->heightSpec == DoricLayoutSpec::DoricLayoutMost) {
setMeasuredHeight(targetHeight); setMeasuredHeight(targetSize.height());
} }
} }
} }
} }
void DoricLayouts::measureUndefinedContent(qreal targetWidth, void DoricLayouts::measureUndefinedContent(QSizeF targetSize) {
qreal targetHeight) {
qreal width = this->view->width(); qreal width = this->view->width();
qreal height = this->view->height(); qreal height = this->view->height();
if (width > targetWidth) { if (width > targetSize.width()) {
width = targetWidth; width = targetSize.width();
} }
if (height > targetHeight) { if (height > targetSize.height()) {
height = targetHeight; height = targetSize.height();
} }
if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) { if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) {
setMeasuredWidth(width + this->paddingLeft + this->paddingRight); setMeasuredWidth(width + this->paddingLeft + this->paddingRight);
@ -240,7 +238,7 @@ void DoricLayouts::measureUndefinedContent(qreal targetWidth,
setMeasuredHeight(height + this->paddingTop + this->paddingBottom); setMeasuredHeight(height + this->paddingTop + this->paddingBottom);
} }
} }
void DoricLayouts::measureStackContent(qreal targetWidth, qreal targetHeight) { void DoricLayouts::measureStackContent(QSizeF targetSize) {
qreal contentWidth = 0, contentHeight = 0; qreal contentWidth = 0, contentHeight = 0;
foreach (QQuickItem *subview, this->view->childItems()) { foreach (QQuickItem *subview, this->view->childItems()) {
DoricLayouts *layout = DoricLayouts *layout =
@ -253,8 +251,7 @@ void DoricLayouts::measureStackContent(qreal targetWidth, qreal targetHeight) {
continue; continue;
} }
QPair<int, int> size = layout->removeMargin(targetWidth, targetHeight); layout->measure(layout->removeMargin(targetSize));
layout->measure(size.first, size.second);
contentWidth = qMax(contentWidth, layout->takenWidth()); contentWidth = qMax(contentWidth, layout->takenWidth());
contentHeight = qMax(contentHeight, layout->takenHeight()); contentHeight = qMax(contentHeight, layout->takenHeight());
} }
@ -269,8 +266,7 @@ void DoricLayouts::measureStackContent(qreal targetWidth, qreal targetHeight) {
this->contentWidth = contentWidth; this->contentWidth = contentWidth;
this->contentHeight = contentHeight; this->contentHeight = contentHeight;
} }
void DoricLayouts::measureVLayoutContent(qreal targetWidth, void DoricLayouts::measureVLayoutContent(QSizeF targetSize) {
qreal targetHeight) {
qreal contentWidth = 0, contentHeight = 0, contentWeight = 0; qreal contentWidth = 0, contentHeight = 0, contentWeight = 0;
bool had = false; bool had = false;
foreach (QQuickItem *subview, this->view->childItems()) { foreach (QQuickItem *subview, this->view->childItems()) {
@ -285,9 +281,8 @@ void DoricLayouts::measureVLayoutContent(qreal targetWidth,
} }
had = true; had = true;
QPair<int, int> pair = layout->measure(layout->removeMargin(
layout->removeMargin(targetWidth, targetHeight - contentHeight); QSizeF(targetSize.width(), targetSize.height() - contentHeight)));
layout->measure(pair.first, pair.second);
contentWidth = qMax(contentWidth, layout->takenWidth()); contentWidth = qMax(contentWidth, layout->takenWidth());
contentHeight += layout->takenHeight() + this->spacing; contentHeight += layout->takenHeight() + this->spacing;
contentWeight += layout->weight; contentWeight += layout->weight;
@ -298,7 +293,7 @@ void DoricLayouts::measureVLayoutContent(qreal targetWidth,
} }
if (contentWeight > 0) { if (contentWeight > 0) {
qreal remaining = targetHeight - contentHeight; qreal remaining = targetSize.height() - contentHeight;
contentWidth = 0; contentWidth = 0;
foreach (QQuickItem *subview, this->view->childItems()) { foreach (QQuickItem *subview, this->view->childItems()) {
DoricLayouts *layout = DoricLayouts *layout =
@ -314,13 +309,13 @@ void DoricLayouts::measureVLayoutContent(qreal targetWidth,
layout->measuredHeight + remaining / contentWeight * layout->weight; layout->measuredHeight + remaining / contentWeight * layout->weight;
layout->measuredHeight = measuredHeight; layout->measuredHeight = measuredHeight;
// Need Remeasure // Need Remeasure
layout->measureContent( layout->measureContent(QSizeF(
layout->measuredWidth - layout->paddingLeft - layout->paddingRight, layout->measuredWidth - layout->paddingLeft - layout->paddingRight,
measuredHeight - layout->paddingTop - layout->paddingBottom); measuredHeight - layout->paddingTop - layout->paddingBottom));
layout->measuredHeight = measuredHeight; layout->measuredHeight = measuredHeight;
contentWidth = qMax(contentWidth, layout->takenWidth()); contentWidth = qMax(contentWidth, layout->takenWidth());
} }
contentHeight = targetHeight; contentHeight = targetSize.height();
} }
if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) { if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) {
@ -334,8 +329,7 @@ void DoricLayouts::measureVLayoutContent(qreal targetWidth,
this->contentWidth = contentWidth; this->contentWidth = contentWidth;
this->contentHeight = contentHeight; this->contentHeight = contentHeight;
} }
void DoricLayouts::measureHLayoutContent(qreal targetWidth, void DoricLayouts::measureHLayoutContent(QSizeF targetSize) {
qreal targetHeight) {
qreal contentWidth = 0, contentHeight = 0, contentWeight = 0; qreal contentWidth = 0, contentHeight = 0, contentWeight = 0;
bool had = false; bool had = false;
foreach (QQuickItem *subview, this->view->childItems()) { foreach (QQuickItem *subview, this->view->childItems()) {
@ -349,9 +343,9 @@ void DoricLayouts::measureHLayoutContent(qreal targetWidth,
continue; continue;
} }
had = true; had = true;
QPair<int, int> pair =
layout->removeMargin(targetWidth - contentWidth, targetHeight); layout->measure(layout->removeMargin(
layout->measure(pair.first, pair.second); QSizeF(targetSize.width() - contentWidth, targetSize.height())));
contentWidth += layout->takenWidth() + this->spacing; contentWidth += layout->takenWidth() + this->spacing;
contentHeight = qMax(contentHeight, layout->takenHeight()); contentHeight = qMax(contentHeight, layout->takenHeight());
contentWeight += layout->weight; contentWeight += layout->weight;
@ -362,7 +356,7 @@ void DoricLayouts::measureHLayoutContent(qreal targetWidth,
} }
if (contentWeight > 0) { if (contentWeight > 0) {
qreal remaining = targetWidth - contentWidth; qreal remaining = targetSize.width() - contentWidth;
contentHeight = 0; contentHeight = 0;
foreach (QQuickItem *subview, this->view->childItems()) { foreach (QQuickItem *subview, this->view->childItems()) {
DoricLayouts *layout = DoricLayouts *layout =
@ -378,13 +372,13 @@ void DoricLayouts::measureHLayoutContent(qreal targetWidth,
layout->measuredWidth + remaining / contentWeight * layout->weight; layout->measuredWidth + remaining / contentWeight * layout->weight;
layout->measuredWidth = measuredWidth; layout->measuredWidth = measuredWidth;
// Need Remeasure // Need Remeasure
layout->measureContent( layout->measureContent(QSizeF(
measuredWidth - layout->paddingLeft - layout->paddingRight, measuredWidth - layout->paddingLeft - layout->paddingRight,
layout->measuredHeight - layout->paddingTop - layout->paddingBottom); layout->measuredHeight - layout->paddingTop - layout->paddingBottom));
layout->measuredWidth = measuredWidth; layout->measuredWidth = measuredWidth;
contentHeight = qMax(contentHeight, layout->takenHeight()); contentHeight = qMax(contentHeight, layout->takenHeight());
} }
contentWidth = targetWidth; contentWidth = targetSize.width();
} }
if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) { if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) {
@ -405,11 +399,9 @@ qreal DoricLayouts::takenWidth() {
qreal DoricLayouts::takenHeight() { qreal DoricLayouts::takenHeight() {
return this->measuredHeight + this->marginTop + this->marginBottom; return this->measuredHeight + this->marginTop + this->marginBottom;
} }
QPair<qreal, qreal> DoricLayouts::removeMargin(qreal targetWidth, QSizeF DoricLayouts::removeMargin(QSizeF targetSize) {
qreal targetHeight) { return QSizeF(targetSize.width() - this->marginLeft - this->marginRight,
QPair<int, int> pair(targetWidth - this->marginLeft - this->marginRight, targetSize.height() - this->marginTop - this->marginBottom);
targetHeight - this->marginTop - this->marginBottom);
return pair;
} }
bool DoricLayouts::restrainSize() { bool DoricLayouts::restrainSize() {

View File

@ -80,7 +80,7 @@ public:
void setMinWidth(qreal minWidth); void setMinWidth(qreal minWidth);
void setMinHeight(qreal minHeight); void setMinHeight(qreal minHeight);
void apply(qreal targetWidth, qreal targetHeight); void apply(QSizeF frameSize);
void apply(); void apply();
@ -142,20 +142,20 @@ private:
qreal contentWidth; qreal contentWidth;
qreal contentHeight; qreal contentHeight;
void measure(qreal targetWidth, qreal targetHeight); void measure(QSizeF targetSize);
void measureSelf(qreal targetWidth, qreal targetHeight); void measureSelf(QSizeF targetSize);
void measureContent(qreal targetWidth, qreal targetHeight); void measureContent(QSizeF targetSize);
void measureUndefinedContent(qreal targetWidth, qreal targetHeight); void measureUndefinedContent(QSizeF targetSize);
void measureStackContent(qreal targetWidth, qreal targetHeight); void measureStackContent(QSizeF targetSize);
void measureVLayoutContent(qreal targetWidth, qreal targetHeight); void measureVLayoutContent(QSizeF targetSize);
void measureHLayoutContent(qreal targetWidth, qreal targetHeight); void measureHLayoutContent(QSizeF targetSize);
qreal takenWidth(); qreal takenWidth();
qreal takenHeight(); qreal takenHeight();
QPair<qreal, qreal> removeMargin(qreal targetWidth, qreal targetHeight); QSizeF removeMargin(QSizeF targetSize);
bool restrainSize(); bool restrainSize();