From 8459fc47feb4647acd1a306b4cfb2ef7094d7588 Mon Sep 17 00:00:00 2001 From: Atul R Date: Sun, 26 May 2019 20:25:45 +0200 Subject: [PATCH] Adds custom flex layout manager based on yoga --- config/application.gypi | 1 + src/cpp/core/FlexLayout/flexlayout.cpp | 105 +++++++++++++++++++++++++ src/cpp/core/FlexLayout/flexlayout.h | 32 ++++++++ 3 files changed, 138 insertions(+) create mode 100644 src/cpp/core/FlexLayout/flexlayout.cpp create mode 100644 src/cpp/core/FlexLayout/flexlayout.h diff --git a/config/application.gypi b/config/application.gypi index 3f846ad5d..4d8b95ca1 100644 --- a/config/application.gypi +++ b/config/application.gypi @@ -9,6 +9,7 @@ "../src/cpp/main.cpp", # non-wrapped cpps "../src/cpp/Extras/Utils/utils.cpp", + "../src/cpp/core/FlexLayout/flexlayout.cpp", # wrapped cpps "../src/cpp/QtGui/QApplication/qapplication_wrap.cpp", "../src/cpp/QtGui/QWidget/qwidget_wrap.cpp", diff --git a/src/cpp/core/FlexLayout/flexlayout.cpp b/src/cpp/core/FlexLayout/flexlayout.cpp new file mode 100644 index 000000000..9077466a1 --- /dev/null +++ b/src/cpp/core/FlexLayout/flexlayout.cpp @@ -0,0 +1,105 @@ +#include "flexlayout.h" +#include +#include + +FlexLayout::NodeContext *FlexLayout::getNodeContext(YGNodeRef node) const +{ + void* childContext = YGNodeGetContext(node); + NodeContext *ctx = reinterpret_cast(childContext); + return ctx; +} + +FlexLayout::FlexLayout(QWidget *parentWidget, YGNodeRef parentNode): QLayout(parentWidget) +{ + this->node = parentNode; +} + +FlexLayout::~FlexLayout() +{ + const uint32_t childCount = YGNodeGetChildCount(this->node); + for (uint32_t i = 0; i < childCount; i++) { + const YGNodeRef oldChild = YGNodeGetChild(this->node, i); + NodeContext* ctx = getNodeContext(oldChild); + delete ctx->item; + } + YGNodeRemoveAllChildren(this->node); +} + +QSize FlexLayout::sizeHint() const{ + QSize size; + int width = static_cast(YGNodeLayoutGetWidth(this->node)); + int height = static_cast(YGNodeLayoutGetHeight(this->node)); + size.setWidth(width); + size.setHeight(height); + return size; +} + +void FlexLayout::addItem(QLayoutItem * item){ + qDebug() <<"Unsupported method addItem. item:"<node, static_cast(index)); + NodeContext *ctx = getNodeContext(childNode); + return ctx->item; +} + +QLayoutItem *FlexLayout::takeAt(int index) +{ + + YGNodeRef childNode = YGNodeGetChild(this->node, static_cast(index)); + NodeContext *ctx = getNodeContext(childNode); + QLayoutItem* childLayoutItem = ctx->item; + YGNodeRemoveChild(this->node, childNode); + delete ctx; + return childLayoutItem; +} + +int FlexLayout::count() const +{ + return static_cast(YGNodeGetChildCount(this->node)); + +} + +void FlexLayout::addWidget(QWidget* childWidget, YGNodeRef childNode) +{ + uint count = YGNodeGetChildCount(this->node); + YGNodeInsertChild(this->node,childNode, count); + QLayoutItem* layoutItem = new QWidgetItem(childWidget); + NodeContext* childContext = new NodeContext(layoutItem); + YGNodeSetContext(childNode, static_cast(childContext)); +} + +void FlexLayout::setGeometry(const QRect &rect) +{ + + int availableWidth = rect.width(); + int availableHeight = rect.height(); + YGDirection direction = YGDirection::YGDirectionLTR; //TODO + + YGNodeCalculateLayout(this->node,availableWidth,availableHeight,direction); + + uint count = YGNodeGetChildCount(this->node); + + for (uint i = 0; i < count; ++i) { + YGNode *childNode = YGNodeGetChild(this->node, i); + int width = static_cast(YGNodeLayoutGetWidth(childNode)); + int height = static_cast(YGNodeLayoutGetHeight(childNode)); + int left = static_cast(YGNodeLayoutGetLeft(childNode)); + int top = static_cast(YGNodeLayoutGetTop(childNode)); + + QRect childRect(left, top,width, height); + NodeContext *ctx = getNodeContext(childNode); + QLayoutItem* childLayoutItem = ctx->item; + QWidget* childWidget = childLayoutItem->widget(); + + if(childWidget){ + childWidget->setGeometry(childRect); + }else { + childLayoutItem->setGeometry(childRect); + } + } + QLayout::setGeometry(rect); +} + diff --git a/src/cpp/core/FlexLayout/flexlayout.h b/src/cpp/core/FlexLayout/flexlayout.h new file mode 100644 index 000000000..d080c2686 --- /dev/null +++ b/src/cpp/core/FlexLayout/flexlayout.h @@ -0,0 +1,32 @@ +#ifndef FLEXLAYOUT_H +#define FLEXLAYOUT_H + +#include "deps/yoga/YGNode.h" +#include + +class FlexLayout: public QLayout +{ +private: + YGNodeRef node; + struct NodeContext + { + NodeContext(QLayoutItem *i) { + item = i; + } + QLayoutItem *item; + }; + NodeContext* getNodeContext(YGNodeRef node) const; + +public: + FlexLayout(QWidget* parentWidget, YGNodeRef parentNode); + ~FlexLayout() override; + QSize sizeHint() const override; + void addItem(QLayoutItem *) override; + QLayoutItem *itemAt(int index) const override; + QLayoutItem *takeAt(int index) override; + int count() const override; + void addWidget(QWidget* childWidget, YGNodeRef childNode); + void setGeometry(const QRect &rect) override; +}; + +#endif // FLEXLAYOUT_H