2 (:use
:cl
:gtk
:gdk
:gobject
:iter
)
18 #:test-color-selection
23 #:test-box-child-property
30 #:test-entry-completion
35 (in-package :gtk-demo
)
37 (defparameter *src-location
* (asdf:component-pathname
(asdf:find-system
:cl-gtk2-gtk
)))
40 "A simple test of 'on-expose' event"
42 (let ((window (make-instance 'gtk-window
:type
:toplevel
:app-paintable t
))
44 (g-signal-connect window
"destroy" (lambda (widget)
45 (declare (ignore widget
))
47 (g-signal-connect window
"motion-notify-event" (lambda (widget event
)
48 (declare (ignore widget
))
49 (setf x
(event-motion-x event
)
50 y
(event-motion-y event
))
51 (widget-queue-draw window
)))
52 (g-signal-connect window
"expose-event"
53 (lambda (widget event
)
54 (declare (ignore widget event
))
55 (let* ((gdk-window (widget-window window
))
56 (gc (gdk-gc-new gdk-window
))
57 (layout (widget-create-pango-layout window
(format nil
"X: ~F~%Y: ~F" x y
))))
58 (gdk-draw-layout gdk-window gc
0 0 layout
)
59 (gdk-gc-set-rgb-fg-color gc
(make-color :red
65535 :green
0 :blue
0))
60 (multiple-value-bind (x y
) (drawable-get-size gdk-window
)
61 (gdk-draw-line gdk-window gc
0 0 x y
)))))
62 (g-signal-connect window
"configure-event"
63 (lambda (widget event
)
64 (declare (ignore widget event
))
65 (widget-queue-draw window
)))
67 (push :pointer-motion-mask
(gdk-window-events (widget-window window
))))))
70 "Testing GtkTextEntry"
72 (let* ((window (make-instance 'gtk-window
:type
:toplevel
:title
"Testing entry" :border-width
10))
73 (box (make-instance 'v-box
))
74 (entry (make-instance 'entry
))
75 (button (make-instance 'button
:label
"OK"))
76 (text-buffer (make-instance 'text-buffer
))
77 (text-view (make-instance 'text-view
:buffer text-buffer
))
78 (button-select (make-instance 'button
:label
"Select"))
79 (button-insert (make-instance 'button
:label
"Insert")))
80 (box-pack-start box
(make-instance 'label
:label
"Enter <b>anything</b> you wish:" :use-markup t
) :expand nil
)
81 (box-pack-start box entry
:expand nil
)
82 (box-pack-start box button
:expand nil
)
83 (box-pack-start box button-select
:expand nil
)
84 (box-pack-start box button-insert
:expand nil
)
85 (let* ((w (make-instance 'scrolled-window
)))
86 (box-pack-start box w
)
87 (container-add w text-view
))
88 (container-add window box
)
89 (g-signal-connect window
"destroy" (lambda (widget) (declare (ignore widget
)) (leave-gtk-main)))
90 (g-signal-connect window
"delete-event" (lambda (widget event
)
91 (declare (ignore widget event
))
92 (let ((dlg (make-instance 'message-dialog
95 (let ((response (dialog-run dlg
)))
97 (not (eq :yes response
))))))
98 (g-signal-connect button
"clicked" (lambda (button)
99 (declare (ignore button
))
100 (setf (text-buffer-text text-buffer
)
101 (format nil
"~A~%~A" (text-buffer-text text-buffer
) (entry-text entry
))
102 (entry-text entry
) "")))
103 (g-signal-connect button-select
"clicked" (lambda (button)
104 (declare (ignore button
))
105 (editable-select-region entry
5 10)))
106 (g-signal-connect button-insert
"clicked" (lambda (button)
107 (declare (ignore button
))
108 (editable-insert-text entry
"hello" 2)))
109 (widget-show window
))))
111 (defun table-packing ()
112 "Simple test of packing widgets into GtkTable"
114 (let* ((window (make-instance 'gtk-window
:type
:toplevel
:title
"Table packing" :border-width
20))
115 (table (make-instance 'table
:n-rows
2 :n-columns
2 :homogeneous t
))
116 (button-1 (make-instance 'button
:label
"Button 1"))
117 (button-2 (make-instance 'button
:label
"Button 2"))
118 (button-q (make-instance 'button
:label
"Quit")))
119 (container-add window table
)
120 (table-attach table button-1
0 1 0 1)
121 (table-attach table button-2
1 2 0 1)
122 (table-attach table button-q
0 2 1 2)
123 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
124 (g-signal-connect button-q
"clicked" (lambda (b) (declare (ignore b
)) (object-destroy window
)))
125 (widget-show window
))))
127 (defun test-pixbuf ()
130 (let* ((window (make-instance 'gtk-window
:title
"Test pixbuf" :request-width
600 :request-height
240))
131 (vbox (make-instance 'v-box
))
132 (eventbox (make-instance 'event-box
))
133 (vbox-1 (make-instance 'v-box
)))
134 (container-add window vbox
)
135 (box-pack-start vbox
(make-instance 'label
:text
"Placing bg image" :font
"Times New Roman Italic 10" :color
"#00f" :request-height
40))
136 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
137 (box-pack-start vbox eventbox
)
138 (container-add eventbox vbox-1
)
139 (box-pack-start vbox-1
(make-instance 'label
:text
"This is the eventbox"))
140 (box-pack-start vbox-1
(make-instance 'label
:text
"The green ball is the bg"))
141 (widget-show window
))))
144 "Using GtkImage with stock icon"
146 (let* ((window (make-instance 'gtk-window
:title
"Test images"))
147 (image (make-instance 'image
:icon-name
"applications-development" :icon-size
6)))
148 (container-add window image
)
149 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
150 (widget-show window
))))
152 (defun test-progress-bar ()
153 "Testing progress-bar"
155 (let* ((window (make-instance 'gtk-window
:title
"Test progress bar"))
156 (v-box (make-instance 'v-box
))
157 (p-bar (make-instance 'progress-bar
:test
"A process"))
158 (button-pulse (make-instance 'button
:label
"Pulse"))
159 (button-set (make-instance 'button
:label
"Set"))
160 (entry (make-instance 'entry
)))
161 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
162 (container-add window v-box
)
163 (box-pack-start v-box p-bar
)
164 (box-pack-start v-box button-pulse
)
165 (box-pack-start v-box button-set
)
166 (box-pack-start v-box entry
)
167 (g-signal-connect button-pulse
"clicked" (lambda (w) (declare (ignore w
)) (progress-bar-pulse p-bar
)))
168 (g-signal-connect button-set
"clicked" (lambda (w)
170 (setf (progress-bar-fraction p-bar
)
171 (coerce (read-from-string (entry-text entry
)) 'real
))))
172 (widget-show window
))))
174 (defun test-statusbar ()
175 "Test of GtkStatusbar"
177 (let* ((window (make-instance 'gtk-window
:title
"Text status bar"))
178 (v-box (make-instance 'v-box
))
179 (h-box (make-instance 'h-box
))
180 (label (make-instance 'label
:label
"Test of status bar" :xalign
0.5 :yalign
0.5))
181 (statusbar (make-instance 'statusbar
:has-resize-grip t
))
182 (button-push (make-instance 'button
:label
"Push"))
183 (button-pop (make-instance 'button
:label
"Pop"))
184 (entry (make-instance 'entry
))
185 (icon (make-instance 'status-icon
:icon-name
"applications-development")))
186 (set-status-icon-tooltip icon
"An icon from lisp program")
187 (g-signal-connect window
"destroy" (lambda (w)
189 #+ (or) (setf (status-icon-visible icon
) nil
)
191 (g-signal-connect button-push
"clicked" (lambda (b)
193 (statusbar-push statusbar
"lisp-prog" (entry-text entry
))))
194 (g-signal-connect button-pop
"clicked" (lambda (b)
196 (statusbar-pop statusbar
"lisp-prog")))
197 (g-signal-connect icon
"activate" (lambda (i)
199 (let ((message-dialog (make-instance 'message-dialog
201 :text
"You clicked on icon!")))
202 (dialog-run message-dialog
)
203 (object-destroy message-dialog
))))
204 (container-add window v-box
)
205 (box-pack-start v-box h-box
:expand nil
)
206 (box-pack-start h-box entry
)
207 (box-pack-start h-box button-push
:expand nil
)
208 (box-pack-start h-box button-pop
:expand nil
)
209 (box-pack-start v-box label
)
210 (box-pack-start v-box statusbar
:expand nil
)
212 (setf (status-icon-screen icon
) (gtk-window-screen window
)))))
214 (defun test-scale-button ()
215 "Test of scale button with icons"
217 (let* ((window (make-instance 'gtk-window
:type
:toplevel
:title
"Testing scale button"))
218 (button (make-instance 'scale-button
:icons
(list "media-seek-backward" "media-seek-forward" "media-playback-stop" "media-playback-start") :adjustment
(make-instance 'adjustment
:lower -
40 :upper
50 :value
20))))
219 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
220 (container-add window button
)
221 (widget-show window
))))
223 (defun test-text-view ()
224 "Test of GtkTextView"
226 (let* ((window (make-instance 'gtk-window
:type
:toplevel
:title
"Testing text view" :width-request
400 :height-request
300))
227 (button (make-instance 'button
:label
"Do"))
228 (button-insert (make-instance 'button
:label
"Insert a button!"))
229 (bold-btn (make-instance 'button
:label
"Bold"))
230 (buffer (make-instance 'text-buffer
:text
"Some text buffer with some text inside"))
231 (v (make-instance 'text-view
:buffer buffer
:wrap-mode
:word
))
232 (box (make-instance 'v-box
))
233 (scrolled (make-instance 'scrolled-window
:hscrollbar-policy
:automatic
:vscrollbar-policy
:automatic
)))
234 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
235 (g-signal-connect button
"clicked" (lambda (b)
237 (multiple-value-bind (i1 i2
) (text-buffer-get-selection-bounds buffer
)
239 (let* ((i1 i1
) (i2 i2
)
240 (dialog (make-instance 'message-dialog
:buttons
:ok
)))
241 (setf (message-dialog-text dialog
)
242 (format nil
"selection: from (~A,~A) to (~A,~A)"
243 (text-iter-line i1
) (text-iter-line-offset i1
)
244 (text-iter-line i2
) (text-iter-line-offset i2
)))
246 (object-destroy dialog
))))))
247 (g-signal-connect bold-btn
"clicked" (Lambda (b)
249 (multiple-value-bind (start end
) (text-buffer-get-selection-bounds buffer
)
250 (when (and start end
)
253 (tag (text-tag-table-lookup (text-buffer-tag-table buffer
) "bold")))
254 (if (text-iter-has-tag start tag
)
255 (text-buffer-remove-tag buffer tag start end
)
256 (text-buffer-apply-tag buffer tag start end
)))))))
257 (g-signal-connect button-insert
"clicked" (lambda (b)
259 (let* ((iter (text-buffer-get-iter-at-mark buffer
(text-buffer-get-mark buffer
"insert")))
260 (anchor (text-buffer-insert-child-anchor buffer iter
))
261 (button (make-instance 'button
:label
"A button!")))
263 (text-view-add-child-at-anchor v button anchor
))))
264 (let ((tag (make-instance 'text-tag
:name
"bold" :weight
700)))
265 (text-tag-table-add (text-buffer-tag-table buffer
) tag
)
266 (g-signal-connect tag
"event"
267 (lambda (tag object event iter
)
268 (declare (ignore tag object iter
))
269 (when (eq (event-type event
) :button-release
)
270 (let ((dlg (make-instance 'message-dialog
:text
"You clicked on bold text." :buttons
:ok
)))
272 (object-destroy dlg
))))))
273 (container-add window box
)
274 (container-add scrolled v
)
275 (box-pack-start box button
:expand nil
)
276 (box-pack-start box button-insert
:expand nil
)
277 (box-pack-start box bold-btn
:expand nil
)
278 (box-pack-start box scrolled
)
279 (widget-show window
))))
281 (defun demo-code-editor ()
284 (let* ((window (make-instance 'gtk-window
:type
:toplevel
:title
"Code editor" :width-request
400 :height-request
400 :window-position
:center
))
285 (scrolled (make-instance 'scrolled-window
:hscrollbar-policy
:automatic
:vscrollbar-policy
:automatic
))
286 (buffer (make-instance 'text-buffer
))
287 (view (make-instance 'text-view
:buffer buffer
)))
288 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
289 (container-add window scrolled
)
290 (container-add scrolled view
)
292 (g-signal-connect buffer
"insert-text" (lambda (buffer location text len
)
293 (let* ((buffer buffer
)
295 (format t
"~A~%" (list buffer location text len
))))))))
297 (defstruct tvi title value
)
299 (defun test-treeview-list ()
300 "Test of treeview with CL-GTK2-GTK:ARRAY-LIST-STORE"
302 (let* ((window (make-instance 'gtk-window
:type
:toplevel
:title
"Treeview (list)"))
303 (model (make-instance 'array-list-store
))
304 (scroll (make-instance 'scrolled-window
:hscrollbar-policy
:automatic
:vscrollbar-policy
:automatic
))
305 (tv (make-instance 'tree-view
:headers-visible t
:width-request
100 :height-request
400 :rules-hint t
))
306 (h-box (make-instance 'h-box
))
307 (v-box (make-instance 'v-box
))
308 (title-entry (make-instance 'entry
))
309 (value-entry (make-instance 'entry
))
310 (button (make-instance 'button
:label
"Add")))
311 (store-add-column model
"gchararray" #'tvi-title
)
312 (store-add-column model
"gint" #'tvi-value
)
313 (store-add-item model
(make-tvi :title
"Monday" :value
1))
314 (store-add-item model
(make-tvi :title
"Tuesday" :value
2))
315 (store-add-item model
(make-tvi :title
"Wednesday" :value
3))
316 (store-add-item model
(make-tvi :title
"Thursday" :value
4))
317 (store-add-item model
(make-tvi :title
"Friday" :value
5))
318 (store-add-item model
(make-tvi :title
"Saturday" :value
6))
319 (store-add-item model
(make-tvi :title
"Sunday" :value
7))
320 (setf (tree-view-model tv
) model
(tree-view-tooltip-column tv
) 0)
321 (gobject:g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
322 (gobject:g-signal-connect button
"clicked" (lambda (b)
324 (store-add-item model
(make-tvi :title
(entry-text title-entry
)
325 :value
(or (parse-integer (entry-text value-entry
)
328 (g-signal-connect tv
"row-activated" (lambda (tv path column
)
329 (declare (ignore tv column
))
330 (format t
"You clicked on row ~A~%" (tree-path-indices path
))))
331 (container-add window v-box
)
332 (box-pack-start v-box h-box
:expand nil
)
333 (box-pack-start h-box title-entry
:expand nil
)
334 (box-pack-start h-box value-entry
:expand nil
)
335 (box-pack-start h-box button
:expand nil
)
336 (box-pack-start v-box scroll
)
337 (container-add scroll tv
)
338 (let ((column (make-instance 'tree-view-column
:title
"Title" :sort-column-id
0))
339 (renderer (make-instance 'cell-renderer-text
:text
"A text")))
340 (tree-view-column-pack-start column renderer
)
341 (tree-view-column-add-attribute column renderer
"text" 0)
342 (tree-view-append-column tv column
)
343 (print (tree-view-column-tree-view column
))
344 (print (tree-view-column-cell-renderers column
)))
345 (let ((column (make-instance 'tree-view-column
:title
"Value"))
346 (renderer (make-instance 'cell-renderer-text
:text
"A text")))
347 (tree-view-column-pack-start column renderer
)
348 (tree-view-column-add-attribute column renderer
"text" 1)
349 (tree-view-append-column tv column
)
350 (print (tree-view-column-tree-view column
))
351 (print (tree-view-column-cell-renderers column
)))
352 (widget-show window
))))
354 (defun test-combo-box ()
355 "Testing GtkComboBox"
357 (let* ((window (make-instance 'gtk-window
:type
:toplevel
:title
"Treeview (list)"))
358 (model (make-instance 'array-list-store
))
359 (combo-box (make-instance 'combo-box
:model model
))
360 (h-box (make-instance 'h-box
))
361 (v-box (make-instance 'v-box
))
362 (title-entry (make-instance 'entry
))
363 (value-entry (make-instance 'entry
))
364 (button (make-instance 'button
:label
"Add")))
365 (store-add-column model
"gchararray" #'tvi-title
)
366 (store-add-column model
"gint" #'tvi-value
)
367 (store-add-item model
(make-tvi :title
"Monday" :value
1))
368 (store-add-item model
(make-tvi :title
"Tuesday" :value
2))
369 (store-add-item model
(make-tvi :title
"Wednesday" :value
3))
370 (store-add-item model
(make-tvi :title
"Thursday" :value
4))
371 (store-add-item model
(make-tvi :title
"Friday" :value
5))
372 (store-add-item model
(make-tvi :title
"Saturday" :value
6))
373 (store-add-item model
(make-tvi :title
"Sunday" :value
7))
374 (gobject:g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
375 (gobject:g-signal-connect button
"clicked" (lambda (b)
377 (store-add-item model
(make-tvi :title
(entry-text title-entry
)
378 :value
(or (parse-integer (entry-text value-entry
)
381 (g-signal-connect combo-box
"changed" (lambda (c)
383 (format t
"You clicked on row ~A~%" (combo-box-active combo-box
))))
384 (container-add window v-box
)
385 (box-pack-start v-box h-box
:expand nil
)
386 (box-pack-start h-box title-entry
:expand nil
)
387 (box-pack-start h-box value-entry
:expand nil
)
388 (box-pack-start h-box button
:expand nil
)
389 (box-pack-start v-box combo-box
)
390 (let ((renderer (make-instance 'cell-renderer-text
:text
"A text")))
391 (cell-layout-pack-start combo-box renderer
:expand t
)
392 (cell-layout-add-attribute combo-box renderer
"text" 0))
393 (let ((renderer (make-instance 'cell-renderer-text
:text
"A number")))
394 (cell-layout-pack-start combo-box renderer
:expand nil
)
395 (cell-layout-add-attribute combo-box renderer
"text" 1))
396 (widget-show window
))))
398 (defun test-ui-manager ()
399 "Testing GtkUIManager"
401 (let* ((window (make-instance 'gtk-window
:type
:toplevel
:title
"UI Manager" :default-width
200 :default-height
100 :window-position
:center
))
402 (ui-manager (make-instance 'ui-manager
))
403 (print-confirmation t
))
404 (ui-manager-add-ui-from-string ui-manager
407 <toolbar action='toolbar1'>
409 <toolitem name='Left' action='justify-left'/>
410 <toolitem name='Center' action='justify-center'/>
411 <toolitem name='Right' action='justify-right'/>
412 <toolitem name='Zoom in' action='zoom-in' />
413 <toolitem name='print-confirm' action='print-confirm' />
417 (gobject:g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
418 (iter (with fn
= (lambda (action) (when print-confirmation
(format t
"Action ~A with name ~A activated~%" action
(action-name action
)))))
419 (with action-group
= (make-instance 'action-group
:name
"Actions"))
420 (finally (let ((a (make-instance 'toggle-action
:name
"print-confirm" :label
"Print" :stock-id
"gtk-print-report" :active t
)))
421 (g-signal-connect a
"toggled" (lambda (action) (setf print-confirmation
(toggle-action-active action
))))
422 (action-group-add-action action-group a
))
423 (ui-manager-insert-action-group ui-manager action-group
0))
424 (for (name stock-id
) in
'(("justify-left" "gtk-justify-left")
425 ("justify-center" "gtk-justify-center")
426 ("justify-right" "gtk-justify-right")
427 ("zoom-in" "gtk-zoom-in")))
428 (for action
= (make-instance 'action
:name name
:stock-id stock-id
))
429 (g-signal-connect action
"activate" fn
)
430 (action-group-add-action action-group action
))
431 (let ((widget (ui-manager-widget ui-manager
"/toolbar1")))
433 (container-add window widget
)))
434 (widget-show window
))))
436 (defun test-color-button ()
437 "Test of GtkColorButton"
439 (let ((window (make-instance 'gtk-window
:title
"Color button" :type
:toplevel
:window-position
:center
:width-request
100 :height-request
100))
440 (button (make-instance 'color-button
:title
"Color button")))
441 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
442 (g-signal-connect button
"color-set" (lambda (b)
444 (format t
"Chose color ~A~%" (color-button-color button
))))
445 (container-add window button
)
446 (widget-show window
))))
448 (defun test-color-selection ()
449 "Test of GtkColorSelection"
451 (let ((window (make-instance 'gtk-window
:title
"Color selection" :type
:toplevel
:window-position
:center
))
452 (selection (make-instance 'color-selection
:has-opacity-control t
)))
453 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
454 (g-signal-connect selection
"color-changed" (lambda (s) (declare (ignore s
)) (unless (color-selection-adjusting-p selection
) (format t
"color: ~A~%" (color-selection-current-color selection
)))))
455 (container-add window selection
)
456 (widget-show window
))))
458 (defun test-file-chooser ()
459 "Test of GtkFileChooser"
461 (let ((window (make-instance 'gtk-window
:title
"file chooser" :type
:toplevel
:window-position
:center
:default-width
100 :default-height
100))
462 (v-box (make-instance 'v-box
))
463 (button (make-instance 'file-chooser-button
:action
:open
))
464 (b (make-instance 'button
:label
"Choose for save" :stock-id
"gtk-save")))
465 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
466 (g-signal-connect button
"file-set" (lambda (b) (declare (ignore b
)) (format t
"File set: ~A~%" (file-chooser-filename button
))))
467 (g-signal-connect b
"clicked" (lambda (b)
469 (let ((d (make-instance 'file-chooser-dialog
:action
:save
:title
"Choose file to save")))
470 (dialog-add-button d
"gtk-save" :accept
)
471 (dialog-add-button d
"gtk-cancel" :cancel
)
472 (when (eq (dialog-run d
) :accept
)
473 (format t
"saved to file ~A~%" (file-chooser-filename d
)))
474 (object-destroy d
))))
475 (container-add window v-box
)
476 (box-pack-start v-box button
)
477 (box-pack-start v-box b
)
478 (widget-show window
))))
480 (defun test-font-chooser ()
483 (let ((window (make-instance 'gtk-window
:title
"fonts" :type
:toplevel
:window-position
:center
:default-width
100 :default-height
100))
484 (v-box (make-instance 'v-box
))
485 (button (make-instance 'font-button
:title
"Choose font" :font-name
"Sans 10")))
486 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
487 (g-signal-connect button
"font-set" (lambda (b) (declare (ignore b
)) (format t
"Chose font ~A~%" (font-button-font-name button
))))
488 (container-add window v-box
)
489 (box-pack-start v-box button
)
490 (widget-show window
))))
492 (defun test-notebook ()
495 (let ((window (make-instance 'gtk-window
:title
"Notebook" :type
:toplevel
:window-position
:center
:default-width
100 :default-height
100))
496 (expander (make-instance 'expander
:expanded t
:label
"notebook"))
497 (notebook (make-instance 'notebook
:enable-popup t
)))
498 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
499 (iter (for i from
0 to
5)
500 (for page
= (make-instance 'label
:label
(format nil
"Label for page ~A" i
)))
501 (for tab-label
= (make-instance 'label
:label
(format nil
"Tab ~A" i
)))
502 (for tab-button
= (make-instance 'button
503 :image
(make-instance 'image
:stock
"gtk-close" :icon-size
1)
505 (g-signal-connect tab-button
"clicked"
508 (declare (ignore button
))
509 (format t
"Removing page ~A~%" page
)
510 (notebook-remove-page notebook page
))))
511 (for tab-hbox
= (make-instance 'h-box
))
512 (box-pack-start tab-hbox tab-label
)
513 (box-pack-start tab-hbox tab-button
)
514 (widget-show tab-hbox
)
515 (notebook-add-page notebook page tab-hbox
))
516 (container-add window expander
)
517 (container-add expander notebook
)
518 (widget-show window
))))
520 (defun calendar-detail (calendar year month day
)
521 (declare (ignore calendar year month
))
525 (defun test-calendar ()
526 "Test of GtkCalendar"
528 (let ((window (make-instance 'gtk-window
:title
"Calendar" :type
:toplevel
:window-position
:center
:default-width
100 :default-height
100))
529 (calendar (make-instance 'calendar
:detail-function
#'calendar-detail
)))
530 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
531 (g-signal-connect calendar
"day-selected" (lambda (c) (declare (ignore c
)) (format t
"selected: year ~A month ~A day ~A~%"
532 (calendar-year calendar
)
533 (calendar-month calendar
)
534 (calendar-day calendar
))))
535 (container-add window calendar
)
536 (widget-show window
))))
538 (defun test-box-child-property ()
539 "Test of child-property usage"
541 (let ((window (make-instance 'gtk-window
:title
"Text box child property" :type
:toplevel
:window-position
:center
:width-request
200 :height-request
200))
542 (box (make-instance 'h-box
))
543 (button (make-instance 'toggle-button
:active t
:label
"Expand")))
544 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
545 (g-signal-connect button
"toggled" (lambda (b) (declare (ignore b
)) (setf (box-child-expand box button
) (toggle-button-active button
))))
546 (container-add window box
)
547 (box-pack-start box button
)
548 (widget-show window
))))
550 (defun test-builder ()
553 (let ((builder (make-instance 'builder
)))
554 (builder-add-from-file builder
(namestring (merge-pathnames "demo/demo1.ui" *src-location
*)))
555 (let ((text-view (builder-get-object builder
"textview1"))
557 (builder-connect-signals-simple builder
`(("toolbutton1_clicked_cb" ,(lambda (b)
559 #+nil
(print (current-event))
560 (setf (text-buffer-text (text-view-buffer text-view
))
561 (format nil
"Clicked ~A times~%" (incf c
)))
562 (statusbar-pop (builder-get-object builder
"statusbar1")
564 (statusbar-push (builder-get-object builder
"statusbar1")
566 (format nil
"~A times" c
))))
567 ("quit_cb" ,(lambda (&rest args
)
569 (object-destroy (builder-get-object builder
"window1"))))
570 ("about_cb" ,(lambda (&rest args
)
572 (let ((d (make-instance 'about-dialog
573 :program-name
"GtkBuilder text"
575 :authors
'("Dmitry Kalyanov")
576 :logo-icon-name
"gtk-apply")))
578 (object-destroy d
)))))))
579 (g-signal-connect (builder-get-object builder
"window1") "destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
580 (statusbar-push (builder-get-object builder
"statusbar1") "times" "0 times")
581 (widget-show (builder-get-object builder
"window1")))))
583 (defun read-text-file (file-name)
584 (with-output-to-string (str)
585 (with-open-file (file file-name
)
587 for line
= (read-line file nil nil
)
590 do
(write-string line str
)))))
592 (defun demo-text-editor ()
593 "More advanced example: text editor with ability to evaluate lisp expressions"
595 (let* ((builder (let ((builder (make-instance 'builder
)))
596 (builder-add-from-file builder
(namestring (merge-pathnames "demo/text-editor.ui" *src-location
*)))
598 (window (builder-get-object builder
"window1"))
599 (text-view (builder-get-object builder
"textview1"))
600 (statusbar (builder-get-object builder
"statusbar1"))
603 (statusbar-push statusbar
"filename" "Untitled *")
604 (labels ((set-properties ()
605 (statusbar-pop statusbar
"filename")
606 (statusbar-push statusbar
"filename" (format nil
"~A~:[~; *~]" (or file-name
"Untitled") modified-p
)))
607 (new (&rest args
) (declare (ignore args
))
610 (text-buffer-text (text-view-buffer text-view
)) "")
612 (cb-open (&rest args
) (declare (ignore args
))
613 (let ((d (make-instance 'file-chooser-dialog
:action
:open
:title
"Open file")))
614 (when file-name
(setf (file-chooser-filename d
) file-name
))
615 (dialog-add-button d
"gtk-open" :accept
)
616 (dialog-add-button d
"gtk-cancel" :cancel
)
617 (when (eq :accept
(dialog-run d
))
618 (setf file-name
(file-chooser-filename d
)
619 (text-buffer-text (text-view-buffer text-view
)) (read-text-file file-name
)
623 (save (&rest args
) (declare (ignore args
))
626 (with-open-file (file file-name
:direction
:output
:if-exists
:supersede
)
627 (write-string (text-buffer-text (text-view-buffer text-view
)) file
))
628 (setf modified-p nil
)
631 (save-as (&rest args
) (declare (ignore args
))
632 (let ((d (make-instance 'file-chooser-dialog
:action
:save
:title
"Save file")))
633 (when file-name
(setf (file-chooser-filename d
) file-name
))
634 (dialog-add-button d
"gtk-save" :accept
)
635 (dialog-add-button d
"gtk-cancel" :cancel
)
636 (if (eq :accept
(dialog-run d
))
638 (setf file-name
(file-chooser-filename d
))
641 (object-destroy d
))))
642 (cut (&rest args
) (declare (ignore args
))
643 (text-buffer-cut-clipboard (text-view-buffer text-view
) (get-clipboard "CLIPBOARD") t
))
644 (copy (&rest args
) (declare (ignore args
))
645 (text-buffer-copy-clipboard (text-view-buffer text-view
) (get-clipboard "CLIPBOARD")))
646 (paste (&rest args
) (declare (ignore args
))
647 (text-buffer-paste-clipboard (text-view-buffer text-view
) (get-clipboard "CLIPBOARD")))
648 (cb-delete (&rest args
) (declare (ignore args
))
649 (let ((buffer (text-view-buffer text-view
)))
650 (multiple-value-bind (i1 i2
) (text-buffer-get-selection-bounds buffer
)
652 (text-buffer-delete buffer i1 i2
)))))
653 (about (&rest args
) (declare (ignore args
))
654 (let ((d (make-instance 'about-dialog
655 :program-name
"Lisp Gtk+ Binding Demo Text Editor"
656 :version
(format nil
"0.0.0.1 ~A" #\GREEK_SMALL_LETTER_ALPHA
)
657 :authors
'("Kalyanov Dmitry")
658 :license
"Public Domain"
659 :logo-icon-name
"accessories-text-editor")))
662 (quit (&rest args
) (declare (ignore args
)) (object-destroy window
))
663 (cb-eval (&rest args
) (declare (ignore args
))
664 (let ((buffer (text-view-buffer text-view
)))
665 (multiple-value-bind (i1 i2
) (text-buffer-get-selection-bounds buffer
)
667 (with-gtk-message-error-handler
668 (let* ((text (text-buffer-slice buffer i1 i2
))
669 (value (eval (read-from-string text
)))
670 (value-str (format nil
"~A" value
))
671 (pos (max (text-iter-offset i1
) (text-iter-offset i2
))))
672 (text-buffer-insert buffer
" => " :position
(text-buffer-get-iter-at-offset buffer pos
))
673 (incf pos
(length " => "))
674 (text-buffer-insert buffer value-str
:position
(text-buffer-get-iter-at-offset buffer pos
)))))))))
675 (builder-connect-signals-simple builder
`(("new" ,#'new
)
678 ("save-as" ,#'save-as
)
682 ("delete" ,#'cb-delete
)
685 ("eval" ,#'cb-eval
)))
686 (g-signal-connect window
"destroy" (lambda (w) (declare (ignore w
)) (leave-gtk-main)))
687 (g-signal-connect (text-view-buffer text-view
) "changed" (lambda (b) (declare (ignore b
)) (setf modified-p t
) (set-properties)))
688 (widget-show window
)))))
690 (defun demo-class-browser ()
691 "Show slots of a given class"
692 (let ((output *standard-output
*))
694 (let* ((window (make-instance 'gtk-window
695 :window-position
:center
696 :title
"Class Browser"
698 :default-height
600))
699 (search-entry (make-instance 'entry
))
700 (search-button (make-instance 'button
:label
"Search"))
701 (scroll (make-instance 'scrolled-window
702 :hscrollbar-policy
:automatic
703 :vscrollbar-policy
:automatic
))
704 (slots-model (make-instance 'array-list-store
))
705 (slots-list (make-instance 'tree-view
:model slots-model
)))
706 (let ((v-box (make-instance 'v-box
))
707 (search-box (make-instance 'h-box
)))
708 (container-add window v-box
)
709 (box-pack-start v-box search-box
:expand nil
)
710 (box-pack-start search-box search-entry
)
711 (box-pack-start search-box search-button
:expand nil
)
712 (box-pack-start v-box scroll
)
713 (container-add scroll slots-list
))
714 (store-add-column slots-model
"gchararray"
716 (format nil
"~S" (closer-mop:slot-definition-name slot
))))
717 (let ((col (make-instance 'tree-view-column
:title
"Slot name"))
718 (cr (make-instance 'cell-renderer-text
)))
719 (tree-view-column-pack-start col cr
)
720 (tree-view-column-add-attribute col cr
"text" 0)
721 (tree-view-append-column slots-list col
))
722 (labels ((display-class-slots (class)
723 (format output
"Displaying ~A~%" class
)
725 repeat
(store-items-count slots-model
)
726 do
(store-remove-item slots-model
(store-item slots-model
0)))
727 (closer-mop:finalize-inheritance class
)
729 for slot in
(closer-mop:class-slots class
)
730 do
(store-add-item slots-model slot
)))
731 (on-search-clicked (button)
732 (declare (ignore button
))
733 (with-gtk-message-error-handler
734 (let* ((class-name (read-from-string (entry-text search-entry
)))
735 (class (find-class class-name
)))
736 (display-class-slots class
)))))
737 (g-signal-connect search-button
"clicked" #'on-search-clicked
))
738 (widget-show window
)))))
740 (defun make-tree-from-sexp (l)
741 (setf l
(if (listp l
) l
(list l
)))
742 (let ((node (make-tree-node :item
(make-tvi :title
(format nil
"~S" (first l
))
743 :value
(format nil
"~S" (class-of (first l
)))))))
744 (iter (for child in
(rest l
))
745 (tree-node-insert-at node
(make-tree-from-sexp child
) (length (tree-node-children node
))))
748 (defun demo-treeview-tree ()
749 "Advanced demo: show s-expression tree structure"
751 (let* ((window (make-instance 'gtk-window
:type
:toplevel
:title
"Treeview (tree)"))
752 (model (make-instance 'tree-lisp-store
))
753 (scroll (make-instance 'scrolled-window
:hscrollbar-policy
:automatic
:vscrollbar-policy
:automatic
))
754 (tree-view (make-instance 'tree-view
:headers-visible t
:width-request
300 :height-request
400 :rules-hint t
))
755 (h-box (make-instance 'h-box
))
756 (v-box (make-instance 'v-box
))
757 (entry (make-instance 'entry
))
758 (button (make-instance 'button
:label
"Display")))
759 (tree-lisp-store-add-column model
"gchararray" #'tvi-title
)
760 (tree-lisp-store-add-column model
"gchararray" #'tvi-value
)
761 (tree-node-insert-at (tree-lisp-store-root model
)
762 (make-tree-from-sexp '(lambda (object &rest initargs
&key
&allow-other-keys
)
766 (setf (tree-view-model tree-view
) model
767 (tree-view-tooltip-column tree-view
) 0)
768 (connect-signal tree-view
"row-activated" (lambda (tv path column
)
769 (declare (ignore tv column
))
770 (format t
"You clicked on row ~A~%" (tree-path-indices path
))))
771 (connect-signal button
"clicked" (lambda (b)
773 (let ((object (read-from-string (entry-text entry
))))
774 (tree-node-remove-at (tree-lisp-store-root model
) 0)
775 (tree-node-insert-at (tree-lisp-store-root model
)
776 (make-tree-from-sexp object
)
778 (container-add window v-box
)
779 (box-pack-start v-box h-box
:expand nil
)
780 (box-pack-start h-box entry
)
781 (box-pack-start h-box button
:expand nil
)
782 (box-pack-start v-box scroll
)
783 (container-add scroll tree-view
)
784 (let ((column (make-instance 'tree-view-column
:title
"Value" :sort-column-id
0))
785 (renderer (make-instance 'cell-renderer-text
:text
"A text")))
786 (tree-view-column-pack-start column renderer
)
787 (tree-view-column-add-attribute column renderer
"text" 0)
788 (tree-view-append-column tree-view column
)
789 (print (tree-view-column-tree-view column
))
790 (print (tree-view-column-cell-renderers column
)))
791 (let ((column (make-instance 'tree-view-column
:title
"Type"))
792 (renderer (make-instance 'cell-renderer-text
:text
"A text")))
793 (tree-view-column-pack-start column renderer
)
794 (tree-view-column-add-attribute column renderer
"text" 1)
795 (tree-view-append-column tree-view column
)
796 (print (tree-view-column-tree-view column
))
797 (print (tree-view-column-cell-renderers column
)))
798 (widget-show window
))))
800 (defclass custom-window
(gtk-window)
801 ((label :initform
(make-instance 'label
:label
"A label text") :reader custom-window-label
)
802 (button :initform
(make-instance 'button
:label
"Click me!") :reader custom-window-button
))
803 (:metaclass gobject-class
)
804 (:default-initargs
:title
"Custom window with default initargs" :default-width
320 :default-height
240))
806 (defun custom-window-label-text (w)
807 (label-label (custom-window-label w
)))
809 (defun (setf custom-window-label-text
) (new-value w
)
810 (setf (label-label (custom-window-label w
)) new-value
))
812 (defmethod initialize-instance :after
((w custom-window
) &key
&allow-other-keys
)
813 (let ((box (make-instance 'v-box
)))
814 (box-pack-start box
(custom-window-label w
))
815 (box-pack-start box
(custom-window-button w
) :expand nil
)
816 (container-add w box
))
817 (connect-signal (custom-window-button w
) "clicked" (lambda (b)
819 (custom-window-button-clicked w
))))
821 (defun custom-window-button-clicked (w)
822 (setf (custom-window-label-text w
)
823 (format nil
"Now is: ~A~%" (get-internal-run-time))))
825 (defun test-custom-window ()
826 "Simple test of non-GObject subclass of GtkWindow"
828 (let ((w (make-instance 'custom-window
)))
831 (defun test-assistant ()
832 "Simple test of GtkAssistant wizard"
833 (let ((output *standard-output
*))
835 (let ((d (make-instance 'assistant
:title
"Username wizard"))
836 (p-1 (make-instance 'h-box
))
837 (entry (make-instance 'entry
))
838 (p-2 (make-instance 'label
:label
"Click Apply to close this wizard")))
839 (box-pack-start p-1
(make-instance 'label
:label
"Enter your name:") :expand nil
)
840 (box-pack-start p-1 entry
)
841 (assistant-append-page d p-1
)
842 (assistant-append-page d p-2
)
843 (setf (assistant-child-title d p-1
) "Username wizard"
844 (assistant-child-title d p-2
) "Username wizard"
845 (assistant-child-complete d p-1
) nil
846 (assistant-child-complete d p-2
) t
847 (assistant-child-page-type d p-1
) :intro
848 (assistant-child-page-type d p-2
) :confirm
849 (assistant-forward-page-function d
) (lambda (i)
850 (format output
"(assistant-forward-page-function ~A)~%" i
)
854 (connect-signal entry
"notify::text" (lambda (object pspec
)
855 (declare (ignore object pspec
))
856 (setf (assistant-child-complete d p-1
)
857 (plusp (length (entry-text entry
))))))
858 (let ((w (make-instance 'label
:label
"A label in action area")))
860 (assistant-add-action-widget d w
))
861 (connect-signal d
"cancel" (lambda (assistant)
862 (declare (ignore assistant
))
864 (format output
"Canceled~%")))
865 (connect-signal d
"close" (lambda (assistant)
866 (declare (ignore assistant
))
868 (format output
"Thank you, ~A~%" (entry-text entry
))))
869 (connect-signal d
"prepare" (lambda (assistant page-widget
)
870 (declare (ignore assistant page-widget
))
871 (format output
"Assistant ~A has ~A pages and is on ~Ath page~%"
872 d
(assistant-n-pages d
) (assistant-current-page d
))))
875 (defun test-entry-completion ()
876 "Not working example of GtkEntryCompletion"
878 (let* ((w (make-instance 'gtk-window
))
879 (model (make-instance 'tree-lisp-store
)))
880 (tree-lisp-store-add-column model
"gchararray" #'identity
)
881 (tree-node-insert-at (tree-lisp-store-root model
) (make-tree-node :item
"Monday") 0)
882 (tree-node-insert-at (tree-lisp-store-root model
) (make-tree-node :item
"Tuesday") 0)
883 (tree-node-insert-at (tree-lisp-store-root model
) (make-tree-node :item
"Wednesday") 0)
884 (tree-node-insert-at (tree-lisp-store-root model
) (make-tree-node :item
"Thursday") 0)
885 (tree-node-insert-at (tree-lisp-store-root model
) (make-tree-node :item
"Friday") 0)
886 (tree-node-insert-at (tree-lisp-store-root model
) (make-tree-node :item
"Saturday") 0)
887 (tree-node-insert-at (tree-lisp-store-root model
) (make-tree-node :item
"Sunday") 0)
888 (let* ((completion (make-instance 'entry-completion
:model model
:text-column
0))
889 (e (make-instance 'entry
:completion completion
)))
890 (setf (entry-completion-text-column completion
) 0)
896 (let* ((window (make-instance 'gtk-window
897 :title
"cl-gtk2-gtk demo"
898 :window-position
:center
900 :default-height
500))
901 (scrolled (make-instance 'scrolled-window
902 :hscrollbar-policy
:automatic
903 :vscrollbar-policy
:automatic
))
904 (viewport (make-instance 'viewport
))
905 (v-box-buttons (make-instance 'v-box
))
906 (v-box-top (make-instance 'v-box
)))
907 (container-add window v-box-top
)
908 (box-pack-start v-box-top
(make-instance 'label
:label
"These are the demos of cl-gtk2-gtk:") :expand nil
)
909 (box-pack-start v-box-top scrolled
)
910 (container-add scrolled viewport
)
911 (container-add viewport v-box-buttons
)
912 (iter (for s in-package
:gtk-demo
:external-only t
)
913 (for fn
= (fdefinition s
))
914 (unless fn
(next-iteration))
915 (when (eq s
'gtk-demo
:demo-all
) (next-iteration))
916 (for docstring
= (documentation fn t
))
917 (for description
= (format nil
"~A~@[~%~A~]" (string-downcase (symbol-name s
)) docstring
))
918 (for label
= (make-instance 'label
:label description
:justify
:center
))
919 (for button
= (make-instance 'button
))
920 (container-add button label
)
921 (connect-signal button
"clicked"
926 (box-pack-start v-box-buttons button
:expand nil
))
927 (widget-show window
))))
929 (defun test-ui-markup ()
931 (let ((label (make-instance 'label
:label
"Hello!")))
932 (let-ui (gtk-window :type
:toplevel
934 :title
"Hello, world!"
939 (:expr label
) :expand nil
941 :hscrollbar-policy
:automatic
942 :vscrollbar-policy
:automatic
943 :shadow-type
:etched-in
946 (label :label
"Insert:") :expand nil
948 (button :label
"gtk-ok" :use-stock t
:var btn
) :expand nil
)
950 (label :label
"Table packing")
955 (label :label
"2 x 1") :left
0 :right
2 :top
0 :bottom
1
956 (label :label
"1 x 1") :left
0 :right
1 :top
1 :bottom
2
957 (label :label
"1 x 1") :left
1 :right
2 :top
1 :bottom
2)))
958 (connect-signal btn
"clicked"
961 (text-buffer-insert (text-view-buffer tv
)
962 (entry-text entry
))))
965 (defun test-list-store ()
966 "Demonstrates usage of list store"
970 :title
"GtkListStore"
975 (label :label
"A GtkListStore") :expand nil
977 :hscrollbar-policy
:automatic
978 :vscrollbar-policy
:automatic
979 (tree-view :var tv
))))
980 (let ((l (make-instance 'list-store
:column-types
'("gint" "gchararray"))))
981 (iter (for i from
0 below
100)
982 (for n
= (random 10000000))
983 (for s
= (format nil
"~R" n
))
984 (list-store-insert-with-values l i n s
))
985 (setf (tree-view-model tv
) l
)
986 (let ((column (make-instance 'tree-view-column
:title
"Number" :sort-column-id
0))
987 (renderer (make-instance 'cell-renderer-text
:text
"A text")))
988 (tree-view-column-pack-start column renderer
)
989 (tree-view-column-add-attribute column renderer
"text" 0)
990 (tree-view-append-column tv column
))
991 (let ((column (make-instance 'tree-view-column
:title
"As string" :sort-column-id
1))
992 (renderer (make-instance 'cell-renderer-text
:text
"A text")))
993 (tree-view-column-pack-start column renderer
)
994 (tree-view-column-add-attribute column renderer
"text" 1)
995 (tree-view-append-column tv column
))
996 (connect-signal tv
"row-activated"
997 (lambda (w path column
)
998 (declare (ignore w column
))
999 (let* ((iter (tree-model-iter-by-path l path
))
1000 (n (tree-model-value l iter
0))
1001 (dialog (make-instance 'message-dialog
1003 :text
(format nil
"Number ~A was clicked" n
)
1006 (object-destroy dialog
)))))
1009 (defun test-tree-store ()
1010 "Demonstrates usage of tree store"
1014 :title
"GtkListStore"
1019 (label :label
"A GtkListStore") :expand nil
1021 :hscrollbar-policy
:automatic
1022 :vscrollbar-policy
:automatic
1023 (tree-view :var tv
))))
1024 (let ((l (make-instance 'tree-store
:column-types
'("gint" "gchararray"))))
1025 (iter (for i from
0 below
100)
1026 (for n
= (random 10000000))
1027 (for s
= (format nil
"~R" n
))
1028 (for it
= (tree-store-insert-with-values l nil i n s
))
1029 (iter (for j from
0 below
10)
1030 (for n2
= (random 10000000))
1031 (for s2
= (format nil
"~R" n
))
1032 (tree-store-insert-with-values l it j n2 s2
)))
1033 (setf (tree-view-model tv
) l
)
1034 (let ((column (make-instance 'tree-view-column
:title
"Number" :sort-column-id
0))
1035 (renderer (make-instance 'cell-renderer-text
:text
"A text")))
1036 (tree-view-column-pack-start column renderer
)
1037 (tree-view-column-add-attribute column renderer
"text" 0)
1038 (tree-view-append-column tv column
))
1039 (let ((column (make-instance 'tree-view-column
:title
"As string" :sort-column-id
1))
1040 (renderer (make-instance 'cell-renderer-text
:text
"A text")))
1041 (tree-view-column-pack-start column renderer
)
1042 (tree-view-column-add-attribute column renderer
"text" 1)
1043 (tree-view-append-column tv column
))
1044 (connect-signal tv
"row-activated"
1045 (lambda (w path column
)
1046 (declare (ignore w column
))
1047 (let* ((iter (tree-model-iter-by-path l path
))
1048 (n (tree-model-value l iter
0))
1049 (dialog (make-instance 'message-dialog
1051 :text
(format nil
"Number ~A was clicked" n
)
1054 (object-destroy dialog
)))))