mirror of
https://gitlab.com/eql/EQL5.git
synced 2026-01-30 12:22:36 -08:00
"quick": get rid of JS glue code (now done in Qt/C++, better and safer); only drawback is "Lisp.call()" max. argument limit (currently 16, but could be extended);
This commit is contained in:
parent
763040a437
commit
5403e5db46
22 changed files with 494 additions and 104 deletions
|
|
@ -30,15 +30,17 @@ Examples:
|
|||
QML FILES
|
||||
=========
|
||||
|
||||
Always add these 2 "import" lines for Lisp access:
|
||||
The only "import" needed is:
|
||||
|
||||
import EQL5 1.0
|
||||
import "qrc:///eql5.js" as Lisp
|
||||
|
||||
The "eql5.js" file is compiled as a resource into the eql5 shared library,
|
||||
see "eql5/src/eql5.js" and "eql5/src/eql5.qrc".
|
||||
which provides all of:
|
||||
|
||||
To reload the QML file after changes, do:
|
||||
Lisp.call()
|
||||
Lisp.apply()
|
||||
PaintedItem
|
||||
|
||||
To reload the QML source file after changes, do:
|
||||
|
||||
(qml:reload)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,15 +10,102 @@ static QObject* lisp_provider(QQmlEngine*, QJSEngine*) { return lisp; }
|
|||
QObject* ini() {
|
||||
if(!lisp) {
|
||||
lisp = new Lisp;
|
||||
qmlRegisterSingletonType<Lisp>("EQL5", 1, 0, "EQL5", lisp_provider);
|
||||
qmlRegisterSingletonType<Lisp>("EQL5", 1, 0, "Lisp", lisp_provider);
|
||||
qmlRegisterType<PaintedItem>("EQL5", 1, 0, "PaintedItem"); }
|
||||
return lisp; }
|
||||
|
||||
QVariant Lisp::apply(QObject* caller, const QString& function, const QVariantList& arguments) {
|
||||
return eql_fun("qml:qml-apply", QVariant::String,
|
||||
Q_ARG(QObject*, caller),
|
||||
Q_ARG(QString, function),
|
||||
Q_ARG(QVariantList, arguments)); }
|
||||
static QQmlContext* rootContext() {
|
||||
QVariant var = eql_fun("qml:root-context", QMetaType::VoidStar);
|
||||
return Q_PTR(QQmlContext*, var); }
|
||||
|
||||
static QVariant qmlApply(QObject* caller, const QString& function, const QVariantList& arguments) {
|
||||
QVariant var =
|
||||
eql_fun("qml:qml-apply", QVariant::String,
|
||||
Q_ARG(QObject*, caller),
|
||||
Q_ARG(QString, function),
|
||||
Q_ARG(QVariantList, arguments));
|
||||
if(var.type() == QVariant::String) {
|
||||
QString str(var.toString());
|
||||
if(str.startsWith("#<>")) { // prepared in Lisp for JS eval
|
||||
QQmlExpression exp(rootContext(), caller, str.mid(3));
|
||||
return exp.evaluate(); }}
|
||||
return var; }
|
||||
|
||||
QVariant Lisp::call(const QJSValue& caller_or_function, const QJSValue& function_or_arg0,
|
||||
const QJSValue& arg1,
|
||||
const QJSValue& arg2,
|
||||
const QJSValue& arg3,
|
||||
const QJSValue& arg4,
|
||||
const QJSValue& arg5,
|
||||
const QJSValue& arg6,
|
||||
const QJSValue& arg7,
|
||||
const QJSValue& arg8,
|
||||
const QJSValue& arg9,
|
||||
const QJSValue& arg10,
|
||||
const QJSValue& arg11,
|
||||
const QJSValue& arg12,
|
||||
const QJSValue& arg13,
|
||||
const QJSValue& arg14,
|
||||
const QJSValue& arg15,
|
||||
const QJSValue& arg16) {
|
||||
QObject* caller = 0;
|
||||
QString function;
|
||||
QVariantList arguments;
|
||||
if(caller_or_function.isQObject()) {
|
||||
caller = caller_or_function.toQObject();
|
||||
function = function_or_arg0.toString(); }
|
||||
else if(caller_or_function.isString()) {
|
||||
function = caller_or_function.toString();
|
||||
if(!function_or_arg0.isUndefined()) {
|
||||
arguments << function_or_arg0.toVariant(); }}
|
||||
if(!arg1.isUndefined()) {
|
||||
arguments << arg1.toVariant();
|
||||
if(!arg2.isUndefined()) {
|
||||
arguments << arg2.toVariant();
|
||||
if(!arg3.isUndefined()) {
|
||||
arguments << arg3.toVariant();
|
||||
if(!arg4.isUndefined()) {
|
||||
arguments << arg4.toVariant();
|
||||
if(!arg5.isUndefined()) {
|
||||
arguments << arg5.toVariant();
|
||||
if(!arg6.isUndefined()) {
|
||||
arguments << arg6.toVariant();
|
||||
if(!arg7.isUndefined()) {
|
||||
arguments << arg7.toVariant();
|
||||
if(!arg8.isUndefined()) {
|
||||
arguments << arg8.toVariant();
|
||||
if(!arg9.isUndefined()) {
|
||||
arguments << arg9.toVariant();
|
||||
if(!arg10.isUndefined()) {
|
||||
arguments << arg10.toVariant();
|
||||
if(!arg11.isUndefined()) {
|
||||
arguments << arg11.toVariant();
|
||||
if(!arg12.isUndefined()) {
|
||||
arguments << arg12.toVariant();
|
||||
if(!arg13.isUndefined()) {
|
||||
arguments << arg13.toVariant();
|
||||
if(!arg14.isUndefined()) {
|
||||
arguments << arg14.toVariant();
|
||||
if(!arg15.isUndefined()) {
|
||||
arguments << arg15.toVariant();
|
||||
if(!arg16.isUndefined()) {
|
||||
arguments << arg16.toVariant(); }}}}}}}}}}}}}}}}
|
||||
return qmlApply(caller, function, arguments); }
|
||||
|
||||
QVariant Lisp::apply(const QJSValue& caller_or_function,
|
||||
const QJSValue& function_or_arguments,
|
||||
const QJSValue& arguments_or_undefined) {
|
||||
QObject* caller = 0;
|
||||
QString function;
|
||||
QVariantList arguments;
|
||||
if(caller_or_function.isQObject()) {
|
||||
caller = caller_or_function.toQObject();
|
||||
function = function_or_arguments.toString();
|
||||
arguments = arguments_or_undefined.toVariant().value<QVariantList>(); }
|
||||
else if(caller_or_function.isString()) {
|
||||
function = caller_or_function.toString();
|
||||
arguments = function_or_arguments.toVariant().value<QVariantList>(); }
|
||||
return qmlApply(caller, function, arguments); }
|
||||
|
||||
void PaintedItem::paint(QPainter* painter) {
|
||||
eql_fun("qml:paint",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,26 @@ class Lisp : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE QVariant apply(QObject*, const QString&, const QVariantList& = QVariantList());
|
||||
Q_INVOKABLE QVariant call(const QJSValue&,
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue());
|
||||
|
||||
Q_INVOKABLE QVariant apply(const QJSValue&, const QJSValue& = QJSValue(), const QJSValue& = QJSValue());
|
||||
};
|
||||
|
||||
class PaintedItem : public QQuickPaintedItem {
|
||||
|
|
@ -30,8 +49,6 @@ public:
|
|||
void paint(QPainter*);
|
||||
};
|
||||
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@
|
|||
#:js
|
||||
#:qml-get
|
||||
#:qml-set
|
||||
#:paint
|
||||
#:reload
|
||||
#:root-context
|
||||
#:root-item))
|
||||
|
||||
(provide :qml-lisp)
|
||||
|
|
@ -81,6 +83,10 @@
|
|||
(when *quick-view*
|
||||
(|rootObject| *quick-view*)))
|
||||
|
||||
(defun root-context ()
|
||||
(when *quick-view*
|
||||
(|rootContext| *quick-view*)))
|
||||
|
||||
(defun find-quick-item (object-name)
|
||||
"Finds the first QQuickItem matching OBJECT-NAME."
|
||||
(if (string= (|objectName| (root-item)) object-name)
|
||||
|
|
@ -131,7 +137,7 @@
|
|||
(defun js (item/name js-format-string &rest arguments)
|
||||
"Evaluates a JS string, with 'this' bound to either ITEM, or first object matching NAME. Arguments are passed through FORMAT."
|
||||
(qlet ((qml-exp "QQmlExpression(QQmlContext*,QObject*,QString)"
|
||||
(|rootContext| *quick-view*)
|
||||
(root-context)
|
||||
(quick-item item/name)
|
||||
(apply 'format nil js-format-string arguments))
|
||||
(variant (|evaluate| qml-exp)))
|
||||
|
|
|
|||
|
|
@ -2,9 +2,7 @@
|
|||
|
||||
import QtQuick 2.0
|
||||
import "ext"
|
||||
|
||||
import EQL5 1.0
|
||||
import "qrc:eql5.js" as Lisp
|
||||
|
||||
Rectangle {
|
||||
id: game
|
||||
|
|
|
|||
|
|
@ -10,15 +10,102 @@ static QObject* lisp_provider(QQmlEngine*, QJSEngine*) { return lisp; }
|
|||
QObject* ini() {
|
||||
if(!lisp) {
|
||||
lisp = new Lisp;
|
||||
qmlRegisterSingletonType<Lisp>("EQL5", 1, 0, "EQL5", lisp_provider);
|
||||
qmlRegisterSingletonType<Lisp>("EQL5", 1, 0, "Lisp", lisp_provider);
|
||||
qmlRegisterType<PaintedItem>("EQL5", 1, 0, "PaintedItem"); }
|
||||
return lisp; }
|
||||
|
||||
QVariant Lisp::apply(QObject* caller, const QString& function, const QVariantList& arguments) {
|
||||
return eql_fun("qml:qml-apply", QVariant::String,
|
||||
Q_ARG(QObject*, caller),
|
||||
Q_ARG(QString, function),
|
||||
Q_ARG(QVariantList, arguments)); }
|
||||
static QQmlContext* rootContext() {
|
||||
QVariant var = eql_fun("qml:root-context", QMetaType::VoidStar);
|
||||
return Q_PTR(QQmlContext*, var); }
|
||||
|
||||
static QVariant qmlApply(QObject* caller, const QString& function, const QVariantList& arguments) {
|
||||
QVariant var =
|
||||
eql_fun("qml:qml-apply", QVariant::String,
|
||||
Q_ARG(QObject*, caller),
|
||||
Q_ARG(QString, function),
|
||||
Q_ARG(QVariantList, arguments));
|
||||
if(var.type() == QVariant::String) {
|
||||
QString str(var.toString());
|
||||
if(str.startsWith("#<>")) { // prepared in Lisp for JS eval
|
||||
QQmlExpression exp(rootContext(), caller, str.mid(3));
|
||||
return exp.evaluate(); }}
|
||||
return var; }
|
||||
|
||||
QVariant Lisp::call(const QJSValue& caller_or_function, const QJSValue& function_or_arg0,
|
||||
const QJSValue& arg1,
|
||||
const QJSValue& arg2,
|
||||
const QJSValue& arg3,
|
||||
const QJSValue& arg4,
|
||||
const QJSValue& arg5,
|
||||
const QJSValue& arg6,
|
||||
const QJSValue& arg7,
|
||||
const QJSValue& arg8,
|
||||
const QJSValue& arg9,
|
||||
const QJSValue& arg10,
|
||||
const QJSValue& arg11,
|
||||
const QJSValue& arg12,
|
||||
const QJSValue& arg13,
|
||||
const QJSValue& arg14,
|
||||
const QJSValue& arg15,
|
||||
const QJSValue& arg16) {
|
||||
QObject* caller = 0;
|
||||
QString function;
|
||||
QVariantList arguments;
|
||||
if(caller_or_function.isQObject()) {
|
||||
caller = caller_or_function.toQObject();
|
||||
function = function_or_arg0.toString(); }
|
||||
else if(caller_or_function.isString()) {
|
||||
function = caller_or_function.toString();
|
||||
if(!function_or_arg0.isUndefined()) {
|
||||
arguments << function_or_arg0.toVariant(); }}
|
||||
if(!arg1.isUndefined()) {
|
||||
arguments << arg1.toVariant();
|
||||
if(!arg2.isUndefined()) {
|
||||
arguments << arg2.toVariant();
|
||||
if(!arg3.isUndefined()) {
|
||||
arguments << arg3.toVariant();
|
||||
if(!arg4.isUndefined()) {
|
||||
arguments << arg4.toVariant();
|
||||
if(!arg5.isUndefined()) {
|
||||
arguments << arg5.toVariant();
|
||||
if(!arg6.isUndefined()) {
|
||||
arguments << arg6.toVariant();
|
||||
if(!arg7.isUndefined()) {
|
||||
arguments << arg7.toVariant();
|
||||
if(!arg8.isUndefined()) {
|
||||
arguments << arg8.toVariant();
|
||||
if(!arg9.isUndefined()) {
|
||||
arguments << arg9.toVariant();
|
||||
if(!arg10.isUndefined()) {
|
||||
arguments << arg10.toVariant();
|
||||
if(!arg11.isUndefined()) {
|
||||
arguments << arg11.toVariant();
|
||||
if(!arg12.isUndefined()) {
|
||||
arguments << arg12.toVariant();
|
||||
if(!arg13.isUndefined()) {
|
||||
arguments << arg13.toVariant();
|
||||
if(!arg14.isUndefined()) {
|
||||
arguments << arg14.toVariant();
|
||||
if(!arg15.isUndefined()) {
|
||||
arguments << arg15.toVariant();
|
||||
if(!arg16.isUndefined()) {
|
||||
arguments << arg16.toVariant(); }}}}}}}}}}}}}}}}
|
||||
return qmlApply(caller, function, arguments); }
|
||||
|
||||
QVariant Lisp::apply(const QJSValue& caller_or_function,
|
||||
const QJSValue& function_or_arguments,
|
||||
const QJSValue& arguments_or_undefined) {
|
||||
QObject* caller = 0;
|
||||
QString function;
|
||||
QVariantList arguments;
|
||||
if(caller_or_function.isQObject()) {
|
||||
caller = caller_or_function.toQObject();
|
||||
function = function_or_arguments.toString();
|
||||
arguments = arguments_or_undefined.toVariant().value<QVariantList>(); }
|
||||
else if(caller_or_function.isString()) {
|
||||
function = caller_or_function.toString();
|
||||
arguments = function_or_arguments.toVariant().value<QVariantList>(); }
|
||||
return qmlApply(caller, function, arguments); }
|
||||
|
||||
void PaintedItem::paint(QPainter* painter) {
|
||||
eql_fun("qml:paint",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,26 @@ class Lisp : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE QVariant apply(QObject*, const QString&, const QVariantList& = QVariantList());
|
||||
Q_INVOKABLE QVariant call(const QJSValue&,
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue());
|
||||
|
||||
Q_INVOKABLE QVariant apply(const QJSValue&, const QJSValue& = QJSValue(), const QJSValue& = QJSValue());
|
||||
};
|
||||
|
||||
class PaintedItem : public QQuickPaintedItem {
|
||||
|
|
@ -30,8 +49,6 @@ public:
|
|||
void paint(QPainter*);
|
||||
};
|
||||
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@
|
|||
#:js
|
||||
#:qml-get
|
||||
#:qml-set
|
||||
#:paint
|
||||
#:reload
|
||||
#:root-context
|
||||
#:root-item))
|
||||
|
||||
(provide :qml-lisp)
|
||||
|
|
@ -81,6 +83,10 @@
|
|||
(when *quick-view*
|
||||
(|rootObject| *quick-view*)))
|
||||
|
||||
(defun root-context ()
|
||||
(when *quick-view*
|
||||
(|rootContext| *quick-view*)))
|
||||
|
||||
(defun find-quick-item (object-name)
|
||||
"Finds the first QQuickItem matching OBJECT-NAME."
|
||||
(if (string= (|objectName| (root-item)) object-name)
|
||||
|
|
@ -131,7 +137,7 @@
|
|||
(defun js (item/name js-format-string &rest arguments)
|
||||
"Evaluates a JS string, with 'this' bound to either ITEM, or first object matching NAME. Arguments are passed through FORMAT."
|
||||
(qlet ((qml-exp "QQmlExpression(QQmlContext*,QObject*,QString)"
|
||||
(|rootContext| *quick-view*)
|
||||
(root-context)
|
||||
(quick-item item/name)
|
||||
(apply 'format nil js-format-string arguments))
|
||||
(variant (|evaluate| qml-exp)))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
import EQL5 1.0
|
||||
import "qrc:eql5.js" as Lisp
|
||||
|
||||
ListView {
|
||||
x: 5; y: 5; width: 200; height: 250
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
import EQL5 1.0
|
||||
import "qrc:///eql5.js" as Lisp
|
||||
|
||||
ListView {
|
||||
x: 5; y: 5; width: 150; height: 250
|
||||
|
|
|
|||
|
|
@ -10,15 +10,102 @@ static QObject* lisp_provider(QQmlEngine*, QJSEngine*) { return lisp; }
|
|||
QObject* ini() {
|
||||
if(!lisp) {
|
||||
lisp = new Lisp;
|
||||
qmlRegisterSingletonType<Lisp>("EQL5", 1, 0, "EQL5", lisp_provider);
|
||||
qmlRegisterSingletonType<Lisp>("EQL5", 1, 0, "Lisp", lisp_provider);
|
||||
qmlRegisterType<PaintedItem>("EQL5", 1, 0, "PaintedItem"); }
|
||||
return lisp; }
|
||||
|
||||
QVariant Lisp::apply(QObject* caller, const QString& function, const QVariantList& arguments) {
|
||||
return eql_fun("qml:qml-apply", QVariant::String,
|
||||
Q_ARG(QObject*, caller),
|
||||
Q_ARG(QString, function),
|
||||
Q_ARG(QVariantList, arguments)); }
|
||||
static QQmlContext* rootContext() {
|
||||
QVariant var = eql_fun("qml:root-context", QMetaType::VoidStar);
|
||||
return Q_PTR(QQmlContext*, var); }
|
||||
|
||||
static QVariant qmlApply(QObject* caller, const QString& function, const QVariantList& arguments) {
|
||||
QVariant var =
|
||||
eql_fun("qml:qml-apply", QVariant::String,
|
||||
Q_ARG(QObject*, caller),
|
||||
Q_ARG(QString, function),
|
||||
Q_ARG(QVariantList, arguments));
|
||||
if(var.type() == QVariant::String) {
|
||||
QString str(var.toString());
|
||||
if(str.startsWith("#<>")) { // prepared in Lisp for JS eval
|
||||
QQmlExpression exp(rootContext(), caller, str.mid(3));
|
||||
return exp.evaluate(); }}
|
||||
return var; }
|
||||
|
||||
QVariant Lisp::call(const QJSValue& caller_or_function, const QJSValue& function_or_arg0,
|
||||
const QJSValue& arg1,
|
||||
const QJSValue& arg2,
|
||||
const QJSValue& arg3,
|
||||
const QJSValue& arg4,
|
||||
const QJSValue& arg5,
|
||||
const QJSValue& arg6,
|
||||
const QJSValue& arg7,
|
||||
const QJSValue& arg8,
|
||||
const QJSValue& arg9,
|
||||
const QJSValue& arg10,
|
||||
const QJSValue& arg11,
|
||||
const QJSValue& arg12,
|
||||
const QJSValue& arg13,
|
||||
const QJSValue& arg14,
|
||||
const QJSValue& arg15,
|
||||
const QJSValue& arg16) {
|
||||
QObject* caller = 0;
|
||||
QString function;
|
||||
QVariantList arguments;
|
||||
if(caller_or_function.isQObject()) {
|
||||
caller = caller_or_function.toQObject();
|
||||
function = function_or_arg0.toString(); }
|
||||
else if(caller_or_function.isString()) {
|
||||
function = caller_or_function.toString();
|
||||
if(!function_or_arg0.isUndefined()) {
|
||||
arguments << function_or_arg0.toVariant(); }}
|
||||
if(!arg1.isUndefined()) {
|
||||
arguments << arg1.toVariant();
|
||||
if(!arg2.isUndefined()) {
|
||||
arguments << arg2.toVariant();
|
||||
if(!arg3.isUndefined()) {
|
||||
arguments << arg3.toVariant();
|
||||
if(!arg4.isUndefined()) {
|
||||
arguments << arg4.toVariant();
|
||||
if(!arg5.isUndefined()) {
|
||||
arguments << arg5.toVariant();
|
||||
if(!arg6.isUndefined()) {
|
||||
arguments << arg6.toVariant();
|
||||
if(!arg7.isUndefined()) {
|
||||
arguments << arg7.toVariant();
|
||||
if(!arg8.isUndefined()) {
|
||||
arguments << arg8.toVariant();
|
||||
if(!arg9.isUndefined()) {
|
||||
arguments << arg9.toVariant();
|
||||
if(!arg10.isUndefined()) {
|
||||
arguments << arg10.toVariant();
|
||||
if(!arg11.isUndefined()) {
|
||||
arguments << arg11.toVariant();
|
||||
if(!arg12.isUndefined()) {
|
||||
arguments << arg12.toVariant();
|
||||
if(!arg13.isUndefined()) {
|
||||
arguments << arg13.toVariant();
|
||||
if(!arg14.isUndefined()) {
|
||||
arguments << arg14.toVariant();
|
||||
if(!arg15.isUndefined()) {
|
||||
arguments << arg15.toVariant();
|
||||
if(!arg16.isUndefined()) {
|
||||
arguments << arg16.toVariant(); }}}}}}}}}}}}}}}}
|
||||
return qmlApply(caller, function, arguments); }
|
||||
|
||||
QVariant Lisp::apply(const QJSValue& caller_or_function,
|
||||
const QJSValue& function_or_arguments,
|
||||
const QJSValue& arguments_or_undefined) {
|
||||
QObject* caller = 0;
|
||||
QString function;
|
||||
QVariantList arguments;
|
||||
if(caller_or_function.isQObject()) {
|
||||
caller = caller_or_function.toQObject();
|
||||
function = function_or_arguments.toString();
|
||||
arguments = arguments_or_undefined.toVariant().value<QVariantList>(); }
|
||||
else if(caller_or_function.isString()) {
|
||||
function = caller_or_function.toString();
|
||||
arguments = function_or_arguments.toVariant().value<QVariantList>(); }
|
||||
return qmlApply(caller, function, arguments); }
|
||||
|
||||
void PaintedItem::paint(QPainter* painter) {
|
||||
eql_fun("qml:paint",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,26 @@ class Lisp : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE QVariant apply(QObject*, const QString&, const QVariantList& = QVariantList());
|
||||
Q_INVOKABLE QVariant call(const QJSValue&,
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue());
|
||||
|
||||
Q_INVOKABLE QVariant apply(const QJSValue&, const QJSValue& = QJSValue(), const QJSValue& = QJSValue());
|
||||
};
|
||||
|
||||
class PaintedItem : public QQuickPaintedItem {
|
||||
|
|
@ -30,8 +49,6 @@ public:
|
|||
void paint(QPainter*);
|
||||
};
|
||||
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -14,10 +14,11 @@
|
|||
#:children
|
||||
#:find-quick-item
|
||||
#:js
|
||||
#:paint
|
||||
#:qml-get
|
||||
#:qml-set
|
||||
#:paint
|
||||
#:reload
|
||||
#:root-context
|
||||
#:root-item))
|
||||
|
||||
(provide :qml-lisp)
|
||||
|
|
@ -82,6 +83,10 @@
|
|||
(when *quick-view*
|
||||
(|rootObject| *quick-view*)))
|
||||
|
||||
(defun root-context ()
|
||||
(when *quick-view*
|
||||
(|rootContext| *quick-view*)))
|
||||
|
||||
(defun find-quick-item (object-name)
|
||||
"Finds the first QQuickItem matching OBJECT-NAME."
|
||||
(if (string= (|objectName| (root-item)) object-name)
|
||||
|
|
@ -132,7 +137,7 @@
|
|||
(defun js (item/name js-format-string &rest arguments)
|
||||
"Evaluates a JS string, with 'this' bound to either ITEM, or first object matching NAME. Arguments are passed through FORMAT."
|
||||
(qlet ((qml-exp "QQmlExpression(QQmlContext*,QObject*,QString)"
|
||||
(|rootContext| *quick-view*)
|
||||
(root-context)
|
||||
(quick-item item/name)
|
||||
(apply 'format nil js-format-string arguments))
|
||||
(variant (|evaluate| qml-exp)))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
import EQL5 1.0
|
||||
import "qrc:eql5.js" as Lisp
|
||||
|
||||
Rectangle {
|
||||
color: "gray"
|
||||
|
|
|
|||
|
|
@ -42,15 +42,17 @@ Examples:
|
|||
QML FILES
|
||||
=========
|
||||
|
||||
Always add these 2 "import" lines for Lisp access:
|
||||
The only "import" needed is:
|
||||
|
||||
import EQL5 1.0
|
||||
import "qrc:///eql5.js" as Lisp
|
||||
|
||||
The "eql5.js" file is compiled as a resource into the eql5 shared library,
|
||||
see "eql5/src/eql5.js" and "eql5/src/eql5.qrc".
|
||||
which provides all of:
|
||||
|
||||
To reload the QML file after changes, do:
|
||||
Lisp.call()
|
||||
Lisp.apply()
|
||||
PaintedItem
|
||||
|
||||
To reload the QML source file after changes, do:
|
||||
|
||||
(qml:reload)
|
||||
|
||||
|
|
|
|||
|
|
@ -10,15 +10,102 @@ static QObject* lisp_provider(QQmlEngine*, QJSEngine*) { return lisp; }
|
|||
QObject* ini() {
|
||||
if(!lisp) {
|
||||
lisp = new Lisp;
|
||||
qmlRegisterSingletonType<Lisp>("EQL5", 1, 0, "EQL5", lisp_provider);
|
||||
qmlRegisterSingletonType<Lisp>("EQL5", 1, 0, "Lisp", lisp_provider);
|
||||
qmlRegisterType<PaintedItem>("EQL5", 1, 0, "PaintedItem"); }
|
||||
return lisp; }
|
||||
|
||||
QVariant Lisp::apply(QObject* caller, const QString& function, const QVariantList& arguments) {
|
||||
return eql_fun("qml:qml-apply", QVariant::String,
|
||||
Q_ARG(QObject*, caller),
|
||||
Q_ARG(QString, function),
|
||||
Q_ARG(QVariantList, arguments)); }
|
||||
static QQmlContext* rootContext() {
|
||||
QVariant var = eql_fun("qml:root-context", QMetaType::VoidStar);
|
||||
return Q_PTR(QQmlContext*, var); }
|
||||
|
||||
static QVariant qmlApply(QObject* caller, const QString& function, const QVariantList& arguments) {
|
||||
QVariant var =
|
||||
eql_fun("qml:qml-apply", QVariant::String,
|
||||
Q_ARG(QObject*, caller),
|
||||
Q_ARG(QString, function),
|
||||
Q_ARG(QVariantList, arguments));
|
||||
if(var.type() == QVariant::String) {
|
||||
QString str(var.toString());
|
||||
if(str.startsWith("#<>")) { // prepared in Lisp for JS eval
|
||||
QQmlExpression exp(rootContext(), caller, str.mid(3));
|
||||
return exp.evaluate(); }}
|
||||
return var; }
|
||||
|
||||
QVariant Lisp::call(const QJSValue& caller_or_function, const QJSValue& function_or_arg0,
|
||||
const QJSValue& arg1,
|
||||
const QJSValue& arg2,
|
||||
const QJSValue& arg3,
|
||||
const QJSValue& arg4,
|
||||
const QJSValue& arg5,
|
||||
const QJSValue& arg6,
|
||||
const QJSValue& arg7,
|
||||
const QJSValue& arg8,
|
||||
const QJSValue& arg9,
|
||||
const QJSValue& arg10,
|
||||
const QJSValue& arg11,
|
||||
const QJSValue& arg12,
|
||||
const QJSValue& arg13,
|
||||
const QJSValue& arg14,
|
||||
const QJSValue& arg15,
|
||||
const QJSValue& arg16) {
|
||||
QObject* caller = 0;
|
||||
QString function;
|
||||
QVariantList arguments;
|
||||
if(caller_or_function.isQObject()) {
|
||||
caller = caller_or_function.toQObject();
|
||||
function = function_or_arg0.toString(); }
|
||||
else if(caller_or_function.isString()) {
|
||||
function = caller_or_function.toString();
|
||||
if(!function_or_arg0.isUndefined()) {
|
||||
arguments << function_or_arg0.toVariant(); }}
|
||||
if(!arg1.isUndefined()) {
|
||||
arguments << arg1.toVariant();
|
||||
if(!arg2.isUndefined()) {
|
||||
arguments << arg2.toVariant();
|
||||
if(!arg3.isUndefined()) {
|
||||
arguments << arg3.toVariant();
|
||||
if(!arg4.isUndefined()) {
|
||||
arguments << arg4.toVariant();
|
||||
if(!arg5.isUndefined()) {
|
||||
arguments << arg5.toVariant();
|
||||
if(!arg6.isUndefined()) {
|
||||
arguments << arg6.toVariant();
|
||||
if(!arg7.isUndefined()) {
|
||||
arguments << arg7.toVariant();
|
||||
if(!arg8.isUndefined()) {
|
||||
arguments << arg8.toVariant();
|
||||
if(!arg9.isUndefined()) {
|
||||
arguments << arg9.toVariant();
|
||||
if(!arg10.isUndefined()) {
|
||||
arguments << arg10.toVariant();
|
||||
if(!arg11.isUndefined()) {
|
||||
arguments << arg11.toVariant();
|
||||
if(!arg12.isUndefined()) {
|
||||
arguments << arg12.toVariant();
|
||||
if(!arg13.isUndefined()) {
|
||||
arguments << arg13.toVariant();
|
||||
if(!arg14.isUndefined()) {
|
||||
arguments << arg14.toVariant();
|
||||
if(!arg15.isUndefined()) {
|
||||
arguments << arg15.toVariant();
|
||||
if(!arg16.isUndefined()) {
|
||||
arguments << arg16.toVariant(); }}}}}}}}}}}}}}}}
|
||||
return qmlApply(caller, function, arguments); }
|
||||
|
||||
QVariant Lisp::apply(const QJSValue& caller_or_function,
|
||||
const QJSValue& function_or_arguments,
|
||||
const QJSValue& arguments_or_undefined) {
|
||||
QObject* caller = 0;
|
||||
QString function;
|
||||
QVariantList arguments;
|
||||
if(caller_or_function.isQObject()) {
|
||||
caller = caller_or_function.toQObject();
|
||||
function = function_or_arguments.toString();
|
||||
arguments = arguments_or_undefined.toVariant().value<QVariantList>(); }
|
||||
else if(caller_or_function.isString()) {
|
||||
function = caller_or_function.toString();
|
||||
arguments = function_or_arguments.toVariant().value<QVariantList>(); }
|
||||
return qmlApply(caller, function, arguments); }
|
||||
|
||||
void PaintedItem::paint(QPainter* painter) {
|
||||
eql_fun("qml:paint",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,26 @@ class Lisp : public QObject {
|
|||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Q_INVOKABLE QVariant apply(QObject*, const QString&, const QVariantList& = QVariantList());
|
||||
Q_INVOKABLE QVariant call(const QJSValue&,
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue(),
|
||||
const QJSValue& = QJSValue());
|
||||
|
||||
Q_INVOKABLE QVariant apply(const QJSValue&, const QJSValue& = QJSValue(), const QJSValue& = QJSValue());
|
||||
};
|
||||
|
||||
class PaintedItem : public QQuickPaintedItem {
|
||||
|
|
@ -30,8 +49,6 @@ public:
|
|||
void paint(QPainter*);
|
||||
};
|
||||
|
||||
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -16,7 +16,9 @@
|
|||
#:js
|
||||
#:qml-get
|
||||
#:qml-set
|
||||
#:paint
|
||||
#:reload
|
||||
#:root-context
|
||||
#:root-item))
|
||||
|
||||
(provide :qml-lisp)
|
||||
|
|
@ -81,6 +83,10 @@
|
|||
(when *quick-view*
|
||||
(|rootObject| *quick-view*)))
|
||||
|
||||
(defun root-context ()
|
||||
(when *quick-view*
|
||||
(|rootContext| *quick-view*)))
|
||||
|
||||
(defun find-quick-item (object-name)
|
||||
"Finds the first QQuickItem matching OBJECT-NAME."
|
||||
(if (string= (|objectName| (root-item)) object-name)
|
||||
|
|
@ -131,7 +137,7 @@
|
|||
(defun js (item/name js-format-string &rest arguments)
|
||||
"Evaluates a JS string, with 'this' bound to either ITEM, or first object matching NAME. Arguments are passed through FORMAT."
|
||||
(qlet ((qml-exp "QQmlExpression(QQmlContext*,QObject*,QString)"
|
||||
(|rootContext| *quick-view*)
|
||||
(root-context)
|
||||
(quick-item item/name)
|
||||
(apply 'format nil js-format-string arguments))
|
||||
(variant (|evaluate| qml-exp)))
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
import EQL5 1.0
|
||||
import "qrc:eql5.js" as Lisp
|
||||
|
||||
Item {
|
||||
id: root
|
||||
|
|
|
|||
36
src/eql5.js
36
src/eql5.js
|
|
@ -1,36 +0,0 @@
|
|||
function checkEval(arg) {
|
||||
// prepared in Lisp for JS evaluation
|
||||
if((typeof(arg) == "string") && (arg.substr(0, 3) == "#<>")) {
|
||||
return eval(arg.substr(3)); }
|
||||
return arg; }
|
||||
|
||||
function call() {
|
||||
// accepts any number of arguments (no way to achieve the same in Qt/C++)
|
||||
var caller, name, args;
|
||||
var start = 1;
|
||||
var arg1 = arguments[0];
|
||||
if(typeof(arg1) == "object") { // 'this'
|
||||
caller = arg1;
|
||||
name = arguments[1];
|
||||
start++; }
|
||||
else if(typeof(arg1) == "string") {
|
||||
name = arg1; }
|
||||
if(arguments.length > start) {
|
||||
var len = arguments.length - start;
|
||||
args = new Array(len);
|
||||
for(var i = 0; i < len; i++) {
|
||||
args[i] = arguments[i + start]; }}
|
||||
if(undefined != caller) {
|
||||
return apply(caller, name, args); }
|
||||
return apply(name, args); }
|
||||
|
||||
function apply(arg1, arg2, arg3) {
|
||||
var caller, name, args;
|
||||
if(typeof(arg1) == "object") { // 'this'
|
||||
caller = arg1;
|
||||
name = arg2;
|
||||
args = arg3; }
|
||||
else if(typeof(arg1) == "string") {
|
||||
name = arg1;
|
||||
args = arg2; }
|
||||
return checkEval(EQL5.apply(caller, name, args)); }
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
<!DOCTYPE RCC><RCC version="1.0">
|
||||
<qresource>
|
||||
<file>eql5.js</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
@ -32,8 +32,6 @@ SOURCES += gen/_lobjects.cpp \
|
|||
extras.cpp \
|
||||
eql.cpp
|
||||
|
||||
RESOURCES = eql5.qrc
|
||||
|
||||
gcc {
|
||||
QMAKE_CXXFLAGS_WARN_ON += -Wno-clobbered
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue