[Gd-chatter] r11401 - branches/opendylan-melange/gtk-duim

hannes at gwydiondylan.org hannes at gwydiondylan.org
Tue Jun 12 03:17:32 CEST 2007


Author: hannes
Date: Tue Jun 12 03:17:31 2007
New Revision: 11401

Modified:
   branches/opendylan-melange/gtk-duim/gtk-gadgets.dylan
Log:
Job: fd

cache model in <gtk-list-control-mixin> class.
 add-item and remove-item can be implemented easily (and, especially
without the need to recreate the model)

implement a tree view, this is work in progress, because somehow I
don't get the signal row-selected. also, selection is not working.



Modified: branches/opendylan-melange/gtk-duim/gtk-gadgets.dylan
==============================================================================
--- branches/opendylan-melange/gtk-duim/gtk-gadgets.dylan	(original)
+++ branches/opendylan-melange/gtk-duim/gtk-gadgets.dylan	Tue Jun 12 03:17:31 2007
@@ -1101,6 +1101,7 @@
     (<gtk-gadget-mixin>,
      <collection-gadget>,
      <sealed-constructor-mixin>)
+  slot store-model :: false-or(<GtkTreeModel>) = #f;
 end class <gtk-list-control-mixin>;
 
 define method update-mirror-attributes
@@ -1129,7 +1130,7 @@
     (sheet :: <gtk-list-control-mixin>, mirror :: <gadget-mirror>) => ()
   next-method();
   let widget = mirror-widget(mirror);
-  let selection = gtk-tree-view-get-selection(widget);
+  let selection = with-gdk-lock gtk-tree-view-get-selection(widget) end;
   g-signal-connect(selection, "changed", method (#rest args) handle-gtk-select-row-event(sheet) end);
   duim-g-signal-connect(sheet, #"button-press-event") (widget, event, #rest args) handle-gtk-button-press-event(sheet, event) end;
   with-gdk-lock
@@ -1147,11 +1148,11 @@
   let new-selection = make(<stretchy-vector>);
   
   with-stack-structure (model :: <GtkTreeModel*>)
-    let selected-paths = glist-to-vector
-      (gtk-tree-selection-get-selected-rows
-         (selection, model),
+    let selected-paths
+      = glist-to-vector
+      (gtk-tree-selection-get-selected-rows(selection, model),
        <GtkTreePath>);
-
+    
     for (path in selected-paths)
       with-stack-structure (iter :: <GtkTreeIter>)
         gtk-tree-model-get-iter(model[0], iter, path);
@@ -1163,7 +1164,7 @@
       end;
     end;
   end;
-
+  
   gtk-debug("  Selection now %=", new-selection);
   distribute-selection-changed-callback(gadget, new-selection);
   #t
@@ -1221,17 +1222,29 @@
   mirror & update-list-control-items(gadget, mirror)
 end method update-gadget;
 
+define function generate-list-model () => (res :: <GtkTreeModel>)
+  with-gdk-lock
+    let type-vector = make(<GType*>, element-count: 2);
+    type-vector[0] := $G-TYPE-INT;
+    type-vector[1] := $G-TYPE-STRING;
+    gtk-list-store-newv(2, type-vector);
+  end;
+end;
+
 define sealed method update-list-control-items
     (gadget :: <gtk-list-control-mixin>, mirror :: <gadget-mirror>)
  => ()
   let widget = mirror.mirror-widget;
   let items = gadget-items(gadget);
   let label-function = gadget-label-key(gadget);
+  let model = gadget.store-model
+    | begin
+        gadget.store-model := generate-list-model();
+        with-gdk-lock widget. at model := gadget.store-model end;
+        gadget.store-model;
+      end;
   with-gdk-lock
-    let type-vector = make(<GType*>, element-count: 2);
-    type-vector[0] := $G-TYPE-INT;
-    type-vector[1] := $G-TYPE-STRING;
-    let model = gtk-list-store-newv(2, type-vector);
+    gtk-list-store-clear(model);
     with-stack-structure(iter :: <GtkTreeIter>)
       for (item in items, i from 0)
         let label = label-function(item);
@@ -1246,7 +1259,6 @@
         end;
       end
     end;
-    widget. at model := model;
   end
 end method update-list-control-items;
 
@@ -1447,6 +1459,19 @@
   #t
 end method handle-gtk-resize-column-event;
 */
+
+define function generate-table-model (no-of-columns :: <integer>)
+ => (res :: <GtkTreeModel>)
+  with-gdk-lock
+    let type-vector = make(<GType*>, element-count: 1 + no-of-columns);
+    type-vector[0] := $G-TYPE-INT;
+    for (i from 1 to no-of-columns)
+      type-vector[i] := $G-TYPE-STRING;
+    end;
+    gtk-list-store-newv(no-of-columns + 1, type-vector);
+  end;
+end;
+
 define sealed method update-list-control-items
     (gadget :: <gtk-table-control>, mirror :: <gadget-mirror>)
  => ()
@@ -1454,13 +1479,14 @@
   let items = gadget-items(gadget);
   let columns = table-control-columns(gadget);
   let no-of-columns = columns.size;
-  with-gdk-lock
-    let type-vector = make(<GType*>, element-count: 1 + no-of-columns);
-    type-vector[0] := $G-TYPE-INT;
-    for (i from 1 to no-of-columns)
-      type-vector[i] := $G-TYPE-STRING;
+  let model = gadget.store-model |
+    begin
+      gadget.store-model := generate-table-model(no-of-columns);
+      widget. at model := with-gdk-lock gadget.store-model end;
+      gadget.store-model;
     end;
-    let model = gtk-list-store-newv(no-of-columns + 1, type-vector);
+  with-gdk-lock
+    gtk-list-store-clear(model);
     with-stack-structure(iter :: <GtkTreeIter>)
       for (item in items, i from 0)
         format-out("item %=\n", item);
@@ -1486,10 +1512,172 @@
         end;
       end;
     end;
-    widget. at model := model;
   end;
 end method update-list-control-items;
 
+// Tree control
+
+define sealed class <gtk-tree-control>
+    (<gtk-list-control-mixin>,
+     <tree-control>,
+     <leaf-pane>)
+  sealed constant slot %nodes :: <stretchy-object-vector> = make(<stretchy-vector>);
+end;
+
+define sealed method class-for-make-pane
+    (framem :: <gtk-frame-manager>, class == <tree-control>, #key)
+ => (class :: <class>, options :: false-or(<sequence>))
+  values(<gtk-tree-control>, #f);
+end;
+
+define sealed method make-gtk-mirror
+    (gadget :: <gtk-tree-control>) => (mirror :: <gadget-mirror>)
+  with-gdk-lock
+    let widget = gtk-tree-view-new();
+    let renderer = gtk-cell-renderer-text-new();
+    let column = gtk-tree-view-column-new();
+    gtk-tree-view-column-pack-start(column, renderer, 0);
+    gtk-tree-view-column-add-attribute(column, renderer, "text", 0);
+    gtk-tree-view-append-column(widget, column);
+    let type-vector = make(<GType*>, element-count: 1);
+    type-vector[0] := $G-TYPE-STRING;
+    let model = gtk-tree-store-newv(1, type-vector);
+    gadget.store-model := model;
+    widget. at model := model;
+    make(<gadget-mirror>,
+         widget: widget,
+         sheet: gadget);
+  end;
+end;
+
+define sealed class <gtk-tree-node> (<tree-node>)
+  sealed slot %tree :: false-or(<tree-control>) = #f;
+end;
+
+define sealed domain make (singleton(<gtk-tree-node>));
+define selaed domain initialize (<gtk-tree-node>);
+
+define sealed method do-make-item
+    (pane :: <gtk-tree-control>, class == <tree-node>, #key object)
+ => (item :: <gtk-tree-node>)
+  make(<gtk-tree-node>, object: object);
+end;
+
+define sealed method do-add-node
+    (pane :: <gtk-tree-control>, parent, item :: <gtk-tree-node>, #key after) => ()
+  let mirror = sheet-direct-mirror(pane);
+  when (mirror)
+    update-list-control-items(pane, mirror);
+  end;
+end;
+
+define class <node-of-tree-control> (<object>)
+  constant slot real-object, init-keyword: object:;
+  constant slot children :: <stretchy-vector> = make(<stretchy-vector>);
+end;
+
+define sealed method update-list-control-items
+    (gadget :: <gtk-tree-control>, mirror :: <gadget-mirror>)
+ => ()
+  gadget.%nodes.size := 0;
+  let model = gadget.store-model;
+  let roots = tree-control-roots(gadget);
+  let children? = tree-control-children-predicate(gadget);
+  let label-function = gadget-label-key(gadget);
+  with-gdk-lock
+    gtk-tree-store-clear(model);
+    let np = null-pointer(<GtkTreeIter>);
+    with-stack-structure (iter :: <GtkTreeIter>)
+      with-stack-structure (data :: <GValue>)
+        for (tln in roots)
+          gtk-tree-store-insert-before(model, iter, np, np);
+          g-value-nullify(data);
+          let label = label-function(tln);
+          unless (instance?(label, <string>))
+            label := format-to-string("%=", label);
+          end;
+          g-value-set-value(data, label);
+          gtk-tree-store-set-value(model, iter, 0, data);
+          add!(gadget.%nodes, make(<node-of-tree-control>, object: tln));
+          if (children?(tln))
+            with-stack-structure (dummy :: <GtkTreeIter>)
+              gtk-tree-store-insert-before(model, dummy, iter, np);
+//              g-value-nullify(data);
+//              g-value-set-value(data, "this is just a dummy");
+              gtk-tree-store-set-value(model, dummy, 0, data);
+            end;
+          end;
+        end;
+      end;
+    end;
+  end;
+end;
+
+define method install-event-handlers
+    (sheet :: <gtk-tree-control>, mirror :: <gadget-mirror>) => ()
+  next-method();
+  duim-g-signal-connect(sheet, #"row-expanded")
+    (treeview, treeiter, treepath, #rest args)
+    handle-row-expanded(sheet, treeiter, treepath) end;
+end;
+
+define function find-node-list
+    (gadget :: <gtk-tree-control>, indices :: <collection>)
+ => (res :: false-or(<node-of-tree-control>))
+  let node-list = gadget.%nodes;
+  for (index in indices)
+    node-list := node-list.children[index];
+  end;
+  node-list;
+end;
+
+define method handle-row-expanded
+  (sheet :: <gtk-tree-control>, parent :: <GtkTreeIter>, path :: <GtkTreePath>)
+  format-out("handling row expansion signal\n");
+  let model = sheet.store-model;
+  let children? = tree-control-children-predicate(sheet);
+  let generator = tree-control-children-generator(sheet);
+  let label-function = gadget-label-key(sheet);
+  with-gdk-lock
+    let path = map(string-to-integer,
+                   split(gtk-tree-path-to-string(path), ':'));
+    let parent-tree = find-node-list(sheet, path);
+    let object = parent-tree.real-object;
+    with-stack-structure (iter :: <GtkTreeIter>)
+      //first, remove the dummy
+      gtk-tree-model-iter-children(model, iter, parent);
+      gtk-tree-store-remove(model, iter);
+    end;
+    //insert all childrens, check whether they fulfill the children-predicate
+    //if that is the case, add a dummy as child
+    let np = null-pointer(<GtkTreeIter>);
+    with-stack-structure (iter :: <GtkTreeIter>)
+      with-stack-structure (data :: <GValue>)
+        for (node in generator(object))
+          gtk-tree-store-insert-before(model, iter, parent, np);
+          g-value-nullify(data);
+          let label = label-function(node);
+          unless (instance?(label, <string>))
+            label := format-to-string("%=", label);
+          end;
+          g-value-set-value(data, label);
+          gtk-tree-store-set-value(model, iter, 0, data);
+          add!(parent-tree.children, make(<node-of-tree-control>, object: node));
+          if (children?(node))
+            with-stack-structure (dummy :: <GtkTreeIter>)
+              gtk-tree-store-insert-before(model, dummy, iter, np);
+              //g-value-nullify(data);
+              //g-value-set-value(data, "this is just a dummy");
+              gtk-tree-store-set-value(model, dummy, 0, data);
+            end;
+          end;
+        end;
+      end;
+    end;
+  end;
+  #t;
+end;
+
 
 /// Option boxes
 



More information about the chatter mailing list