# Copyright (c) 2016 Ruby-GNOME2 Project Team # This program is licenced under the same licence as Ruby-GNOME2. # =begin = Tree View/Editable Cells This demo demonstrates the use of editable cells in a GtkTreeView. If you're new to the GtkTreeView widgets and associates, look into the GtkListStore example first. It also shows how to use the GtkCellRenderer::editing-started signal to do custom setup of the editable widget. The cell renderers used in this demo are GtkCellRendererText, GtkCellRendererCombo and GtkCellRendererProgress. =end class EditableCellsDemo Item = Struct.new("Item", :number, :product, :yummy) COL_ITEM_NUM, COL_ITEM_PROD, COL_ITEM_YUMMY = *(0..3).to_a COL_NUM_TEXT = 0 def initialize(main_window) @window = Gtk::Window.new(:toplevel) @window.screen = main_window.screen @window.title = "Editable Cells" @window.border_width = 5 vbox = Gtk::Box.new(:vertical, 5) @window.add(vbox) label = Gtk::Label.new("Shopping list (you can edit the cells)") vbox.pack_start(label, :expand => false, :fill => true, :padding => 0) sw = Gtk::ScrolledWindow.new sw.shadow_type = :etched_in sw.set_policy(:automatic, :automatic) vbox.pack_start(sw, :expand => true, :fill => true, :padding => 0) # create models create_items_model create_numbers_model # create tree view @treeview = Gtk::TreeView.new(@items_model) @treeview.selection.mode = :single add_columns sw.add(@treeview) # Some buttons hbox = Gtk::Box.new(:horizontal, 4) hbox.homogeneous = true vbox.pack_start(hbox, :expand => false, :fill => false, :padding => 0) button = Gtk::Button.new(:label => "Add item") button.signal_connect("clicked") { add_item } hbox.pack_start(button, :expand => true, :fill => true, :padding => 0) button = Gtk::Button.new(:label => "Remove item") button.signal_connect("clicked") { remove_item } hbox.pack_start(button, :expand => true, :fill => true, :padding => 0) @window.set_default_size(320, 200) end def run if !@window.visible? @window.show_all else @window.destroy end @window end private def add_item return if @items.nil? item = Item.new(0, "Description here", 50) @items << item # Insert a row below the current one path = @treeview.cursor[0] iter = if path current = @items_model.get_iter(path) @items_model.insert_after(current) else @items_model.insert(-1) end # set the data for the new row item.each_with_index do |value, index| iter[index] = value end # Move focus to the new row path = @items_model.get_path(iter) column = @treeview.get_column(0) @treeview.set_cursor(path, column, false) end def remove_item selection = @treeview.selection iter = selection.selected if iter path = @items_model.get_path(iter) i = path.indices[0] @items_model.remove(iter) @items.delete_at(i) end end def add_items @items << Item.new(3, "bottles of coke", 20) @items << Item.new(5, "packages of noodles", 50) @items << Item.new(2, "packages of chocolate chip cookies", 90) @items << Item.new(1, "can vanilla ice cream", 60) @items << Item.new(6, "eggs", 10) end def create_items_model @items = [] add_items # Create list store @items_model = Gtk::ListStore.new(Integer, String, Integer, TrueClass) @items.each do |item| iter = @items_model.append iter[COL_ITEM_NUM] = item.number iter[COL_ITEM_PROD] = item.product iter[COL_ITEM_YUMMY] = item.yummy end end def create_numbers_model @numbers_model = Gtk::ListStore.new(String, Integer) (1..10).each do |n| iter = @numbers_model.append iter[COL_NUM_TEXT] = n.to_s end end def add_columns add_number_column add_product_column add_yummy_column end def add_number_column renderer = Gtk::CellRendererCombo.new renderer.model = @numbers_model renderer.text_column = COL_NUM_TEXT renderer.has_entry = false renderer.editable = true renderer.signal_connect "edited" do |cell, path, new_text| cell_edited(cell, path, new_text) end renderer.signal_connect "editing-started" do |_cell, editable, path| editable.set_row_separator_func do |model, iter| path = model.get_path(iter) idx = path.indices[0] idx == 5 end end def renderer.column COL_ITEM_NUM end @treeview.insert_column(-1, "Number", renderer, :text => COL_ITEM_NUM) end def add_product_column renderer = Gtk::CellRendererText.new renderer.editable = true renderer.signal_connect "edited" do |cell, path, new_text| cell_edited(cell, path, new_text) end def renderer.column COL_ITEM_PROD end @treeview.insert_column(-1, "Product", renderer, :text => COL_ITEM_PROD) end def add_yummy_column renderer = Gtk::CellRendererProgress.new def renderer.column COL_ITEM_YUMMY end @treeview.insert_column(-1, "Yummy", renderer, :value => COL_ITEM_YUMMY) end def cell_edited(cell, path_string, new_text) path = Gtk::TreePath.new(path_string) column = cell.column iter = @items_model.get_iter(path) case column when COL_ITEM_NUM i = path.indices[0] @items[i].number = new_text.to_i iter.set_value(column, @items[i].number) when COL_ITEM_PROD i = path.indices[0] @items[i].product = new_text iter.set_value(column, @items[i].product) end end end