Re: Control what happens when GtkTextView is resized: keep the bottom part visible



Bind a callback to the "size-allocate" signal of the scrolled window:

#include <gtk/gtk.h>

void cb_autoscroll_to_end( GtkWidget* widget, GtkAllocation* allocation, gpointer user_data)
{
    GtkAdjustment    *vericalAdjust;
    GtkAllocation       hscrollAlloc;
GtkWidget *hscrollBar; /* the horizontal scroll bar of the scrolled window */
    double                 upper, height;

    /* get the vertical adjustment of the scrolled window */
vericalAdjust = gtk_scrolled_window_get_vadjustment( GTK_SCROLLED_WINDOW( widget ) ); /* get the upper bound of the adjustment - you want your text to end at that point */
    upper = gtk_adjustment_get_upper( vericalAdjust );
    height = allocation->height;

/* if there is a scroll bar at the bottom, it will steal some of the available pixels for the text */ hscrollBar = gtk_scrolled_window_get_hscrollbar( GTK_SCROLLED_WINDOW( widget ) );
    gtk_widget_get_allocation( hscrollBar, &hscrollAlloc );

/* as long as (the scroll widget height - height of the horiz scrollbar) is the same as the upper bound of the adjustment, the whole text can be seen without obstruction and you do not need to auto scroll */
    if ( ( height - hscrollAlloc.height ) >= upper )
    {
        gtk_adjustment_set_value( vericalAdjust, 0 );
    }
    else
    {
        /* otherwise you need to scroll down to the point where */
        double newPosition = upper - ( height - hscrollAlloc.height );
        gtk_adjustment_set_value( vericalAdjust, newPosition );
    }
}

After you create the scroll window in main(), connect like:

g_signal_connect( scr1, "size-allocate", G_CALLBACK( cb_autoscroll_to_end ), NULL );

It will work with every scroll bar policy (always, none, auto)....

Cheers!

On 11/09/2009 05:12 AM, Eduardo M KALINOWSKI wrote:
I have a question concerning how to set which part of a GtkTextBuffer is
displayed when a GtkTextView is resized.

To explain the situation, consider this sample code:

----8<----
/* gcc -o tvtest tvtest.c `pkg-config --libs --cflags gtk+-2.0` */
#include<gtk/gtk.h>

int main(int argc, char *argv[])
{
   GtkWidget     *window;
   GtkWidget     *vpaned;
   GtkWidget     *text1;
   GtkWidget     *scr1;
   GtkTextBuffer *buffer;
   GtkWidget     *text2;
   GtkWidget     *scr2;

   gtk_init(&argc,&argv);

   window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
   gtk_widget_set_size_request(window, 500, 300);
   g_signal_connect(G_OBJECT(window), "delete-event",
                    G_CALLBACK(gtk_main_quit), NULL);

   vpaned = gtk_vpaned_new();

   text1 = gtk_text_view_new();
   buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text1));
   gtk_text_buffer_set_text(buffer,
                            "Lorem ipsum dolor sit amet,\n"
                            "consectetur adipisicing elit,\n"
                            "sed do eiusmod tempor incididunt\n"
                            "ut labore et dolore magna aliqua.\n"
                            "Ut enim ad minim veniam,\n"
                            "quis nostrud exercitation ullamco laboris\n"
                            "nisi ut aliquip ex ea commodo consequat.\n"
                            "Duis aute irure dolor in reprehenderit\n"
                            "in voluptate velit esse cillum dolore\n"
                            "eu fugiat nulla pariatur.\n"
                            "Excepteur sint occaecat cupidatat non
proident,\n"
                            "sunt in culpa qui officia\n"
                            "deserunt mollit anim id est laborum.", -1);

   text2 = gtk_text_view_new_with_buffer(buffer);

   scr1 = gtk_scrolled_window_new(NULL, NULL);
   gtk_container_add(GTK_CONTAINER(scr1), text1);
   gtk_paned_add1(GTK_PANED(vpaned), scr1);

   scr2 = gtk_scrolled_window_new(NULL, NULL);
   gtk_container_add(GTK_CONTAINER(scr2), text2);
   gtk_paned_add2(GTK_PANED(vpaned), scr2);

   gtk_container_add(GTK_CONTAINER(window), vpaned);

   gtk_widget_show_all(window);
   gtk_main();

   return 0;
}
----8<----

When the division in the GtkPaned is moved, what happens is that the top
of the GtkTextViews remains the same (thus keeps displaying the same
thing), while the bottom part shrinks, hiding some text at the bottom if
the widget gets smaller, or displaying more text at the bottom if it is
enlarged.

What I would like to do is the opposite: for the GtkTextView in the
bottom, I'd like that the bottom of the widget remains the same, but
changes in size are reflected at the top: if the widget shrinks, then
less text at the top should be displayed, if it grows, then more text at
the top should be displayed. The bottom should remain fixed displaying
always the same part.

Another way to visualize is that by changing the division in the
GtkPaned it should cover more of the top of the bottom GtkTextView,
instead of pushing it down.

Does anyone have a solution for that?




[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]