RE: Unable To Keep Showing Last Item In Gtk2::TreeView



Williams, James P2 <james p2 williams lmco com> wrote:
How can I keep my automatic scrolling, even after these kinds of events?
Iâve tried reacting to various signals, but the tree view seems too stale
for $tree->get_visible_range() or $tree->scroll_to_cell() to work.
You might react to "size-allocate" events, but a slightly different approach
is necessary. Here's a hack around your test code:

Your suggestion was enough to get something running.  I had to keep track of how many items were added, and 
had to watch for scroll bar changes.  As far as I can tell, the scroll bar stays at the bottom now unless I 
move it, even if I resize the window to be shorter.  My modified version follows, for reference.

Thanks,

Jim

#!/usr/bin/perl

use strict;
use warnings;

use Glib qw(TRUE FALSE);
use Gtk2 -init;

my($numAdded)=0;

my($win,$tree)=createWin();
Glib::Timeout->add(1000,sub {tickCB($tree)});

$win->show_all();
Gtk2->main();


#
# Creates the widgets in the application.  Returns the main
# window and tree view.
#
sub createWin
{
   my($win,$scroll,$tree,$model,$mustScroll);


   $win=new Gtk2::Window();
   $win->set_default_size(250,300);
   $win->signal_connect(destroy => \&Gtk2::main_quit);

   $win->add($scroll=new Gtk2::ScrolledWindow());
   $scroll->add($tree=new Gtk2::TreeView());
   $tree->set_rules_hint(TRUE);

   $tree->insert_column_with_attributes(-1,'Goo',
      new Gtk2::CellRendererText(),text => 0);
   $tree->set_model($model=
      new Gtk2::ListStore('Glib::String'));

   $tree->signal_connect(
      size_allocate => sub {sizeCB(\$mustScroll,@_)});

   $model->signal_connect(
      row_inserted => sub {rowCB(\$mustScroll,$tree,@_)});

   $scroll->get_vadjustment()->signal_connect(
      value_changed => sub {$numAdded=0});

   addWords($model,100);
   showLast($tree,\$mustScroll);

   return ($win,$tree);
}


#
# Called at regular intervals to add more random "words" to
# the bottom of the tree view.  If the previous word was
# visible beforehand, scrolls the tree view so the new
# words are visible.
#
sub tickCB
{
   my($tree)= _;

   addWords($tree->get_model(),100);
   return TRUE;
}


#
# Adds random "words" to the bottom of the tree view.
#
sub addWords
{
   my($model,$numAdd)= _;
   my(@cons)=grep !/[aeiou]/,'a' .. 'z';

   for (1 .. $numAdd) {
      $model->set($model->append(),0,
         $cons[rand @cons] . 'oo');
      $numAdded++;
   }
}


#
# Scrolls the tree view so the last row is visible.
#
sub showLast
{
   my($tree,$mustScroll)= _;
   my($numRows)=$tree->get_model()->iter_n_children(undef);

   $tree->scroll_to_cell(
      new Gtk2::TreePath($numRows-1),undef,TRUE,0.0,1.0);
   $$mustScroll=TRUE;
   $numAdded=0;
}


#
# Called each time the tree view is resized.  This is where
# we correct the scroll bar, moving it to the bottom if
# appropriate.
#
sub sizeCB
{
   my($mustScroll,$tree,$rect)= _;

   showLast($tree,$mustScroll) if $$mustScroll;
}


#
# Called each time a row is added to the model.
#
sub rowCB
{
   my($mustScroll,$tree,$model,$path,$it)= _;
   my($numRows)=$model->iter_n_children(undef);
   my($lastVis);


   if ($tree->realized()) {
      $lastVis=($tree->get_visible_range())[1];
      $$mustScroll=$lastVis &&
         $lastVis->get_indices() == $numRows-2-$numAdded;
   } else {
      $$mustScroll=TRUE;
   }
}



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