add doric layout
This commit is contained in:
		| @@ -46,6 +46,7 @@ SOURCES += \ | ||||
|         shader/DoricViewNode.cpp \ | ||||
|         utils/DoricConstant.cpp \ | ||||
|         utils/DoricContextHolder.cpp \ | ||||
|         utils/DoricLayouts.cpp \ | ||||
|         utils/DoricMouseAreaBridge.cpp \ | ||||
|         widget/flex/FlexLayout.cpp \ | ||||
|         widget/flex/FlexLayoutConfig.cpp \ | ||||
| @@ -114,6 +115,7 @@ HEADERS += \ | ||||
|     utils/DoricConstant.h \ | ||||
|     utils/DoricContextHolder.h \ | ||||
|     utils/DoricCountDownLatch.h \ | ||||
|     utils/DoricLayouts.h \ | ||||
|     utils/DoricMouseAreaBridge.h \ | ||||
|     utils/DoricObjectFactory.h \ | ||||
|     utils/DoricThreadMode.h \ | ||||
|   | ||||
| @@ -20,10 +20,12 @@ void DoricShaderPlugin::render(QString jsValueString, QString callbackId) { | ||||
|               jsValue["type"].toString() == "Root") { | ||||
|             rootNode->setId(viewId); | ||||
|             rootNode->blend(jsValue["props"]); | ||||
|             rootNode->requestLayout(); | ||||
|           } else { | ||||
|             DoricViewNode *viewNode = getContext()->targetViewNode(viewId); | ||||
|             if (viewNode != nullptr) { | ||||
|               viewNode->blend(jsValue["props"]); | ||||
|               viewNode->requestLayout(); | ||||
|             } | ||||
|           } | ||||
|         } catch (...) { | ||||
|   | ||||
| @@ -3,21 +3,15 @@ import QtQuick.Controls 2.5 | ||||
| import QtQuick.Layouts 1.15 | ||||
|  | ||||
| import "util.mjs" as Util | ||||
| import "gravity.mjs" as Gravity | ||||
|  | ||||
| Rectangle { | ||||
|     property var wrapper | ||||
|  | ||||
|     clip: true | ||||
|  | ||||
|     property var tag: "HLayout" | ||||
|  | ||||
|     property var uuid: Util.uuidv4() | ||||
|  | ||||
|     property int widthSpec: 0 | ||||
|     property int heightSpec: 0 | ||||
|     property int childrenRectWidth: childrenRect.width | ||||
|     property int childrenRectHeight: childrenRect.height | ||||
|     property var tag: "HLayout" | ||||
|  | ||||
|     onWidthChanged: { | ||||
|         console.log(tag, uuid + " onWidthChanged: " + this.width) | ||||
| @@ -27,41 +21,6 @@ Rectangle { | ||||
|         console.log(tag, uuid + " onHeightChanged: " + this.height) | ||||
|     } | ||||
|  | ||||
|     onWidthSpecChanged: { | ||||
|         console.log(tag, uuid + " onWidthSpecChanged: " + this.widthSpec) | ||||
|         console.log(tag, uuid + " parent width: " + parent.width) | ||||
|  | ||||
|         if (this.widthSpec === 2) { | ||||
|             this.width = parent.width | ||||
|             children[1].width = parent.width | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     onHeightSpecChanged: { | ||||
|         console.log(tag, uuid + " onHeightSpecChanged: " + this.heightSpec) | ||||
|         console.log(tag, uuid + " parent height: " + parent.height) | ||||
|  | ||||
|         if (this.heightSpec === 2) { | ||||
|             this.height = parent.height | ||||
|             children[1].height = parent.height | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     onChildrenRectChanged: { | ||||
|         console.log(tag, uuid + " widthSpec: " + widthSpec + " heightSpec: " + heightSpec) | ||||
|         console.log(tag, uuid + " onChildrenRectChanged: " + childrenRect) | ||||
|         this.childrenRectWidth = childrenRect.width | ||||
|         this.childrenRectHeight = childrenRect.height | ||||
|  | ||||
|         if (this.widthSpec === 1) { | ||||
|             this.width = childrenRectWidth | ||||
|         } | ||||
|  | ||||
|         if (this.heightSpec === 1) { | ||||
|             this.height = childrenRectHeight | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     color: 'transparent' | ||||
|  | ||||
|     property var backgroundColor | ||||
| @@ -77,47 +36,4 @@ Rectangle { | ||||
|             mouseAreaBridge.onClick(wrapper) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     RowLayout { | ||||
|         property int gravity: 0 | ||||
|  | ||||
|         spacing: 0 | ||||
|  | ||||
|         Item { | ||||
|             id: head | ||||
|             objectName: "head" | ||||
|         } | ||||
|  | ||||
|         onChildrenChanged: { | ||||
|             console.log(tag, uuid + " gravity: " + gravity) | ||||
|             for (var i = 0;i !== children.length;i++) { | ||||
|                 if (children[i] !== head && children[i] !== tail) { | ||||
|                     switch(this.gravity) { | ||||
|                         case Gravity.enumerate().CENTER_X: | ||||
|                             children[i].Layout.alignment = Qt.AlignHCenter | ||||
|                             break | ||||
|                         case Gravity.enumerate().CENTER: | ||||
|                             children[i].Layout.alignment = Qt.AlignCenter | ||||
|                             break | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (parent.widthSpec == 1) { | ||||
|                 tail.Layout.fillWidth = false | ||||
|             } else { | ||||
|                 if (gravity === Gravity.enumerate().CENTER || gravity === Gravity.enumerate().CENTER_X) { | ||||
|                     head.Layout.fillWidth = true | ||||
|                 } else { | ||||
|                     head.Layout.fillWidth = false | ||||
|                 } | ||||
|                 tail.Layout.fillWidth = true | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Item { | ||||
|             id: tail | ||||
|             objectName: "tail" | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -11,11 +11,6 @@ Rectangle { | ||||
|  | ||||
|     property var uuid: Util.uuidv4() | ||||
|  | ||||
|     property int widthSpec: 0 | ||||
|     property int heightSpec: 0 | ||||
|     property int childrenRectWidth: childrenRect.width | ||||
|     property int childrenRectHeight: childrenRect.height | ||||
|  | ||||
|     property var tag: "Stack" | ||||
|  | ||||
|     onWidthChanged: { | ||||
| @@ -26,38 +21,6 @@ Rectangle { | ||||
|         console.log(tag, uuid + " onHeightChanged: " + this.height) | ||||
|     } | ||||
|  | ||||
|     onWidthSpecChanged: { | ||||
|         console.log(tag, uuid + " onWidthSpecChanged: " + this.widthSpec) | ||||
|         console.log(tag, uuid + " parent width: " + parent.width) | ||||
|         if (this.widthSpec === 2) { | ||||
|             this.width = parent.width | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     onHeightSpecChanged: { | ||||
|         console.log(tag, uuid + " onHeightSpecChanged: " + this.heightSpec) | ||||
|         console.log(tag, uuid + " parent height: " + parent.height) | ||||
|  | ||||
|         if (this.heightSpec === 2) { | ||||
|             this.height = parent.height | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     onChildrenRectChanged: { | ||||
|         console.log(tag, uuid + " widthSpec: " + widthSpec + " heightSpec: " + heightSpec) | ||||
|         console.log(tag, uuid + " onChildrenRectChanged: " + childrenRect) | ||||
|         this.childrenRectWidth = childrenRect.width | ||||
|         this.childrenRectHeight = childrenRect.height | ||||
|  | ||||
|         if (this.widthSpec === 1) { | ||||
|             this.width = childrenRectWidth | ||||
|         } | ||||
|  | ||||
|         if (this.heightSpec === 1) { | ||||
|             this.height = childrenRectHeight | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     color: 'transparent' | ||||
|  | ||||
|     property var backgroundColor | ||||
|   | ||||
| @@ -39,11 +39,13 @@ TextArea { | ||||
|     } | ||||
|  | ||||
|     onWidthChanged: { | ||||
|         bg.implicitWidth = width | ||||
| //        bg.implicitWidth = width | ||||
|         console.log(tag, uuid + " onWidthChanged: " + this.width) | ||||
|     } | ||||
|  | ||||
|     onHeightChanged: { | ||||
|         bg.implicitHeight = height | ||||
| //        bg.implicitHeight = height | ||||
|         console.log(tag, uuid + " onHeightChanged: " + this.height) | ||||
|     } | ||||
|  | ||||
|     MouseArea { | ||||
|   | ||||
| @@ -3,21 +3,15 @@ import QtQuick.Controls 2.5 | ||||
| import QtQuick.Layouts 1.15 | ||||
|  | ||||
| import "util.mjs" as Util | ||||
| import "gravity.mjs" as Gravity | ||||
|  | ||||
| Rectangle { | ||||
|     property var wrapper | ||||
|  | ||||
|     clip: true | ||||
|  | ||||
|     property var tag: "VLayout" | ||||
|  | ||||
|     property var uuid: Util.uuidv4() | ||||
|  | ||||
|     property int widthSpec: 0 | ||||
|     property int heightSpec: 0 | ||||
|     property int childrenRectWidth: childrenRect.width | ||||
|     property int childrenRectHeight: childrenRect.height | ||||
|     property var tag: "VLayout" | ||||
|  | ||||
|     onWidthChanged: { | ||||
|         console.log(tag, uuid + " onWidthChanged: " + this.width) | ||||
| @@ -27,41 +21,6 @@ Rectangle { | ||||
|         console.log(tag, uuid + " onHeightChanged: " + this.height) | ||||
|     } | ||||
|  | ||||
|     onWidthSpecChanged: { | ||||
|         console.log(tag, uuid + " onWidthSpecChanged: " + this.widthSpec) | ||||
|         console.log(tag, uuid + " parent width: " + parent.width) | ||||
|  | ||||
|         if (this.widthSpec === 2) { | ||||
|             this.width = parent.width | ||||
|             children[1].width = parent.width | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     onHeightSpecChanged: { | ||||
|         console.log(tag, uuid + " onHeightSpecChanged: " + this.heightSpec) | ||||
|         console.log(tag, uuid + " parent height: " + parent.height) | ||||
|  | ||||
|         if (this.heightSpec === 2) { | ||||
|             this.height = parent.height | ||||
|             children[1].height = parent.height | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     onChildrenRectChanged: { | ||||
|         console.log(tag, uuid + " widthSpec: " + widthSpec + " heightSpec: " + heightSpec) | ||||
|         console.log(tag, uuid + " onChildrenRectChanged: " + childrenRect) | ||||
|         this.childrenRectWidth = childrenRect.width | ||||
|         this.childrenRectHeight = childrenRect.height | ||||
|  | ||||
|         if (this.widthSpec === 1) { | ||||
|             this.width = childrenRectWidth | ||||
|         } | ||||
|  | ||||
|         if (this.heightSpec === 1) { | ||||
|             this.height = childrenRectHeight | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     color: 'transparent' | ||||
|  | ||||
|     property var backgroundColor | ||||
| @@ -77,48 +36,4 @@ Rectangle { | ||||
|             mouseAreaBridge.onClick(wrapper) | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     ColumnLayout { | ||||
|         property int gravity: 0 | ||||
|  | ||||
|         spacing: 0 | ||||
|  | ||||
|         Item { | ||||
|             id: head | ||||
|             objectName: "head" | ||||
|         } | ||||
|  | ||||
|         onChildrenChanged: { | ||||
|             console.log(tag, uuid + " gravity: " + gravity) | ||||
|  | ||||
|             for (var i = 0;i !== children.length;i++) { | ||||
|                 if (children[i] !== head && children[i] !== tail) { | ||||
|                     switch(this.gravity) { | ||||
|                         case Gravity.enumerate().CENTER_X: | ||||
|                             children[i].Layout.alignment = Qt.AlignHCenter | ||||
|                             break | ||||
|                         case Gravity.enumerate().CENTER: | ||||
|                             children[i].Layout.alignment = Qt.AlignCenter | ||||
|                             break | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
|             if (parent.heightSpec == 1) { | ||||
|                 tail.Layout.fillHeight = false | ||||
|             } else { | ||||
|                 if (gravity === Gravity.enumerate().CENTER || gravity === Gravity.enumerate().CENTER_Y) { | ||||
|                     head.Layout.fillHeight = true | ||||
|                 } else { | ||||
|                     head.Layout.fillHeight = false | ||||
|                 } | ||||
|                 tail.Layout.fillHeight = true | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         Item { | ||||
|             id: tail | ||||
|             objectName: "tail" | ||||
|         } | ||||
|     } | ||||
| } | ||||
|   | ||||
| @@ -20,16 +20,13 @@ void DoricGroupNode::blend(QQuickItem *view, QString name, QJsonValue prop) { | ||||
|  | ||||
| void DoricGroupNode::blend(QJsonValue jsValue) { | ||||
|   DoricViewNode::blend(jsValue); | ||||
|   configChildNode(); | ||||
| } | ||||
|  | ||||
| void DoricGroupNode::afterBlended(QJsonValue props) { configChildNode(); } | ||||
|  | ||||
| void DoricGroupNode::configChildNode() { | ||||
|   QQuickItem *parent = nullptr; | ||||
|   if (mType == "HLayout" || mType == "VLayout") { | ||||
|     parent = mView->childItems().at(1); | ||||
|   } else { | ||||
|     parent = mView; | ||||
|   } | ||||
|   QQuickItem *parent = mView; | ||||
|  | ||||
|   for (int idx = 0; idx < mChildViewIds.size(); idx++) { | ||||
|     QString id = mChildViewIds.at(idx); | ||||
|     QJsonValue model = getSubModel(id); | ||||
| @@ -140,23 +137,6 @@ void DoricGroupNode::configChildNode() { | ||||
|     viewNode->getNodeView()->setParentItem(nullptr); | ||||
|     viewNode->getNodeView()->deleteLater(); | ||||
|   } | ||||
|  | ||||
|   // handle tail | ||||
|   if (mType == "VLayout" || mType == "HLayout") { | ||||
|       int tailIndex = -1; | ||||
|       for (int idx = 0; idx < parent->childItems().size(); idx++) { | ||||
|         if (parent->childItems().at(idx)->objectName() == "tail") { | ||||
|           tailIndex = idx; | ||||
|           break; | ||||
|         } | ||||
|       } | ||||
|       if (tailIndex != -1 && tailIndex != parent->childItems().size() - 1) { | ||||
|         QQuickItem *tail = parent->childItems().at(tailIndex); | ||||
|         tail->setParentItem(nullptr); | ||||
|         tail->setParentItem(parent); | ||||
|       } | ||||
|   } | ||||
|  | ||||
| } | ||||
|  | ||||
| void DoricGroupNode::blendSubNode(QJsonValue subProperties) { | ||||
| @@ -168,3 +148,8 @@ void DoricGroupNode::blendSubNode(QJsonValue subProperties) { | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| void DoricGroupNode::requestLayout() { | ||||
|   DoricSuperNode::requestLayout(); | ||||
|   foreach (DoricViewNode *node, this->mChildNodes) { node->requestLayout(); } | ||||
| } | ||||
|   | ||||
| @@ -19,6 +19,10 @@ protected: | ||||
|   void configChildNode(); | ||||
|  | ||||
|   virtual void blendSubNode(QJsonValue subProperties) override; | ||||
|  | ||||
|   virtual void afterBlended(QJsonValue props) override; | ||||
|  | ||||
|   virtual void requestLayout() override; | ||||
| }; | ||||
|  | ||||
| #endif // DORICGROUPNODE_H | ||||
|   | ||||
| @@ -11,16 +11,20 @@ QQuickItem *DoricHLayoutNode::build() { | ||||
|   } | ||||
|  | ||||
|   QQuickItem *item = qobject_cast<QQuickItem *>(component.create()); | ||||
|   this->createLayouts(item); | ||||
|  | ||||
|   getLayouts()->setLayoutType(DoricLayoutType::DoricHLayout); | ||||
|  | ||||
|   item->setProperty("wrapper", QString::number((qint64)this)); | ||||
|   return item; | ||||
| } | ||||
|  | ||||
| void DoricHLayoutNode::blend(QQuickItem *view, QString name, QJsonValue prop) { | ||||
|   QQuickItem *container = view->childItems().at(1); | ||||
|   QQuickItem *container = view; | ||||
|   if (name == "space") { | ||||
|     container->setProperty("spacing", prop.toInt()); | ||||
|     getLayouts()->setSpacing(prop.toInt()); | ||||
|   } else if (name == "gravity") { | ||||
|     container->setProperty("gravity", prop.toInt()); | ||||
|     getLayouts()->setGravity(prop.toInt()); | ||||
|   } else { | ||||
|     DoricGroupNode::blend(view, name, prop); | ||||
|   } | ||||
|   | ||||
| @@ -2,4 +2,12 @@ | ||||
|  | ||||
| void DoricRootNode::setRootView(QQuickItem *rootView) { | ||||
|   this->mView = rootView; | ||||
|   this->createLayouts(rootView); | ||||
|  | ||||
|   this->getLayouts()->setLayoutType(DoricLayoutType::DoricStack); | ||||
| } | ||||
|  | ||||
| void DoricRootNode::requestLayout() { | ||||
|   getLayouts()->apply(); | ||||
|   DoricStackNode::requestLayout(); | ||||
| } | ||||
|   | ||||
| @@ -10,6 +10,8 @@ public: | ||||
|   using DoricStackNode::DoricStackNode; | ||||
|  | ||||
|   void setRootView(QQuickItem *rootView); | ||||
|  | ||||
|   virtual void requestLayout() override; | ||||
| }; | ||||
|  | ||||
| #endif // ROOTNODE_H | ||||
|   | ||||
| @@ -11,6 +11,10 @@ QQuickItem *DoricStackNode::build() { | ||||
|   } | ||||
|  | ||||
|   QQuickItem *item = qobject_cast<QQuickItem *>(component.create()); | ||||
|   this->createLayouts(item); | ||||
|  | ||||
|   getLayouts()->setLayoutType(DoricLayoutType::DoricStack); | ||||
|  | ||||
|   item->setProperty("wrapper", QString::number((qint64)this)); | ||||
|   return item; | ||||
| } | ||||
|   | ||||
| @@ -54,10 +54,3 @@ void DoricSuperNode::blendSubLayoutConfig(DoricViewNode *viewNode, | ||||
|                                           QJsonValue jsValue) { | ||||
|   viewNode->blendLayoutConfig(jsValue); | ||||
| } | ||||
|  | ||||
| QJsonValue DoricSuperNode::generateDefaultLayoutConfig() { | ||||
|   QJsonObject layoutConfig; | ||||
|   layoutConfig.insert("widthSpec", SpecMode::JUST); | ||||
|   layoutConfig.insert("heightSpec", SpecMode::JUST); | ||||
|   return layoutConfig; | ||||
| } | ||||
|   | ||||
| @@ -23,8 +23,6 @@ public: | ||||
|  | ||||
|   void blendSubLayoutConfig(DoricViewNode *viewNode, QJsonValue jsValue); | ||||
|  | ||||
|   QJsonValue generateDefaultLayoutConfig(); | ||||
|  | ||||
| private: | ||||
|   void mixinSubNode(QJsonValue subNode); | ||||
|  | ||||
|   | ||||
| @@ -12,6 +12,7 @@ QQuickItem *DoricTextNode::build() { | ||||
|   } | ||||
|  | ||||
|   QQuickItem *item = qobject_cast<QQuickItem *>(component.create()); | ||||
|   this->createLayouts(item); | ||||
|  | ||||
|   item->setProperty("wrapper", QString::number((qint64)this)); | ||||
|   return item; | ||||
|   | ||||
| @@ -11,16 +11,20 @@ QQuickItem *DoricVLayoutNode::build() { | ||||
|   } | ||||
|  | ||||
|   QQuickItem *item = qobject_cast<QQuickItem *>(component.create()); | ||||
|   this->createLayouts(item); | ||||
|  | ||||
|   getLayouts()->setLayoutType(DoricLayoutType::DoricVLayout); | ||||
|  | ||||
|   item->setProperty("wrapper", QString::number((qint64)this)); | ||||
|   return item; | ||||
| } | ||||
|  | ||||
| void DoricVLayoutNode::blend(QQuickItem *view, QString name, QJsonValue prop) { | ||||
|   QQuickItem *container = view->childItems().at(1); | ||||
|   QQuickItem *container = view; | ||||
|   if (name == "space") { | ||||
|     container->setProperty("spacing", prop.toInt()); | ||||
|     getLayouts()->setSpacing(prop.toInt()); | ||||
|   } else if (name == "gravity") { | ||||
|     container->setProperty("gravity", prop.toInt()); | ||||
|     getLayouts()->setGravity(prop.toInt()); | ||||
|   } else { | ||||
|     DoricGroupNode::blend(view, name, prop); | ||||
|   } | ||||
|   | ||||
| @@ -3,42 +3,62 @@ | ||||
| #include "../utils/DoricUtils.h" | ||||
| #include "DoricSuperNode.h" | ||||
|  | ||||
| void DoricViewNode::blendLayoutConfig(QJsonValue jsObject) { | ||||
|   this->mLayoutConfig = jsObject; | ||||
| void DoricViewNode::blendLayoutConfig(QJsonValue jsValue) { | ||||
|   QJsonObject jsObject = jsValue.toObject(); | ||||
|   if (jsObject.contains("widthSpec")) | ||||
|     getLayouts()->setWidthSpec(jsObject["widthSpec"].toInt()); | ||||
|  | ||||
|   QJsonValue margin = jsObject["margin"]; | ||||
|   QJsonValue widthSpec = jsObject["widthSpec"]; | ||||
|   QJsonValue heightSpec = jsObject["heightSpec"]; | ||||
|   if (jsObject.contains("heightSpec")) | ||||
|     getLayouts()->setHeightSpec(jsObject["heightSpec"].toInt()); | ||||
|  | ||||
|   if (widthSpec.isDouble()) { | ||||
|     switch (widthSpec.toInt()) { | ||||
|     case SpecMode::JUST: | ||||
|       mView->setProperty("widthSpec", SpecMode::JUST); | ||||
|       break; | ||||
|     case SpecMode::FIT: | ||||
|       mView->setProperty("widthSpec", SpecMode::FIT); | ||||
|       break; | ||||
|     case SpecMode::MOST: | ||||
|       mView->setProperty("widthSpec", SpecMode::MOST); | ||||
|       break; | ||||
|     } | ||||
|   if (jsObject.contains("margin")) { | ||||
|     QJsonObject margin = jsObject["margin"].toObject(); | ||||
|  | ||||
|     if (margin.contains("left")) | ||||
|       getLayouts()->setMarginLeft(margin["left"].toInt()); | ||||
|  | ||||
|     if (margin.contains("top")) | ||||
|       getLayouts()->setMarginTop(margin["top"].toInt()); | ||||
|  | ||||
|     if (margin.contains("right")) | ||||
|       getLayouts()->setMarginRight(margin["right"].toInt()); | ||||
|  | ||||
|     if (margin.contains("bottom")) | ||||
|       getLayouts()->setMarginBottom(margin["bottom"].toInt()); | ||||
|   } | ||||
|  | ||||
|   if (heightSpec.isDouble()) { | ||||
|     switch (heightSpec.toInt()) { | ||||
|     case SpecMode::JUST: | ||||
|       mView->setProperty("heightSpec", SpecMode::JUST); | ||||
|       break; | ||||
|     case SpecMode::FIT: | ||||
|       mView->setProperty("heightSpec", SpecMode::FIT); | ||||
|       break; | ||||
|     case SpecMode::MOST: | ||||
|       mView->setProperty("heightSpec", SpecMode::MOST); | ||||
|       break; | ||||
|     } | ||||
|   if (jsObject.contains("alignment")) | ||||
|     getLayouts()->setAlignment(jsObject["alignment"].toInt()); | ||||
|  | ||||
|   if (jsObject.contains("weight")) | ||||
|     getLayouts()->setWeight(jsObject["weight"].toInt()); | ||||
|  | ||||
|   if (jsObject.contains("maxWidth")) | ||||
|     getLayouts()->setMaxWidth(jsObject["maxWidth"].toInt()); | ||||
|  | ||||
|   if (jsObject.contains("maxHeight")) | ||||
|     getLayouts()->setMaxHeight(jsObject["maxHeight"].toInt()); | ||||
|  | ||||
|   if (jsObject.contains("minWidth")) | ||||
|     getLayouts()->setMinWidth(jsObject["minWidth"].toInt()); | ||||
|  | ||||
|   if (jsObject.contains("minHeight")) | ||||
|     getLayouts()->setMinHeight(jsObject["minHeight"].toInt()); | ||||
| } | ||||
|  | ||||
| void DoricViewNode::createLayouts(QQuickItem *view) { | ||||
|   if (mLayouts == nullptr) { | ||||
|     mLayouts = new DoricLayouts(); | ||||
|     mLayouts->setWidth(view->width()); | ||||
|     mLayouts->setHeight(view->height()); | ||||
|     mLayouts->setView(view); | ||||
|  | ||||
|     view->setProperty("doricLayout", QString::number((qint64)mLayouts)); | ||||
|   } | ||||
| } | ||||
|  | ||||
| DoricLayouts *DoricViewNode::getLayouts() { return mLayouts; } | ||||
|  | ||||
| void DoricViewNode::setLayoutConfig(QJsonValue layoutConfig) { | ||||
|   if (mSuperNode != nullptr) { | ||||
|     mSuperNode->blendSubLayoutConfig(this, layoutConfig); | ||||
| @@ -53,8 +73,8 @@ void DoricViewNode::init(DoricSuperNode *superNode) { | ||||
|     thiz->mReusable = superNode->mReusable; | ||||
|   } | ||||
|   this->mSuperNode = superNode; | ||||
|   this->mLayoutConfig = superNode->generateDefaultLayoutConfig(); | ||||
|   this->mView = build(); | ||||
|   getLayouts(); | ||||
| } | ||||
|  | ||||
| QString DoricViewNode::getId() { return mId; } | ||||
| @@ -75,54 +95,41 @@ void DoricViewNode::blend(QJsonValue jsValue) { | ||||
|     QJsonValue value = jsValue[key]; | ||||
|     blend(mView, key, value); | ||||
|   } | ||||
|  | ||||
|   this->afterBlended(jsValue); | ||||
| } | ||||
|  | ||||
| void DoricViewNode::blend(QQuickItem *view, QString name, QJsonValue prop) { | ||||
|   if (name == "width") { | ||||
|     if (!prop.isDouble()) { | ||||
|       return; | ||||
|     } | ||||
|     if (this->mLayoutConfig.isUndefined()) { | ||||
|       view->setWidth(prop.toInt()); | ||||
|     } else { | ||||
|       QJsonValue widthSpec = this->mLayoutConfig["widthSpec"]; | ||||
|       if (widthSpec.isDouble()) { | ||||
|         if (widthSpec.toInt() == SpecMode::JUST) { | ||||
|           view->setWidth(prop.toInt()); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     getLayouts()->setWidth(prop.toInt()); | ||||
|   } else if (name == "height") { | ||||
|     if (!prop.isDouble()) { | ||||
|       return; | ||||
|     } | ||||
|     if (this->mLayoutConfig.isUndefined()) { | ||||
|       view->setHeight(prop.toInt()); | ||||
|     } else { | ||||
|       QJsonValue heightSpec = this->mLayoutConfig["heightSpec"]; | ||||
|       if (heightSpec.isDouble()) { | ||||
|         if (heightSpec.toInt() == SpecMode::JUST) { | ||||
|           view->setHeight(prop.toInt()); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     getLayouts()->setHeight(prop.toInt()); | ||||
|   } else if (name == "backgroundColor") { | ||||
|     QString color = DoricUtils::doricColor(prop.toInt()).name(); | ||||
|     view->setProperty("backgroundColor", color); | ||||
|   } else if (name == "x") { | ||||
|     view->setProperty("x", prop.toInt()); | ||||
|     getLayouts()->setMarginLeft(prop.toInt()); | ||||
|   } else if (name == "y") { | ||||
|     view->setProperty("y", prop.toInt()); | ||||
|     getLayouts()->setMarginRight(prop.toInt()); | ||||
|   } else if (name == "corners") { | ||||
|     view->setProperty("radius", prop.toInt()); | ||||
|   } else if (name == "onClick") { | ||||
|     if (prop.isString()) | ||||
|       clickFunction = prop.toString(); | ||||
|   } else if (name == "padding") { | ||||
|     getLayouts()->setPaddingLeft(prop["left"].toInt()); | ||||
|     getLayouts()->setPaddingRight(prop["right"].toInt()); | ||||
|     getLayouts()->setPaddingTop(prop["top"].toInt()); | ||||
|     getLayouts()->setPaddingBottom(prop["bottom"].toInt()); | ||||
|   } else if (name == "hidden") { | ||||
|     getLayouts()->setDisabled(prop.toBool()); | ||||
|   } else if (name != "layoutConfig") { | ||||
|     qCritical() << name << ": " << prop.toString(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void DoricViewNode::afterBlended(QJsonValue prop) {} | ||||
|  | ||||
| QList<QString> DoricViewNode::getIdList() { | ||||
|   QList<QString> ids; | ||||
|  | ||||
| @@ -135,6 +142,8 @@ QList<QString> DoricViewNode::getIdList() { | ||||
|   return ids; | ||||
| } | ||||
|  | ||||
| void DoricViewNode::requestLayout() {} | ||||
|  | ||||
| void DoricViewNode::callJSResponse(QString funcId, QVariantList args) { | ||||
|   QVariantList nArgs; | ||||
|   QList<QString> idList = getIdList(); | ||||
|   | ||||
| @@ -6,13 +6,7 @@ | ||||
| #include <QQuickItem> | ||||
|  | ||||
| #include "../utils/DoricContextHolder.h" | ||||
|  | ||||
| class SpecMode { | ||||
| public: | ||||
|   const static int JUST = 0; | ||||
|   const static int FIT = 1; | ||||
|   const static int MOST = 2; | ||||
| }; | ||||
| #include "../utils/DoricLayouts.h" | ||||
|  | ||||
| class DoricSuperNode; | ||||
|  | ||||
| @@ -21,17 +15,21 @@ class DoricViewNode : public DoricContextHolder { | ||||
| protected: | ||||
|   QQuickItem *mView; | ||||
|  | ||||
|   DoricLayouts *mLayouts = nullptr; | ||||
|  | ||||
|   DoricSuperNode *mSuperNode = nullptr; | ||||
|  | ||||
|   virtual QQuickItem *build() = 0; | ||||
|  | ||||
|   void createLayouts(QQuickItem *view); | ||||
|  | ||||
|   DoricLayouts *getLayouts(); | ||||
|  | ||||
|   void setLayoutConfig(QJsonValue layoutConfig); | ||||
|  | ||||
| private: | ||||
|   QString mId; | ||||
|  | ||||
|   QJsonValue mLayoutConfig; | ||||
|  | ||||
|   QList<QString> getIdList(); | ||||
|  | ||||
|   QString clickFunction; | ||||
| @@ -70,8 +68,12 @@ public: | ||||
|  | ||||
|   virtual void blend(QQuickItem *view, QString name, QJsonValue prop); | ||||
|  | ||||
|   virtual void afterBlended(QJsonValue prop); | ||||
|  | ||||
|   virtual void blendLayoutConfig(QJsonValue jsObject); | ||||
|  | ||||
|   virtual void requestLayout(); | ||||
|  | ||||
|   void onClick(); | ||||
|  | ||||
|   void callJSResponse(QString funcId, QVariantList args); | ||||
|   | ||||
							
								
								
									
										660
									
								
								doric-Qt/doric/utils/DoricLayouts.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										660
									
								
								doric-Qt/doric/utils/DoricLayouts.cpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,660 @@ | ||||
| #include "DoricLayouts.h" | ||||
|  | ||||
| DoricLayouts::DoricLayouts() { | ||||
|   this->widthSpec = DoricLayoutSpec::DoricLayoutJust; | ||||
|   this->heightSpec = DoricLayoutSpec::DoricLayoutJust; | ||||
|   this->maxWidth = 32767; | ||||
|   this->maxHeight = 32767; | ||||
|   this->minWidth = 0; | ||||
|   this->minHeight = 0; | ||||
| } | ||||
|  | ||||
| void DoricLayouts::setWidthSpec(int widthSpec) { this->widthSpec = widthSpec; } | ||||
| void DoricLayouts::setHeightSpec(int heightSpec) { | ||||
|   this->heightSpec = heightSpec; | ||||
| } | ||||
|  | ||||
| void DoricLayouts::setAlignment(int alignment) { this->alignment = alignment; } | ||||
|  | ||||
| void DoricLayouts::setGravity(int gravity) { this->gravity = gravity; } | ||||
|  | ||||
| void DoricLayouts::setWidth(int width) { this->width = width; } | ||||
| void DoricLayouts::setHeight(int height) { this->height = height; } | ||||
|  | ||||
| void DoricLayouts::setSpacing(int spacing) { this->spacing = spacing; } | ||||
|  | ||||
| void DoricLayouts::setMarginLeft(int marginLeft) { | ||||
|   this->marginLeft = marginLeft; | ||||
| } | ||||
| void DoricLayouts::setMarginTop(int marginTop) { this->marginTop = marginTop; } | ||||
| void DoricLayouts::setMarginRight(int marginRight) { | ||||
|   this->marginRight = marginRight; | ||||
| } | ||||
| void DoricLayouts::setMarginBottom(int marginBottom) { | ||||
|   this->marginBottom = marginBottom; | ||||
| } | ||||
|  | ||||
| void DoricLayouts::setPaddingLeft(int paddingLeft) { | ||||
|   this->paddingLeft = paddingLeft; | ||||
| } | ||||
| void DoricLayouts::setPaddingTop(int paddingTop) { | ||||
|   this->paddingTop = paddingTop; | ||||
| } | ||||
| void DoricLayouts::setPaddingRight(int paddingRight) { | ||||
|   this->paddingRight = paddingRight; | ||||
| } | ||||
| void DoricLayouts::setPaddingBottom(int paddingBottom) { | ||||
|   this->paddingBottom = paddingBottom; | ||||
| } | ||||
|  | ||||
| void DoricLayouts::setWeight(int weight) { this->weight = weight; } | ||||
|  | ||||
| void DoricLayouts::setView(QQuickItem *view) { | ||||
|   this->view = view; | ||||
|   this->tag = view->property("tag").toString(); | ||||
| } | ||||
|  | ||||
| void DoricLayouts::setLayoutType(int layoutType) { | ||||
|   this->layoutType = layoutType; | ||||
| } | ||||
|  | ||||
| void DoricLayouts::setDisabled(bool disabled) { this->disabled = disabled; } | ||||
|  | ||||
| void DoricLayouts::setMaxWidth(int maxWidth) { this->maxWidth = maxWidth; } | ||||
| void DoricLayouts::setMaxHeight(int maxHeight) { this->maxHeight = maxHeight; } | ||||
| void DoricLayouts::setMinWidth(int minWidth) { this->minWidth = minWidth; } | ||||
| void DoricLayouts::setMinHeight(int minHeight) { this->minHeight = minHeight; } | ||||
|  | ||||
| void DoricLayouts::apply(int targetWidth, int targetHeight) { | ||||
|   this->resolved = false; | ||||
|  | ||||
|   this->measure(targetWidth, targetHeight); | ||||
|   this->setFrame(); | ||||
|  | ||||
|   this->resolved = true; | ||||
| } | ||||
|  | ||||
| void DoricLayouts::apply() { | ||||
|   this->apply(this->view->width(), this->view->height()); | ||||
| } | ||||
|  | ||||
| void DoricLayouts::measure(int targetWidth, int targetHeight) { | ||||
|   this->measureSelf(targetWidth, targetHeight); | ||||
|   this->layout(); | ||||
| } | ||||
|  | ||||
| void DoricLayouts::measureSelf(int targetWidth, int targetHeight) { | ||||
|   // measure width | ||||
|   int width; | ||||
|   if (this->widthSpec == DoricLayoutSpec::DoricLayoutMost) { | ||||
|     QQuickItem *parent = this->view->parentItem(); | ||||
|     DoricLayouts *parentDoricLayout = | ||||
|         (DoricLayouts *)(parent->property("doricLayout").toULongLong()); | ||||
|     if (parentDoricLayout->layoutType == DoricLayoutType::DoricHLayout && | ||||
|         this->weight > 0) { | ||||
|       width = this->measuredWidth = 0; | ||||
|       setMeasuredWidth(); | ||||
|     } else { | ||||
|       width = this->measuredWidth = targetWidth; | ||||
|       setMeasuredWidth(); | ||||
|     } | ||||
|   } else if (this->widthSpec == DoricLayoutSpec::DoricLayoutJust) { | ||||
|     width = this->measuredWidth = this->width; | ||||
|     setMeasuredWidth(); | ||||
|   } else { | ||||
|     width = targetWidth; | ||||
|   } | ||||
|  | ||||
|   // measure height | ||||
|   int height; | ||||
|   if (this->heightSpec == DoricLayoutSpec::DoricLayoutMost) { | ||||
|     QQuickItem *parent = this->view->parentItem(); | ||||
|     DoricLayouts *parentDoricLayout = | ||||
|         (DoricLayouts *)(parent->property("doricLayout").toULongLong()); | ||||
|     if (parentDoricLayout->layoutType == DoricLayoutType::DoricVLayout && | ||||
|         this->weight > 0) { | ||||
|       height = this->measuredHeight = 0; | ||||
|     } else { | ||||
|       height = this->measuredHeight = targetHeight; | ||||
|     } | ||||
|   } else if (this->heightSpec == DoricLayoutSpec::DoricLayoutJust) { | ||||
|     height = this->measuredHeight = this->height; | ||||
|   } else { | ||||
|     height = targetHeight; | ||||
|   } | ||||
|  | ||||
|   // measure content | ||||
|  | ||||
|   this->measureContent(width - this->paddingLeft - this->paddingRight, | ||||
|                        height - this->paddingTop - this->paddingBottom); | ||||
|  | ||||
|   if (this->restrainSize()) { | ||||
|     this->measureContent( | ||||
|         this->measuredWidth - this->paddingLeft - this->paddingRight, | ||||
|         this->measuredHeight - this->paddingTop - this->paddingBottom); | ||||
|   } | ||||
|   this->restrainSize(); | ||||
| } | ||||
|  | ||||
| void DoricLayouts::measureContent(int targetWidth, int targetHeight) { | ||||
|   switch (this->layoutType) { | ||||
|   case DoricLayoutType::DoricStack: { | ||||
|     this->measureStackContent(targetWidth, targetHeight); | ||||
|     break; | ||||
|   } | ||||
|   case DoricLayoutType::DoricVLayout: { | ||||
|     this->measureVLayoutContent(targetWidth, targetHeight); | ||||
|     break; | ||||
|   } | ||||
|   case DoricLayoutType::DoricHLayout: { | ||||
|     this->measureHLayoutContent(targetWidth, targetHeight); | ||||
|     break; | ||||
|   } | ||||
|   default: { | ||||
|     this->measureUndefinedContent(targetWidth, targetHeight); | ||||
|     break; | ||||
|   } | ||||
|   } | ||||
|  | ||||
|   QQuickItem *parent = this->view->parentItem(); | ||||
|   DoricLayouts *parentDoricLayout = | ||||
|       (DoricLayouts *)(parent->property("doricLayout").toULongLong()); | ||||
|   if (parentDoricLayout != nullptr) { | ||||
|     if (parentDoricLayout->layoutType != DoricLayoutType::DoricUndefined && | ||||
|         parentDoricLayout->widthSpec == DoricLayoutSpec::DoricLayoutFit && | ||||
|         this->widthSpec == DoricLayoutSpec::DoricLayoutMost) { | ||||
|       this->measuredWidth = 0; | ||||
|         setMeasuredWidth(); | ||||
|     } | ||||
|     if (parentDoricLayout->layoutType != DoricLayoutType::DoricUndefined && | ||||
|         parentDoricLayout->heightSpec == DoricLayoutSpec::DoricLayoutFit && | ||||
|         this->heightSpec == DoricLayoutSpec::DoricLayoutMost) { | ||||
|       this->measuredHeight = 0; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| void DoricLayouts::measureUndefinedContent(int targetWidth, int targetHeight) { | ||||
|   int width = this->view->width(); | ||||
|   int height = this->view->height(); | ||||
|  | ||||
|   if (width > targetWidth) { | ||||
|     width = targetWidth; | ||||
|   } | ||||
|   if (height > targetHeight) { | ||||
|     height = targetHeight; | ||||
|   } | ||||
|   if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) { | ||||
|     this->measuredWidth = width + this->paddingLeft + this->paddingRight; | ||||
|       setMeasuredWidth(); | ||||
|   } | ||||
|   if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit) { | ||||
|     this->measuredHeight = height + this->paddingTop + this->paddingBottom; | ||||
|   } | ||||
| } | ||||
| void DoricLayouts::measureStackContent(int targetWidth, int targetHeight) { | ||||
|   int contentWidth = 0, contentHeight = 0; | ||||
|   foreach (QQuickItem *subview, this->view->childItems()) { | ||||
|     DoricLayouts *layout = | ||||
|         (DoricLayouts *)(subview->property("doricLayout").toULongLong()); | ||||
|     if (layout == nullptr) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (layout->disabled) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     QPair<int, int> size = layout->removeMargin(targetWidth, targetHeight); | ||||
|     layout->measure(size.first, size.second); | ||||
|     contentWidth = qMax(contentWidth, layout->takenWidth()); | ||||
|     contentHeight = qMax(contentHeight, layout->takenHeight()); | ||||
|   } | ||||
|   if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) { | ||||
|     this->measuredWidth = contentWidth + this->paddingLeft + this->paddingRight; | ||||
|       setMeasuredWidth(); | ||||
|   } | ||||
|  | ||||
|   if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit) { | ||||
|     this->measuredHeight = | ||||
|         contentHeight + this->paddingTop + this->paddingBottom; | ||||
|   } | ||||
|  | ||||
|   this->contentWidth = contentWidth; | ||||
|   this->contentHeight = contentHeight; | ||||
| } | ||||
| void DoricLayouts::measureVLayoutContent(int targetWidth, int targetHeight) { | ||||
|   int contentWidth = 0, contentHeight = 0, contentWeight = 0; | ||||
|   bool had = false; | ||||
|   foreach (QQuickItem *subview, this->view->childItems()) { | ||||
|     DoricLayouts *layout = | ||||
|         (DoricLayouts *)(subview->property("doricLayout").toULongLong()); | ||||
|     if (layout == nullptr) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (layout->disabled) { | ||||
|       continue; | ||||
|     } | ||||
|     had = true; | ||||
|  | ||||
|     QPair<int, int> pair = | ||||
|         layout->removeMargin(targetWidth, targetHeight - contentHeight); | ||||
|     layout->measure(pair.first, pair.second); | ||||
|     contentWidth = qMax(contentWidth, layout->takenWidth()); | ||||
|     contentHeight += layout->takenHeight() + this->spacing; | ||||
|     contentWeight += layout->weight; | ||||
|   } | ||||
|  | ||||
|   if (had) { | ||||
|     contentHeight -= this->spacing; | ||||
|   } | ||||
|  | ||||
|   if (contentWeight > 0) { | ||||
|     int remaining = targetHeight - contentHeight; | ||||
|     contentWidth = 0; | ||||
|     foreach (QQuickItem *subview, this->view->childItems()) { | ||||
|       DoricLayouts *layout = | ||||
|           (DoricLayouts *)(subview->property("doricLayout").toULongLong()); | ||||
|       if (layout == nullptr) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       if (layout->disabled) { | ||||
|         continue; | ||||
|       } | ||||
|       int measuredHeight = | ||||
|           layout->measuredHeight + remaining / contentWeight * layout->weight; | ||||
|       layout->measuredHeight = measuredHeight; | ||||
|       // Need Remeasure | ||||
|       layout->measureContent( | ||||
|           layout->measuredWidth - layout->paddingLeft - layout->paddingRight, | ||||
|           measuredHeight - layout->paddingTop - layout->paddingBottom); | ||||
|       layout->measuredHeight = measuredHeight; | ||||
|       contentWidth = qMax(contentWidth, layout->takenWidth()); | ||||
|     } | ||||
|     contentHeight = targetHeight; | ||||
|   } | ||||
|  | ||||
|   if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) { | ||||
|     this->measuredWidth = contentWidth + this->paddingLeft + this->paddingRight; | ||||
|       setMeasuredWidth(); | ||||
|   } | ||||
|  | ||||
|   if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit) { | ||||
|     this->measuredHeight = | ||||
|         contentHeight + this->paddingTop + this->paddingBottom; | ||||
|   } | ||||
|  | ||||
|   this->contentWidth = contentWidth; | ||||
|   this->contentHeight = contentHeight; | ||||
| } | ||||
| void DoricLayouts::measureHLayoutContent(int targetWidth, int targetHeight) { | ||||
|   int contentWidth = 0, contentHeight = 0, contentWeight = 0; | ||||
|   bool had = false; | ||||
|   foreach (QQuickItem *subview, this->view->childItems()) { | ||||
|     DoricLayouts *layout = | ||||
|         (DoricLayouts *)(subview->property("doricLayout").toULongLong()); | ||||
|     if (layout == nullptr) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (layout->disabled) { | ||||
|       continue; | ||||
|     } | ||||
|     had = true; | ||||
|     QPair<int, int> pair = | ||||
|         layout->removeMargin(targetWidth - contentWidth, targetHeight); | ||||
|     layout->measure(pair.first, pair.second); | ||||
|     contentWidth += layout->takenWidth() + this->spacing; | ||||
|     contentHeight = qMax(contentHeight, layout->takenHeight()); | ||||
|     contentWeight += layout->weight; | ||||
|   } | ||||
|  | ||||
|   if (had) { | ||||
|     contentWidth -= this->spacing; | ||||
|   } | ||||
|  | ||||
|   if (contentWeight > 0) { | ||||
|     int remaining = targetWidth - contentWidth; | ||||
|     contentHeight = 0; | ||||
|     foreach (QQuickItem *subview, this->view->childItems()) { | ||||
|       DoricLayouts *layout = | ||||
|           (DoricLayouts *)(subview->property("doricLayout").toULongLong()); | ||||
|       if (layout == nullptr) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       if (layout->disabled) { | ||||
|         continue; | ||||
|       } | ||||
|       int measuredWidth = | ||||
|           layout->measuredWidth + remaining / contentWeight * layout->weight; | ||||
|       layout->measuredWidth = measuredWidth; | ||||
|       // Need Remeasure | ||||
|       layout->measureContent( | ||||
|           measuredWidth - layout->paddingLeft - layout->paddingRight, | ||||
|           layout->measuredHeight - layout->paddingTop - layout->paddingBottom); | ||||
|       layout->measuredWidth = measuredWidth; | ||||
|       contentHeight = qMax(contentHeight, layout->takenHeight()); | ||||
|     } | ||||
|     contentWidth = targetWidth; | ||||
|   } | ||||
|  | ||||
|   if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) { | ||||
|     this->measuredWidth = contentWidth + this->paddingLeft + this->paddingRight; | ||||
|       setMeasuredWidth(); | ||||
|   } | ||||
|  | ||||
|   if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit) { | ||||
|     this->measuredHeight = | ||||
|         contentHeight + this->paddingTop + this->paddingBottom; | ||||
|   } | ||||
|  | ||||
|   this->contentWidth = contentWidth; | ||||
|   this->contentHeight = contentHeight; | ||||
| } | ||||
|  | ||||
| int DoricLayouts::takenWidth() { | ||||
|   return this->measuredWidth + this->marginLeft + this->marginRight; | ||||
| } | ||||
| int DoricLayouts::takenHeight() { | ||||
|   return this->measuredHeight + this->marginTop + this->marginBottom; | ||||
| } | ||||
| QPair<int, int> DoricLayouts::removeMargin(int targetWidth, int targetHeight) { | ||||
|   QPair<int, int> pair(targetWidth - this->marginLeft - this->marginRight, | ||||
|                        targetHeight - this->marginTop - this->marginBottom); | ||||
|   return pair; | ||||
| } | ||||
|  | ||||
| bool DoricLayouts::restrainSize() { | ||||
|   bool needRemeasure = false; | ||||
|   if (this->measuredWidth > this->maxWidth) { | ||||
|     this->measuredWidth = this->maxWidth; | ||||
|       setMeasuredWidth(); | ||||
|     needRemeasure = true; | ||||
|   } | ||||
|   if (this->measuredHeight > this->maxHeight) { | ||||
|     this->measuredHeight = this->maxHeight; | ||||
|     needRemeasure = true; | ||||
|   } | ||||
|   if (this->measuredWidth < this->minWidth) { | ||||
|     this->measuredWidth = this->minWidth; | ||||
|       setMeasuredWidth(); | ||||
|     needRemeasure = true; | ||||
|   } | ||||
|   if (this->measuredHeight < this->minHeight) { | ||||
|     this->measuredHeight = this->minHeight; | ||||
|     needRemeasure = true; | ||||
|   } | ||||
|   return needRemeasure; | ||||
| } | ||||
|  | ||||
| void DoricLayouts::layout() { | ||||
|   switch (this->layoutType) { | ||||
|   case DoricLayoutType::DoricStack: { | ||||
|     this->layoutStack(); | ||||
|     break; | ||||
|   } | ||||
|   case DoricLayoutType::DoricVLayout: { | ||||
|     this->layoutVLayout(); | ||||
|     break; | ||||
|   } | ||||
|   case DoricLayoutType::DoricHLayout: { | ||||
|     this->layoutHLayout(); | ||||
|     break; | ||||
|   } | ||||
|   default: { | ||||
|     break; | ||||
|   } | ||||
|   } | ||||
| } | ||||
|  | ||||
| void DoricLayouts::setFrame() { | ||||
|   if (this->layoutType != DoricLayoutType::DoricUndefined) { | ||||
|     foreach (QQuickItem *subview, this->view->childItems()) { | ||||
|       DoricLayouts *layout = | ||||
|           (DoricLayouts *)(subview->property("doricLayout").toULongLong()); | ||||
|       if (layout == nullptr) { | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       layout->setFrame(); | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   this->view->setProperty("width", this->measuredWidth); | ||||
|   this->view->setProperty("height", this->measuredHeight); | ||||
|   this->view->setProperty("x", this->measuredX); | ||||
|   this->view->setProperty("y", this->measuredY); | ||||
| } | ||||
|  | ||||
| void DoricLayouts::layoutStack() { | ||||
|   foreach (QQuickItem *subview, this->view->childItems()) { | ||||
|     DoricLayouts *layout = | ||||
|         (DoricLayouts *)(subview->property("doricLayout").toULongLong()); | ||||
|     if (layout == nullptr) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (layout->disabled) { | ||||
|       continue; | ||||
|     } | ||||
|     if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit && | ||||
|         layout->widthSpec == DoricLayoutSpec::DoricLayoutMost) { | ||||
|       layout->measuredWidth = | ||||
|           this->measuredWidth - layout->marginLeft - layout->marginRight; | ||||
|     } | ||||
|     if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit && | ||||
|         layout->heightSpec == DoricLayoutSpec::DoricLayoutMost) { | ||||
|       layout->measuredHeight = | ||||
|           this->measuredHeight - layout->marginTop - layout->marginBottom; | ||||
|     } | ||||
|     layout->layout(); | ||||
|  | ||||
|     int gravity = layout->alignment; | ||||
|     if ((gravity & DoricGravity::DoricGravityLeft) == | ||||
|         DoricGravity::DoricGravityLeft) { | ||||
|       layout->measuredX = this->paddingLeft; | ||||
|     } else if ((gravity & DoricGravity::DoricGravityRight) == | ||||
|                DoricGravity::DoricGravityRight) { | ||||
|       layout->measuredX = | ||||
|           this->measuredWidth - this->paddingRight - layout->measuredWidth; | ||||
|     } else if ((gravity & DoricGravity::DoricGravityCenterX) == | ||||
|                DoricGravity::DoricGravityCenterX) { | ||||
|       layout->measuredX = this->measuredWidth / 2 - layout->measuredWidth / 2; | ||||
|     } else { | ||||
|       if (layout->marginLeft || layout->marginRight) { | ||||
|         layout->measuredX = this->paddingLeft; | ||||
|       } else { | ||||
|         layout->measuredX = 0; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if ((gravity & DoricGravity::DoricGravityTop) == | ||||
|         DoricGravity::DoricGravityTop) { | ||||
|       layout->measuredY = this->paddingTop; | ||||
|     } else if ((gravity & DoricGravity::DoricGravityBottom) == | ||||
|                DoricGravity::DoricGravityBottom) { | ||||
|       layout->measuredY = | ||||
|           this->measuredHeight - this->paddingBottom - layout->measuredHeight; | ||||
|     } else if ((gravity & DoricGravity::DoricGravityCenterY) == | ||||
|                DoricGravity::DoricGravityCenterY) { | ||||
|       layout->measuredY = this->measuredHeight / 2 - layout->measuredHeight / 2; | ||||
|     } else { | ||||
|       if (layout->marginTop || layout->marginBottom) { | ||||
|         layout->measuredY = this->paddingTop; | ||||
|       } else { | ||||
|         layout->measuredY = 0; | ||||
|       } | ||||
|     } | ||||
|  | ||||
|     if (!gravity) { | ||||
|       gravity = DoricGravity::DoricGravityLeft | DoricGravity::DoricGravityTop; | ||||
|     } | ||||
|     if (layout->marginLeft && !((gravity & DoricGravity::DoricGravityRight) == | ||||
|                                 DoricGravity::DoricGravityRight)) { | ||||
|       layout->measuredX += layout->marginLeft; | ||||
|     } | ||||
|     if (layout->marginRight && !((gravity & DoricGravity::DoricGravityLeft) == | ||||
|                                  DoricGravity::DoricGravityLeft)) { | ||||
|       layout->measuredX -= layout->marginRight; | ||||
|     } | ||||
|     if (layout->marginTop && !((gravity & DoricGravity::DoricGravityBottom) == | ||||
|                                DoricGravity::DoricGravityBottom)) { | ||||
|       layout->measuredY += layout->marginTop; | ||||
|     } | ||||
|     if (layout->marginBottom && !((gravity & DoricGravity::DoricGravityTop) == | ||||
|                                   DoricGravity::DoricGravityTop)) { | ||||
|       layout->measuredY -= layout->marginBottom; | ||||
|     } | ||||
|   } | ||||
| } | ||||
|  | ||||
| void DoricLayouts::layoutVLayout() { | ||||
|   int yStart = this->paddingTop; | ||||
|   if ((this->gravity & DoricGravity::DoricGravityTop) == | ||||
|       DoricGravity::DoricGravityTop) { | ||||
|     yStart = this->paddingTop; | ||||
|   } else if ((this->gravity & DoricGravity::DoricGravityBottom) == | ||||
|              DoricGravity::DoricGravityBottom) { | ||||
|     yStart = this->measuredHeight - this->contentHeight - this->paddingBottom; | ||||
|   } else if ((this->gravity & DoricGravity::DoricGravityCenterY) == | ||||
|              DoricGravity::DoricGravityCenterY) { | ||||
|     yStart = (this->measuredHeight - this->contentHeight - this->paddingTop - | ||||
|               this->paddingBottom) / | ||||
|                  2 + | ||||
|              this->paddingTop; | ||||
|   } | ||||
|  | ||||
|   foreach (QQuickItem *subview, this->view->childItems()) { | ||||
|     DoricLayouts *layout = | ||||
|         (DoricLayouts *)(subview->property("doricLayout").toULongLong()); | ||||
|     if (layout == nullptr) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (layout->disabled) { | ||||
|       continue; | ||||
|     } | ||||
|     if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit && | ||||
|         layout->widthSpec == DoricLayoutSpec::DoricLayoutMost) { | ||||
|       layout->measuredWidth = | ||||
|           this->measuredWidth - layout->marginLeft - layout->marginRight; | ||||
|     } | ||||
|     if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit && | ||||
|         layout->heightSpec == DoricLayoutSpec::DoricLayoutMost) { | ||||
|       layout->measuredHeight = this->measuredHeight - yStart - | ||||
|                                layout->marginTop - layout->marginBottom; | ||||
|     } | ||||
|     layout->layout(); | ||||
|     int gravity = layout->alignment | this->gravity; | ||||
|     if ((gravity & DoricGravity::DoricGravityLeft) == | ||||
|         DoricGravity::DoricGravityLeft) { | ||||
|       layout->measuredX = this->paddingLeft; | ||||
|     } else if ((gravity & DoricGravity::DoricGravityRight) == | ||||
|                DoricGravity::DoricGravityRight) { | ||||
|       layout->measuredX = | ||||
|           this->measuredWidth - this->paddingRight - layout->measuredWidth; | ||||
|     } else if ((gravity & DoricGravity::DoricGravityCenterX) == | ||||
|                DoricGravity::DoricGravityCenterX) { | ||||
|       layout->measuredX = this->measuredWidth / 2 - layout->measuredWidth / 2; | ||||
|     } else { | ||||
|       layout->measuredX = this->paddingLeft; | ||||
|     } | ||||
|     if (!gravity) { | ||||
|       gravity = DoricGravity::DoricGravityLeft; | ||||
|     } | ||||
|     if (layout->marginLeft && !((gravity & DoricGravity::DoricGravityRight) == | ||||
|                                 DoricGravity::DoricGravityRight)) { | ||||
|       layout->measuredX += layout->marginLeft; | ||||
|     } | ||||
|     if (layout->marginRight && !((gravity & DoricGravity::DoricGravityLeft) == | ||||
|                                  DoricGravity::DoricGravityLeft)) { | ||||
|       layout->measuredX -= layout->marginRight; | ||||
|     } | ||||
|     layout->measuredY = yStart + layout->marginTop; | ||||
|     yStart += this->spacing + layout->takenHeight(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| void DoricLayouts::layoutHLayout() { | ||||
|   int xStart = this->paddingLeft; | ||||
|   if ((this->gravity & DoricGravity::DoricGravityLeft) == | ||||
|       DoricGravity::DoricGravityLeft) { | ||||
|     xStart = this->paddingLeft; | ||||
|   } else if ((this->gravity & DoricGravity::DoricGravityRight) == | ||||
|              DoricGravity::DoricGravityRight) { | ||||
|     xStart = this->measuredWidth - this->contentWidth - this->paddingRight; | ||||
|   } else if ((this->gravity & DoricGravity::DoricGravityCenterX) == | ||||
|              DoricGravity::DoricGravityCenterX) { | ||||
|     xStart = (this->measuredWidth - this->contentWidth - this->paddingLeft - | ||||
|               this->paddingRight) / | ||||
|                  2 + | ||||
|              this->paddingLeft; | ||||
|   } | ||||
|   foreach (QQuickItem *subview, this->view->childItems()) { | ||||
|     DoricLayouts *layout = | ||||
|         (DoricLayouts *)(subview->property("doricLayout").toULongLong()); | ||||
|     if (layout == nullptr) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (layout->disabled) { | ||||
|       continue; | ||||
|     } | ||||
|  | ||||
|     if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit && | ||||
|         layout->widthSpec == DoricLayoutSpec::DoricLayoutMost) { | ||||
|       layout->measuredWidth = this->measuredWidth - xStart - | ||||
|                               layout->marginLeft - layout->marginRight; | ||||
|     } | ||||
|  | ||||
|     if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit && | ||||
|         layout->heightSpec == DoricLayoutSpec::DoricLayoutMost) { | ||||
|       layout->measuredHeight = | ||||
|           this->measuredHeight - layout->marginTop - layout->marginBottom; | ||||
|     } | ||||
|  | ||||
|     layout->layout(); | ||||
|  | ||||
|     int gravity = layout->alignment | this->gravity; | ||||
|     if ((gravity & DoricGravity::DoricGravityTop) == | ||||
|         DoricGravity::DoricGravityTop) { | ||||
|       layout->measuredY = this->paddingTop; | ||||
|     } else if ((gravity & DoricGravity::DoricGravityBottom) == | ||||
|                DoricGravity::DoricGravityBottom) { | ||||
|       layout->measuredY = | ||||
|           this->measuredHeight - this->paddingBottom - layout->measuredHeight; | ||||
|     } else if ((gravity & DoricGravity::DoricGravityCenterY) == | ||||
|                DoricGravity::DoricGravityCenterY) { | ||||
|       layout->measuredY = this->measuredHeight / 2 - layout->measuredHeight / 2; | ||||
|     } else { | ||||
|       layout->measuredY = this->paddingTop; | ||||
|     } | ||||
|     if (!gravity) { | ||||
|       gravity = DoricGravity::DoricGravityTop; | ||||
|     } | ||||
|     if (layout->marginTop && !((gravity & DoricGravity::DoricGravityBottom) == | ||||
|                                DoricGravity::DoricGravityBottom)) { | ||||
|       layout->measuredY += layout->marginTop; | ||||
|     } | ||||
|     if (layout->marginBottom && !((gravity & DoricGravity::DoricGravityTop) == | ||||
|                                   DoricGravity::DoricGravityTop)) { | ||||
|       layout->measuredY -= layout->marginBottom; | ||||
|     } | ||||
|     layout->measuredX = xStart + layout->marginLeft; | ||||
|     xStart += this->spacing + layout->takenWidth(); | ||||
|   } | ||||
| } | ||||
|  | ||||
| // Private Section | ||||
| void DoricLayouts::setMeasuredWidth() { | ||||
|   qCritical() << "DoricLayouts: " << tag << this->view->property("uuid") | ||||
|               << " measuredWidth: " << this->measuredWidth; | ||||
| } | ||||
|  | ||||
| void DoricLayouts::setMeasuredHeight() { | ||||
|   qCritical() << "DoricLayouts: " << tag | ||||
|               << " measuredHeight: " << this->measuredHeight; | ||||
| } | ||||
							
								
								
									
										166
									
								
								doric-Qt/doric/utils/DoricLayouts.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										166
									
								
								doric-Qt/doric/utils/DoricLayouts.h
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,166 @@ | ||||
| #ifndef DORICLAYOUTS_H | ||||
| #define DORICLAYOUTS_H | ||||
|  | ||||
| #include <QQuickItem> | ||||
|  | ||||
| class DoricLayoutType { | ||||
| public: | ||||
|   const static int DoricUndefined = 0; | ||||
|   const static int DoricStack = 1; | ||||
|   const static int DoricVLayout = 2; | ||||
|   const static int DoricHLayout = 3; | ||||
| }; | ||||
|  | ||||
| class DoricLayoutSpec { | ||||
| public: | ||||
|   const static int DoricLayoutJust = 0; | ||||
|   const static int DoricLayoutFit = 1; | ||||
|   const static int DoricLayoutMost = 2; | ||||
| }; | ||||
|  | ||||
| class DoricGravity { | ||||
| public: | ||||
|   const static int DoricGravitySpecified = 1; | ||||
|   const static int DoricGravityStart = 1 << 1; | ||||
|   const static int DoricGravityEnd = 1 << 2; | ||||
|   const static int DoricGravityShiftX = 0; | ||||
|   const static int DoricGravityShiftY = 4; | ||||
|   const static int DoricGravityLeft = | ||||
|       (DoricGravityStart | DoricGravitySpecified) << DoricGravityShiftX; | ||||
|   const static int DoricGravityRight = (DoricGravityEnd | DoricGravitySpecified) | ||||
|                                        << DoricGravityShiftX; | ||||
|   const static int DoricGravityTop = (DoricGravityStart | DoricGravitySpecified) | ||||
|                                      << DoricGravityShiftY; | ||||
|   const static int DoricGravityBottom = | ||||
|       (DoricGravityEnd | DoricGravitySpecified) << DoricGravityShiftY; | ||||
|   const static int DoricGravityCenterX = DoricGravitySpecified | ||||
|                                          << DoricGravityShiftX; | ||||
|   const static int DoricGravityCenterY = DoricGravitySpecified | ||||
|                                          << DoricGravityShiftY; | ||||
|   const static int DoricGravityCenter = | ||||
|       DoricGravityCenterX | DoricGravityCenterY; | ||||
| }; | ||||
|  | ||||
| class DoricLayouts { | ||||
| public: | ||||
|   DoricLayouts(); | ||||
|  | ||||
|   void setWidthSpec(int widthSpec); | ||||
|   void setHeightSpec(int heightSpec); | ||||
|  | ||||
|   void setAlignment(int alignment); | ||||
|  | ||||
|   void setGravity(int gravity); | ||||
|  | ||||
|   void setWidth(int width); | ||||
|   void setHeight(int height); | ||||
|  | ||||
|   void setSpacing(int spacing); | ||||
|  | ||||
|   void setMarginLeft(int marginLeft); | ||||
|   void setMarginTop(int marginTop); | ||||
|   void setMarginRight(int marginRight); | ||||
|   void setMarginBottom(int marginBottom); | ||||
|  | ||||
|   void setPaddingLeft(int paddingLeft); | ||||
|   void setPaddingTop(int paddingTop); | ||||
|   void setPaddingRight(int paddingRight); | ||||
|   void setPaddingBottom(int paddingBottom); | ||||
|  | ||||
|   void setWeight(int weight); | ||||
|  | ||||
|   void setView(QQuickItem *view); | ||||
|  | ||||
|   void setLayoutType(int layoutType); | ||||
|  | ||||
|   void setDisabled(bool disabled); | ||||
|  | ||||
|   void setMaxWidth(int maxWidth); | ||||
|   void setMaxHeight(int maxHeight); | ||||
|   void setMinWidth(int minWidth); | ||||
|   void setMinHeight(int minHeight); | ||||
|  | ||||
|   void apply(int targetWidth, int targetHeight); | ||||
|  | ||||
|   void apply(); | ||||
|  | ||||
|   void measure(int targetWidth, int targetHeight); | ||||
|  | ||||
|   void measureSelf(int targetWidth, int targetHeight); | ||||
|  | ||||
|   void measureContent(int targetWidth, int targetHeight); | ||||
|  | ||||
|   void measureUndefinedContent(int targetWidth, int targetHeight); | ||||
|   void measureStackContent(int targetWidth, int targetHeight); | ||||
|   void measureVLayoutContent(int targetWidth, int targetHeight); | ||||
|   void measureHLayoutContent(int targetWidth, int targetHeight); | ||||
|  | ||||
|   int takenWidth(); | ||||
|   int takenHeight(); | ||||
|   QPair<int, int> removeMargin(int targetWidth, int targetHeight); | ||||
|  | ||||
|   bool restrainSize(); | ||||
|  | ||||
|   void layout(); | ||||
|  | ||||
|   void layoutStack(); | ||||
|   void layoutVLayout(); | ||||
|   void layoutHLayout(); | ||||
|  | ||||
|   void setFrame(); | ||||
|  | ||||
| private: | ||||
|   QString tag; | ||||
|  | ||||
|   int widthSpec; | ||||
|   int heightSpec; | ||||
|  | ||||
|   int alignment; | ||||
|  | ||||
|   int gravity; | ||||
|  | ||||
|   int width; | ||||
|   int height; | ||||
|  | ||||
|   int spacing; | ||||
|  | ||||
|   int marginLeft; | ||||
|   int marginTop; | ||||
|   int marginRight; | ||||
|   int marginBottom; | ||||
|  | ||||
|   int paddingLeft; | ||||
|   int paddingTop; | ||||
|   int paddingRight; | ||||
|   int paddingBottom; | ||||
|  | ||||
|   int weight; | ||||
|  | ||||
|   QQuickItem *view; | ||||
|  | ||||
|   int layoutType; | ||||
|  | ||||
|   bool disabled; | ||||
|  | ||||
|   int maxWidth; | ||||
|   int maxHeight; | ||||
|   int minWidth; | ||||
|   int minHeight; | ||||
|  | ||||
|   bool resolved; | ||||
|  | ||||
|   int measuredWidth; | ||||
|   void setMeasuredWidth(); | ||||
|   int measuredHeight; | ||||
|   void setMeasuredHeight(); | ||||
|   int measuredX; | ||||
|   int measuredY; | ||||
|  | ||||
|   bool undefined; | ||||
|  | ||||
|   // | ||||
|   int contentWidth; | ||||
|   int contentHeight; | ||||
| }; | ||||
|  | ||||
| #endif // DORICLAYOUTS_H | ||||
		Reference in New Issue
	
	Block a user