PHP-GTK2 Newsletter

PHP-GTK2 Tips & Techniques
FREE Newsletter
by kksou



Sample Code 50: How to drag and drop between 2 GtkTreeViews - Part 1 - left to right?
Written by kksou   
Sunday, 08 October 2006
Problem

You would like to drag and drop items from the treeview on the left to the treeview on the right as shown below:

How to drag and drop between 2 GtkTreeViews - Part 1 - left to right?


Solution

Sample Code
1   
2   
3   
4   
5   
6   
7   
8   
9   
10   
11   
12   
13   
14   
15   
16   
17   
18   
19   
20   
21   
22   
23   
24   
25   
26   
27   
28   
29   
30   
31   
32   
33   
34   
35   
36   
37   
38   
39   
40   
41   
42   
43   
44   
45   
46   
47   
48   
49   
50   
51   
52   
53   
54   
55   
56   
57   
58   
59   
60   
61   
62   
63   
64   
65   
66   
67   
68   
69   
70   
71   
72   
73   
74   
75   
76   
77   
78   
79   
80   
81   
82   
83   
84   
85   
86   
87   
88   
89   
90   
91   
92   
93   
94   
95   
96   
97   
98   
99   
100   
101   
102   
103   
<?php
$window = new GtkWindow();
$window->set_size_request(600, 240);
$window->connect_simple('destroy', array('Gtk','main_quit'));
$window->add($vbox = new GtkVBox());

// display title
$title = new GtkLabel("Drag and Drop between 2 TreeViews - Part 1 (left to right)");
$title->modify_font(new PangoFontDescription("Times New Roman Italic 10"));
$title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff"));
$title->set_size_request(-1, 40);
$vbox->pack_start($title, 0, 0);
$vbox->pack_start(new GtkLabel(''), 0, 0);
$vbox->pack_start($hbox = new GtkHBox());

// Set up treeview1
$data1 = array(
    array('row0', 'item 42', 2, 3.1),
    array('row1', 'item 36', 20, 6.21),
    array('row2', 'item 21', 8, 9.36),
    array('row3', 'item 10', 11, 12.4),
    array('row4', 'item 7', 5, 15.5),
    array('row5', 'item 4', 17, 18.6),
    array('row6', 'item 3', 20, 21.73));
$view1 = display_table ($hbox, $data1);
$view1->drag_source_set(Gdk::BUTTON1_MASK,  
    array( array( 'text/plain', 0, 0)), Gdk::ACTION_COPY|Gdk::ACTION_MOVE); // note 1
$view1->connect('drag-data-get', 'on_drag'); // note 2
$hbox->pack_start(new GtkLabel('  '), 0, 0);

// Set up treeview2
$data2 = array(
    array('row7', 'item 127', 105, 115.5),
    array('row8', 'item 124', 117, 118.6),
    array('row9', 'item 123', 120, 121.73));
$view2 = display_table ($hbox, $data2);
$view2->drag_dest_set(Gtk::DEST_DEFAULT_ALL, 
    array( array( 'text/plain', 0, 0)), Gdk::ACTION_COPY|Gdk::ACTION_MOVE); // note 3
$view2->connect('drag-data-received', 'on_drop', $view1); // note 4

$window->show_all();
Gtk::main();

function display_table($container, $data) {

    // Set up a scroll window
    $scrolled_win = new GtkScrolledWindow();
    $scrolled_win->set_policy( Gtk::POLICY_AUTOMATIC,
        Gtk::POLICY_AUTOMATIC);
    $container->pack_start($scrolled_win);

    // Creates the list store
    if (defined("GObject::TYPE_STRING")) {
        $model = new GtkListStore(GObject::TYPE_STRING, GObject::TYPE_STRING,
                GObject::TYPE_LONG, GObject::TYPE_DOUBLE);
    } else {
        $model = new GtkListStore(Gtk::TYPE_STRING, Gtk::TYPE_STRING,
                    Gtk::TYPE_LONG, Gtk::TYPE_DOUBLE);
    }
    $field_header = array('Row #', 'Description', 'Qty', 'Price');
    $field_justification = array(0.0, 0.0, 0.5, 1.0);

    // Creates the view to display the list store
    $view = new GtkTreeView($model);
    $scrolled_win->add($view);

    // Creates the columns
    for ($col=0; $col<count($field_header); ++$col) {
        $cell_renderer = new GtkCellRendererText();
        $cell_renderer->set_property("xalign", $field_justification[$col]);
        $column = new GtkTreeViewColumn($field_header[$col],
            $cell_renderer, 'text', $col);
        $column->set_alignment($field_justification[$col]);
        $column->set_sort_column_id($col);

        // set the header font and color
        $label = new GtkLabel($field_header[$col]);
        $label->modify_font(new PangoFontDescription("Arial Bold"));
        $label->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000FF"));
        $column->set_widget($label);
        $label->show();

        // setup self-defined function to display alternate row color
        $column->set_cell_data_func($cell_renderer, "format_col", $col);
        $view->append_column($column);
    }

    // pupulates the data
    for ($row=0; $row<count($data); ++$row) {
        $values = array();
        for ($col=0; $col<count($data[$row]); ++$col) {
            $values[] = $data[$row][$col];
        }
        $model->append($values);
    }

    // setup selection
    $selection = $view->get_selection();
    $selection->connect('changed', 'on_selection');
    return $view;
}

// display alternate row color
  • Note that this is only 70% of the sample code. You have to be a registered member to see the entire sample code. Please login or register.
  • Registration is free and immediate.
  • Have some doubt about the registration? Please read this forum article.
Explanation
  1. To enable drag on the source treeview, we use the method drag_source_set(start_button_mask, targets, actions).
    • start_button_mask: just a combination of GDK Modifier Constants
    • targets: an array containing information about the targets. For each target,
      1. the first element is the MIME type of the drag source. For treeview items, we use 'text/plain'.
      2. The second element is the target flags, which could be a combination of gtk.TARGET_SAME_APP and gtk.TARGET_SAME_WIDGET or neither. Here we just use 0 which means no restriction.
      3. The last element is an integer ID used for identification purpose. Here we also just put a 0.
    • actions: a combination of GDK Drag Action Constants. Here we use Gdk::ACTION_COPY|Gdk::ACTION_MOVE.
  2. The signal drag-data-get allows us to know when user start dragging.
  3. To enable drop on the destination treeview, we use the method drag_dest_set(flags, targets, actions).
    • flags is one of four GtkDestDefaults values which define how the widget reacts when the drag is over the widget. Here we use GTK_DEST_DEFAULT_ALL.
    • targets and actions are exactly the same as in note 1.
  4. The signal drag-data-received allows us to know when user "drops" an item.
  5. Store the item to be dragged in the data field.
  6. Remove the item from the source first, and append the dragged item to the end of the destination tree view.

Related Links
 
< Prev   Next >

Blog - Forum - Privacy Policy - Contact Us
Copyright © 2006-2012. kksou.com. All Rights Reserved