mirror of
https://gitlab.com/eql/EQL5.git
synced 2025-12-20 17:10:54 -08:00
add examples in "quick/item-model"; lots of minor revisions;
This commit is contained in:
parent
d773093dbd
commit
376b7caed4
55 changed files with 3410 additions and 3006 deletions
139
examples/M-modules/quick/item-model/qml-lisp.lisp
Normal file
139
examples/M-modules/quick/item-model/qml-lisp.lisp
Normal file
|
|
@ -0,0 +1,139 @@
|
|||
;;;
|
||||
;;; * enables QML to call Lisp functions
|
||||
;;; * allows to get/set any QML property from Lisp (needs 'objectName' to be set)
|
||||
;;; * allows to evaluate JS code from Lisp (needs 'objectName' to be set)
|
||||
;;;
|
||||
;;; (requires a C++ plugin, see "lib/")
|
||||
|
||||
(defpackage :qml-lisp
|
||||
(:use :common-lisp :eql)
|
||||
(:nicknames :qml)
|
||||
(:export
|
||||
#:*quick-view*
|
||||
#:*caller*
|
||||
#:children
|
||||
#:find-quick-item
|
||||
#:js
|
||||
#:qml-get
|
||||
#:qml-set
|
||||
#:reload
|
||||
#:root-item))
|
||||
|
||||
(provide :qml-lisp)
|
||||
|
||||
(in-package :qml-lisp)
|
||||
|
||||
(defvar *qml-lisp* (qload-c++ "lib/qml_lisp"))
|
||||
(defvar *caller* nil)
|
||||
(defvar *quick-view* nil)
|
||||
|
||||
(defun string-to-symbol (name)
|
||||
(let ((upper (string-upcase name))
|
||||
(p (position #\: name)))
|
||||
(if p
|
||||
(find-symbol (subseq upper (1+ (position #\: name :from-end t)))
|
||||
(subseq upper 0 p))
|
||||
(find-symbol upper))))
|
||||
|
||||
;;; function calls from QML
|
||||
|
||||
(defun print-js-readably (object)
|
||||
"Prints (nested) 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 (caller function arguments)
|
||||
"Every 'Lisp.call()' or 'Lisp.apply()' function call in QML will call this function. The variable *CALLER* will be bound to the calling QQuickItem, if passed with 'this' as first argument to 'Lisp.call()' / 'Lisp.apply()'."
|
||||
(let* ((*caller* (if (qnull caller) nil (qt-object-? caller)))
|
||||
(object (apply (string-to-symbol function)
|
||||
arguments)))
|
||||
(if (stringp object)
|
||||
object
|
||||
(print-to-js-string object))))
|
||||
|
||||
;;; utils
|
||||
|
||||
(defun root-item ()
|
||||
(when *quick-view*
|
||||
(|rootObject| *quick-view*)))
|
||||
|
||||
(defun find-quick-item (object-name)
|
||||
"Finds the first QQuickItem matching OBJECT-NAME."
|
||||
(if (string= (|objectName| (root-item)) object-name)
|
||||
(root-item)
|
||||
(qt-object-? (qfind-child (root-item) object-name))))
|
||||
|
||||
(defun quick-item (item/name)
|
||||
(cond ((stringp item/name)
|
||||
(find-quick-item item/name))
|
||||
((qt-object-p item/name)
|
||||
item/name)
|
||||
((not item/name)
|
||||
(root-item))))
|
||||
|
||||
(defun children (item/name)
|
||||
(|childItems| (quick-item item/name)))
|
||||
|
||||
(defun reload ()
|
||||
"Force reloading of QML file after changes made to it."
|
||||
(|clearComponentCache| (|engine| *quick-view*))
|
||||
(|setSource| *quick-view* (|source| *quick-view*)))
|
||||
|
||||
;;; get/set QQmlProperty
|
||||
|
||||
(defun qml-get (item/name property-name)
|
||||
"Gets QQmlProperty of either ITEM or first object matching NAME."
|
||||
(qlet ((property "QQmlProperty(QObject*,QString)"
|
||||
(quick-item item/name)
|
||||
property-name))
|
||||
(if (|isValid| property)
|
||||
(qlet ((variant (|read| property)))
|
||||
(values (qvariant-value variant)
|
||||
t))
|
||||
(eql::%error-msg "QML-GET" (list item/name property-name)))))
|
||||
|
||||
(defun qml-set (item/name property-name value)
|
||||
"Sets QQmlProperty of either ITEM, or first object matching NAME. Returns T on success."
|
||||
(qlet ((property "QQmlProperty(QObject*,QString)"
|
||||
(quick-item item/name)
|
||||
property-name))
|
||||
(if (|isValid| property)
|
||||
(qlet ((variant (qvariant-from-value value (|propertyTypeName| property))))
|
||||
(|write| property variant))
|
||||
(eql::%error-msg "QML-SET" (list item/name property-name value)))))
|
||||
|
||||
;;; JS
|
||||
|
||||
(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*)
|
||||
(quick-item item/name)
|
||||
(apply 'format nil js-format-string arguments))
|
||||
(variant (|evaluate| qml-exp)))
|
||||
(qvariant-value variant)))
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue