Gtk2-Ex-ErrorTextDialog

 view release on metacpan or  search on metacpan

devel/AddOn-FollowAppend.pm  view on Meta::CPAN

# stay at end when resize ...
#
# size-allocate is run-first, so for a shrink would have to keep track of
# whether the end of the text was previously visible



# Copyright 2009, 2010, 2011, 2013 Kevin Ryde

# This file is part of Gtk2-Ex-ErrorTextDialog.
#
# Gtk2-Ex-ErrorTextDialog is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as published
# by the Free Software Foundation; either version 3, or (at your option) any
# later version.
#
# Gtk2-Ex-ErrorTextDialog is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
# Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with Gtk2-Ex-ErrorTextDialog.  If not, see <http://www.gnu.org/licenses/>.

package Gtk2::Ex::TextView::FollowAppend;
use strict;
use warnings;
use Gtk2;
use Glib::Ex::SignalIds;

our $VERSION = 11

use constant DEBUG => 0;

sub new {
  my ($class, $textview) = @_;

  require Scalar::Util;

  my $self = bless { textview => $textview }, $class;
  Scalar::Util::weaken ($self->{'textview'});

  my $weak_self = $self;
  Scalar::Util::weaken ($weak_self);

  $self->{'textview_ids'} = Glib::Ex::SignalIds->new
    ($textview,
     $textview->signal_connect ('notify::buffer', \&_connect_textbuf,
                                \$weak_self));
  # initial textbuf connection
  _connect_textbuf ($textview, undef, \$weak_self);

  return $self;
}
sub _connect_textbuf {
  my ($textview, $pspec, $ref_weak_self) = @_;
  my $self = $$ref_weak_self || return;
  my $textbuf = $textview->get_buffer;
  $self->{'textbuf_ids'} = $textbuf && Glib::Ex::SignalIds->new
    ($textbuf,
     $textbuf->signal_connect_after ('insert-text',
                                     \&_textbuf_insert,
                                     $ref_weak_self),
     $textbuf->signal_connect_after ('insert-pixbuf',
                                     \&_textbuf_insert_pixbuf_or_anchor,
                                     $ref_weak_self),
     $textbuf->signal_connect_after ('insert-child-anchor',
                                     \&_textbuf_insert_pixbuf_or_anchor,
                                     $ref_weak_self));
}

# 'insert-pixbuf' and 'insert-child-anchor' on textbuf
sub _textbuf_insert_pixbuf_or_anchor {
  my ($textbuf, $iter, $pixbuf_or_anchor, $ref_weak_self) = @_;
  _textbuf_insert ($textbuf, $iter, undef, 1, $ref_weak_self);
}

# 'insert' handler on textbuf
sub _textbuf_insert {
  my ($textbuf, $iter, $text, $textlen, $ref_weak_self) = @_;
  my $self = $$ref_weak_self || return;
  my $end_iter = $textbuf->get_end_iter;

  if (DEBUG) {
    my $cursor_mark = $textbuf->get_insert;
    my $cursor_iter = $textbuf->get_iter_at_mark ($cursor_mark);
    my $insert_iter = $textbuf->get_iter_at_offset
      ($iter->get_offset - $textlen);
    print "FollowAppend ",
      " insert=", $insert_iter->get_offset, " len=$textlen,",
        " iter=", $iter->get_offset,
          " cursor=", $cursor_iter->get_offset,
            " end=", $end_iter->get_offset,
              " charcount=", $textbuf->get_char_count,
                "\n";
    print "  text=",(defined $text ? "'$text'" : "undef"),"\n",
  }

  $iter->equal($end_iter) or return;

  my $cursor_mark = $textbuf->get_insert;
  my $cursor_iter = $textbuf->get_iter_at_mark ($cursor_mark);
  $cursor_iter->equal($end_iter) or return;



( run in 1.092 second using v1.01-cache-2.11-cpan-39bf76dae61 )