add convenience function '(eql:qml)' for auto generating vars according to QML item's 'objectName'; bump version number;
This commit is contained in:
parent
97feac95d4
commit
ca22ff0254
17 changed files with 176 additions and 15 deletions
|
|
@ -354,6 +354,11 @@ Converts a Unicode pathname to a simple ECL base string, using <code>QString::to
|
|||
Convenience function: a simple message box, converting <code>x</code> to a string if necessary.<br>Returns its argument (just like <code>print</code>).
|
||||
<br>
|
||||
<br><br>
|
||||
<b>QML ()</b>
|
||||
<br><br>
|
||||
Generates global variables for all QML items with <code>objectName</code> set. Requires the QML app to be running. Will show an error message if <code>objectName</code> is not unique.
|
||||
<br>
|
||||
<br><br>
|
||||
<b>QNEW-INSTANCE (class-name &rest arguments/properties)</b>
|
||||
<br>
|
||||
<b>QNEW</b>
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
(defparameter *help* nil)
|
||||
|
||||
(defun add-cpp-docu ()
|
||||
(with-open-file (s (eql:in-home "src/ecl_fun.cpp") :direction :input)
|
||||
(with-open-file (s "../src/ecl_fun.cpp" :direction :input)
|
||||
(let (curr ex)
|
||||
(flet ((add-curr ()
|
||||
(when curr
|
||||
|
|
@ -45,7 +45,7 @@
|
|||
(setf *help* nil)
|
||||
(add-cpp-docu)
|
||||
(add-lisp-docu)
|
||||
(with-open-file (s (eql:in-home "doc/auto-doc.htm") :direction :output :if-exists :supersede)
|
||||
(with-open-file (s "auto-doc.htm" :direction :output :if-exists :supersede)
|
||||
(format s "<!doctype html>~%~
|
||||
<html lang=\"en\">~%~
|
||||
<head>~%~
|
||||
|
|
|
|||
22
examples/M-modules/quick/sokoban/lisp/ui-vars.lisp
Normal file
22
examples/M-modules/quick/sokoban/lisp/ui-vars.lisp
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
;;; THIS FILE IS GENERATED, see '(eql:qml)'
|
||||
|
||||
(defpackage ui
|
||||
(:use :cl :eql)
|
||||
(:export
|
||||
#:*board*
|
||||
#:*level*
|
||||
#:*rotate-player*
|
||||
#:*wiggle-box*
|
||||
#:*zoom-board-in*
|
||||
#:*zoom-board-out*))
|
||||
|
||||
(provide :ui-vars)
|
||||
|
||||
(in-package :ui)
|
||||
|
||||
(defvar *board* "board") ; Rectangle "qml/sokoban.qml"
|
||||
(defvar *rotate-player* "rotate_player") ; RotationAnimation "qml/items/player.qml"
|
||||
(defvar *zoom-board-in* "zoom_board_in") ; ScaleAnimator "qml/sokoban.qml"
|
||||
(defvar *zoom-board-out* "zoom_board_out") ; ScaleAnimator "qml/sokoban.qml"
|
||||
(defvar *wiggle-box* "wiggle_box") ; SequentialAnimation "qml/items/box2.qml"
|
||||
(defvar *level* "level") ; Slider "qml/sokoban.qml"
|
||||
|
|
@ -6,9 +6,10 @@
|
|||
|
||||
(qrequire :quick)
|
||||
|
||||
(require :sokoban "3rd-party/sokoban")
|
||||
(require :levels "3rd-party/my-levels")
|
||||
(require :qml-lisp "qml-lisp")
|
||||
(require :sokoban "lisp/3rd-party/sokoban")
|
||||
(require :levels "lisp/3rd-party/my-levels")
|
||||
(require :qml-lisp "lisp/qml-lisp")
|
||||
(require :ui-vars "lisp/ui-vars.lisp")
|
||||
|
||||
(defpackage :qsoko
|
||||
(:use :common-lisp :eql :qml)
|
||||
|
|
@ -48,13 +49,13 @@
|
|||
(defvar *static-item* (qml-component "static.qml")) ; :wall :goal
|
||||
|
||||
(defun board ()
|
||||
(qml:find-quick-item "board"))
|
||||
(qml:find-quick-item ui:*board*))
|
||||
|
||||
(defun level ()
|
||||
(floor (q< |value| "level")))
|
||||
(floor (q< |value| ui:*level*)))
|
||||
|
||||
(defun set-level (index)
|
||||
(q> |value| "level" index))
|
||||
(q> |value| ui:*level* index))
|
||||
|
||||
(defun assoc* (item alist)
|
||||
(cdr (assoc item alist)))
|
||||
|
|
@ -157,9 +158,9 @@
|
|||
(+ (if (eql :next direction/index) 1 -1)
|
||||
(level)))))))
|
||||
(when (/= level (level))
|
||||
(queued (q> |running| "zoom_board_out" t)
|
||||
(queued (q> |running| ui:*zoom-board-out* t)
|
||||
(set-level level) ; will call SET-MAZE from QML
|
||||
(q> |running| "zoom_board_in" t))))
|
||||
(q> |running| ui:*zoom-board-in* t))))
|
||||
(level))
|
||||
|
||||
(defun key-pressed (object event)
|
||||
|
|
@ -283,8 +284,8 @@
|
|||
t)
|
||||
|
||||
(defun final-animation ()
|
||||
(queued (q> |running| "rotate_player" t)
|
||||
(q>* |running| "wiggle_box" t)))
|
||||
(queued (q> |running| ui:*rotate-player* t)
|
||||
(q>* |running| ui:*wiggle-box* t)))
|
||||
|
||||
(defun run ()
|
||||
(x:do-with *quick-view*
|
||||
|
|
@ -295,7 +296,7 @@
|
|||
(qadd-event-filter nil |QEvent.KeyPress| 'key-pressed)
|
||||
(setf sokoban:*move-hook* 'move-item
|
||||
sokoban:*undo-hook* 'add-undo-step)
|
||||
(q> |maximumValue| "level" (1- (length *my-mazes*)))
|
||||
(q> |maximumValue| ui:*level* (1- (length *my-mazes*)))
|
||||
(set-maze))
|
||||
|
||||
(progn
|
||||
|
|
|
|||
125
lib/qml-ui-vars.lisp
Normal file
125
lib/qml-ui-vars.lisp
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
;;; generate global vars in a package named :ui for all QML items with
|
||||
;;; 'objectName' set
|
||||
;;;
|
||||
;;; this expects all QML files to be under 'qml/'
|
||||
;;;
|
||||
;;; since 'objectName' must be unique, an error message box will be shown
|
||||
;;; if more than one occurrence of the same name is found
|
||||
;;;
|
||||
;;; usage:
|
||||
;;; - run app, e.g. 'eql5 run.lisp' (use -qtpl if called from the console)
|
||||
;;; - call '(eql:qml)'
|
||||
;;; - generated file is 'lisp/ui-vars.lisp' (replaced without warning)
|
||||
|
||||
(defpackage qml-ui-variables
|
||||
(:use :cl :eql))
|
||||
|
||||
(in-package :qml-ui-variables)
|
||||
|
||||
(defparameter *warn-if-exists* nil)
|
||||
|
||||
(defparameter *qml-items* (qfind-children qml:*quick-view*))
|
||||
|
||||
(defun class-name* (item)
|
||||
(let ((name (|className| (|metaObject| item))))
|
||||
(subseq name
|
||||
(let ((start 0))
|
||||
(dolist (q '("QDeclarative" "QQuick" "QQml" "Qml"))
|
||||
(when (x:starts-with q name)
|
||||
(setf start (length q))
|
||||
(return)))
|
||||
start)
|
||||
(position #\_ name))))
|
||||
|
||||
(defun sort* (list key &optional stable)
|
||||
(funcall (if stable 'stable-sort 'sort)
|
||||
list 'string< :key key))
|
||||
|
||||
(defun filter (list)
|
||||
(remove-if (lambda (it)
|
||||
(or (x:empty-string (|objectName| it))
|
||||
(find (class-name* it)
|
||||
'("MnemonicLabel") ; exclude internal items
|
||||
:test 'string=)))
|
||||
list))
|
||||
|
||||
(defun grep (name)
|
||||
(ext:run-program "grep" (list "-rn"
|
||||
"--include"
|
||||
"*.qml"
|
||||
(format nil "objectName:[[:space:]]*~S" name)
|
||||
"qml/")))
|
||||
|
||||
(defun one-space (string)
|
||||
(x:join (remove-if 'x:empty-string (x:split string))))
|
||||
|
||||
(defun collect ()
|
||||
(setf *qml-items*
|
||||
(sort* (sort* (filter *qml-items*)
|
||||
'|objectName| t)
|
||||
'class-name*))
|
||||
(let ((max-name 0)
|
||||
(max-class 0)
|
||||
collected not-unique grepped)
|
||||
(dolist (item *qml-items*)
|
||||
(let* ((name (|objectName| item))
|
||||
(class* (class-name* item))
|
||||
(grep (ignore-errors (read-line (grep name)))))
|
||||
(when (and grep
|
||||
(not (find grep grepped :test 'string=)))
|
||||
(push (list (substitute #\- #\_ name)
|
||||
name
|
||||
class*
|
||||
(subseq grep 0 (position #\: grep)))
|
||||
collected)
|
||||
(setf max-name (max (length name) max-name)
|
||||
max-class (max (length class*) max-class))
|
||||
(when (and (find name not-unique :test 'string=)
|
||||
(not (find grep grepped :test 'string=)))
|
||||
(qmsg (format nil "<font color=red>QML: not unique:</font><br><pre>~A</pre>"
|
||||
(one-space (read-line (grep name))))))
|
||||
(pushnew grep grepped :test 'string=)
|
||||
(pushnew name not-unique :test 'string=))))
|
||||
(values (setf collected (nreverse collected))
|
||||
max-name
|
||||
max-class)))
|
||||
|
||||
(defun write-ui-file (out &optional (ui-package "ui"))
|
||||
(multiple-value-bind (items max-name max-class)
|
||||
(collect)
|
||||
(format out ";;; THIS FILE IS GENERATED, see '(eql:qml)'~
|
||||
~%~
|
||||
~%(defpackage ~(~A~)~% (:use :cl :eql)"
|
||||
ui-package)
|
||||
(format out "~% (:export~{~% #:*~A*~}))~%~%"
|
||||
(sort (mapcar 'first items) 'string<))
|
||||
(format out "(provide :ui-vars)~%~%(in-package ~(:~A~))~%~%" ui-package)
|
||||
(dolist (item items)
|
||||
(let ((diff-name (make-string (- max-name (length (first item)))))
|
||||
(diff-class (make-string (- max-class (length (third item))))))
|
||||
(format out "(defvar *~A*~A ~S)~A ; ~A~A ~S~%"
|
||||
(first item)
|
||||
diff-name
|
||||
(second item)
|
||||
diff-name
|
||||
(third item)
|
||||
diff-class
|
||||
(fourth item))))
|
||||
(terpri)))
|
||||
|
||||
(defun run ()
|
||||
(let ((ui "lisp/ui-vars.lisp"))
|
||||
(when (and *warn-if-exists*
|
||||
(probe-file ui)
|
||||
(/= |QMessageBox.Yes|
|
||||
(|question.QMessageBox| nil "Replace?"
|
||||
(format nil "File ~S already exists.<br>Replace it?" ui)
|
||||
(logior |QMessageBox.Yes| |QMessageBox.Cancel|))))
|
||||
(return-from run))
|
||||
(ensure-directories-exist ui)
|
||||
(with-open-file (out ui :direction :output :if-exists :supersede)
|
||||
(write-ui-file out)
|
||||
(format t "~%UI file generated: ~S~%~%" ui))))
|
||||
|
||||
(run)
|
||||
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
#include <QTimer>
|
||||
#include <QStringList>
|
||||
|
||||
const char EQL::version[] = "20.5.1"; // May 2020
|
||||
const char EQL::version[] = "20.7.1"; // July 2020
|
||||
|
||||
extern "C" void ini_EQL(cl_object);
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
<file>../lib/properties.lisp</file>
|
||||
<file>../lib/properties.ui</file>
|
||||
<file>../lib/qselect.lisp</file>
|
||||
<file>../lib/qml-ui-vars.lisp</file>
|
||||
<file>../lib/quic.lisp</file>
|
||||
<file>../lib/restart-dialog.lisp</file>
|
||||
<file>../lib/thread-safe.lisp</file>
|
||||
|
|
|
|||
|
|
@ -633,6 +633,11 @@
|
|||
(load (in-home "lib/quic")))
|
||||
(funcall (intern "RUN" :quic) ui.h ui.lisp ui-package properties)))
|
||||
|
||||
(defun qml ()
|
||||
"args: ()
|
||||
Generates global variables for all QML items with <code>objectName</code> set. Requires the QML app to be running. Will show an error message if <code>objectName</code> is not unique."
|
||||
(load (in-home "lib/qml-ui-vars")))
|
||||
|
||||
(defun qrequire (module &optional quiet)
|
||||
(%qrequire module quiet))
|
||||
|
||||
|
|
|
|||
|
|
@ -58,6 +58,7 @@
|
|||
#:qlocal8bit
|
||||
#:qlog
|
||||
#:qmessage-box
|
||||
#:qml
|
||||
#:qmsg
|
||||
#:qnew
|
||||
#:qnew-instance
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
void ini() {
|
||||
QString home(QDir::homePath() + "/.eql5/");
|
||||
if(!QFile::exists(home + "lib/gui.lisp")) {
|
||||
if(!QFile::exists(home + "lib/qml-ui-vars.lisp")) { // latest added file
|
||||
QDir dir(QDir::homePath());
|
||||
dir.mkdir(".eql5");
|
||||
dir.setPath(home);
|
||||
|
|
@ -35,6 +35,7 @@ void ini() {
|
|||
<< "lib/properties.lisp"
|
||||
<< "lib/properties.ui"
|
||||
<< "lib/qselect.lisp"
|
||||
<< "lib/qml-ui-vars.lisp"
|
||||
<< "lib/quic.lisp"
|
||||
<< "lib/restart-dialog.lisp"
|
||||
<< "lib/thread-safe.lisp"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue