Re: Forcing TreeView column widths while still allowing user resizing




On Jul 4, 2008, at 1:04 AM, Matthew Braid wrote:

One thing I have yet to get working is column widths. Columns MUST be
user-resizable, and I'd like to force the TreeView to _not_ autoresize
while its loading data but to instead keep its columns fixed to the
size stored in the box's state, but then once loading is complete
allow the user to resize at will.

After a bit of experimentation and poking around in gtktreeviewcolumn.c and gtktreeview.c, you can set it to have fixed column sizes and still allow user resizing, and i think this is what gives you what you want.

Since you'd set the columns as reorderable as well as resizable, this saves and restores both the width of each column as well as their display order. In a real app, you might want to skip saving and restoring the width of the last column.



#!/usr/bin/env perl
use warnings;
use strict;
use Glib ':constants';
use Gtk2 '-init';

#
# Basic column definitions.  These are in the order in which they will
# exist in the model.
#
my @cols = (
    { title => 'One',   type => 'Glib::String', default_width => 45 },
    { title => 'Two',   type => 'Glib::String', default_width => 75 },
    { title => 'Three', type => 'Glib::String', default_width => 300 },
);

#
# primitive way to store column width and arrangement state across
# invocations.  a real app would be much more sophisticated than this.
# see save_columns(), below, for how this gets created; we'll call
# save_columns() from the destroy signal on the main window.
#
my @layout = `cat saved_columns`;
if (@layout) {
    # got the lines, parse them...
    @layout = map {
                  chomp;
                  my @f = split;
                  { source => $f[0], width => $f[1] }
              } @layout;

} else {
    # make stuff up from config.
    @layout = map {
                  { source => $_, width => $cols[$_]{default_width} }
              } 0..$#cols;
}


my $list = Gtk2::ListStore->new (map { $_->{type} } @cols);


my $treeview = Gtk2::TreeView->new ($list);

#
# Create the view columns in saved layout order.
#
foreach my $l (@layout) {
    my $c = $cols[ $l->{source} ];

    my $cell = Gtk2::CellRendererText->new;

    my $column = Gtk2::TreeViewColumn->new_with_attributes
($c->{title}, $cell, text => $l- >{source});

    $column->set (
        clickable => TRUE,
        spacing => 0,
        reorderable => TRUE,         # user determines view order.
        sizing => 'fixed',           # do NOT autosize...
        fixed_width => $l->{width},  # use this, instead.
        resizable => TRUE,           # unless the user does something.
    );

    $column->set_sort_column_id ($l->{source}); # no property?

    $treeview->append_column ($column);
}


sub save_columns {
    open OUT, ">saved_columns" and do {
        foreach my $column ($treeview->get_columns) {
            #
            # 'width' is a readonly column describing the current
            # actual width.
            #
            print OUT join (' ', $column->get_sort_column_id,
                                 $column->get ('width'))
                    . "\n";
        }
        close OUT;
    };
}



#
# And the rest.
#

my $window = Gtk2::Window->new;
$window->set_default_size (500, 500);
$window->signal_connect (destroy => sub { save_columns(); Gtk2- >main_quit });

my $vbox = Gtk2::VBox->new;
$window->add ($vbox);

my $scroller = Gtk2::ScrolledWindow->new;
$scroller->set_policy ('automatic', 'automatic');
$scroller->add ($treeview);
$vbox->add ($scroller);

my $hbox = Gtk2::HBox->new;
$vbox->pack_start ($hbox, 0, 0, 0);

#
# Here's a way to chuck in randomly-sized strings to verify that the
# columns don't auto-size on input.
#
my $add_rows = Gtk2::Button->new ("Add rows");
$hbox->add ($add_rows);
$add_rows->signal_connect (clicked => sub {
    foreach (1..4) {
        $list->set ($list->append,
                    0, 'A' x int (rand 50),
                    1, 'B' x int (rand 50),
                    2, 'C' x int (rand 50));
    }
});

$window->show_all;
Gtk2->main;

__END__

--
The front of your fridge may be cheap and nasty, but I hope the next time you look at the back of your fridge, you'll regard it with suitable admiration.
  -- Tim Hunkin, "The Secret Life of Machines"




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]