Sounds difficult. For trapping resize events (and other window manager-related events like exposing) you can bind the <Configure> event. You have to be careful when setting the size of the text widget: if geometry propagation is turned on (which by default is), then any change to the child windows will change the size of the toplevel window, which in turn could cause a resize (if your geometry calculation were not exact) and this would again cause a <Configure> event and so on.
The other difficult part is determining the total line number or the xy position of the last character in the text widget. It's easy if the text is completely visible. In this case you can use a method like dlineinfo or bbox. But if the end of text is invisible because it's larger than the widget, then I don't know of any way to get information about the end.
| [reply] |
Thanks for the reply. I've played around with the dlineinfo() method, but it returns information in Pixels. How do I convert from pixels to actual width of characters and height of lines?
| [reply] |
You can use the ascent/descent information from the fontMetrics call. Of course, this does not help if you have embedded images or widgets in your text widget.
| [reply] |
Hi again, I'm not sure exactly what you are trying to do, but the thought just occured to me, that if you really want scalable text, you might be better off using Tk::Zinc. It will let you scale
text (which most other Toolkits don't allow). Now the example below is very simplistic, BUT you could work out an automatic sizing sub, where if you are given the pixel dimensions of the entire box, you could keep scaling the text, and checking it's bbox values, until it just fit into the display box. This is all frought with difficulties, like some fonts look ugly when scaled, etc. Anyways, left-click will zoom, right-click will shrink.
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
use Tk::Zinc;
my $mw = MainWindow->new();
$mw->geometry($mw->screenwidth . 'x' .
$mw->screenheight . '+0+20');
$mw->title("Text Scale Test");
my $zinc = $mw->Zinc(
-height => $mw->screenheight,
-width => $mw->screenwidth,
-backcolor => 'black',
-relief => 'raised'
)->pack();
$zinc->fontCreate(
"fonta",
-family => 'arial',
-size => -30,
-weight => 'bold'
);
my $text = $zinc->add('text',1,
-position => [$mw->screenwidth/2 , 75 ],
-text => 'foobar foobaz',
-composescale => 1,
-anchor => 'center',
-color => 'hotpink',
-font => 'fonta',
);
$mw->bind( '<ButtonPress-1>', sub { &move } );
$mw->bind( '<ButtonPress-3>', sub { &move1; } );
#my $id = $mw->repeat(75, sub{ &move } );
MainLoop;
sub move {
# $zinc->translate($text,0, 1);
$zinc->scale( $text, 1.1, 1.1);
}
sub move1 {
# $zinc->translate($text,0, 1);
$zinc->scale( $text, .9, .9);
}
__END__
| [reply] [d/l] |
I'd like to do is to make the Text widget only as large as I need to given the number of lines that are in the widget at the time. I don't think that should be too hard, since the text widget's height and width options are in terms of
lines and character width. If you say -height=>4, -width=>25,
that is 4 lines and 25 characters. I havn't tried a $mw configure yet, but as esserte said, you may run into an infinite feedback loop if you try to reconfigure the $text widget as the $mw is being resized. You might be able to work out a flag, that gets set when the $mw resize starts, and is unset on the Button-1 Release. Then do your $text resize after the $mw resize is finished. But back to the point of pixel size -vs -character size, look at this script, you don't need to worry about pixels. I didn't adjust for line width, but all you would need to do is loop through each line, take it's 'length' then reconfigure your $text widget -width option to the max length.
P.S. I guess there would be some trouble if you went to a very small window size, and you needed to search for a font that would fit and still be legible. All systems don't have the same fonts installed, so that is another problem.
#!/usr/bin/perl
use warnings;
use strict;
use Tk;
my $mw = tkinit;
$mw->fontCreate('big',
-family=>'courier',
-weight=>'bold',
-size=>int(-18*18/14));
my $tx = $mw->Text(
-height => 4, #initialy set it small
-width => 25,
)->pack();
foreach (1 .. 20 ) { $tx->insert( 'end', "line$_\n" ); }
$tx->insert('end', "Blah " x 10);
my $end = $tx->index('insert'); #get last line
$tx->configure(-height=>$end);
my $button = $mw->Button(-text=>'Reconfigure',
-command=>sub{
$tx->configure(-font => 'big');
$tx->update;
$tx->configure(-height => $end);
},
)->pack();
MainLoop;
| [reply] [d/l] |