diff --git a/doric-Qt/doric/main.cpp b/doric-Qt/doric/main.cpp index d4123f0b..6115b025 100644 --- a/doric-Qt/doric/main.cpp +++ b/doric-Qt/doric/main.cpp @@ -11,6 +11,9 @@ int main(int argc, char *argv[]) { QGuiApplication app(argc, argv); QQmlApplicationEngine engine; + qmlRegisterType("pub.doric.widget", 1, 0, + "FlexLayoutService"); + // const QUrl url(QStringLiteral("qrc:/doric/qml/test-layout.qml")); const QUrl url(QStringLiteral("qrc:/main.qml")); QObject::connect( &engine, &QQmlApplicationEngine::objectCreated, &app, @@ -20,12 +23,11 @@ int main(int argc, char *argv[]) { }, Qt::QueuedConnection); - DoricDemoBridge *demoBridge = new DoricDemoBridge(); auto context = engine.rootContext(); + DoricDemoBridge *demoBridge = new DoricDemoBridge(); context->setContextProperty("demoBridge", demoBridge); + engine.load(url); - qmlRegisterType("pub.doric.widget", 1, 0, - "FlexLayoutService"); return app.exec(); } diff --git a/doric-Qt/doric/qml.qrc b/doric-Qt/doric/qml.qrc index fc6f7c10..54d341f1 100644 --- a/doric-Qt/doric/qml.qrc +++ b/doric-Qt/doric/qml.qrc @@ -1,7 +1,7 @@ - ./resources/main.qml - ./resources/qtquickcontrols2.conf + resources/main.qml + resources/qtquickcontrols2.conf ../../doric-js/bundle/doric-sandbox.es5.js @@ -12,12 +12,14 @@ ../../doric-demo/bundle/src/Snake.es5.js - ./resources/Flex.qml - ./resources/view.qml - ./resources/panel.qml - ./resources/stack.qml - ./resources/vlayout.qml - ./resources/hlayout.qml - ./resources/text.qml + resources/Flex.qml + resources/view.qml + resources/panel.qml + resources/stack.qml + resources/vlayout.qml + resources/hlayout.qml + resources/text.qml + resources/util.mjs + test-layout.qml diff --git a/doric-Qt/doric/resources/hlayout.qml b/doric-Qt/doric/resources/hlayout.qml index 83ed8129..cc8eab33 100644 --- a/doric-Qt/doric/resources/hlayout.qml +++ b/doric-Qt/doric/resources/hlayout.qml @@ -1,9 +1,61 @@ import QtQuick 2.12 import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.15 -Flex { - flexDirection: "row" - justifyContent: "flexStart" - alignItems: "flexStart" - alignContent: "flexStart" +import "util.mjs" as Util + +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: "HLayout" + + onWidthChanged: () => { + console.log(tag, uuid + " onWidthChanged: " + this.width) + } + + onHeightChanged: () => { + 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 + " childrenRect: " + 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' + + RowLayout { + spacing: 0 + } } diff --git a/doric-Qt/doric/resources/panel.qml b/doric-Qt/doric/resources/panel.qml index f6d6d22d..12aad812 100644 --- a/doric-Qt/doric/resources/panel.qml +++ b/doric-Qt/doric/resources/panel.qml @@ -1,12 +1,6 @@ import QtQuick 2.12 import QtQuick.Controls 2.5 -Flex { - flexDirection: "row" - justifyContent: "flexStart" - alignItems: "flexStart" - alignContent: "flexStart" - flexWrap: "noWrap" - +Rectangle { color: 'cyan' } diff --git a/doric-Qt/doric/resources/stack.qml b/doric-Qt/doric/resources/stack.qml index be34e87f..740a7838 100644 --- a/doric-Qt/doric/resources/stack.qml +++ b/doric-Qt/doric/resources/stack.qml @@ -1,6 +1,57 @@ import QtQuick 2.12 import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.15 -Flex { +import "util.mjs" as Util +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: () => { + console.log(tag, uuid + " onWidthChanged: " + this.width) + } + + onHeightChanged: () => { + 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 + " childrenRect: " + 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' } diff --git a/doric-Qt/doric/resources/text.qml b/doric-Qt/doric/resources/text.qml index a945e93a..9c867c90 100644 --- a/doric-Qt/doric/resources/text.qml +++ b/doric-Qt/doric/resources/text.qml @@ -1,7 +1,9 @@ import QtQuick 2.12 import QtQuick.Controls 2.5 -Flex { +Rectangle { + color: 'transparent' + Text { } diff --git a/doric-Qt/doric/resources/util.mjs b/doric-Qt/doric/resources/util.mjs new file mode 100644 index 00000000..0633ff4c --- /dev/null +++ b/doric-Qt/doric/resources/util.mjs @@ -0,0 +1,8 @@ +// util.mjs +export function uuidv4() { + return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) { + var r = Math.random() * 16 | 0, + v = c === 'x' ? r : (r & 0x3 | 0x8); + return v.toString(16); + }); +} diff --git a/doric-Qt/doric/resources/vlayout.qml b/doric-Qt/doric/resources/vlayout.qml index 6c8fb92e..3be0f35b 100644 --- a/doric-Qt/doric/resources/vlayout.qml +++ b/doric-Qt/doric/resources/vlayout.qml @@ -1,10 +1,61 @@ import QtQuick 2.12 import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.15 -Flex { - flexDirection: "column" - justifyContent: "flexStart" - alignItems: "flexStart" - alignContent: "flexStart" +import "util.mjs" as Util + +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: "VLayout" + + onWidthChanged: () => { + console.log(tag, uuid + " onWidthChanged: " + this.width) + } + + onHeightChanged: () => { + 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 + " childrenRect: " + 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' + + ColumnLayout { + spacing: 0 + } } - diff --git a/doric-Qt/doric/shader/DoricGroupNode.cpp b/doric-Qt/doric/shader/DoricGroupNode.cpp index c4af5681..9c4b45d8 100644 --- a/doric-Qt/doric/shader/DoricGroupNode.cpp +++ b/doric-Qt/doric/shader/DoricGroupNode.cpp @@ -23,6 +23,12 @@ void DoricGroupNode::blend(QJSValue jsValue) { } void DoricGroupNode::configChildNode() { + QQuickItem *parent = nullptr; + if (mType.isEmpty() || mType == "Stack") { + parent = mView; + } else { + parent = mView->childItems().at(0); + } for (int idx = 0; idx < mChildViewIds.size(); idx++) { QString id = mChildViewIds.at(idx); QJSValue model = getSubModel(id); @@ -53,17 +59,18 @@ void DoricGroupNode::configChildNode() { if (newNode != nullptr) { newNode->setId(id); newNode->init(this); - newNode->blend(model.property("props")); if (idx >= mChildNodes.size()) { mChildNodes.append(newNode); - newNode->getNodeView()->setParentItem(mView); + newNode->getNodeView()->setParentItem(parent); } else { mChildNodes.insert(idx, newNode); - newNode->getNodeView()->setParentItem(mView); + newNode->getNodeView()->setParentItem(parent); newNode->getNodeView()->stackBefore( - mView->childItems().at(idx)); + parent->childItems().at(idx)); } + + newNode->blend(model.property("props")); } } } else { @@ -80,24 +87,25 @@ void DoricGroupNode::configChildNode() { if (position >= 0) { // Found swap idx,position mChildNodes.swapItemsAt(position, idx); - mView->childItems().swapItemsAt(position, idx); + parent->childItems().swapItemsAt(position, idx); } else { // Not found,insert DoricViewNode *newNode = DoricViewNode::create(getContext(), type); if (newNode != nullptr) { newNode->setId(id); newNode->init(this); - newNode->blend(model.property("props")); if (idx >= mChildNodes.size()) { mChildNodes.append(newNode); - newNode->getNodeView()->setParentItem(mView); + newNode->getNodeView()->setParentItem(parent); } else { mChildNodes.insert(idx, newNode); - newNode->getNodeView()->setParentItem(mView); + newNode->getNodeView()->setParentItem(parent); newNode->getNodeView()->stackBefore( - mView->childItems().at(idx)); + parent->childItems().at(idx)); } + + newNode->blend(model.property("props")); } } } @@ -108,16 +116,17 @@ void DoricGroupNode::configChildNode() { if (newNode != nullptr) { newNode->setId(id); newNode->init(this); - newNode->blend(model.property("props")); if (idx >= mChildNodes.size()) { mChildNodes.append(newNode); - newNode->getNodeView()->setParentItem(mView); + newNode->getNodeView()->setParentItem(parent); } else { mChildNodes.insert(idx, newNode); - newNode->getNodeView()->setParentItem(mView); - newNode->getNodeView()->stackBefore(mView->childItems().at(idx)); + newNode->getNodeView()->setParentItem(parent); + newNode->getNodeView()->stackBefore(parent->childItems().at(idx)); } + + newNode->blend(model.property("props")); } } } diff --git a/doric-Qt/doric/shader/DoricHLayoutNode.cpp b/doric-Qt/doric/shader/DoricHLayoutNode.cpp index 04260492..ef91ba9e 100644 --- a/doric-Qt/doric/shader/DoricHLayoutNode.cpp +++ b/doric-Qt/doric/shader/DoricHLayoutNode.cpp @@ -16,7 +16,7 @@ QQuickItem *DoricHLayoutNode::build() { void DoricHLayoutNode::blend(QQuickItem *view, QString name, QJSValue prop) { if (name == "space") { - view->setProperty("spacing", prop.toInt()); + view->childItems().at(0)->setProperty("spacing", prop.toInt()); } else if (name == "gravity") { switch (prop.toInt()) { case 1: diff --git a/doric-Qt/doric/shader/DoricVLayoutNode.cpp b/doric-Qt/doric/shader/DoricVLayoutNode.cpp index 31e6352a..8cadf2a7 100644 --- a/doric-Qt/doric/shader/DoricVLayoutNode.cpp +++ b/doric-Qt/doric/shader/DoricVLayoutNode.cpp @@ -16,7 +16,7 @@ QQuickItem *DoricVLayoutNode::build() { void DoricVLayoutNode::blend(QQuickItem *view, QString name, QJSValue prop) { if (name == "space") { - view->setProperty("spacing", prop.toInt()); + view->childItems().at(0)->setProperty("spacing", prop.toInt()); } else if (name == "gravity") { switch (prop.toInt()) { case 1: diff --git a/doric-Qt/doric/shader/DoricViewNode.cpp b/doric-Qt/doric/shader/DoricViewNode.cpp index f037e9f3..89a2a057 100644 --- a/doric-Qt/doric/shader/DoricViewNode.cpp +++ b/doric-Qt/doric/shader/DoricViewNode.cpp @@ -5,34 +5,36 @@ #include "DoricViewNode.h" void DoricViewNode::blendLayoutConfig(QJSValue jsObject) { + this->mLayoutConfig = jsObject; + QJSValue margin = jsObject.property("margin"); QJSValue widthSpec = jsObject.property("widthSpec"); QJSValue heightSpec = jsObject.property("heightSpec"); if (widthSpec.isNumber()) { switch (widthSpec.toInt()) { + case 0: + mView->setProperty("widthSpec", 0); + break; case 1: - qCritical() << 1; + mView->setProperty("widthSpec", 1); break; case 2: - qCritical() << 2; - break; - default: - qCritical() << "default"; + mView->setProperty("widthSpec", 2); break; } } if (heightSpec.isNumber()) { switch (heightSpec.toInt()) { + case 0: + mView->setProperty("heightSpec", 0); + break; case 1: - qCritical() << 1; + mView->setProperty("heightSpec", 1); break; case 2: - qCritical() << 2; - break; - default: - qCritical() << "default"; + mView->setProperty("heightSpec", 2); break; } } @@ -80,12 +82,30 @@ void DoricViewNode::blend(QQuickItem *view, QString name, QJSValue prop) { if (!prop.isNumber()) { return; } - view->setWidth(prop.toInt()); + if (this->mLayoutConfig.isUndefined()) { + view->setWidth(prop.toInt()); + } else { + QJSValue widthSpec = this->mLayoutConfig.property("widthSpec"); + if (widthSpec.isNumber()) { + if (widthSpec.toInt() == 0) { + view->setWidth(prop.toInt()); + } + } + } } else if (name == "height") { if (!prop.isNumber()) { return; } - view->setHeight(prop.toInt()); + if (this->mLayoutConfig.isUndefined()) { + view->setHeight(prop.toInt()); + } else { + QJSValue heightSpec = this->mLayoutConfig.property("heightSpec"); + if (heightSpec.isNumber()) { + if (heightSpec.toInt() == 0) { + view->setHeight(prop.toInt()); + } + } + } } else if (name == "backgroundColor") { QString color = DoricUtils::doricColor(prop.toNumber()).name(); view->setProperty("color", color); @@ -95,6 +115,8 @@ void DoricViewNode::blend(QQuickItem *view, QString name, QJSValue prop) { view->setProperty("y", prop.toInt()); } else if (name == "corners") { view->setProperty("radius", prop.toInt()); + } else if (name == "layoutConfig") { + } else { qCritical() << name << ": " << prop.toString(); } diff --git a/doric-Qt/doric/shader/DoricViewNode.h b/doric-Qt/doric/shader/DoricViewNode.h index 1d8c1381..be272a9d 100644 --- a/doric-Qt/doric/shader/DoricViewNode.h +++ b/doric-Qt/doric/shader/DoricViewNode.h @@ -20,9 +20,12 @@ protected: private: QString mId; - QString mType; + + QJSValue mLayoutConfig; public: + QString mType; + using DoricContextHolder::DoricContextHolder; void init(DoricSuperNode *superNode); diff --git a/doric-Qt/doric/test-layout.qml b/doric-Qt/doric/test-layout.qml new file mode 100644 index 00000000..e7d2078a --- /dev/null +++ b/doric-Qt/doric/test-layout.qml @@ -0,0 +1,54 @@ +import QtQuick 2.0 +import QtQuick.Controls 2.5 +import QtQuick.Layouts 1.15 + +ApplicationWindow { + visible: true + width: 450 + height: 800 + title: qsTr("Scroll") + + Rectangle { + color: 'red' + width: childrenRect.width + height: childrenRect.height + + RowLayout { + spacing: 0 + Rectangle { + width: 100 + height: 100 + color: 'black' + Layout.alignment: Qt.AlignTop | Qt.AlignLeft + } + Rectangle { + Layout.topMargin: 30 + width: 100 + height: 100 + color: 'yellow' + } + Rectangle { + Layout.topMargin: 0 + width: 100 + height: 100 + color: 'black' + Layout.alignment: Qt.AlignTop | Qt.AlignLeft + } + Rectangle { + width: 100 + height: 100 + color: 'yellow' + } + Rectangle { + width: 100 + height: 100 + color: 'black' + } + Rectangle { + width: 100 + height: 100 + color: 'yellow' + } + } + } +}