ruby-****@sourc*****
ruby-****@sourc*****
2009年 2月 18日 (水) 01:32:59 JST
------------------------- REMOTE_ADDR = 74.15.84.244 REMOTE_HOST = URL = http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-treev-crs ------------------------- @@ -1,10 +1,152 @@ = The Tree View Widget -{{link "tut-gtk2-treev-cdf", "tut-gtk2-treev", "tut-gtk", "tut-gtk2-treev-pxbr"}} +{{link "tut-gtk2-treev-etr", "tut-gtk2-treev", "tut-gtk", "tut-gtk2-treev-pxbr"}} -= Sorry this page is still under construction - == Cell Renderers - +Up to this point, you have only learnt about one type of cell renderer, Gtk::CellRendererText. This renderer allows you to display strings, numbers and Boolean values as text. You are able to customize how how the text is displayed with cell renderer attributes and cell data functions and allow it to be edited by the user. -{{image_left("treev-cdf-01.png")}} +GTK+ provides a large number of cell renderers that can display other types of widgets beside text. Following is the list are of all of the cell renderers, about two the Gtk::CellRenderer and Gtk::CellRendererText you have already learnt, but the rest of which will all be covered in the reminder of this chapter. + +:Cell Renderers: + * Gtk::CellRenderer - An object for rendering a single cell on a Gdk::Drawable + * Gtk::CellRendererText - Renders text in a cell +:Still to be covered: + * Toggle Button Renderers (Gtk::CellRendererToggle) + * Pixbuf Renderers (Gtk::CellRendererPixbuf) + * Spin Button Renderers (Gtk::CellRendererSpin) + * Combo Box Renderers (Gtk::CellRendererCombo) + * Progress Bar Renderers (Gtk::CellRendererProgress) + * Keyboard Accelerator Renderers (Gtk::CellRendererAccel) + + + + +=== Toggle Button Renderers + +Displaying Boolean values as "TRUE" or "FALSE" with Gtk::CellRendererText is a bit tacky, and it takes up a large amount of valuable space in each row, especially when there are a lot of visible Boolean columns. You might be thinking that it would be nice if you could display a check button for Boolean values instead of text strings.It turns out that you can, with the help of a type of ell renderer called Gtk::CellRendererToggle. + +By default, toggle button cell renderers are drawn as a check button, but you can also set them up to be drawn as radio buttons, however you will need to manage the radio button functionality yourself. + +As with the editable text renderers, you have to manually apply the changes performed by the user. Otherwise, the button will not toggle visually on the screen. Because of this, Gtk::CellRendererToggle provides the ((*toggle*)) signal, which is emitted when the user presses the check button. + +We are using the same program as in the introductory session to the tree store (1.3 ((<Using Gtk::ListStore|tut-gtk2-treev-parts#Using Gtk::ListStore>))), there called "treestore.rb". The only changes are in the ((*setup_tree_view(treeview)*)) method, where we had to change the type of our cell renderer. An important, often overlooked change is also in the column line, where we change the name of the attribute that used to be "text" to "active". Since we wish to provide our users with the ability to interactively change the status of "Buy" column, wee need to make our toggle button clickable, which means that we also need to provide the callback proc (block) which will set the toggle to the new value. + +{{image_left("treev-crs-01.png")}} {{br}} + +The listing "treestore-toggle.rb" presents the Grocery List application with a toggled callback function. In it the $buy_index column is rendered with Gtk::CellRendererToggle. + +((*treestore-toggle.rb*)) + + #!/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. + def setup_tree_view(treeview) + # Create a new GtkCellRendererText, add it to the tree + # view column and append the column to the tree view. + + renderer = Gtk::CellRendererToggle.new + column = Gtk::TreeViewColumn.new("Buy", renderer, "active" => $buy_index) + + renderer.activatable = true + renderer.signal_connect('toggled') do |w, path| + iter = treeview.model.get_iter(path) + iter[$buy_index] = !iter[$buy_index] if (iter) + end + treeview.append_column(column) + + renderer = Gtk::CellRendererText.new + column = Gtk::TreeViewColumn.new("Count", renderer, "text" => $qty_index) + treeview.append_column(column) + renderer = Gtk::CellRendererText.new + column = Gtk::TreeViewColumn.new("Product", renderer, "text" => $prod_index) + 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) + + class GroceryItem + attr_accessor :product_type, :buy, :quantity, :product + def initialize(t,b,q,p) + @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 + + 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") + + treeview = Gtk::TreeView.new + setup_tree_view(treeview) + + # Create a new tree model with three columns, as Boolean, + # integer and string. + store = Gtk::TreeStore.new(TrueClass, Integer, String) + + # Avoid creation of iterators on every iterration, since they + # need to provide state information for all iterations. Hence: + # establish closure variables for iterators parent and child. + parent = child = nil + + # Add all of the products to the GtkListStore. + list.each_with_index do |e, i| + + # 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) + j = i + 1 + + # Calculate how many products will be bought in + # the category. + while j < list.size && list[j].product_type != $p_category + 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 + + # 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 + end + end + + # Add the tree model to the tree view + treeview.model = store + treeview.expand_all + + scrolled_win = Gtk::ScrolledWindow.new + scrolled_win.add(treeview) + scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC) + window.add(scrolled_win) + window.show_all + Gtk.main + +Toggle cell renderers are created