ruby-****@sourc*****
ruby-****@sourc*****
2012年 11月 27日 (火) 06:42:09 JST
------------------------- REMOTE_ADDR = 184.145.95.170 REMOTE_HOST = URL = http://ruby-gnome2.sourceforge.jp/hiki.cgi?tut-gtk2-dnd-intro ------------------------- @@ -63,3 +63,129 @@ Gtk::Drag.dest_set(widget, flags, targets, actions) Do not be too much concerned with all the different ways we may be using when setting up source and destination widgets. Try to emulate the examples you can find in our tutorial, they should provide enough material, to grasp the basic understanding. + + + + + + + +# (10.2) +== DnD Tree View Items + + + + +{{image_right("treeview-builtin-dnd.png")}} + +Some Gtk widgets have built in drag-and-drop mechanism, which require very little or no additional coding. Such a widget is Gtk::TreeView. So our first example program will show that only with a line of code you can get the complete drag-and-drop behaviour for free. All you need is to set up the reorderable attribute to true, by using the 'Gtk::TreeView#reorderable=' method. The drag objects here are the tree view rows, regardless whether they are leaf or nodes with children. When you left-click, hold the mouse button down and drag the mouse simultaneously the cursor changes to the 'move-icon' and the row you are dragging appears underneath it. If you look carefully, when dragging, you will notice that a potential drop position is shown, namely, the items over which you are dragging the row get highlighted, and the when you are in-between i.e., above or below rows a line appears. If you are dropping the dragged row onto a highlighted row it will become it's child, but if you drop it when the line indicator is shown, the dragged item will be placed at that position. + + +Let's look at the code: + + +((*treeview-built-in-dnd.rb*)) + + #!/usr/bin/env ruby + require 'gtk2' + + module InitializeOfficeSuppliesFromASCItable + # Tree View Iinitialization Array Of Arrays: + # name, qty, Children + # --------------------------------------------- + INIT_ARRAY = [ + ['Stationery', nil, [ + ['Letter paper', "500 sheets", nil], + ['Envelopes', "200", nil], + ['Computer paper', nil, [ + ['Legal', "1 box", nil], + ['Letter', "2 boxes", nil], + ] + ] + ] + ], + + ['Notebooks & Writing Pads', nil, [ + ['Memo Book', "10", nil], + ['Journals', "5", nil], + ] + ], + + ['Computer Accessories', nil, [ + ['Printer Tonner', "2x C501AB", nil], + ['RWCDs&DVD', "100x 4GB", nil], + ] + ], + ] + + class OfficeSupplies + attr_accessor :name, :qty, :children + def initialize(name, qty, children) + @name, @qty, @children = name, qty, children + arr = [] + if @children + @children.each do |row| + arr << OfficeSupplies.new(*row) + end + @children = arr + end + end + end + + end + + include InitializeOfficeSuppliesFromASCItable + + office_supply_list = [] + INIT_ARRAY.each_with_index do |row, i| + office_supply_list[i] = OfficeSupplies.new(*row) + end + + def setup_tree_view(treeview) + renderer = Gtk::CellRendererText.new + column = Gtk::TreeViewColumn.new("Name", renderer, :text => NAME_COLUMN) + treeview.append_column(column) + renderer = Gtk::CellRendererText.new + column = Gtk::TreeViewColumn.new("Quantity", renderer, :text => QTY_COLUMN) + treeview.append_column(column) + end + + def load_office_supplies_into_tree_view(store, office_supply_list, parent) + # Add all of the names to the GtkTreeStore. + office_supply_list.each do |supplies_obj| + # If the supplies object has children it's a parent + if (supplies_obj.children) + # Add the parent as a new root row (element). + child_parent = store.append(parent) + child_parent[NAME_COLUMN] = supplies_obj.name + child_parent[QTY_COLUMN] = supplies_obj.qty + load_office_supplies_into_tree_view(store, supplies_obj.children, child_parent) + # Otherwise, add the leaf item as a child row. + else + child = store.append(parent) + child[NAME_COLUMN] = supplies_obj.name + child[QTY_COLUMN] = supplies_obj.qty + end + end + end + + NAME_COLUMN, QTY_COLUMN = 0, 1 + treeview = Gtk::TreeView.new(store = Gtk::TreeStore.new(String, String)) + load_office_supplies_into_tree_view(store, office_supply_list, nil) + treeview.expand_all # only works after treview is loaded + setup_tree_view(treeview) + + ## -- Enables automatic Drag-And-Drop in the tree view ------- + treeview.reorderable = true + + window = Gtk::Window.new("Built-in Drag-n-Drop Within a Tree View") + window.resizable = true + window.border_width = 10 + window.signal_connect('destroy') { Gtk.main_quit } + window.set_size_request(400, 350) + 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