[mcclim-devel] question about display functions and control apps
Paul Werkowski
pw at snoopy.mv.com
Thu Jan 6 19:04:36 UTC 2005
| I'm afraid I'm restarting an old discussion, but I've had it on the
| backburner, and now that I'm moving forward, I'm not quite sure how to
| finish out the solution.
|
| >>>>> "AH" == Andy Hefner <ahefner at gmail.com> writes:
|
| AH> What I might do is run a separate thread from the GUI that
monitors
| AH> external conditions. It can close over your frame event queue, and
| AH> communicate changes to the GUI via events as necessary. Just
define
| AH> your own event subclasses and write handle-event methods for them,
| AH> which will run in the GUI thread and can perform the necessary
| AH> updates. McCLIM itself already works in this fashion on threaded
| AH> platforms, events are collected from CLX in a background thread
which
| AH> queues them up for the applications to handle.
|
| I think this is the right solution for control applications. One has
| a second thread, which gets status updates and latches them into
| slots in the application frame, and then we queue up an event. Here
| are a couple of follow-ons, though:
|
| 1. Do I just make an event that will translate into setting
| frame-needs-redisplay?
|
I tried this approach in Lispworks CLIM and it seems to work pretty well.
Paul
~~~~~~~~~~~~~~~~~~~~~~~~~~
(in-package :clim-user)
(defclass thing ()
((x :initarg :x)
(y :initarg :y))
(:default-initargs :x (random 100) :y (random 100)))
(define-application-frame a-test ()
((things :initform nil))
(:pointer-documentation nil)
(:menu-bar nil)
(:panes
(p1 :application
:width 300 :height 200
:end-of-line-action :allow
:display-function 'p1df
:incremental-redisplay t
:display-time t
))
(:layouts
(default p1)))
(defun p1df (frame pane)
(with-output-recording-options (pane :record t)
(with-slots (things) frame
(dolist (thing things)
(with-slots (x y) thing
(updating-output (pane :unique-id thing
:cache-value (list x y)
:cache-test #'equal)
(draw-rectangle* pane x y (+ x 10) (+ y 10) :ink +blue+)))))))
(defvar *frame* nil)
(defun doit ()
;; display A-TEST application
(setq *frame* (make-application-frame 'a-test))
(run-frame-top-level *frame*))
(defclass my-event (device-event)
;; T-L-S seems to expect only device-event
;; Can't make application-pane see any yet
((pane :initarg :pane)))
(defmethod handle-event (client (event my-event))
(with-application-frame (frame)
(with-slots (pane) event
(redisplay-frame-pane frame pane))))
(defun stuffit (frame)
;; do something to "update the database"
(let ((tls (frame-top-level-sheet frame))
(pane (frame-standard-output frame)))
(with-slots (things) frame
(with-output-recording-options (pane :record t)
(push (make-instance 'thing) things))
(setf (pane-needs-redisplay pane) t))
(queue-event
tls
(make-instance 'my-event :sheet tls :pane pane :modifier-state 0))))
More information about the mcclim-devel
mailing list