1 (defpackage #:cl-gtk2-cairo-demo
2 (:shadowing-import-from #:cl-cairo2 #:scale)
3 (:use :cl #:gtk #:cl-cairo2 #:cl-gtk2-cairo #:iter)
6 (in-package #:cl-gtk2-cairo-demo)
8 (eval-when (:compile-toplevel :load-toplevel :execute)
9 (defclass cairo-w (drawing-area)
10 ((draw-fn :initform 'draw-clock-face :accessor cairo-w-draw-fn))
11 (:metaclass gobject:gobject-class)))
13 (defmethod initialize-instance :after ((w cairo-w) &rest initargs)
14 (declare (ignore initargs))
15 (gobject:connect-signal w "configure-event" (lambda (widget event)
16 (declare (ignore event))
17 (widget-queue-draw widget)))
18 (gobject:connect-signal w "expose-event" (lambda (widget event)
19 (declare (ignore event))
22 (defmethod (setf cairo-w-draw-fn) :after (new-value (w cairo-w))
23 (declare (ignore new-value))
24 (widget-queue-draw w))
26 (defun cc-expose (widget)
27 (multiple-value-bind (w h) (gdk:drawable-get-size (widget-window widget))
28 (with-gdk-context (ctx (widget-window widget))
30 (funcall (cairo-w-draw-fn widget) w h)
33 (defstruct cairo-fn name fn)
35 (defun starts-with (str prefix)
36 (string= str prefix :end1 (min (length str) (length prefix))))
38 (defun get-draw-fns ()
39 (iter (for symbol in-package '#:cl-gtk2-cairo-demo)
40 (when (and (fboundp symbol)
41 (starts-with (symbol-name symbol) "DRAW-"))
42 (for doc = (or (documentation (fdefinition symbol) t) (let ((*print-case* :downcase)) (format nil "~A" symbol))))
43 (collect (make-cairo-fn :name doc :fn symbol)))))
47 (let ((cb-list (make-instance 'array-list-store)))
48 (store-add-column cb-list gobject:+g-type-string+ #'cairo-fn-name)
49 (iter (for fn in (get-draw-fns))
50 (store-add-item cb-list fn))
56 :title "Cairo drawing"
58 (combo-box :var combo :model cb-list) :expand nil
60 (let ((renderer (make-instance 'cell-renderer-text :text "A text")))
61 (cell-layout-pack-start combo renderer)
62 (cell-layout-add-attribute combo renderer "text" 0))
63 (gobject:connect-signal combo "changed"
65 (declare (ignore widget))
66 (let ((iter (combo-box-active-iter combo)))
68 (setf (cairo-w-draw-fn cw)
69 (cairo-fn-fn (tree-model-item cb-list iter)))))))
70 (setf (combo-box-active-iter combo) (tree-model-iter-first cb-list))
73 (defun draw-clock-face (w h)
76 (translate (/ w 2) (/ h 2))
77 (setf w (- w 2) h (- h 2))
78 (scale (* 0.99 (/ (min w h) 2)) (* 0.99 (/ (min w h) 2)))
82 (arc 0 0 1 0 (* 2 pi))
83 (set-source-rgb 1 1 1)
85 (set-source-rgb 0 0 0)
89 (iter (for i from 0 below 12)
90 (for angle = (/ (* i pi) 6))
91 (for cos = (cos angle))
92 (for sin = (sin angle))
95 (progn (set-line-width 0.02)
96 (move-to (* 0.8 cos) (* 0.8 sin)))
97 (move-to (* 0.9 cos) (* 0.9 sin)))
99 (set-source-rgb 0 0 0)
103 (defun draw-line (w h)
104 "Draw simple diagonal line"
108 (set-source-rgb 1 1 1)
111 (defun draw-ex-1 (w h)
112 "White diagonal line on a blue background"
113 (set-source-rgb 0.2 0.2 1)
119 (set-source-rgb 1 1 1)
123 (defun draw-text (w h)
124 "Very simple text example"
125 (declare (ignore w h))
128 (show-text "foo. Привет мир!"))
130 (defparameter *lis-a* 9)
131 (defparameter *lis-b* 8)
132 (defparameter *lis-delta* (/ pi 2))
133 (defparameter *lis-density* 2000)
134 (defparameter *lis-margin* 10)
136 (defun draw-lissajou (w h)
137 "Draw Lissajous curve"
139 (set-source-rgb 0.9 0.9 1)
142 (labels ((stretch (s x)
147 (move-to (stretch w (sin *lis-delta*)) (stretch h 0))
148 (dotimes (i *lis-density*)
149 (let* ((v (/ (* i pi 2) *lis-density*))
150 (x (sin (+ (* *lis-a* v) *lis-delta*)))
151 (y (sin (* *lis-b* v))))
152 (line-to (stretch w x) (stretch h y)))))
155 (set-source-rgb 0 0 1)
159 "Draw a heart with fixed size and the given transparency alpha.
160 Heart is upside down."
161 (let ((radius (sqrt 0.5)))
164 (arc 0.5 -0.5 radius (deg-to-rad -45) (deg-to-rad 135))
165 (arc -0.5 -0.5 radius (deg-to-rad 45) (deg-to-rad 215))
167 (set-source-rgba 1 0 0 alpha)
170 (defvar *heart-max-angle* 40d0)
172 (defun draw-heart (w h)
173 "Draw a lot of hearts"
175 (set-source-rgb 1 1 1)
179 (let ((scaling (+ 5d0 (random 40d0))))
180 (reset-trans-matrix) ; reset matrix
181 (translate (random w) (random h)) ; move the origin
182 (scale scaling scaling) ; scale
183 (rotate (deg-to-rad (- (random (* 2 *heart-max-angle*))
184 *heart-max-angle* 180))) ; rotate
185 (heart (+ 0.1 (random 0.7))))))
187 (defun draw-gradient (w h)
189 (with-linear-pattern rainbow (0 0 w h)
190 `((0 (0.7 0 0.7 0)) ;rgb(a) color as list
191 (1/6 ,cl-colors:+blue+) ;color as cl-color
192 (2/6 ,cl-colors:+green+)
193 (3/6 ,cl-colors:+yellow+)
194 (4/6 ,cl-colors:+orange+)
195 (5/6 ,cl-colors:+red+)
196 (1 ,cl-colors:+violetred+))