diff --git a/src/cpp/include/nodegui/core/FlexLayout/flexlayout.h b/src/cpp/include/nodegui/core/FlexLayout/flexlayout.h index 28c50ccd1..96c0f889a 100644 --- a/src/cpp/include/nodegui/core/FlexLayout/flexlayout.h +++ b/src/cpp/include/nodegui/core/FlexLayout/flexlayout.h @@ -23,11 +23,14 @@ class FlexLayout : public QLayout, public EventWidget { YGNodeRef node; YGNodeRef getRootNode(YGNodeRef node) const; void calculateLayout() const; + void restoreNodeMinStyle(YGValue &previousMinWidth, + YGValue &previousMinHeight); public: FlexLayout(QWidget *parentWidget = nullptr, YGNodeRef parentNode = nullptr); ~FlexLayout() override; QSize sizeHint() const override; + QSize minimumSize() const override; void addItem(QLayoutItem *) override; QLayoutItem *itemAt(int index) const override; QLayoutItem *takeAt(int index) override; @@ -38,7 +41,6 @@ class FlexLayout : public QLayout, public EventWidget { void removeWidget(QWidget *childWidget, YGNodeRef childNode); void setGeometry(const QRect &rect) override; void setFlexNode(YGNodeRef parentNode); - Qt::Orientations expandingDirections() const override; bool hasHeightForWidth() const override; EVENTWIDGET_IMPLEMENTATIONS(QLayout) diff --git a/src/cpp/include/nodegui/core/FlexLayout/flexutils.h b/src/cpp/include/nodegui/core/FlexLayout/flexutils.h index 7e687aa62..927a5d8fb 100644 --- a/src/cpp/include/nodegui/core/FlexLayout/flexutils.h +++ b/src/cpp/include/nodegui/core/FlexLayout/flexutils.h @@ -19,9 +19,10 @@ class FlexNodeContext { namespace flexutils { YGSize measureQtWidget(YGNodeRef node, float width, YGMeasureMode widthMode, float height, YGMeasureMode heightMode); -const QRect getFlexNodeGeometry(YGNodeRef node); +QRect getFlexNodeGeometry(YGNodeRef node); void setFlexNodeGeometry(YGNodeRef node, const QRect& geometry); FlexNodeContext* getFlexNodeContext(YGNodeRef node); +bool isFlexNodeSizeControlled(YGNodeRef node); void configureFlexNode(QWidget* widget, YGNodeRef node, bool isLeafNode = false); diff --git a/src/cpp/lib/core/FlexLayout/flexlayout.cpp b/src/cpp/lib/core/FlexLayout/flexlayout.cpp index a023c180f..37db58b9a 100644 --- a/src/cpp/lib/core/FlexLayout/flexlayout.cpp +++ b/src/cpp/lib/core/FlexLayout/flexlayout.cpp @@ -131,57 +131,72 @@ YGNodeRef FlexLayout::getRootNode(YGNodeRef node) const { } } -Qt::Orientations FlexLayout::expandingDirections() const { - return Qt::Vertical | Qt::Horizontal; -} - bool FlexLayout::hasHeightForWidth() const { return false; } QSize FlexLayout::sizeHint() const { calculateLayout(); - QSize sizeHint = QSize(YGNodeLayoutGetWidth(this->node), - YGNodeLayoutGetHeight(this->node)); - // qDebug() << "sizeHint" << this->parentWidget() << sizeHint; - return sizeHint; + return QSize(YGNodeLayoutGetWidth(this->node), + YGNodeLayoutGetHeight(this->node)); +} + +QSize FlexLayout::minimumSize() const { + calculateLayout(); + QSize minSize = QSize(YGNodeLayoutGetWidth(this->node), + YGNodeLayoutGetHeight(this->node)); + return minSize; } void FlexLayout::setGeometry(const QRect& rect) { if (!this->node) { return; } - // qDebug() << "setGeometry" << rect << this->parentWidget(); - FlexNodeContext* layoutNodeCtx = flexutils::getFlexNodeContext(this->node); - if (parentWidget()->isWindow() || layoutNodeCtx->isSizeControlled) { - // qDebug() << "controlled" << this->parentWidget(); - YGNodeStyleSetWidth(this->node, rect.width()); - YGNodeStyleSetHeight(this->node, rect.height()); - } - - calculateLayout(); - QRect calculatedRect = flexutils::getFlexNodeGeometry(this->node); - QLayout::setGeometry(calculatedRect); - // qDebug() << "calculatedRect" << calculatedRect << this->parentWidget(); - - uint count = YGNodeGetChildCount(this->node); - - for (uint i = 0; i < count; ++i) { - YGNode* childNode = YGNodeGetChild(this->node, i); - QRect childRect = flexutils::getFlexNodeGeometry(childNode); - FlexNodeContext* ctx = flexutils::getFlexNodeContext(childNode); - QLayoutItem* childItem = ctx->layoutItem(); - // qDebug() << "child" << childRect << childItem->widget(); - childItem->setGeometry(childRect); + if (!rect.isValid() || rect != geometry()) { + bool isSizeControlled = flexutils::isFlexNodeSizeControlled(this->node); + YGNodeMarkDirtyAndPropogateToDescendants(this->node); + YGValue prevStyleMinWidth = YGNodeStyleGetMinWidth(this->node); + YGValue prevStyleMinHeight = YGNodeStyleGetMinHeight(this->node); + if (isSizeControlled) { + YGNodeStyleSetMinHeight(this->node, rect.height()); + YGNodeStyleSetMinWidth(this->node, rect.width()); + } + + calculateLayout(); + + uint count = YGNodeGetChildCount(this->node); + for (uint i = 0; i < count; ++i) { + YGNode* childNode = YGNodeGetChild(this->node, i); + QRect childRect = flexutils::getFlexNodeGeometry(childNode); + FlexNodeContext* ctx = flexutils::getFlexNodeContext(childNode); + QLayoutItem* childItem = ctx->layoutItem(); + childItem->setGeometry(childRect); + } + if (isSizeControlled) { + restoreNodeMinStyle(prevStyleMinWidth, prevStyleMinHeight); + } } + QLayout::setGeometry(rect); } void FlexLayout::setFlexNode(YGNodeRef parentNode) { this->node = parentNode; } void FlexLayout::calculateLayout() const { - YGNodeRef parentNode = this->node; - YGNodeRef rootNode = getRootNode(parentNode); - YGDirection rootDirection = YGNodeStyleGetDirection(rootNode); - float rootWidth = YGNodeLayoutGetWidth(rootNode); - float rootHeight = YGNodeLayoutGetHeight(rootNode); - - YGNodeCalculateLayout(rootNode, rootWidth, rootHeight, rootDirection); + if (YGNodeIsDirty(this->node)) { + YGNodeRef rootNode = getRootNode(this->node); + YGDirection rootDirection = YGNodeStyleGetDirection(rootNode); + YGNodeCalculateLayout(rootNode, YGUndefined, YGUndefined, rootDirection); + } } + +void FlexLayout::restoreNodeMinStyle(YGValue& previousMinWidth, + YGValue& previousMinHeight) { + if (previousMinHeight.unit == YGUnitPercent) { + YGNodeStyleSetMinHeightPercent(this->node, previousMinHeight.value); + } else { + YGNodeStyleSetMinHeight(this->node, previousMinHeight.value); + } + if (previousMinWidth.unit == YGUnitPercent) { + YGNodeStyleSetMinWidthPercent(this->node, previousMinWidth.value); + } else { + YGNodeStyleSetMinWidth(this->node, previousMinWidth.value); + } +} \ No newline at end of file diff --git a/src/cpp/lib/core/FlexLayout/flexutils.cpp b/src/cpp/lib/core/FlexLayout/flexutils.cpp index d30ca4db0..dc1fed0b1 100644 --- a/src/cpp/lib/core/FlexLayout/flexutils.cpp +++ b/src/cpp/lib/core/FlexLayout/flexutils.cpp @@ -17,11 +17,11 @@ void FlexNodeContext::setLayoutItem(QLayoutItem* item) { this->_layoutItem = item; } -const QRect flexutils::getFlexNodeGeometry(YGNodeRef node) { - int width = static_cast(YGNodeLayoutGetWidth(node)); - int height = static_cast(YGNodeLayoutGetHeight(node)); - int left = static_cast(YGNodeLayoutGetLeft(node)); - int top = static_cast(YGNodeLayoutGetTop(node)); +QRect flexutils::getFlexNodeGeometry(YGNodeRef node) { + int width = static_cast(YGNodeLayoutGetWidth(node)); + int height = static_cast(YGNodeLayoutGetHeight(node)); + int left = static_cast(YGNodeLayoutGetLeft(node)); + int top = static_cast(YGNodeLayoutGetTop(node)); const QRect geometry(left, top, width, height); return geometry; } @@ -47,6 +47,19 @@ FlexNodeContext* flexutils::getFlexNodeContext(YGNodeRef node) { return ctx; } +// if true, it means this node's size can controlled by external things like +// resize handles in case of qmainwindow etc +bool flexutils::isFlexNodeSizeControlled(YGNodeRef node) { + if (!node) { + return false; + } + FlexNodeContext* ctx = getFlexNodeContext(node); + if (ctx->widget()->isWindow() || ctx->isSizeControlled) { + return true; + } + return false; +} + YGSize flexutils::measureQtWidget(YGNodeRef node, float _width, YGMeasureMode widthMode, float _height, YGMeasureMode heightMode) { diff --git a/src/demo.ts b/src/demo.ts index ac38f8a3c..eec83ca63 100644 --- a/src/demo.ts +++ b/src/demo.ts @@ -1,50 +1,40 @@ -import { QWidget, QMainWindow, FlexLayout, QLabel } from './index'; +import { QWidget, QMainWindow, FlexLayout, QGridLayout, QLabel } from './index'; import { QScrollArea } from './lib/QtWidgets/QScrollArea'; -const win = new QMainWindow(); -const center = new QWidget(); -const label = new QLabel(); const scrollArea = new QScrollArea(); +scrollArea.setObjectName('scrollArea'); +scrollArea.setWidgetResizable(true); +// scrollArea.resize(500, 500); +const center = new QWidget(); +center.setObjectName('center'); +const label = new QLabel(); +label.setObjectName('label'); label.setText(` -😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱 - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - Hellloooooo - `); +Hellloooooo123 +Hellloooooo +`); center.setInlineStyle(`border: 3px solid blue;`); -label.setInlineStyle(`border: 2px solid green;padding: 10;font-family: "Sans serif";`); -scrollArea.setWidget(label); +label.setInlineStyle(`border: 2px solid green;padding: 10;flex:1;font-family: "Sans serif";`); +// center.setLayout(new QGridLayout()); center.setLayout(new FlexLayout()); -center.layout?.addWidget(scrollArea); -win.setCentralWidget(center); -win.show(); -scrollArea.setInlineStyle(`flex: 1;`); +center.layout?.addWidget(label); +scrollArea.setWidget(center); +console.log('SHOW scrollArea'); +scrollArea.show(); +console.log('SET TEXT'); +setTimeout(() => { + label.setText(`Heloo + Heloo + Jello + Hoell + jaksjd + asjdkajdk + aksjdkajsdkja + ajksjdakjsd + jkasjdkajd + ajksdjakjs`); +}, 3000); -(global as any).win = win; +(global as any).scrollArea = scrollArea; diff --git a/src/lib/QtWidgets/QScrollArea.ts b/src/lib/QtWidgets/QScrollArea.ts index 35d3f6679..c4d3b737a 100644 --- a/src/lib/QtWidgets/QScrollArea.ts +++ b/src/lib/QtWidgets/QScrollArea.ts @@ -25,6 +25,7 @@ export class QScrollArea extends QAbstractScrollArea { // react:✓, //TODO:getter this.contentWidget = widget; this.native.setWidget(widget.native); + this.contentWidget.setFlexNodeSizeControlled(this.widgetResizable()); } takeWidget(): NodeWidget | null { // react:✓ @@ -38,6 +39,9 @@ export class QScrollArea extends QAbstractScrollArea { } setWidgetResizable(resizable: boolean): void { this.native.setWidgetResizable(resizable); + if (this.contentWidget) { + this.contentWidget.setFlexNodeSizeControlled(resizable); + } } widgetResizable(): boolean { return this.native.widgetResizable();