[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