Object Oriented PHP-GTK2 - Auto Scrolling TextView Object Oriented PHP-GTK2 - Auto Scrolling TextView
it's me, bob. lol. Object Oriented PHP-GTK2 OOPS

Auto Scrolling TextView

Append new data and have it automatically scroll down.

Topic: GtkTextView (View All Tutorials)
Keywords: gtktextview gtkscrolledwindow autoscroll bottom
Updated: 362 Days Ago, 2007/12/06 10:53

This widget is not a true GtkTextView, you might recognize it as a modified version of the Scrollable Text View tutorial. However since we need scrolling capabilities, that is a good widget to extend.

Auto Scroll

Hard to tell by a screenshot... trust me and/or download it. Link at bottom.

To automatically scroll, all we need to do is manually rescroll the textview every time we add data to the end of the text buffer. To make life easy, I will create a new method called append() which will jump to the end of the buffer, append the text, then scroll down.

 

Auto Scrolling Code

#!/usr/bin/php -c/etc/gtk/php.ini
<?php

define
('EXECROOT',dirname(__FILE__));

class 
bob {

    static 
$fp;
    
    static function 
readline($text) {
        if(
self::$fp) {
            if((
$line fgets(self::$fp))) {
                
$text->append($line);
                return 
true;
            } else {
                
fclose(self::$fp);
                
self::$fp null;
            }
        }
        
        return 
false;
    }
    
    static function 
update_gui() {
        while(
Gtk::events_pending() || Gdk::events_pending()) {
            
Gtk::main_iteration_do(true);
        }
    }
}

class 
bobTextView extends GtkScrolledWindow {

    public 
$viewer,$buffer;
    
    public function 
__construct($readonly true) {
        
parent::__construct();

        
$this->viewer = new GtkTextView;
        
$this->buffer $this->viewer->get_buffer();
        
        
$this->set_policy(Gtk::POLICY_NEVER,Gtk::POLICY_ALWAYS);
        
$this->set_shadow_type(Gtk::SHADOW_ETCHED_IN);
        
$this->viewer->set_wrap_mode(Gtk::WRAP_WORD_CHAR);
        
$this->viewer->set_editable(!$readonly);
        
$this->viewer->set_cursor_visible(!$readonly);
    
        
$this->add($this->viewer);
        
$this->show_all();
        return;
    }
    
    
// note 1
    
public function append($text) {
        
$this->buffer->place_cursor($this->buffer->get_end_iter());
        
$this->buffer->insert_at_cursor($text);
        
bob::update_gui();
        
        
// note 2
        
$this->viewer->scroll_to_iter($this->buffer->get_end_iter(),0);
        
bob::update_gui();
        return;
    }    

}

class 
bobWindow extends GtkWindow {

    public 
$text;
    
    public function 
__construct() {
        
parent::__construct();
        
        
$this->text = new bobTextView;

        
$this->set_position(Gtk::WIN_POS_CENTER);
        
$this->set_size_request(420,200);
        
$this->set_title('Auto Scrolling GtkTextView');
        
$this->set_border_width(6);
        
$this->connect_simple('delete-event',array($this,'on_quit'));
        
        
$this->add($this->text);
        
$this->show_all();
        return;
    }
    
    public function 
on_quit() {
        
$this->hide();
        
Gtk::main_quit();
        return;
    }

}

$w = new bobWindow;
if(
file_exists($file EXECROOT.'/demo-data.txt')) {
    
bob::$fp fopen($file,'r');
    
Gtk::timeout_add(1000,array('bob','readline'),$w->text);
} else {
    
$w->text->append('What did you do with my demo text file?');
}

Gtk::main();

$w->destroy();
unset(
$w);
exit(
0);

?>

Note 1

Here is our new method which we will use to append data to the end of the text buffer. Notice that it was built onto the parent class of my textview and not the actual buffer itself, however it uses the proper text buffer as it should.

Note 2

Notice both before this and after this I manually force the GUI to update. After adding new text we need to give GTK time to recalculate the height of the text area as well as recount the text area iterators. Then we can safely scroll down and know that it will scroll to the correct place. Then after scrolling I force the GUI update again to make sure it gets applied and the user sees it - in case some time later we are using this in a processing loop.

 

End Game

Was this document helpful? I appreciate your feedback.
What are the rules about reusing this code?


i can has web two point ooh // copyright © 2007-2008 bob majdak jr
[ xhtml css | firefox ie7 opera ]