On Jan 22, 2006, at 5:37 PM, zentara wrote:
I will mention that if I use set_default_size instead of set_size_request the window expands with the widget's size. I guess I have to think about it more.
You're telling the left textview's scrolled window not to scroll vertically. If you set_size_request on the toplevel, that is honored (and the user cannot shrink below that). If you set_default_size on the toplevel window, the toplevel asks the children how big they want to be. The scroller is told not to scroll its child, so it will respond that it wants all the space the child wants. The child wants enough space to display 500 rows...
You have to tell either the scrolled window or the textview to request *no* vertical space. Then it will work as you want.
when I link the $vadj scroll, the scrolled window WILL NOT goto the end mark at line 500, it ends up at around line 482.
I don't see this. From your description i suspected it to be something to do with the fact that the two views have different vertical sizes, but can't prove that, as it behaves correctly for me.
P.S. I modified your example to insert 500 lines, and it does not scroll to the end mark either. Does it work for you? Is this a window manager problem?
Worked for me, as you might expect. I wouldn't have posted it, otherwise. ;-)
Now, thinking about it some more and poking through other code, using linked textviews just for line numbers is a bit silly. The second textview + buffer takes up an awful lot of memory just to display line numbers. GtkTextView actually provides border windows for you to draw your own things on, such as line numbers and other annotations, and this is, in fact, what GtkSourceView does.
To that end, attached is a quick, still-somewhat-c-ish port of the line number drawing from gtksourceview.c. It's two almost two hundred lines, but requires no extra memory for a nearly useless text buffer, requires no synchronization of scrollbars, and does not require anything external to Gtk2.
#!/usr/bin/perl -w =doc This is a quick port of the line-number drawing code from gtksourceview. I've removed the stuff about markers and the ability to turn off line numbers. =cut package LineNumberedTextView; use strict; use Gtk2; use Glib ':constants'; use Glib::Object::Subclass Gtk2::TextView::, signals => { expose_event => \&_expose_event, }, ; sub INIT_INSTANCE { my $self = shift; # just make up a size, it will be set properly later. $self->set_border_window_size (left => 10); # start with a monospace font; the user can set whatever else he likes. $self->modify_font (Gtk2::Pango::FontDescription->from_string ('monospace')); } # This function is taken from gtk+/tests/testtext.c sub _get_lines { my ($text_view, $first_y, $last_y, $buffer_coords, $numbers) = @_; my $last_line_num = -1; @$buffer_coords = (); @$numbers = (); # Get iter at first y (my $iter, undef) = $text_view->get_line_at_y ($first_y); # For each iter, get its location and add it to the arrays. # Stop when we pass last_y my $count = 0; my $size = 0; while (! $iter->is_end) { my ($y, $height) = $text_view->get_line_yrange ($iter); push @$buffer_coords, $y; push @$numbers, $iter->get_line; ++$count; last if (($y + $height) >= $last_y); $iter->forward_line; } if ($iter->is_end) { my ($y, $height) = $text_view->get_line_yrange ($iter); my $line_num = $iter->get_line; if ($line_num != $last_line_num) { push @$buffer_coords, $y; push @$numbers, $line_num; ++$count; } } return $count; } sub _paint_margin { my ($self, $event) = @_; my $win = $self->get_window ('left'); my $y1 = $event->area->y; my $y2 = $y1 + $event->area->height; # get the extents of the line printing (undef, $y1) = $self->window_to_buffer_coords ('left', 0, $y1); (undef, $y2) = $self->window_to_buffer_coords ('left', 0, $y2); my @numbers; my @pixels; # get the line numbers and y coordinates. my $count = $self->_get_lines ($y1, $y2, [EMAIL PROTECTED], [EMAIL PROTECTED]); # A zero-lined document should display a "1"; we don't need to worry about # scrolling effects of the text widget in this special case if ($count == 0) { $count = 1; push @pixels, 0; push @numbers, 0; } #warn ("Painting line numbers $numbers[0] - $numbers[$#numbers]\n"); # set size. my $str = sprintf "%d", $self->get_buffer->get_line_count; my $layout = $self->create_pango_layout ($str); my ($text_width, undef) = $layout->get_pixel_size; $layout->set_width ($text_width); $layout->set_alignment ('right'); # determine the width of the left margin. my $margin_width = $text_width + 4; $self->set_border_window_size (left => $margin_width); my $i = 0; my $cur = $self->get_buffer->get_iter_at_mark ($self->get_buffer->get_insert); # Remember to account for zero-indexing my $cur_line = $cur->get_line + 1; while ($i < $count) { my $pos; (undef, $pos) = $self->buffer_to_window_coords ('left', 0, $pixels[$i]); my $line_to_paint = $numbers[$i] + 1; if ($line_to_paint == $cur_line) { $layout->set_markup ("<b>$line_to_paint</b>"); } else { $layout->set_markup ("$line_to_paint"); } $self->style->paint_layout ($win, $self->state, FALSE, undef, $self, undef, $text_width + 2, $pos, $layout); ++$i; } } sub _expose_event { my ($self, $event) = @_; # if the event is actually on the left window, we need to repaint # our line numbers. if ($event->window == $self->get_window ('left')) { return $self->_paint_margin ($event); } else { # otherwise, we just let TextView do all the work. return $self->signal_chain_from_overridden ($event); } } ############## package main; use strict; use Gtk2 -init; my $window = Gtk2::Window->new; my $scroller = Gtk2::ScrolledWindow->new; my $textview = LineNumberedTextView->new; my $buffer = $textview->get_buffer; while (<>) { $buffer->insert ($buffer->get_end_iter, $_); } $window->add ($scroller); $scroller->add ($textview); $window->set_default_size (500, 300); $window->show_all; $window->signal_connect (destroy => sub {Gtk2->main_quit}); Gtk2->main; # vim: set et sw=4 sts=4 :
-- elysse (pregnant): are your hands cold? me: uh, i suppose so. elysse: will you put them on me?
_______________________________________________ gtk-perl-list mailing list gtk-perl-list@gnome.org http://mail.gnome.org/mailman/listinfo/gtk-perl-list