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