FreezePane using Gtk2::TreeStore
- From: ofey aikon <ofey_aikon yahoo com>
- To: gtk-perl-list gnome org
- Subject: FreezePane using Gtk2::TreeStore
- Date: Mon, 14 Jun 2004 22:10:37 -0700 (PDT)
Last month, I saw this nifty piece of code (from
muppet et al) in this list to create a freeze-pane
using Gtk2::TreeView.
I thought it will be cool to have a freezepane with a
Gtk2::TreeStore in place of Gtk2::ListStore. Also,
since we are talking about hierarchical data, I
thought it will be cool to use XML::Simple and build
the tree from a simple xml definition file.
Here is my code for that. This is my first
contribution to the 'free' world. I would love
feedback from you guys. (Assuming no one is annoyed by
a posting of code into the email list :) ). And may be
this can be included in the documentation/examples.
_Ofey
Here it comes :
-----------------
Tree data is contained in data.xml as follows
-----------------
<Node Name="Food Products">
<Node Name="Fruits">
<Node Name="Apple"
Color = "Red"
Price = "100.00"
Taste = "Sweet"
/>
<Node Name="Lemon"
Color = "Yellow"
Price = "78.10"
Taste = "Sour"
/>
</Node>
<Node Name="Vegetables">
<Node Name="Potato"
Color = "Brown"
Price = "100.00"
Source = "Idaho"
/>
<Node Name="Onion"
Color = "Yellow"
Taste = "Pungent"
/>
</Node>
</Node>
-----------------
And the code
-----------------
use strict;
use warnings;
use constant TRUE => 1;
use constant FALSE => !TRUE;
use Gtk2 -init;
use XML::Simple;
# Read the xml file into a hash using the XML::Simple
module
my $tree_xml_file = 'data.xml';
my $data_tree = XMLin($tree_xml_file, forcearray =>
1);
# Define the columns in the order to be seen
my $all_columns = [
{ ColumnName => 'Name' },
{ ColumnName => 'Color'},
{ ColumnName => 'Price'},
{ ColumnName => 'Taste'},
{ ColumnName => 'Source'}
];
# Let us choose to freeze the first column
my $frozen_columns = [$all_columns->[0]];
# Create two arrays for sending into the
Gtk2::TreeStore->new method
my @tree_store_full_types = map {'Glib::String'}
@$all_columns;
my @tree_store_frozen_types = map {'Glib::String'}
@$frozen_columns;
# Create the 'full' tree on the right side pane
my $tree_store_full =
Gtk2::TreeStore->new(@tree_store_full_types);
my $tree_view_full =
Gtk2::TreeView->new($tree_store_full);
my $column_count = 0;
for my $column (@$all_columns) {
my $column_name = $column->{ColumnName};
my $column =
Gtk2::TreeViewColumn->new_with_attributes(
$column_name, Gtk2::CellRendererText->new(),
text => $column_count);
$column->set_resizable(TRUE);
$tree_view_full->append_column($column);
# Hide the first column
# Ensure that the expander is fixed to the first
column (and hence is hidden too)
if ($column_count == 0) {
$column->set_visible(FALSE);
$tree_view_full->set_expander_column($column);
}
$column_count++;
}
# Create the single column tree for the left side pane
my $tree_store_frozen =
Gtk2::TreeStore->new(@tree_store_frozen_types);
my $tree_view_frozen =
Gtk2::TreeView->new($tree_store_frozen);
# There is only one column (the first column) in this
case
my $column_name = $frozen_columns->[0]->{ColumnName};
my $column =
Gtk2::TreeViewColumn->new_with_attributes(
$column_name, Gtk2::CellRendererText->new(),
text => 0);
$column->set_resizable(TRUE);
$tree_view_frozen->append_column($column);
# Synchronize the frozen-tree with the full-tree
$tree_view_frozen->signal_connect('row-expanded' =>
sub {
my ($view, $iter, $path) = @_;
$tree_view_full->expand_row($path,0);
}
);
$tree_view_frozen->signal_connect('row-collapsed' =>
sub {
my ($view, $iter, $path) = @_;
$tree_view_full->collapse_row($path);
}
);
# Recursive function to actually create the tree
append_children($tree_view_full->get_model(), undef,
$data_tree, $all_columns);
append_children($tree_view_frozen->get_model(), undef,
$data_tree, $frozen_columns);
# Add the frozen-tree to the left side of the pane
my $paned = Gtk2::HPaned->new;
$paned->add1 ($tree_view_frozen);
# we set the vertical size request very small, and it
will fill up the
# available space when we set the default size of the
window.
$tree_view_frozen->set_size_request (-1, 10);
# Add the full-tree to a scrolled window in the right
pane
my $scroll = Gtk2::ScrolledWindow->new;
$scroll->add ($tree_view_full);
$paned->add2 ($scroll);
# Synchronize the scrolling
$tree_view_frozen->set(vadjustment =>
$tree_view_full->get_vadjustment);
# Create a new window and add the pane into it
my $window = Gtk2::Window->new;
$window->signal_connect(destroy => sub {
Gtk2->main_quit; });
$window->add($paned);
$window->set_default_size(300, 100);
$window->show_all;
Gtk2->main;
# The obligatory recursive function to display the
tree
# I don't know the performance implications of using
recursion,
# but it seems easy to write and understand
sub append_children {
my ($tree_store, $iter, $data_tree, $columns) = @_;
if ($data_tree) {
my $count = 0;
my $child_iter = $tree_store->append ($iter);
for my $column(@$columns) {
my $column_name = $column->{ColumnName};
if ($data_tree->{$column_name}) {
$tree_store->set($child_iter, $count,
$data_tree->{$column_name});
}
$count++;
}
foreach my $child(@{$data_tree->{'Node'}}) {
append_children($tree_store, $child_iter, $child,
$columns);
}
}
}
__________________________________
Do you Yahoo!?
Friends. Fun. Try the all-new Yahoo! Messenger.
http://messenger.yahoo.com/
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]