Gtk tree-model
[cl-gtk2.git] / gtk / gtk.tree-model.lisp
1 (in-package :gtk)
2
3 (define-g-flags "GtkTreeModelFlags" tree-model-flags (:type-initializer "gtk_tree_model_flags_get_type")
4   (:iters-persist 1) (:list-only 2))
5
6 (export 'tree-model-flags)
7
8 (defcstruct tree-iter
9   (stamp :int)
10   (user-data :pointer)
11   (user-data-2 :pointer)
12   (user-data-3 :pointer))
13
14 (defun tree-iter-get-stamp (i) (foreign-slot-value (pointer i) 'tree-iter 'stamp))
15 (defun tree-iter-set-stamp (value i) (setf (foreign-slot-value (pointer i) 'tree-iter 'stamp) value))
16 (defun tree-iter-get-user-data (i) (pointer-address (foreign-slot-value (pointer i) 'tree-iter 'user-data)))
17 (defun tree-iter-set-user-data (value i) (setf (foreign-slot-value (pointer i) 'tree-iter 'user-data) (make-pointer value)))
18
19 (defun tree-iter-alloc () (glib::g-malloc (foreign-type-size 'tree-iter)))
20 (defun tree-iter-free (v) (glib::g-free v))
21
22 (define-g-boxed-ref "GtkTreeIter" tree-iter
23   (:slots (stamp :reader tree-iter-get-stamp :writer tree-iter-set-stamp :accessor tree-iter-stamp)
24           (user-data :reader tree-iter-get-user-data :writer tree-iter-set-user-data :accessor tree-iter-user-data))
25   (:alloc-function tree-iter-alloc)
26   (:free-function tree-iter-free))
27
28 (defctype tree-path :pointer)
29 (defcfun (%gtk-tree-path-get-depth "gtk_tree_path_get_depth") :int
30   (path tree-path))
31
32 (defcfun (%gtk-tree-path-get-indices "gtk_tree_path_get_indices") (:pointer :int)
33   (path tree-path))
34
35 (defcfun (%gtk-tree-path-new "gtk_tree_path_new") :pointer)
36
37 (defcfun (%gtk-tree-path-append-index "gtk_tree_path_append_index") :void
38   (path :pointer)
39   (index :int))
40
41 (defun tree-path-get-indices (path)
42   (setf path (pointer path))
43   (let ((n (%gtk-tree-path-get-depth path))
44         (indices (%gtk-tree-path-get-indices path)))
45     (loop
46        for i from 0 below n
47        collect (mem-aref indices :int i))))
48
49 (defun tree-path-set-indices (indices path)
50   (setf path (pointer path))
51   (loop 
52      repeat (%gtk-tree-path-get-depth path)
53      do (foreign-funcall "gtk_tree_path_up" :pointer path :boolean))
54   (loop
55      for index in indices
56      do(foreign-funcall "gtk_tree_path_append_index" :pointer path :int index :void)))
57
58 (defcfun gtk-tree-path-new :pointer)
59 (defcfun gtk-tree-path-free :void (path :pointer))
60
61 (define-g-boxed-ref "GtkTreePath" tree-path
62   (:alloc-function gtk-tree-path-new)
63   (:free-function gtk-tree-path-free)
64   (:slots (indices :reader tree-path-get-indices :writer tree-path-set-indices :accessor tree-path-indices)))
65
66 (define-vtable ("GtkTreeModel" c-gtk-tree-model)
67   (:skip parent-instance g-type-interface)
68   ;;some signals
69   (:skip tree-model-row-changed :pointer)
70   (:skip tree-model-row-inserted :pointer)
71   (:skip tree-model-row-has-child-toggled :pointer)
72   (:skip tree-model-row-deleted :pointer)
73   (:skip tree-model-rows-reordered :pointer)
74   ;;methods
75   (tree-model-get-flags-impl tree-model-get-flags-cb tree-model-flags (tree-model g-object))
76   (tree-model-get-n-columns-impl tree-model-get-n-columns-cb :int (tree-model g-object))
77   (tree-model-get-column-type-impl tree-model-get-column-type-cb g-type (tree-model g-object) (index :int))
78   (tree-model-get-iter-impl tree-model-get-iter-cb :boolean (tree-model g-object) (iter (g-boxed-ref tree-iter)) (path (g-boxed-ref tree-path)))
79   (tree-model-get-path-impl tree-model-get-path-cb (g-boxed-ref tree-path) (tree-model g-object) (iter (g-boxed-ref tree-iter)))
80   (tree-model-get-value-impl tree-model-get-value-cb :void (tree-model g-object) (iter (g-boxed-ref tree-iter)) (n :int) (value (:pointer g-value)))
81   (tree-model-iter-next-impl tree-model-iter-next-cb :boolean (tree-model g-object) (iter (g-boxed-ref tree-iter)))
82   (tree-model-iter-children-impl tree-model-iter-children-cb :boolean (tree-model g-object) (iter (g-boxed-ref tree-iter)) (parent (g-boxed-ref tree-iter)))
83   (tree-model-iter-has-child-impl tree-model-iter-has-child-cb :boolean (tree-model g-object) (iter (g-boxed-ref tree-iter)))
84   (tree-model-iter-n-children-impl tree-model-iter-n-children-cb :int (tree-model g-object) (iter (g-boxed-ref tree-iter)))
85   (tree-model-iter-nth-child-impl tree-model-iter-nth-child-cb :boolean (tree-model g-object) (iter (g-boxed-ref tree-iter)) (parent (g-boxed-ref tree-iter)) (n :int))
86   (tree-model-iter-parent-impl tree-model-iter-parent-cb :boolean (tree-model g-object) (iter (g-boxed-ref tree-iter)) (child (g-boxed-ref tree-iter)))
87   (tree-model-ref-node-impl tree-model-ref-node-cb :void (tree-model g-object) (iter (g-boxed-ref tree-iter)))
88   (tree-model-unref-node-impl tree-model-unref-node-cb :void (tree-model g-object) (iter (g-boxed-ref tree-iter))))
89
90 (defclass array-list-store (g-object gtk:tree-model)
91   ((items :initform (make-array 0 :adjustable t :fill-pointer t) :reader store-items)
92    (columns-getters :initform (make-array 0 :adjustable t :fill-pointer t) :reader store-getters)
93    (columns-types :initform (make-array 0 :adjustable t :fill-pointer t) :reader store-types)))
94
95 (export 'array-list-store)
96
97 (register-object-type-implementation "LispArrayListStore" array-list-store "GObject" ("GtkTreeModel") nil)
98
99 (defun store-add-item (store item)
100   (vector-push-extend item (store-items store))
101   (using* ((path (make-instance 'tree-path))
102                    (iter (make-instance 'tree-iter)))
103     (setf (tree-path-indices path) (list (1- (length (store-items store)))))
104     (setf (tree-iter-stamp iter) 0 (tree-iter-user-data iter) (1- (length (store-items store))))
105     (emit-signal store "row-inserted" path iter)))
106
107 (export 'store-add-item)
108
109 (defun store-add-column (store type getter)
110   (vector-push-extend (ensure-g-type type) (store-types store))
111   (vector-push-extend getter (store-getters store))
112   (1- (length (store-types store))))
113
114 (export 'store-add-column)
115
116 (defmethod tree-model-get-flags-impl ((model array-list-store))
117   '(:list-only))
118
119 (defmethod tree-model-get-n-columns-impl ((model array-list-store))
120   (length (store-types model)))
121
122 (defmethod tree-model-get-column-type-impl ((tree-model array-list-store) index)
123   (aref (store-types tree-model) index))
124
125 (defmethod tree-model-get-iter-impl ((model array-list-store) iter path)
126   (using* (iter path)
127     (let ((indices (tree-path-indices path)))
128       (when (= 1 (length indices))
129         (setf (tree-iter-stamp iter) 0 (tree-iter-user-data iter) (first indices))
130         t))))
131
132 (defmethod tree-model-ref-node-impl ((model array-list-store) iter) (release iter))
133 (defmethod tree-model-unref-node-impl ((model array-list-store) iter) (release iter))
134
135 (defmethod tree-model-iter-next-impl ((model array-list-store) iter)
136   (using* (iter)
137     (let ((n (tree-iter-user-data iter)))
138       (when (< n (1- (length (store-items model))))
139         (setf (tree-iter-user-data iter) (1+ n))
140         t))))
141
142 (defmethod tree-model-iter-nth-child-impl ((model array-list-store) iter parent n)
143   (using* (iter parent)
144     (setf (tree-iter-stamp iter) 0
145           (tree-iter-user-data iter) n)
146     t))
147
148 (defmethod tree-model-iter-n-children-impl ((model array-list-store) iter)
149   (if (null-pointer-p iter)
150       (length (store-items model))
151       0))
152
153 (defmethod tree-model-get-path-impl ((model array-list-store) iter)
154   (using* (iter)
155     (anaphora:aprog1 (make-instance 'tree-path)
156       (setf (tree-path-indices anaphora:it) (list (tree-iter-user-data iter)))
157       (disown-boxed-ref anaphora:it))))
158
159 (defmethod tree-model-iter-has-child-impl ((model array-list-store) iter)
160   (release iter)
161   nil)
162
163 (defmethod tree-model-get-value-impl ((model array-list-store) iter n value)
164   (using (iter)
165     (let ((n-row (tree-iter-user-data iter)))
166       (set-g-value value
167                    (funcall (aref (store-getters model) n) 
168                             (aref (store-items model) n-row))
169                    (aref (store-types model) n)))))
170
171 (defcfun (tree-view-append-column "gtk_tree_view_append_column") :int
172   (tree-view (g-object gtk:tree-view))
173   (column (g-object gtk:tree-view-column)))
174
175 (export 'tree-view-append-column)
176
177 (defcfun (tree-view-column-pack-start "gtk_tree_view_column_pack_start") :void
178   (tree-column (g-object gtk:tree-view-column))
179   (cell (g-object gtk:cell-renderer))
180   (expand :boolean))
181
182 (export 'tree-view-column-pack-start)
183
184 (defcfun (tree-view-column-add-attribute "gtk_tree_view_column_add_attribute") :void
185   (tree-column (g-object gtk:tree-view-column))
186   (cell-renderer (g-object gtk:cell-renderer))
187   (attribute :string)
188   (column-number :int))
189
190 (export 'tree-view-column-add-attribute)
191
192 (defcfun (tree-model-flags "gtk_tree_model_get_flags") tree-model-flags
193   (tree-model g-object))
194
195 (export 'tree-modelg-flags)
196
197 (defcfun (tree-model-n-columns "gtk_tree_model_get_n_columns") :int
198   (tree-model g-object))
199
200 (export 'tree-model-flags)
201
202 (defcfun (tree-model-column-type "gtk_tree_model_column_get_type") g-type
203   (tree-model g-object)
204   (index :int))
205
206 (export 'tree-model-column-type)
207
208 (defcfun (tree-model-set-iter-to-path "gtk_tree_model_get_iter") :boolean
209   (tree-model g-object)
210   (iter (g-boxed-ref tree-iter))
211   (path (g-boxed-ref tree-path)))
212
213 (defun tree-model-iter-by-path (tree-model tree-path)
214   (let ((iter (make-instance 'tree-iter)))
215     (if (tree-model-set-iter-to-path tree-model iter tree-path)
216         iter
217         (progn (release iter) nil))))
218
219 (export 'tree-model-iter-by-path)
220
221 (defcfun (tree-model-set-iter-from-string "gtk_tree_model_get_iter_from_string") :boolean
222   (tree-model g-object)
223   (iter (g-boxed-ref tree-iter))
224   (path-string :string))
225
226 (defun tree-model-iter-from-string (tree-model path-string)
227   (let ((iter (make-instance 'tree-iter)))
228     (if (tree-model-set-iter-from-string tree-model iter path-string)
229         iter
230         (progn (release iter) nil))))
231
232 (export 'tree-model-iter-from-string)
233
234 (defcfun (tree-model-set-iter-to-first "gtk_tree_model_get_iter_first") :boolean
235   (model g-object)
236   (iter (g-boxed-ref tree-iter)))
237
238 (defun tree-model-iter-first (tree-model)
239   (let ((iter (make-instance 'tree-iter)))
240     (if (tree-model-set-iter-to-first tree-model iter)
241         iter
242         (progn (release iter) nil))))
243
244 (export 'tree-model-iter-first)
245
246 (defcfun (tree-model-path "gtk_tree_model_get_path") (g-boxed-ref tree-path :owner :lisp)
247   (tree-model g-object)
248   (iter (g-boxed-ref tree-iter)))
249
250 (export 'tree-model-path)
251
252 (defcfun gtk-tree-model-get-value :void
253   (model g-object)
254   (iter (g-boxed-ref tree-iter))
255   (column :int)
256   (value (:pointer g-value)))
257
258 (defun tree-model-value (tree-model iter column)
259   (with-foreign-object (v 'g-value)
260     (g-value-zero v)
261     (gtk-tree-model-get-value tree-model iter column v)
262     (prog1 (parse-gvalue v)
263       (g-value-unset v))))
264
265 (export 'tree-model-value)
266
267 (defcfun (tree-model-iter-next "gtk_tree_model_iter_next") :boolean
268   (tree-model g-object)
269   (iter (g-boxed-ref tree-iter)))
270
271 (export 'tree-model-iter-next)
272
273 (defcfun gtk-tree-model-iter-children :boolean
274   (tree-model g-object)
275   (iter (g-boxed-ref tree-iter))
276   (parent (g-boxed-ref tree-iter)))
277
278 (defun tree-model-iter-first-child (tree-model parent)
279   (let ((iter (make-instance 'tree-iter)))
280     (if (gtk-tree-model-iter-children tree-model iter parent)
281         iter
282         (progn (release iter) nil))))
283
284 (export 'tree-model-iter-first-child)
285
286 (defcfun (tree-model-has-children "gtk_tree_model_has_child") :boolean
287   (tree-model g-object)
288   (iter (g-boxed-ref tree-iter)))
289
290 (export 'tree-model-has-children)
291
292 (defcfun (tree-model-iter-n-children "gtk_tree_model_iter_n_children") :int
293   (tree-model g-object)
294   (iter (g-boxed-ref tree-iter)))
295
296 (export 'tree-model-iter-n-children)
297
298 (defcfun gtk-tree-model-iter-nth-child :boolean
299   (tree-model g-object)
300   (iter (g-boxed-ref tree-iter))
301   (parent (g-boxed-ref tree-iter))
302   (n :int))
303
304 (defun tree-model-iter-nth-child (tree-model parent n)
305   (let ((iter (make-instance 'tree-iter)))
306     (if (gtk-tree-model-iter-nth-child tree-model iter parent n)
307         iter
308         (progn (release iter) n))))
309
310 (export 'tree-model-iter-nth-child)
311
312 (defcfun gtk-tree-model-iter-parent :boolean
313   (tree-model g-object)
314   (iter (g-boxed-ref tree-iter))
315   (parent (g-boxed-ref tree-iter)))
316
317 (defun tree-model-iter-parent (tree-model iter)
318   (let ((parent (make-instance 'tree-iter)))
319     (if (gtk-tree-model-iter-parent tree-model iter parent)
320         parent
321         (progn (release parent) nil))))
322
323 (export 'tree-model-iter-parent)
324
325 (defcfun (tree-model-iter-to-string "gtk_tree_model_get_string_from_iter") (g-string :free-from-foreign t)
326   (tree-model g-object)
327   (iter (g-boxed-ref tree-iter)))
328
329 (export 'tree-model-iter-to-string)
330
331 (defcfun (tree-model-ref-node "gtk_tree_model_ref_node") :void
332   (tree-model g-object)
333   (iter (g-boxed-ref tree-iter)))
334
335 (export 'tree-model-ref-node)
336
337 (defcfun (tree-model-unref-node "gtk_tree_model_unref_node") :void
338   (tree-model g-object)
339   (iter (g-boxed-ref tree-iter)))
340
341 (export 'tree-model-unref-node)
342
343 (defcallback gtk-tree-model-foreach-cb :boolean ((model g-object) (path (g-boxed-ref tree-path)) (iter (g-boxed-ref tree-iter)) (data :pointer))
344   (let ((fn (get-stable-pointer-value data)))
345     (restart-case
346         (funcall fn model path iter)
347       (stop-tree-model-iteration () t)
348       (skip-tree-model-current () nil))))
349
350 (defcfun gtk-tree-model-foreach :void
351   (model g-object)
352   (func :pointer)
353   (data :pointer))
354
355 (defun do-tree-model (model fn)
356   (with-stable-pointer (ptr fn)
357     (gtk-tree-model-foreach model (callback gtk-tree-model-foreach-cb) ptr)))
358
359 (export 'do-tree-model)
360