[ruby-gnome2-doc-cvs] [Ruby-GNOME2 Project Website] update - tut-gtk2-treev-spbttr

Back to archive index

ruby-****@sourc***** ruby-****@sourc*****
2012年 10月 7日 (日) 06:59:02 JST


-------------------------
REMOTE_ADDR = 184.145.80.187
REMOTE_HOST = 
        URL = http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-treev-spbttr
-------------------------
@@ -6,7 +6,8 @@
 In session about "Numeric/Text Data Entry" we have learnt about the Gtk::SpinButton. While Gtk::CellRendererText can display numbers, a better option is to use Gtk::CellRendererSpin. Instead of displaying a Gtk::Entry when the content is to be edited, a Gtk::CellRendererSpin is used.
 
 
-{{image_left("treev-crs-01.png")}}
+{{image_left("treev-crs-03-spin-btts.png")}}
+
 Just like with the pixbuf renderer example there is a problem with the spin button renderers, you can see this from the image on the the left, where we would expect spin buttons in the Count column. Obviously there is again a problem in GTK+. As of Ruby 1.8.6 and Ruby-GNOME2 rel.: 2-0.17.0-rc1, {{image_right("dialog-warning.png")}} most of the methods in Gtk::CellRendererSpin class do not work as expected. It also looks that this is a combined C GTK+ as well as Ruby GTK+ problem. I have compiled the C example from Andrew Klause's book, and it exhibits exactly the same problems as my Ruby translation. You may check it out by clicking on ((<treestore-spin.c|tut-gtk2-treev-treev-spin-cgtk-01>))
 
 With Gtk2 2.24.10-3 and Ruby 1.9.3 the example below works if the CellRendererSpin renderer is set to editable
@@ -20,44 +21,54 @@
  #!/usr/bin/env ruby
  require 'gtk2'
  
- # Add three columns to the GtkTreeView. All three of the
- # columns will be displayed as text, although one is a boolean
- # value and another is an integer.
+ # Add three columns to the tree view. The first of the three
+ # columns will be displayed as the toggle button, the second
+ # column will be an editable spin button and the last column
+ # will be the name of the product category or the product to buy.
  def setup_tree_view(treeview)
  
    renderer = Gtk::CellRendererToggle.new
-   column = Gtk::TreeViewColumn.new("Buy", renderer, "active" => $buy_index)
-   
+   column = Gtk::TreeViewColumn.new("Buy", renderer, "active" => BUY_COLUMN)
+ 
    renderer.activatable = true
    renderer.signal_connect('toggled') do |w, path|
      iter = treeview.model.get_iter(path)
-     iter[$buy_index] = !iter[$buy_index] if (iter)
+     iter[BUY_COLUMN] = !iter[BUY_COLUMN] if (iter)
    end
    treeview.append_column(column)
  
  # Create spin button cell renderer
                          # value, min, max,   step, pg-incr, pg-size
-   adj = Gtk::Adjustment.new(0.0, 0.0, 100.0, 1.0,  2.0,     2.0)
+   adj = Gtk::Adjustment.new(0.0, 0.0, 100.0, 1.0,  2.0,     0)
    renderer = Gtk::CellRendererSpin.new
    renderer.adjustment = adj
    renderer.signal_connect('edited') do |w, path, new_text|
      iter = treeview.model.get_iter(path)
-     iter[$qty_index] = new_text
+     iter[COUNT_COLUMN] = new_text.to_i
    end
-   column = Gtk::TreeViewColumn.new("Count", renderer, "text" => $qty_index)
+   
+ #  renderer.editable = true
+   column = Gtk::TreeViewColumn.new("Count-spin", renderer, "text" => COUNT_COLUMN)
+   column.set_cell_data_func(renderer) do |tvc, cell, model, iter|
+     cell.editable = iter.has_child? ? false : true
+     fix_parents_total(iter) if !iter.has_child?
+   end
    treeview.append_column(column) 
  
    renderer = Gtk::CellRendererText.new
-   column = Gtk::TreeViewColumn.new("Product", renderer, "text" => $prod_index)
+   column = Gtk::TreeViewColumn.new("Product", renderer, "text" => PRODUCT_COLUMN)
    treeview.append_column(column)
  end
  
- window = Gtk::Window.new(Gtk::Window::TOPLEVEL)
- window.resizable = true
- window.title = "Grocery List"
- window.border_width = 10
- window.signal_connect('delete_event') { Gtk.main_quit }
- window.set_size_request(275, 200)
+ def fix_parents_total(iter)
+   parent = iter.parent
+   tmp_iter = parent.first_child
+   total = 0
+   total = tmp_iter[COUNT_COLUMN] if tmp_iter[BUY_COLUMN]
+   (total += tmp_iter[COUNT_COLUMN] if tmp_iter[BUY_COLUMN]) while tmp_iter.next!
+   parent[COUNT_COLUMN] = total
+ end
  
  class GroceryItem
    attr_accessor :product_type, :buy, :quantity, :product
@@ -65,19 +75,29 @@
      @product_type, @buy, @quantity, @product = t, b, q, p
    end
  end
- $buy_index = 0; $qty_index = 1; $prod_index = 2
- $p_category = 0; $p_child = 1
+ BUY_COLUMN = 0; COUNT_COLUMN = 1; PRODUCT_COLUMN = 2
+ P_CATG = 0; P_CHLD = 1
  
  list = Array.new
- list[0] = GroceryItem.new($p_category, true,  0, "Cleaning Supplies")
- list[1] = GroceryItem.new($p_child,    true,  1, "Paper Towels")
- list[2] = GroceryItem.new($p_child,    true,  3, "Toilet Paper")
- list[3] = GroceryItem.new($p_category, true,  0, "Food")
- list[4] = GroceryItem.new($p_child,    true,  2, "Bread")
- list[5] = GroceryItem.new($p_child,    false, 1, "Butter")
- list[6] = GroceryItem.new($p_child,    true,  1, "Milk")
- list[7] = GroceryItem.new($p_child,    false, 3, "Chips")
- list[8] = GroceryItem.new($p_child,    true,  4, "Soda")
+ list[0] = GroceryItem.new(P_CATG, true,  0, "Cleaning Supplies")
+ list[1] = GroceryItem.new(P_CHLD, true,  1, "Paper Towels")
+ list[2] = GroceryItem.new(P_CHLD, true,  3, "Toilet Paper")
+ list[3] = GroceryItem.new(P_CATG, true,  0, "Food")
+ list[4] = GroceryItem.new(P_CHLD, true,  2, "Bread")
+ list[5] = GroceryItem.new(P_CHLD, false, 1, "Butter")
+ list[6] = GroceryItem.new(P_CHLD, true,  1, "Milk")
+ list[7] = GroceryItem.new(P_CHLD, false, 3, "Chips")
+ list[8] = GroceryItem.new(P_CHLD, true,  4, "Soda")
  
  treeview = Gtk::TreeView.new
  setup_tree_view(treeview)
@@ -97,30 +107,40 @@
    # If the product type is a category, count the quantity
    # of all of the products in the category that are going
    # to be bought.
-   if (e.product_type == $p_category)
+   if (e.product_type == P_CATG)
      j = i + 1
  
      # Calculate how many products will be bought in
      # the category.
-     while j < list.size && list[j].product_type != $p_category
+     while j < list.size && list[j].product_type != P_CATG
        list[i].quantity += list[j].quantity if list[j].buy
        j += 1
      end
-     
+ 
      # Add the category as a new root (parent) row (element).
      parent = store.append(nil)
-     # store.set_value(parent, $buy_index, list[i].buy) # <= same as below
-     parent[$buy_index]  = list[i].buy
-     parent[$qty_index]  = list[i].quantity
-     parent[$prod_index] = list[i].product
+     # store.set_value(parent, BUY_COLUMN, list[i].buy) # <= same as below
+     parent[BUY_COLUMN]  = list[i].buy
+     parent[COUNT_COLUMN]  = list[i].quantity
+     parent[PRODUCT_COLUMN] = list[i].product
  
    # Otherwise, add the product as a child row of the category.
    else
      child = store.append(parent)
-     # store.set_value(child, $buy_index, list[i].buy) # <= same as below
-     child[$buy_index]  = list[i].buy
-     child[$qty_index]  = list[i].quantity
-     child[$prod_index] = list[i].product
+     # store.set_value(child, BUY_COLUMN, list[i].buy) # <= same as below
+     child[BUY_COLUMN]  = list[i].buy
+     child[COUNT_COLUMN]  = list[i].quantity
+     child[PRODUCT_COLUMN] = list[i].product
    end
  end
  
@@ -131,6 +141,22 @@
  scrolled_win = Gtk::ScrolledWindow.new
  scrolled_win.add(treeview)
  scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC)
+ 
+ window = Gtk::Window.new("Grocery List (w/spin btt.)")
+ window.resizable = true
+ window.border_width = 10
+ window.signal_connect('destroy') { Gtk.main_quit }
+ window.set_size_request(275, 200)
  window.add(scrolled_win)
  window.show_all
  Gtk.main




ruby-gnome2-cvs メーリングリストの案内
Back to archive index