split project with app & doric module
This commit is contained in:
126
doric-Qt/example/doric/DoricContext.cpp
Normal file
126
doric-Qt/example/doric/DoricContext.cpp
Normal file
@@ -0,0 +1,126 @@
|
||||
#include "DoricContext.h"
|
||||
#include "DoricContextManager.h"
|
||||
#include "DoricNativeDriver.h"
|
||||
|
||||
#include "shader/DoricRootNode.h"
|
||||
#include "utils/DoricConstant.h"
|
||||
#include "utils/DoricContextHolder.h"
|
||||
|
||||
DoricContext::DoricContext(QString contextId, QString source, QString extra) {
|
||||
this->mRootNode = new DoricRootNode();
|
||||
this->mRootNode->setContext(this);
|
||||
|
||||
this->mContextId = contextId;
|
||||
this->source = source;
|
||||
this->extra = extra;
|
||||
}
|
||||
|
||||
DoricContext::~DoricContext() {
|
||||
QVariantList args;
|
||||
callEntity(DoricConstant::DORIC_ENTITY_DESTROY, args);
|
||||
DoricContextManager::getInstance()->destroyContext(this);
|
||||
}
|
||||
|
||||
DoricContext *DoricContext::create(QString script, QString source,
|
||||
QString extra) {
|
||||
DoricContext *context =
|
||||
DoricContextManager::getInstance()->createContext(script, source, extra);
|
||||
context->script = script;
|
||||
context->init(extra);
|
||||
|
||||
QVariantList args;
|
||||
context->callEntity(DoricConstant::DORIC_ENTITY_CREATE, args);
|
||||
return context;
|
||||
}
|
||||
|
||||
void DoricContext::init(QString initData) {
|
||||
this->extra = initData;
|
||||
if (!initData.isEmpty()) {
|
||||
QVariantList args;
|
||||
args.push_back(initData);
|
||||
callEntity(DoricConstant::DORIC_ENTITY_INIT, args);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricContext::build(int width, int height) {
|
||||
QMap<QString, QVariant> map;
|
||||
map.insert("width", QVariant(width));
|
||||
map.insert("height", QVariant(height));
|
||||
QVariant jsValue(map);
|
||||
this->initParams = jsValue;
|
||||
|
||||
QVariantList args;
|
||||
args.push_back(this->initParams);
|
||||
callEntity(DoricConstant::DORIC_ENTITY_BUILD, args);
|
||||
}
|
||||
|
||||
void DoricContext::callEntity(QString methodName, QVariantList args) {
|
||||
return getDriver()->invokeContextEntityMethod(this->mContextId, methodName,
|
||||
args);
|
||||
}
|
||||
|
||||
DoricInterfaceDriver *DoricContext::getDriver() {
|
||||
if (driver == NULL) {
|
||||
driver = DoricNativeDriver::getInstance();
|
||||
return driver;
|
||||
}
|
||||
return driver;
|
||||
}
|
||||
|
||||
DoricRootNode *DoricContext::getRootNode() { return mRootNode; }
|
||||
|
||||
QObject *DoricContext::obtainPlugin(QString name) {
|
||||
if (mPluginMap.keys().contains(name)) {
|
||||
return mPluginMap.value(name);
|
||||
} else {
|
||||
QObject *plugin = getDriver()->getRegistry()->plugins.createObject(name);
|
||||
dynamic_cast<DoricContextHolder *>(plugin)->setContext(this);
|
||||
mPluginMap.insert(name, plugin);
|
||||
return plugin;
|
||||
}
|
||||
}
|
||||
|
||||
void DoricContext::setQmlEngine(QQmlEngine *engine) { mQmlEngine = engine; }
|
||||
|
||||
QQmlEngine *DoricContext::getQmlEngine() { return mQmlEngine; }
|
||||
|
||||
DoricViewNode *DoricContext::targetViewNode(QString id) {
|
||||
if (id == mRootNode->getId()) {
|
||||
return mRootNode;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString DoricContext::getContextId() { return mContextId; }
|
||||
|
||||
QList<DoricViewNode *> DoricContext::allHeadNodes(QString type) {
|
||||
return mHeadNodes[type].values();
|
||||
}
|
||||
|
||||
void DoricContext::addHeadNode(QString type, DoricViewNode *viewNode) {
|
||||
if (mHeadNodes.contains(type)) {
|
||||
QMap<QString, DoricViewNode *> map = mHeadNodes[type];
|
||||
map.insert(viewNode->getId(), viewNode);
|
||||
mHeadNodes.insert(type, map);
|
||||
} else {
|
||||
QMap<QString, DoricViewNode *> map;
|
||||
map.insert(viewNode->getId(), viewNode);
|
||||
mHeadNodes.insert(type, map);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricContext::removeHeadNode(QString type, DoricViewNode *viewNode) {
|
||||
if (mHeadNodes.contains(type)) {
|
||||
QMap<QString, DoricViewNode *> map = mHeadNodes[type];
|
||||
map.remove(viewNode->getId());
|
||||
mHeadNodes.insert(type, map);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricContext::clearHeadNodes(QString type) {
|
||||
if (mHeadNodes.contains(type)) {
|
||||
QMap<QString, DoricViewNode *> map = mHeadNodes[type];
|
||||
map.clear();
|
||||
mHeadNodes.insert(type, map);
|
||||
}
|
||||
}
|
62
doric-Qt/example/doric/DoricContext.h
Normal file
62
doric-Qt/example/doric/DoricContext.h
Normal file
@@ -0,0 +1,62 @@
|
||||
#ifndef CONTEXT_H
|
||||
#define CONTEXT_H
|
||||
|
||||
#include <QQmlEngine>
|
||||
#include <QVariant>
|
||||
|
||||
#include "DoricInterfaceDriver.h"
|
||||
|
||||
class DoricViewNode;
|
||||
class DoricRootNode;
|
||||
|
||||
class DoricContext {
|
||||
private:
|
||||
QString mContextId;
|
||||
QMap<QString, QObject *> mPluginMap;
|
||||
DoricRootNode *mRootNode;
|
||||
QString source;
|
||||
QString script;
|
||||
QString extra;
|
||||
QVariant initParams;
|
||||
DoricInterfaceDriver *driver = NULL;
|
||||
QQmlEngine *mQmlEngine;
|
||||
|
||||
QMap<QString, QMap<QString, DoricViewNode *>> mHeadNodes;
|
||||
|
||||
public:
|
||||
DoricContext(QString contextId, QString source, QString extra);
|
||||
|
||||
~DoricContext();
|
||||
|
||||
static DoricContext *create(QString script, QString source, QString extra);
|
||||
|
||||
void init(QString initData);
|
||||
|
||||
void build(int width, int height);
|
||||
|
||||
void callEntity(QString methodName, QVariantList args);
|
||||
|
||||
DoricInterfaceDriver *getDriver();
|
||||
|
||||
DoricRootNode *getRootNode();
|
||||
|
||||
QObject *obtainPlugin(QString name);
|
||||
|
||||
void setQmlEngine(QQmlEngine *engine);
|
||||
|
||||
QQmlEngine *getQmlEngine();
|
||||
|
||||
DoricViewNode *targetViewNode(QString id);
|
||||
|
||||
QString getContextId();
|
||||
|
||||
QList<DoricViewNode *> allHeadNodes(QString type);
|
||||
|
||||
void addHeadNode(QString type, DoricViewNode *viewNode);
|
||||
|
||||
void removeHeadNode(QString type, DoricViewNode *viewNode);
|
||||
|
||||
void clearHeadNodes(QString type);
|
||||
};
|
||||
|
||||
#endif // CONTEXT_H
|
21
doric-Qt/example/doric/DoricContextManager.cpp
Normal file
21
doric-Qt/example/doric/DoricContextManager.cpp
Normal file
@@ -0,0 +1,21 @@
|
||||
#include "DoricContextManager.h"
|
||||
|
||||
DoricContext *DoricContextManager::createContext(QString script, QString source,
|
||||
QString extra) {
|
||||
int contextId = counter->fetchAndAddOrdered(1);
|
||||
DoricContext *context =
|
||||
new DoricContext(QString::number(contextId), source, extra);
|
||||
contextMap->insert(QString::number(contextId), context);
|
||||
context->getDriver()->createContext(QString::number(contextId), script,
|
||||
source);
|
||||
return context;
|
||||
}
|
||||
|
||||
DoricContext *DoricContextManager::getContext(QString contextId) {
|
||||
return contextMap->value(contextId);
|
||||
}
|
||||
|
||||
void DoricContextManager::destroyContext(DoricContext *context) {
|
||||
context->getDriver()->destroyContext(context->getContextId());
|
||||
contextMap->remove(context->getContextId());
|
||||
}
|
32
doric-Qt/example/doric/DoricContextManager.h
Normal file
32
doric-Qt/example/doric/DoricContextManager.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef CONTEXTMANAGER_H
|
||||
#define CONTEXTMANAGER_H
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "DoricContext.h"
|
||||
|
||||
class DoricContextManager {
|
||||
private:
|
||||
static DoricContextManager *local_instance;
|
||||
DoricContextManager() {}
|
||||
|
||||
~DoricContextManager() {}
|
||||
|
||||
QAtomicInt *counter = new QAtomicInt();
|
||||
QMap<QString, DoricContext *> *contextMap =
|
||||
new QMap<QString, DoricContext *>();
|
||||
|
||||
public:
|
||||
static DoricContextManager *getInstance() {
|
||||
static DoricContextManager instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
DoricContext *createContext(QString script, QString source, QString extra);
|
||||
|
||||
DoricContext *getContext(QString contextId);
|
||||
|
||||
void destroyContext(DoricContext *context);
|
||||
};
|
||||
|
||||
#endif // CONTEXTMANAGER_H
|
30
doric-Qt/example/doric/DoricInterfaceDriver.h
Normal file
30
doric-Qt/example/doric/DoricInterfaceDriver.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef INTERFACEDRIVER_H
|
||||
#define INTERFACEDRIVER_H
|
||||
|
||||
#include <QRunnable>
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
#include "DoricRegistry.h"
|
||||
#include "async/DoricAsyncResult.h"
|
||||
#include "utils/DoricThreadMode.h"
|
||||
|
||||
class DoricInterfaceDriver {
|
||||
public:
|
||||
virtual void invokeContextEntityMethod(QString contextId, QString method,
|
||||
QVariantList args) = 0;
|
||||
|
||||
virtual void invokeDoricMethod(QString method, QVariantList args) = 0;
|
||||
|
||||
virtual DoricAsyncResult *asyncCall(std::function<void()> lambda,
|
||||
DoricThreadMode mode) = 0;
|
||||
|
||||
virtual void createContext(QString contextId, QString script,
|
||||
QString source) = 0;
|
||||
|
||||
virtual void destroyContext(QString contextId) = 0;
|
||||
|
||||
virtual DoricRegistry *getRegistry() = 0;
|
||||
};
|
||||
|
||||
#endif // INTERFACEDRIVER_H
|
50
doric-Qt/example/doric/DoricNativeDriver.cpp
Normal file
50
doric-Qt/example/doric/DoricNativeDriver.cpp
Normal file
@@ -0,0 +1,50 @@
|
||||
#include <functional>
|
||||
|
||||
#include "DoricNativeDriver.h"
|
||||
#include "async/DoricAsyncCall.h"
|
||||
#include "utils/DoricConstant.h"
|
||||
|
||||
void DoricNativeDriver::invokeContextEntityMethod(QString contextId,
|
||||
QString method,
|
||||
QVariantList args) {
|
||||
args.insert(0, QVariant(contextId));
|
||||
args.insert(1, QVariant(method));
|
||||
invokeDoricMethod(DoricConstant::DORIC_CONTEXT_INVOKE, args);
|
||||
}
|
||||
|
||||
void DoricNativeDriver::invokeDoricMethod(QString method, QVariantList args) {
|
||||
return DoricAsyncCall::ensureRunInThreadPool(
|
||||
&jsEngine.mJSThreadPool,
|
||||
[this, method, args] { this->jsEngine.invokeDoricMethod(method, args); });
|
||||
}
|
||||
|
||||
DoricAsyncResult *DoricNativeDriver::asyncCall(std::function<void()> lambda,
|
||||
DoricThreadMode mode) {
|
||||
switch (mode) {
|
||||
case UI:
|
||||
DoricAsyncCall::ensureRunInMain(lambda);
|
||||
break;
|
||||
case JS:
|
||||
DoricAsyncCall::ensureRunInThreadPool(&jsEngine.mJSThreadPool, lambda);
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void DoricNativeDriver::createContext(QString contextId, QString script,
|
||||
QString source) {
|
||||
DoricAsyncCall::ensureRunInThreadPool(
|
||||
&jsEngine.mJSThreadPool, [this, contextId, script, source] {
|
||||
this->jsEngine.prepareContext(contextId, script, source);
|
||||
});
|
||||
}
|
||||
|
||||
void DoricNativeDriver::destroyContext(QString contextId) {
|
||||
DoricAsyncCall::ensureRunInThreadPool(
|
||||
&jsEngine.mJSThreadPool,
|
||||
[this, contextId] { this->jsEngine.destroyContext(contextId); });
|
||||
}
|
||||
|
||||
DoricRegistry *DoricNativeDriver::getRegistry() {
|
||||
return this->jsEngine.getRegistry();
|
||||
}
|
39
doric-Qt/example/doric/DoricNativeDriver.h
Normal file
39
doric-Qt/example/doric/DoricNativeDriver.h
Normal file
@@ -0,0 +1,39 @@
|
||||
#ifndef NATIVEDRIVER_H
|
||||
#define NATIVEDRIVER_H
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "DoricInterfaceDriver.h"
|
||||
#include "engine/DoricJSEngine.h"
|
||||
|
||||
class DoricNativeDriver : public DoricInterfaceDriver {
|
||||
private:
|
||||
static DoricNativeDriver *local_instance;
|
||||
DoricNativeDriver() {}
|
||||
|
||||
~DoricNativeDriver() {}
|
||||
|
||||
DoricJSEngine jsEngine;
|
||||
|
||||
public:
|
||||
static DoricNativeDriver *getInstance() {
|
||||
static DoricNativeDriver instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
void invokeContextEntityMethod(QString contextId, QString method,
|
||||
QVariantList args) override;
|
||||
|
||||
void invokeDoricMethod(QString method, QVariantList args) override;
|
||||
|
||||
DoricAsyncResult *asyncCall(std::function<void()> lambda,
|
||||
DoricThreadMode mode) override;
|
||||
|
||||
void createContext(QString contextId, QString script,
|
||||
QString source) override;
|
||||
|
||||
void destroyContext(QString contextId) override;
|
||||
|
||||
DoricRegistry *getRegistry() override;
|
||||
};
|
||||
#endif // NATIVEDRIVER_H
|
23
doric-Qt/example/doric/DoricPanel.cpp
Normal file
23
doric-Qt/example/doric/DoricPanel.cpp
Normal file
@@ -0,0 +1,23 @@
|
||||
#include "DoricPanel.h"
|
||||
#include "shader/DoricRootNode.h"
|
||||
|
||||
DoricPanel::DoricPanel(QQmlEngine *qmlEngine, QQuickItem *quickItem) {
|
||||
mQmlEngine = qmlEngine;
|
||||
mQuickItem = quickItem;
|
||||
}
|
||||
|
||||
DoricPanel::~DoricPanel() {
|
||||
delete mContext;
|
||||
}
|
||||
|
||||
void DoricPanel::config(QString script, QString alias, QString extra) {
|
||||
DoricContext *context = DoricContext::create(script, alias, extra);
|
||||
config(context);
|
||||
}
|
||||
|
||||
void DoricPanel::config(DoricContext *context) {
|
||||
this->mContext = context;
|
||||
this->mContext->setQmlEngine(mQmlEngine);
|
||||
this->mContext->getRootNode()->setRootView(mQuickItem);
|
||||
this->mContext->build(mQuickItem->width(), mQuickItem->height());
|
||||
}
|
27
doric-Qt/example/doric/DoricPanel.h
Normal file
27
doric-Qt/example/doric/DoricPanel.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef PANEL_H
|
||||
#define PANEL_H
|
||||
|
||||
#include <QQuickItem>
|
||||
|
||||
#include "DoricContext.h"
|
||||
|
||||
class DoricPanel {
|
||||
private:
|
||||
DoricContext *mContext;
|
||||
int renderedWidth = -1;
|
||||
int renderedHeight = -1;
|
||||
|
||||
QQmlEngine *mQmlEngine;
|
||||
QQuickItem *mQuickItem;
|
||||
|
||||
public:
|
||||
DoricPanel(QQmlEngine *qmlEngine, QQuickItem *quickItem);
|
||||
|
||||
~DoricPanel();
|
||||
|
||||
void config(QString script, QString alias, QString extra);
|
||||
|
||||
void config(DoricContext *context);
|
||||
};
|
||||
|
||||
#endif // PANEL_H
|
37
doric-Qt/example/doric/DoricRegistry.cpp
Normal file
37
doric-Qt/example/doric/DoricRegistry.cpp
Normal file
@@ -0,0 +1,37 @@
|
||||
#include "DoricRegistry.h"
|
||||
|
||||
#include "plugin/DoricModalPlugin.h"
|
||||
#include "plugin/DoricNetworkPlugin.h"
|
||||
#include "plugin/DoricPopoverPlugin.h"
|
||||
#include "plugin/DoricShaderPlugin.h"
|
||||
|
||||
#include "shader/DoricHLayoutNode.h"
|
||||
#include "shader/DoricImageNode.h"
|
||||
#include "shader/DoricRootNode.h"
|
||||
#include "shader/DoricScrollerNode.h"
|
||||
#include "shader/DoricStackNode.h"
|
||||
#include "shader/DoricTextNode.h"
|
||||
#include "shader/DoricVLayoutNode.h"
|
||||
|
||||
DoricRegistry::DoricRegistry() {
|
||||
registerNativePlugin<DoricShaderPlugin>("shader");
|
||||
registerNativePlugin<DoricModalPlugin>("modal");
|
||||
registerNativePlugin<DoricPopoverPlugin>("popover");
|
||||
registerNativePlugin<DoricNetworkPlugin>("network");
|
||||
|
||||
registerViewNode<DoricRootNode>("Root");
|
||||
registerViewNode<DoricStackNode>("Stack");
|
||||
registerViewNode<DoricVLayoutNode>("VLayout");
|
||||
registerViewNode<DoricHLayoutNode>("HLayout");
|
||||
registerViewNode<DoricTextNode>("Text");
|
||||
registerViewNode<DoricScrollerNode>("Scroller");
|
||||
registerViewNode<DoricImageNode>("Image");
|
||||
}
|
||||
|
||||
bool DoricRegistry::acquirePluginInfo(QString name) {
|
||||
return plugins.acquireClass(name);
|
||||
}
|
||||
|
||||
bool DoricRegistry::acquireNodeInfo(QString name) {
|
||||
return nodes.acquireClass(name);
|
||||
}
|
28
doric-Qt/example/doric/DoricRegistry.h
Normal file
28
doric-Qt/example/doric/DoricRegistry.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef REGISTRY_H
|
||||
#define REGISTRY_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "utils/DoricObjectFactory.h"
|
||||
|
||||
class DoricRegistry {
|
||||
public:
|
||||
DoricObjectFactory plugins;
|
||||
DoricObjectFactory nodes;
|
||||
|
||||
DoricRegistry();
|
||||
|
||||
template <typename T> void registerNativePlugin(QString name) {
|
||||
plugins.registerClass<T>(name);
|
||||
}
|
||||
|
||||
template <typename T> void registerViewNode(QString name) {
|
||||
nodes.registerClass<T>(name);
|
||||
}
|
||||
|
||||
bool acquirePluginInfo(QString name);
|
||||
|
||||
bool acquireNodeInfo(QString name);
|
||||
};
|
||||
|
||||
#endif // REGISTRY_H
|
26
doric-Qt/example/doric/async/DoricAsyncCall.h
Normal file
26
doric-Qt/example/doric/async/DoricAsyncCall.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#ifndef ASYNC_CALL_H
|
||||
#define ASYNC_CALL_H
|
||||
|
||||
#include <QFuture>
|
||||
#include <QThreadPool>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
class DoricAsyncCall {
|
||||
|
||||
public:
|
||||
static void ensureRunInThreadPool(QThreadPool *threadPool,
|
||||
std::function<void()> lambda) {
|
||||
QFuture<std::function<void()>::result_type> future =
|
||||
QtConcurrent::run(threadPool, lambda);
|
||||
}
|
||||
|
||||
template <typename Function>
|
||||
static void ensureRunInMain(Function &&function,
|
||||
QThread *thread = qApp->thread()) {
|
||||
auto *obj = QAbstractEventDispatcher::instance(thread);
|
||||
Q_ASSERT(obj);
|
||||
QMetaObject::invokeMethod(obj, std::forward<Function>(function));
|
||||
}
|
||||
};
|
||||
|
||||
#endif // ASYNC_CALL_H
|
38
doric-Qt/example/doric/async/DoricAsyncResult.cpp
Normal file
38
doric-Qt/example/doric/async/DoricAsyncResult.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "DoricAsyncResult.h"
|
||||
|
||||
DoricAsyncResult::DoricAsyncResult() {}
|
||||
|
||||
DoricAsyncResult::DoricAsyncResult(QJSValue result) { this->result = result; }
|
||||
|
||||
void DoricAsyncResult::setResult(QJSValue result) {
|
||||
this->result = result;
|
||||
if (this->callback != NULL) {
|
||||
this->callback->onResult(result);
|
||||
this->callback->onFinish();
|
||||
}
|
||||
}
|
||||
|
||||
void DoricAsyncResult::setError(QJSValue exception) {
|
||||
this->result = exception;
|
||||
if (this->callback != NULL) {
|
||||
this->callback->onResult(result);
|
||||
this->callback->onFinish();
|
||||
}
|
||||
}
|
||||
|
||||
bool DoricAsyncResult::hasResult() { return !result.equals(EMPTY); }
|
||||
|
||||
QJSValue DoricAsyncResult::getResult() { return this->result; }
|
||||
|
||||
void DoricAsyncResult::setCallback(DoricCallback *callback) {
|
||||
this->callback = callback;
|
||||
if (this->result.isError()) {
|
||||
this->callback->onError(result);
|
||||
this->callback->onFinish();
|
||||
} else if (!result.equals(EMPTY)) {
|
||||
this->callback->onResult(result);
|
||||
this->callback->onFinish();
|
||||
}
|
||||
}
|
||||
|
||||
DoricSettableFuture *DoricAsyncResult::synchronous() { return NULL; }
|
34
doric-Qt/example/doric/async/DoricAsyncResult.h
Normal file
34
doric-Qt/example/doric/async/DoricAsyncResult.h
Normal file
@@ -0,0 +1,34 @@
|
||||
#ifndef ASYNCRESULT_H
|
||||
#define ASYNCRESULT_H
|
||||
|
||||
#include <QJSValue>
|
||||
|
||||
#include "DoricCallback.h"
|
||||
#include "DoricSettableFuture.h"
|
||||
|
||||
static QJSValue EMPTY(QJSValue::NullValue);
|
||||
|
||||
class DoricAsyncResult {
|
||||
private:
|
||||
QJSValue result = EMPTY;
|
||||
DoricCallback *callback;
|
||||
|
||||
public:
|
||||
DoricAsyncResult();
|
||||
|
||||
DoricAsyncResult(QJSValue result);
|
||||
|
||||
void setResult(QJSValue result);
|
||||
|
||||
void setError(QJSValue exception);
|
||||
|
||||
bool hasResult();
|
||||
|
||||
QJSValue getResult();
|
||||
|
||||
void setCallback(DoricCallback *callback);
|
||||
|
||||
DoricSettableFuture *synchronous();
|
||||
};
|
||||
|
||||
#endif // ASYNCRESULT_H
|
15
doric-Qt/example/doric/async/DoricCallback.h
Normal file
15
doric-Qt/example/doric/async/DoricCallback.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef CALLBACK_H
|
||||
#define CALLBACK_H
|
||||
|
||||
#include <QJSValue>
|
||||
|
||||
class DoricCallback {
|
||||
public:
|
||||
virtual void onResult(QJSValue result) = 0;
|
||||
|
||||
virtual void onError(QJSValue error) = 0;
|
||||
|
||||
virtual void onFinish() = 0;
|
||||
};
|
||||
|
||||
#endif // CALLBACK_H
|
17
doric-Qt/example/doric/async/DoricSettableFuture.cpp
Normal file
17
doric-Qt/example/doric/async/DoricSettableFuture.cpp
Normal file
@@ -0,0 +1,17 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "DoricSettableFuture.h"
|
||||
|
||||
void DoricSettableFuture::set(QJSValue result) {
|
||||
if (mReadyLatch == NULL) {
|
||||
qDebug() << "Result has already been set!";
|
||||
return;
|
||||
}
|
||||
mResult = result;
|
||||
delete mReadyLatch;
|
||||
}
|
||||
|
||||
QJSValue DoricSettableFuture::get() {
|
||||
mReadyLatch->lock();
|
||||
return mResult;
|
||||
}
|
19
doric-Qt/example/doric/async/DoricSettableFuture.h
Normal file
19
doric-Qt/example/doric/async/DoricSettableFuture.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef SETTABLE_FUTURE_H
|
||||
#define SETTABLE_FUTURE_H
|
||||
|
||||
#include <QJSValue>
|
||||
|
||||
#include "utils/DoricCountDownLatch.h"
|
||||
|
||||
class DoricSettableFuture {
|
||||
private:
|
||||
QJSValue mResult;
|
||||
DoricCountDownLatch *mReadyLatch = new DoricCountDownLatch();
|
||||
|
||||
public:
|
||||
void set(QJSValue result);
|
||||
|
||||
QJSValue get();
|
||||
};
|
||||
|
||||
#endif // SETTABLE_FUTURE_H
|
193
doric-Qt/example/doric/doric.pro
Normal file
193
doric-Qt/example/doric/doric.pro
Normal file
@@ -0,0 +1,193 @@
|
||||
QT += quick
|
||||
|
||||
CONFIG += c++14
|
||||
|
||||
TEMPLATE = lib
|
||||
CONFIG += staticlib
|
||||
|
||||
# The following define makes your compiler emit warnings if you use
|
||||
# any Qt feature that has been marked deprecated (the exact warnings
|
||||
# depend on your compiler). Refer to the documentation for the
|
||||
# deprecated API to know how to port your code away from it.
|
||||
DEFINES += QT_DEPRECATED_WARNINGS
|
||||
DEFINES += V8_COMPRESS_POINTERS
|
||||
|
||||
# You can also make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
# You can also select to disable deprecated APIs only up to a certain version of Qt.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
DoricContext.cpp \
|
||||
DoricContextManager.cpp \
|
||||
DoricNativeDriver.cpp \
|
||||
DoricPanel.cpp \
|
||||
DoricRegistry.cpp \
|
||||
async/DoricAsyncResult.cpp \
|
||||
async/DoricSettableFuture.cpp \
|
||||
engine/DoricBridgeExtension.cpp \
|
||||
engine/DoricJSEngine.cpp \
|
||||
engine/DoricNativeEmpty.cpp \
|
||||
engine/DoricNativeJSE.cpp \
|
||||
engine/DoricNativeLog.cpp \
|
||||
engine/DoricNativeRequire.cpp \
|
||||
engine/DoricTimerExtension.cpp \
|
||||
engine/native/NativeExecutor.cpp \
|
||||
engine/v8/JSValueHelper.cpp \
|
||||
engine/v8/V8Executor.cpp \
|
||||
plugin/DoricModalPlugin.cpp \
|
||||
plugin/DoricNetworkPlugin.cpp \
|
||||
plugin/DoricPopoverPlugin.cpp \
|
||||
plugin/DoricShaderPlugin.cpp \
|
||||
shader/DoricGroupNode.cpp \
|
||||
shader/DoricHLayoutNode.cpp \
|
||||
shader/DoricImageNode.cpp \
|
||||
shader/DoricRootNode.cpp \
|
||||
shader/DoricScrollerNode.cpp \
|
||||
shader/DoricStackNode.cpp \
|
||||
shader/DoricSuperNode.cpp \
|
||||
shader/DoricTextNode.cpp \
|
||||
shader/DoricVLayoutNode.cpp \
|
||||
shader/DoricViewNode.cpp \
|
||||
utils/DoricConstant.cpp \
|
||||
utils/DoricContextHolder.cpp \
|
||||
utils/DoricDialogBridge.cpp \
|
||||
utils/DoricImageBridge.cpp \
|
||||
utils/DoricLayouts.cpp \
|
||||
utils/DoricMouseAreaBridge.cpp \
|
||||
widget/flex/FlexLayout.cpp \
|
||||
widget/flex/FlexLayoutConfig.cpp \
|
||||
widget/flex/FlexLayoutService.cpp \
|
||||
yoga/Utils.cpp \
|
||||
yoga/YGConfig.cpp \
|
||||
yoga/YGEnums.cpp \
|
||||
yoga/YGLayout.cpp \
|
||||
yoga/YGNode.cpp \
|
||||
yoga/YGNodePrint.cpp \
|
||||
yoga/YGStyle.cpp \
|
||||
yoga/YGValue.cpp \
|
||||
yoga/Yoga.cpp \
|
||||
yoga/event/event.cpp \
|
||||
yoga/internal/experiments.cpp \
|
||||
yoga/log.cpp
|
||||
|
||||
RESOURCES += qml.qrc
|
||||
|
||||
# Additional import path used to resolve QML modules in Qt Creator's code model
|
||||
QML_IMPORT_PATH =
|
||||
|
||||
# Additional import path used to resolve QML modules just for Qt Quick Designer
|
||||
QML_DESIGNER_IMPORT_PATH =
|
||||
|
||||
# Default rules for deployment.
|
||||
qnx: target.path = /tmp/$${TARGET}/bin
|
||||
else: unix:!android: target.path = /opt/$${TARGET}/bin
|
||||
!isEmpty(target.path): INSTALLS += target
|
||||
|
||||
HEADERS += \
|
||||
DoricContext.h \
|
||||
DoricContextManager.h \
|
||||
DoricInterfaceDriver.h \
|
||||
DoricNativeDriver.h \
|
||||
DoricPanel.h \
|
||||
DoricRegistry.h \
|
||||
async/DoricAsyncCall.h \
|
||||
async/DoricAsyncResult.h \
|
||||
async/DoricCallback.h \
|
||||
async/DoricSettableFuture.h \
|
||||
engine/DoricBridgeExtension.h \
|
||||
engine/DoricInterfaceJSE.h \
|
||||
engine/DoricJSEngine.h \
|
||||
engine/DoricNativeEmpty.h \
|
||||
engine/DoricNativeJSE.h \
|
||||
engine/DoricNativeLog.h \
|
||||
engine/DoricNativeRequire.h \
|
||||
engine/DoricPromise.h \
|
||||
engine/DoricTimerExtension.h \
|
||||
engine/native/NativeExecutor.h \
|
||||
engine/v8/JSValueHelper.h \
|
||||
engine/v8/V8Executor.h \
|
||||
plugin/DoricModalPlugin.h \
|
||||
plugin/DoricNativePlugin.h \
|
||||
plugin/DoricNetworkPlugin.h \
|
||||
plugin/DoricPopoverPlugin.h \
|
||||
plugin/DoricShaderPlugin.h \
|
||||
shader/DoricGroupNode.h \
|
||||
shader/DoricHLayoutNode.h \
|
||||
shader/DoricImageNode.h \
|
||||
shader/DoricRootNode.h \
|
||||
shader/DoricScrollerNode.h \
|
||||
shader/DoricStackNode.h \
|
||||
shader/DoricSuperNode.h \
|
||||
shader/DoricTextNode.h \
|
||||
shader/DoricVLayoutNode.h \
|
||||
shader/DoricViewNode.h \
|
||||
template/DoricSingleton.h \
|
||||
utils/DoricConstant.h \
|
||||
utils/DoricContextHolder.h \
|
||||
utils/DoricCountDownLatch.h \
|
||||
utils/DoricDialogBridge.h \
|
||||
utils/DoricImageBridge.h \
|
||||
utils/DoricLayouts.h \
|
||||
utils/DoricMouseAreaBridge.h \
|
||||
utils/DoricNetworkService.h \
|
||||
utils/DoricObjectFactory.h \
|
||||
utils/DoricThreadMode.h \
|
||||
utils/DoricUtils.h \
|
||||
widget/flex/FlexLayout.h \
|
||||
widget/flex/FlexLayoutConfig.h \
|
||||
widget/flex/FlexLayoutService.h \
|
||||
yoga/BitUtils.h \
|
||||
yoga/CompactValue.h \
|
||||
yoga/Utils.h \
|
||||
yoga/YGConfig.h \
|
||||
yoga/YGEnums.h \
|
||||
yoga/YGFloatOptional.h \
|
||||
yoga/YGLayout.h \
|
||||
yoga/YGMacros.h \
|
||||
yoga/YGNode.h \
|
||||
yoga/YGNodePrint.h \
|
||||
yoga/YGStyle.h \
|
||||
yoga/YGValue.h \
|
||||
yoga/Yoga-internal.h \
|
||||
yoga/Yoga.h \
|
||||
yoga/event/event.h \
|
||||
yoga/internal/experiments-inl.h \
|
||||
yoga/internal/experiments.h \
|
||||
yoga/log.h
|
||||
|
||||
win32:CONFIG(debug, debug|release): {
|
||||
QMAKE_CFLAGS_DEBUG += -MT
|
||||
QMAKE_CXXFLAGS_DEBUG += -MT
|
||||
|
||||
LIBS += -lwinmm
|
||||
LIBS += -lAdvapi32
|
||||
LIBS += -lDbghelp
|
||||
|
||||
INCLUDEPATH += $$PWD/../../v8/v8/win32/include
|
||||
|
||||
LIBS += -L$$PWD/../../v8/v8/win32/release/
|
||||
LIBS += -lv8_monolith
|
||||
}
|
||||
else:win32:CONFIG(release, debug|release): {
|
||||
QMAKE_CFLAGS_RELEASE += -MT
|
||||
QMAKE_CXXFLAGS_RELEASE += -MT
|
||||
|
||||
LIBS += -lwinmm
|
||||
LIBS += -lAdvapi32
|
||||
LIBS += -lDbghelp
|
||||
|
||||
INCLUDEPATH += $$PWD/../../v8/v8/win32/include
|
||||
|
||||
LIBS += -L$$PWD/../../v8/v8/win32/release/
|
||||
LIBS += -lv8_monolith
|
||||
}
|
||||
else:unix: {
|
||||
QMAKE_CFLAGS_RELEASE += -MT
|
||||
QMAKE_CXXFLAGS_RELEASE += -MT
|
||||
|
||||
INCLUDEPATH += $$PWD/../../v8/v8/darwin/include
|
||||
|
||||
LIBS += -L$$PWD/../../v8/v8/darwin/release/
|
||||
LIBS += -lv8_monolith
|
||||
}
|
317
doric-Qt/example/doric/doric.pro.user
Normal file
317
doric-Qt/example/doric/doric.pro.user
Normal file
@@ -0,0 +1,317 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE QtCreatorProject>
|
||||
<!-- Written by QtCreator 4.14.2, 2021-04-29T17:00:52. -->
|
||||
<qtcreator>
|
||||
<data>
|
||||
<variable>EnvironmentId</variable>
|
||||
<value type="QByteArray">{a49b4abd-08cf-4556-b46e-b0f44132419f}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
||||
<value type="int">0</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
||||
<value type="QString" key="language">Cpp</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
||||
<value type="QString" key="language">QmlJS</value>
|
||||
<valuemap type="QVariantMap" key="value">
|
||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
<value type="int" key="EditorConfiguration.CodeStyle.Count">2</value>
|
||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
||||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
|
||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
||||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
|
||||
<value type="bool" key="AutoTest.Framework.Boost">true</value>
|
||||
<value type="bool" key="AutoTest.Framework.Catch">true</value>
|
||||
<value type="bool" key="AutoTest.Framework.GTest">true</value>
|
||||
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
|
||||
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
|
||||
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
||||
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
||||
<valuelist type="QVariantList" key="ClangCodeModel.CustomCommandLineKey"/>
|
||||
<value type="bool" key="ClangCodeModel.UseGlobalConfig">true</value>
|
||||
<value type="QString" key="ClangCodeModel.WarningConfigId">Builtin.Questionable</value>
|
||||
<valuemap type="QVariantMap" key="ClangTools">
|
||||
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
|
||||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
||||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
||||
<value type="int" key="ClangTools.ParallelJobs">4</value>
|
||||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
||||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
||||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
||||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
||||
</valuemap>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
||||
<valuemap type="QVariantMap">
|
||||
<value type="QString" key="DeviceType">Desktop</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop Qt 5.15.2 clang 64bit</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop Qt 5.15.2 clang 64bit</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">qt.qt5.5152.clang_64_kit</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
||||
<value type="int" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
||||
<value type="int" key="EnableQmlDebugging">0</value>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/maverick/Workspace/Doric/doric-Qt/build-doric-Desktop_Qt_5_15_2_clang_64bit-Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/Users/maverick/Workspace/Doric/doric-Qt/build-doric-Desktop_Qt_5_15_2_clang_64bit-Debug</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">2</value>
|
||||
<value type="int" key="RunSystemFunction">0</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/maverick/Workspace/Doric/doric-Qt/build-doric-Desktop_Qt_5_15_2_clang_64bit-Release</value>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/Users/maverick/Workspace/Doric/doric-Qt/build-doric-Desktop_Qt_5_15_2_clang_64bit-Release</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||
<value type="int" key="QtQuickCompiler">0</value>
|
||||
<value type="int" key="RunSystemFunction">0</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
||||
<value type="int" key="EnableQmlDebugging">0</value>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/Users/maverick/Workspace/Doric/doric-Qt/build-doric-Desktop_Qt_5_15_2_clang_64bit-Profile</value>
|
||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory.shadowDir">/Users/maverick/Workspace/Doric/doric-Qt/build-doric-Desktop_Qt_5_15_2_clang_64bit-Profile</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">QtProjectManager.QMakeBuildStep</value>
|
||||
<value type="QString" key="QtProjectManager.QMakeBuildStep.QMakeArguments"></value>
|
||||
<value type="bool" key="QtProjectManager.QMakeBuildStep.QMakeForced">false</value>
|
||||
<valuelist type="QVariantList" key="QtProjectManager.QMakeBuildStep.SelectedAbis"/>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Build</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
||||
</valuemap>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.MakeStep</value>
|
||||
<value type="QString" key="Qt4ProjectManager.MakeStep.MakeArguments">clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Clean</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value type="int" key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration">0</value>
|
||||
<value type="int" key="QtQuickCompiler">0</value>
|
||||
<value type="int" key="RunSystemFunction">0</value>
|
||||
<value type="int" key="SeparateDebugInfo">0</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
||||
<value type="int" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deploy</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deploy</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
||||
<value type="QString" key="Analyzer.Perf.CallgraphMode">dwarf</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.Events">
|
||||
<value type="QString">cpu-cycles</value>
|
||||
</valuelist>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.ExtraArguments"/>
|
||||
<value type="int" key="Analyzer.Perf.Frequency">250</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Perf.RecordArguments">
|
||||
<value type="QString">-e</value>
|
||||
<value type="QString">cpu-cycles</value>
|
||||
<value type="QString">--call-graph</value>
|
||||
<value type="QString">dwarf,4096</value>
|
||||
<value type="QString">-F</value>
|
||||
<value type="QString">250</value>
|
||||
</valuelist>
|
||||
<value type="QString" key="Analyzer.Perf.SampleMode">-F</value>
|
||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
||||
<value type="int" key="Analyzer.Perf.StackSize">4096</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.AggregateTraces">false</value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.FlushEnabled">false</value>
|
||||
<value type="uint" key="Analyzer.QmlProfiler.FlushInterval">1000</value>
|
||||
<value type="QString" key="Analyzer.QmlProfiler.LastTraceFile"></value>
|
||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.AddedSuppressionFiles"/>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectBusEvents">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.CollectSystime">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableBranchSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableCacheSim">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Callgrind.EnableEventToolTips">true</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.MinimumCostRatio">0.01</value>
|
||||
<value type="double" key="Analyzer.Valgrind.Callgrind.VisualisationMinimumCostRatio">10</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.FilterExternalIssues">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.KCachegrindExecutable">kcachegrind</value>
|
||||
<value type="int" key="Analyzer.Valgrind.LeakCheckOnFinish">1</value>
|
||||
<value type="int" key="Analyzer.Valgrind.NumCallers">25</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.RemovedSuppressionFiles"/>
|
||||
<value type="int" key="Analyzer.Valgrind.SelfModifyingCodeDetection">1</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.ShowReachable">false</value>
|
||||
<value type="bool" key="Analyzer.Valgrind.TrackOrigins">true</value>
|
||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">valgrind</value>
|
||||
<valuelist type="QVariantList" key="Analyzer.Valgrind.VisibleErrorKinds">
|
||||
<value type="int">0</value>
|
||||
<value type="int">1</value>
|
||||
<value type="int">2</value>
|
||||
<value type="int">3</value>
|
||||
<value type="int">4</value>
|
||||
<value type="int">5</value>
|
||||
<value type="int">6</value>
|
||||
<value type="int">7</value>
|
||||
<value type="int">8</value>
|
||||
<value type="int">9</value>
|
||||
<value type="int">10</value>
|
||||
<value type="int">11</value>
|
||||
<value type="int">12</value>
|
||||
<value type="int">13</value>
|
||||
<value type="int">14</value>
|
||||
</valuelist>
|
||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.CustomExecutableRunConfiguration</value>
|
||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey"></value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
||||
</valuemap>
|
||||
<value type="int" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
||||
</valuemap>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
||||
<value type="int">1</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
<value type="int">22</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>Version</variable>
|
||||
<value type="int">22</value>
|
||||
</data>
|
||||
</qtcreator>
|
34
doric-Qt/example/doric/engine/DoricBridgeExtension.cpp
Normal file
34
doric-Qt/example/doric/engine/DoricBridgeExtension.cpp
Normal file
@@ -0,0 +1,34 @@
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QMetaObject>
|
||||
|
||||
#include "../DoricContextManager.h"
|
||||
#include "DoricBridgeExtension.h"
|
||||
|
||||
DoricBridgeExtension::DoricBridgeExtension(QObject *parent) : QObject(parent) {}
|
||||
|
||||
void DoricBridgeExtension::callNative(QString contextId, QString module,
|
||||
QString methodName, QString callbackId,
|
||||
QString argument) {
|
||||
qDebug() << "contextId: " + contextId << "module: " + module
|
||||
<< "methodName: " + methodName << "callbackId: " + callbackId
|
||||
<< "jsValue: " + argument;
|
||||
|
||||
DoricContext *context =
|
||||
DoricContextManager::getInstance()->getContext(contextId);
|
||||
|
||||
if (context == nullptr) {
|
||||
qCritical() << "cannot find context: " + contextId;
|
||||
return;
|
||||
}
|
||||
bool classRegistered =
|
||||
context->getDriver()->getRegistry()->acquirePluginInfo(module);
|
||||
if (classRegistered) {
|
||||
QObject *plugin = context->obtainPlugin(module);
|
||||
QMetaObject::invokeMethod(plugin, methodName.toUtf8(), Qt::DirectConnection,
|
||||
QGenericReturnArgument(),
|
||||
Q_ARG(QString, argument),
|
||||
Q_ARG(QString, callbackId));
|
||||
}
|
||||
}
|
17
doric-Qt/example/doric/engine/DoricBridgeExtension.h
Normal file
17
doric-Qt/example/doric/engine/DoricBridgeExtension.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef BRIDGEEXTENSION_H
|
||||
#define BRIDGEEXTENSION_H
|
||||
|
||||
#include <QJSValue>
|
||||
#include <QObject>
|
||||
|
||||
class DoricBridgeExtension : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DoricBridgeExtension(QObject *parent = nullptr);
|
||||
|
||||
Q_INVOKABLE void callNative(QString contextId, QString module,
|
||||
QString methodName, QString callbackId,
|
||||
QString argument);
|
||||
};
|
||||
|
||||
#endif // BRIDGEEXTENSION_H
|
20
doric-Qt/example/doric/engine/DoricInterfaceJSE.h
Normal file
20
doric-Qt/example/doric/engine/DoricInterfaceJSE.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef INTERFACE_JSE_H
|
||||
#define INTERFACE_JSE_H
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
class DoricInterfaceJSE {
|
||||
public:
|
||||
virtual QString loadJS(QString script, QString source) = 0;
|
||||
|
||||
virtual void injectGlobalJSObject(QString name, QObject *object) = 0;
|
||||
|
||||
virtual void injectGlobalJSFunction(QString name, QObject *function,
|
||||
QString property) = 0;
|
||||
|
||||
virtual void invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments) = 0;
|
||||
};
|
||||
|
||||
#endif // INTERFACE_JSE_H
|
137
doric-Qt/example/doric/engine/DoricJSEngine.cpp
Normal file
137
doric-Qt/example/doric/engine/DoricJSEngine.cpp
Normal file
@@ -0,0 +1,137 @@
|
||||
#include <QGuiApplication>
|
||||
#include <QJsonObject>
|
||||
#include <QRect>
|
||||
#include <QScreen>
|
||||
#include <QSysInfo>
|
||||
#include <QtConcurrent/QtConcurrent>
|
||||
|
||||
#include "../utils/DoricConstant.h"
|
||||
#include "../utils/DoricUtils.h"
|
||||
#include "DoricBridgeExtension.h"
|
||||
#include "DoricJSEngine.h"
|
||||
#include "DoricNativeEmpty.h"
|
||||
#include "DoricNativeJSE.h"
|
||||
#include "DoricNativeLog.h"
|
||||
#include "DoricNativeRequire.h"
|
||||
#include "DoricTimerExtension.h"
|
||||
|
||||
DoricJSEngine::DoricJSEngine(QObject *parent) : QObject(parent) {
|
||||
mJSThreadPool.setMaxThreadCount(1);
|
||||
mJSThreadPool.setExpiryTimeout(-1);
|
||||
|
||||
{
|
||||
auto result = QtConcurrent::run(
|
||||
&mJSThreadPool, [this] { mJSE = new DoricNativeJSE(JSEType::V8); });
|
||||
}
|
||||
{
|
||||
auto result = QtConcurrent::run(&mJSThreadPool, [this] {
|
||||
// inject env
|
||||
QScreen *screen = QGuiApplication::primaryScreen();
|
||||
QRect screenGeometry = screen->geometry();
|
||||
int screenWidth = screenGeometry.width();
|
||||
int screenHeight = screenGeometry.height();
|
||||
|
||||
QObject *envObject = new QObject();
|
||||
envObject->setProperty("platform", "Qt");
|
||||
envObject->setProperty("platformVersion", qVersion());
|
||||
envObject->setProperty("appName", "appName");
|
||||
envObject->setProperty("appVersion", "appVersion");
|
||||
envObject->setProperty("screenWidth", screenWidth);
|
||||
envObject->setProperty("screenHeight", screenHeight);
|
||||
envObject->setProperty("screenScale", 1);
|
||||
envObject->setProperty("statusBarHeight", 0);
|
||||
envObject->setProperty("hasNotch", false);
|
||||
envObject->setProperty("deviceBrand", QSysInfo::prettyProductName());
|
||||
envObject->setProperty("deviceModel", QSysInfo::productType());
|
||||
|
||||
mJSE->injectGlobalJSObject(DoricConstant::INJECT_ENVIRONMENT, envObject);
|
||||
|
||||
// inject log
|
||||
DoricNativeLog *nativeLog = new DoricNativeLog();
|
||||
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_LOG, nativeLog,
|
||||
"function");
|
||||
|
||||
// inject empty
|
||||
DoricNativeEmpty *nativeEmpty = new DoricNativeEmpty();
|
||||
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_EMPTY, nativeEmpty,
|
||||
"function");
|
||||
|
||||
// inject require
|
||||
DoricNativeRequire *nativeRequire = new DoricNativeRequire();
|
||||
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_REQUIRE, nativeRequire,
|
||||
"function");
|
||||
|
||||
// inject timer set & clear
|
||||
DoricTimerExtension *timerExtension =
|
||||
new DoricTimerExtension([this](long timerId) {
|
||||
auto result = QtConcurrent::run(&mJSThreadPool, [this, timerId] {
|
||||
QVariantList arguments;
|
||||
arguments.push_back(QVariant((int)timerId));
|
||||
this->invokeDoricMethod(DoricConstant::DORIC_TIMER_CALLBACK,
|
||||
arguments);
|
||||
});
|
||||
});
|
||||
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_TIMER_SET,
|
||||
timerExtension, "setTimer");
|
||||
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_TIMER_CLEAR,
|
||||
timerExtension, "clearTimer");
|
||||
|
||||
DoricBridgeExtension *bridgeExtension = new DoricBridgeExtension();
|
||||
mJSE->injectGlobalJSFunction(DoricConstant::INJECT_BRIDGE,
|
||||
bridgeExtension, "callNative");
|
||||
});
|
||||
}
|
||||
|
||||
{
|
||||
auto result = QtConcurrent::run(&mJSThreadPool, [this] {
|
||||
loadBuiltinJS(DoricConstant::DORIC_BUNDLE_SANDBOX);
|
||||
|
||||
QString libName = DoricConstant::DORIC_MODULE_LIB;
|
||||
QString libJS =
|
||||
DoricUtils::readAssetFile("/doric", DoricConstant::DORIC_BUNDLE_LIB);
|
||||
QString script = packageModuleScript(libName, libJS);
|
||||
|
||||
mJSE->loadJS(script, "Module://" + libName);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void DoricJSEngine::prepareContext(QString contextId, QString script,
|
||||
QString source) {
|
||||
mJSE->loadJS(packageContextScript(contextId, script), "Context://" + source);
|
||||
}
|
||||
|
||||
void DoricJSEngine::destroyContext(QString contextId) {
|
||||
QString script =
|
||||
QString(DoricConstant::TEMPLATE_CONTEXT_DESTROY).replace("%s", contextId);
|
||||
mJSE->loadJS(script, "_Context://" + contextId);
|
||||
}
|
||||
|
||||
void DoricJSEngine::invokeDoricMethod(QString method, QVariantList arguments) {
|
||||
return mJSE->invokeObject(DoricConstant::GLOBAL_DORIC, method, arguments);
|
||||
}
|
||||
|
||||
void DoricJSEngine::loadBuiltinJS(QString assetName) {
|
||||
QString script = DoricUtils::readAssetFile("/doric", assetName);
|
||||
QString result = mJSE->loadJS(script, "Assets://" + assetName);
|
||||
qDebug() << result;
|
||||
}
|
||||
|
||||
QString DoricJSEngine::packageContextScript(QString contextId,
|
||||
QString content) {
|
||||
return QString(DoricConstant::TEMPLATE_CONTEXT_CREATE)
|
||||
.replace("%s1", content)
|
||||
.replace("%s2", contextId)
|
||||
.replace("%s3", contextId);
|
||||
}
|
||||
|
||||
QString DoricJSEngine::packageModuleScript(QString moduleName,
|
||||
QString content) {
|
||||
return QString(DoricConstant::TEMPLATE_MODULE)
|
||||
.replace("%s1", moduleName)
|
||||
.replace("%s2", content);
|
||||
}
|
||||
|
||||
DoricRegistry *DoricJSEngine::getRegistry() { return this->mRegistry; }
|
||||
|
||||
DoricJSEngine::~DoricJSEngine() {}
|
36
doric-Qt/example/doric/engine/DoricJSEngine.h
Normal file
36
doric-Qt/example/doric/engine/DoricJSEngine.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef JSENGINE_H
|
||||
#define JSENGINE_H
|
||||
|
||||
#include <QJSValue>
|
||||
#include <QThreadPool>
|
||||
|
||||
#include "../DoricRegistry.h"
|
||||
#include "DoricInterfaceJSE.h"
|
||||
|
||||
class DoricJSEngine : public QObject {
|
||||
Q_OBJECT
|
||||
private:
|
||||
DoricInterfaceJSE *mJSE;
|
||||
DoricRegistry *mRegistry = new DoricRegistry();
|
||||
|
||||
void loadBuiltinJS(QString assetName);
|
||||
QString packageContextScript(QString contextId, QString content);
|
||||
QString packageModuleScript(QString moduleName, QString content);
|
||||
|
||||
public:
|
||||
QThreadPool mJSThreadPool;
|
||||
|
||||
explicit DoricJSEngine(QObject *parent = nullptr);
|
||||
|
||||
~DoricJSEngine();
|
||||
|
||||
void prepareContext(QString contextId, QString script, QString source);
|
||||
|
||||
void destroyContext(QString contextId);
|
||||
|
||||
void invokeDoricMethod(QString method, QVariantList arguments);
|
||||
|
||||
DoricRegistry *getRegistry();
|
||||
};
|
||||
|
||||
#endif // JSENGINE_H
|
6
doric-Qt/example/doric/engine/DoricNativeEmpty.cpp
Normal file
6
doric-Qt/example/doric/engine/DoricNativeEmpty.cpp
Normal file
@@ -0,0 +1,6 @@
|
||||
#include "DoricNativeEmpty.h"
|
||||
#include <QDebug>
|
||||
|
||||
Q_INVOKABLE void DoricNativeEmpty::function() {
|
||||
qDebug() << "nativeEmpty";
|
||||
}
|
15
doric-Qt/example/doric/engine/DoricNativeEmpty.h
Normal file
15
doric-Qt/example/doric/engine/DoricNativeEmpty.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef NATIVEEMPTY_H
|
||||
#define NATIVEEMPTY_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class DoricNativeEmpty : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DoricNativeEmpty(QObject *parent = nullptr) : QObject(parent) {}
|
||||
|
||||
Q_INVOKABLE void function();
|
||||
};
|
||||
|
||||
#endif // NATIVEEMPTY_H
|
66
doric-Qt/example/doric/engine/DoricNativeJSE.cpp
Normal file
66
doric-Qt/example/doric/engine/DoricNativeJSE.cpp
Normal file
@@ -0,0 +1,66 @@
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "../utils/DoricUtils.h"
|
||||
#include "DoricNativeJSE.h"
|
||||
|
||||
DoricNativeJSE::DoricNativeJSE(JSEType type) {
|
||||
mType = type;
|
||||
if (mType == JSEType::V8) {
|
||||
v8Executor = new V8Executor();
|
||||
} else if (mType == JSEType::Native) {
|
||||
nativeExecutor = new NativeExecutor();
|
||||
}
|
||||
}
|
||||
|
||||
QString DoricNativeJSE::loadJS(QString script, QString source) {
|
||||
if (mType == JSEType::V8) {
|
||||
return v8Executor->loadJS(script, source);
|
||||
} else if (mType == JSEType::Native) {
|
||||
return nativeExecutor->loadJS(script, source);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricNativeJSE::injectGlobalJSObject(QString name, QObject *object) {
|
||||
if (mType == JSEType::V8) {
|
||||
QJsonObject jsonObject;
|
||||
|
||||
QList<QByteArray> propertyNames = object->dynamicPropertyNames();
|
||||
foreach (QByteArray propertyName, propertyNames) {
|
||||
QString key = QString::fromStdString(propertyName.toStdString());
|
||||
object->property(propertyName).toString();
|
||||
if (key == "undefined" || key.isEmpty()) {
|
||||
|
||||
} else {
|
||||
jsonObject[key] =
|
||||
QJsonValue::fromVariant(object->property(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
QJsonDocument doc(jsonObject);
|
||||
QString strJson(doc.toJson(QJsonDocument::Compact));
|
||||
|
||||
v8Executor->injectGlobalJSObject(name, strJson.toUtf8().constData());
|
||||
} else if (mType == JSEType::Native) {
|
||||
nativeExecutor->injectGlobalJSObject(name, object);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricNativeJSE::injectGlobalJSFunction(QString name, QObject *function,
|
||||
QString property) {
|
||||
if (mType == JSEType::V8) {
|
||||
v8Executor->injectGlobalJSFunction(name, function, property);
|
||||
} else if (mType == JSEType::Native) {
|
||||
nativeExecutor->injectGlobalJSFunction(name, function, property);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricNativeJSE::invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments) {
|
||||
if (mType == JSEType::V8) {
|
||||
v8Executor->invokeObject(objectName, functionName, arguments);
|
||||
} else if (mType == JSEType::Native) {
|
||||
nativeExecutor->invokeObject(objectName, functionName, arguments);
|
||||
}
|
||||
}
|
31
doric-Qt/example/doric/engine/DoricNativeJSE.h
Normal file
31
doric-Qt/example/doric/engine/DoricNativeJSE.h
Normal file
@@ -0,0 +1,31 @@
|
||||
#ifndef NATIVE_JSE_H
|
||||
#define NATIVE_JSE_H
|
||||
|
||||
#include "DoricInterfaceJSE.h"
|
||||
#include "native/NativeExecutor.h"
|
||||
#include "v8/V8Executor.h"
|
||||
|
||||
enum class JSEType { V8, Native };
|
||||
|
||||
class DoricNativeJSE : public DoricInterfaceJSE {
|
||||
private:
|
||||
JSEType mType;
|
||||
|
||||
V8Executor *v8Executor;
|
||||
NativeExecutor *nativeExecutor;
|
||||
|
||||
public:
|
||||
DoricNativeJSE(JSEType type);
|
||||
|
||||
QString loadJS(QString script, QString source) override;
|
||||
|
||||
void injectGlobalJSObject(QString name, QObject *object) override;
|
||||
|
||||
void injectGlobalJSFunction(QString name, QObject *function,
|
||||
QString property) override;
|
||||
|
||||
void invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments) override;
|
||||
};
|
||||
|
||||
#endif // NATIVE_JSE_H
|
13
doric-Qt/example/doric/engine/DoricNativeLog.cpp
Normal file
13
doric-Qt/example/doric/engine/DoricNativeLog.cpp
Normal file
@@ -0,0 +1,13 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "DoricNativeLog.h"
|
||||
|
||||
Q_INVOKABLE void DoricNativeLog::function(QString level, QString content) {
|
||||
if (level == 'w') {
|
||||
qWarning() << content;
|
||||
} else if (level == 'd') {
|
||||
qDebug() << content;
|
||||
} else if (level == 'e') {
|
||||
qCritical() << content;
|
||||
}
|
||||
}
|
15
doric-Qt/example/doric/engine/DoricNativeLog.h
Normal file
15
doric-Qt/example/doric/engine/DoricNativeLog.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef NATIVE_LOG_H
|
||||
#define NATIVE_LOG_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class DoricNativeLog : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DoricNativeLog(QObject *parent = nullptr) : QObject(parent) {}
|
||||
|
||||
Q_INVOKABLE void function(QString level, QString content);
|
||||
};
|
||||
|
||||
#endif // NATIVE_LOG_H
|
7
doric-Qt/example/doric/engine/DoricNativeRequire.cpp
Normal file
7
doric-Qt/example/doric/engine/DoricNativeRequire.cpp
Normal file
@@ -0,0 +1,7 @@
|
||||
#include "DoricNativeRequire.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
Q_INVOKABLE void DoricNativeRequire::function(QString name) {
|
||||
qDebug() << "nativeRequire: " << name.toUtf8();
|
||||
}
|
15
doric-Qt/example/doric/engine/DoricNativeRequire.h
Normal file
15
doric-Qt/example/doric/engine/DoricNativeRequire.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef NATIVE_REQUIRE_H
|
||||
#define NATIVE_REQUIRE_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class DoricNativeRequire : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
DoricNativeRequire(QObject *parent = nullptr) : QObject(parent) {}
|
||||
|
||||
Q_INVOKABLE void function(QString name);
|
||||
};
|
||||
|
||||
#endif // NATIVE_REQUIRE_H
|
36
doric-Qt/example/doric/engine/DoricPromise.h
Normal file
36
doric-Qt/example/doric/engine/DoricPromise.h
Normal file
@@ -0,0 +1,36 @@
|
||||
#ifndef DORICPROMISE_H
|
||||
#define DORICPROMISE_H
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
#include "DoricContext.h"
|
||||
#include "utils/DoricConstant.h"
|
||||
|
||||
class DoricPromise {
|
||||
public:
|
||||
static void resolve(DoricContext *context, QString callbackId,
|
||||
QVariantList args) {
|
||||
QVariantList params;
|
||||
params.append(context->getContextId());
|
||||
params.append(callbackId);
|
||||
|
||||
foreach (QVariant arg, args) { params.append(arg); }
|
||||
|
||||
context->getDriver()->invokeDoricMethod(DoricConstant::DORIC_BRIDGE_RESOLVE,
|
||||
params);
|
||||
}
|
||||
|
||||
static void reject(DoricContext *context, QString callbackId,
|
||||
QVariantList args) {
|
||||
QVariantList params;
|
||||
params.append(context->getContextId());
|
||||
params.append(callbackId);
|
||||
|
||||
foreach (QVariant arg, args) { params.append(arg); }
|
||||
|
||||
context->getDriver()->invokeDoricMethod(DoricConstant::DORIC_BRIDGE_REJECT,
|
||||
params);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // DORICPROMISE_H
|
36
doric-Qt/example/doric/engine/DoricTimerExtension.cpp
Normal file
36
doric-Qt/example/doric/engine/DoricTimerExtension.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <QCoreApplication>
|
||||
#include <QTimer>
|
||||
|
||||
#include "../utils/DoricConstant.h"
|
||||
#include "DoricTimerExtension.h"
|
||||
|
||||
Q_INVOKABLE void DoricTimerExtension::setTimer(long timerId, int time,
|
||||
bool repeat) {
|
||||
|
||||
connect(this, &DoricTimerExtension::startTimer, qApp, [=]() {
|
||||
QTimer *timer = new QTimer();
|
||||
timer->setSingleShot(!repeat);
|
||||
|
||||
connect(timer, &QTimer::timeout, [=]() {
|
||||
if (deletedTimerIds->contains(timerId)) {
|
||||
deletedTimerIds->remove(timerId);
|
||||
timer->deleteLater();
|
||||
} else {
|
||||
this->method(timerId);
|
||||
|
||||
if (!repeat) {
|
||||
deletedTimerIds->remove(timerId);
|
||||
timer->deleteLater();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
timer->start(time);
|
||||
});
|
||||
|
||||
emit startTimer();
|
||||
}
|
||||
|
||||
Q_INVOKABLE void DoricTimerExtension::clearTimer(long timerId) {
|
||||
deletedTimerIds->insert(timerId);
|
||||
}
|
28
doric-Qt/example/doric/engine/DoricTimerExtension.h
Normal file
28
doric-Qt/example/doric/engine/DoricTimerExtension.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef NATIVETIMER_H
|
||||
#define NATIVETIMER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QSet>
|
||||
|
||||
class DoricTimerExtension : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
private:
|
||||
QSet<long> *deletedTimerIds = new QSet<long>();
|
||||
std::function<void(long)> method;
|
||||
|
||||
public:
|
||||
explicit DoricTimerExtension(std::function<void(long)> method,
|
||||
QObject *parent = nullptr)
|
||||
: QObject(parent) {
|
||||
this->method = method;
|
||||
}
|
||||
|
||||
Q_INVOKABLE void setTimer(long timerId, int time, bool repeat);
|
||||
|
||||
Q_INVOKABLE void clearTimer(long timerId);
|
||||
|
||||
signals:
|
||||
void startTimer();
|
||||
};
|
||||
#endif // NATIVETIMER_H
|
82
doric-Qt/example/doric/engine/native/NativeExecutor.cpp
Normal file
82
doric-Qt/example/doric/engine/native/NativeExecutor.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
#include "NativeExecutor.h"
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
NativeExecutor::NativeExecutor() {
|
||||
mJSEngine = new QJSEngine();
|
||||
mJSEngine->installExtensions(QJSEngine::AllExtensions);
|
||||
}
|
||||
|
||||
NativeExecutor::~NativeExecutor() { delete mJSEngine; }
|
||||
|
||||
QString NativeExecutor::loadJS(QString script, QString source) {
|
||||
return mJSEngine->evaluate(script, source).toString();
|
||||
}
|
||||
|
||||
void NativeExecutor::injectGlobalJSObject(QString name, QObject *object) {
|
||||
QJSValue jsObject = mJSEngine->newQObject(object);
|
||||
|
||||
QList<QByteArray> propertyNames = object->dynamicPropertyNames();
|
||||
foreach (QByteArray propertyName, propertyNames) {
|
||||
QString key = QString::fromStdString(propertyName.toStdString());
|
||||
if (key == "undefined") {
|
||||
|
||||
} else {
|
||||
jsObject.setProperty(
|
||||
key, mJSEngine->toScriptValue(object->property(propertyName)));
|
||||
}
|
||||
}
|
||||
|
||||
mJSEngine->globalObject().setProperty(name, jsObject);
|
||||
}
|
||||
|
||||
void NativeExecutor::injectGlobalJSFunction(QString name, QObject *function,
|
||||
QString property) {
|
||||
QJSValue functionObject = mJSEngine->newQObject(function);
|
||||
mJSEngine->globalObject().setProperty(name,
|
||||
functionObject.property(property));
|
||||
}
|
||||
|
||||
QJSValue NativeExecutor::invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments) {
|
||||
QJSValue object = mJSEngine->evaluate(objectName);
|
||||
QJSValue function = object.property(functionName);
|
||||
|
||||
QJSValueList args;
|
||||
foreach (QVariant variant, arguments) {
|
||||
if (variant.type() == QVariant::String) {
|
||||
args.push_back(QJSValue(variant.toString()));
|
||||
} else if (variant.type() == QVariant::Map) {
|
||||
QJSValue arg = mJSEngine->newObject();
|
||||
QMap<QString, QVariant> map = variant.toMap();
|
||||
foreach (QString key, map.keys()) {
|
||||
QVariant value = map.value(key);
|
||||
if (value.type() == QVariant::String) {
|
||||
arg.setProperty(key, value.toString());
|
||||
} else if (value.type() == QVariant::Int) {
|
||||
arg.setProperty(key, value.toInt());
|
||||
}
|
||||
}
|
||||
args.push_back(arg);
|
||||
} else if (variant.type() == QVariant::StringList) {
|
||||
QStringList array = variant.toStringList();
|
||||
QJSValue arg = mJSEngine->newArray(array.size());
|
||||
|
||||
for (int i = 0; i != array.size(); i++) {
|
||||
arg.setProperty(i, array.at(i));
|
||||
}
|
||||
args.push_back(arg);
|
||||
}
|
||||
}
|
||||
|
||||
QJSValue result = function.call(args);
|
||||
if (result.isError()) {
|
||||
qCritical() << "++++++++++++++++++++++++++++++++++++++++++++++++";
|
||||
qCritical() << result.toString();
|
||||
QStringList stacktraces = result.property("stack").toString().split("\n");
|
||||
foreach (QString stacktrace, stacktraces) { qDebug() << stacktrace; }
|
||||
qCritical() << "------------------------------------------------";
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
27
doric-Qt/example/doric/engine/native/NativeExecutor.h
Normal file
27
doric-Qt/example/doric/engine/native/NativeExecutor.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef NATIVEEXECUTOR_H
|
||||
#define NATIVEEXECUTOR_H
|
||||
|
||||
#include <QJSEngine>
|
||||
|
||||
class NativeExecutor {
|
||||
|
||||
private:
|
||||
QJSEngine *mJSEngine;
|
||||
|
||||
public:
|
||||
NativeExecutor();
|
||||
|
||||
~NativeExecutor();
|
||||
|
||||
QString loadJS(QString script, QString source);
|
||||
|
||||
void injectGlobalJSObject(QString name, QObject *object);
|
||||
|
||||
void injectGlobalJSFunction(QString name, QObject *function,
|
||||
QString property);
|
||||
|
||||
QJSValue invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments);
|
||||
};
|
||||
|
||||
#endif // NATIVEEXECUTOR_H
|
95
doric-Qt/example/doric/engine/v8/JSValueHelper.cpp
Normal file
95
doric-Qt/example/doric/engine/v8/JSValueHelper.cpp
Normal file
@@ -0,0 +1,95 @@
|
||||
#include "JSValueHelper.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
std::string JS2String(v8::Local<v8::Value> object) {
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
v8::HandleScope handleScope(isolate);
|
||||
v8::Local<v8::Context> context = isolate->GetEnteredOrMicrotaskContext();
|
||||
if (object->IsString() || object->IsRegExp() || object->IsFunction()) {
|
||||
v8::String::Utf8Value utf8(isolate, object);
|
||||
return std::string(*utf8);
|
||||
}
|
||||
if (object->IsObject()) {
|
||||
v8::MaybeLocal<v8::String> str = v8::JSON::Stringify(
|
||||
context, object->ToObject(context).ToLocalChecked());
|
||||
if (str.IsEmpty()) {
|
||||
return "<string conversion failed>";
|
||||
}
|
||||
v8::Local<v8::String> s = str.ToLocalChecked();
|
||||
v8::String::Utf8Value str2(isolate, s);
|
||||
return std::string(*str2 ? *str2 : "<string conversion failed>");
|
||||
}
|
||||
|
||||
v8::String::Utf8Value str(
|
||||
isolate, v8::JSON::Stringify(context, object).ToLocalChecked());
|
||||
return std::string(*str ? *str : "<string conversion failed>");
|
||||
}
|
||||
|
||||
double JS2Number(v8::Local<v8::Value> value) {
|
||||
v8::HandleScope handleScope(v8::Isolate::GetCurrent());
|
||||
v8::Local<v8::Context> context =
|
||||
v8::Isolate::GetCurrent()->GetCurrentContext();
|
||||
if (value->IsNumber()) {
|
||||
return value->ToNumber(context).ToLocalChecked()->Value();
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool JS2Bool(v8::Local<v8::Value> value) {
|
||||
v8::HandleScope handleScope(v8::Isolate::GetCurrent());
|
||||
if (value->IsBoolean()) {
|
||||
return value->ToBoolean(v8::Isolate::GetCurrent())->Value();
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> String2JS(std::string string) {
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
v8::EscapableHandleScope handleScope(isolate);
|
||||
v8::Local<v8::Context> context = isolate->GetEnteredOrMicrotaskContext();
|
||||
v8::Local<v8::String> jsString = NewV8String(string.c_str());
|
||||
|
||||
v8::Local<v8::Value> ret =
|
||||
v8::JSON::Parse(context, jsString).ToLocalChecked();
|
||||
|
||||
return handleScope.Escape(ret);
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> Variant2JS(QVariant variant) {
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
|
||||
v8::EscapableHandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Context> context = isolate->GetEnteredOrMicrotaskContext();
|
||||
|
||||
v8::Local<v8::Value> jsValue;
|
||||
if (variant.type() == QVariant::String) {
|
||||
jsValue = NewV8String(variant.toString().toUtf8().constData());
|
||||
} else if (variant.type() == QVariant::Map) {
|
||||
QMap<QString, QVariant> map = variant.toMap();
|
||||
|
||||
QJsonObject jsonObject;
|
||||
foreach (QString key, map.keys()) {
|
||||
QVariant value = map.value(key);
|
||||
jsonObject.insert(key, QJsonValue::fromVariant(value));
|
||||
}
|
||||
QJsonDocument doc(jsonObject);
|
||||
QString strJson(doc.toJson(QJsonDocument::Compact));
|
||||
jsValue = String2JS(strJson.toUtf8().constData());
|
||||
} else if (variant.type() == QVariant::StringList) {
|
||||
QStringList list = variant.toStringList();
|
||||
v8::Handle<v8::Array> array = v8::Array::New(isolate, list.size());
|
||||
for (int i = 0; i != list.size(); i++) {
|
||||
v8::Local<v8::Value> value = NewV8String(list.at(i).toUtf8().constData());
|
||||
auto result = array->Set(context, i, value);
|
||||
result.ToChecked();
|
||||
}
|
||||
jsValue = array;
|
||||
} else if (variant.type() == QVariant::Int) {
|
||||
jsValue = v8::Number::New(isolate, variant.toDouble());
|
||||
}
|
||||
return handle_scope.Escape(jsValue);
|
||||
}
|
24
doric-Qt/example/doric/engine/v8/JSValueHelper.h
Normal file
24
doric-Qt/example/doric/engine/v8/JSValueHelper.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef JSVALUEHELPER_H
|
||||
#define JSVALUEHELPER_H
|
||||
|
||||
#include <QVariant>
|
||||
#include <string>
|
||||
|
||||
#include "v8.h"
|
||||
|
||||
#define NewV8String(name) \
|
||||
v8::String::NewFromUtf8(v8::Isolate::GetCurrent(), name, \
|
||||
v8::NewStringType::kNormal) \
|
||||
.ToLocalChecked()
|
||||
|
||||
std::string JS2String(v8::Local<v8::Value> object);
|
||||
|
||||
double JS2Number(v8::Local<v8::Value> value);
|
||||
|
||||
bool JS2Bool(v8::Local<v8::Value> value);
|
||||
|
||||
v8::Local<v8::Value> String2JS(std::string string);
|
||||
|
||||
v8::Local<v8::Value> Variant2JS(QVariant variant);
|
||||
|
||||
#endif // JSVALUEHELPER_H
|
348
doric-Qt/example/doric/engine/v8/V8Executor.cpp
Normal file
348
doric-Qt/example/doric/engine/v8/V8Executor.cpp
Normal file
@@ -0,0 +1,348 @@
|
||||
#include <QDebug>
|
||||
|
||||
#include "JSValueHelper.h"
|
||||
#include "V8Executor.h"
|
||||
|
||||
V8Executor::V8Executor() : platform(v8::platform::NewDefaultPlatform()) {
|
||||
v8::V8::InitializeICUDefaultLocation("");
|
||||
v8::V8::InitializeExternalStartupData("");
|
||||
v8::V8::InitializePlatform(platform.get());
|
||||
v8::V8::Initialize();
|
||||
|
||||
create_params.array_buffer_allocator =
|
||||
v8::ArrayBuffer::Allocator::NewDefaultAllocator();
|
||||
m_isolate = v8::Isolate::New(create_params);
|
||||
m_isolate_scope = new v8::Isolate::Scope(m_isolate);
|
||||
|
||||
v8::Isolate *isolate = v8::Isolate::GetCurrent();
|
||||
v8::HandleScope scope(isolate);
|
||||
|
||||
v8::Local<v8::ObjectTemplate> global = v8::ObjectTemplate::New(isolate);
|
||||
v8::Local<v8::Context> context = v8::Context::New(isolate, nullptr, global);
|
||||
context->Enter();
|
||||
m_global_context = new v8::Global<v8::Context>(isolate, context);
|
||||
}
|
||||
|
||||
V8Executor::~V8Executor() {
|
||||
{
|
||||
v8::HandleScope scope(m_isolate);
|
||||
v8::Local<v8::Context> context = m_global_context->Get(m_isolate);
|
||||
context->Exit();
|
||||
}
|
||||
m_global_context->Reset();
|
||||
delete m_global_context;
|
||||
delete m_isolate_scope;
|
||||
m_isolate->Dispose();
|
||||
v8::V8::Dispose();
|
||||
v8::V8::ShutdownPlatform();
|
||||
delete create_params.array_buffer_allocator;
|
||||
}
|
||||
|
||||
QString V8Executor::loadJS(QString script, QString source) {
|
||||
v8::Isolate *isolate = m_isolate;
|
||||
|
||||
std::string exception;
|
||||
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Value> ret = innerExec(script.toUtf8().constData(),
|
||||
source.toUtf8().constData(), &exception);
|
||||
std::string result = JS2String(ret);
|
||||
|
||||
return QString::fromUtf8(result.c_str());
|
||||
}
|
||||
|
||||
void V8Executor::injectGlobalJSObject(QString name, std::string target) {
|
||||
v8::Isolate *isolate = m_isolate;
|
||||
v8::HandleScope handleScope(isolate);
|
||||
|
||||
v8::Local<v8::Value> local = String2JS(target);
|
||||
|
||||
injectObject(name.toUtf8().constData(), local);
|
||||
}
|
||||
|
||||
void V8Executor::injectGlobalJSFunction(QString name, QObject *function,
|
||||
QString property) {
|
||||
if (map->keys().contains(name)) {
|
||||
qCritical() << "already injected";
|
||||
return;
|
||||
} else {
|
||||
QPair<QObject *, QString> pair(function, property);
|
||||
map->insert(name, pair);
|
||||
}
|
||||
injectFunctions(nullptr, name.toUtf8().constData(), true);
|
||||
}
|
||||
|
||||
void V8Executor::invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments) {
|
||||
std::string exception;
|
||||
v8::HandleScope handleScope(m_isolate);
|
||||
int valueSize = arguments.size();
|
||||
|
||||
auto js_values = new v8::Local<v8::Value>[valueSize];
|
||||
for (int i = 0; i < valueSize; i++) {
|
||||
js_values[i] = Variant2JS(arguments.at(i));
|
||||
}
|
||||
v8::Local<v8::Value> value = invokeMethod(objectName.toUtf8().constData(),
|
||||
functionName.toUtf8().constData(),
|
||||
valueSize, js_values, &exception);
|
||||
delete[] js_values;
|
||||
}
|
||||
|
||||
// private segment
|
||||
void V8Executor::injectObject(const char *string, v8::Local<v8::Value> local) {
|
||||
v8::Isolate *isolate = m_isolate;
|
||||
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Context> context = isolate->GetEnteredOrMicrotaskContext();
|
||||
v8::Local<v8::Object> object = context->Global();
|
||||
v8::Maybe<bool> result = object->Set(context, NewV8String(string), local);
|
||||
result.ToChecked();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> V8Executor::innerExec(const char *script,
|
||||
const char *source,
|
||||
std::string *exception_str) {
|
||||
v8::Isolate *isolate = m_isolate;
|
||||
|
||||
v8::EscapableHandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Value> result = Undefined(isolate);
|
||||
v8::Local<v8::Context> context = isolate->GetEnteredOrMicrotaskContext();
|
||||
v8::Context::Scope context_scope(context);
|
||||
v8::ScriptOrigin origin(NewV8String(source));
|
||||
if (script) {
|
||||
v8::Local<v8::String> jsSource = NewV8String(script);
|
||||
v8::TryCatch try_catch(isolate);
|
||||
try_catch.SetVerbose(true);
|
||||
|
||||
v8::MaybeLocal<v8::Script> maybeScript =
|
||||
v8::Script::Compile(context, jsSource, &origin);
|
||||
|
||||
if (!maybeScript.IsEmpty()) {
|
||||
v8::Local<v8::Script> js_script = maybeScript.ToLocalChecked();
|
||||
v8::MaybeLocal<v8::Value> res = js_script->Run(context);
|
||||
if (!res.IsEmpty()) {
|
||||
result = res.ToLocalChecked();
|
||||
}
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> exception = try_catch.Exception();
|
||||
if (!exception.IsEmpty()) {
|
||||
if (exception->IsObject()) {
|
||||
v8::Local<v8::Object> exc = v8::Local<v8::Object>::Cast(exception);
|
||||
v8::Local<v8::Value> stack =
|
||||
exc->Get(context, NewV8String("stack")).FromMaybe(exception);
|
||||
*exception_str = JS2String(stack);
|
||||
} else {
|
||||
*exception_str = JS2String(exception);
|
||||
}
|
||||
}
|
||||
}
|
||||
return handle_scope.Escape(result);
|
||||
}
|
||||
|
||||
static void InjectedFunction(const v8::FunctionCallbackInfo<v8::Value> &args) {
|
||||
v8::Isolate *isolate = args.GetIsolate();
|
||||
v8::HandleScope scope(isolate);
|
||||
v8::Local<v8::Context> context = isolate->GetEnteredOrMicrotaskContext();
|
||||
v8::Local<v8::Object> data = args.Data()->ToObject(context).ToLocalChecked();
|
||||
|
||||
std::string objectKey =
|
||||
JS2String(data->Get(context, NewV8String("obj")).ToLocalChecked())
|
||||
.c_str();
|
||||
std::string functionKey =
|
||||
JS2String(data->Get(context, NewV8String("func")).ToLocalChecked())
|
||||
.c_str();
|
||||
bool hashKey = data->Get(context, NewV8String("hashKey"))
|
||||
.ToLocalChecked()
|
||||
->BooleanValue(isolate);
|
||||
|
||||
// invoke
|
||||
QPair<QObject *, QString> pair =
|
||||
map->find(QString::fromUtf8(functionKey.c_str())).value();
|
||||
|
||||
QString functionKeyQString = QString::fromUtf8(functionKey.c_str());
|
||||
|
||||
if (args.Length() == 0) {
|
||||
if (functionKeyQString == "nativeEmpty") {
|
||||
QMetaObject::invokeMethod(pair.first, pair.second.toUtf8().constData(),
|
||||
Qt::DirectConnection, QGenericReturnArgument());
|
||||
}
|
||||
} else if (args.Length() == 1) {
|
||||
if (functionKeyQString == "nativeRequire") {
|
||||
v8::Local<v8::Value> arg = args[0];
|
||||
std::string argString = JS2String(arg);
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
pair.first, pair.second.toUtf8().constData(), Qt::DirectConnection,
|
||||
QGenericReturnArgument(),
|
||||
Q_ARG(QString, QString::fromUtf8(argString.c_str())));
|
||||
} else if (functionKeyQString == "nativeClearTimer") {
|
||||
v8::Local<v8::Value> arg = args[0];
|
||||
double number = JS2Number(arg);
|
||||
|
||||
QMetaObject::invokeMethod(pair.first, pair.second.toUtf8().constData(),
|
||||
Qt::DirectConnection, QGenericReturnArgument(),
|
||||
Q_ARG(long, number));
|
||||
}
|
||||
|
||||
} else if (args.Length() == 2) {
|
||||
v8::Local<v8::Value> arg0 = args[0];
|
||||
std::string argString0 = JS2String(arg0);
|
||||
|
||||
v8::Local<v8::Value> arg1 = args[1];
|
||||
std::string argString1 = JS2String(arg1);
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
pair.first, pair.second.toUtf8().constData(), Qt::DirectConnection,
|
||||
QGenericReturnArgument(),
|
||||
Q_ARG(QString, QString::fromUtf8(argString0.c_str())),
|
||||
Q_ARG(QString, QString::fromUtf8(argString1.c_str())));
|
||||
} else if (args.Length() == 3) {
|
||||
v8::Local<v8::Value> arg0 = args[0];
|
||||
long argLong = JS2Number(arg0);
|
||||
|
||||
v8::Local<v8::Value> arg1 = args[1];
|
||||
int argInt = JS2Number(arg1);
|
||||
|
||||
v8::Local<v8::Value> arg2 = args[2];
|
||||
bool argBool = JS2Bool(arg2);
|
||||
|
||||
QMetaObject::invokeMethod(pair.first, pair.second.toUtf8().constData(),
|
||||
Qt::DirectConnection, QGenericReturnArgument(),
|
||||
Q_ARG(long, argLong), Q_ARG(int, argInt),
|
||||
Q_ARG(bool, argBool));
|
||||
} else if (args.Length() == 5) {
|
||||
v8::Local<v8::Value> arg0 = args[0];
|
||||
std::string argString0 = JS2String(arg0);
|
||||
|
||||
v8::Local<v8::Value> arg1 = args[1];
|
||||
std::string argString1 = JS2String(arg1);
|
||||
|
||||
v8::Local<v8::Value> arg2 = args[2];
|
||||
std::string argString2 = JS2String(arg2);
|
||||
|
||||
v8::Local<v8::Value> arg3 = args[3];
|
||||
std::string argString3 = JS2String(arg3);
|
||||
|
||||
v8::Local<v8::Value> arg4 = args[4];
|
||||
std::string argString4 = JS2String(arg4);
|
||||
|
||||
QMetaObject::invokeMethod(
|
||||
pair.first, pair.second.toUtf8().constData(), Qt::DirectConnection,
|
||||
QGenericReturnArgument(),
|
||||
Q_ARG(QString, QString::fromUtf8(argString0.c_str())),
|
||||
Q_ARG(QString, QString::fromUtf8(argString1.c_str())),
|
||||
Q_ARG(QString, QString::fromUtf8(argString2.c_str())),
|
||||
Q_ARG(QString, QString::fromUtf8(argString3.c_str())),
|
||||
Q_ARG(QString, QString::fromUtf8(argString4.c_str())));
|
||||
}
|
||||
|
||||
// begin check to perform micro task checkpoint
|
||||
|
||||
std::string objectNameString = "global";
|
||||
std::string functionKeyString = "nativeEmpty";
|
||||
|
||||
int objectCompareResult = strncmp(objectKey.c_str(), objectNameString.c_str(),
|
||||
strlen(objectKey.c_str()));
|
||||
|
||||
if (objectCompareResult == 0) {
|
||||
int functionCompareResult =
|
||||
strncmp(functionKey.c_str(), functionKeyString.c_str(),
|
||||
strlen(functionKey.c_str()));
|
||||
if (functionCompareResult == 0) {
|
||||
isolate->PerformMicrotaskCheckpoint();
|
||||
}
|
||||
}
|
||||
// end check
|
||||
}
|
||||
|
||||
void V8Executor::injectFunctions(const char *objectName,
|
||||
const char *functionName, bool hashKey) {
|
||||
v8::Isolate *isolate = m_isolate;
|
||||
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Context> context = isolate->GetEnteredOrMicrotaskContext();
|
||||
v8::Local<v8::Object> object = context->Global();
|
||||
if (objectName) {
|
||||
object = object->Get(context, NewV8String(objectName))
|
||||
.ToLocalChecked()
|
||||
->ToObject(context)
|
||||
.ToLocalChecked();
|
||||
}
|
||||
|
||||
v8::Local<v8::String> name = NewV8String(functionName);
|
||||
v8::Local<v8::Object> data = v8::Object::New(isolate);
|
||||
if (objectName) {
|
||||
v8::Maybe<bool> result =
|
||||
data->Set(context, NewV8String("obj"), NewV8String(objectName));
|
||||
result.ToChecked();
|
||||
} else {
|
||||
v8::Maybe<bool> result =
|
||||
data->Set(context, NewV8String("obj"), NewV8String("global"));
|
||||
result.ToChecked();
|
||||
}
|
||||
{
|
||||
v8::Maybe<bool> result =
|
||||
data->Set(context, NewV8String("func"), NewV8String(functionName));
|
||||
result.ToChecked();
|
||||
}
|
||||
{
|
||||
v8::Maybe<bool> result = data->Set(context, NewV8String("hashKey"),
|
||||
v8::Boolean::New(isolate, hashKey));
|
||||
result.ToChecked();
|
||||
}
|
||||
|
||||
v8::Local<v8::Function> function =
|
||||
v8::Function::New(context, InjectedFunction, data).ToLocalChecked();
|
||||
v8::Maybe<bool> result = object->Set(context, name, function);
|
||||
result.ToChecked();
|
||||
}
|
||||
|
||||
v8::Local<v8::Value> V8Executor::invokeMethod(const char *objectName,
|
||||
const char *functionName,
|
||||
int argc,
|
||||
v8::Local<v8::Value> argv[],
|
||||
std::string *exception_str) {
|
||||
v8::Isolate *isolate = m_isolate;
|
||||
v8::EscapableHandleScope handle_scope(isolate);
|
||||
v8::Local<v8::Context> context = isolate->GetEnteredOrMicrotaskContext();
|
||||
v8::Local<v8::Object> object = context->Global();
|
||||
v8::Local<v8::Value> result = Undefined(isolate);
|
||||
|
||||
if (objectName) {
|
||||
object = object->Get(context, NewV8String(objectName))
|
||||
.ToLocalChecked()
|
||||
->ToObject(context)
|
||||
.ToLocalChecked();
|
||||
}
|
||||
if (object.IsEmpty()) {
|
||||
*exception_str = std::string("Cannot find Object:") +
|
||||
std::string(objectName ? objectName : "global");
|
||||
return handle_scope.Escape(result);
|
||||
}
|
||||
v8::Local<v8::Value> target_value =
|
||||
object->Get(context, NewV8String(functionName)).ToLocalChecked();
|
||||
if (!target_value->IsFunction()) {
|
||||
*exception_str =
|
||||
std::string("In ") + std::string(objectName ? objectName : "global") +
|
||||
std::string("cannot find target function ") + std::string(functionName);
|
||||
return handle_scope.Escape(result);
|
||||
}
|
||||
v8::TryCatch try_catch(isolate);
|
||||
try_catch.SetVerbose(true);
|
||||
v8::Local<v8::Function> target_function =
|
||||
v8::Local<v8::Function>::Cast(target_value);
|
||||
result = target_function->Call(context, object, argc, argv).ToLocalChecked();
|
||||
v8::Local<v8::Value> exception = try_catch.Exception();
|
||||
if (!exception.IsEmpty()) {
|
||||
if (exception->IsObject()) {
|
||||
v8::Local<v8::Object> exc = v8::Local<v8::Object>::Cast(exception);
|
||||
v8::Local<v8::Value> stack =
|
||||
exc->Get(context, NewV8String("stack")).FromMaybe(exception);
|
||||
*exception_str = JS2String(stack);
|
||||
} else {
|
||||
*exception_str = JS2String(exception);
|
||||
}
|
||||
}
|
||||
return handle_scope.Escape(result);
|
||||
}
|
52
doric-Qt/example/doric/engine/v8/V8Executor.h
Normal file
52
doric-Qt/example/doric/engine/v8/V8Executor.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#ifndef V8EXECUTOR_H
|
||||
#define V8EXECUTOR_H
|
||||
|
||||
#include "libplatform/libplatform.h"
|
||||
#include "v8.h"
|
||||
|
||||
#include <QMap>
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
|
||||
static QMap<QString, QPair<QObject *, QString>> *map =
|
||||
new QMap<QString, QPair<QObject *, QString>>();
|
||||
|
||||
class V8Executor {
|
||||
|
||||
private:
|
||||
std::unique_ptr<v8::Platform> platform;
|
||||
v8::Isolate::CreateParams create_params;
|
||||
v8::Isolate *m_isolate;
|
||||
v8::Isolate::Scope *m_isolate_scope;
|
||||
v8::Global<v8::Context> *m_global_context;
|
||||
|
||||
void injectObject(const char *string, v8::Local<v8::Value> local);
|
||||
|
||||
v8::Local<v8::Value> innerExec(const char *script, const char *source,
|
||||
std::string *exception_str);
|
||||
|
||||
void injectFunctions(const char *objectName, const char *functionName,
|
||||
bool hashKey);
|
||||
|
||||
v8::Local<v8::Value> invokeMethod(const char *objectName,
|
||||
const char *functionName, int argc,
|
||||
v8::Local<v8::Value> argv[],
|
||||
std::string *exception_str);
|
||||
|
||||
public:
|
||||
V8Executor();
|
||||
|
||||
~V8Executor();
|
||||
|
||||
QString loadJS(QString script, QString source);
|
||||
|
||||
void injectGlobalJSObject(QString name, std::string target);
|
||||
|
||||
void injectGlobalJSFunction(QString name, QObject *function,
|
||||
QString property);
|
||||
|
||||
void invokeObject(QString objectName, QString functionName,
|
||||
QVariantList arguments);
|
||||
};
|
||||
|
||||
#endif // V8EXECUTOR_H
|
260
doric-Qt/example/doric/plugin/DoricModalPlugin.cpp
Normal file
260
doric-Qt/example/doric/plugin/DoricModalPlugin.cpp
Normal file
@@ -0,0 +1,260 @@
|
||||
#include "DoricModalPlugin.h"
|
||||
#include "engine/DoricPromise.h"
|
||||
#include "shader/DoricRootNode.h"
|
||||
#include "utils/DoricLayouts.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QObject>
|
||||
#include <QQmlComponent>
|
||||
#include <QQuickWindow>
|
||||
#include <QTimer>
|
||||
|
||||
void DoricModalPlugin::toast(QString jsValueString, QString callbackId) {
|
||||
getContext()->getDriver()->asyncCall(
|
||||
[this, jsValueString] {
|
||||
QJsonDocument document =
|
||||
QJsonDocument::fromJson(jsValueString.toUtf8());
|
||||
QJsonValue jsValue = document.object();
|
||||
|
||||
QString msg = jsValue["msg"].toString();
|
||||
int gravity = jsValue["gravity"].toInt();
|
||||
|
||||
QQmlComponent component(getContext()->getQmlEngine());
|
||||
const QUrl url(QStringLiteral("qrc:/doric/qml/toast.qml"));
|
||||
component.loadUrl(url);
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errorString();
|
||||
}
|
||||
QQuickWindow *window = qobject_cast<QQuickWindow *>(component.create());
|
||||
|
||||
QQuickWindow *parentWindow =
|
||||
getContext()->getRootNode()->getRootView()->window();
|
||||
|
||||
window->contentItem()
|
||||
->childItems()
|
||||
.at(0)
|
||||
->childItems()
|
||||
.at(0)
|
||||
->childItems()
|
||||
.at(0)
|
||||
->setProperty("text", msg);
|
||||
|
||||
std::function<void()> setX = [window, parentWindow]() {
|
||||
window->setProperty("x",
|
||||
(parentWindow->width() - window->width()) / 2.f +
|
||||
parentWindow->x());
|
||||
};
|
||||
std::function<void()> setY = [window, parentWindow, gravity]() {
|
||||
if ((gravity & DoricGravity::DoricGravityBottom) ==
|
||||
DoricGravity::DoricGravityBottom) {
|
||||
window->setProperty("y", parentWindow->height() - window->height() -
|
||||
20 + parentWindow->y());
|
||||
} else if ((gravity & DoricGravity::DoricGravityTop) ==
|
||||
DoricGravity::DoricGravityTop) {
|
||||
window->setProperty("y", 20 + parentWindow->y());
|
||||
} else {
|
||||
window->setProperty(
|
||||
"y", (parentWindow->height() - window->height()) / 2 +
|
||||
parentWindow->y());
|
||||
}
|
||||
};
|
||||
// init set x
|
||||
setX();
|
||||
// init set y
|
||||
setY();
|
||||
|
||||
// update x
|
||||
connect(window, &QQuickWindow::widthChanged, setX);
|
||||
|
||||
// update y
|
||||
connect(window, &QQuickWindow::heightChanged, setY);
|
||||
|
||||
QTimer::singleShot(2000, qApp, [window]() { window->deleteLater(); });
|
||||
},
|
||||
DoricThreadMode::UI);
|
||||
}
|
||||
|
||||
void DoricModalPlugin::alert(QString jsValueString, QString callbackId) {
|
||||
getContext()->getDriver()->asyncCall(
|
||||
[this, jsValueString, callbackId] {
|
||||
QJsonDocument document =
|
||||
QJsonDocument::fromJson(jsValueString.toUtf8());
|
||||
QJsonValue jsValue = document.object();
|
||||
|
||||
QJsonValue titleVal = jsValue["title"];
|
||||
QJsonValue msgVal = jsValue["msg"];
|
||||
QJsonValue okBtn = jsValue["okLabel"];
|
||||
|
||||
QQmlComponent component(getContext()->getQmlEngine());
|
||||
const QUrl url(QStringLiteral("qrc:/doric/qml/alert.qml"));
|
||||
component.loadUrl(url);
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errorString();
|
||||
}
|
||||
QQuickWindow *window = qobject_cast<QQuickWindow *>(component.create());
|
||||
window->setProperty("pointer", QString::number((qint64)window));
|
||||
window->setProperty("plugin", QString::number((qint64)this));
|
||||
window->setProperty("callbackId", callbackId);
|
||||
|
||||
window->setProperty("title", titleVal.toString());
|
||||
window->setProperty("msg", msgVal.toString());
|
||||
window->setProperty("okLabel", okBtn.toString());
|
||||
|
||||
QQuickWindow *parentWindow =
|
||||
getContext()->getRootNode()->getRootView()->window();
|
||||
|
||||
std::function<void()> setX = [window, parentWindow]() {
|
||||
window->setProperty("x",
|
||||
(parentWindow->width() - window->width()) / 2.f +
|
||||
parentWindow->x());
|
||||
};
|
||||
std::function<void()> setY = [window, parentWindow]() {
|
||||
window->setProperty("y",
|
||||
(parentWindow->height() - window->height()) / 2 +
|
||||
parentWindow->y());
|
||||
};
|
||||
// init set x
|
||||
setX();
|
||||
// init set y
|
||||
setY();
|
||||
|
||||
// update x
|
||||
connect(window, &QQuickWindow::widthChanged, setX);
|
||||
|
||||
// update y
|
||||
connect(window, &QQuickWindow::heightChanged, setY);
|
||||
},
|
||||
DoricThreadMode::UI);
|
||||
}
|
||||
|
||||
void DoricModalPlugin::confirm(QString jsValueString, QString callbackId) {
|
||||
getContext()->getDriver()->asyncCall(
|
||||
[this, jsValueString, callbackId] {
|
||||
QJsonDocument document =
|
||||
QJsonDocument::fromJson(jsValueString.toUtf8());
|
||||
QJsonValue jsValue = document.object();
|
||||
|
||||
QJsonValue titleVal = jsValue["title"];
|
||||
QJsonValue msgVal = jsValue["msg"];
|
||||
QJsonValue okBtn = jsValue["okLabel"];
|
||||
QJsonValue cancelBtn = jsValue["cancelLabel"];
|
||||
|
||||
QQmlComponent component(getContext()->getQmlEngine());
|
||||
const QUrl url(QStringLiteral("qrc:/doric/qml/confirm.qml"));
|
||||
component.loadUrl(url);
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errorString();
|
||||
}
|
||||
QQuickWindow *window = qobject_cast<QQuickWindow *>(component.create());
|
||||
window->setProperty("pointer", QString::number((qint64)window));
|
||||
window->setProperty("plugin", QString::number((qint64)this));
|
||||
window->setProperty("callbackId", callbackId);
|
||||
|
||||
window->setProperty("title", titleVal.toString());
|
||||
window->setProperty("msg", msgVal.toString());
|
||||
window->setProperty("okLabel", okBtn.toString());
|
||||
window->setProperty("cancelLabel", cancelBtn.toString());
|
||||
|
||||
QQuickWindow *parentWindow =
|
||||
getContext()->getRootNode()->getRootView()->window();
|
||||
|
||||
std::function<void()> setX = [window, parentWindow]() {
|
||||
window->setProperty("x",
|
||||
(parentWindow->width() - window->width()) / 2.f +
|
||||
parentWindow->x());
|
||||
};
|
||||
std::function<void()> setY = [window, parentWindow]() {
|
||||
window->setProperty("y",
|
||||
(parentWindow->height() - window->height()) / 2 +
|
||||
parentWindow->y());
|
||||
};
|
||||
// init set x
|
||||
setX();
|
||||
// init set y
|
||||
setY();
|
||||
|
||||
// update x
|
||||
connect(window, &QQuickWindow::widthChanged, setX);
|
||||
|
||||
// update y
|
||||
connect(window, &QQuickWindow::heightChanged, setY);
|
||||
},
|
||||
DoricThreadMode::UI);
|
||||
}
|
||||
|
||||
void DoricModalPlugin::prompt(QString jsValueString, QString callbackId) {
|
||||
getContext()->getDriver()->asyncCall(
|
||||
[this, jsValueString, callbackId] {
|
||||
QJsonDocument document =
|
||||
QJsonDocument::fromJson(jsValueString.toUtf8());
|
||||
QJsonValue jsValue = document.object();
|
||||
|
||||
QJsonValue titleVal = jsValue["title"];
|
||||
QJsonValue msgVal = jsValue["msg"];
|
||||
QJsonValue okBtn = jsValue["okLabel"];
|
||||
QJsonValue cancelBtn = jsValue["cancelLabel"];
|
||||
|
||||
QQmlComponent component(getContext()->getQmlEngine());
|
||||
const QUrl url(QStringLiteral("qrc:/doric/qml/prompt.qml"));
|
||||
component.loadUrl(url);
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errorString();
|
||||
}
|
||||
QQuickWindow *window = qobject_cast<QQuickWindow *>(component.create());
|
||||
window->setProperty("pointer", QString::number((qint64)window));
|
||||
window->setProperty("plugin", QString::number((qint64)this));
|
||||
window->setProperty("callbackId", callbackId);
|
||||
|
||||
window->setProperty("title", titleVal.toString());
|
||||
window->setProperty("msg", msgVal.toString());
|
||||
window->setProperty("okLabel", okBtn.toString());
|
||||
window->setProperty("cancelLabel", cancelBtn.toString());
|
||||
|
||||
QQuickWindow *parentWindow =
|
||||
getContext()->getRootNode()->getRootView()->window();
|
||||
|
||||
std::function<void()> setX = [window, parentWindow]() {
|
||||
window->setProperty("x",
|
||||
(parentWindow->width() - window->width()) / 2.f +
|
||||
parentWindow->x());
|
||||
};
|
||||
std::function<void()> setY = [window, parentWindow]() {
|
||||
window->setProperty("y",
|
||||
(parentWindow->height() - window->height()) / 2 +
|
||||
parentWindow->y());
|
||||
};
|
||||
// init set x
|
||||
setX();
|
||||
// init set y
|
||||
setY();
|
||||
|
||||
// update x
|
||||
connect(window, &QQuickWindow::widthChanged, setX);
|
||||
|
||||
// update y
|
||||
connect(window, &QQuickWindow::heightChanged, setY);
|
||||
},
|
||||
DoricThreadMode::UI);
|
||||
}
|
||||
|
||||
void DoricModalPlugin::onAccepted(QString callbackId) {
|
||||
QVariantList args;
|
||||
DoricPromise::resolve(getContext(), callbackId, args);
|
||||
}
|
||||
|
||||
void DoricModalPlugin::onAcceptedWithInput(QString callbackId, QString input) {
|
||||
QVariantList args;
|
||||
args.append(input);
|
||||
DoricPromise::resolve(getContext(), callbackId, args);
|
||||
}
|
||||
|
||||
void DoricModalPlugin::onRejected(QString callbackId) {
|
||||
QVariantList args;
|
||||
DoricPromise::reject(getContext(), callbackId, args);
|
||||
}
|
||||
|
||||
void DoricModalPlugin::onRejectedWithInput(QString callbackId, QString input) {
|
||||
QVariantList args;
|
||||
args.append(input);
|
||||
DoricPromise::reject(getContext(), callbackId, args);
|
||||
}
|
28
doric-Qt/example/doric/plugin/DoricModalPlugin.h
Normal file
28
doric-Qt/example/doric/plugin/DoricModalPlugin.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef DORICMODALPLUGIN_H
|
||||
#define DORICMODALPLUGIN_H
|
||||
|
||||
#include "DoricNativePlugin.h"
|
||||
|
||||
class DoricModalPlugin : public DoricNativePlugin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using DoricNativePlugin::DoricNativePlugin;
|
||||
|
||||
Q_INVOKABLE void toast(QString jsValueString, QString callbackId);
|
||||
|
||||
Q_INVOKABLE void alert(QString jsValueString, QString callbackId);
|
||||
|
||||
Q_INVOKABLE void confirm(QString jsValueString, QString callbackId);
|
||||
|
||||
Q_INVOKABLE void prompt(QString jsValueString, QString callbackId);
|
||||
|
||||
void onAccepted(QString callbackId);
|
||||
|
||||
void onAcceptedWithInput(QString callbackId, QString input);
|
||||
|
||||
void onRejected(QString callbackId);
|
||||
|
||||
void onRejectedWithInput(QString callbackId, QString input);
|
||||
};
|
||||
|
||||
#endif // DORICMODALPLUGIN_H
|
11
doric-Qt/example/doric/plugin/DoricNativePlugin.h
Normal file
11
doric-Qt/example/doric/plugin/DoricNativePlugin.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef DORICNATIVEPLUGIN_H
|
||||
#define DORICNATIVEPLUGIN_H
|
||||
|
||||
#include "../utils/DoricContextHolder.h"
|
||||
|
||||
class DoricNativePlugin : public DoricContextHolder {
|
||||
public:
|
||||
using DoricContextHolder::DoricContextHolder;
|
||||
};
|
||||
|
||||
#endif // DORICNATIVEPLUGIN_H
|
29
doric-Qt/example/doric/plugin/DoricNetworkPlugin.cpp
Normal file
29
doric-Qt/example/doric/plugin/DoricNetworkPlugin.cpp
Normal file
@@ -0,0 +1,29 @@
|
||||
#include "DoricNetworkPlugin.h"
|
||||
#include "engine/DoricPromise.h"
|
||||
#include "utils/DoricNetworkService.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
void DoricNetworkPlugin::request(QString jsValueString, QString callbackId) {
|
||||
QJsonDocument document = QJsonDocument::fromJson(jsValueString.toUtf8());
|
||||
QJsonValue jsValue = document.object();
|
||||
|
||||
DoricNetworkService::getInstance()->request(
|
||||
jsValue, qApp,
|
||||
[this, callbackId](int code, QList<QByteArray> headers, QByteArray data) {
|
||||
getContext()->getDriver()->asyncCall(
|
||||
[this, callbackId, code, headers, data] {
|
||||
QMap<QString, QVariant> map;
|
||||
map.insert("status", code);
|
||||
map.insert("headers", QVariant::fromValue(headers));
|
||||
map.insert("data", QString(data));
|
||||
|
||||
QVariantList args;
|
||||
args.append(map);
|
||||
DoricPromise::resolve(getContext(), callbackId, args);
|
||||
},
|
||||
DoricThreadMode::JS);
|
||||
});
|
||||
}
|
13
doric-Qt/example/doric/plugin/DoricNetworkPlugin.h
Normal file
13
doric-Qt/example/doric/plugin/DoricNetworkPlugin.h
Normal file
@@ -0,0 +1,13 @@
|
||||
#ifndef DORICNETWORKPLUGIN_H
|
||||
#define DORICNETWORKPLUGIN_H
|
||||
|
||||
#include "DoricNativePlugin.h"
|
||||
|
||||
class DoricNetworkPlugin : public DoricNativePlugin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using DoricNativePlugin::DoricNativePlugin;
|
||||
|
||||
Q_INVOKABLE void request(QString jsValueString, QString callbackId);
|
||||
};
|
||||
#endif // DORICNETWORKPLUGIN_H
|
120
doric-Qt/example/doric/plugin/DoricPopoverPlugin.cpp
Normal file
120
doric-Qt/example/doric/plugin/DoricPopoverPlugin.cpp
Normal file
@@ -0,0 +1,120 @@
|
||||
#include "DoricPopoverPlugin.h"
|
||||
#include "engine/DoricPromise.h"
|
||||
#include "shader/DoricRootNode.h"
|
||||
#include "shader/DoricViewNode.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QQuickWindow>
|
||||
|
||||
void DoricPopoverPlugin::show(QString jsValueString, QString callbackId) {
|
||||
getContext()->getDriver()->asyncCall(
|
||||
[this, jsValueString, callbackId] {
|
||||
QJsonDocument document =
|
||||
QJsonDocument::fromJson(jsValueString.toUtf8());
|
||||
QJsonValue jsValue = document.object();
|
||||
|
||||
QQuickItem *rootItem =
|
||||
getContext()->getRootNode()->getRootView()->window()->contentItem();
|
||||
|
||||
if (this->fullScreenView == nullptr) {
|
||||
QQmlComponent component(getContext()->getQmlEngine());
|
||||
|
||||
const QUrl url(QStringLiteral("qrc:/doric/qml/stack.qml"));
|
||||
component.loadUrl(url);
|
||||
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errorString();
|
||||
}
|
||||
|
||||
QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
|
||||
item->setWidth(rootItem->width());
|
||||
item->setHeight(rootItem->height());
|
||||
|
||||
DoricLayouts *layout = new DoricLayouts();
|
||||
layout->setWidth(item->width());
|
||||
layout->setHeight(item->height());
|
||||
layout->setView(item);
|
||||
layout->setLayoutType(DoricLayoutType::DoricStack);
|
||||
|
||||
item->setProperty("doricLayout", QString::number((qint64)layout));
|
||||
|
||||
item->setParentItem(rootItem);
|
||||
|
||||
this->fullScreenView = item;
|
||||
} else {
|
||||
DoricLayouts *layout =
|
||||
(DoricLayouts *)(this->fullScreenView->property("doricLayout")
|
||||
.toULongLong());
|
||||
layout->setWidth(rootItem->width());
|
||||
layout->setHeight(rootItem->height());
|
||||
}
|
||||
this->fullScreenView->setVisible(true);
|
||||
|
||||
QString viewId = jsValue["id"].toString();
|
||||
QString type = jsValue["type"].toString();
|
||||
|
||||
DoricViewNode *viewNode = getContext()->targetViewNode(viewId);
|
||||
if (viewNode == nullptr) {
|
||||
viewNode = DoricViewNode::create(getContext(), type);
|
||||
viewNode->setId(viewId);
|
||||
viewNode->init(nullptr);
|
||||
|
||||
viewNode->getNodeView()->setParentItem(this->fullScreenView);
|
||||
}
|
||||
|
||||
viewNode->blend(jsValue["props"]);
|
||||
|
||||
DoricLayouts *layout =
|
||||
(DoricLayouts *)(this->fullScreenView->property("doricLayout")
|
||||
.toULongLong());
|
||||
layout->apply();
|
||||
|
||||
getContext()->addHeadNode(TYPE, viewNode);
|
||||
|
||||
QVariantList args;
|
||||
DoricPromise::resolve(getContext(), callbackId, args);
|
||||
},
|
||||
DoricThreadMode::UI);
|
||||
}
|
||||
|
||||
void DoricPopoverPlugin::dismiss(QString jsValueString, QString callbackId) {
|
||||
getContext()->getDriver()->asyncCall(
|
||||
[this, jsValueString, callbackId] {
|
||||
QJsonDocument document =
|
||||
QJsonDocument::fromJson(jsValueString.toUtf8());
|
||||
QJsonValue jsValue = document.object();
|
||||
|
||||
if (jsValue.toObject().contains("id")) {
|
||||
QString viewId = jsValue["id"].toString();
|
||||
|
||||
DoricViewNode *viewNode = getContext()->targetViewNode(viewId);
|
||||
this->dismissViewNode(viewNode);
|
||||
} else {
|
||||
this->dismissPopover();
|
||||
}
|
||||
|
||||
QVariantList args;
|
||||
DoricPromise::resolve(getContext(), callbackId, args);
|
||||
},
|
||||
DoricThreadMode::UI);
|
||||
}
|
||||
|
||||
void DoricPopoverPlugin::dismissViewNode(DoricViewNode *viewNode) {
|
||||
if (viewNode != nullptr) {
|
||||
getContext()->removeHeadNode(TYPE, viewNode);
|
||||
viewNode->getNodeView()->setParent(nullptr);
|
||||
viewNode->getNodeView()->setParentItem(nullptr);
|
||||
viewNode->getNodeView()->deleteLater();
|
||||
}
|
||||
|
||||
if (getContext()->allHeadNodes(TYPE).size() == 0) {
|
||||
this->fullScreenView->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricPopoverPlugin::dismissPopover() {
|
||||
foreach (DoricViewNode *node, getContext()->allHeadNodes(TYPE)) {
|
||||
dismissViewNode(node);
|
||||
}
|
||||
}
|
27
doric-Qt/example/doric/plugin/DoricPopoverPlugin.h
Normal file
27
doric-Qt/example/doric/plugin/DoricPopoverPlugin.h
Normal file
@@ -0,0 +1,27 @@
|
||||
#ifndef DORICPOPOVERPLUGIN_H
|
||||
#define DORICPOPOVERPLUGIN_H
|
||||
|
||||
#include "DoricNativePlugin.h"
|
||||
|
||||
#include <QQuickItem>
|
||||
|
||||
static QString TYPE = "popover";
|
||||
|
||||
class DoricPopoverPlugin : public DoricNativePlugin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using DoricNativePlugin::DoricNativePlugin;
|
||||
|
||||
Q_INVOKABLE void show(QString jsValueString, QString callbackId);
|
||||
|
||||
Q_INVOKABLE void dismiss(QString jsValueString, QString callbackId);
|
||||
|
||||
private:
|
||||
QQuickItem *fullScreenView = nullptr;
|
||||
|
||||
void dismissViewNode(DoricViewNode *node);
|
||||
|
||||
void dismissPopover();
|
||||
};
|
||||
|
||||
#endif // DORICPOPOVERPLUGIN_H
|
36
doric-Qt/example/doric/plugin/DoricShaderPlugin.cpp
Normal file
36
doric-Qt/example/doric/plugin/DoricShaderPlugin.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
#include "../shader/DoricRootNode.h"
|
||||
#include "DoricShaderPlugin.h"
|
||||
|
||||
void DoricShaderPlugin::render(QString jsValueString, QString callbackId) {
|
||||
getContext()->getDriver()->asyncCall(
|
||||
[this, jsValueString] {
|
||||
try {
|
||||
QJsonDocument document =
|
||||
QJsonDocument::fromJson(jsValueString.toUtf8());
|
||||
QJsonValue jsValue = document.object();
|
||||
|
||||
QString viewId = jsValue["id"].toString();
|
||||
DoricRootNode *rootNode = getContext()->getRootNode();
|
||||
|
||||
if (rootNode->getId().isEmpty() &&
|
||||
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 (...) {
|
||||
qCritical() << "render exception";
|
||||
}
|
||||
},
|
||||
DoricThreadMode::UI);
|
||||
}
|
14
doric-Qt/example/doric/plugin/DoricShaderPlugin.h
Normal file
14
doric-Qt/example/doric/plugin/DoricShaderPlugin.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef SHADERPLUGIN_H
|
||||
#define SHADERPLUGIN_H
|
||||
|
||||
#include "DoricNativePlugin.h"
|
||||
|
||||
class DoricShaderPlugin : public DoricNativePlugin {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using DoricNativePlugin::DoricNativePlugin;
|
||||
|
||||
Q_INVOKABLE void render(QString jsValueString, QString callbackId);
|
||||
};
|
||||
|
||||
#endif // SHADERPLUGIN_H
|
3
doric-Qt/example/doric/qml.qrc
Normal file
3
doric-Qt/example/doric/qml.qrc
Normal file
@@ -0,0 +1,3 @@
|
||||
<RCC>
|
||||
|
||||
</RCC>
|
312
doric-Qt/example/doric/resources/Flex.qml
Normal file
312
doric-Qt/example/doric/resources/Flex.qml
Normal file
@@ -0,0 +1,312 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Layouts 1.15
|
||||
import pub.doric.widget 1.0
|
||||
|
||||
Rectangle {
|
||||
id: flex
|
||||
|
||||
property int minHeight: 0
|
||||
property int minWidth: 0
|
||||
|
||||
property int flexShrink: 0
|
||||
property int flexGrow: 0
|
||||
|
||||
property int marginTop: 0
|
||||
property int marginLeft: 0
|
||||
property int marginRight: 0
|
||||
property int marginBottom: 0
|
||||
|
||||
property int paddingTop: 0
|
||||
property int paddingLeft: 0
|
||||
property int paddingRight: 0
|
||||
property int paddingBottom: 0
|
||||
|
||||
property string alignContent: "auto"
|
||||
property string alignItems: "auto"
|
||||
property string alignSelf: "auto"
|
||||
|
||||
property string justifyContent: "flexStart"
|
||||
|
||||
property string display: "flex"
|
||||
|
||||
property string flexWrap: "noWrap"
|
||||
|
||||
property string flexDirection: "row"
|
||||
|
||||
FlexLayoutService {
|
||||
id: flexLayoutService
|
||||
}
|
||||
|
||||
function isFlex(child) {
|
||||
if (typeof child.flexShrink === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.flexGrow === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.minHeight === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.minWidth === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.marginTop === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.marginLeft === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.marginRight === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.marginBottom === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.paddingTop === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.paddingLeft === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.paddingRight === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.paddingBottom === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.alignContent === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.alignItems === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.alignSelf === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.justifyContent === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.display === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.flexWrap === 'undefined') {
|
||||
return false;
|
||||
} else if (typeof child.flexDirection === 'undefined') {
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
function setAlignContent(child, node) {
|
||||
var align = child.alignContent;
|
||||
if (align === "auto") {
|
||||
node.setAlignContentAuto();
|
||||
} else if (align === "flexStart") {
|
||||
node.setAlignContentFlexStart();
|
||||
} else if (align === "center") {
|
||||
node.setAlignContentCenter();
|
||||
} else if (align === "flexEnd") {
|
||||
node.setAlignContentFlexEnd();
|
||||
} else if (align === "stretch") {
|
||||
node.setAlignContentStretch();
|
||||
} else if (align === "baseline") {
|
||||
node.setAlignContentBaseline();
|
||||
} else if (align === "spaceBetween") {
|
||||
node.setAlignContentSpaceBetween();
|
||||
} else if (align === "spaceAround") {
|
||||
node.setAlignContentSpaceAround();
|
||||
} else {
|
||||
throw "setAlignContent invalid param";
|
||||
}
|
||||
}
|
||||
|
||||
function setAlignItems(child, node) {
|
||||
var align = child.alignItems;
|
||||
if (align === "auto") {
|
||||
node.setAlignItemsAuto();
|
||||
} else if (align === "flexStart") {
|
||||
node.setAlignItemsFlexStart();
|
||||
} else if (align === "center") {
|
||||
node.setAlignItemsCenter();
|
||||
} else if (align === "flexEnd") {
|
||||
node.setAlignItemsFlexEnd();
|
||||
} else if (align === "stretch") {
|
||||
node.setAlignItemsStretch();
|
||||
} else if (align === "baseline") {
|
||||
node.setAlignItemsBaseline();
|
||||
} else if (align === "spaceBetween") {
|
||||
node.setAlignItemsSpaceBetween();
|
||||
} else if (align === "spaceAround") {
|
||||
node.setAlignItemsSpaceAround();
|
||||
} else {
|
||||
throw "setAlignItems invalid param";
|
||||
}
|
||||
}
|
||||
|
||||
function setAlignSelf(child, node) {
|
||||
var align = child.alignSelf;
|
||||
if (align === "auto") {
|
||||
node.setAlignSelfAuto();
|
||||
} else if (align === "flexStart") {
|
||||
node.setAlignSelfFlexStart();
|
||||
} else if (align === "center") {
|
||||
node.setAlignSelfCenter();
|
||||
} else if (align === "flexEnd") {
|
||||
node.setAlignSelfFlexEnd();
|
||||
} else if (align === "stretch") {
|
||||
node.setAlignSelfStretch();
|
||||
} else if (align === "baseline") {
|
||||
node.setAlignSelfBaseline();
|
||||
} else if (align === "spaceBetween") {
|
||||
node.setAlignSelfSpaceBetween();
|
||||
} else if (align === "spaceAround") {
|
||||
node.setAlignSelfSpaceAround();
|
||||
} else {
|
||||
throw "setAlignSelf invalid param";
|
||||
}
|
||||
}
|
||||
|
||||
function setDisplay(child, node) {
|
||||
var display = child.display;
|
||||
if (display === "flex") {
|
||||
node.setDisplayFlex();
|
||||
} else if (display === "none") {
|
||||
node.setDisplayNone();
|
||||
} else {
|
||||
throw "setDisplay invalid param";
|
||||
}
|
||||
}
|
||||
|
||||
function setJustifyContent(child, node) {
|
||||
var justify = child.justifyContent;
|
||||
if (justify === "center") {
|
||||
node.setJustifyCenter();
|
||||
} else if (justify === "flexEnd") {
|
||||
node.setJustifyFlexEnd();
|
||||
} else if (justify === "flexStart") {
|
||||
node.setJustifyFlexStart();
|
||||
} else if (justify === "spaceAround") {
|
||||
node.setJustifySpaceAround();
|
||||
} else if (justify === "spaceEvenly") {
|
||||
node.setJustifySpaceEvenly();
|
||||
} else if (justify === "spaceBetween") {
|
||||
node.setJustifySpaceBetween();
|
||||
} else {
|
||||
throw "setJustifyContent invalid param";
|
||||
}
|
||||
}
|
||||
|
||||
function setFlexWrap(child, node) {
|
||||
var wrap = child.flexWrap;
|
||||
if (wrap === "wrap") {
|
||||
node.setWrap();
|
||||
} else if (wrap === "noWrap") {
|
||||
node.setNoWrap();
|
||||
} else if (wrap === "wrapReverse") {
|
||||
node.setWrapReverse();
|
||||
} else {
|
||||
throw "setFlexWrap invalid param";
|
||||
}
|
||||
}
|
||||
|
||||
function setFlexDirection(child, node) {
|
||||
var direction = child.flexDirection;
|
||||
if (direction === "row") {
|
||||
node.setFlexDirectionRow();
|
||||
} else if (direction === "column") {
|
||||
node.setFlexDirectionColumn();
|
||||
} else if (direction === "rowReverse") {
|
||||
node.setFlexDirectionRowReverse();
|
||||
} else if (direction === "columnReverse") {
|
||||
node.setFlexDirectionColumnReverse();
|
||||
} else {
|
||||
throw "setFlexDirection invalid param";
|
||||
}
|
||||
}
|
||||
|
||||
function setOtherNodeProps(child, node) {
|
||||
node.minHeight = child.minHeight;
|
||||
node.minWidth = child.minWidth;
|
||||
node.flexShrink = child.flexShrink;
|
||||
node.flexGrow = child.flexGrow;
|
||||
|
||||
node.marginTop = child.marginTop;
|
||||
node.marginLeft = child.marginLeft;
|
||||
node.marginRight = child.marginRight;
|
||||
node.marginBottom = child.marginBottom;
|
||||
|
||||
node.paddingTop = child.paddingTop;
|
||||
node.paddingLeft = child.paddingLeft;
|
||||
node.paddingRight = child.paddingRight;
|
||||
node.paddingBottom = child.paddingBottom;
|
||||
|
||||
node.height = child.height;
|
||||
node.width = child.width;
|
||||
}
|
||||
|
||||
function setDefaultNodeProps(child, node) {
|
||||
node.minHeight = 9999;
|
||||
node.minWidth = 0;
|
||||
node.flexShrink = 0;
|
||||
node.flexGrow = 0;
|
||||
|
||||
node.marginTop = 0;
|
||||
node.marginLeft = 0;
|
||||
node.marginRight = 0;
|
||||
node.marginBottom = 0;
|
||||
|
||||
node.paddingTop = 0;
|
||||
node.paddingLeft = 0;
|
||||
node.paddingRight = 0;
|
||||
node.paddingBottom = 0;
|
||||
|
||||
node.height = child.height;
|
||||
node.width = child.width;
|
||||
|
||||
node.setDisplayFlex();
|
||||
|
||||
node.setAlignSelfAuto();
|
||||
node.setAlignItemsAuto();
|
||||
node.setAlignContentAuto();
|
||||
|
||||
node.setJustifySpaceBetween();
|
||||
node.setNoWrap();
|
||||
|
||||
node.setFlexDirectionRow();
|
||||
}
|
||||
|
||||
function processNode(child, node) {
|
||||
setOtherNodeProps(child, node, true);
|
||||
setJustifyContent(child, node);
|
||||
setFlexDirection(child, node);
|
||||
setAlignContent(child, node);
|
||||
setAlignItems(child, node);
|
||||
setAlignSelf(child, node);
|
||||
setFlexWrap(child, node);
|
||||
setDisplay(child, node);
|
||||
}
|
||||
|
||||
function updatePositions() {
|
||||
if (flex.height !== 0 && flex.width !== 0) {
|
||||
var rootNode = flexLayoutService.createNode();
|
||||
processNode(flex, rootNode);
|
||||
var nodes = []
|
||||
var node = {}
|
||||
var child = {}
|
||||
var i = 0;
|
||||
for (i = 0; i !== flex.children.length; i++) {
|
||||
node = flexLayoutService.createNode();
|
||||
child = flex.children[i];
|
||||
if (isFlex(child)) {
|
||||
processNode(child, node);
|
||||
} else {
|
||||
setDefaultNodeProps(child, node);
|
||||
}
|
||||
nodes.push(node);
|
||||
}
|
||||
rootNode.appendChildren(nodes);
|
||||
rootNode.calculateLayoutLtr(flex.width, flex.height);
|
||||
/* console.log(JSON.stringify({root: rootNode})); */
|
||||
for (i = 0; i !== flex.children.length; i++) {
|
||||
node = nodes[i];
|
||||
flex.children[i].x = node.getLayoutLeft();
|
||||
flex.children[i].y = node.getLayoutTop();
|
||||
flex.children[i].width = node.getLayoutWidth();
|
||||
flex.children[i].height = node.getLayoutHeight();
|
||||
/* console.log(JSON.stringify(node)); */
|
||||
}
|
||||
flexLayoutService.collectGarbage(rootNode);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
onChildrenChanged: updatePositions();
|
||||
onWidthChanged: updatePositions();
|
||||
onHeightChanged: updatePositions();
|
||||
}
|
55
doric-Qt/example/doric/resources/alert.qml
Normal file
55
doric-Qt/example/doric/resources/alert.qml
Normal file
@@ -0,0 +1,55 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
ApplicationWindow {
|
||||
id: window
|
||||
|
||||
flags: flags | Qt.WindowStaysOnTopHint | Qt.Tool | Qt.FramelessWindowHint
|
||||
visible: true
|
||||
modality: Qt.ApplicationModal
|
||||
|
||||
property var pointer
|
||||
property var plugin
|
||||
property var callbackId
|
||||
|
||||
property var title
|
||||
property var msg
|
||||
property var okLabel
|
||||
|
||||
onTitleChanged: {
|
||||
dialog.title = title
|
||||
}
|
||||
|
||||
onMsgChanged: {
|
||||
content.text = msg
|
||||
}
|
||||
|
||||
onOkLabelChanged: {
|
||||
dialog.standardButton(Dialog.Ok).text = qsTrId(okLabel)
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: dialog
|
||||
standardButtons: Dialog.Ok
|
||||
modal: true
|
||||
contentItem: Text {
|
||||
id: content
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
dialogBridge.onAccepted(pointer, plugin, callbackId)
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
window.width = implicitWidth
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
window.height = implicitHeight
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
dialog.open()
|
||||
}
|
||||
}
|
64
doric-Qt/example/doric/resources/confirm.qml
Normal file
64
doric-Qt/example/doric/resources/confirm.qml
Normal file
@@ -0,0 +1,64 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
|
||||
ApplicationWindow {
|
||||
id: window
|
||||
|
||||
flags: flags | Qt.WindowStaysOnTopHint | Qt.Tool | Qt.FramelessWindowHint
|
||||
visible: true
|
||||
modality: Qt.ApplicationModal
|
||||
|
||||
property var pointer
|
||||
property var plugin
|
||||
property var callbackId
|
||||
|
||||
property var title
|
||||
property var msg
|
||||
property var okLabel
|
||||
property var cancelLabel
|
||||
|
||||
onTitleChanged: {
|
||||
dialog.title = title
|
||||
}
|
||||
|
||||
onMsgChanged: {
|
||||
content.text = msg
|
||||
}
|
||||
|
||||
onOkLabelChanged: {
|
||||
dialog.standardButton(Dialog.Ok).text = qsTrId(okLabel)
|
||||
}
|
||||
|
||||
onCancelLabelChanged: {
|
||||
dialog.standardButton(Dialog.Cancel).text = qsTrId(cancelLabel)
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: dialog
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
modal: true
|
||||
contentItem: Text {
|
||||
id: content
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
dialogBridge.onAccepted(pointer, plugin, callbackId)
|
||||
}
|
||||
|
||||
onRejected: {
|
||||
dialogBridge.onRejected(pointer, plugin, callbackId)
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
window.width = implicitWidth
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
window.height = implicitHeight
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
dialog.open()
|
||||
}
|
||||
}
|
32
doric-Qt/example/doric/resources/gravity.mjs
Normal file
32
doric-Qt/example/doric/resources/gravity.mjs
Normal file
@@ -0,0 +1,32 @@
|
||||
// gravity.mjs
|
||||
export function enumerate() {
|
||||
const SPECIFIED = 1;
|
||||
const START = 1 << 1;
|
||||
const END = 1 << 2;
|
||||
const SHIFT_X = 0;
|
||||
const SHIFT_Y = 4;
|
||||
const LEFT = (START | SPECIFIED) << SHIFT_X;
|
||||
const RIGHT = (END | SPECIFIED) << SHIFT_X;
|
||||
const TOP = (START | SPECIFIED) << SHIFT_Y;
|
||||
const BOTTOM = (END | SPECIFIED) << SHIFT_Y;
|
||||
const CENTER_X = SPECIFIED << SHIFT_X;
|
||||
const CENTER_Y = SPECIFIED << SHIFT_Y;
|
||||
const CENTER = CENTER_X | CENTER_Y;
|
||||
|
||||
var gravity = {
|
||||
SPECIFIED,
|
||||
START,
|
||||
END,
|
||||
SHIFT_X,
|
||||
SHIFT_Y,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
TOP,
|
||||
BOTTOM,
|
||||
CENTER_X,
|
||||
CENTER_Y,
|
||||
CENTER
|
||||
}
|
||||
|
||||
return gravity
|
||||
}
|
74
doric-Qt/example/doric/resources/hlayout.qml
Normal file
74
doric-Qt/example/doric/resources/hlayout.qml
Normal file
@@ -0,0 +1,74 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.5
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
import "util.mjs" as Util
|
||||
|
||||
Rectangle {
|
||||
property var wrapper
|
||||
|
||||
clip: true
|
||||
|
||||
property var uuid: Util.uuidv4()
|
||||
|
||||
property var tag: "HLayout"
|
||||
|
||||
onWidthChanged: {
|
||||
console.log(tag, uuid + " onWidthChanged: " + this.width)
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
console.log(tag, uuid + " onHeightChanged: " + this.height)
|
||||
}
|
||||
|
||||
color: 'transparent'
|
||||
|
||||
property var backgroundColor
|
||||
|
||||
onBackgroundColorChanged: {
|
||||
color = backgroundColor
|
||||
}
|
||||
|
||||
property var borderWidth: 0
|
||||
onBorderWidthChanged: {
|
||||
border.width = borderWidth
|
||||
}
|
||||
|
||||
property var borderColor: ""
|
||||
onBorderColorChanged: {
|
||||
border.color = borderColor
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
console.log(tag, uuid + " wrapper: " + wrapper)
|
||||
mouseAreaBridge.onClick(wrapper)
|
||||
}
|
||||
}
|
||||
|
||||
property var shadowColor
|
||||
property var shadowRadius
|
||||
property var shadowOffsetX
|
||||
property var shadowOffsetY
|
||||
property var shadowOpacity
|
||||
|
||||
onShadowOpacityChanged: {
|
||||
if (shadowOpacity > 0) {
|
||||
layer.enabled = true
|
||||
} else {
|
||||
layer.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
layer.enabled: false
|
||||
layer.effect: DropShadow {
|
||||
horizontalOffset: shadowOffsetX
|
||||
verticalOffset: shadowOffsetY
|
||||
radius: shadowRadius
|
||||
samples: 16
|
||||
color: shadowColor
|
||||
transparentBorder: true
|
||||
}
|
||||
}
|
103
doric-Qt/example/doric/resources/image.qml
Normal file
103
doric-Qt/example/doric/resources/image.qml
Normal file
@@ -0,0 +1,103 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.5
|
||||
|
||||
import "util.mjs" as Util
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
property var isBlur: false
|
||||
onIsBlurChanged: {
|
||||
console.log(tag, uuid + " onIsBlurChanged: " + this.isBlur)
|
||||
if (isBlur) {
|
||||
this.layer.enabled = true
|
||||
} else {
|
||||
this.layer.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
layer.enabled: false
|
||||
layer.effect: FastBlur {
|
||||
radius: 50
|
||||
transparentBorder: true
|
||||
}
|
||||
}
|
10
doric-Qt/example/doric/resources/panel.qml
Normal file
10
doric-Qt/example/doric/resources/panel.qml
Normal file
@@ -0,0 +1,10 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.5
|
||||
|
||||
Rectangle {
|
||||
property var backgroundColor
|
||||
|
||||
onBackgroundColorChanged: {
|
||||
color = backgroundColor
|
||||
}
|
||||
}
|
72
doric-Qt/example/doric/resources/prompt.qml
Normal file
72
doric-Qt/example/doric/resources/prompt.qml
Normal file
@@ -0,0 +1,72 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.12
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
ApplicationWindow {
|
||||
id: window
|
||||
|
||||
flags: flags | Qt.WindowStaysOnTopHint | Qt.Tool | Qt.FramelessWindowHint
|
||||
visible: true
|
||||
modality: Qt.ApplicationModal
|
||||
|
||||
property var pointer
|
||||
property var plugin
|
||||
property var callbackId
|
||||
|
||||
property var title
|
||||
property var msg
|
||||
property var okLabel
|
||||
property var cancelLabel
|
||||
|
||||
onTitleChanged: {
|
||||
dialog.title = title
|
||||
}
|
||||
|
||||
onMsgChanged: {
|
||||
content.text = msg
|
||||
}
|
||||
|
||||
onOkLabelChanged: {
|
||||
dialog.standardButton(Dialog.Ok).text = qsTrId(okLabel)
|
||||
}
|
||||
|
||||
onCancelLabelChanged: {
|
||||
dialog.standardButton(Dialog.Cancel).text = qsTrId(cancelLabel)
|
||||
}
|
||||
|
||||
Dialog {
|
||||
id: dialog
|
||||
standardButtons: Dialog.Ok | Dialog.Cancel
|
||||
modal: true
|
||||
contentItem: ColumnLayout {
|
||||
Text {
|
||||
id: content
|
||||
}
|
||||
|
||||
TextArea {
|
||||
id: input
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
}
|
||||
|
||||
onAccepted: {
|
||||
dialogBridge.onAcceptedWithInput(pointer, plugin, callbackId, input.text)
|
||||
}
|
||||
|
||||
onRejected: {
|
||||
dialogBridge.onRejectedWithInput(pointer, plugin, callbackId, input.text)
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
window.width = implicitWidth
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
window.height = implicitHeight
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
dialog.open()
|
||||
}
|
||||
}
|
73
doric-Qt/example/doric/resources/scroller.qml
Normal file
73
doric-Qt/example/doric/resources/scroller.qml
Normal file
@@ -0,0 +1,73 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.5
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import "util.mjs" as Util
|
||||
|
||||
ScrollView {
|
||||
property var wrapper
|
||||
|
||||
property var uuid: Util.uuidv4()
|
||||
|
||||
property var tag: "Scroller"
|
||||
|
||||
ScrollBar.horizontal.policy: ScrollBar.AlwaysOff
|
||||
ScrollBar.vertical.policy: ScrollBar.AlwaysOff
|
||||
|
||||
clip: true
|
||||
|
||||
background: Rectangle {
|
||||
id: bg
|
||||
color: 'transparent'
|
||||
}
|
||||
|
||||
property var backgroundColor
|
||||
|
||||
onBackgroundColorChanged: {
|
||||
bg.color = backgroundColor
|
||||
}
|
||||
|
||||
property var borderWidth: 0
|
||||
onBorderWidthChanged: {
|
||||
bg.border.width = borderWidth
|
||||
}
|
||||
|
||||
property var borderColor: ""
|
||||
onBorderColorChanged: {
|
||||
bg.border.color = borderColor
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
bg.implicitWidth = width
|
||||
console.log(tag, uuid + " onWidthChanged: " + this.width)
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
bg.implicitHeight = height
|
||||
console.log(tag, uuid + " onHeightChanged: " + this.height)
|
||||
}
|
||||
|
||||
onImplicitWidthChanged: {
|
||||
console.log(tag, uuid + " onImplicitWidthChanged: " + this.implicitWidth)
|
||||
}
|
||||
|
||||
onImplicitHeightChanged: {
|
||||
console.log(tag, uuid + " onImplicitHeightChanged: " + this.implicitHeight)
|
||||
}
|
||||
|
||||
onContentWidthChanged: {
|
||||
console.log(tag, uuid + " onContentWidthChanged: " + this.contentWidth)
|
||||
}
|
||||
|
||||
onContentHeightChanged: {
|
||||
console.log(tag, uuid + " onContentHeightChanged: " + this.contentHeight)
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
console.log(tag, uuid + " wrapper: " + wrapper)
|
||||
mouseAreaBridge.onClick(wrapper)
|
||||
}
|
||||
}
|
||||
}
|
74
doric-Qt/example/doric/resources/stack.qml
Normal file
74
doric-Qt/example/doric/resources/stack.qml
Normal file
@@ -0,0 +1,74 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.5
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
import "util.mjs" as Util
|
||||
|
||||
Rectangle {
|
||||
property var wrapper
|
||||
|
||||
clip: true
|
||||
|
||||
property var uuid: Util.uuidv4()
|
||||
|
||||
property var tag: "Stack"
|
||||
|
||||
onWidthChanged: {
|
||||
console.log(tag, uuid + " onWidthChanged: " + this.width)
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
console.log(tag, uuid + " onHeightChanged: " + this.height)
|
||||
}
|
||||
|
||||
color: 'transparent'
|
||||
|
||||
property var backgroundColor
|
||||
|
||||
onBackgroundColorChanged: {
|
||||
color = backgroundColor
|
||||
}
|
||||
|
||||
property var borderWidth: 0
|
||||
onBorderWidthChanged: {
|
||||
border.width = borderWidth
|
||||
}
|
||||
|
||||
property var borderColor: ""
|
||||
onBorderColorChanged: {
|
||||
border.color = borderColor
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
console.log(tag, uuid + " wrapper: " + wrapper)
|
||||
mouseAreaBridge.onClick(wrapper)
|
||||
}
|
||||
}
|
||||
|
||||
property var shadowColor
|
||||
property var shadowRadius
|
||||
property var shadowOffsetX
|
||||
property var shadowOffsetY
|
||||
property var shadowOpacity
|
||||
|
||||
onShadowOpacityChanged: {
|
||||
if (shadowOpacity > 0) {
|
||||
layer.enabled = true
|
||||
} else {
|
||||
layer.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
layer.enabled: false
|
||||
layer.effect: DropShadow {
|
||||
horizontalOffset: shadowOffsetX
|
||||
verticalOffset: shadowOffsetY
|
||||
radius: shadowRadius
|
||||
samples: 16
|
||||
color: shadowColor
|
||||
transparentBorder: true
|
||||
}
|
||||
}
|
88
doric-Qt/example/doric/resources/text.qml
Normal file
88
doric-Qt/example/doric/resources/text.qml
Normal file
@@ -0,0 +1,88 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.5
|
||||
|
||||
import "util.mjs" as Util
|
||||
import "gravity.mjs" as Gravity
|
||||
|
||||
TextArea {
|
||||
property var wrapper
|
||||
|
||||
property var uuid: Util.uuidv4()
|
||||
|
||||
property var tag: "Text"
|
||||
|
||||
readOnly: true
|
||||
|
||||
leftPadding: 0
|
||||
topPadding: 0
|
||||
rightPadding: 0
|
||||
bottomPadding: 0
|
||||
|
||||
property int textAlignment: 0
|
||||
|
||||
background: Rectangle {
|
||||
id: bg
|
||||
color: 'transparent'
|
||||
}
|
||||
|
||||
property var backgroundColor
|
||||
|
||||
onBackgroundColorChanged: {
|
||||
bg.color = backgroundColor
|
||||
}
|
||||
|
||||
horizontalAlignment: TextInput.AlignHCenter
|
||||
verticalAlignment: TextInput.AlignVCenter
|
||||
|
||||
onTextAlignmentChanged: {
|
||||
let gravity = Gravity.enumerate()
|
||||
let result = this.textAlignment | gravity.CENTER_Y
|
||||
console.log(tag, uuid + " onTextAlignmentChanged: " + this.textAlignment)
|
||||
switch(result) {
|
||||
case gravity.CENTER:
|
||||
this.horizontalAlignment = TextInput.AlignHCenter
|
||||
this.verticalAlignment = TextInput.AlignVCenter
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
bg.implicitWidth = width
|
||||
console.log(tag, uuid + " onWidthChanged: " + this.width)
|
||||
|
||||
let tempText = this.text
|
||||
this.text = ""
|
||||
this.text = tempText
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
bg.implicitHeight = height
|
||||
console.log(tag, uuid + " onHeightChanged: " + this.height)
|
||||
|
||||
let tempText = this.text
|
||||
this.text = ""
|
||||
this.text = tempText
|
||||
}
|
||||
|
||||
onTextChanged: {
|
||||
console.log(tag, uuid + " onTextChanged: " + this.text)
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
33
doric-Qt/example/doric/resources/toast.qml
Normal file
33
doric-Qt/example/doric/resources/toast.qml
Normal file
@@ -0,0 +1,33 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.5
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
ApplicationWindow {
|
||||
id: window
|
||||
|
||||
flags: flags | Qt.WindowStaysOnTopHint | Qt.Tool | Qt.FramelessWindowHint | Qt.WindowTransparentForInput
|
||||
|
||||
color: "#bb000000"
|
||||
visible: true
|
||||
|
||||
ColumnLayout {
|
||||
Text {
|
||||
text: "toast"
|
||||
font.pixelSize: 20
|
||||
color: 'white'
|
||||
Layout.leftMargin: 5
|
||||
Layout.rightMargin: 5
|
||||
Layout.topMargin: 15
|
||||
Layout.bottomMargin: 15
|
||||
}
|
||||
|
||||
onWidthChanged: {
|
||||
window.width = implicitWidth
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
window.height = implicitHeight
|
||||
}
|
||||
}
|
||||
}
|
||||
|
8
doric-Qt/example/doric/resources/util.mjs
Normal file
8
doric-Qt/example/doric/resources/util.mjs
Normal file
@@ -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);
|
||||
});
|
||||
}
|
7
doric-Qt/example/doric/resources/view.qml
Normal file
7
doric-Qt/example/doric/resources/view.qml
Normal file
@@ -0,0 +1,7 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.5
|
||||
|
||||
Rectangle {
|
||||
width: childrenRect.width
|
||||
height: childrenRect.height
|
||||
}
|
74
doric-Qt/example/doric/resources/vlayout.qml
Normal file
74
doric-Qt/example/doric/resources/vlayout.qml
Normal file
@@ -0,0 +1,74 @@
|
||||
import QtQuick 2.12
|
||||
import QtQuick.Controls 2.5
|
||||
import QtQuick.Layouts 1.15
|
||||
import QtGraphicalEffects 1.12
|
||||
|
||||
import "util.mjs" as Util
|
||||
|
||||
Rectangle {
|
||||
property var wrapper
|
||||
|
||||
clip: true
|
||||
|
||||
property var uuid: Util.uuidv4()
|
||||
|
||||
property var tag: "VLayout"
|
||||
|
||||
onWidthChanged: {
|
||||
console.log(tag, uuid + " onWidthChanged: " + this.width)
|
||||
}
|
||||
|
||||
onHeightChanged: {
|
||||
console.log(tag, uuid + " onHeightChanged: " + this.height)
|
||||
}
|
||||
|
||||
color: 'transparent'
|
||||
|
||||
property var backgroundColor
|
||||
|
||||
onBackgroundColorChanged: {
|
||||
color = backgroundColor
|
||||
}
|
||||
|
||||
property var borderWidth: 0
|
||||
onBorderWidthChanged: {
|
||||
border.width = borderWidth
|
||||
}
|
||||
|
||||
property var borderColor: ""
|
||||
onBorderColorChanged: {
|
||||
border.color = borderColor
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
console.log(tag, uuid + " wrapper: " + wrapper)
|
||||
mouseAreaBridge.onClick(wrapper)
|
||||
}
|
||||
}
|
||||
|
||||
property var shadowColor
|
||||
property var shadowRadius
|
||||
property var shadowOffsetX
|
||||
property var shadowOffsetY
|
||||
property var shadowOpacity
|
||||
|
||||
onShadowOpacityChanged: {
|
||||
if (shadowOpacity > 0) {
|
||||
layer.enabled = true
|
||||
} else {
|
||||
layer.enabled = false
|
||||
}
|
||||
}
|
||||
|
||||
layer.enabled: false
|
||||
layer.effect: DropShadow {
|
||||
horizontalOffset: shadowOffsetX
|
||||
verticalOffset: shadowOffsetY
|
||||
radius: shadowRadius
|
||||
samples: 16
|
||||
color: shadowColor
|
||||
transparentBorder: true
|
||||
}
|
||||
}
|
155
doric-Qt/example/doric/shader/DoricGroupNode.cpp
Normal file
155
doric-Qt/example/doric/shader/DoricGroupNode.cpp
Normal file
@@ -0,0 +1,155 @@
|
||||
#include "DoricGroupNode.h"
|
||||
|
||||
void DoricGroupNode::blend(QQuickItem *view, QString name, QJsonValue prop) {
|
||||
if (name == "children") {
|
||||
mChildViewIds.clear();
|
||||
if (prop.isArray()) {
|
||||
QJsonArray array = prop.toArray();
|
||||
const int length = array.size();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QJsonValue value = array.at(i);
|
||||
if (value.isString()) {
|
||||
mChildViewIds.append(value.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DoricSuperNode::blend(view, name, prop);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricGroupNode::blend(QJsonValue jsValue) {
|
||||
DoricViewNode::blend(jsValue);
|
||||
}
|
||||
|
||||
void DoricGroupNode::afterBlended(QJsonValue props) { configChildNode(); }
|
||||
|
||||
void DoricGroupNode::configChildNode() {
|
||||
QQuickItem *parent = mView;
|
||||
|
||||
for (int idx = 0; idx < mChildViewIds.size(); idx++) {
|
||||
QString id = mChildViewIds.at(idx);
|
||||
QJsonValue model = getSubModel(id);
|
||||
if (model.isUndefined()) {
|
||||
DoricRegistry *registry = getContext()->getDriver()->getRegistry();
|
||||
qCritical() << "model.isUndefined()";
|
||||
continue;
|
||||
}
|
||||
QString type = model["type"].toString();
|
||||
if (idx < mChildNodes.size()) {
|
||||
DoricViewNode *oldNode = mChildNodes.at(idx);
|
||||
if (id == oldNode->getId()) {
|
||||
// The same, skip
|
||||
} else {
|
||||
if (mReusable) {
|
||||
if (oldNode->getType() == type) {
|
||||
// Same type,can be reused
|
||||
oldNode->setId(id);
|
||||
oldNode->blend(model["props"]);
|
||||
} else {
|
||||
// Replace this view
|
||||
mChildNodes.removeAt(idx);
|
||||
oldNode->getNodeView()->setParent(nullptr);
|
||||
oldNode->getNodeView()->setParentItem(nullptr);
|
||||
oldNode->getNodeView()->deleteLater();
|
||||
|
||||
DoricViewNode *newNode = DoricViewNode::create(getContext(), type);
|
||||
if (newNode != nullptr) {
|
||||
newNode->setId(id);
|
||||
newNode->init(this);
|
||||
|
||||
if (idx >= mChildNodes.size()) {
|
||||
mChildNodes.append(newNode);
|
||||
newNode->getNodeView()->setParentItem(parent);
|
||||
} else {
|
||||
mChildNodes.insert(idx, newNode);
|
||||
newNode->getNodeView()->setParentItem(parent);
|
||||
newNode->getNodeView()->stackBefore(
|
||||
parent->childItems().at(idx));
|
||||
}
|
||||
|
||||
newNode->blend(model["props"]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Find in remain nodes
|
||||
int position = -1;
|
||||
for (int start = idx + 1; start < mChildNodes.size(); start++) {
|
||||
DoricViewNode *node = mChildNodes.at(start);
|
||||
if (id == node->getId()) {
|
||||
// Found
|
||||
position = start;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (position >= 0) {
|
||||
// Found swap idx,position
|
||||
mChildNodes.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);
|
||||
|
||||
if (idx >= mChildNodes.size()) {
|
||||
mChildNodes.append(newNode);
|
||||
newNode->getNodeView()->setParentItem(parent);
|
||||
} else {
|
||||
mChildNodes.insert(idx, newNode);
|
||||
newNode->getNodeView()->setParentItem(parent);
|
||||
newNode->getNodeView()->stackBefore(
|
||||
parent->childItems().at(idx));
|
||||
}
|
||||
|
||||
newNode->blend(model["props"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Insert
|
||||
DoricViewNode *newNode = DoricViewNode::create(getContext(), type);
|
||||
if (newNode != nullptr) {
|
||||
newNode->setId(id);
|
||||
newNode->init(this);
|
||||
|
||||
if (idx >= mChildNodes.size()) {
|
||||
mChildNodes.append(newNode);
|
||||
newNode->getNodeView()->setParentItem(parent);
|
||||
} else {
|
||||
mChildNodes.insert(idx, newNode);
|
||||
newNode->getNodeView()->setParentItem(parent);
|
||||
newNode->getNodeView()->stackBefore(parent->childItems().at(idx));
|
||||
}
|
||||
|
||||
newNode->blend(model["props"]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int size = mChildNodes.size();
|
||||
for (int idx = mChildViewIds.size(); idx < size; idx++) {
|
||||
DoricViewNode *viewNode = mChildNodes.at(mChildViewIds.size());
|
||||
mChildNodes.removeAt(mChildViewIds.size());
|
||||
viewNode->getNodeView()->setParent(nullptr);
|
||||
viewNode->getNodeView()->setParentItem(nullptr);
|
||||
viewNode->getNodeView()->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void DoricGroupNode::blendSubNode(QJsonValue subProperties) {
|
||||
QString subNodeId = subProperties["id"].toString();
|
||||
for (DoricViewNode *node : mChildNodes) {
|
||||
if (subNodeId == node->getId()) {
|
||||
node->blend(subProperties["props"]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoricGroupNode::requestLayout() {
|
||||
DoricSuperNode::requestLayout();
|
||||
foreach (DoricViewNode *node, this->mChildNodes) { node->requestLayout(); }
|
||||
}
|
28
doric-Qt/example/doric/shader/DoricGroupNode.h
Normal file
28
doric-Qt/example/doric/shader/DoricGroupNode.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef DORICGROUPNODE_H
|
||||
#define DORICGROUPNODE_H
|
||||
|
||||
#include "DoricSuperNode.h"
|
||||
|
||||
class DoricGroupNode : public DoricSuperNode {
|
||||
public:
|
||||
using DoricSuperNode::DoricSuperNode;
|
||||
|
||||
virtual void blend(QQuickItem *view, QString name, QJsonValue prop) override;
|
||||
|
||||
virtual void blend(QJsonValue jsValue) override;
|
||||
|
||||
protected:
|
||||
QList<DoricViewNode *> mChildNodes;
|
||||
|
||||
QList<QString> mChildViewIds;
|
||||
|
||||
void configChildNode();
|
||||
|
||||
virtual void blendSubNode(QJsonValue subProperties) override;
|
||||
|
||||
virtual void afterBlended(QJsonValue props) override;
|
||||
|
||||
virtual void requestLayout() override;
|
||||
};
|
||||
|
||||
#endif // DORICGROUPNODE_H
|
31
doric-Qt/example/doric/shader/DoricHLayoutNode.cpp
Normal file
31
doric-Qt/example/doric/shader/DoricHLayoutNode.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "DoricHLayoutNode.h"
|
||||
|
||||
QQuickItem *DoricHLayoutNode::build() {
|
||||
QQmlComponent component(getContext()->getQmlEngine());
|
||||
|
||||
const QUrl url(QStringLiteral("qrc:/doric/qml/hlayout.qml"));
|
||||
component.loadUrl(url);
|
||||
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errorString();
|
||||
}
|
||||
|
||||
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;
|
||||
if (name == "space") {
|
||||
getLayouts()->setSpacing(prop.toDouble());
|
||||
} else if (name == "gravity") {
|
||||
getLayouts()->setGravity(prop.toInt());
|
||||
} else {
|
||||
DoricGroupNode::blend(view, name, prop);
|
||||
}
|
||||
}
|
16
doric-Qt/example/doric/shader/DoricHLayoutNode.h
Normal file
16
doric-Qt/example/doric/shader/DoricHLayoutNode.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef DORICHLAYOUTNODE_H
|
||||
#define DORICHLAYOUTNODE_H
|
||||
|
||||
|
||||
#include "DoricGroupNode.h"
|
||||
|
||||
class DoricHLayoutNode : public DoricGroupNode {
|
||||
public:
|
||||
using DoricGroupNode::DoricGroupNode;
|
||||
|
||||
QQuickItem *build() override;
|
||||
|
||||
virtual void blend(QQuickItem *view, QString name, QJsonValue prop) override;
|
||||
};
|
||||
|
||||
#endif // DORICHLAYOUTNODE_H
|
79
doric-Qt/example/doric/shader/DoricImageNode.cpp
Normal file
79
doric-Qt/example/doric/shader/DoricImageNode.cpp
Normal file
@@ -0,0 +1,79 @@
|
||||
#include "DoricImageNode.h"
|
||||
#include "DoricSuperNode.h"
|
||||
|
||||
#include "../utils/DoricUtils.h"
|
||||
|
||||
#include <QQuickItem>
|
||||
|
||||
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<QQuickItem *>(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 if (name == "isBlur") {
|
||||
if (prop.toBool()) {
|
||||
container->setProperty("isBlur", prop.toBool());
|
||||
}
|
||||
} else {
|
||||
DoricViewNode::blend(view, name, prop);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricImageNode::onReady() {
|
||||
if (!this->loadCallbackId.isEmpty()) {
|
||||
QVariantList args;
|
||||
|
||||
QMap<QString, QVariant> map;
|
||||
map.insert("width", mView->width());
|
||||
map.insert("height", mView->height());
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
30
doric-Qt/example/doric/shader/DoricImageNode.h
Normal file
30
doric-Qt/example/doric/shader/DoricImageNode.h
Normal file
@@ -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
|
15
doric-Qt/example/doric/shader/DoricRootNode.cpp
Normal file
15
doric-Qt/example/doric/shader/DoricRootNode.cpp
Normal file
@@ -0,0 +1,15 @@
|
||||
#include "DoricRootNode.h"
|
||||
|
||||
void DoricRootNode::setRootView(QQuickItem *rootView) {
|
||||
this->mView = rootView;
|
||||
this->createLayouts(rootView);
|
||||
|
||||
this->getLayouts()->setLayoutType(DoricLayoutType::DoricStack);
|
||||
}
|
||||
|
||||
QQuickItem *DoricRootNode::getRootView() { return mView; }
|
||||
|
||||
void DoricRootNode::requestLayout() {
|
||||
getLayouts()->apply();
|
||||
DoricStackNode::requestLayout();
|
||||
}
|
19
doric-Qt/example/doric/shader/DoricRootNode.h
Normal file
19
doric-Qt/example/doric/shader/DoricRootNode.h
Normal file
@@ -0,0 +1,19 @@
|
||||
#ifndef ROOTNODE_H
|
||||
#define ROOTNODE_H
|
||||
|
||||
#include <QQuickItem>
|
||||
|
||||
#include "DoricStackNode.h"
|
||||
|
||||
class DoricRootNode : public DoricStackNode {
|
||||
public:
|
||||
using DoricStackNode::DoricStackNode;
|
||||
|
||||
void setRootView(QQuickItem *rootView);
|
||||
|
||||
QQuickItem *getRootView();
|
||||
|
||||
virtual void requestLayout() override;
|
||||
};
|
||||
|
||||
#endif // ROOTNODE_H
|
119
doric-Qt/example/doric/shader/DoricScrollerNode.cpp
Normal file
119
doric-Qt/example/doric/shader/DoricScrollerNode.cpp
Normal file
@@ -0,0 +1,119 @@
|
||||
#include "DoricScrollerNode.h"
|
||||
|
||||
QQuickItem *DoricScrollerNode::build() {
|
||||
QQmlComponent component(getContext()->getQmlEngine());
|
||||
|
||||
const QUrl url(QStringLiteral("qrc:/doric/qml/scroller.qml"));
|
||||
component.loadUrl(url);
|
||||
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errorString();
|
||||
}
|
||||
|
||||
QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
|
||||
this->createLayouts(item);
|
||||
|
||||
item->setProperty("wrapper", QString::number((qint64)this));
|
||||
return item;
|
||||
}
|
||||
|
||||
void DoricScrollerNode::blend(QQuickItem *view, QString name, QJsonValue prop) {
|
||||
if (name == "content") {
|
||||
if (!prop.isString()) {
|
||||
return;
|
||||
}
|
||||
mChildViewId = prop.toString();
|
||||
} else if (name == "onScroll") {
|
||||
if (!prop.isString()) {
|
||||
return;
|
||||
}
|
||||
onScrollFuncId = prop.toString();
|
||||
} else if (name == "onScrollEnd") {
|
||||
if (!prop.isString()) {
|
||||
return;
|
||||
}
|
||||
onScrollEndFuncId = prop.toString();
|
||||
} else {
|
||||
DoricSuperNode::blend(view, name, prop);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricScrollerNode::afterBlended(QJsonValue jsValue) {
|
||||
QJsonValue contentModel = getSubModel(mChildViewId);
|
||||
if (contentModel == QJsonValue::Undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString viewId = contentModel["id"].toString();
|
||||
QString type = contentModel["type"].toString();
|
||||
QJsonValue props = contentModel["props"];
|
||||
|
||||
QQuickItem *parent = mView;
|
||||
|
||||
if (mChildNode != nullptr) {
|
||||
if (viewId == mChildNode->getId()) {
|
||||
// skip
|
||||
} else {
|
||||
if (mReusable && mChildNode->getType() == type) {
|
||||
mChildNode->setId(viewId);
|
||||
mChildNode->blend(props);
|
||||
} else {
|
||||
// remove all views
|
||||
for (int i = 0; i != parent->childItems().size(); i++) {
|
||||
parent->childItems().at(i)->setParent(nullptr);
|
||||
parent->childItems().at(i)->setParentItem(nullptr);
|
||||
parent->childItems().at(i)->deleteLater();
|
||||
}
|
||||
|
||||
mChildNode = DoricViewNode::create(getContext(), type);
|
||||
mChildNode->setId(viewId);
|
||||
mChildNode->init(this);
|
||||
mChildNode->blend(props);
|
||||
|
||||
QQmlListProperty<QQuickItem> contentChildren =
|
||||
qvariant_cast<QQmlListProperty<QQuickItem>>(
|
||||
parent->property("contentChildren"));
|
||||
contentChildren.append(&contentChildren, mChildNode->getNodeView());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
mChildNode = DoricViewNode::create(getContext(), type);
|
||||
mChildNode->setId(viewId);
|
||||
mChildNode->init(this);
|
||||
mChildNode->blend(props);
|
||||
|
||||
QQmlListProperty<QQuickItem> contentChildren =
|
||||
qvariant_cast<QQmlListProperty<QQuickItem>>(
|
||||
parent->property("contentChildren"));
|
||||
contentChildren.append(&contentChildren, mChildNode->getNodeView());
|
||||
}
|
||||
}
|
||||
|
||||
void DoricScrollerNode::requestLayout() {
|
||||
this->mChildNode->requestLayout();
|
||||
DoricLayouts *layout = (DoricLayouts *)(mChildNode->getNodeView()
|
||||
->property("doricLayout")
|
||||
.toULongLong());
|
||||
if (layout != nullptr) {
|
||||
layout->apply(QSizeF(mView->width(), mView->height()));
|
||||
|
||||
mView->setProperty("contentWidth", layout->getMeasuredWidth());
|
||||
mView->setProperty("contentHeight", layout->getMeasuredHeight());
|
||||
}
|
||||
}
|
||||
|
||||
void DoricScrollerNode::blendSubNode(QJsonValue subProperties) {
|
||||
if (mChildNode != nullptr) {
|
||||
mChildNode->blend(subProperties["props"]);
|
||||
}
|
||||
}
|
||||
|
||||
QSizeF DoricScrollerNode::sizeThatFits(QSizeF size) {
|
||||
DoricLayouts *layout = (DoricLayouts *)mChildNode->getNodeView()
|
||||
->property("doricLayout")
|
||||
.toULongLong();
|
||||
layout->apply(size);
|
||||
|
||||
return QSizeF(qMin(size.width(), layout->getMeasuredWidth()),
|
||||
qMin(size.height(), layout->getMeasuredHeight()));
|
||||
}
|
30
doric-Qt/example/doric/shader/DoricScrollerNode.h
Normal file
30
doric-Qt/example/doric/shader/DoricScrollerNode.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef DORICSCROLLERNODE_H
|
||||
#define DORICSCROLLERNODE_H
|
||||
|
||||
#include "DoricSuperNode.h"
|
||||
|
||||
class DoricScrollerNode : public DoricSuperNode {
|
||||
private:
|
||||
DoricViewNode *mChildNode = nullptr;
|
||||
|
||||
QString mChildViewId;
|
||||
QString onScrollFuncId;
|
||||
QString onScrollEndFuncId;
|
||||
|
||||
public:
|
||||
using DoricSuperNode::DoricSuperNode;
|
||||
|
||||
QQuickItem *build() override;
|
||||
|
||||
virtual void blend(QQuickItem *view, QString name, QJsonValue prop) override;
|
||||
|
||||
virtual void blendSubNode(QJsonValue subProperties) override;
|
||||
|
||||
virtual void afterBlended(QJsonValue jsValue) override;
|
||||
|
||||
virtual void requestLayout() override;
|
||||
|
||||
QSizeF sizeThatFits(QSizeF size);
|
||||
};
|
||||
|
||||
#endif // DORICSCROLLERNODE_H
|
30
doric-Qt/example/doric/shader/DoricStackNode.cpp
Normal file
30
doric-Qt/example/doric/shader/DoricStackNode.cpp
Normal file
@@ -0,0 +1,30 @@
|
||||
#include "DoricStackNode.h"
|
||||
|
||||
QQuickItem *DoricStackNode::build() {
|
||||
QQmlComponent component(getContext()->getQmlEngine());
|
||||
|
||||
const QUrl url(QStringLiteral("qrc:/doric/qml/stack.qml"));
|
||||
component.loadUrl(url);
|
||||
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errorString();
|
||||
}
|
||||
|
||||
QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
|
||||
this->createLayouts(item);
|
||||
|
||||
getLayouts()->setLayoutType(DoricLayoutType::DoricStack);
|
||||
|
||||
item->setProperty("wrapper", QString::number((qint64)this));
|
||||
return item;
|
||||
}
|
||||
|
||||
void DoricStackNode::blendLayoutConfig(QJsonValue jsValue) {
|
||||
DoricViewNode::blendLayoutConfig(jsValue);
|
||||
QJsonValue maxWidth = jsValue["maxWidth"];
|
||||
if (maxWidth.isDouble()) {
|
||||
}
|
||||
QJsonValue maxHeight = jsValue["maxHeight"];
|
||||
if (maxHeight.isDouble()) {
|
||||
}
|
||||
}
|
15
doric-Qt/example/doric/shader/DoricStackNode.h
Normal file
15
doric-Qt/example/doric/shader/DoricStackNode.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef DORICSTACKNODE_H
|
||||
#define DORICSTACKNODE_H
|
||||
|
||||
#include "DoricGroupNode.h"
|
||||
|
||||
class DoricStackNode : public DoricGroupNode {
|
||||
public:
|
||||
using DoricGroupNode::DoricGroupNode;
|
||||
|
||||
QQuickItem *build() override;
|
||||
|
||||
void blendLayoutConfig(QJsonValue jsValue) override;
|
||||
};
|
||||
|
||||
#endif // DORICSTACKNODE_H
|
56
doric-Qt/example/doric/shader/DoricSuperNode.cpp
Normal file
56
doric-Qt/example/doric/shader/DoricSuperNode.cpp
Normal file
@@ -0,0 +1,56 @@
|
||||
#include <QJSValueIterator>
|
||||
|
||||
#include "DoricSuperNode.h"
|
||||
|
||||
void DoricSuperNode::blend(QQuickItem *view, QString name, QJsonValue prop) {
|
||||
if (name == "subviews") {
|
||||
if (prop.isArray()) {
|
||||
QJsonArray array = prop.toArray();
|
||||
const int length = array.size();
|
||||
for (int i = 0; i < length; ++i) {
|
||||
QJsonValue subNode = array.at(i);
|
||||
mixinSubNode(subNode);
|
||||
blendSubNode(subNode);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
DoricViewNode::blend(view, name, prop);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricSuperNode::mixinSubNode(QJsonValue subNode) {
|
||||
QString id = subNode["id"].toString();
|
||||
QList<QString> keys = subNodes.keys();
|
||||
if (!keys.contains(id)) {
|
||||
subNodes.insert(id, subNode);
|
||||
} else {
|
||||
mixin(subNode, subNodes.value(id));
|
||||
}
|
||||
}
|
||||
|
||||
void DoricSuperNode::mixin(QJsonValue src, QJsonValue target) {
|
||||
QJsonValue srcProps = src["props"];
|
||||
QJsonValue targetProps = target["props"];
|
||||
|
||||
foreach (const QString &key, srcProps.toObject().keys()) {
|
||||
QJsonValue value = srcProps[key];
|
||||
if (key == "subviews" && value.isArray()) {
|
||||
|
||||
} else {
|
||||
targetProps.toObject().insert(key, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QJsonValue DoricSuperNode::getSubModel(QString id) {
|
||||
if (subNodes.keys().contains(id)) {
|
||||
return subNodes.value(id);
|
||||
} else {
|
||||
return QJsonValue::Undefined;
|
||||
}
|
||||
}
|
||||
|
||||
void DoricSuperNode::blendSubLayoutConfig(DoricViewNode *viewNode,
|
||||
QJsonValue jsValue) {
|
||||
viewNode->blendLayoutConfig(jsValue);
|
||||
}
|
32
doric-Qt/example/doric/shader/DoricSuperNode.h
Normal file
32
doric-Qt/example/doric/shader/DoricSuperNode.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef DORICSUPERNODE_H
|
||||
#define DORICSUPERNODE_H
|
||||
|
||||
#include <QJsonArray>
|
||||
|
||||
#include "DoricViewNode.h"
|
||||
|
||||
class DoricSuperNode : public DoricViewNode {
|
||||
private:
|
||||
QMap<QString, QJsonValue> subNodes;
|
||||
|
||||
protected:
|
||||
virtual void blend(QQuickItem *view, QString name, QJsonValue prop) override;
|
||||
|
||||
virtual void blendSubNode(QJsonValue subProperties) = 0;
|
||||
|
||||
public:
|
||||
using DoricViewNode::DoricViewNode;
|
||||
|
||||
bool mReusable = false;
|
||||
|
||||
QJsonValue getSubModel(QString id);
|
||||
|
||||
void blendSubLayoutConfig(DoricViewNode *viewNode, QJsonValue jsValue);
|
||||
|
||||
private:
|
||||
void mixinSubNode(QJsonValue subNode);
|
||||
|
||||
void mixin(QJsonValue src, QJsonValue target);
|
||||
};
|
||||
|
||||
#endif // DORICSUPERNODE_H
|
36
doric-Qt/example/doric/shader/DoricTextNode.cpp
Normal file
36
doric-Qt/example/doric/shader/DoricTextNode.cpp
Normal file
@@ -0,0 +1,36 @@
|
||||
#include "DoricTextNode.h"
|
||||
#include "../utils/DoricUtils.h"
|
||||
|
||||
QQuickItem *DoricTextNode::build() {
|
||||
QQmlComponent component(getContext()->getQmlEngine());
|
||||
|
||||
const QUrl url(QStringLiteral("qrc:/doric/qml/text.qml"));
|
||||
component.loadUrl(url);
|
||||
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errorString();
|
||||
}
|
||||
|
||||
QQuickItem *item = qobject_cast<QQuickItem *>(component.create());
|
||||
this->createLayouts(item);
|
||||
|
||||
item->setProperty("wrapper", QString::number((qint64)this));
|
||||
return item;
|
||||
}
|
||||
|
||||
void DoricTextNode::blend(QQuickItem *view, QString name, QJsonValue prop) {
|
||||
if (name == "text") {
|
||||
view->setProperty("text", prop.toString());
|
||||
} else if (name == "textColor") {
|
||||
QString color = DoricUtils::doricColor(prop.toInt()).name();
|
||||
view->setProperty("color", color);
|
||||
} else if (name == "textSize") {
|
||||
QFont font = view->property("font").value<QFont>();
|
||||
font.setPixelSize(prop.toInt());
|
||||
view->setProperty("font", QVariant(font));
|
||||
} else if (name == "textAlignment") {
|
||||
view->setProperty("textAlignment", prop.toInt());
|
||||
} else {
|
||||
DoricViewNode::blend(view, name, prop);
|
||||
}
|
||||
}
|
15
doric-Qt/example/doric/shader/DoricTextNode.h
Normal file
15
doric-Qt/example/doric/shader/DoricTextNode.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef DORICTEXTNODE_H
|
||||
#define DORICTEXTNODE_H
|
||||
|
||||
#include "DoricViewNode.h"
|
||||
|
||||
class DoricTextNode : public DoricViewNode {
|
||||
public:
|
||||
using DoricViewNode::DoricViewNode;
|
||||
|
||||
QQuickItem *build() override;
|
||||
|
||||
virtual void blend(QQuickItem *view, QString name, QJsonValue prop) override;
|
||||
};
|
||||
|
||||
#endif // DORICTEXTNODE_H
|
31
doric-Qt/example/doric/shader/DoricVLayoutNode.cpp
Normal file
31
doric-Qt/example/doric/shader/DoricVLayoutNode.cpp
Normal file
@@ -0,0 +1,31 @@
|
||||
#include "DoricVLayoutNode.h"
|
||||
|
||||
QQuickItem *DoricVLayoutNode::build() {
|
||||
QQmlComponent component(getContext()->getQmlEngine());
|
||||
|
||||
const QUrl url(QStringLiteral("qrc:/doric/qml/vlayout.qml"));
|
||||
component.loadUrl(url);
|
||||
|
||||
if (component.isError()) {
|
||||
qCritical() << component.errorString();
|
||||
}
|
||||
|
||||
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;
|
||||
if (name == "space") {
|
||||
getLayouts()->setSpacing(prop.toDouble());
|
||||
} else if (name == "gravity") {
|
||||
getLayouts()->setGravity(prop.toInt());
|
||||
} else {
|
||||
DoricGroupNode::blend(view, name, prop);
|
||||
}
|
||||
}
|
15
doric-Qt/example/doric/shader/DoricVLayoutNode.h
Normal file
15
doric-Qt/example/doric/shader/DoricVLayoutNode.h
Normal file
@@ -0,0 +1,15 @@
|
||||
#ifndef DORICVLAYOUTNODE_H
|
||||
#define DORICVLAYOUTNODE_H
|
||||
|
||||
#include "DoricGroupNode.h"
|
||||
|
||||
class DoricVLayoutNode : public DoricGroupNode {
|
||||
public:
|
||||
using DoricGroupNode::DoricGroupNode;
|
||||
|
||||
QQuickItem *build() override;
|
||||
|
||||
virtual void blend(QQuickItem *view, QString name, QJsonValue prop) override;
|
||||
};
|
||||
|
||||
#endif // DORICVLAYOUTNODE_H
|
177
doric-Qt/example/doric/shader/DoricViewNode.cpp
Normal file
177
doric-Qt/example/doric/shader/DoricViewNode.cpp
Normal file
@@ -0,0 +1,177 @@
|
||||
#include "DoricViewNode.h"
|
||||
#include "../utils/DoricConstant.h"
|
||||
#include "../utils/DoricUtils.h"
|
||||
#include "DoricSuperNode.h"
|
||||
|
||||
void DoricViewNode::blendLayoutConfig(QJsonValue jsValue) {
|
||||
QJsonObject jsObject = jsValue.toObject();
|
||||
if (jsObject.contains("widthSpec"))
|
||||
getLayouts()->setWidthSpec(jsObject["widthSpec"].toInt());
|
||||
|
||||
if (jsObject.contains("heightSpec"))
|
||||
getLayouts()->setHeightSpec(jsObject["heightSpec"].toInt());
|
||||
|
||||
if (jsObject.contains("margin")) {
|
||||
QJsonObject margin = jsObject["margin"].toObject();
|
||||
|
||||
if (margin.contains("left"))
|
||||
getLayouts()->setMarginLeft(margin["left"].toDouble());
|
||||
|
||||
if (margin.contains("top"))
|
||||
getLayouts()->setMarginTop(margin["top"].toDouble());
|
||||
|
||||
if (margin.contains("right"))
|
||||
getLayouts()->setMarginRight(margin["right"].toDouble());
|
||||
|
||||
if (margin.contains("bottom"))
|
||||
getLayouts()->setMarginBottom(margin["bottom"].toDouble());
|
||||
}
|
||||
|
||||
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"].toDouble());
|
||||
|
||||
if (jsObject.contains("maxHeight"))
|
||||
getLayouts()->setMaxHeight(jsObject["maxHeight"].toDouble());
|
||||
|
||||
if (jsObject.contains("minWidth"))
|
||||
getLayouts()->setMinWidth(jsObject["minWidth"].toDouble());
|
||||
|
||||
if (jsObject.contains("minHeight"))
|
||||
getLayouts()->setMinHeight(jsObject["minHeight"].toDouble());
|
||||
}
|
||||
|
||||
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);
|
||||
} else {
|
||||
blendLayoutConfig(layoutConfig);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricViewNode::init(DoricSuperNode *superNode) {
|
||||
if (DoricUtils:: instanceof <DoricSuperNode *>(this)) {
|
||||
DoricSuperNode *thiz = dynamic_cast<DoricSuperNode *>(this);
|
||||
thiz->mReusable = superNode->mReusable;
|
||||
}
|
||||
this->mSuperNode = superNode;
|
||||
this->mView = build();
|
||||
getLayouts();
|
||||
}
|
||||
|
||||
QString DoricViewNode::getId() { return mId; }
|
||||
|
||||
void DoricViewNode::setId(QString id) { mId = id; }
|
||||
|
||||
QString DoricViewNode::getType() { return mType; }
|
||||
|
||||
QQuickItem *DoricViewNode::getNodeView() { return mView; }
|
||||
|
||||
void DoricViewNode::blend(QJsonValue jsValue) {
|
||||
QJsonValue value = jsValue["layoutConfig"];
|
||||
if (value.isObject()) {
|
||||
setLayoutConfig(value);
|
||||
}
|
||||
|
||||
foreach (const QString &key, jsValue.toObject().keys()) {
|
||||
QJsonValue value = jsValue[key];
|
||||
blend(mView, key, value);
|
||||
}
|
||||
|
||||
this->afterBlended(jsValue);
|
||||
}
|
||||
|
||||
void DoricViewNode::blend(QQuickItem *view, QString name, QJsonValue prop) {
|
||||
if (name == "width") {
|
||||
getLayouts()->setWidth(prop.toDouble());
|
||||
} else if (name == "height") {
|
||||
getLayouts()->setHeight(prop.toDouble());
|
||||
} else if (name == "backgroundColor") {
|
||||
view->setProperty(
|
||||
"backgroundColor",
|
||||
QVariant::fromValue(DoricUtils::doricColor(prop.toInt())));
|
||||
} else if (name == "x") {
|
||||
getLayouts()->setMarginLeft(prop.toDouble());
|
||||
} else if (name == "y") {
|
||||
getLayouts()->setMarginTop(prop.toDouble());
|
||||
} else if (name == "corners") {
|
||||
view->setProperty("radius", prop.toDouble());
|
||||
} else if (name == "onClick") {
|
||||
if (prop.isString())
|
||||
clickFunction = prop.toString();
|
||||
} else if (name == "padding") {
|
||||
getLayouts()->setPaddingLeft(prop["left"].toDouble());
|
||||
getLayouts()->setPaddingRight(prop["right"].toDouble());
|
||||
getLayouts()->setPaddingTop(prop["top"].toDouble());
|
||||
getLayouts()->setPaddingBottom(prop["bottom"].toDouble());
|
||||
} else if (name == "hidden") {
|
||||
getLayouts()->setDisabled(prop.toBool());
|
||||
} else if (name == "border") {
|
||||
qreal borderWidth = prop["width"].toDouble();
|
||||
QString borderColor = DoricUtils::doricColor(prop["color"].toInt()).name();
|
||||
view->setProperty("borderWidth", borderWidth);
|
||||
view->setProperty("borderColor", borderColor);
|
||||
} else if (name == "shadow") {
|
||||
view->setProperty("shadowColor", QVariant::fromValue(DoricUtils::doricColor(
|
||||
prop["color"].toInt())));
|
||||
view->setProperty("shadowRadius", prop["radius"].toDouble());
|
||||
view->setProperty("shadowOffsetX", prop["offsetX"].toDouble());
|
||||
view->setProperty("shadowOffsetY", prop["offsetY"].toDouble());
|
||||
view->setProperty("shadowOpacity", prop["opacity"].toDouble());
|
||||
} else if (name != "layoutConfig") {
|
||||
qCritical() << name << ": " << prop.toString();
|
||||
}
|
||||
}
|
||||
|
||||
void DoricViewNode::afterBlended(QJsonValue prop) {}
|
||||
|
||||
QList<QString> DoricViewNode::getIdList() {
|
||||
QList<QString> ids;
|
||||
|
||||
DoricViewNode *viewNode = this;
|
||||
do {
|
||||
ids.insert(0, viewNode->mId);
|
||||
viewNode = viewNode->mSuperNode;
|
||||
} while (viewNode != nullptr);
|
||||
|
||||
return ids;
|
||||
}
|
||||
|
||||
void DoricViewNode::requestLayout() {}
|
||||
|
||||
void DoricViewNode::callJSResponse(QString funcId, QVariantList args) {
|
||||
QVariantList nArgs;
|
||||
QList<QString> idList = getIdList();
|
||||
nArgs.append(QVariant(idList));
|
||||
nArgs.append(funcId);
|
||||
foreach (const QVariant &arg, args)
|
||||
nArgs.append(arg);
|
||||
|
||||
return getContext()->callEntity(DoricConstant::DORIC_ENTITY_RESPONSE, nArgs);
|
||||
}
|
||||
|
||||
void DoricViewNode::onClick() {
|
||||
if (clickFunction.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
QVariantList args;
|
||||
callJSResponse(clickFunction, args);
|
||||
}
|
82
doric-Qt/example/doric/shader/DoricViewNode.h
Normal file
82
doric-Qt/example/doric/shader/DoricViewNode.h
Normal file
@@ -0,0 +1,82 @@
|
||||
#ifndef DORICVIEWNODE_H
|
||||
#define DORICVIEWNODE_H
|
||||
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QQuickItem>
|
||||
|
||||
#include "../utils/DoricContextHolder.h"
|
||||
#include "../utils/DoricLayouts.h"
|
||||
|
||||
class DoricSuperNode;
|
||||
|
||||
class DoricViewNode : public DoricContextHolder {
|
||||
|
||||
protected:
|
||||
QQuickItem *mView;
|
||||
|
||||
DoricLayouts *mLayouts = nullptr;
|
||||
|
||||
virtual QQuickItem *build() = 0;
|
||||
|
||||
void createLayouts(QQuickItem *view);
|
||||
|
||||
DoricLayouts *getLayouts();
|
||||
|
||||
void setLayoutConfig(QJsonValue layoutConfig);
|
||||
|
||||
private:
|
||||
QString mId;
|
||||
|
||||
QList<QString> getIdList();
|
||||
|
||||
QString clickFunction;
|
||||
|
||||
public:
|
||||
QString mType;
|
||||
|
||||
DoricSuperNode *mSuperNode = nullptr;
|
||||
|
||||
using DoricContextHolder::DoricContextHolder;
|
||||
|
||||
void init(DoricSuperNode *superNode);
|
||||
|
||||
static DoricViewNode *create(DoricContext *context, QString type) {
|
||||
bool classRegistered =
|
||||
context->getDriver()->getRegistry()->acquireNodeInfo(type);
|
||||
if (classRegistered) {
|
||||
QObject *node =
|
||||
context->getDriver()->getRegistry()->nodes.createObject(type);
|
||||
DoricViewNode *castNode = dynamic_cast<DoricViewNode *>(node);
|
||||
castNode->setContext(context);
|
||||
castNode->mType = type;
|
||||
return castNode;
|
||||
} else {
|
||||
qCritical() << "DoricViewNode create error: " + type;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
QString getId();
|
||||
|
||||
void setId(QString id);
|
||||
|
||||
QString getType();
|
||||
|
||||
QQuickItem *getNodeView();
|
||||
|
||||
virtual void blend(QJsonValue jsValue);
|
||||
|
||||
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);
|
||||
};
|
||||
#endif // DORICVIEWNODE_H
|
20
doric-Qt/example/doric/template/DoricSingleton.h
Normal file
20
doric-Qt/example/doric/template/DoricSingleton.h
Normal file
@@ -0,0 +1,20 @@
|
||||
#ifndef SINGLETON_H
|
||||
#define SINGLETON_H
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
class DoricSingleton {
|
||||
private:
|
||||
static DoricSingleton *local_instance;
|
||||
DoricSingleton() { qDebug() << "constructor"; }
|
||||
|
||||
~DoricSingleton() { qDebug() << "destructor"; }
|
||||
|
||||
public:
|
||||
static DoricSingleton *getInstance() {
|
||||
static DoricSingleton instance;
|
||||
return &instance;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // SINGLETON_H
|
38
doric-Qt/example/doric/utils/DoricConstant.cpp
Normal file
38
doric-Qt/example/doric/utils/DoricConstant.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "DoricConstant.h"
|
||||
|
||||
const QString DoricConstant::DORIC_BUNDLE_SANDBOX = "doric-sandbox.js";
|
||||
const QString DoricConstant::DORIC_BUNDLE_LIB = "doric-lib.js";
|
||||
const QString DoricConstant::DORIC_MODULE_LIB = "doric";
|
||||
|
||||
const QString DoricConstant::INJECT_ENVIRONMENT = "Environment";
|
||||
const QString DoricConstant::INJECT_LOG = "nativeLog";
|
||||
const QString DoricConstant::INJECT_EMPTY = "nativeEmpty";
|
||||
const QString DoricConstant::INJECT_REQUIRE = "nativeRequire";
|
||||
const QString DoricConstant::INJECT_TIMER_SET = "nativeSetTimer";
|
||||
const QString DoricConstant::INJECT_TIMER_CLEAR = "nativeClearTimer";
|
||||
const QString DoricConstant::INJECT_BRIDGE = "nativeBridge";
|
||||
|
||||
const QString DoricConstant::TEMPLATE_CONTEXT_CREATE =
|
||||
QString("Reflect.apply(") +
|
||||
"function(doric,context,Entry,require,exports){" + "\n" + "%s1" + "\n" +
|
||||
"},undefined,[" + "undefined," + "doric.jsObtainContext(\"%s2\")," +
|
||||
"doric.jsObtainEntry(\"%s3\")," + "doric.__require__" + ",{}" + "])";
|
||||
const QString DoricConstant::TEMPLATE_MODULE =
|
||||
QString("Reflect.apply(doric.jsRegisterModule,this,[") + "\"%s1\"," +
|
||||
"Reflect.apply(function(__module){" + "(function(module,exports,require){" +
|
||||
"\n" + "%s2" + "\n" + "})(__module,__module.exports,doric.__require__);" +
|
||||
"\nreturn __module.exports;" + "},this,[{exports:{}}])" + "])";
|
||||
const QString DoricConstant::TEMPLATE_CONTEXT_DESTROY =
|
||||
QString("doric.jsReleaseContext(\"%s\")");
|
||||
|
||||
const QString DoricConstant::GLOBAL_DORIC = "doric";
|
||||
const QString DoricConstant::DORIC_CONTEXT_INVOKE = "jsCallEntityMethod";
|
||||
const QString DoricConstant::DORIC_TIMER_CALLBACK = "jsCallbackTimer";
|
||||
const QString DoricConstant::DORIC_BRIDGE_RESOLVE = "jsCallResolve";
|
||||
const QString DoricConstant::DORIC_BRIDGE_REJECT = "jsCallReject";
|
||||
|
||||
const QString DoricConstant::DORIC_ENTITY_RESPONSE = "__response__";
|
||||
const QString DoricConstant::DORIC_ENTITY_INIT = "__init__";
|
||||
const QString DoricConstant::DORIC_ENTITY_CREATE = "__onCreate__";
|
||||
const QString DoricConstant::DORIC_ENTITY_BUILD = "__build__";
|
||||
const QString DoricConstant::DORIC_ENTITY_DESTROY = "__onDestroy__";
|
38
doric-Qt/example/doric/utils/DoricConstant.h
Normal file
38
doric-Qt/example/doric/utils/DoricConstant.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#ifndef CONSTANT_H
|
||||
#define CONSTANT_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
class DoricConstant {
|
||||
|
||||
public:
|
||||
static const QString DORIC_BUNDLE_SANDBOX;
|
||||
static const QString DORIC_BUNDLE_LIB;
|
||||
static const QString DORIC_MODULE_LIB;
|
||||
|
||||
static const QString INJECT_ENVIRONMENT;
|
||||
static const QString INJECT_LOG;
|
||||
static const QString INJECT_EMPTY;
|
||||
static const QString INJECT_REQUIRE;
|
||||
static const QString INJECT_TIMER_SET;
|
||||
static const QString INJECT_TIMER_CLEAR;
|
||||
static const QString INJECT_BRIDGE;
|
||||
|
||||
static const QString TEMPLATE_CONTEXT_CREATE;
|
||||
static const QString TEMPLATE_MODULE;
|
||||
static const QString TEMPLATE_CONTEXT_DESTROY;
|
||||
|
||||
static const QString GLOBAL_DORIC;
|
||||
static const QString DORIC_CONTEXT_INVOKE;
|
||||
static const QString DORIC_TIMER_CALLBACK;
|
||||
static const QString DORIC_BRIDGE_RESOLVE;
|
||||
static const QString DORIC_BRIDGE_REJECT;
|
||||
|
||||
static const QString DORIC_ENTITY_RESPONSE;
|
||||
static const QString DORIC_ENTITY_CREATE;
|
||||
static const QString DORIC_ENTITY_INIT;
|
||||
static const QString DORIC_ENTITY_BUILD;
|
||||
static const QString DORIC_ENTITY_DESTROY;
|
||||
};
|
||||
|
||||
#endif // CONSTANT_H
|
9
doric-Qt/example/doric/utils/DoricContextHolder.cpp
Normal file
9
doric-Qt/example/doric/utils/DoricContextHolder.cpp
Normal file
@@ -0,0 +1,9 @@
|
||||
#include "DoricContextHolder.h"
|
||||
|
||||
DoricContextHolder::DoricContextHolder(QObject *parent) { mContext = NULL; }
|
||||
|
||||
void DoricContextHolder::setContext(DoricContext *context) {
|
||||
mContext = context;
|
||||
}
|
||||
|
||||
DoricContext *DoricContextHolder::getContext() { return mContext; }
|
18
doric-Qt/example/doric/utils/DoricContextHolder.h
Normal file
18
doric-Qt/example/doric/utils/DoricContextHolder.h
Normal file
@@ -0,0 +1,18 @@
|
||||
#ifndef DORICCONTEXTHOLDER_H
|
||||
#define DORICCONTEXTHOLDER_H
|
||||
|
||||
#include "../DoricContext.h"
|
||||
|
||||
class DoricContextHolder : public QObject {
|
||||
protected:
|
||||
DoricContext *mContext = NULL;
|
||||
|
||||
public:
|
||||
explicit DoricContextHolder(QObject *parent = nullptr);
|
||||
|
||||
void setContext(DoricContext *context);
|
||||
|
||||
DoricContext *getContext();
|
||||
};
|
||||
|
||||
#endif // DORICCONTEXTHOLDER_H
|
32
doric-Qt/example/doric/utils/DoricCountDownLatch.h
Normal file
32
doric-Qt/example/doric/utils/DoricCountDownLatch.h
Normal file
@@ -0,0 +1,32 @@
|
||||
#ifndef COUNTDOWNLATCH_H
|
||||
#define COUNTDOWNLATCH_H
|
||||
|
||||
#include <QSemaphore>
|
||||
#include <climits>
|
||||
|
||||
class DoricCountDownLatch {
|
||||
Q_DISABLE_COPY(DoricCountDownLatch)
|
||||
QSemaphore m_sem{INT_MAX};
|
||||
|
||||
public:
|
||||
DoricCountDownLatch() {}
|
||||
~DoricCountDownLatch() {
|
||||
m_sem.acquire(INT_MAX);
|
||||
m_sem.release(INT_MAX);
|
||||
}
|
||||
class Locker {
|
||||
DoricCountDownLatch *sem;
|
||||
|
||||
public:
|
||||
Locker(const Locker &other) : sem{other.sem} { sem->m_sem.acquire(); }
|
||||
Locker(Locker &&other) : sem{other.sem} { other.sem = nullptr; }
|
||||
Locker(DoricCountDownLatch *sem) : sem{sem} { sem->m_sem.acquire(); }
|
||||
~Locker() {
|
||||
if (sem)
|
||||
sem->m_sem.release();
|
||||
}
|
||||
};
|
||||
Locker lock() { return Locker{this}; }
|
||||
};
|
||||
|
||||
#endif // COUNTDOWNLATCH_H
|
68
doric-Qt/example/doric/utils/DoricDialogBridge.cpp
Normal file
68
doric-Qt/example/doric/utils/DoricDialogBridge.cpp
Normal file
@@ -0,0 +1,68 @@
|
||||
#include "DoricDialogBridge.h"
|
||||
#include "plugin/DoricModalPlugin.h"
|
||||
|
||||
#include <QQuickWindow>
|
||||
|
||||
DoricDialogBridge::DoricDialogBridge(QObject *parent) : QObject(parent) {}
|
||||
|
||||
void DoricDialogBridge::onAccepted(QString windowPointer, QString pluginPointer,
|
||||
QString callbackId) {
|
||||
{
|
||||
QObject *object = (QObject *)(windowPointer.toULongLong());
|
||||
QQuickWindow *window = dynamic_cast<QQuickWindow *>(object);
|
||||
window->deleteLater();
|
||||
}
|
||||
|
||||
{
|
||||
QObject *object = (QObject *)(pluginPointer.toULongLong());
|
||||
DoricModalPlugin *modalPlugin = dynamic_cast<DoricModalPlugin *>(object);
|
||||
modalPlugin->onAccepted(callbackId);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricDialogBridge::onRejected(QString windowPointer, QString pluginPointer,
|
||||
QString callbackId) {
|
||||
{
|
||||
QObject *object = (QObject *)(windowPointer.toULongLong());
|
||||
QQuickWindow *window = dynamic_cast<QQuickWindow *>(object);
|
||||
window->deleteLater();
|
||||
}
|
||||
|
||||
{
|
||||
QObject *object = (QObject *)(pluginPointer.toULongLong());
|
||||
DoricModalPlugin *modalPlugin = dynamic_cast<DoricModalPlugin *>(object);
|
||||
modalPlugin->onRejected(callbackId);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricDialogBridge::onAcceptedWithInput(QString windowPointer,
|
||||
QString pluginPointer,
|
||||
QString callbackId, QString input) {
|
||||
{
|
||||
QObject *object = (QObject *)(windowPointer.toULongLong());
|
||||
QQuickWindow *window = dynamic_cast<QQuickWindow *>(object);
|
||||
window->deleteLater();
|
||||
}
|
||||
|
||||
{
|
||||
QObject *object = (QObject *)(pluginPointer.toULongLong());
|
||||
DoricModalPlugin *modalPlugin = dynamic_cast<DoricModalPlugin *>(object);
|
||||
modalPlugin->onAcceptedWithInput(callbackId, input);
|
||||
}
|
||||
}
|
||||
|
||||
void DoricDialogBridge::onRejectedWithInput(QString windowPointer,
|
||||
QString pluginPointer,
|
||||
QString callbackId, QString input) {
|
||||
{
|
||||
QObject *object = (QObject *)(windowPointer.toULongLong());
|
||||
QQuickWindow *window = dynamic_cast<QQuickWindow *>(object);
|
||||
window->deleteLater();
|
||||
}
|
||||
|
||||
{
|
||||
QObject *object = (QObject *)(pluginPointer.toULongLong());
|
||||
DoricModalPlugin *modalPlugin = dynamic_cast<DoricModalPlugin *>(object);
|
||||
modalPlugin->onRejectedWithInput(callbackId, input);
|
||||
}
|
||||
}
|
28
doric-Qt/example/doric/utils/DoricDialogBridge.h
Normal file
28
doric-Qt/example/doric/utils/DoricDialogBridge.h
Normal file
@@ -0,0 +1,28 @@
|
||||
#ifndef DORICDIALOGBRIDGE_H
|
||||
#define DORICDIALOGBRIDGE_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
class DoricDialogBridge : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DoricDialogBridge(QObject *parent = nullptr);
|
||||
|
||||
Q_INVOKABLE
|
||||
void onAccepted(QString windowPointer, QString pluginPointer,
|
||||
QString callbackId);
|
||||
|
||||
Q_INVOKABLE
|
||||
void onAcceptedWithInput(QString windowPointer, QString pluginPointer,
|
||||
QString callbackId, QString input);
|
||||
|
||||
Q_INVOKABLE
|
||||
void onRejected(QString windowPointer, QString pluginPointer,
|
||||
QString callbackId);
|
||||
|
||||
Q_INVOKABLE
|
||||
void onRejectedWithInput(QString windowPointer, QString pluginPointer,
|
||||
QString callbackId, QString input);
|
||||
};
|
||||
|
||||
#endif // DORICDIALOGBRIDGE_H
|
20
doric-Qt/example/doric/utils/DoricImageBridge.cpp
Normal file
20
doric-Qt/example/doric/utils/DoricImageBridge.cpp
Normal file
@@ -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<DoricImageNode *>(object);
|
||||
imageNode->onReady();
|
||||
}
|
||||
|
||||
void DoricImageBridge::onLoading(QString pointer) {}
|
||||
|
||||
void DoricImageBridge::onError(QString pointer) {
|
||||
QObject *object = (QObject *)(pointer.toULongLong());
|
||||
DoricImageNode *imageNode = dynamic_cast<DoricImageNode *>(object);
|
||||
imageNode->onError();
|
||||
}
|
24
doric-Qt/example/doric/utils/DoricImageBridge.h
Normal file
24
doric-Qt/example/doric/utils/DoricImageBridge.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef DORICIMAGEBRIDGE_H
|
||||
#define DORICIMAGEBRIDGE_H
|
||||
|
||||
#include <QObject>
|
||||
|
||||
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
|
752
doric-Qt/example/doric/utils/DoricLayouts.cpp
Normal file
752
doric-Qt/example/doric/utils/DoricLayouts.cpp
Normal file
@@ -0,0 +1,752 @@
|
||||
#include "DoricLayouts.h"
|
||||
#include "shader/DoricScrollerNode.h"
|
||||
|
||||
DoricLayouts::DoricLayouts(QObject *parent) : QObject(parent) {
|
||||
this->widthSpec = DoricLayoutSpec::DoricLayoutJust;
|
||||
this->heightSpec = DoricLayoutSpec::DoricLayoutJust;
|
||||
|
||||
this->alignment = 0;
|
||||
this->gravity = 0;
|
||||
|
||||
this->width = 0;
|
||||
this->height = 0;
|
||||
|
||||
this->spacing = 0;
|
||||
|
||||
this->marginBottom = 0;
|
||||
this->marginTop = 0;
|
||||
this->marginLeft = 0;
|
||||
this->marginRight = 0;
|
||||
|
||||
this->paddingLeft = 0;
|
||||
this->paddingRight = 0;
|
||||
this->paddingBottom = 0;
|
||||
this->paddingTop = 0;
|
||||
|
||||
this->weight = 0;
|
||||
|
||||
this->layoutType = DoricLayoutType::DoricUndefined;
|
||||
|
||||
this->disabled = false;
|
||||
|
||||
this->maxWidth = INT_MAX;
|
||||
this->maxHeight = INT_MAX;
|
||||
this->minWidth = 0;
|
||||
this->minHeight = 0;
|
||||
|
||||
this->measuredWidth = 0;
|
||||
this->measuredHeight = 0;
|
||||
|
||||
this->measuredX = 0;
|
||||
this->measuredY = 0;
|
||||
|
||||
this->undefined = false;
|
||||
|
||||
this->contentWidth = 0;
|
||||
this->contentHeight = 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(qreal width) { this->width = width; }
|
||||
void DoricLayouts::setHeight(qreal height) { this->height = height; }
|
||||
|
||||
void DoricLayouts::setSpacing(qreal spacing) { this->spacing = spacing; }
|
||||
|
||||
void DoricLayouts::setMarginLeft(qreal marginLeft) {
|
||||
this->marginLeft = marginLeft;
|
||||
}
|
||||
void DoricLayouts::setMarginTop(qreal marginTop) {
|
||||
this->marginTop = marginTop;
|
||||
}
|
||||
void DoricLayouts::setMarginRight(qreal marginRight) {
|
||||
this->marginRight = marginRight;
|
||||
}
|
||||
void DoricLayouts::setMarginBottom(qreal marginBottom) {
|
||||
this->marginBottom = marginBottom;
|
||||
}
|
||||
|
||||
void DoricLayouts::setPaddingLeft(qreal paddingLeft) {
|
||||
this->paddingLeft = paddingLeft;
|
||||
}
|
||||
void DoricLayouts::setPaddingTop(qreal paddingTop) {
|
||||
this->paddingTop = paddingTop;
|
||||
}
|
||||
void DoricLayouts::setPaddingRight(qreal paddingRight) {
|
||||
this->paddingRight = paddingRight;
|
||||
}
|
||||
void DoricLayouts::setPaddingBottom(qreal paddingBottom) {
|
||||
this->paddingBottom = paddingBottom;
|
||||
}
|
||||
|
||||
void DoricLayouts::setWeight(int weight) { this->weight = weight; }
|
||||
|
||||
void DoricLayouts::setView(QQuickItem *view) {
|
||||
this->view = view;
|
||||
this->setParent(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(qreal maxWidth) { this->maxWidth = maxWidth; }
|
||||
void DoricLayouts::setMaxHeight(qreal maxHeight) {
|
||||
this->maxHeight = maxHeight;
|
||||
}
|
||||
void DoricLayouts::setMinWidth(qreal minWidth) { this->minWidth = minWidth; }
|
||||
void DoricLayouts::setMinHeight(qreal minHeight) {
|
||||
this->minHeight = minHeight;
|
||||
}
|
||||
|
||||
void DoricLayouts::apply(QSizeF frameSize) {
|
||||
this->resolved = false;
|
||||
|
||||
this->measure(frameSize);
|
||||
this->setFrame();
|
||||
|
||||
this->resolved = true;
|
||||
}
|
||||
|
||||
void DoricLayouts::apply() {
|
||||
this->apply(QSizeF(this->view->width(), this->view->height()));
|
||||
}
|
||||
|
||||
void DoricLayouts::measure(QSizeF targetSize) {
|
||||
this->measureSelf(targetSize);
|
||||
this->layout();
|
||||
}
|
||||
|
||||
void DoricLayouts::measureSelf(QSizeF targetSize) {
|
||||
// measure width
|
||||
qreal width;
|
||||
if (this->widthSpec == DoricLayoutSpec::DoricLayoutMost) {
|
||||
QQuickItem *parent = this->view->parentItem();
|
||||
if (parent == nullptr) {
|
||||
// incase parent is scroller
|
||||
width = targetSize.width();
|
||||
setMeasuredWidth(targetSize.width());
|
||||
} else {
|
||||
DoricLayouts *parentDoricLayout =
|
||||
(DoricLayouts *)(parent->property("doricLayout").toULongLong());
|
||||
if (parentDoricLayout != nullptr &&
|
||||
parentDoricLayout->layoutType == DoricLayoutType::DoricHLayout &&
|
||||
this->weight > 0) {
|
||||
width = 0;
|
||||
setMeasuredWidth(0);
|
||||
} else {
|
||||
width = targetSize.width();
|
||||
setMeasuredWidth(targetSize.width());
|
||||
}
|
||||
}
|
||||
} else if (this->widthSpec == DoricLayoutSpec::DoricLayoutJust) {
|
||||
width = this->width;
|
||||
setMeasuredWidth(this->width);
|
||||
} else {
|
||||
width = targetSize.width();
|
||||
}
|
||||
|
||||
// measure height
|
||||
qreal height;
|
||||
if (this->heightSpec == DoricLayoutSpec::DoricLayoutMost) {
|
||||
QQuickItem *parent = this->view->parentItem();
|
||||
if (parent == nullptr) {
|
||||
// incase parent is scroller
|
||||
height = targetSize.height();
|
||||
setMeasuredHeight(targetSize.height());
|
||||
} else {
|
||||
DoricLayouts *parentDoricLayout =
|
||||
(DoricLayouts *)(parent->property("doricLayout").toULongLong());
|
||||
if (parentDoricLayout != nullptr &&
|
||||
parentDoricLayout->layoutType == DoricLayoutType::DoricVLayout &&
|
||||
this->weight > 0) {
|
||||
height = 0;
|
||||
setMeasuredHeight(0);
|
||||
} else {
|
||||
height = targetSize.height();
|
||||
setMeasuredHeight(targetSize.height());
|
||||
}
|
||||
}
|
||||
|
||||
} else if (this->heightSpec == DoricLayoutSpec::DoricLayoutJust) {
|
||||
height = this->height;
|
||||
setMeasuredHeight(this->height);
|
||||
} else {
|
||||
height = targetSize.height();
|
||||
}
|
||||
|
||||
// measure content
|
||||
this->measureContent(QSizeF(width - this->paddingLeft - this->paddingRight,
|
||||
height - this->paddingTop - this->paddingBottom));
|
||||
|
||||
if (this->restrainSize()) {
|
||||
this->measureContent(
|
||||
QSizeF(this->measuredWidth - this->paddingLeft - this->paddingRight,
|
||||
this->measuredHeight - this->paddingTop - this->paddingBottom));
|
||||
}
|
||||
this->restrainSize();
|
||||
}
|
||||
|
||||
void DoricLayouts::measureContent(QSizeF targetSize) {
|
||||
qCritical() << "measureContent: " << tag << this->view->property("uuid");
|
||||
switch (this->layoutType) {
|
||||
case DoricLayoutType::DoricStack: {
|
||||
this->measureStackContent(targetSize);
|
||||
break;
|
||||
}
|
||||
case DoricLayoutType::DoricVLayout: {
|
||||
this->measureVLayoutContent(targetSize);
|
||||
break;
|
||||
}
|
||||
case DoricLayoutType::DoricHLayout: {
|
||||
this->measureHLayoutContent(targetSize);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
this->measureUndefinedContent(targetSize);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
QQuickItem *parent = this->view->parentItem();
|
||||
if (parent != nullptr) {
|
||||
DoricLayouts *parentDoricLayout =
|
||||
(DoricLayouts *)(parent->property("doricLayout").toULongLong());
|
||||
if (parentDoricLayout != nullptr) {
|
||||
if (parentDoricLayout->layoutType != DoricLayoutType::DoricUndefined &&
|
||||
parentDoricLayout->widthSpec == DoricLayoutSpec::DoricLayoutFit &&
|
||||
this->widthSpec == DoricLayoutSpec::DoricLayoutMost) {
|
||||
setMeasuredWidth(targetSize.width());
|
||||
}
|
||||
if (parentDoricLayout->layoutType != DoricLayoutType::DoricUndefined &&
|
||||
parentDoricLayout->heightSpec == DoricLayoutSpec::DoricLayoutFit &&
|
||||
this->heightSpec == DoricLayoutSpec::DoricLayoutMost) {
|
||||
setMeasuredHeight(targetSize.height());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DoricLayouts::measureUndefinedContent(QSizeF targetSize) {
|
||||
// begin size that fits
|
||||
QSizeF measuredSize;
|
||||
|
||||
if (tag == "Scroller") {
|
||||
QObject *object =
|
||||
(QObject *)(this->view->property("wrapper").toULongLong());
|
||||
DoricScrollerNode *viewNode = dynamic_cast<DoricScrollerNode *>(object);
|
||||
measuredSize = viewNode->sizeThatFits(targetSize);
|
||||
} else {
|
||||
qreal actualWidth = this->view->width();
|
||||
qreal actualHeight = this->view->height();
|
||||
|
||||
measuredSize = QSizeF(actualWidth, actualHeight);
|
||||
}
|
||||
// end size that fits
|
||||
|
||||
if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) {
|
||||
setMeasuredWidth(measuredSize.width() + this->paddingLeft +
|
||||
this->paddingRight);
|
||||
}
|
||||
if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit) {
|
||||
setMeasuredHeight(measuredSize.height() + this->paddingTop +
|
||||
this->paddingBottom);
|
||||
}
|
||||
}
|
||||
void DoricLayouts::measureStackContent(QSizeF targetSize) {
|
||||
qreal 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;
|
||||
}
|
||||
|
||||
layout->measure(layout->removeMargin(targetSize));
|
||||
contentWidth = qMax(contentWidth, layout->takenWidth());
|
||||
contentHeight = qMax(contentHeight, layout->takenHeight());
|
||||
}
|
||||
if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) {
|
||||
setMeasuredWidth(contentWidth + this->paddingLeft + this->paddingRight);
|
||||
}
|
||||
|
||||
if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit) {
|
||||
setMeasuredHeight(contentHeight + this->paddingTop + this->paddingBottom);
|
||||
}
|
||||
|
||||
this->contentWidth = contentWidth;
|
||||
this->contentHeight = contentHeight;
|
||||
}
|
||||
void DoricLayouts::measureVLayoutContent(QSizeF targetSize) {
|
||||
qreal 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;
|
||||
|
||||
layout->measure(layout->removeMargin(
|
||||
QSizeF(targetSize.width(), targetSize.height() - contentHeight)));
|
||||
contentWidth = qMax(contentWidth, layout->takenWidth());
|
||||
contentHeight += layout->takenHeight() + this->spacing;
|
||||
contentWeight += layout->weight;
|
||||
}
|
||||
|
||||
if (had) {
|
||||
contentHeight -= this->spacing;
|
||||
}
|
||||
|
||||
if (contentWeight > 0) {
|
||||
qreal remaining = targetSize.height() - contentHeight;
|
||||
contentWidth = 0;
|
||||
foreach (QQuickItem *subview, this->view->childItems()) {
|
||||
DoricLayouts *layout =
|
||||
(DoricLayouts *)(subview->property("doricLayout").toULongLong());
|
||||
if (layout == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layout->disabled) {
|
||||
continue;
|
||||
}
|
||||
qreal measuredHeight =
|
||||
layout->measuredHeight + remaining / contentWeight * layout->weight;
|
||||
layout->measuredHeight = measuredHeight;
|
||||
// Need Remeasure
|
||||
layout->measureContent(QSizeF(
|
||||
layout->measuredWidth - layout->paddingLeft - layout->paddingRight,
|
||||
measuredHeight - layout->paddingTop - layout->paddingBottom));
|
||||
layout->measuredHeight = measuredHeight;
|
||||
contentWidth = qMax(contentWidth, layout->takenWidth());
|
||||
}
|
||||
contentHeight = targetSize.height();
|
||||
}
|
||||
|
||||
if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) {
|
||||
setMeasuredWidth(contentWidth + this->paddingLeft + this->paddingRight);
|
||||
}
|
||||
|
||||
if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit) {
|
||||
setMeasuredHeight(contentHeight + this->paddingTop + this->paddingBottom);
|
||||
}
|
||||
|
||||
this->contentWidth = contentWidth;
|
||||
this->contentHeight = contentHeight;
|
||||
}
|
||||
void DoricLayouts::measureHLayoutContent(QSizeF targetSize) {
|
||||
qreal 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;
|
||||
|
||||
layout->measure(layout->removeMargin(
|
||||
QSizeF(targetSize.width() - contentWidth, targetSize.height())));
|
||||
contentWidth += layout->takenWidth() + this->spacing;
|
||||
contentHeight = qMax(contentHeight, layout->takenHeight());
|
||||
contentWeight += layout->weight;
|
||||
}
|
||||
|
||||
if (had) {
|
||||
contentWidth -= this->spacing;
|
||||
}
|
||||
|
||||
if (contentWeight > 0) {
|
||||
qreal remaining = targetSize.width() - contentWidth;
|
||||
contentHeight = 0;
|
||||
foreach (QQuickItem *subview, this->view->childItems()) {
|
||||
DoricLayouts *layout =
|
||||
(DoricLayouts *)(subview->property("doricLayout").toULongLong());
|
||||
if (layout == nullptr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (layout->disabled) {
|
||||
continue;
|
||||
}
|
||||
qreal measuredWidth =
|
||||
layout->measuredWidth + remaining / contentWeight * layout->weight;
|
||||
layout->measuredWidth = measuredWidth;
|
||||
// Need Remeasure
|
||||
layout->measureContent(QSizeF(
|
||||
measuredWidth - layout->paddingLeft - layout->paddingRight,
|
||||
layout->measuredHeight - layout->paddingTop - layout->paddingBottom));
|
||||
layout->measuredWidth = measuredWidth;
|
||||
contentHeight = qMax(contentHeight, layout->takenHeight());
|
||||
}
|
||||
contentWidth = targetSize.width();
|
||||
}
|
||||
|
||||
if (this->widthSpec == DoricLayoutSpec::DoricLayoutFit) {
|
||||
setMeasuredWidth(contentWidth + this->paddingLeft + this->paddingRight);
|
||||
}
|
||||
|
||||
if (this->heightSpec == DoricLayoutSpec::DoricLayoutFit) {
|
||||
setMeasuredHeight(contentHeight + this->paddingTop + this->paddingBottom);
|
||||
}
|
||||
|
||||
this->contentWidth = contentWidth;
|
||||
this->contentHeight = contentHeight;
|
||||
}
|
||||
|
||||
qreal DoricLayouts::takenWidth() {
|
||||
return this->measuredWidth + this->marginLeft + this->marginRight;
|
||||
}
|
||||
qreal DoricLayouts::takenHeight() {
|
||||
return this->measuredHeight + this->marginTop + this->marginBottom;
|
||||
}
|
||||
QSizeF DoricLayouts::removeMargin(QSizeF targetSize) {
|
||||
return QSizeF(targetSize.width() - this->marginLeft - this->marginRight,
|
||||
targetSize.height() - this->marginTop - this->marginBottom);
|
||||
}
|
||||
|
||||
bool DoricLayouts::restrainSize() {
|
||||
bool needRemeasure = false;
|
||||
if (this->measuredWidth > this->maxWidth) {
|
||||
setMeasuredWidth(this->maxWidth);
|
||||
needRemeasure = true;
|
||||
}
|
||||
if (this->measuredHeight > this->maxHeight) {
|
||||
setMeasuredHeight(this->maxHeight);
|
||||
needRemeasure = true;
|
||||
}
|
||||
if (this->measuredWidth < this->minWidth) {
|
||||
setMeasuredWidth(this->minWidth);
|
||||
needRemeasure = true;
|
||||
}
|
||||
if (this->measuredHeight < this->minHeight) {
|
||||
setMeasuredHeight(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();
|
||||
}
|
||||
}
|
||||
|
||||
qCritical() << "DoricLayouts setProperty: " << tag
|
||||
<< this->view->property("uuid")
|
||||
<< " measuredWidth: " << this->measuredWidth
|
||||
<< " measuredHeight: " << this->measuredHeight
|
||||
<< " width: " << this->view->width()
|
||||
<< " height: " << this->view->height()
|
||||
<< " measuredX: " << this->measuredX
|
||||
<< " measuredY: " << this->measuredY;
|
||||
|
||||
if (qAbs(this->measuredWidth - this->view->width()) >= 0.00001f)
|
||||
this->view->setProperty("width", this->measuredWidth);
|
||||
if (qAbs(this->measuredHeight - this->view->height()) >= 0.00001f)
|
||||
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->setMeasuredX(this->paddingLeft);
|
||||
} else if ((gravity & DoricGravity::DoricGravityRight) ==
|
||||
DoricGravity::DoricGravityRight) {
|
||||
layout->setMeasuredX(this->measuredWidth - this->paddingRight -
|
||||
layout->measuredWidth);
|
||||
} else if ((gravity & DoricGravity::DoricGravityCenterX) ==
|
||||
DoricGravity::DoricGravityCenterX) {
|
||||
layout->setMeasuredX(this->measuredWidth / 2 - layout->measuredWidth / 2);
|
||||
} else {
|
||||
if (layout->marginLeft || layout->marginRight) {
|
||||
layout->setMeasuredX(this->paddingLeft);
|
||||
} else {
|
||||
layout->setMeasuredX(0);
|
||||
}
|
||||
}
|
||||
|
||||
if ((gravity & DoricGravity::DoricGravityTop) ==
|
||||
DoricGravity::DoricGravityTop) {
|
||||
layout->setMeasuredY(this->paddingTop);
|
||||
} else if ((gravity & DoricGravity::DoricGravityBottom) ==
|
||||
DoricGravity::DoricGravityBottom) {
|
||||
layout->setMeasuredY(this->measuredHeight - this->paddingBottom -
|
||||
layout->measuredHeight);
|
||||
} else if ((gravity & DoricGravity::DoricGravityCenterY) ==
|
||||
DoricGravity::DoricGravityCenterY) {
|
||||
layout->setMeasuredY(this->measuredHeight / 2 -
|
||||
layout->measuredHeight / 2);
|
||||
} else {
|
||||
if (layout->marginTop || layout->marginBottom) {
|
||||
layout->setMeasuredY(this->paddingTop);
|
||||
} else {
|
||||
layout->setMeasuredY(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() {
|
||||
qreal 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->setMeasuredX(this->paddingLeft);
|
||||
} else if ((gravity & DoricGravity::DoricGravityRight) ==
|
||||
DoricGravity::DoricGravityRight) {
|
||||
layout->setMeasuredX(this->measuredWidth - this->paddingRight -
|
||||
layout->measuredWidth);
|
||||
} else if ((gravity & DoricGravity::DoricGravityCenterX) ==
|
||||
DoricGravity::DoricGravityCenterX) {
|
||||
layout->setMeasuredX(this->measuredWidth / 2 - layout->measuredWidth / 2);
|
||||
} else {
|
||||
layout->setMeasuredX(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->setMeasuredY(yStart + layout->marginTop);
|
||||
yStart += this->spacing + layout->takenHeight();
|
||||
}
|
||||
}
|
||||
|
||||
void DoricLayouts::layoutHLayout() {
|
||||
qreal 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->setMeasuredY(this->paddingTop);
|
||||
} else if ((gravity & DoricGravity::DoricGravityBottom) ==
|
||||
DoricGravity::DoricGravityBottom) {
|
||||
layout->setMeasuredY(this->measuredHeight - this->paddingBottom -
|
||||
layout->measuredHeight);
|
||||
} else if ((gravity & DoricGravity::DoricGravityCenterY) ==
|
||||
DoricGravity::DoricGravityCenterY) {
|
||||
layout->setMeasuredY(this->measuredHeight / 2 -
|
||||
layout->measuredHeight / 2);
|
||||
} else {
|
||||
layout->setMeasuredY(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->setMeasuredX(xStart + layout->marginLeft);
|
||||
xStart += this->spacing + layout->takenWidth();
|
||||
}
|
||||
}
|
||||
|
||||
// Private Section
|
||||
void DoricLayouts::setMeasuredWidth(qreal measuredWidth) {
|
||||
this->measuredWidth = measuredWidth;
|
||||
qCritical() << "DoricLayouts: " << tag << this->view->property("uuid")
|
||||
<< " measuredWidth: " << this->measuredWidth;
|
||||
}
|
||||
|
||||
qreal DoricLayouts::getMeasuredWidth() { return this->measuredWidth; }
|
||||
|
||||
void DoricLayouts::setMeasuredHeight(qreal measuredHeight) {
|
||||
this->measuredHeight = measuredHeight;
|
||||
qCritical() << "DoricLayouts: " << tag << this->view->property("uuid")
|
||||
<< " measuredHeight: " << this->measuredHeight;
|
||||
}
|
||||
|
||||
qreal DoricLayouts::getMeasuredHeight() { return this->measuredHeight; }
|
||||
|
||||
void DoricLayouts::setMeasuredX(qreal measuredX) {
|
||||
this->measuredX = measuredX;
|
||||
qCritical() << "DoricLayouts: " << tag << this->view->property("uuid")
|
||||
<< " measuredX: " << this->measuredX;
|
||||
}
|
||||
|
||||
void DoricLayouts::setMeasuredY(qreal measuredY) {
|
||||
this->measuredY = measuredY;
|
||||
qCritical() << "DoricLayouts: " << tag << this->view->property("uuid")
|
||||
<< " measuredY: " << this->measuredY;
|
||||
}
|
171
doric-Qt/example/doric/utils/DoricLayouts.h
Normal file
171
doric-Qt/example/doric/utils/DoricLayouts.h
Normal file
@@ -0,0 +1,171 @@
|
||||
#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 QObject {
|
||||
public:
|
||||
explicit DoricLayouts(QObject *parent = nullptr);
|
||||
|
||||
void setWidthSpec(int widthSpec);
|
||||
void setHeightSpec(int heightSpec);
|
||||
|
||||
void setAlignment(int alignment);
|
||||
|
||||
void setGravity(int gravity);
|
||||
|
||||
void setWidth(qreal width);
|
||||
void setHeight(qreal height);
|
||||
|
||||
void setSpacing(qreal spacing);
|
||||
|
||||
void setMarginLeft(qreal marginLeft);
|
||||
void setMarginTop(qreal marginTop);
|
||||
void setMarginRight(qreal marginRight);
|
||||
void setMarginBottom(qreal marginBottom);
|
||||
|
||||
void setPaddingLeft(qreal paddingLeft);
|
||||
void setPaddingTop(qreal paddingTop);
|
||||
void setPaddingRight(qreal paddingRight);
|
||||
void setPaddingBottom(qreal paddingBottom);
|
||||
|
||||
void setWeight(int weight);
|
||||
|
||||
void setView(QQuickItem *view);
|
||||
|
||||
void setLayoutType(int layoutType);
|
||||
|
||||
void setDisabled(bool disabled);
|
||||
|
||||
void setMaxWidth(qreal maxWidth);
|
||||
void setMaxHeight(qreal maxHeight);
|
||||
void setMinWidth(qreal minWidth);
|
||||
void setMinHeight(qreal minHeight);
|
||||
|
||||
void apply(QSizeF frameSize);
|
||||
|
||||
void apply();
|
||||
|
||||
qreal getMeasuredWidth();
|
||||
qreal getMeasuredHeight();
|
||||
|
||||
private:
|
||||
QString tag;
|
||||
|
||||
int widthSpec;
|
||||
int heightSpec;
|
||||
|
||||
int alignment;
|
||||
|
||||
int gravity;
|
||||
|
||||
qreal width;
|
||||
qreal height;
|
||||
|
||||
qreal spacing;
|
||||
|
||||
qreal marginLeft;
|
||||
qreal marginTop;
|
||||
qreal marginRight;
|
||||
qreal marginBottom;
|
||||
|
||||
qreal paddingLeft;
|
||||
qreal paddingTop;
|
||||
qreal paddingRight;
|
||||
qreal paddingBottom;
|
||||
|
||||
int weight;
|
||||
|
||||
QQuickItem *view;
|
||||
|
||||
int layoutType;
|
||||
|
||||
bool disabled;
|
||||
|
||||
qreal maxWidth;
|
||||
qreal maxHeight;
|
||||
qreal minWidth;
|
||||
qreal minHeight;
|
||||
|
||||
bool resolved;
|
||||
|
||||
qreal measuredWidth;
|
||||
void setMeasuredWidth(qreal measuredWidth);
|
||||
qreal measuredHeight;
|
||||
void setMeasuredHeight(qreal measuredHeight);
|
||||
qreal measuredX;
|
||||
void setMeasuredX(qreal measuredX);
|
||||
qreal measuredY;
|
||||
void setMeasuredY(qreal measuredY);
|
||||
|
||||
bool undefined;
|
||||
|
||||
//
|
||||
qreal contentWidth;
|
||||
qreal contentHeight;
|
||||
|
||||
void measure(QSizeF targetSize);
|
||||
|
||||
void measureSelf(QSizeF targetSize);
|
||||
|
||||
void measureContent(QSizeF targetSize);
|
||||
|
||||
void measureUndefinedContent(QSizeF targetSize);
|
||||
void measureStackContent(QSizeF targetSize);
|
||||
void measureVLayoutContent(QSizeF targetSize);
|
||||
void measureHLayoutContent(QSizeF targetSize);
|
||||
|
||||
qreal takenWidth();
|
||||
qreal takenHeight();
|
||||
QSizeF removeMargin(QSizeF targetSize);
|
||||
|
||||
bool restrainSize();
|
||||
|
||||
void layout();
|
||||
|
||||
void layoutStack();
|
||||
void layoutVLayout();
|
||||
void layoutHLayout();
|
||||
|
||||
void setFrame();
|
||||
};
|
||||
|
||||
#endif // DORICLAYOUTS_H
|
10
doric-Qt/example/doric/utils/DoricMouseAreaBridge.cpp
Normal file
10
doric-Qt/example/doric/utils/DoricMouseAreaBridge.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "DoricMouseAreaBridge.h"
|
||||
#include "shader/DoricViewNode.h"
|
||||
|
||||
DoricMouseAreaBridge::DoricMouseAreaBridge(QObject *parent) : QObject(parent) {}
|
||||
|
||||
void DoricMouseAreaBridge::onClick(QString pointer) {
|
||||
QObject *object = (QObject *)(pointer.toULongLong());
|
||||
DoricViewNode *viewNode = dynamic_cast<DoricViewNode *>(object);
|
||||
viewNode->onClick();
|
||||
}
|
17
doric-Qt/example/doric/utils/DoricMouseAreaBridge.h
Normal file
17
doric-Qt/example/doric/utils/DoricMouseAreaBridge.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef DORICMOUSEAREABRIDGE_H
|
||||
#define DORICMOUSEAREABRIDGE_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QVariant>
|
||||
|
||||
class DoricMouseAreaBridge : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit DoricMouseAreaBridge(QObject *parent = nullptr);
|
||||
|
||||
Q_INVOKABLE
|
||||
void onClick(QString pointer);
|
||||
signals:
|
||||
};
|
||||
|
||||
#endif // DORICMOUSEAREABRIDGE_H
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user