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
+))