chiark / gitweb /
Bug fix
[clg] / examples / testgtk.lisp
CommitLineData
55212af1 1;; Common Lisp bindings for GTK+ v2.x
2;; Copyright 1999-2005 Espen S. Johnsen <espen@users.sf.net>
0d07716f 3;;
55212af1 4;; Permission is hereby granted, free of charge, to any person obtaining
5;; a copy of this software and associated documentation files (the
6;; "Software"), to deal in the Software without restriction, including
7;; without limitation the rights to use, copy, modify, merge, publish,
8;; distribute, sublicense, and/or sell copies of the Software, and to
9;; permit persons to whom the Software is furnished to do so, subject to
10;; the following conditions:
0d07716f 11;;
55212af1 12;; The above copyright notice and this permission notice shall be
13;; included in all copies or substantial portions of the Software.
0d07716f 14;;
55212af1 15;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18;; IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19;; CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20;; TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21;; SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
0d07716f 22
55212af1 23;; Parts of this file are direct translations of code from 'testgtk.c'
24;; distributed with the Gtk+ library, and thus covered by the GNU
25;; Lesser General Public License and copyright Peter Mattis, Spencer
26;; Kimball, Josh MacDonald and others.
27
28
19d91f52 29;; $Id: testgtk.lisp,v 1.32 2005/04/25 21:45:05 espen Exp $
129f5f77 30
31#+sbcl(require :gtk)
19d91f52 32#+cmu(asdf:oos 'asdf:load-op :gtk)
0d07716f 33
582a125f 34(defpackage "TESTGTK"
35 (:use "COMMON-LISP" "GTK"))
35ec512c 36
582a125f 37(in-package "TESTGTK")
35ec512c 38
39(defmacro define-toplevel (name (window title &rest initargs) &body body)
40 `(let ((,window nil))
0d07716f 41 (defun ,name ()
35ec512c 42 (unless ,window
6490e9f1 43 (setq ,window (make-instance 'window :title ,title ,@initargs :show-children t))
35ec512c 44 (signal-connect ,window 'destroy #'(lambda () (setq ,window nil)))
0d07716f 45 ,@body)
46
582a125f 47 (when ,window
48 (if (not (widget-visible-p ,window))
49 (widget-show ,window)
50 (widget-hide ,window))))))
35ec512c 51
0d07716f 52
35ec512c 53(defmacro define-dialog (name (dialog title &optional (class 'dialog)
54 &rest initargs)
55 &body body)
56 `(let ((,dialog nil))
0d07716f 57 (defun ,name ()
35ec512c 58 (unless ,dialog
6490e9f1 59 (setq ,dialog (make-instance ,class :title ,title ,@initargs :show-children t))
35ec512c 60 (signal-connect ,dialog 'destroy #'(lambda () (setq ,dialog nil)))
61 ,@body)
0d07716f 62
582a125f 63 (when ,dialog
64 (if (not (widget-visible-p ,dialog))
65 (widget-show ,dialog)
66 (widget-hide ,dialog))))))
0d07716f 67
68
35ec512c 69(defmacro define-simple-dialog (name (dialog title &rest initargs) &body body)
70 `(define-dialog ,name (,dialog ,title 'dialog ,@initargs)
e025589b 71 ,@body
72 (dialog-add-button ,dialog "gtk-close" #'widget-destroy :object t)))
0d07716f 73
74
0d07716f 75
76;;; Pixmaps used in some of the tests
77
78(defvar gtk-mini-xpm
4fb50b71 79 #("15 20 17 1"
0d07716f 80 " c None"
81 ". c #14121F"
82 "+ c #278828"
83 "@ c #9B3334"
84 "# c #284C72"
85 "$ c #24692A"
86 "% c #69282E"
87 "& c #37C539"
88 "* c #1D2F4D"
89 "= c #6D7076"
90 "- c #7D8482"
91 "; c #E24A49"
92 "> c #515357"
93 ", c #9B9C9B"
94 "' c #2FA232"
95 ") c #3CE23D"
96 "! c #3B6CCB"
97 " "
98 " ***> "
99 " >.*!!!* "
100 " ***....#*= "
101 " *!*.!!!**!!# "
102 " .!!#*!#*!!!!# "
103 " @%#!.##.*!!$& "
104 " @;%*!*.#!#')) "
105 " @;;@%!!*$&)'' "
106 " @%.%@%$'&)$+' "
107 " @;...@$'*'*)+ "
108 " @;%..@$+*.')$ "
109 " @;%%;;$+..$)# "
110 " @;%%;@$$$'.$# "
111 " %;@@;;$$+))&* "
112 " %;;;@+$&)&* "
113 " %;;@'))+> "
114 " %;@'&# "
115 " >%$$ "
116 " >= "))
117
118(defvar book-closed-xpm
4fb50b71 119 #("16 16 6 1"
0d07716f 120 " c None s None"
121 ". c black"
122 "X c red"
123 "o c yellow"
124 "O c #808080"
125 "# c white"
126 " "
127 " .. "
128 " ..XX. "
129 " ..XXXXX. "
130 " ..XXXXXXXX. "
131 ".ooXXXXXXXXX. "
132 "..ooXXXXXXXXX. "
133 ".X.ooXXXXXXXXX. "
134 ".XX.ooXXXXXX.. "
135 " .XX.ooXXX..#O "
136 " .XX.oo..##OO. "
137 " .XX..##OO.. "
138 " .X.#OO.. "
139 " ..O.. "
140 " .. "
141 " "))
142
143(defvar mini-page-xpm
4fb50b71 144 #("16 16 4 1"
0d07716f 145 " c None s None"
146 ". c black"
147 "X c white"
148 "o c #808080"
149 " "
150 " ....... "
151 " .XXXXX.. "
152 " .XoooX.X. "
153 " .XXXXX.... "
154 " .XooooXoo.o "
155 " .XXXXXXXX.o "
156 " .XooooooX.o "
157 " .XXXXXXXX.o "
158 " .XooooooX.o "
159 " .XXXXXXXX.o "
160 " .XooooooX.o "
161 " .XXXXXXXX.o "
162 " ..........o "
163 " oooooooooo "
164 " "))
165
166(defvar book-open-xpm
4fb50b71 167 #("16 16 4 1"
0d07716f 168 " c None s None"
169 ". c black"
170 "X c #808080"
171 "o c white"
172 " "
173 " .. "
174 " .Xo. ... "
175 " .Xoo. ..oo. "
176 " .Xooo.Xooo... "
177 " .Xooo.oooo.X. "
178 " .Xooo.Xooo.X. "
179 " .Xooo.oooo.X. "
180 " .Xooo.Xooo.X. "
181 " .Xooo.oooo.X. "
182 " .Xoo.Xoo..X. "
183 " .Xo.o..ooX. "
184 " .X..XXXXX. "
185 " ..X....... "
186 " .. "
187 " "))
188
189
190
191;;; Button box
192
4fb50b71 193(defun create-bbox-in-frame (class frame-label spacing width height layout)
35ec512c 194 (declare (ignore width height))
195 (make-instance 'frame
196 :label frame-label
197 :child (make-instance class
198 :border-width 5 :layout-style layout :spacing spacing
8804934b 199 :child (make-instance 'button :stock "gtk-ok")
200 :child (make-instance 'button :stock "gtk-cancel")
201 :child (make-instance 'button :stock "gtk-help"))))
35ec512c 202
203(define-toplevel create-button-box (window "Button Boxes")
204 (make-instance 'v-box
6490e9f1 205 :parent window :border-width 10 :spacing 10
35ec512c 206 :child (make-instance 'frame
207 :label "Horizontal Button Boxes"
208 :child (make-instance 'v-box
209 :border-width 10 :spacing 10
210 :children (mapcar
211 #'(lambda (args)
212 (apply #'create-bbox-in-frame
213 'h-button-box args))
214 '(("Spread" 40 85 20 :spread)
215 ("Edge" 40 85 20 :edge)
216 ("Start" 40 85 20 :start)
217 ("End" 40 85 20 :end)))))
218 :child (make-instance 'frame
219 :label "Vertical Button Boxes"
220 :child (make-instance 'h-box
221 :border-width 10 :spacing 10
222 :children (mapcar
223 #'(lambda (args)
224 (apply #'create-bbox-in-frame
225 'v-button-box args))
226 '(("Spread" 30 85 20 :spread)
227 ("Edge" 30 85 20 :edge)
228 ("Start" 30 85 20 :start)
229 ("End" 30 85 20 :end)))))))
4fb50b71 230
231
232;; Buttons
233
35ec512c 234(define-simple-dialog create-buttons (dialog "Buttons")
4fb50b71 235 (let ((table (make-instance 'table
35ec512c 236 :n-rows 3 :n-columns 3 :homogeneous nil
4fb50b71 237 :row-spacing 5 :column-spacing 5 :border-width 10
35ec512c 238 :parent dialog))
239 (buttons (loop
240 for n from 1 to 10
241 collect (make-instance 'button
242 :label (format nil "button~D" (1+ n))))))
243
4fb50b71 244 (dotimes (column 3)
245 (dotimes (row 3)
35ec512c 246 (let ((button (nth (+ (* 3 row) column) buttons))
247 (button+1 (nth (mod (+ (* 3 row) column 1) 9) buttons)))
4fb50b71 248 (signal-connect button 'clicked
249 #'(lambda ()
250 (if (widget-visible-p button+1)
251 (widget-hide button+1)
252 (widget-show button+1))))
81f2aa93 253 (table-attach table button column (1+ column) row (1+ row)
6490e9f1 254 :options '(:expand :fill)))))))
0d07716f 255
256
257;; Calenadar
258
35ec512c 259(define-simple-dialog create-calendar (dialog "Calendar")
260 (make-instance 'v-box
6490e9f1 261 :parent dialog :border-width 10
35ec512c 262 :child (make-instance 'calendar)))
0d07716f 263
264
265;;; Check buttons
266
35ec512c 267(define-simple-dialog create-check-buttons (dialog "Check Buttons")
268 (make-instance 'v-box
6490e9f1 269 :border-width 10 :spacing 10 :parent dialog
35ec512c 270 :children (loop
271 for n from 1 to 3
272 collect (make-instance 'check-button
273 :label (format nil "Button~D" n)))))
0d07716f 274
275
276
277;;; Color selection
278
35ec512c 279(define-dialog create-color-selection (dialog "Color selection dialog"
280 'color-selection-dialog
6490e9f1 281 :allow-grow nil :allow-shrink nil
282 :show-children nil)
283 (with-slots (colorsel) dialog
284 (let ((button (make-instance 'check-button :label "Show Opacity")))
285 (dialog-add-action-widget dialog button
286 #'(lambda ()
287 (setf
288 (color-selection-has-opacity-control-p colorsel)
289 (toggle-button-active-p button)))))
290
291 (let ((button (make-instance 'check-button :label "Show Palette")))
292 (dialog-add-action-widget dialog button
293 #'(lambda ()
294 (setf
295 (color-selection-has-palette-p colorsel)
296 (toggle-button-active-p button)))))
35ec512c 297
298 (signal-connect dialog :ok
299 #'(lambda ()
300 (let ((color (color-selection-current-color colorsel)))
301 (format t "Selected color: ~A~%" color)
302 (setf (color-selection-current-color colorsel) color)
303 (widget-hide dialog))))
0d07716f 304
35ec512c 305 (signal-connect dialog :cancel #'widget-destroy :object t)))
0d07716f 306
0d07716f 307
308;;; Cursors
309
310(defun clamp (n min-val max-val)
311 (declare (number n min-val max-val))
312 (max (min n max-val) min-val))
313
af5eb952 314(defun set-cursor (spinner drawing-area label)
315 (let ((cursor
316 (glib:int-enum
317 (logand (clamp (spin-button-value-as-int spinner) 0 152) #xFE)
318 'gdk:cursor-type)))
319 (setf (label-label label) (string-downcase cursor))
320 (setf (widget-cursor drawing-area) cursor)))
321
322(defun cursor-expose (drawing-area event)
323 (declare (ignore event))
324 (multiple-value-bind (width height)
8804934b 325 (widget-get-size-allocation drawing-area)
af5eb952 326 (let* ((window (widget-window drawing-area))
327 (style (widget-style drawing-area))
328 (white-gc (style-white-gc style))
329 (gray-gc (style-bg-gc style :normal))
330 (black-gc (style-black-gc style)))
331 (gdk:draw-rectangle window white-gc t 0 0 width (floor height 2))
332 (gdk:draw-rectangle window black-gc t 0 (floor height 2) width
333 (floor height 2))
334 (gdk:draw-rectangle window gray-gc t (floor width 3)
335 (floor height 3) (floor width 3)
336 (floor height 3))))
337 t)
338
339(define-simple-dialog create-cursors (dialog "Cursors")
340 (let ((spinner (make-instance 'spin-button
341 :adjustment (adjustment-new
342 0 0
e7020c53 343 (1- (glib:enum-int :last-cursor 'gdk:cursor-type))
af5eb952 344 2 10 0)))
345 (drawing-area (make-instance 'drawing-area
346 :width-request 80 :height-request 80
8f0159a6 347 :events '(:exposure :button-press)))
af5eb952 348 (label (make-instance 'label :label "XXX")))
349
350 (signal-connect drawing-area 'expose-event #'cursor-expose :object t)
351
352 (signal-connect drawing-area 'button-press-event
353 #'(lambda (event)
354 (case (gdk:event-button event)
45314d76 355 (1 (spin-button-spin spinner :step-forward))
356 (3 (spin-button-spin spinner :step-backward)))
af5eb952 357 t))
0d07716f 358
af5eb952 359 (signal-connect drawing-area 'scroll-event
360 #'(lambda (event)
361 (case (gdk:event-direction event)
45314d76 362 (:up (spin-button-spin spinner :step-forward))
363 (:down (spin-button-spin spinner :step-backward)))
af5eb952 364 t))
0d07716f 365
af5eb952 366 (signal-connect spinner 'changed
367 #'(lambda ()
368 (set-cursor spinner drawing-area label)))
0d07716f 369
af5eb952 370 (make-instance 'v-box
6490e9f1 371 :parent dialog :border-width 10 :spacing 5
af5eb952 372 :child (list
373 (make-instance 'h-box
374 :border-width 5
375 :child (list
376 (make-instance 'label :label "Cursor Value : ")
377 :expand nil)
378 :child spinner)
379 :expand nil)
380 :child (make-instance 'frame
af5eb952 381 :label "Cursor Area" :label-xalign 0.5 :border-width 10
382 :child drawing-area)
383 :child (list label :expand nil))
384
385 (widget-realize drawing-area)
386 (set-cursor spinner drawing-area label)))
0d07716f 387
388
389;;; Dialog
390
35ec512c 391(let ((dialog nil))
392 (defun create-dialog ()
393 (unless dialog
394 (setq dialog (make-instance 'dialog
395 :title "Dialog" :default-width 200
396 :button "Toggle"
397 :button (list "gtk-ok" #'widget-destroy :object t)
398 :signal (list 'destroy
399 #'(lambda ()
400 (setq dialog nil)))))
401
402 (let ((label (make-instance 'label
403 :label "Dialog Test" :xpad 10 :ypad 10 :visible t
404 :parent dialog)))
405 (signal-connect dialog "Toggle"
406 #'(lambda ()
407 (if (widget-visible-p label)
408 (widget-hide label)
409 (widget-show label))))))
0d07716f 410
35ec512c 411 (if (widget-visible-p dialog)
412 (widget-hide dialog)
413 (widget-show dialog))))
0d07716f 414
415
416;; Entry
417
35ec512c 418(define-simple-dialog create-entry (dialog "Entry")
419 (let ((main (make-instance 'v-box
420 :border-width 10 :spacing 10 :parent dialog)))
4fb50b71 421
35ec512c 422 (let ((entry (make-instance 'entry :text "hello world" :parent main)))
423 (editable-select-region entry 0 5) ; this has no effect when
424 ; entry is editable
425;; (editable-insert-text entry "great " 6)
426;; (editable-delete-text entry 6 12)
4fb50b71 427
e52cf822 428 (let ((combo (make-instance 'combo-box-entry
35ec512c 429 :parent main
e52cf822 430 :content '("item0"
431 "item1 item1"
432 "item2 item2 item2"
433 "item3 item3 item3 item3"
434 "item4 item4 item4 item4 item4"
435 "item5 item5 item5 item5 item5 item5"
436 "item6 item6 item6 item6 item6"
437 "item7 item7 item7 item7"
438 "item8 item8 item8"
439 "item9 item9"))))
440 (with-slots (child) combo
441 (setf (editable-text child) "hello world")
442 (editable-select-region child 0)))
35ec512c 443
444 (flet ((create-check-button (label slot)
445 (make-instance 'check-button
446 :label label :active t :parent main
447 :signal (list 'toggled
448 #'(lambda (button)
449 (setf (slot-value entry slot)
450 (toggle-button-active-p button)))
451 :object t))))
452
453 (create-check-button "Editable" 'editable)
454 (create-check-button "Visible" 'visibility)
6490e9f1 455 (create-check-button "Sensitive" 'sensitive)))))
0d07716f 456
0d07716f 457
36c95ad8 458;; Expander
459
460(define-simple-dialog create-expander (dialog "Expander" :resizable nil)
461 (make-instance 'v-box
6490e9f1 462 :parent dialog :spacing 5 :border-width 5
36c95ad8 463 :child (create-label "Expander demo. Click on the triangle for details.")
464 :child (make-instance 'expander
465 :label "Details"
466 :child (create-label "Details can be shown or hidden."))))
467
0d07716f 468
35ec512c 469;; File chooser dialog
0d07716f 470
35ec512c 471(define-dialog create-file-chooser (dialog "File Chooser" 'file-chooser-dialog)
d5e2ce7c 472 (file-chooser-add-filter dialog
473 (make-instance 'file-filter :name "All files" :pattern "*"))
474 (file-chooser-add-filter dialog
475 (make-instance 'file-filter :name "Common Lisp source code"
476 :patterns '("*.lisp" "*.lsp")))
477
35ec512c 478 (dialog-add-button dialog "gtk-cancel" #'widget-destroy :object t)
479 (dialog-add-button dialog "gtk-ok"
480 #'(lambda ()
ab652f5f 481 (if (slot-boundp dialog 'filename)
7c1f9a1e 482 (format t "Selected file: ~A~%" (file-chooser-filename dialog))
483 (write-line "No files selected"))
35ec512c 484 (widget-destroy dialog))))
0d07716f 485
486
b9d3ad20 487;; Font selection dialog
488
489(define-toplevel create-font-selection (window "Font Button" :resizable nil)
490 (make-instance 'h-box
491 :parent window :spacing 8 :border-width 8
492 :child (make-instance 'label :label "Pick a font")
493 :child (make-instance 'font-button
494 :use-font t :title "Font Selection Dialog")))
495
0d07716f 496
582a125f 497;;; Icon View
498
499#+gtk2.6
500(let ((file-pixbuf nil)
501 (folder-pixbuf nil))
502 (defun load-pixbufs ()
503 (unless file-pixbuf
504 (handler-case
505 (setf
506 file-pixbuf (gdk:pixbuf-load #p"clg:examples;gnome-fs-regular.png")
507 folder-pixbuf (gdk:pixbuf-load #p"clg:examples;gnome-fs-directory.png"))
508 (glib:glib-error (condition)
509 (make-instance 'message-dialog
510 :message-type :error :visible t
511 :text "<b>Failed to load an image</b>"
512 :secondary-text (glib:gerror-message condition)
513 :signal (list :close #'widget-destroy :object t))
514 (return-from load-pixbufs nil))))
515 t)
516
517 (defun fill-store (store directory)
518 (list-store-clear store)
519 (let ((dir #+cmu(unix:open-dir directory)
520 #+sbcl(sb-posix:opendir directory)))
521 (unwind-protect
522 (loop
523 as filename = #+cmu(unix:read-dir dir)
524 #+sbcl(let ((dirent (sb-posix:readdir dir)))
525 (unless (sb-grovel::foreign-nullp dirent)
526 (sb-posix:dirent-name dirent)))
527 while filename
528 unless (or (equal filename ".") (equal filename ".."))
529 do (let* ((pathname (format nil "~A~A" directory filename))
530 (directory-p
531 #+cmu(eq (unix:unix-file-kind pathname) :directory)
532 #+sbcl(sb-posix:s-isdir (sb-posix:stat-mode (sb-posix:stat pathname)))))
533 (list-store-append store
534 (vector
535 filename
536 (if directory-p folder-pixbuf file-pixbuf)
537 directory-p))))
538 #+cmu(unix:close-dir dir)
539 #+sbcl(sb-posix:closedir dir))))
540
541 (defun sort-func (store a b)
542 (let ((a-dir-p (tree-model-value store a 'directory-p))
543 (b-dir-p (tree-model-value store b 'directory-p))
544 (a-name (tree-model-value store a 'filename))
545 (b-name (tree-model-value store b 'filename)))
546 (cond
547 ((and a-dir-p (not b-dir-p)) :before)
548 ((and (not a-dir-p) b-dir-p) :after)
549 ((string< a-name b-name) :before)
550 ((string> a-name b-name) :after)
551 (t :equal))))
552
553 (defun parent-dir (dir)
554 (let ((end (1+ (position #\/ dir :from-end t :end (1- (length dir))))))
555 (subseq dir 0 end)))
556
557 (define-toplevel create-icon-view (window "Icon View demo"
558 :default-width 650
559 :default-height 400)
560 (if (not (load-pixbufs))
561 (widget-destroy window)
562 (let* ((directory "/")
563 (store (make-instance 'list-store
564 :column-types '(string gdk:pixbuf boolean)
565 :column-names '(filename pixbuf directory-p)))
566 (icon-view (make-instance 'icon-view
567 :model store :selection-mode :multiple
568 :text-column 'filename :pixbuf-column 'pixbuf))
569 (up (make-instance 'tool-button
570 :stock "gtk-go-up" :is-important t :sensitive nil))
571 (home (make-instance 'tool-button
572 :stock "gtk-home" :is-important t)))
573 (tree-sortable-set-sort-func store :default #'sort-func)
574 (tree-sortable-set-sort-column store :default :ascending)
575 (fill-store store directory)
576
577 (signal-connect icon-view 'item-activated
578 #'(lambda (path)
579 (when (tree-model-value store path 'directory-p)
580 (setq directory
581 (concatenate 'string directory (tree-model-value store path 'filename) "/"))
582 (fill-store store directory)
583 (setf (widget-sensitive-p up) t))))
584
585 (signal-connect up 'clicked
586 #'(lambda ()
587 (unless (string= directory "/")
588 (setq directory (parent-dir directory))
589 (fill-store store directory)
590 (setf
591 (widget-sensitive-p home)
592 (not (string= directory (namestring (truename #p"clg:")))))
593 (setf (widget-sensitive-p up) (not (string= directory "/"))))))
594
595 (signal-connect home 'clicked
596 #'(lambda ()
597 (setq directory (namestring (truename #p"clg:")))
598 (fill-store store directory)
599 (setf (widget-sensitive-p up) t)
600 (setf (widget-sensitive-p home) nil)))
601
602 (make-instance 'v-box
603 :parent window
604 :child (list
605 (make-instance 'toolbar :child up :child home)
606 :fill nil :expand nil)
607 :child (make-instance 'scrolled-window
608 :shadow-type :etched-in :policy :automatic
609 :child icon-view))))))
610
611
35ec512c 612;;; Image
0d07716f 613
c1f1a833 614(define-toplevel create-image (window "Image" :resizable nil)
35ec512c 615 (make-instance 'image :file #p"clg:examples;gtk.png" :parent window))
0d07716f 616
617
618;;; Labels
619
35ec512c 620(define-toplevel create-labels (window "Labels" :border-width 5 :resizable nil)
4fb50b71 621 (flet ((create-label-in-frame (frame-label label-text &rest args)
622 (list
623 (make-instance 'frame
624 :label frame-label
35ec512c 625 :child (apply #'make-instance 'label :label label-text :xpad 5 :ypad 5 args))
4fb50b71 626 :fill nil :expand nil)))
35ec512c 627 (make-instance 'h-box
628 :spacing 5 :parent window
629 :child-args '(:fill nil :expand nil)
630 :child (make-instance 'v-box
631 :spacing 5
632 :child (create-label-in-frame "Normal Label" "This is a Normal label")
633 :child (create-label-in-frame "Multi-line Label"
0d07716f 634"This is a Multi-line label.
635Second line
4fb50b71 636Third line")
35ec512c 637 :child (create-label-in-frame "Left Justified Label"
0d07716f 638"This is a Left-Justified
639Multi-line.
4fb50b71 640Third line"
35ec512c 641 :justify :left)
642 :child (create-label-in-frame "Right Justified Label"
0d07716f 643"This is a Right-Justified
644Multi-line.
4fb50b71 645Third line"
35ec512c 646 :justify :right))
647 :child (make-instance 'v-box
648 :spacing 5
649 :child (create-label-in-frame "Line wrapped label"
0d07716f 650"This is an example of a line-wrapped label. It should not be taking up the entire width allocated to it, but automatically wraps the words to fit. The time has come, for all good men, to come to the aid of their party. The sixth sheik's six sheep's sick.
4fb50b71 651 It supports multiple paragraphs correctly, and correctly adds many extra spaces. "
35ec512c 652 :wrap t)
653
654 :child (create-label-in-frame "Filled, wrapped label"
0d07716f 655"This is an example of a line-wrapped, filled label. It should be taking up the entire width allocated to it. Here is a seneance to prove my point. Here is another sentence. Here comes the sun, do de do de do.
656 This is a new paragraph.
4fb50b71 657 This is another newer, longer, better paragraph. It is coming to an end, unfortunately."
35ec512c 658 :justify :fill :wrap t)
659
660 :child (create-label-in-frame "Underlined label"
e7020c53 661(#+cmu glib:latin1-to-unicode #+sbcl identity
0d07716f 662"This label is underlined!
e7020c53 663