Update of /project/pal/cvsroot/pal-gui
In directory clnet:/tmp/cvs-serv701
Modified Files:
gob.lisp gui.lisp package.lisp present.lisp widgets.lisp
Log Message:
Added more examples. Numerous other improvements. Nearing v 0.1
--- /project/pal/cvsroot/pal-gui/gob.lisp 2007/10/24 19:59:56 1.10
+++ /project/pal/cvsroot/pal-gui/gob.lisp 2007/10/29 20:06:01 1.11
@@ -80,6 +80,10 @@
(defmethod on-select ((gob gob))
nil)
+(defgeneric on-key-down (gob char))
+(defmethod on-key-down ((gob gob) char)
+ nil)
+
(defgeneric on-drag (gob start-pos delta-pos))
(defmethod on-drag ((gob gob) start-pos delta)
(declare (ignore start-pos delta))
@@ -89,6 +93,10 @@
(defmethod pointedp ((gob gob))
(eq *pointed-gob* gob))
+(defgeneric focusedp (gob))
+(defmethod focusedp ((gob gob))
+ (eq *focused-gob* gob))
+
(defgeneric armedp (gob))
(defmethod armedp ((gob gob))
(eq *armed-gob* gob))
@@ -181,10 +189,14 @@
(exp-size (- height (+ (* (1- (length (childs-of g))) (gap-of g)) (* 2 (y-pad-of g))
(loop for c in (remove-if 'y-expand-p (childs-of g)) summing (min-height-of c))))))
(dolist (c childs)
- (when (y-expand-p c)
- (setf (height-of c) (max (min-height-of c) (truncate exp-size exp-count))))
- (when (x-expand-p c)
- (setf (width-of c) (max 1 (- width (* 2 x-pad)))))))
+ (setf (height-of c)
+ (if (y-expand-p c)
+ (max (min-height-of c) (truncate exp-size exp-count))
+ (min-height-of c)))
+ (setf (width-of c)
+ (if (x-expand-p c)
+ (max 1 (- width (* 2 x-pad)))
+ (min-width-of c)))))
(let ((cpos (v x-pad y-pad)))
(dolist (c (reverse childs))
(setf (pos-of c) cpos)
@@ -214,10 +226,14 @@
(exp-size (- width (+ (* (1- (length (childs-of g))) (gap-of g)) (* 2 (x-pad-of g))
(loop for c in (remove-if 'x-expand-p (childs-of g)) summing (min-width-of c))))))
(dolist (c childs)
- (when (x-expand-p c)
- (setf (width-of c) (max (min-width-of c) (truncate exp-size exp-count))))
- (when (y-expand-p c)
- (setf (height-of c) (max 1 (- height (* 2 y-pad)))))))
+ (setf (width-of c)
+ (if (x-expand-p c)
+ (max (min-width-of c) (truncate exp-size exp-count))
+ (min-width-of c)))
+ (setf (height-of c)
+ (if (y-expand-p c)
+ (max 1 (- height (* 2 y-pad)))
+ (min-height-of c)))))
(let ((cpos (v x-pad y-pad)))
(dolist (c (reverse childs))
(setf (pos-of c) cpos)
--- /project/pal/cvsroot/pal-gui/gui.lisp 2007/10/24 19:59:56 1.6
+++ /project/pal/cvsroot/pal-gui/gui.lisp 2007/10/29 20:06:01 1.7
@@ -2,6 +2,7 @@
(defmacro gui-loop ((&key key-up-fn key-down-fn mouse-motion-fn quit-fn) &body redraw)
+ "Same as PAL:EVENT-LOOP but with added GUI event handling"
(let ((event (gensym)))
`(block event-loop
(cffi:with-foreign-object (,event :char 500)
@@ -19,12 +20,17 @@
(return-from event-loop)))
(:key-mouse-1 (cond
(*pointed-gob*
- (setf *drag-start-pos* (get-mouse-pos))
- (setf *relative-drag-start-pos* (v- *drag-start-pos* (absolute-pos-of *pointed-gob*)))
- (setf *armed-gob* *pointed-gob*)
+ (setf *drag-start-pos* (get-mouse-pos)
+ *relative-drag-start-pos* (v- *drag-start-pos* (absolute-pos-of *pointed-gob*))
+ *focused-gob* *pointed-gob*
+ *armed-gob* *pointed-gob*)
(on-button-down *pointed-gob* (v- (get-mouse-pos) (absolute-pos-of *pointed-gob*))))
- (t (pal::funcall? ,key-down-fn key))))
- (otherwise (pal::funcall? ,key-down-fn key))))))
+ (t (setf *focused-gob* nil)
+ (pal::funcall? ,key-down-fn key))))
+ (otherwise (if *focused-gob*
+ (let ((char (keysym-char key)))
+ (when (and char (graphic-char-p char)) (on-key-down *focused-gob* char)))
+ (pal::funcall? ,key-down-fn key)))))))
(loop
(pal::do-event ,event key-up key-down ,mouse-motion-fn ,quit-fn)
@@ -39,8 +45,7 @@
(when *pointed-gob*
(on-leave *pointed-gob*))
(on-enter g)))))
- (update-gui)
- (update-screen)))))))
+ (update-gui)))))))
(defmacro with-gui (args &body body)
@@ -73,4 +78,9 @@
*armed-gob* nil))
(defun update-gui ()
- (repaint *root*))
\ No newline at end of file
+ "Like PAL:UPDATE but also updates the GUI"
+ (pal::close-quads)
+ (reset-blend)
+ (pal-ffi:gl-load-identity)
+ (repaint *root*)
+ (update-screen))
\ No newline at end of file
--- /project/pal/cvsroot/pal-gui/package.lisp 2007/10/15 19:14:36 1.1
+++ /project/pal/cvsroot/pal-gui/package.lisp 2007/10/29 20:06:01 1.2
@@ -1,2 +1,16 @@
(defpackage #:pal-gui
- (:use :common-lisp :pal))
+ (:use :common-lisp :pal)
+ (:export #:with-gui #:init-gui #:update-gui #:gui-loop
+
+ #:present
+
+ #:window #:button #:list-widget #:text-widget #:choice-widget #:pin #:label #:h-gauge #:v-slider #:h-meter
+ #:sliding #:clipping #:highlighted
+ #:on-select #:on-button-down #:on-button-up #:on-key-down #:on-enter #:on-leave #:on-repaint #:on-drag #:repaint
+
+ #:box #:v-box #:h-box
+
+ #:pos-of #:width-of #:height-of #:childs-of #:parent-of #:min-width-of #:min-height-of #:x-expand-p #:y-expand-p
+ #:absolute-pos-of #:point-inside-p #:pointedp #:focusedp #:armedp #:activep
+ #:raise #:lower
+ #:label-of #:value-of #:text-of #:state-of #:min-value #:max-value #:page-size-of #:items-of #:item-height-of #:selected-of))
--- /project/pal/cvsroot/pal-gui/present.lisp 2007/10/25 14:10:16 1.1
+++ /project/pal/cvsroot/pal-gui/present.lisp 2007/10/29 20:06:01 1.2
@@ -3,11 +3,50 @@
(defgeneric present (object gob width height))
-(defmethod present :around (object (g widget) width height)
- (let ((ap (absolute-pos-of g)))
- (with-clipping ((1+ (vx ap)) (1+ (vy ap)) (- (width-of g) 2) (- (height-of g) 2))
- (call-next-method))))
(defmethod present (object (g widget) width height)
(with-blend (:color *text-color*)
- (draw-text (format nil "~a" object) (get-text-offset))))
\ No newline at end of file
+ (draw-text (format nil "~a" object) (v (vx (get-text-offset))
+ (- (truncate height 2) (truncate (get-font-height *gui-font*) 2) 1)))))
+
+
+
+(defmethod present ((image image) (g widget) width height)
+ (draw-image image (v 0 0) :scale (min (/ height (image-height image)) (/ width (image-width image)))))
+
+
+
+(defmethod present ((s (eql :up-arrow)) (g widget) width height)
+ (draw-polygon (list (v 3 (- height 3))
+ (v (/ width 2) 3)
+ (v (- width 3) (- height 3)))
+ (first *text-color*) (second *text-color*) (third *text-color*)(fourth *text-color*) :smoothp t))
+
+
+(defmethod present ((s (eql :down-arrow)) (g widget) width height)
+ (draw-polygon (list (v 3 3)
+ (v (/ width 2) (- height 3))
+ (v (- width 3) 3))
+ (first *text-color*) (second *text-color*) (third *text-color*)(fourth *text-color*) :smoothp t))
+
+
+(defmethod present ((s (eql :right-arrow)) (g widget) width height)
+ (draw-polygon (list (v 3 3)
+ (v (- width 3) (/ height 2))
+ (v 3 (- height 3)))
+ (first *text-color*) (second *text-color*) (third *text-color*)(fourth *text-color*) :smoothp t))
+
+
+(defmethod present ((s (eql :left-arrow)) (g widget) width height)
+ (draw-polygon (list (v (- width 3) 3)
+ (v 3 (/ height 2))
+ (v (- width 3) (- height 3)))
+ (first *text-color*) (second *text-color*) (third *text-color*)(fourth *text-color*) :smoothp t))
+
+
+(defmethod present ((s (eql :box)) (g widget) width height)
+ (draw-rectangle (v 3 3) (- width 6) (- height 6) (first *text-color*) (second *text-color*) (third *text-color*)(fourth *text-color*) :smoothp t))
+
+
+(defmethod present ((s (eql :circle)) (g widget) width height)
+ (draw-circle (v (/ width 2) (/ height 2)) (/ (min width height) pi) (first *text-color*) (second *text-color*) (third *text-color*)(fourth *text-color*) :smoothp t))
--- /project/pal/cvsroot/pal-gui/widgets.lisp 2007/10/24 19:59:56 1.10
+++ /project/pal/cvsroot/pal-gui/widgets.lisp 2007/10/29 20:06:01 1.11
@@ -52,8 +52,10 @@
(defclass widget (gob)
((on-drag :accessor on-drag-of :initarg :on-drag :initform (lambda (widget pos d) (declare (ignore widget pos d)) nil))
(on-select :accessor on-select-of :initarg :on-select :initform (lambda (widget) (declare (ignore widget)) nil))
+ (on-repaint :accessor on-repaint-of :initarg :on-repaint :initform (lambda (widget) (declare (ignore widget)) nil))
(on-button-down :accessor on-button-down-of :initarg :on-button-down :initform (lambda (widget pos) (declare (ignore widget pos)) nil))
(on-button-up :accessor on-button-up-of :initarg :on-button-up :initform (lambda (widget pos) (declare (ignore widget pos)) nil))
+ (on-key-down :accessor on-key-down-of :initarg :on-key-down :initform (lambda (widget char) (declare (ignore widget char)) nil))
(on-enter :accessor on-enter-of :initarg :on-enter :initform (lambda (widget) (declare (ignore widget)) nil))
(on-leave :accessor on-leave-of :initarg :on-leave :initform (lambda (widget) (declare (ignore widget)) nil)))
(:default-initargs :width (get-m) :height (get-m)))
@@ -66,6 +68,10 @@
(unless (funcall (on-select-of g) g)
(call-next-method)))
+(defmethod repaint :around ((g widget))
+ (unless (funcall (on-repaint-of g) g)
+ (call-next-method)))
+
(defmethod on-button-down :around ((g widget) pos)
(unless (funcall (on-button-down-of g) g pos)
(call-next-method)))
@@ -74,6 +80,10 @@
(unless (funcall (on-button-up-of g) g pos)
(call-next-method)))
+(defmethod on-key-down :around ((g widget) char)
+ (unless (funcall (on-key-down-of g) g char)
+ (call-next-method)))
+
(defmethod on-enter :around ((g widget))
(unless (funcall (on-enter-of g) g)
(call-next-method)))
@@ -92,16 +102,20 @@
((label :accessor label-of :initform nil :initarg :label))
(:default-initargs :activep nil :x-expand-p t :y-expand-p t))
-(defmethod initialize-instance :after ((g box) &key label)
- (when label
- (setf (y-pad-of g) (truncate (get-m) 2)
- (x-pad-of g) (truncate (get-m) 2))))
-
(defmethod repaint ((g box))
(when (label-of g)
- (draw-rectangle (v 0 0) (width-of g) (height-of g) 0 0 0 128 :fill nil)
- (with-blend (:color *text-color*)
- (draw-text (label-of g) (v- (get-text-offset) (v 0 (truncate (get-m) 2)))))))
+ (let ((text-offset (get-text-offset)))
+ (with-accessors ((width width-of) (height height-of) (label label-of)) g
+
+ (draw-line (v 0 0) (v 0 height) 0 0 0 160)
+ (draw-line (v width 0) (v width height) 0 0 0 160)
+ (draw-line (v 0 height) (v width height) 0 0 0 160)
+
+ (draw-line (v 0 0) (v (vx text-offset) 0) 0 0 0 160)
+ (draw-line (v (- (get-text-bounds label) (vx text-offset)) 0) (v width 0) 0 0 0 160)
+
+ (with-blend (:color *text-color*)
+ (draw-text label (v- text-offset (v 0 (truncate (get-m) 2)))))))))
@@ -109,13 +123,20 @@
()
(:default-initargs :x-pad 0 :y-pad 0 :gap (truncate (get-m) 3)))
+(defmethod initialize-instance :after ((g v-box) &key label)
+ (when label
+ (setf (y-pad-of g) (truncate (get-m) 2)
+ (x-pad-of g) (truncate (get-m) 2))))
(defclass h-box (box h-packing)
()
(:default-initargs :x-pad 0 :y-pad 0 :gap (truncate (get-m) 2)))
-
+(defmethod initialize-instance :after ((g h-box) &key label)
+ (when label
+ (setf (y-pad-of g) (truncate (get-m) 2)
+ (x-pad-of g) (truncate (get-m) 2))))
@@ -158,36 +179,69 @@
+(defclass label (widget)
+ ((value :reader value-of :initform "" :initarg :value)))
+
+(defmethod initialize-instance :after ((g label) &key value &allow-other-keys)
+ (when (stringp value)
+ (setf (width-of g) (get-text-bounds value))))
+
+(defmethod (setf value-of) (value (g label))
+ (when (stringp value)
+ (setf (width-of g) (get-text-bounds value)))
+ (setf (slot-value g 'value) value))
+
+(defmethod repaint ((g label))
+ (present (value-of g) g (width-of g) (height-of g)))
+
+
+
+(defclass pin (label sliding highlighted)
+ ((r :accessor r-of :initarg :r :initform 255)
+ (g :accessor g-of :initarg :g :initform 255)
+ (b :accessor b-of :initarg :b :initform 255)
+ (a :accessor a-of :initarg :a :initform 255))
+ (:default-initargs :activep t))
+
+(defmethod repaint ((g pin))
+ (draw-rectangle (v 0 0) (width-of g) (height-of g) (r-of g) (g-of g) (b-of g) (a-of g))
+ (call-next-method)
+ (draw-rectangle (v 0 0) (width-of g) (height-of g) 0 0 0 (a-of g) :fill nil))
+
+
+
(defclass button (widget highlighted)
- ((value :accessor value-of :initform "" :initarg :value))
+ ((value :accessor value-of :initform "" :initarg :value)
+ (stickyp :reader stickyp :initform nil :initarg :stickyp)
+ (state :accessor state-of :initform nil :initarg :state))
(:default-initargs :x-expand-p t))
(defmethod on-button-up ((g button) pos)
(when (eq *armed-gob* g)
- (on-select g)))
+ (on-select g)
+ (when (stickyp g)
+ (setf (state-of g) (not (state-of g))))))
(defmethod repaint ((g button))
(with-accessors ((width width-of) (height height-of) (value value-of)) g
(cond
- ((armedp g)
+ ((or (state-of g) (armedp g))
(draw-frame (v 0 0) width height *widget-color* :style :sunken)
(with-transformation (:pos (v 1 1))
- (with-blend (:color *text-color*)
- (present value g width height))))
+ (present value g width height)))
(t
(draw-frame (v 0 0) width height *widget-color* :style :raised)
- (with-blend (:color *text-color*)
- (present value g width height))))))
+ (present value g width height)))))
(defclass h-gauge (widget highlighted)
- ((value :reader value-of :initarg :value :initform 0)
- (min-value :reader min-value-of :initarg :min-value :initform 0)
- (max-value :reader max-value-of :initarg :max-value :initform 100))
+ ((value :accessor value-of :initarg :value :initform 0)
+ (min-value :accessor min-value-of :initarg :min-value :initform 0)
+ (max-value :accessor max-value-of :initarg :max-value :initform 100))
(:default-initargs :x-expand-p t))
(defgeneric (setf value-of) (value g))
@@ -219,10 +273,10 @@
(defclass v-slider (widget highlighted)
- ((value :reader value-of :initarg :value :initform 0)
- (page-size :reader page-size-of :initarg :page-size :initform 1)
- (min-value :reader min-value-of :initarg :min-value :initform 0)
- (max-value :reader max-value-of :initarg :max-value :initform 100))
+ ((value :accessor value-of :initarg :value :initform 0)
+ (page-size :accessor page-size-of :initarg :page-size :initform 1)
+ (min-value :accessor min-value-of :initarg :min-value :initform 0)
+ (max-value :accessor max-value-of :initarg :max-value :initform 100))
(:default-initargs :y-expand-p t))
(defmethod (setf value-of) (value (g v-slider))
@@ -278,7 +332,7 @@
(defclass list-view (widget)
- ((items :reader items-of :initarg :items :initform '())
+ ((items :accessor items-of :initarg :items :initform '())
(item-height :reader item-height-of :initarg :item-height :initform (get-m))
(multip :reader multip :initarg :multip :initform nil)
(selected :accessor selected-of :initform nil)
@@ -301,41 +355,41 @@
(with-accessors ((selected selected-of) (scroll scroll-of) (item-height item-height-of)) g
(let* ((y (vy pos))
(item (truncate (+ y scroll) item-height)))
- (if (multip g)
- (if (find item selected :test '=)
- (setf selected (remove item selected))
- (pushnew item selected))
- (if (and selected (= (first selected) item))
- (on-select g)
- (setf selected (list item)))))))
+ (when (< item (length (items-of g)))
+ (if (multip g)
+ (if (find item selected :test '=)
+ (setf selected (remove item selected))
+ (pushnew item selected))
+ (if (and selected (= (first selected) item))
+ (on-select g)
+ (setf selected (list item))))))))
(defmethod repaint ((g list-view))
(with-accessors ((width width-of) (height height-of) (scroll scroll-of) (ap absolute-pos-of) (item-height item-height-of)) g
(draw-frame (v 0 0) width height *paper-color* :style :sunken)
(with-clipping ((vx ap) (vy ap) width height)
- (with-blend (:color *text-color*)
- (with-transformation (:pos (v 0 (- (mod scroll item-height))))
- (let ((y 0))
- (dolist (i (items-of g))
- (when (and (> (* (1+ y) item-height) scroll)
- (< (* y item-height) (+ scroll height)))
- (cond
- ((find y (selected-of g) :test '=)
- (draw-rectangle (v 0 0) width item-height 0 0 0 160))
- ((oddp y)
- (draw-rectangle (v 0 0) width item-height 0 0 0 32)))
- (present i g width item-height)
- (translate (v 0 item-height)))
- (incf y))))))))
+ (with-transformation (:pos (v 0 (- (mod scroll item-height))))
+ (let ((y 0))
+ (dolist (i (items-of g))
+ (when (and (> (* (1+ y) item-height) scroll)
+ (< (* y item-height) (+ scroll height)))
+ (when (oddp y)
+ (draw-rectangle (v 0 0) width item-height 0 0 0 32))
+ (present i g width item-height)
+ (when (find y (selected-of g) :test '=)
+ (draw-rectangle (v 1 0) width item-height 0 0 0 128))
+ (translate (v 0 item-height)))
+ (incf y)))))))
-(defclass list-box (h-box)
- ((list-view :accessor list-view-of))
+(defclass list-widget (h-box)
+ ((list-view :accessor list-view-of)
+ (slider :accessor slider-of))
(:default-initargs :gap 3))
-(defmethod initialize-instance :after ((g list-box) &key items (item-height (get-m)) (multip nil) &allow-other-keys)
+(defmethod initialize-instance :after ((g list-widget) &key items (item-height (get-m)) (multip nil) &allow-other-keys)
(let* ((w (truncate (get-m) 1.5))
(list-view (make-instance 'list-view
:multip multip
@@ -359,8 +413,10 @@
(incf (scroll-of list-view) (* d item-height))
(setf (value-of slider) (scroll-of list-view))
nil)))
- (setf (list-view-of g) list-view)
+ (setf (list-view-of g) list-view
+ (slider-of g) slider)
(make-instance 'button
+ :value :up-arrow
:parent slider-box
:x-expand-p nil
:y-expand-p nil
@@ -369,6 +425,7 @@
:on-button-down (scroll-fn -1)
:on-drag (scroll-fn -0.3))
(make-instance 'button
+ :value :down-arrow
:parent slider-box
:x-expand-p nil
:y-expand-p nil
@@ -377,25 +434,66 @@
:on-button-down (scroll-fn 1)
:on-drag (scroll-fn 0.3)))))
-(defmethod value-of ((g list-box))
+(defmethod selected-of ((g list-widget))
(convert-selected-of (list-view-of g)))
+(defmethod items-of ((g list-widget))
+ (items-of (list-view-of g)))
+(defmethod (setf items-of) (items (g list-widget))
+ (setf (items-of (list-view-of g)) items
+ (scroll-of (list-view-of g)) 0
+ (selected-of (list-view-of g)) nil
+ (max-value-of (slider-of g)) (* (item-height-of (list-view-of g)) (length items))))
+
+
+
+(defclass choice-widget (v-box)
+ ((items :accessor items-of :initarg :items :initform '())))
+
+(defmethod initialize-instance :after ((g choice-widget) &key items multip (item-height (get-m)) &allow-other-keys)
+ (setf (items-of g)
+ (mapcar (lambda (i)
+ (make-instance 'button
+ :parent g
+ :height item-height
+ :value i
+ :stickyp t
+ :on-select (lambda (c)
+ (declare (ignore c))
+ (unless multip
+ (dolist (c (childs-of g))
+ (setf (state-of c) nil)))
+ nil)))
+ items)))
+
+(defmethod selected-of ((g choice-widget))
+ (mapcar 'value-of (remove-if-not 'state-of (childs-of g))))
-(defclass choice-box (v-box)
- ((items :reader items-of :initarg :items :initform '())
- (item-height :reader item-height-of :initarg :item-height :initform (get-m))
- (multip :reader multip :initarg :multip :initform nil)
- (selected :accessor selected-of :initform nil)))
-(defmethod repaint ((g choice-box))
- (with-accessors ((items items-of) (item-height item-height-of) (width width-of) (height height-of)) g
- (let ((i/2 (truncate item-height 2)))
- (with-transformation ()
- (dolist (i items)
- (draw-circle (v i/2 i/2) 6 0 0 0 255 :smoothp t)
- (draw-circle (v i/2 i/2) 4 255 255 255 255 :smoothp t)
- (with-transformation (:pos (v (get-m) 0))
- (present i g width item-height))
- (translate (v 0 item-height)))))))
\ No newline at end of file
+
+(defclass text-widget (widget)
+ ((point :accessor point-of :initform 0)
+ (text :accessor text-of :initarg :text :initform ""))
+ (:default-initargs :x-expand-p t))
+
+(defmethod initialize-instance :after ((g text-widget) &key text &allow-other-keys)
+ (setf (point-of g) (length text)))
+
+(defmethod repaint ((g text-widget))
+ (with-accessors ((width width-of) (height height-of) (text text-of) (point point-of)) g
+ (draw-frame (v 0 0) width height *widget-color* :fill nil :style :raised)
+ (draw-rectangle (v 1 1) (1- width) (1- height) (first *paper-color*) (second *paper-color*) (third *paper-color*) (fourth *paper-color*))
+ (let* ((offset (get-text-offset))
+ (point-x (+ (vx offset) (get-text-size (subseq text 0 point)))))
+ (with-blend (:color *text-color*)
+ (draw-text text offset)
+ (when (focusedp g)
+ (draw-rectangle (v point-x (vy offset))
+ 2 (- height (* 2 (vy offset)))
+ 0 0 0 255))))))
+
+(defmethod on-key-down ((g text-widget) char)
+ (setf (text-of g) (concatenate 'string (text-of g) (string char)))
+ (incf (point-of g)))
\ No newline at end of file