From 0a29cc2876ae302ad3de39dc6f2e31bd2f1df6e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=8E=8B=E5=8A=B2=E9=B9=8F?= Date: Fri, 23 Apr 2021 17:56:08 +0800 Subject: [PATCH] add image render --- doric-Qt/doric/DoricRegistry.cpp | 2 + doric-Qt/doric/demo/DoricDemoBridge.cpp | 11 +-- doric-Qt/doric/doric.pro | 4 ++ doric-Qt/doric/qml.qrc | 1 + doric-Qt/doric/resources/image.qml | 86 +++++++++++++++++++++++ doric-Qt/doric/resources/main.qml | 4 +- doric-Qt/doric/resources/test-layout.qml | 2 +- doric-Qt/doric/shader/DoricImageNode.cpp | 75 ++++++++++++++++++++ doric-Qt/doric/shader/DoricImageNode.h | 30 ++++++++ doric-Qt/doric/shader/DoricViewNode.h | 4 +- doric-Qt/doric/utils/DoricImageBridge.cpp | 20 ++++++ doric-Qt/doric/utils/DoricImageBridge.h | 24 +++++++ 12 files changed, 254 insertions(+), 9 deletions(-) create mode 100644 doric-Qt/doric/resources/image.qml create mode 100644 doric-Qt/doric/shader/DoricImageNode.cpp create mode 100644 doric-Qt/doric/shader/DoricImageNode.h create mode 100644 doric-Qt/doric/utils/DoricImageBridge.cpp create mode 100644 doric-Qt/doric/utils/DoricImageBridge.h diff --git a/doric-Qt/doric/DoricRegistry.cpp b/doric-Qt/doric/DoricRegistry.cpp index bdccbc23..ed38af43 100644 --- a/doric-Qt/doric/DoricRegistry.cpp +++ b/doric-Qt/doric/DoricRegistry.cpp @@ -5,6 +5,7 @@ #include "plugin/DoricShaderPlugin.h" #include "shader/DoricHLayoutNode.h" +#include "shader/DoricImageNode.h" #include "shader/DoricRootNode.h" #include "shader/DoricScrollerNode.h" #include "shader/DoricStackNode.h" @@ -22,6 +23,7 @@ DoricRegistry::DoricRegistry() { registerViewNode("HLayout"); registerViewNode("Text"); registerViewNode("Scroller"); + registerViewNode("Image"); } bool DoricRegistry::acquirePluginInfo(QString name) { diff --git a/doric-Qt/doric/demo/DoricDemoBridge.cpp b/doric-Qt/doric/demo/DoricDemoBridge.cpp index f130710b..fe67f66b 100644 --- a/doric-Qt/doric/demo/DoricDemoBridge.cpp +++ b/doric-Qt/doric/demo/DoricDemoBridge.cpp @@ -5,6 +5,7 @@ #include "DoricDemoBridge.h" #include "DoricPanel.h" #include "utils/DoricDialogBridge.h" +#include "utils/DoricImageBridge.h" #include "utils/DoricMouseAreaBridge.h" #include "utils/DoricUtils.h" @@ -44,8 +45,8 @@ void DoricDemoBridge::navigate(QVariant route) { { const QUrl url(QStringLiteral("qrc:/doric/qml/view.qml")); view->setSource(url); - view->setWidth(405); - view->setHeight(720); + view->setWidth(600); + view->setHeight(800); Qt::WindowFlags flag = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::WindowTitleHint | Qt::WindowCloseButtonHint | Qt::CustomizeWindowHint | Qt::WindowSystemMenuHint; @@ -58,8 +59,8 @@ void DoricDemoBridge::navigate(QVariant route) { component.loadUrl(url); QQuickItem *quickItem = qobject_cast(component.create()); DoricPanel *panel = new DoricPanel(view->engine(), quickItem); - quickItem->setWidth(405); - quickItem->setHeight(720); + quickItem->setWidth(600); + quickItem->setHeight(800); quickItem->setParentItem(view->rootObject()); panel->config(script, name, NULL); @@ -78,4 +79,6 @@ void DoricDemoBridge::navigate(QVariant route) { context->setContextProperty("mouseAreaBridge", mouseAreaBridge); DoricDialogBridge *dialogBridge = new DoricDialogBridge(); context->setContextProperty("dialogBridge", dialogBridge); + DoricImageBridge *imageBridge = new DoricImageBridge(); + context->setContextProperty("imageBridge", imageBridge); } diff --git a/doric-Qt/doric/doric.pro b/doric-Qt/doric/doric.pro index e208771d..2a708de5 100644 --- a/doric-Qt/doric/doric.pro +++ b/doric-Qt/doric/doric.pro @@ -39,6 +39,7 @@ SOURCES += \ plugin/DoricShaderPlugin.cpp \ shader/DoricGroupNode.cpp \ shader/DoricHLayoutNode.cpp \ + shader/DoricImageNode.cpp \ shader/DoricRootNode.cpp \ shader/DoricScrollerNode.cpp \ shader/DoricStackNode.cpp \ @@ -49,6 +50,7 @@ SOURCES += \ utils/DoricConstant.cpp \ utils/DoricContextHolder.cpp \ utils/DoricDialogBridge.cpp \ + utils/DoricImageBridge.cpp \ utils/DoricLayouts.cpp \ utils/DoricMouseAreaBridge.cpp \ widget/flex/FlexLayout.cpp \ @@ -110,6 +112,7 @@ HEADERS += \ plugin/DoricShaderPlugin.h \ shader/DoricGroupNode.h \ shader/DoricHLayoutNode.h \ + shader/DoricImageNode.h \ shader/DoricRootNode.h \ shader/DoricScrollerNode.h \ shader/DoricStackNode.h \ @@ -122,6 +125,7 @@ HEADERS += \ utils/DoricContextHolder.h \ utils/DoricCountDownLatch.h \ utils/DoricDialogBridge.h \ + utils/DoricImageBridge.h \ utils/DoricLayouts.h \ utils/DoricMouseAreaBridge.h \ utils/DoricObjectFactory.h \ diff --git a/doric-Qt/doric/qml.qrc b/doric-Qt/doric/qml.qrc index fb555ed6..938b7e02 100644 --- a/doric-Qt/doric/qml.qrc +++ b/doric-Qt/doric/qml.qrc @@ -26,6 +26,7 @@ resources/hlayout.qml resources/text.qml resources/scroller.qml + resources/image.qml resources/toast.qml resources/alert.qml diff --git a/doric-Qt/doric/resources/image.qml b/doric-Qt/doric/resources/image.qml new file mode 100644 index 00000000..fdae00dd --- /dev/null +++ b/doric-Qt/doric/resources/image.qml @@ -0,0 +1,86 @@ +import QtQuick 2.12 +import QtQuick.Controls 2.5 + +import "util.mjs" as Util + +AnimatedImage { + property var wrapper + + property var uuid: Util.uuidv4() + + property var tag: "Image" + + Rectangle { + id: bg + color: "transparent" + } + + onSourceChanged: { + console.log(tag, uuid + " onSourceChanged: " + this.source) + } + + onStatusChanged: { + if (this.status === Image.Null) { + console.log(tag, uuid + " onStatusChanged: Image.Null") + imageBridge.onNull(wrapper); + } else if (this.status === Image.Ready) { + console.log(tag, uuid + " onStatusChanged: Image.Ready") + + if (this.width !== 0 && this.height !== 0 && this.status === Image.Ready) { + imageBridge.onReady(wrapper); + } + } else if (this.status === Image.Loading) { + console.log(tag, uuid + " onStatusChanged: Image.Loading") + imageBridge.onLoading(wrapper); + } else if (this.status === Image.Error) { + console.log(tag, uuid + " onStatusChanged: Image.Error") + imageBridge.onError(wrapper); + } + } + + onProgressChanged: { + console.log(tag, uuid + " onProgressChanged: " + this.progress) + } + + onWidthChanged: { + console.log(tag, uuid + " onWidthChanged: " + this.width) + bg.width = this.width + + if (this.width !== 0 && this.height !== 0 && this.status === Image.Ready) { + imageBridge.onReady(wrapper); + } + } + + onHeightChanged: { + console.log(tag, uuid + " onHeightChanged: " + this.height) + bg.height = this.height + + if (this.width !== 0 && this.height !== 0 && this.status === Image.Ready) { + imageBridge.onReady(wrapper); + } + } + + property var backgroundColor + + onBackgroundColorChanged: { + bg.color = backgroundColor + } + + property var borderWidth: 0 + onBorderWidthChanged: { + bg.border.width = borderWidth + } + + property var borderColor: "" + onBorderColorChanged: { + bg.border.color = borderColor + } + + MouseArea { + anchors.fill: parent + onClicked: { + console.log(tag, uuid + " wrapper: " + wrapper) + mouseAreaBridge.onClick(wrapper) + } + } +} diff --git a/doric-Qt/doric/resources/main.qml b/doric-Qt/doric/resources/main.qml index 44390387..de946a61 100644 --- a/doric-Qt/doric/resources/main.qml +++ b/doric-Qt/doric/resources/main.qml @@ -3,8 +3,8 @@ import QtQuick.Controls 2.5 ApplicationWindow { visible: true - width: 405 - height: 720 + width: 600 + height: 800 title: qsTr("Scroll") ScrollView { diff --git a/doric-Qt/doric/resources/test-layout.qml b/doric-Qt/doric/resources/test-layout.qml index 766aa4df..2c8535cf 100644 --- a/doric-Qt/doric/resources/test-layout.qml +++ b/doric-Qt/doric/resources/test-layout.qml @@ -4,7 +4,7 @@ import QtQuick.Layouts 1.15 ApplicationWindow { visible: true - width: 450 + width: 600 height: 800 title: qsTr("Scroll") diff --git a/doric-Qt/doric/shader/DoricImageNode.cpp b/doric-Qt/doric/shader/DoricImageNode.cpp new file mode 100644 index 00000000..1949304e --- /dev/null +++ b/doric-Qt/doric/shader/DoricImageNode.cpp @@ -0,0 +1,75 @@ +#include "DoricImageNode.h" +#include "DoricSuperNode.h" + +#include "../utils/DoricUtils.h" + +#include + +QQuickItem *DoricImageNode::build() { + QQmlComponent component(getContext()->getQmlEngine()); + + const QUrl url(QStringLiteral("qrc:/doric/qml/image.qml")); + component.loadUrl(url); + + if (component.isError()) { + qCritical() << component.errorString(); + } + + QQuickItem *item = qobject_cast(component.create()); + this->createLayouts(item); + + item->setProperty("wrapper", QString::number((qint64)this)); + return item; +} + +void DoricImageNode::blend(QJsonValue jsValue) { + if (jsValue.toObject().contains("scaleType")) + this->contentMode = jsValue["scaleType"].toInt(); + if (jsValue.toObject().contains("placeHolderColor")) + this->placeHolderColor = jsValue["placeHolderColor"].toInt(); + if (jsValue.toObject().contains("errorColor")) + this->errorColor = jsValue["errorColor"].toInt(); + if (jsValue.toObject().contains("loadCallback")) + this->loadCallbackId = jsValue["loadCallback"].toString(); + + DoricViewNode::blend(jsValue); +} + +void DoricImageNode::blend(QQuickItem *view, QString name, QJsonValue prop) { + QQuickItem *container = view; + if (name == "imageUrl") { + container->setProperty("fillMode", this->contentMode); + container->setProperty("source", prop.toString()); + } else if (name == "imageBase64") { + container->setProperty("fillMode", this->contentMode); + container->setProperty("source", prop.toString()); + } else { + DoricViewNode::blend(view, name, prop); + } +} + +void DoricImageNode::onReady() { + if (!this->loadCallbackId.isEmpty()) { + QVariantList args; + + QMap map; + map.insert("width", 0); + map.insert("height", 0); + + args.append(QVariant::fromValue(map)); + this->callJSResponse(this->loadCallbackId, args); + } + + DoricSuperNode *node = this->mSuperNode; + while (node->mSuperNode != nullptr) { + node = node->mSuperNode; + } + node->requestLayout(); +} + +void DoricImageNode::onError() { + if (!this->loadCallbackId.isEmpty()) { + QVariantList args; + this->callJSResponse(this->loadCallbackId, args); + } +} diff --git a/doric-Qt/doric/shader/DoricImageNode.h b/doric-Qt/doric/shader/DoricImageNode.h new file mode 100644 index 00000000..6322c205 --- /dev/null +++ b/doric-Qt/doric/shader/DoricImageNode.h @@ -0,0 +1,30 @@ +#ifndef DORICIMAGENODE_H +#define DORICIMAGENODE_H + +#include "DoricViewNode.h" + +class DoricImageNode : public DoricViewNode { +public: + using DoricViewNode::DoricViewNode; + + QQuickItem *build() override; + + virtual void blend(QJsonValue jsValue) override; + + virtual void blend(QQuickItem *view, QString name, QJsonValue prop) override; + + void onReady(); + + void onError(); + +private: + QString loadCallbackId = ""; + + int contentMode = 0; + + int placeHolderColor = -1; + + int errorColor = -1; +}; + +#endif // DORICIMAGENODE_H diff --git a/doric-Qt/doric/shader/DoricViewNode.h b/doric-Qt/doric/shader/DoricViewNode.h index 58453c84..43027456 100644 --- a/doric-Qt/doric/shader/DoricViewNode.h +++ b/doric-Qt/doric/shader/DoricViewNode.h @@ -17,8 +17,6 @@ protected: DoricLayouts *mLayouts = nullptr; - DoricSuperNode *mSuperNode = nullptr; - virtual QQuickItem *build() = 0; void createLayouts(QQuickItem *view); @@ -37,6 +35,8 @@ private: public: QString mType; + DoricSuperNode *mSuperNode = nullptr; + using DoricContextHolder::DoricContextHolder; void init(DoricSuperNode *superNode); diff --git a/doric-Qt/doric/utils/DoricImageBridge.cpp b/doric-Qt/doric/utils/DoricImageBridge.cpp new file mode 100644 index 00000000..7d54a054 --- /dev/null +++ b/doric-Qt/doric/utils/DoricImageBridge.cpp @@ -0,0 +1,20 @@ +#include "DoricImageBridge.h" +#include "shader/DoricImageNode.h" + +DoricImageBridge::DoricImageBridge(QObject *parent) : QObject(parent) {} + +void DoricImageBridge::onNull(QString pointer) {} + +void DoricImageBridge::onReady(QString pointer) { + QObject *object = (QObject *)(pointer.toULongLong()); + DoricImageNode *imageNode = dynamic_cast(object); + imageNode->onReady(); +} + +void DoricImageBridge::onLoading(QString pointer) {} + +void DoricImageBridge::onError(QString pointer) { + QObject *object = (QObject *)(pointer.toULongLong()); + DoricImageNode *imageNode = dynamic_cast(object); + imageNode->onError(); +} diff --git a/doric-Qt/doric/utils/DoricImageBridge.h b/doric-Qt/doric/utils/DoricImageBridge.h new file mode 100644 index 00000000..57496f00 --- /dev/null +++ b/doric-Qt/doric/utils/DoricImageBridge.h @@ -0,0 +1,24 @@ +#ifndef DORICIMAGEBRIDGE_H +#define DORICIMAGEBRIDGE_H + +#include + +class DoricImageBridge : public QObject { + Q_OBJECT +public: + explicit DoricImageBridge(QObject *parent = nullptr); + + Q_INVOKABLE + void onNull(QString pointer); + + Q_INVOKABLE + void onReady(QString pointer); + + Q_INVOKABLE + void onLoading(QString pointer); + + Q_INVOKABLE + void onError(QString pointer); +}; + +#endif // DORICIMAGEBRIDGE_H