0

I'm trying to setup the keypress function to assign the shift+up key combination to scroll back a single line in the vte terminal window. Here is what I have so far:

case GDK_Up: 
    if (event -> state & GDK_SHIFT_MASK)
    {
      GtkAdjustment *verticalAdjust;
      gdouble lower = 0;
      gdouble upper = 0;
      gdouble page_size = 0;
      gdouble step_size = 0.1;


      verticalAdjust = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrollwin[0]));
      lower = gtk_adjustment_get_lower(verticalAdjust);
      upper = gtk_adjustment_get_upper(verticalAdjust);
      page_size = gtk_adjustment_get_page_size(verticalAdjust);
      step_size = ((upper - page_size) - lower)/page_size;

      gtk_adjustment_set_value (verticalAdjust, step_size);

      gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW(scrollwin[0]), verticalAdjust);
      printf("vertAdj: %f, lower: %f, upper: %f, pg_size: %f, step_size: %f\n", gtk_adjustment_get_value(verticalAdjust), lower, upper, page_size, step_size);

      return TRUE;

    }

I read in the docs for gtk_adjustment_set_value ():

Note that for adjustments which are used in a GtkScrollbar, the effective range of allowed values goes from adjustment->lower to adjustment->upper - adjustment->page_size.

It doesn't give any guidance under gtk_scrolled_window_set_vadjustment.

So I thought maybe this formula would give me the scroll step size of a single line:

 `step_size = ((upper - page_size) - lower)/page_size;`

I was wrong. I tried a step size equal to the step_increment of the GtkAdjust structure Set with:

 step_size = gtk_adjustment_get_step_increment(verticalAdjust);

This just left the step_size at 1.0 for the most part, and scrolled back way too much when upper reached ~60.

I tried a step_size of 0.1, 1, 10 and I can't seem to make any sense out of how this whole adjustment thing works.

I just opened a new terminal window and typed dmesg then a single shift+up. I verified via the output created by the printf statement above that the step_size was 1.0, upper was 420 and the scrolled window scrolled all the way to the top. Something is not working right or I'm not getting something.

Any guidance would be much appreciated. Thanks.

nomadicME
  • 1,389
  • 5
  • 15
  • 35
  • I've never used vte, but most likely get_step_increment is the proper value. Upper and lower are going to be fixed for a given buffer # lines, but you have to make sure you set_value keeping the page size in mind. The maximum value you will want to give set_value will be get_upper()-get_page_size(). Of course, the minimum value should always be >= 0. – ergosys Jul 06 '12 at 03:23
  • @ergosys, the get_step_increment isn't doing it for me. I verified that it stays at a constant 1.0, but at an upper of 94 I scrolled back 55 lines with a single press of shift+up. Can you verify for me that this is the only way to scroll back programmatically (using GtkAdjustments). I haven't found any other ways, but I'm hoping. Thanks. – nomadicME Jul 06 '12 at 03:38
  • First a correction, the min value should be >= get_lower(), not 0 as I stated. Moving on, it seems like you are setting the value to the increment. You want to do something like set_value(clamp(get_value()-get_step_increment(),get_lower(),get_upper()-get_page_size())), where clamp restricts its arg #1 to be between arg#2 and arg#3, and returns it. – ergosys Jul 06 '12 at 04:06

2 Answers2

0

Ahh, the light came on!

Simply put to scroll back a single line you would need:

    adjust = upper - page_size - 1;
    gtk_adjustment_set_value (verticalAdjust, adjust);
    gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW(scrollwin[0]), verticalAdjust);

To scroll back another line you would need:

    adjust = upper - page_size - 2;
    gtk_adjustment_set_value (verticalAdjust, adjust);
    gtk_scrolled_window_set_vadjustment (GTK_SCROLLED_WINDOW(scrollwin[0]), verticalAdjust);

So you need to store some values between iterations. Supposedly the GtkAdjustment is supposed to be able to assist with this, but I never could figure out how. Or maybe I just misunderstood the docs. Anyway, I just decided to do it with global variables.

nomadicME
  • 1,389
  • 5
  • 15
  • 35
  • You don't need a global. Adjustments are associated with the scrolledwindow and contain the scroll position and related information. Think of them as objects in the ScrolledWindow object that you can access (get a pointer to) via e.g. get_vadjustment(). You don't need to call set_vadjustment, that's for replacing the existing object. So to scroll back one line: adj->set_value(adj->get_value()-1), its that simple, except for checking limits, as I mentioned. – ergosys Jul 06 '12 at 18:52
  • @ergosys, It really is that simple. It is kinda funny how complicated I was making it. I just couldn't find the way to put the pieces together. Again if you'd care to resubmit this explaination as an answer I'll accept it. Thanks again – nomadicME Jul 12 '12 at 05:45
  • I lack time. Go ahead and choose your answer, or add another one if you want. – ergosys Jul 12 '12 at 05:57
0

As ergosys pointed out the solution is much simpler than I previously thought. Here are the two lines I used to scroll up:

    vertAdj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrollwin[page]));
    gtk_adjustment_set_value (vertAdj,gtk_adjustment_get_value(vertAdj)-1);

and for the scroll down:

    vertAdj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(scrollwin[page]));
    adjValue = gtk_adjustment_get_value(vertAdj);

    upper = gtk_adjustment_get_upper(vertAdj);
    page_size = gtk_adjustment_get_page_size(vertAdj);

    if (adjValue < upper - page_size)
    {

      gtk_adjustment_set_value (vertAdj,gtk_adjustment_get_value(vertAdj)+1);

    }
nomadicME
  • 1,389
  • 5
  • 15
  • 35