1 ;; Common Lisp bindings for GTK+ v2.0
2 ;; Copyright (C) 1999-2000 Espen S. Johnsen <espejohn@online.no>
4 ;; This library is free software; you can redistribute it and/or
5 ;; modify it under the terms of the GNU Lesser General Public
6 ;; License as published by the Free Software Foundation; either
7 ;; version 2 of the License, or (at your option) any later version.
9 ;; This library is distributed in the hope that it will be useful,
10 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
11 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 ;; Lesser General Public License for more details.
14 ;; You should have received a copy of the GNU Lesser General Public
15 ;; License along with this library; if not, write to the Free Software
16 ;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 ;; $Id: testgtk.lisp,v 1.14 2004/12/29 21:21:31 espen Exp $
21 ;;; Some of the code in this file are really outdatet, but it is
22 ;;; still the most complete example of how to use the library
28 (defmacro define-toplevel (name (window title &rest initargs) &body body)
32 (setq ,window (apply #'make-instance 'window :title ,title ',initargs))
33 (signal-connect ,window 'destroy #'(lambda () (setq ,window nil)))
36 (if (not (widget-visible-p ,window))
37 (widget-show-all ,window)
38 (widget-hide ,window)))))
41 (defmacro define-dialog (name (dialog title &optional (class 'dialog)
47 (setq ,dialog (apply #'make-instance ,class :title ,title ',initargs))
48 (signal-connect ,dialog 'destroy #'(lambda () (setq ,dialog nil)))
51 (if (not (widget-visible-p ,dialog))
53 (widget-hide ,dialog)))))
56 (defmacro define-simple-dialog (name (dialog title &rest initargs) &body body)
57 `(define-dialog ,name (,dialog ,title 'dialog ,@initargs)
59 (dialog-add-button ,dialog "gtk-close" #'widget-destroy :object t)))
63 ;;; Pixmaps used in some of the tests
105 (defvar book-closed-xpm
130 (defvar mini-page-xpm
153 (defvar book-open-xpm
180 (defun create-bbox-in-frame (class frame-label spacing width height layout)
181 (declare (ignore width height))
182 (make-instance 'frame
184 :child (make-instance class
185 :border-width 5 :layout-style layout :spacing spacing
186 :child (make-instance 'button :stock "gtk-ok")
187 :child (make-instance 'button :stock "gtk-cancel")
188 :child (make-instance 'button :stock "gtk-help"))))
190 (define-toplevel create-button-box (window "Button Boxes")
191 (make-instance 'v-box
192 :parent window :border-width 10 :spacing 10 :show-all t
193 :child (make-instance 'frame
194 :label "Horizontal Button Boxes"
195 :child (make-instance 'v-box
196 :border-width 10 :spacing 10
199 (apply #'create-bbox-in-frame
201 '(("Spread" 40 85 20 :spread)
202 ("Edge" 40 85 20 :edge)
203 ("Start" 40 85 20 :start)
204 ("End" 40 85 20 :end)))))
205 :child (make-instance 'frame
206 :label "Vertical Button Boxes"
207 :child (make-instance 'h-box
208 :border-width 10 :spacing 10
211 (apply #'create-bbox-in-frame
213 '(("Spread" 30 85 20 :spread)
214 ("Edge" 30 85 20 :edge)
215 ("Start" 30 85 20 :start)
216 ("End" 30 85 20 :end)))))))
221 (define-simple-dialog create-buttons (dialog "Buttons")
222 (let ((table (make-instance 'table
223 :n-rows 3 :n-columns 3 :homogeneous nil
224 :row-spacing 5 :column-spacing 5 :border-width 10
228 collect (make-instance 'button
229 :label (format nil "button~D" (1+ n))))))
233 (let ((button (nth (+ (* 3 row) column) buttons))
234 (button+1 (nth (mod (+ (* 3 row) column 1) 9) buttons)))
235 (signal-connect button 'clicked
237 (if (widget-visible-p button+1)
238 (widget-hide button+1)
239 (widget-show button+1))))
240 (table-attach table button column (1+ column) row (1+ row)
241 :options '(:expand :fill)))))
242 (widget-show-all table)))
247 (define-simple-dialog create-calendar (dialog "Calendar")
248 (make-instance 'v-box
249 :parent dialog :border-width 10 :show-all t
250 :child (make-instance 'calendar)))
255 (define-simple-dialog create-check-buttons (dialog "Check Buttons")
256 (make-instance 'v-box
257 :border-width 10 :spacing 10 :parent dialog :show-all t
260 collect (make-instance 'check-button
261 :label (format nil "Button~D" n)))))
267 (define-dialog create-color-selection (dialog "Color selection dialog"
268 'color-selection-dialog
269 :allow-grow nil :allow-shrink nil)
270 (with-slots (action-area colorsel) dialog
271 ;; This seg faults for some unknown reason
272 ;; (let ((button (make-instance 'check-button :label "Show Palette")))
273 ;; (dialog-add-action-widget dialog button
276 ;; (color-selection-has-palette-p colorsel)
277 ;; (toggle-button-active-p button)))))
279 (container-add action-area
280 (create-check-button "Show Opacity"
282 (setf (color-selection-has-opacity-control-p colorsel) state))))
284 (container-add action-area
285 (create-check-button "Show Palette"
287 (setf (color-selection-has-palette-p colorsel) state))))
289 (signal-connect dialog :ok
291 (let ((color (color-selection-current-color colorsel)))
292 (format t "Selected color: ~A~%" color)
293 (setf (color-selection-current-color colorsel) color)
294 (widget-hide dialog))))
296 (signal-connect dialog :cancel #'widget-destroy :object t)))
301 (defun clamp (n min-val max-val)
302 (declare (number n min-val max-val))
303 (max (min n max-val) min-val))
305 (defun set-cursor (spinner drawing-area label)
308 (logand (clamp (spin-button-value-as-int spinner) 0 152) #xFE)
310 (setf (label-label label) (string-downcase cursor))
311 (setf (widget-cursor drawing-area) cursor)))
313 (defun cursor-expose (drawing-area event)
314 (declare (ignore event))
315 (multiple-value-bind (width height)
316 (widget-get-size-allocation drawing-area)
317 (let* ((window (widget-window drawing-area))
318 (style (widget-style drawing-area))
319 (white-gc (style-white-gc style))
320 (gray-gc (style-bg-gc style :normal))
321 (black-gc (style-black-gc style)))
322 (gdk:draw-rectangle window white-gc t 0 0 width (floor height 2))
323 (gdk:draw-rectangle window black-gc t 0 (floor height 2) width
325 (gdk:draw-rectangle window gray-gc t (floor width 3)
326 (floor height 3) (floor width 3)
330 (define-simple-dialog create-cursors (dialog "Cursors")
331 (let ((spinner (make-instance 'spin-button
332 :adjustment (adjustment-new
334 (1- (enum-int :last-cursor 'gdk:cursor-type))
336 (drawing-area (make-instance 'drawing-area
337 :width-request 80 :height-request 80
338 :events '(:exposure-mask :button-press-mask)))
339 (label (make-instance 'label :label "XXX")))
341 (signal-connect drawing-area 'expose-event #'cursor-expose :object t)
343 (signal-connect drawing-area 'button-press-event
345 (case (gdk:event-button event)
346 (1 (spin-button-spin spinner :step-forward 0.0))
347 (3 (spin-button-spin spinner :step-backward 0.0)))
350 (signal-connect drawing-area 'scroll-event
352 (case (gdk:event-direction event)
353 (:up (spin-button-spin spinner :step-forward 0.0))
354 (:down (spin-button-spin spinner :step-backward 0.0)))
357 (signal-connect spinner 'changed
359 (set-cursor spinner drawing-area label)))
361 (make-instance 'v-box
362 :parent dialog :border-width 10 :spacing 5 :show-all t
364 (make-instance 'h-box
367 (make-instance 'label :label "Cursor Value : ")
371 :child (make-instance 'frame
372 ; :shadow-type :etched-in
373 :label "Cursor Area" :label-xalign 0.5 :border-width 10
375 :child (list label :expand nil))
377 (widget-realize drawing-area)
378 (set-cursor spinner drawing-area label)))
384 (defun create-dialog ()
386 (setq dialog (make-instance 'dialog
387 :title "Dialog" :default-width 200
389 :button (list "gtk-ok" #'widget-destroy :object t)
390 :signal (list 'destroy
392 (setq dialog nil)))))
394 (let ((label (make-instance 'label
395 :label "Dialog Test" :xpad 10 :ypad 10 :visible t
397 (signal-connect dialog "Toggle"
399 (if (widget-visible-p label)
401 (widget-show label))))))
403 (if (widget-visible-p dialog)
405 (widget-show dialog))))
410 (define-simple-dialog create-entry (dialog "Entry")
411 (let ((main (make-instance 'v-box
412 :border-width 10 :spacing 10 :parent dialog)))
414 (let ((entry (make-instance 'entry :text "hello world" :parent main)))
415 (editable-select-region entry 0 5) ; this has no effect when
417 ;; (editable-insert-text entry "great " 6)
418 ;; (editable-delete-text entry 6 12)
420 (let ((combo (make-instance 'combo-box-entry
425 "item3 item3 item3 item3"
426 "item4 item4 item4 item4 item4"
427 "item5 item5 item5 item5 item5 item5"
428 "item6 item6 item6 item6 item6"
429 "item7 item7 item7 item7"
432 (with-slots (child) combo
433 (setf (editable-text child) "hello world")
434 (editable-select-region child 0)))
436 (flet ((create-check-button (label slot)
437 (make-instance 'check-button
438 :label label :active t :parent main
439 :signal (list 'toggled
441 (setf (slot-value entry slot)
442 (toggle-button-active-p button)))
445 (create-check-button "Editable" 'editable)
446 (create-check-button "Visible" 'visibility)
447 (create-check-button "Sensitive" 'sensitive)))
448 (widget-show-all main)))
453 (define-simple-dialog create-expander (dialog "Expander" :resizable nil)
454 (make-instance 'v-box
455 :parent dialog :spacing 5 :border-width 5 :show-all t
456 :child (create-label "Expander demo. Click on the triangle for details.")
457 :child (make-instance 'expander
459 :child (create-label "Details can be shown or hidden."))))
462 ;; File chooser dialog
464 (define-dialog create-file-chooser (dialog "File Chooser" 'file-chooser-dialog)
465 (dialog-add-button dialog "gtk-cancel" #'widget-destroy :object t)
466 (dialog-add-button dialog "gtk-ok"
468 (if (slot-boundp dialog 'filename)
469 (format t "Selected file: ~A~%" (file-chooser-filename dialog))
470 (write-line "No files selected"))
471 (widget-destroy dialog))))
477 ;; (defun create-handle-box-toolbar ()
478 ;; (let ((toolbar (toolbar-new :horizontal :both)))
479 ;; (toolbar-append-item
480 ;; toolbar "Horizontal" (pixmap-new "clg:examples;test.xpm")
481 ;; :tooltip-text "Horizontal toolbar layout"
482 ;; :callback #'(lambda () (setf (toolbar-orientation toolbar) :horizontal)))
484 ;; (toolbar-append-item
485 ;; toolbar "Vertical" (pixmap-new "clg:examples;test.xpm")
486 ;; :tooltip-text "Vertical toolbar layout"
487 ;; :callback #'(lambda () (setf (toolbar-orientation toolbar) :vertical)))
489 ;; (toolbar-append-space toolbar)
491 ;; (toolbar-append-item
492 ;; toolbar "Icons" (pixmap-new "clg:examples;test.xpm")
493 ;; :tooltip-text "Only show toolbar icons"
494 ;; :callback #'(lambda () (setf (toolbar-style toolbar) :icons)))
496 ;; (toolbar-append-item
497 ;; toolbar "Text" (pixmap-new "clg:examples;test.xpm")
498 ;; :tooltip-text "Only show toolbar text"
499 ;; :callback #'(lambda () (setf (toolbar-style toolbar) :text)))
501 ;; (toolbar-append-item
502 ;; toolbar "Both" (pixmap-new "clg:examples;test.xpm")
503 ;; :tooltip-text "Show toolbar icons and text"
504 ;; :callback #'(lambda () (setf (toolbar-style toolbar) :both)))
506 ;; (toolbar-append-space toolbar)
508 ;; (toolbar-append-item
509 ;; toolbar "Small" (pixmap-new "clg:examples;test.xpm")
510 ;; :tooltip-text "Use small spaces"
511 ;; :callback #'(lambda () (setf (toolbar-space-size toolbar) 5)))
513 ;; (toolbar-append-item
514 ;; toolbar "Big" (pixmap-new "clg:examples;test.xpm")
515 ;; :tooltip-text "Use big spaces"
516 ;; :callback #'(lambda () (setf (toolbar-space-size toolbar) 10)))
518 ;; (toolbar-append-space toolbar)
520 ;; (toolbar-append-item
521 ;; toolbar "Enable" (pixmap-new "clg:examples;test.xpm")
522 ;; :tooltip-text "Enable tooltips"
523 ;; :callback #'(lambda () (toolbar-enable-tooltips toolbar)))
525 ;; (toolbar-append-item
526 ;; toolbar "Disable" (pixmap-new "clg:examples;test.xpm")
527 ;; :tooltip-text "Disable tooltips"
528 ;; :callback #'(lambda () (toolbar-disable-tooltips toolbar)))
530 ;; (toolbar-append-space toolbar)
532 ;; (toolbar-append-item
533 ;; toolbar "Borders" (pixmap-new "clg:examples;test.xpm")
534 ;; :tooltip-text "Show borders"
535 ;; :callback #'(lambda () (setf (toolbar-relief toolbar) :normal)))
537 ;; (toolbar-append-item
538 ;; toolbar "Borderless" (pixmap-new "clg:examples;test.xpm")
539 ;; :tooltip-text "Hide borders"
540 ;; :callback #'(lambda () (setf (toolbar-relief toolbar) :none)))
545 ;; (defun handle-box-child-signal (handle-box child action)
546 ;; (format t "~S: child ~S ~A~%" handle-box child action))
549 ;; (define-test-window create-handle-box "Handle Box Test"
550 ;; (setf (window-allow-grow-p window) t)
551 ;; (setf (window-allow-shrink-p window) t)
552 ;; (setf (window-auto-shrink-p window) nil)
553 ;; (setf (container-border-width window) 20)
554 ;; (let ((v-box (v-box-new nil 0)))
555 ;; (container-add window v-box)
557 ;; (container-add v-box (create-label "Above"))
558 ;; (container-add v-box (hseparator-new))
560 ;; (let ((hbox (hbox-new nil 10)))
561 ;; (container-add v-box hbox)
563 ;; (let ((handle-box (handle-box-new)))
564 ;; (box-pack-start hbox handle-box nil nil 0)
566 ;; handle-box 'child-attached
568 ;; (handle-box-child-signal handle-box child "attached")))
570 ;; handle-box 'child-detached
572 ;; (handle-box-child-signal handle-box child "detached")))
573 ;; (container-add handle-box (create-handle-box-toolbar)))
575 ;; (let ((handle-box (handle-box-new)))
576 ;; (box-pack-start hbox handle-box nil nil 0)
578 ;; handle-box 'child-attached
580 ;; (handle-box-child-signal handle-box child "attached")))
582 ;; handle-box 'child-detached
584 ;; (handle-box-child-signal handle-box child "detached")))
586 ;; (let ((handle-box2 (handle-box-new)))
587 ;; (container-add handle-box handle-box2)
589 ;; handle-box2 'child-attached
591 ;; (handle-box-child-signal handle-box child "attached")))
593 ;; handle-box2 'child-detached
595 ;; (handle-box-child-signal handle-box child "detached")))
596 ;; (container-add handle-box2 (create-label "Foo!")))))
598 ;; (container-add v-box (hseparator-new))
599 ;; (container-add v-box (create-label "Below"))))
603 (define-toplevel create-image (window "Image")
604 (make-instance 'image :file #p"clg:examples;gtk.png" :parent window))
609 (define-toplevel create-labels (window "Labels" :border-width 5 :resizable nil)
610 (flet ((create-label-in-frame (frame-label label-text &rest args)
612 (make-instance 'frame
614 :child (apply #'make-instance 'label :label label-text :xpad 5 :ypad 5 args))
615 :fill nil :expand nil)))
616 (make-instance 'h-box
617 :spacing 5 :parent window
618 :child-args '(:fill nil :expand nil)
619 :child (make-instance 'v-box
621 :child (create-label-in-frame "Normal Label" "This is a Normal label")
622 :child (create-label-in-frame "Multi-line Label"
623 "This is a Multi-line label.
626 :child (create-label-in-frame "Left Justified Label"
627 "This is a Left-Justified
631 :child (create-label-in-frame "Right Justified Label"
632 "This is a Right-Justified
636 :child (make-instance 'v-box
638 :child (create-label-in-frame "Line wrapped label"
639 "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.
640 It supports multiple paragraphs correctly, and correctly adds many extra spaces. "
643 :child (create-label-in-frame "Filled, wrapped label"
644 "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.
645 This is a new paragraph.
646 This is another newer, longer, better paragraph. It is coming to an end, unfortunately."
647 :justify :fill :wrap t)
649 :child (create-label-in-frame "Underlined label"
650 "This label is underlined!
651 This one is underlined (こんにちは) in quite a funky fashion"
653 :pattern "_________________________ _ _________ _ _____ _ __ __ ___ ____ _____")))))
658 (defun layout-expose (layout event)
659 (when (eq (gdk:event-window event) (layout-bin-window layout))
660 (with-slots (gdk:x gdk:y gdk:width gdk:height) event
661 (let ((imin (truncate gdk:x 10))
662 (imax (truncate (+ gdk:x gdk:width 9) 10))
663 (jmin (truncate gdk:y 10))
664 (jmax (truncate (+ gdk:y gdk:height 9) 10)))
666 (let ((window (layout-bin-window layout))
667 (gc (style-black-gc (widget-style layout))))
669 for i from imin below imax
671 for j from jmin below jmax
672 unless (zerop (mod (+ i j) 2))
673 do (gdk:draw-rectangle
674 window gc t (* 10 i) (* 10 j)
675 (1+ (mod i 10)) (1+ (mod j 10)))))))))
678 (define-toplevel create-layout (window "Layout" :default-width 200
680 (let ((layout (make-instance 'layout
681 :parent (make-instance 'scrolled-window :parent window)
682 :width 1600 :height 128000 :events '(:exposure-mask)
683 :signal (list 'expose-event #'layout-expose :object t)
686 (with-slots (hadjustment vadjustment) layout
688 (adjustment-step-increment hadjustment) 10.0
689 (adjustment-step-increment vadjustment) 10.0))
693 (let ((text (format nil "Button ~D, ~D" i j)))
694 (make-instance (if (not (zerop (mod (+ i j) 2)))
697 :label text :parent (list layout :x (* j 100) :y (* i 100))))))
700 for i from 16 below 1280
701 do (let ((text (format nil "Button ~D, ~D" i 0)))
702 (make-instance (if (not (zerop (mod i 2)))
705 :label text :parent (list layout :x 0 :y (* i 100)))))))
711 (define-simple-dialog create-list (dialog "List" :default-height 400)
712 (let* ((store (make-instance 'list-store
713 :column-types '(string int boolean)
714 :column-names '(:foo :bar :baz)
715 :initial-content '(#("First" 12321 nil)
716 (:foo "Yeah" :baz t))))
717 (tree (make-instance 'tree-view :model store)))
720 with iter = (make-instance 'tree-iter)
722 do (list-store-append store (vector "Test" i (zerop (mod i 3))) iter))
724 (let ((column (make-instance 'tree-view-column :title "Column 1"))
725 (cell (make-instance 'cell-renderer-text)))
726 (cell-layout-pack column cell :expand t)
727 (cell-layout-add-attribute column cell 'text (column-index store :foo))
728 (tree-view-append-column tree column))
730 (let ((column (make-instance 'tree-view-column :title "Column 2"))
731 (cell (make-instance 'cell-renderer-text :background "orange")))
732 (cell-layout-pack column cell :expand t)
733 (cell-layout-add-attribute column cell 'text (column-index store :bar))
734 (tree-view-append-column tree column))
736 (let ((column (make-instance 'tree-view-column :title "Column 3"))
737 (cell (make-instance 'cell-renderer-text)))
738 (cell-layout-pack column cell :expand t)
739 (cell-layout-add-attribute column cell 'text (column-index store :baz))
740 (tree-view-append-column tree column))
742 (make-instance 'v-box
743 :parent dialog :border-width 10 :spacing 10 :show-all t
745 (make-instance 'h-box
747 :child (make-instance 'button
748 :label "Remove Selection"
749 :signal (list 'clicked
754 (make-instance 'tree-row-reference :model store :path path))
755 (tree-selection-get-selected-rows
756 (tree-view-selection tree)))))
758 #'(lambda (reference)
759 (list-store-remove store reference))
763 (make-instance 'h-box
765 :child (make-instance 'check-button
766 :label "Show Headers" :active t
767 :signal (list 'toggled
770 (tree-view-headers-visible-p tree)
771 (toggle-button-active-p button)))
773 :child (make-instance 'check-button
774 :label "Reorderable" :active nil
775 :signal (list 'toggled
778 (tree-view-reorderable-p tree)
779 (toggle-button-active-p button)))
782 (make-instance 'h-box
783 :child (make-instance 'label :label "Selection Mode: ")
784 :child (make-instance 'combo-box
785 :content '("Single" "Browse" "Multiple")
787 :signal (list 'changed
788 #'(lambda (combo-box)
791 (tree-view-selection tree))
793 #(:single :browse :multiple)
794 (combo-box-active combo-box))))
798 :child (make-instance 'scrolled-window
799 :child tree :hscrollbar-policy :automatic))))
804 (defun create-menu (depth tearoff)
805 (unless (zerop depth)
806 (let ((menu (make-instance 'menu)))
808 (let ((menu-item (make-instance 'tearoff-menu-item)))
809 (menu-shell-append menu menu-item)))
813 (make-instance 'radio-menu-item
814 :label (format nil "item ~2D - ~D" depth (1+ i)))))
816 (radio-menu-item-add-to-group menu-item group)
817 (setq group menu-item))
818 (unless (zerop (mod depth 2))
819 (setf (check-menu-item-active-p menu-item) t))
820 (menu-shell-append menu menu-item)
822 (setf (widget-sensitive-p menu-item) nil))
823 (let ((submenu (create-menu (1- depth) t)))
825 (setf (menu-item-submenu menu-item) submenu))))))
829 (define-simple-dialog create-menus (dialog "Menus" :default-width 200)
830 (let* ((main (make-instance 'v-box :parent dialog))
831 ; (accel-group (make-instance 'accel-group))
832 (menubar (make-instance 'menu-bar :parent (list main :expand nil))))
833 ; (accel-group-attach accel-group window)
835 (let ((menu-item (make-instance 'menu-item
836 :label (format nil "test~%line2"))))
837 (setf (menu-item-submenu menu-item) (create-menu 2 t))
838 (menu-shell-append menubar menu-item))
840 (let ((menu-item (make-instance 'menu-item :label "foo")))
841 (setf (menu-item-submenu menu-item) (create-menu 3 t))
842 (menu-shell-append menubar menu-item))
844 (let ((menu-item (make-instance 'menu-item :label "bar")))
845 (setf (menu-item-submenu menu-item) (create-menu 4 t))
846 (setf (menu-item-right-justified-p menu-item) t)
847 (menu-shell-append menubar menu-item))
849 (make-instance 'v-box
850 :spacing 10 :border-width 10 :parent main
851 :child (make-instance 'combo-box
855 collect (format nil "Item ~D" i))))
857 (widget-show-all main)))
862 (defun create-notebook-page (notebook page-num book-closed)
863 (let* ((title (format nil "Page ~D" page-num))
864 (page (make-instance 'frame :label title :border-width 10))
865 (v-box (make-instance 'v-box
866 :homogeneous t :border-width 10 :parent page)))
868 (make-instance 'h-box
869 :parent (list v-box :fill nil :padding 5) :homogeneous t
870 :child-args '(:padding 5)
871 :child (make-instance 'check-button
872 :label "Fill Tab" :active t
873 :signal (list 'toggled
876 (notebook-child-tab-fill-p page)
877 (toggle-button-active-p button)))
879 :child (make-instance 'check-button
881 :signal (list 'toggled
884 (notebook-child-tab-expand-p page)
885 (toggle-button-active-p button)))
887 :child (make-instance 'check-button
889 :signal (list 'toggled
892 (notebook-child-tab-pack page)
893 (if (toggle-button-active-p button)
897 :child (make-instance 'button
899 :signal (list 'clicked #'(lambda () (widget-hide page)))))
901 (let ((label-box (make-instance 'h-box
903 :child-args '(:expand nil)
904 :child (make-instance 'image :pixbuf book-closed)
905 :child (make-instance 'label :label title)))
906 (menu-box (make-instance 'h-box
908 :child-args '(:expand nil)
909 :child (make-instance 'image :pixbuf book-closed)
910 :child (make-instance 'label :label title))))
912 (widget-show-all page)
913 (notebook-append notebook page label-box menu-box))))
916 (define-simple-dialog create-notebook (dialog "Notebook")
917 (let ((main (make-instance 'v-box :parent dialog)))
918 (let ((book-open (gdk:pixbuf-new-from-xpm-data book-open-xpm))
919 (book-closed (gdk:pixbuf-new-from-xpm-data book-closed-xpm))
920 (notebook (make-instance 'notebook
921 :border-width 10 :tab-pos :top :parent main)))
922 (flet ((set-image (page func pixbuf)
925 (first (container-children (funcall func notebook page))))
927 (signal-connect notebook 'switch-page
928 #'(lambda (pointer page)
929 (declare (ignore pointer))
930 (unless (eq page (notebook-current-page-num notebook))
931 (set-image page #'notebook-menu-label book-open)
932 (set-image page #'notebook-tab-label book-open)
933 (let ((curpage (notebook-current-page notebook)))
935 (set-image curpage #'notebook-menu-label book-closed)
936 (set-image curpage #'notebook-tab-label book-closed)))))))
937 (loop for i from 1 to 5 do (create-notebook-page notebook i book-closed))
939 (make-instance 'h-separator :parent (list main :expand nil :padding 10))
941 (make-instance 'h-box
942 :spacing 5 :border-width 10
943 :parent (list main :expand nil)
944 :child-args '(:fill nil)
945 :child (make-instance 'check-button
947 :signal (list 'clicked
949 (if (toggle-button-active-p button)
950 (notebook-popup-enable notebook)
951 (notebook-popup-disable notebook)))
953 :child (make-instance 'check-button
954 :label "Homogeneous tabs"
955 :signal (list 'clicked
958 (notebook-homogeneous-p notebook)
959 (toggle-button-active-p button)))
962 (make-instance 'h-box
963 :spacing 5 :border-width 10
964 :parent (list main :expand nil)
965 :child-args '(:expand nil)
966 :child (make-instance 'label :label "Notebook Style: ")
967 :child (let ((scrollable-p nil))
968 (make-instance 'combo-box
969 :content '("Standard" "No tabs" "Scrollable") :active 0
970 :signal (list 'changed
971 #'(lambda (combo-box)
972 (case (combo-box-active combo-box)
974 (setf (notebook-show-tabs-p notebook) t)
976 (setq scrollable-p nil)
977 (setf (notebook-scrollable-p notebook) nil)
979 do (notebook-remove-page notebook 5))))
981 (setf (notebook-show-tabs-p notebook) nil)
983 (setq scrollable-p nil)
984 (setf (notebook-scrollable-p notebook) nil)
986 do (notebook-remove-page notebook 5))))
989 (setq scrollable-p t)
990 (setf (notebook-show-tabs-p notebook) t)
991 (setf (notebook-scrollable-p notebook) t)
992 (loop for i from 6 to 15
993 do (create-notebook-page notebook i book-closed))))))
995 :child (make-instance 'button
996 :label "Show all Pages"
997 :signal (list 'clicked
999 (map-container nil #'widget-show notebook)))))
1001 (make-instance 'h-box
1002 :spacing 5 :border-width 10
1003 :parent (list main :expand nil)
1004 :child (make-instance 'button
1006 :signal (list 'clicked #'notebook-prev-page :object notebook))
1007 :child (make-instance 'button
1009 :signal (list 'clicked #'notebook-next-page :object notebook))
1010 :child (make-instance 'button
1012 :signal (let ((tab-pos 0))
1015 (setq tab-pos (mod (1+ tab-pos) 4))
1017 (notebook-tab-pos notebook)
1018 (svref #(:top :right :bottom :left) tab-pos))))))))
1019 (widget-show-all main)))
1024 (defun toggle-resize (child)
1025 (setf (paned-child-resize-p child) (not (paned-child-resize-p child))))
1027 (defun toggle-shrink (child)
1028 (setf (paned-child-shrink-p child) (not (paned-child-shrink-p child))))
1030 (defun create-pane-options (paned frame-label label1 label2)
1031 (let* ((table (make-instance 'table :n-rows 3 :n-columns 2 :homogeneous t)))
1032 (table-attach table (create-label label1) 0 1 0 1 :options '(:expand :fill))
1033 (let ((check-button (make-instance 'check-button :label "Resize")))
1034 (table-attach table check-button 0 1 1 2 :options '(:expand :fill))
1035 (signal-connect check-button 'toggled
1036 #'toggle-resize :object (paned-child1 paned)))
1037 (let ((check-button (make-instance 'check-button :label "Shrink" :active t)))
1038 (table-attach table check-button 0 1 2 3 :options '(:expand :fill))
1039 (signal-connect check-button 'toggled
1040 #'toggle-shrink :object (paned-child1 paned)))
1042 (table-attach table (create-label label2) 1 2 0 1 :options '(:expand :fill))
1043 (let ((check-button (make-instance 'check-button :label "Resize" :active t)))
1044 (table-attach table check-button 1 2 1 2 :options '(:expand :fill))
1045 (signal-connect check-button 'toggled
1046 #'toggle-resize :object (paned-child2 paned)))
1047 (let ((check-button (make-instance 'check-button :label "Shrink" :active t)))
1048 (table-attach table check-button 1 2 2 3 :options '(:expand :fill))
1049 (signal-connect check-button 'toggled
1050 #'toggle-shrink :object (paned-child2 paned)))
1051 (make-instance 'frame :label frame-label :border-width 4 :child table)))
1053 (define-toplevel create-panes (window "Panes")
1054 (let* ((hpaned (make-instance 'h-paned
1055 :child1 (make-instance 'frame
1056 :width-request 60 :height-request 60
1058 :child (make-instance 'button :label "Hi there"))
1059 :child2 (make-instance 'frame
1060 :width-request 80 :height-request 60
1062 (vpaned (make-instance 'v-paned
1065 :child2 (make-instance 'frame
1066 :width-request 80 :height-request 60
1067 :shadow-type :in))))
1069 (make-instance 'v-box
1071 :child-args '(:expand nil)
1072 :child (list vpaned :expand t)
1073 :child (create-pane-options hpaned "Horizontal" "Left" "Right")
1074 :child (create-pane-options vpaned "Vertical" "Top" "Bottom"))))
1079 (define-simple-dialog create-progress-bar (dialog "Progress Bar")
1080 (let* ((progress (make-instance 'progress-bar :pulse-step 0.05))
1081 (activity-mode-button (make-instance 'check-button
1082 :label "Activity mode"))
1083 (timer (timeout-add 100
1085 (if (toggle-button-active-p activity-mode-button)
1086 (progress-bar-pulse progress)
1087 (let ((fract (+ (progress-bar-fraction progress) 0.01)))
1089 (progress-bar-fraction progress)
1095 (make-instance 'v-box
1096 :parent dialog :border-width 10 :spacing 10 :show-all t
1098 :child activity-mode-button)
1100 (signal-connect dialog 'destroy
1101 #'(lambda () (when timer (timeout-remove timer))))))
1106 (define-simple-dialog create-radio-buttons (dialog "Radio buttons")
1107 (make-instance 'v-box
1108 :parent dialog :border-width 10 :spacing 10 :show-all t
1109 :children (create-radio-button-group '("button1" "button2" "button3") 1)))
1114 (define-simple-dialog create-range-controls (dialog "Range controls")
1115 (let ((adjustment (adjustment-new 0.0 0.0 101.0 0.1 1.0 1.0)))
1116 (make-instance 'v-box
1117 :parent dialog :border-width 10 :spacing 10 :show-all t
1118 :child (make-instance 'h-scale
1119 :width-request 150 :adjustment adjustment :inverted t
1120 :update-policy :delayed :digits 1 :draw-value t)
1121 :child (make-instance 'h-scrollbar
1122 :adjustment adjustment :update-policy :continuous))))
1127 (define-simple-dialog create-reparent (dialog "Reparent")
1128 (let ((main (make-instance 'h-box
1129 :homogeneous t :spacing 10 :border-width 10 :parent dialog))
1130 (label (make-instance 'label :label "Hello World")))
1132 (flet ((create-frame (title)
1133 (let* ((frame (make-instance 'frame :label title :parent main))
1134 (box (make-instance 'v-box
1135 :spacing 5 :border-width 5 :parent frame))
1136 (button (make-instance 'button
1137 :label "switch" :parent (list box :expand nil))))
1138 (signal-connect button 'clicked
1140 (widget-reparent label box)))
1143 (box-pack-start (create-frame "Frame 1") label nil t 0)
1144 (create-frame "Frame 2"))
1145 (widget-show-all main)))
1150 (define-toplevel create-rulers (window "Rulers"
1151 :default-width 300 :default-height 300
1152 ;; :events '(:pointer-motion-mask
1153 ;; :pointer-motion-hint-mask)
1156 (widget-events window)
1157 '(:pointer-motion-mask :pointer-motion-hint-mask))
1159 (let ((table (make-instance 'table :n-rows 2 :n-columns 2 :parent window))
1160 (h-ruler (make-instance 'h-ruler
1161 :metric :centimeters :lower 100.0d0 :upper 0.0d0
1162 :position 0.0d0 :max-size 20.0d0))
1163 (v-ruler (make-instance 'v-ruler
1164 :lower 5.0d0 :upper 15.0d0
1165 :position 0.0d0 :max-size 20.0d0)))
1166 (signal-connect window 'motion-notify-event
1168 (widget-event h-ruler event)
1169 (widget-event v-ruler event)))
1170 (table-attach table h-ruler 1 2 0 1 :options :fill :x-options :expand)
1171 (table-attach table v-ruler 0 1 1 2 :options :fill :y-options :expand)))
1176 (define-simple-dialog create-scrolled-windows (dialog "Scrolled windows"
1178 :default-height 300)
1179 (let* ((scrolled-window
1180 (make-instance 'scrolled-window
1181 :parent dialog :border-width 10
1182 :vscrollbar-policy :automatic
1183 :hscrollbar-policy :automatic))
1185 (make-instance 'table
1186 :n-rows 20 :n-columns 20 :row-spacing 10 :column-spacing 10
1187 :focus-vadjustment (scrolled-window-vadjustment scrolled-window)
1188 :focus-hadjustment (scrolled-window-hadjustment scrolled-window))))
1190 (scrolled-window-add-with-viewport scrolled-window table)
1194 (make-instance 'toggle-button
1195 :label (format nil "button (~D,~D)~%" i j))))
1196 (table-attach table button i (1+ i) j (1+ j)))))
1197 (widget-show-all scrolled-window)))
1202 (define-simple-dialog create-size-group (dialog "Size Group" :resizable nil)
1203 (let ((size-group (make-instance 'size-group)))
1204 (flet ((create-frame (label rows)
1205 (let ((table (make-instance 'table
1206 :n-rows (length rows) :n-columns 2 :homogeneous nil
1207 :row-spacing 5 :column-spacing 10 :border-width 5)))
1211 do (table-attach table
1212 (create-label (first row) :xalign 0 :yalign 1)
1213 0 1 i (1+ i) :x-options '(:expand :fill))
1214 (let ((combo (make-instance 'combo-box
1215 :content (rest row) :active 0)))
1216 (size-group-add-widget size-group combo)
1217 (table-attach table combo 1 2 i (1+ i))))
1218 (make-instance 'frame :label label :child table))))
1220 (make-instance 'v-box
1221 :parent dialog :border-width 5 :spacing 5 :show-all t
1222 :child (create-frame "Color Options"
1223 '(("Foreground" "Red" "Green" "Blue")
1224 ("Background" "Red" "Green" "Blue")))
1225 :child (create-frame "Line Options"
1226 '(("Dashing" "Solid" "Dashed" "Dotted")
1227 ("Line ends" "Square" "Round" "Arrow")))
1228 :child (create-check-button "Enable grouping"
1231 (size-group-mode size-group)
1232 (if active :horizontal :none)))
1238 ;; (defun shape-create-icon (xpm-file x y px py type root-window destroy)
1240 ;; (make-instance 'window
1241 ;; :type type :x x :y y
1242 ;; :events '(:button-motion :pointer-motion-hint :button-press)))
1244 ;; (make-instance 'fixed
1245 ;; :parent window :width 100 :height 100)))
1247 ;; (widget-realize window)
1248 ;; (multiple-value-bind (source mask) nil ;(gdk:pixmap-create xpm-file)
1249 ;; (let ((pixmap (pixmap-new source mask))
1252 ;; (declare (fixnum x-offset y-offset))
1253 ;; (fixed-put fixed pixmap px py)
1254 ;; (widget-shape-combine-mask window mask px py)
1256 ;; (signal-connect window 'button-press-event
1257 ;; #'(lambda (event)
1258 ;; (when (typep event 'gdk:button-press-event)
1259 ;; (setq x-offset (truncate (gdk:event-x event)))
1260 ;; (setq y-offset (truncate (gdk:event-y event)))
1261 ;; (grab-add window)
1262 ;; (gdk:pointer-grab
1263 ;; (widget-window window) t
1264 ;; '(:button-release :button-motion :pointer-motion-hint)
1268 ;; (signal-connect window 'button-release-event
1269 ;; #'(lambda (event)
1270 ;; (declare (ignore event))
1271 ;; (grab-remove window)
1272 ;; (gdk:pointer-ungrab 0)
1275 ;; (signal-connect window 'motion-notify-event
1276 ;; #'(lambda (event)
1277 ;; (declare (ignore event))
1278 ;; (multiple-value-bind (win xp yp mask)
1279 ;; (gdk:window-get-pointer root-window)
1280 ;; (declare (ignore mask win) (fixnum xp yp))
1281 ;; (widget-set-uposition
1282 ;; window :x (- xp x-offset) :y (- yp y-offset)))
1284 ;; (signal-connect window 'destroy destroy)))
1286 ;; (widget-show-all window)
1290 ;; (let ((modeller nil)
1293 ;; (defun create-shapes ()
1294 ;; (let ((root-window (gdk:get-root-window)))
1295 ;; (if (not modeller)
1298 ;; (shape-create-icon
1299 ;; "clg:examples;Modeller.xpm" 440 140 0 0 :popup root-window
1300 ;; #'(lambda () (widget-destroyed modeller))))
1301 ;; (widget-destroy modeller))
1306 ;; (shape-create-icon
1307 ;; "clg:examples;FilesQueue.xpm" 580 170 0 0 :popup root-window
1308 ;; #'(lambda () (widget-destroyed sheets))))
1309 ;; (widget-destroy sheets))
1314 ;; (shape-create-icon
1315 ;; "clg:examples;3DRings.xpm" 460 270 25 25 :toplevel root-window
1316 ;; #'(lambda () (widget-destroyed rings))))
1317 ;; (widget-destroy rings)))))
1323 (define-simple-dialog create-spins (dialog "Spin buttons" :has-separator nil)
1324 (let ((main (make-instance 'v-box
1325 :spacing 5 :border-width 10 :parent dialog)))
1327 (flet ((create-date-spinner (label adjustment shadow-type)
1328 (declare (ignore shadow-type))
1329 (make-instance 'v-box
1330 :child-args '(:expand nil)
1331 :child (make-instance 'label
1332 :label label :xalign 0.0 :yalign 0.5)
1333 :child (make-instance 'spin-button
1334 :adjustment adjustment :wrap t))))
1335 (make-instance 'frame
1336 :label "Not accelerated" :parent main
1337 :child (make-instance 'h-box
1339 :child-args '(:padding 5)
1340 :child (create-date-spinner "Day : "
1341 (adjustment-new 1.0 1.0 31.0 1.0 5.0 0.0) :out)
1342 :child (create-date-spinner "Month : "
1343 (adjustment-new 1.0 1.0 12.0 1.0 5.0 0.0) :etched-in)
1344 :child (create-date-spinner "Year : "
1345 (adjustment-new 1998.0 0.0 2100.0 1.0 100.0 0.0) :in))))
1347 (let ((spinner1 (make-instance 'spin-button
1348 :adjustment (adjustment-new 0.0 -10000.0 10000.0 0.5 100.0 0.0)
1349 :climb-rate 1.0 :digits 2 :wrap t :width-request 100))
1350 (spinner2 (make-instance 'spin-button
1351 :adjustment (adjustment-new 2.0 1.0 5.0 1.0 1.0 0.0)
1352 :climb-rate 1.0 :wrap t))
1353 (value-label (make-instance 'label :label "0")))
1354 (signal-connect (spin-button-adjustment spinner2) 'value-changed
1357 (spin-button-digits spinner1)
1358 (floor (spin-button-value spinner2)))))
1360 (make-instance 'frame
1361 :label "Accelerated" :parent main
1362 :child (make-instance 'v-box
1365 (make-instance 'h-box
1366 :child-args '(:padding 5)
1367 :child (make-instance 'v-box
1368 :child (make-instance 'label
1370 :xalign 0.0 :yalign 0.5)
1372 :child (make-instance 'v-box
1373 :child (make-instance 'label
1375 :xalign 0.0 :yalign 0.5)
1377 :expand nil :padding 5)
1378 :child (make-instance 'check-button
1379 :label "Snap to 0.5-ticks" :active t
1380 :signal (list 'clicked
1383 (spin-button-snap-to-ticks-p spinner1)
1384 (toggle-button-active-p button)))
1386 :child (make-instance 'check-button
1387 :label "Numeric only input mode" :active t
1388 :signal (list 'clicked
1391 (spin-button-numeric-p spinner1)
1392 (toggle-button-active-p button)))
1396 (make-instance 'h-box
1397 :child-args '(:padding 5)
1398 :child (make-instance 'button
1399 :label "Value as Int"
1400 :signal (list 'clicked
1403 (label-label value-label)
1405 (spin-button-value-as-int
1407 :child (make-instance 'button
1408 :label "Value as Float"
1409 :signal (list 'clicked
1412 (label-label value-label)
1414 (format nil "~~,~DF"
1415 (spin-button-digits spinner1))
1416 (spin-button-value spinner1)))))))
1417 :padding 5 :expand nil))))
1418 (widget-show-all main)))
1423 (define-toplevel create-statusbar (window "Statusbar")
1424 (let ((statusbar (make-instance 'statusbar :has-resize-grip t))
1425 (close-button (create-button '("close" :can-default t)
1426 #'widget-destroy :object window))
1429 (signal-connect statusbar 'text-popped
1430 #'(lambda (context-id text)
1431 (declare (ignore context-id))
1432 (format nil "Popped: ~A~%" text)))
1434 (make-instance 'v-box
1436 :child (make-instance 'v-box
1437 :border-width 10 :spacing 10
1438 :child (create-button "push something"
1440 (statusbar-push statusbar 1
1441 (format nil "something ~D" (incf counter)))))
1442 :child (create-button "pop"
1444 (statusbar-pop statusbar 1)))
1445 :child (create-button "steal #4"
1447 (statusbar-remove statusbar 1 4)))
1448 :child (create-button "dump stack")
1449 :child (create-button "test contexts"))
1450 :child (list (make-instance 'h-separator) :expand nil)
1452 (make-instance 'v-box :border-width 10 :child close-button)
1454 :child (list statusbar :expand nil))
1456 (widget-grab-focus close-button)))
1461 (define-simple-dialog create-idle-test (dialog "Idle Test")
1462 (let ((label (make-instance 'label
1463 :label "count: 0" :xpad 10 :ypad 10))
1466 (signal-connect dialog 'destroy
1467 #'(lambda () (when idle (idle-remove idle))))
1469 (make-instance 'v-box
1470 :parent dialog :border-width 10 :spacing 10 :show-all t
1472 :child (make-instance 'frame
1473 :label "Label Container" :border-width 5
1474 :child(make-instance 'v-box
1475 :children (create-radio-button-group
1476 '(("Resize-Parent" :parent)
1477 ("Resize-Queue" :queue)
1478 ("Resize-Immediate" :immediate))
1482 (container-resize-mode (dialog-action-area dialog)) mode))))))
1484 (dialog-add-button dialog "Start"
1491 (setf (label-label label) (format nil "count: ~D" count))
1494 (dialog-add-button dialog "Stop"
1498 (setq idle nil))))))
1504 (define-simple-dialog create-timeout-test (dialog "Timeout Test")
1505 (let ((label (make-instance 'label
1506 :label "count: 0" :xpad 10 :ypad 10 :parent dialog :visible t))
1509 (signal-connect dialog 'destroy
1510 #'(lambda () (when timer (timeout-remove timer))))
1512 (dialog-add-button dialog "Start"
1519 (setf (label-label label) (format nil "count: ~D" count))
1522 (dialog-add-button dialog "Stop"
1525 (timeout-remove timer)
1526 (setq timer nil))))))
1531 (define-simple-dialog create-text (dialog "Text" :default-width 400
1532 :default-height 400)
1533 (let* ((text-view (make-instance 'text-view
1534 :border-width 10 :visible t :wrap-mode :word))
1535 (buffer (text-view-buffer text-view))
1538 (text-buffer-create-tag buffer "Bold" :weight :bold)
1539 (text-buffer-create-tag buffer "Italic" :style :italic)
1540 (text-buffer-create-tag buffer "Underline" :underline :single)
1542 (flet ((create-toggle-callback (tag-name)
1543 (let ((tag (text-tag-table-lookup
1544 (text-buffer-tag-table buffer) tag-name)))
1546 (unless (eq (and (find tag active-tags) t) active)
1549 (push tag active-tags)
1550 (setq active-tags (delete tag active-tags)))
1551 (multiple-value-bind (start end)
1552 (text-buffer-get-selection-bounds buffer)
1554 (text-buffer-apply-tag buffer tag start end)
1555 (text-buffer-remove-tag buffer tag start end))))))))
1558 (make-instance 'action-group
1559 :action (create-toggle-action
1560 "Bold" "gtk-bold" "Bold" "<control>B" "Bold" nil
1561 (create-toggle-callback "Bold"))
1562 :action (create-toggle-action
1563 "Italic" "gtk-italic" "Italic" "<control>I" "Italic" nil
1564 (create-toggle-callback "Italic"))
1565 :action (create-toggle-action
1566 "Underline" "gtk-underline" "Underline" "<control>U" "Underline" nil
1567 (create-toggle-callback "Underline"))))
1568 (ui (make-instance 'ui-manager)))
1570 (ui-manager-insert-action-group ui actions)
1571 (ui-manager-add-ui ui
1572 '((:toolbar "ToolBar"
1574 (:toolitem "Italic")
1575 (:toolitem "Underline"))))
1577 ;; Callback to activate/deactivate toolbar buttons when cursor
1579 (signal-connect buffer 'mark-set
1580 #'(lambda (location mark)
1581 (declare (ignore mark))
1582 (text-tag-table-foreach (text-buffer-tag-table buffer)
1587 (text-iter-has-tag-p location tag)
1588 (not (text-iter-begins-tag-p location tag)))
1589 (text-iter-ends-tag-p location tag))))
1590 (unless (eq active (and (find tag active-tags) t))
1592 (push tag active-tags)
1593 (setq active-tags (delete tag active-tags)))
1595 (toggle-action-active-p
1596 (action-group-get-action actions (text-tag-name tag)))
1599 ;; Callback to apply active tags when a character is inserted
1600 (signal-connect buffer 'insert-text
1601 #'(lambda (iter &rest args)
1602 (declare (ignore args))
1603 (let ((before (text-buffer-get-iter-at-offset buffer
1604 (1- (text-iter-offset iter)))))
1606 for tag in active-tags
1607 do (text-buffer-apply-tag buffer tag before iter))))
1610 (container-add dialog (ui-manager-get-widget ui "/ToolBar") :expand nil)
1611 (container-add dialog text-view)))))
1616 (define-simple-dialog create-toggle-buttons (dialog "Toggle Button")
1617 (make-instance 'v-box
1618 :border-width 10 :spacing 10 :parent dialog :show-all t
1621 collect (make-instance 'toggle-button
1622 :label (format nil "Button~D" (1+ n))))))
1628 (define-toplevel create-toolbar (window "Toolbar test" :resizable nil)
1629 (let ((toolbar (make-instance 'toolbar :parent window)))
1631 ;; Insert a stock item
1632 (toolbar-append toolbar "gtk-quit"
1633 :tooltip-text "Destroy toolbar"
1634 :tooltip-private-text "Toolbar/Quit"
1635 :callback #'(lambda () (widget-destroy window)))
1637 ;; Image widge as icon
1638 (toolbar-append toolbar "Horizontal"
1639 :icon (make-instance 'image :file #p"clg:examples;test.xpm")
1640 :tooltip-text "Horizontal toolbar layout"
1641 :tooltip-private-text "Toolbar/Horizontal"
1642 :callback #'(lambda () (setf (toolbar-orientation toolbar) :horizontal)))
1645 (toolbar-append toolbar "Vertical"
1646 :icon #p"clg:examples;test.xpm"
1647 :tooltip-text "Vertical toolbar layout"
1648 :tooltip-private-text "Toolbar/Vertical"
1649 :callback #'(lambda () (setf (toolbar-orientation toolbar) :vertical)))
1651 (toolbar-append toolbar :space)
1654 (toolbar-append toolbar "Icons"
1656 :tooltip-text "Only show toolbar icons"
1657 :tooltip-private-text "Toolbar/IconsOnly"
1658 :callback #'(lambda () (setf (toolbar-style toolbar) :icons)))
1660 ;; Icon from pixmap data
1661 (toolbar-append toolbar "Text"
1663 :tooltip-text "Only show toolbar text"
1664 :tooltip-private-text "Toolbar/TextOnly"
1665 :callback #'(lambda () (setf (toolbar-style toolbar) :text)))
1667 (toolbar-append toolbar "Both"
1668 :tooltip-text "Show toolbar icons and text"
1669 :tooltip-private-text "Toolbar/Both"
1670 :callback #'(lambda () (setf (toolbar-style toolbar) :both)))
1672 (toolbar-append toolbar :space)
1674 (toolbar-append toolbar (make-instance 'entry)
1675 :tooltip-text "This is an unusable GtkEntry"
1676 :tooltip-private-text "Hey don't click me!")
1678 (toolbar-append toolbar :space)
1680 ;; (toolbar-append-item
1681 ;; toolbar "Small" ;(pixmap-new "clg:examples;test.xpm")
1682 ;; :tooltip-text "Use small spaces"
1683 ;; :tooltip-private-text "Toolbar/Small"
1684 ;; :callback #'(lambda () (setf (toolbar-space-size toolbar) 5)))
1686 ;; (toolbar-append-item
1687 ;; toolbar "Big" ;(pixmap-new "clg:examples;test.xpm")
1688 ;; :tooltip-text "Use big spaces"
1689 ;; :tooltip-private-text "Toolbar/Big"
1690 ;; :callback #'(lambda () (setf (toolbar-space-size toolbar) 10)))
1692 ;; (toolbar-append toolbar :space)
1696 :tooltip-text "Enable tooltips"
1697 :callback #'(lambda () (toolbar-enable-tooltips toolbar)))
1701 :tooltip-text "Disable tooltips"
1702 :callback #'(lambda () (toolbar-disable-tooltips toolbar)))
1704 (toolbar-append toolbar :space)
1706 ;; (toolbar-append-item
1707 ;; toolbar "Borders" (pixmap-new "clg:examples;test.xpm")
1708 ;; :tooltip-text "Show borders"
1709 ;; :callback #'(lambda () (setf (toolbar-relief toolbar) :normal)))
1711 ;; (toolbar-append-item
1713 ;; "Borderless" (pixmap-new "clg:examples;test.xpm")
1714 ;; :tooltip-text "Hide borders"
1715 ;; :callback #'(lambda () (setf (toolbar-relief toolbar) :none)))
1717 ;; (toolbar-append toolbar :space)
1719 ;; (toolbar-append-item
1720 ;; toolbar "Empty" (pixmap-new "clg:examples;test.xpm")
1721 ;; :tooltip-text "Empty spaces"
1722 ;; :callback #'(lambda () (setf (toolbar-space-style toolbar) :empty)))
1724 ;; (toolbar-append-item
1725 ;; toolbar "Lines" (pixmap-new "clg:examples;test.xpm")
1726 ;; :tooltip-text "Lines in spaces"
1727 ;; :callback #'(lambda () (setf (toolbar-space-style toolbar) :line)))
1735 (define-simple-dialog create-tooltips (dialog "Tooltips" :default-width 200)
1736 (let ((tooltips (make-instance 'tooltips)))
1737 (flet ((create-button (label tip-text tip-private)
1738 (let ((button (make-instance 'toggle-button :label label)))
1739 (tooltips-set-tip tooltips button tip-text tip-private)
1741 (make-instance 'v-box
1742 :parent dialog :border-width 10 :spacing 10 :show-all t
1743 :child (create-button "button1" "This is button 1" "ContextHelp/button/1")
1744 :child (create-button "button2" "This is button 2. This is also has a really long tooltip which probably won't fit on a single line and will therefore need to be wrapped. Hopefully the wrapping will work correctly." "ContextHelp/button/2")))))
1749 (defvar *ui-description*
1750 '((:menubar "MenuBar"
1755 (:menuitem "SaveAs")
1758 (:menu "PreferencesMenu"
1764 (:menuitem "Square")
1765 (:menuitem "Rectangle")
1769 (:menuitem "About")))
1774 (:toolitem "Logo"))))
1776 (define-toplevel create-ui-manager (window "UI Manager")
1778 (make-instance 'action-group
1780 :action (create-action "FileMenu" nil "_File")
1781 :action (create-action "PreferencesMenu" nil "_Preferences")
1782 :action (create-action "ColorMenu" nil "_Color")
1783 :action (create-action "ShapeMenu" nil "_Shape")
1784 :action (create-action "HelpMenu" nil "_Help")
1785 :action (create-action "New" "gtk-new" "_New" "<control>N" "Create a new file")
1786 :action (create-action "Open" "gtk-open" "_Open" "<control>O" "Open a file" #'create-file-chooser)
1787 :action (create-action "Save" "gtk-save" "_Save" "<control>S" "Save current file")
1788 :action (create-action "SaveAs" "gtk-save" "Save _As..." "" "Save to a file")
1789 :action (create-action "Quit" "gtk-quit" "_Quit" "<control>Q" "Quit" (list #'widget-destroy :object window))
1790 :action (create-action "About" nil "_About" "<control>A" "About")
1791 :action (create-action "Logo" "demo-gtk-logo" "" nil "GTK+")
1792 :action (create-toggle-action "Bold" "gtk-bold" "_Bold" "<control>B" "Bold" t)
1793 :actions (create-radio-actions
1794 '(("Red" nil "_Red" "<control>R" "Blood")
1795 ("Green" nil "_Green" "<control>G" "Grass")
1796 ("Blue" nil "_Blue" "<control>B" "Sky"))
1798 :actions (create-radio-actions
1799 '(("Square" nil "_Square" "<control>S" "Square")
1800 ("Rectangle" nil "_Rectangle" "<control>R" "Rectangle")
1801 ("Oval" nil "_Oval" "<control>O" "Egg")))))
1802 (ui (make-instance 'ui-manager)))
1804 (ui-manager-insert-action-group ui actions)
1805 (ui-manager-add-ui ui *ui-description*)
1807 (window-add-accel-group window (ui-manager-accel-group ui))
1809 (make-instance 'v-box
1810 :parent window :show-all t
1812 (ui-manager-get-widget ui "/MenuBar")
1813 :expand nil :fill nil)
1815 (ui-manager-get-widget ui "/ToolBar")
1816 :expand nil :fill nil)
1817 :child (make-instance 'label
1818 :label "Type <alt> to start"
1819 :xalign 0.5 :yalign 0.5
1820 :width-request 200 :height-request 200))))
1826 (defun create-main-window ()
1827 ;; (rc-parse "clg:examples;testgtkrc2")
1828 ;; (rc-parse "clg:examples;testgtkrc")
1830 (let* ((button-specs
1831 '(("button box" create-button-box)
1832 ("buttons" create-buttons)
1833 ("calendar" create-calendar)
1834 ("check buttons" create-check-buttons)
1835 ("color selection" create-color-selection)
1836 ("cursors" create-cursors)
1837 ("dialog" create-dialog)
1839 ("entry" create-entry)
1840 ;; ("event watcher")
1841 ("enxpander" create-expander)
1842 ("file chooser" create-file-chooser)
1843 ;; ("font selection")
1844 ;; ("handle box" create-handle-box)
1845 ("image" create-image)
1846 ("labels" create-labels)
1847 ("layout" create-layout)
1848 ("list" create-list)
1849 ("menus" create-menus)
1851 ("notebook" create-notebook)
1852 ("panes" create-panes)
1853 ("progress bar" create-progress-bar)
1854 ("radio buttons" create-radio-buttons)
1855 ("range controls" create-range-controls)
1857 ("reparent" create-reparent)
1858 ("rulers" create-rulers)
1859 ;; ("saved position")
1860 ("scrolled windows" create-scrolled-windows)
1861 ("size group" create-size-group)
1862 ;; ("shapes" create-shapes)
1863 ("spinbutton" create-spins)
1864 ("statusbar" create-statusbar)
1865 ("test idle" create-idle-test)
1866 ;; ("test mainloop")
1867 ;; ("test scrolling")
1868 ;; ("test selection")
1869 ("test timeout" create-timeout-test)
1870 ("text" create-text)
1871 ("toggle buttons" create-toggle-buttons)
1872 ("toolbar" create-toolbar)
1873 ("tooltips" create-tooltips)
1874 ;; ("tree" #|create-tree|#)
1875 ("UI manager" create-ui-manager)
1877 (main-window (make-instance 'window
1878 :title "testgtk.lisp" :name "main_window"
1879 :default-width 200 :default-height 400
1880 :allow-grow t :allow-shrink nil))
1881 (scrolled-window (make-instance 'scrolled-window
1882 :hscrollbar-policy :automatic
1883 :vscrollbar-policy :automatic
1885 (close-button (make-instance 'button
1886 :label "close" :can-default t
1887 :signal (list 'clicked #'widget-destroy
1888 :object main-window))))
1890 (let ((icon (gdk:pixbuf-load #p"clg:examples;gtk.png")))
1892 (window-icon main-window)
1893 (gdk:pixbuf-add-alpha icon t 254 254 252)))
1896 (make-instance 'v-box
1898 :child-args '(:expand nil)
1899 :child (list (make-instance 'label :label (gtk-version)) :fill nil)
1900 :child (list (make-instance 'label :label "clg CVS version") :fill nil)
1901 :child (list scrolled-window :expand t)
1902 :child (make-instance 'h-separator)
1903 :child (make-instance 'v-box
1904 :homogeneous nil :spacing 10 :border-width 10
1905 :child close-button))
1908 (make-instance 'v-box
1909 :focus-vadjustment (scrolled-window-vadjustment scrolled-window)
1910 :children (mapcar #'(lambda (spec)
1911 (apply #'create-button spec))
1913 (scrolled-window-add-with-viewport scrolled-window content-box))
1915 (widget-grab-focus close-button)
1916 (widget-show-all main-window)
1920 (create-main-window)