chiark / gitweb /
Bug fix
[clg] / gtk / gtkcontainer.lisp
CommitLineData
112ac1d3 1;; Common Lisp bindings for GTK+ v2.x
2;; Copyright 2000-2005 Espen S. Johnsen <espen@users.sf.net>
560af5c5 3;;
112ac1d3 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:
560af5c5 11;;
112ac1d3 12;; The above copyright notice and this permission notice shall be
13;; included in all copies or substantial portions of the Software.
560af5c5 14;;
112ac1d3 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.
560af5c5 22
c78ef85c 23;; $Id: gtkcontainer.lisp,v 1.23 2007-01-14 23:18:17 espen Exp $
560af5c5 24
25(in-package "GTK")
4a383aae 26
b3de3ed8 27(defgeneric container-add (container widget &rest args))
28(defgeneric container-remove (container widget))
c78ef85c 29(defgeneric container-all-children (container))
30(defgeneric container-internal-children (container))
b3de3ed8 31(defgeneric (setf container-children) (children container))
32
33
76ff9f39 34(defun initial-add (object function initargs key pkey)
35 (loop
36 as (initarg value . rest) = initargs then rest
37 do (cond
38 ((eq initarg key) (funcall function object value))
39 ((eq initarg pkey) (mapc #'(lambda (value)
40 (funcall function object value))
41 value)))
42 while rest))
43
44(defun initial-apply-add (object function initargs key pkey)
45 (initial-add object #'(lambda (object value)
46 (apply function object (mklist value)))
47 initargs key pkey))
48
49
1047e159 50(defmethod shared-initialize ((container container) names &rest initargs
67b44e86 51 &key child children child-args
76ff9f39 52 (show-children nil show-children-p))
53 (declare (ignore names child children))
67b44e86 54 (when show-children-p
55 (if (not show-children)
56 (setf (user-data container 'show-recursive-p) nil)
57 (signal-connect container 'show #'container-show-recursive
58 :object t :remove t)))
59
560af5c5 60 (call-next-method)
4a383aae 61 (initial-add container
62 #'(lambda (container args)
63 (apply #'container-add container (append (mklist args) child-args)))
64 initargs :child :children))
560af5c5 65
560af5c5 66
4c371500 67(defmethod compute-signal-function ((container container) signal function object args)
76ff9f39 68 (declare (ignore signal))
67b44e86 69 (if (eq object :children)
4c371500 70 #'(lambda (&rest emission-args)
71 (let ((all-args (nconc (rest emission-args) args)))
72 (container-foreach container
73 #'(lambda (child)
74 (apply function child all-args)))))
03802c3c 75 (call-next-method)))
76
77
e5b416f0 78(defbinding %container-add () nil
560af5c5 79 (container container)
80 (widget widget))
81
f9e76ebe 82(defmethod container-add ((container container) (widget widget) &rest args)
e5b416f0 83 (%container-add container widget)
84 (when args
85 (setf
c289d084 86 (slot-value widget 'child-properties)
e5b416f0 87 (apply
88 #'make-instance
89 (gethash (class-of container) *container-to-child-class-mappings*)
90 :parent container :child widget args))))
91
4c371500 92(defmethod container-add ((container container) (widgets list) &rest args)
93 (dolist (widget widgets)
94 (apply #'container-add container widget args)))
95
e5b416f0 96(defbinding %container-remove () nil
560af5c5 97 (container container)
98 (widget widget))
99
f9e76ebe 100(defmethod container-remove ((container container) (widget widget))
e5b416f0 101 (%container-remove container widget)
c289d084 102 (slot-makunbound widget 'child-properties))
e5b416f0 103
104
1f518a51 105(defbinding %container-child-get-property () nil
106 (container container)
107 (child widget)
108 (property-name string)
109 (value gvalue))
110
111(defbinding %container-child-set-property () nil
112 (container container)
113 (child widget)
114 (property-name string)
115 (value gvalue))
116
117
0d270bd9 118(defbinding container-check-resize () nil
560af5c5 119 (container container))
120
56ccd5b7 121(define-callback-marshal %foreach-callback nil (widget))
1de3a418 122
123(defbinding %container-foreach (container callback-id) nil
560af5c5 124 (container container)
56ccd5b7 125 (%foreach-callback callback)
1de3a418 126 (callback-id unsigned-int))
127
128(defun container-foreach (container function)
1a1949c7 129 (with-callback-function (id function)
130 (%container-foreach container id)))
560af5c5 131
d2ba9d86 132(defbinding %container-forall (container callback-id) nil
133 (container container)
56ccd5b7 134 (%foreach-callback callback)
d2ba9d86 135 (callback-id unsigned-int))
136
137(defun container-forall (container function)
138 (with-callback-function (id function)
139 (%container-forall container id)))
140
560af5c5 141(defun map-container (seqtype func container)
142 (case seqtype
143 ((nil)
1047e159 144 (container-foreach container func)
560af5c5 145 nil)
146 (list
147 (let ((list nil))
76ff9f39 148 (container-foreach container
560af5c5 149 #'(lambda (child)
150 (push (funcall func child) list)))
151 (nreverse list)))
152 (t
1de3a418 153 (let ((seq (make-sequence seqtype (container-length container)))
560af5c5 154 (index 0))
76ff9f39 155 (container-foreach container
560af5c5 156 #'(lambda (child)
157 (setf (elt seq index) (funcall func child))
158 (incf index)))
159 seq))))
160
76ff9f39 161(defmethod container-all-children ((container container))
162 (let ((internal ()))
163 (container-forall container
164 #'(lambda (child)
165 (push child internal)))
166 (nreverse internal)))
167
168(defmethod container-internal-children ((container container))
c78ef85c 169 (let ((external-children (container-children container))
76ff9f39 170 (all-children (container-all-children container)))
171 (loop
172 for child in all-children
c78ef85c 173 unless (find child external-children)
76ff9f39 174 collect child)))
e5b416f0 175
176(defmethod (setf container-children) (children (container container))
560af5c5 177 (dolist (child (container-children container))
178 (container-remove container child))
179 (dolist (child children)
d2ba9d86 180 (apply #'container-add container (mklist child)))
560af5c5 181 children)
182
1de3a418 183(defun container-length (container)
184 (let ((n 0))
185 (container-foreach container
186 #'(lambda (child)
187 (declare (ignore child))
188 (incf n)))
189 n))
560af5c5 190
0d270bd9 191(defbinding container-resize-children () nil
560af5c5 192 (container container))
1de3a418 193
194(defbinding container-propagate-expose () nil
195 (container container)
196 (child widget)
197 (event gdk:expose-event))
198
199
200(defbinding %container-get-focus-chain () boolean
201 (container container)
202 (focusable-widgets (glist widget) :out))
203
204(defun container-focus-chain (container)
205 (multiple-value-bind (chain-set-p focusable-widgets)
206 (%container-get-focus-chain container)
207 (and chain-set-p focusable-widgets)))
208
209(defbinding %container-set-focus-chain () nil
210 (container container)
211 (focusable-widgets (glist widget)))
212
213(defbinding %container-unset-focus-chain () nil
214 (container container))
215
216(defun (setf container-focus-chain) (focusable-widgets container)
217 (if (null focusable-widgets)
218 (%container-unset-focus-chain container)
219 (%container-set-focus-chain container focusable-widgets)))
67b44e86 220
221(defgeneric container-show-recursive (container))
222
223(defmethod container-show-recursive ((container container))
76ff9f39 224 "Recursively show any child widgets except widgets explicit hidden during construction."
67b44e86 225 (labels ((recursive-show (widget)
226 (when (typep widget 'container)
227 (if (not (user-data-p widget 'show-recursive-p))
228 (container-foreach widget #'recursive-show)
229 (unset-user-data widget 'show-recursive-p)))
230 (unless (widget-hidden-p widget)
231 (widget-show widget))))
232 (container-foreach container #'recursive-show)))