c422022a46562062b67d4c8d9543460926c97090
[cl-gtk2.git] / subtest.lisp
1 (gobject:define-g-flags "GtkTreeModelFlags" tree-model-flags (:type-initializer "gtk_tree_model_flags_get_type")
2   (:iters-persist 1) (:list-only 2))
3
4 (cffi:defcstruct tree-iter
5   (stamp :int)
6   (user-data :pointer)
7   (user-data-2 :pointer)
8   (user-data-3 :pointer))
9
10 (defun tree-iter-get-stamp (i) (cffi:foreign-slot-value (gobject::pointer i) 'tree-iter 'stamp))
11 (defun tree-iter-set-stamp (value i) (setf (cffi:foreign-slot-value (gobject::pointer i) 'tree-iter 'stamp) value))
12 (defun tree-iter-get-user-data (i) (cffi:pointer-address (cffi:foreign-slot-value (gobject::pointer i) 'tree-iter 'user-data)))
13 (defun tree-iter-set-user-data (value i) (setf (cffi:foreign-slot-value (gobject::pointer i) 'tree-iter 'user-data) (cffi:make-pointer value)))
14
15 (defun tree-iter-alloc () (glib::g-malloc (cffi:foreign-type-size 'tree-iter)))
16 (defun tree-iter-free (v) (glib::g-free v))
17
18 (gobject:define-g-boxed-ref "GtkTreeIter" tree-iter
19   (:slots (stamp :reader tree-iter-get-stamp :writer tree-iter-set-stamp :accessor tree-iter-stamp)
20           (user-data :reader tree-iter-get-user-data :writer tree-iter-set-user-data :accessor tree-iter-user-data))
21   (:alloc-function tree-iter-alloc)
22   (:free-function tree-iter-free))
23
24 (cffi:defctype tree-path :pointer)
25 (cffi:defcfun (%gtk-tree-path-get-depth "gtk_tree_path_get_depth") :int
26   (path tree-path))
27
28 (cffi:defcfun (%gtk-tree-path-get-indices "gtk_tree_path_get_indices") (:pointer :int)
29   (path tree-path))
30
31 (cffi:defcfun (%gtk-tree-path-new "gtk_tree_path_new") :pointer)
32
33 (cffi:defcfun (%gtk-tree-path-append-index "gtk_tree_path_append_index") :void
34   (path :pointer)
35   (index :int))
36
37 (defun tree-path-get-indices (path)
38   (setf path (gobject::pointer path))
39   (let ((n (%gtk-tree-path-get-depth path))
40         (indices (%gtk-tree-path-get-indices path)))
41     (loop
42        for i from 0 below n
43        collect (cffi:mem-aref indices :int i))))
44
45 (defun tree-path-set-indices (indices path)
46   (setf path (gobject::pointer path))
47   (loop 
48      repeat (%gtk-tree-path-get-depth path)
49      do (cffi:foreign-funcall "gtk_tree_path_up" :pointer path :boolean))
50   (loop
51      for index in indices
52      do(cffi:foreign-funcall "gtk_tree_path_append_index" :pointer path :int index :void)))
53
54 (cffi:defcfun gtk-tree-path-new :pointer)
55 (cffi:defcfun gtk-tree-path-free :void (path :pointer))
56
57 (gobject::define-g-boxed-ref "GtkTreePath" tree-path
58   (:alloc-function gtk-tree-path-new)
59   (:free-function gtk-tree-path-free)
60   (:slots (indices :reader tree-path-get-indices :writer tree-path-set-indices :accessor tree-path-indices)))
61
62 (gobject::define-vtable ("GtkTreeModel" c-gtk-tree-model)
63   (:skip parent-instance gobject::g-type-interface)
64   ;;some signals
65   (:skip tree-model-row-changed :pointer)
66   (:skip tree-model-row-inserted :pointer)
67   (:skip tree-model-row-has-child-toggled :pointer)
68   (:skip tree-model-row-deleted :pointer)
69   (:skip tree-model-rows-reordered :pointer)
70   ;;methods
71   (tree-model-get-flags-impl tree-model-get-flags-cb tree-model-flags (tree-model gobject:g-object))
72   (tree-model-get-n-columns-impl tree-model-get-n-columns-cb :int (tree-model gobject:g-object))
73   (tree-model-get-column-type-impl tree-model-get-column-type-cb gobject::g-type (tree-model gobject:g-object) (index :int))
74   (tree-model-get-iter-impl tree-model-get-iter-cb :boolean (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter)) (path (gobject:g-boxed-ref tree-path)))
75   (tree-model-get-path-impl tree-model-get-path-cb (gobject:g-boxed-ref tree-path) (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter)))
76   (tree-model-get-value-impl tree-model-get-value-cb :void (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter)) (n :int) (value (:pointer gobject::g-value)))
77   (tree-model-iter-next-impl tree-model-iter-next-cb :boolean (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter)))
78   (tree-model-iter-children-impl tree-model-iter-children-cb :boolean (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter)) (parent (gobject:g-boxed-ref tree-iter)))
79   (tree-model-iter-has-child-impl tree-model-iter-has-child-cb :boolean (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter)))
80   (tree-model-iter-n-children-impl tree-model-iter-n-children-cb :int (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter)))
81   (tree-model-iter-nth-child-impl tree-model-iter-nth-child-cb :boolean (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter)) (parent (gobject:g-boxed-ref tree-iter)) (n :int))
82   (tree-model-iter-parent-impl tree-model-iter-parent-cb :boolean (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter)) (child (gobject:g-boxed-ref tree-iter)))
83   (tree-model-ref-node-impl tree-model-ref-node-cb :void (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter)))
84   (tree-model-unref-node-impl tree-model-unref-node-cb :void (tree-model gobject:g-object) (iter (gobject:g-boxed-ref tree-iter))))
85
86 (defclass array-list-store (gobject:g-object gtk:tree-model)
87   ((items :initform (make-array 0 :adjustable t :fill-pointer t) :reader store-items)
88    (columns-getters :initform (make-array 0 :adjustable t :fill-pointer t) :reader store-getters)
89    (columns-types :initform (make-array 0 :adjustable t :fill-pointer t) :reader store-types)))
90
91 (gobject::register-object-type-implementation "LispArrayListStore" array-list-store "GObject" ("GtkTreeModel") nil)
92
93 (defun store-add-item (store item)
94   (vector-push-extend item (store-items store))
95   (gobject:using* ((path (make-instance 'tree-path))
96                    (iter (make-instance 'tree-iter)))
97     (setf (tree-path-indices path) (list (1- (length (store-items store)))))
98     (setf (tree-iter-stamp iter) 0 (tree-iter-user-data iter) (1- (length (store-items store))))
99     (gobject::emit-signal store "row-inserted" path iter)))
100
101 (defun store-add-column (store type getter)
102   (vector-push-extend (gobject::ensure-g-type type) (store-types store))
103   (vector-push-extend getter (store-getters store))
104   (1- (length (store-types store))))
105
106 (defmethod tree-model-get-flags-impl ((model array-list-store))
107   '(:list-only))
108
109 (defmethod tree-model-get-n-columns-impl ((model array-list-store))
110   (length (store-types model)))
111
112 (defmethod tree-model-get-column-type-impl ((tree-model array-list-store) index)
113   (aref (store-types tree-model) index))
114
115 (defmethod tree-model-get-iter-impl ((model array-list-store) iter path)
116   (gobject:using* (iter path)
117     (let ((indices (tree-path-indices path)))
118       (when (= 1 (length indices))
119         (setf (tree-iter-stamp iter) 0 (tree-iter-user-data iter) (first indices))
120         t))))
121
122 (defmethod tree-model-ref-node-impl ((model array-list-store) iter) (gobject:release iter))
123 (defmethod tree-model-unref-node-impl ((model array-list-store) iter) (gobject:release iter))
124
125 (defmethod tree-model-iter-next-impl ((model array-list-store) iter)
126   (gobject:using* (iter)
127     (let ((n (tree-iter-user-data iter)))
128       (when (< n (1- (length (store-items model))))
129         (setf (tree-iter-user-data iter) (1+ n))
130         t))))
131
132 (defmethod tree-model-iter-nth-child-impl ((model array-list-store) iter parent n)
133   (gobject:using* (iter parent)
134     (setf (tree-iter-stamp iter) 0
135           (tree-iter-user-data iter) n)
136     t))
137
138 (defmethod tree-model-iter-n-children-impl ((model array-list-store) iter)
139   (if (cffi:null-pointer-p iter)
140       (length (store-items model))
141       0))
142
143 (defmethod tree-model-get-path-impl ((model array-list-store) iter)
144   (gobject:using* (iter)
145     (let ((path (make-instance 'tree-path)))
146       (setf (tree-path-indices path) (list (tree-iter-user-data iter)))
147       (gobject:disown-boxed-ref path)
148       path)))
149
150 (defmethod tree-model-iter-has-child-impl ((model array-list-store) iter)
151   (gobject:release iter)
152   nil)
153
154 (defmethod tree-model-get-value-impl ((model array-list-store) iter n value)
155   (gobject:using (iter)
156     (let ((n-row (tree-iter-user-data iter)))
157       (gobject::set-g-value value
158                             (funcall (aref (store-getters model) n) 
159                                      (aref (store-items model) n-row))
160                             (aref (store-types model) n)))))
161
162 (cffi:defcfun (%gtk-tree-view-append-column "gtk_tree_view_append_column") :int
163   (tree-view (gobject:g-object gtk:tree-view))
164   (column (gobject:g-object gtk:tree-view-column)))
165
166 (cffi:defcfun (%gtk-tree-view-column-pack-start "gtk_tree_view_column_pack_start") :void
167   (tree-column (gobject:g-object gtk:tree-view-column))
168   (cell (gobject:g-object gtk:cell-renderer))
169   (expand :boolean))
170
171 (cffi:defcfun (%gtk-tree-view-column-add-attribute "gtk_tree_view_column_add_attribute") :void
172   (tree-column (gobject:g-object gtk:tree-view-column))
173   (cell-renderer (gobject:g-object gtk:cell-renderer))
174   (attribute :string)
175   (column-number :int))
176
177 (defstruct item title value)
178
179 (defun test-treeview ()
180   (let* ((window (make-instance 'gtk:gtk-window :type :toplevel :title "Treeview"))
181          (model (make-instance 'array-list-store))
182          (scroll (make-instance 'gtk:scrolled-window :hscrollbar-policy :automatic :vscrollbar-policy :automatic))
183          (tv (make-instance 'gtk:tree-view :headers-visible t :width-request 100 :height-request 400))
184          (h-box (make-instance 'gtk:h-box))
185          (v-box (make-instance 'gtk:v-box))
186          (title-entry (make-instance 'gtk:entry))
187          (value-entry (make-instance 'gtk:entry))
188          (button (make-instance 'gtk:button :label "Add")))
189     (store-add-column model "gchararray" #'item-title)
190     (store-add-column model "gint" #'item-value)
191     (store-add-item model (make-item :title "Monday" :value 1))
192     (store-add-item model (make-item :title "Tuesday" :value 2))
193     (store-add-item model (make-item :title "Wednesday" :value 3))
194     (store-add-item model (make-item :title "Thursday" :value 4))
195     (store-add-item model (make-item :title "Friday" :value 5))
196     (store-add-item model (make-item :title "Saturday" :value 6))
197     (store-add-item model (make-item :title "Sunday" :value 7))
198     (setf (gtk:tree-view-model tv) model)
199     (gobject:g-signal-connect window "destroy" (lambda (w) (gobject:release w) (gtk:gtk-main-quit)))
200     (gobject:g-signal-connect button "clicked" (lambda (b) (gobject:release b) (store-add-item model (make-item :title (gtk:entry-text title-entry)
201                                                                                                                 :value (parse-integer (gtk:entry-text value-entry) 
202                                                                                                                                       :junk-allowed t)))
203                                                        #+nil(setf (gtk:tree-view-model tv) nil)
204                                                        #+nil(setf (gtk:tree-view-model tv) model)))
205     (gtk:container-add window v-box)
206     (gtk:box-pack-start v-box h-box :expand nil)
207     (gtk:box-pack-start h-box title-entry :expand nil)
208     (gtk:box-pack-start h-box value-entry :expand nil)
209     (gtk:box-pack-start h-box button :expand nil)
210     (gtk:box-pack-start v-box scroll)
211     (gtk:container-add scroll tv)
212     (let ((column (make-instance 'gtk:tree-view-column :title "Title"))
213           (renderer (make-instance 'gtk:cell-renderer-text :text "A text")))
214       (%gtk-tree-view-column-pack-start column renderer t)
215       (%gtk-tree-view-column-add-attribute column renderer "text" 0)
216       (%gtk-tree-view-append-column tv column))
217     (let ((column (make-instance 'gtk:tree-view-column :title "Value"))
218           (renderer (make-instance 'gtk:cell-renderer-text :text "A text")))
219       (%gtk-tree-view-column-pack-start column renderer t)
220       (%gtk-tree-view-column-add-attribute column renderer "text" 1)
221       (%gtk-tree-view-append-column tv column))
222     (gtk:gtk-widget-show-all window)
223     (gtk:gtk-main)))