;;; This is (kind of) a port of the Qt Script Example "Clock" (defpackage :clock (:use :common-lisp :eql) (:export #:*clock* #:start)) (in-package :clock) (defparameter *show-seconds* t) (defparameter *show-minutes* t) (defvar *clock* (qnew "QWidget(QWidget*,Qt::WindowFlags)" nil |Qt.WindowStaysOnTopHint| "size" '(170 170) "pos" '(50 50))) (defun start () (let ((timer (qnew "QTimer(QObject*)" *clock*))) (qconnect timer "timeout()" (lambda () (|update| *clock*))) (qoverride *clock* "paintEvent(QPaintEvent*)" 'paint) (|start| timer 500) (x:do-with *clock* |show| |raise|))) (defun pen (width &optional (color "black")) (x:let-it (qnew "QPen") (x:do-with x:it (|setCapStyle| |Qt.RoundCap|) (|setWidth| width) (|setColor| color)))) (defun brush (color) (x:let-it (qnew "QBrush") (x:do-with x:it (|setStyle| |Qt.SolidPattern|) (|setColor| color)))) (defparameter *pen-clock* (pen 8 "steelblue")) (defparameter *pen-hour-marks* (pen 4)) (defparameter *pen-minute-marks* (pen 2 "steelblue")) (defparameter *pen-hour* (pen 7)) (defparameter *pen-minute* (pen 5)) (defparameter *pen-second* (pen 2 "red")) (defparameter *brush-clock* (brush "white")) (defparameter *brush-second* (brush "gold")) (defun paint (ev) (macrolet ((with-save (() &body body) `(progn (|save| p) ,@body (|restore| p)))) (qlet ((p "QPainter(QWidget*)" *clock*)) (let* ((size (|size| *clock*)) (scale (/ (apply 'min size) 170))) (|translate| p (mapcar (lambda (x) (/ x 2)) size)) (|scale| p scale scale)) (|rotate| p -90) (|setRenderHint| p |QPainter.Antialiasing|) (|setPen| p *pen-clock*) (|setBrush| p *brush-clock*) (|drawEllipse| p '(-75 -75 150 150)) (|setPen| p *pen-hour-marks*) (dotimes (n 12) (|rotate| p 30) (|drawLine| p '(55 0 65 0))) (|setPen| p *pen-minute-marks*) (dotimes (n 60) (|rotate| p 6) (|drawLine| p '(63 0 65 0))) (multiple-value-bind (sec min hour) (get-decoded-time) (with-save () (|rotate| p (+ (* 30 hour) (/ min 2))) (|setPen| p *pen-hour*) (|setOpacity| p 0.5) (|drawLine| p '(-10 0 36 0))) (when *show-minutes* (with-save () (|rotate| p (* 6 min)) (|setPen| p *pen-minute*) (|setOpacity| p 0.5) (|drawLine| p '(-15 0 65 0)))) (when *show-seconds* (with-save () (|rotate| p (* 6 sec)) (|setPen| p *pen-second*) (|setBrush| p *brush-second*) (|drawEllipse| p '(-1.5 -1.5 3 3)) (|setOpacity| p 0.7) (|drawLine| p '(-15 0 52 0)) (|drawEllipse| p '(53 -4 8 8)))))))) (start)