Hi zentara, it's me again.
I experimented with sub scrollcallback{...} as you suggested, and indeed it provides a solution for my problem : to keep the existing behavior of the Text widget when the user drags or clicks on the scrollbar's elements,
and to extend this behavior with actions that I specify (adding text to the Text widget, perhaps fetching it from a file).
Now this part works, and I realize that there are two pairs of bindings on the Text widget itself that I want to extend in similar way. (1) when the user presses repeatedly the
up (down) arrow and the cursor hits the top (bottom) of the Text window, this causes Text to scroll up (down). When there is no more text to scroll to, I want to add some more
from an external source (a file), just as if the user was clicking on the Scrollbar's arrows.
(2) I want to add similar behavior for the mouse wheel rotation which normally also scrolls the text (on Win32).
I looked into Tk docs, tutorials and examples, but so far I failed to puzzle it out:
should I use bind? bindtags? configure? - I'm lost again.
Another succint example from you (or anyone else) would take me closer to the goal.
I was about to post above plea, out of laziness (the wrong kind), but I thought again. Another plea?
This time my hubris would not let me, and I went on to search and experiment some more.
Couple of hours later, here is the demo that shows all three behaviors that I was after.
To test it, just try to scroll the text in every possible way and watch the effect.
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
# create a Main window and a scrolled text widget
my $mw = MainWindow->new();
my $text = $mw->Scrolled(
"Text",
-scrollbars => 'e',
-relief => 'sunken',
-takefocus => 1
)->pack( -expand => 1, -fill => 'both' );
# redefine the scrollbar's callback that tells the Text to scroll
$text->Subwidget("yscrollbar")->configure( -command => \&Yscrollcallba
+ck, );
# add bindings for MouseWheel and for the Y arrow keys
$text->bind( "<MouseWheel>", \&OnYscrolllimit );
$text->bind( "<Key-Up>", \&OnYarrowlimit );
$text->bind( "<Key-Down>", \&OnYarrowlimit );
# for demo, fill Text with some lines ...
for ( 1 .. 200 ) {
$text->insert( 'end', "$_ test\n" );
$text->see('end');
}
my $lineAdded = 0; # and count the inserted ones
MainLoop;
### subs
sub Yscrollcallback {
$text->yview(@_); # scrollbar tells Text to scroll or moveto
OnYscrolllimit(); # additional behavior
}
sub OnYarrowlimit {
my $i = int( $text->index('insert') );
my $e = int( $text->index('end') );
if ( $i == 1 ) {
insertLines('1.0'); # up arrow hits the first line
}
elsif ( $i == $e - 1 ) {
insertLines('end'); # down arrow hits the last line
}
}
sub OnYscrolllimit {
my ( $top, $bot ) = $text->yview;
if ( $top == 0 ) {
insertLines('1.0'); # wheel or scrollbar try to go above th
+e first line
}
elsif ( $bot == 1 ) {
insertLines('end'); # wheel or scrollbar try to go below th
+e last line
}
}
sub insertLines {
my $where = shift;
my $number = shift || 1;
return unless $where =~ /^1.0|end$/;
++$lineAdded;
#print "insert [$lineAdded]: $where $number\n";
$text->insert( $where, "insertLines at $where $lineAdded\n" );
$text->see($where);
}
__END__
Thank you again for the help.
Rudif
-
Are you posting in the right place? Check out Where do I post X? to know for sure.
-
Posts may use any of the Perl Monks Approved HTML tags. Currently these include the following:
<code> <a> <b> <big>
<blockquote> <br /> <dd>
<dl> <dt> <em> <font>
<h1> <h2> <h3> <h4>
<h5> <h6> <hr /> <i>
<li> <nbsp> <ol> <p>
<small> <strike> <strong>
<sub> <sup> <table>
<td> <th> <tr> <tt>
<u> <ul>
-
Snippets of code should be wrapped in
<code> tags not
<pre> tags. In fact, <pre>
tags should generally be avoided. If they must
be used, extreme care should be
taken to ensure that their contents do not
have long lines (<70 chars), in order to prevent
horizontal scrolling (and possible janitor
intervention).
-
Want more info? How to link
or How to display code and escape characters
are good places to start.