mirror of
https://gitlab.com/eql/EQL5.git
synced 2026-01-30 12:22:36 -08:00
"qml-lisp": allow for nested lists, vectors etc. as return values from QML function calls; some revisions;
This commit is contained in:
parent
4cb7bfcfbf
commit
f290094824
10 changed files with 119 additions and 25 deletions
|
|
@ -12,3 +12,13 @@ For Emacs/Slime, this would be:
|
|||
|
||||
eql5 ~/slime/eql-start-swank.lisp tic-tac-toe
|
||||
|
||||
|
||||
NOTES
|
||||
=====
|
||||
|
||||
Try the following:
|
||||
|
||||
(qml-set "game" "difficulty" 8) ; one of: 2, 8, 10
|
||||
|
||||
Since the logic of the buttons is defined in the QML file, changes to
|
||||
properties will be reflected immediately by the UI.
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
// helper functions for convenient QML/EQL5 integration
|
||||
|
||||
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 fun(name, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
|
||||
var args = [];
|
||||
if(undefined != arg1) args.push(arg1); {
|
||||
|
|
@ -11,8 +17,8 @@ function fun(name, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
|
|||
if(undefined != arg7) args.push(arg7); {
|
||||
if(undefined != arg8) args.push(arg8); {
|
||||
if(undefined != arg9) args.push(arg9); }}}}}}}}
|
||||
return EQL5.apply(name, args); }
|
||||
return checkEval(EQL5.apply(name, args)); }
|
||||
|
||||
function apply(name, args) {
|
||||
return EQL5.apply(name, args); }
|
||||
return checkEval(EQL5.apply(name, args)); }
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ QVariant Lisp::apply(const QString& function, const QVariantList& arguments) {
|
|||
eql_fun("qml:qml-apply", QVariant::String,
|
||||
Q_ARG(QString, function),
|
||||
Q_ARG(QVariantList, arguments));
|
||||
if(ret.toString() == "NIL") {
|
||||
ret = QVariant(); }
|
||||
return ret; }
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -34,13 +34,44 @@
|
|||
|
||||
;;; function calls from QML
|
||||
|
||||
(defun print-js-readably (object)
|
||||
"Prints lists, vectors, T, NIL, floats in JS notation, which will be passed to JS 'eval()'."
|
||||
(if (and (not (stringp object))
|
||||
(vectorp object))
|
||||
(print-js-readably (coerce object 'list))
|
||||
(typecase object
|
||||
(cons
|
||||
(write-char #\[)
|
||||
(do ((list object (rest list)))
|
||||
((null list) (write-char #\]))
|
||||
(print-js-readably (first list))
|
||||
(when (rest list)
|
||||
(write-char #\,))))
|
||||
(float
|
||||
;; cut off Lisp specific notations
|
||||
(princ (string-right-trim "dl0" (princ-to-string object))))
|
||||
(t
|
||||
(cond ((eql 't object)
|
||||
(princ "true"))
|
||||
((eql 'nil object)
|
||||
(princ "false"))
|
||||
(t
|
||||
(prin1 object)))))))
|
||||
|
||||
(defun print-to-js-string (object)
|
||||
(with-output-to-string (*standard-output*)
|
||||
(princ "#<>") ; mark for passing to JS "eval()"
|
||||
(print-js-readably object)))
|
||||
|
||||
(defun qml-apply (function arguments)
|
||||
"Every 'Lisp.fun()' or 'Lisp.apply()' function call in QML will call this function."
|
||||
(let ((value (apply (string-to-symbol function)
|
||||
(let ((object (apply (string-to-symbol function)
|
||||
arguments)))
|
||||
(if (stringp value)
|
||||
value
|
||||
(princ-to-string value))))
|
||||
(if (stringp object)
|
||||
object
|
||||
(print-to-js-string object))))
|
||||
|
||||
;;; utils
|
||||
|
||||
(let (root-object)
|
||||
(defun root-object ()
|
||||
|
|
|
|||
|
|
@ -18,22 +18,30 @@ You can access any QML property from Lisp (needs 'objectName' to be set).
|
|||
|
||||
Examples:
|
||||
|
||||
(in-package :qml)
|
||||
|
||||
;; single object
|
||||
(qml:qml-get "label" "text")
|
||||
(qml:qml-set "label" "text" "hi!")
|
||||
(qml:qml-set "label" "color" "red")
|
||||
(qml-get "label" "text")
|
||||
(qml-set "label" "text" "hi!")
|
||||
(qml-set "label" "color" "red")
|
||||
|
||||
;; all objects matching 'objectName'
|
||||
(qml:qml-get* "label" "text")
|
||||
(qml:qml-set* "label" "text" "")
|
||||
(qml-get* "label" "text")
|
||||
(qml-set* "label" "text" "")
|
||||
|
||||
|
||||
NOTES
|
||||
=====
|
||||
|
||||
Please see also the documentation in "qml/example.qml".
|
||||
|
||||
|
||||
TIP
|
||||
===
|
||||
|
||||
In order to have uniform access to QML objects from both JS and Lisp
|
||||
functions, it's convenient to set both 'id:' and 'objectName:' to the same
|
||||
name.
|
||||
functions, it is convenient to set both 'id:' and 'objectName:' to the
|
||||
same name.
|
||||
|
||||
QML Example:
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,11 @@
|
|||
// helper functions for convenient QML/EQL5 integration
|
||||
|
||||
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 fun(name, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
|
||||
var args = [];
|
||||
if(undefined != arg1) args.push(arg1); {
|
||||
|
|
@ -11,8 +17,8 @@ function fun(name, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9) {
|
|||
if(undefined != arg7) args.push(arg7); {
|
||||
if(undefined != arg8) args.push(arg8); {
|
||||
if(undefined != arg9) args.push(arg9); }}}}}}}}
|
||||
return EQL5.apply(name, args); }
|
||||
return checkEval(EQL5.apply(name, args)); }
|
||||
|
||||
function apply(name, args) {
|
||||
return EQL5.apply(name, args); }
|
||||
return checkEval(EQL5.apply(name, args)); }
|
||||
|
||||
|
|
|
|||
|
|
@ -18,8 +18,6 @@ QVariant Lisp::apply(const QString& function, const QVariantList& arguments) {
|
|||
eql_fun("qml:qml-apply", QVariant::String,
|
||||
Q_ARG(QString, function),
|
||||
Q_ARG(QVariantList, arguments));
|
||||
if(ret.toString() == "NIL") {
|
||||
ret = QVariant(); }
|
||||
return ret; }
|
||||
|
||||
QT_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -34,13 +34,44 @@
|
|||
|
||||
;;; function calls from QML
|
||||
|
||||
(defun print-js-readably (object)
|
||||
"Prints lists, vectors, T, NIL, floats in JS notation, which will be passed to JS 'eval()'."
|
||||
(if (and (not (stringp object))
|
||||
(vectorp object))
|
||||
(print-js-readably (coerce object 'list))
|
||||
(typecase object
|
||||
(cons
|
||||
(write-char #\[)
|
||||
(do ((list object (rest list)))
|
||||
((null list) (write-char #\]))
|
||||
(print-js-readably (first list))
|
||||
(when (rest list)
|
||||
(write-char #\,))))
|
||||
(float
|
||||
;; cut off Lisp specific notations
|
||||
(princ (string-right-trim "dl0" (princ-to-string object))))
|
||||
(t
|
||||
(cond ((eql 't object)
|
||||
(princ "true"))
|
||||
((eql 'nil object)
|
||||
(princ "false"))
|
||||
(t
|
||||
(prin1 object)))))))
|
||||
|
||||
(defun print-to-js-string (object)
|
||||
(with-output-to-string (*standard-output*)
|
||||
(princ "#<>") ; mark for passing to JS "eval()"
|
||||
(print-js-readably object)))
|
||||
|
||||
(defun qml-apply (function arguments)
|
||||
"Every 'Lisp.fun()' or 'Lisp.apply()' function call in QML will call this function."
|
||||
(let ((value (apply (string-to-symbol function)
|
||||
(let ((object (apply (string-to-symbol function)
|
||||
arguments)))
|
||||
(if (stringp value)
|
||||
value
|
||||
(princ-to-string value))))
|
||||
(if (stringp object)
|
||||
object
|
||||
(print-to-js-string object))))
|
||||
|
||||
;;; utils
|
||||
|
||||
(let (root-object)
|
||||
(defun root-object ()
|
||||
|
|
|
|||
|
|
@ -10,7 +10,11 @@ Item {
|
|||
Component.onCompleted: {
|
||||
|
||||
// Please note:
|
||||
// Lisp.fun() is limited to 9 arguments; use Lisp.apply() for more arguments.
|
||||
//
|
||||
// * Lisp.fun() is limited to 9 arguments; use Lisp.apply() for more arguments
|
||||
//
|
||||
// * return values can be nested Lisp lists or vectors, which will be converted to
|
||||
// nested JS arrays: they will be prepared in Lisp and passed to JS eval
|
||||
|
||||
// (1) call CL function
|
||||
console.log(Lisp.fun("format", false, "~R", 123))
|
||||
|
|
@ -22,6 +26,8 @@ Item {
|
|||
console.log(Lisp.fun("x:join", ["11", "55"], ":"))
|
||||
|
||||
// (4) nested list arguments; note Lisp.apply() for any number of arguments
|
||||
// N.B: don't get fooled by the printed representation of the return value:
|
||||
// it's a nested JS array internally
|
||||
console.log(Lisp.apply("list", [[[1, 2, 3], ["a", "b", "c"], 4, 5], 6, [[7, 8], 9]]))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -226,7 +226,7 @@
|
|||
(! "name" obj))
|
||||
((search name "QDate QTime QDateTime QFont QUrl QKeySequence")
|
||||
(! "toString" obj))
|
||||
((search name "QPixmap QImage QPicture QIcon QTextCursor QVariant QMargins QWebElement")
|
||||
((search name "QPixmap QImage QPicture QIcon QBitmap QDate QDateTime QTime QTextCursor QVariant QMargins QSqlQuery QWebElement")
|
||||
(if (and (not (zerop (qt-object-pointer obj)))
|
||||
(! "isNull" obj))
|
||||
(null-qt-object obj)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue