Re: [gtk-list] Motif scrollbar patch attempt



On Sat, 7 Mar 1998, Per Lewau wrote:

> Hello,
> 
> I'm trying to patch gtk scrollbars to work like the Motif ones (that is,
> button 2 moves directly to the clicked spot; try it in Netscape for
> instance) and I'm stuck.
> 
> It appears as though it would be quite easy, but I need to translate the
> xy position clicked to an adjustment value. Now there is a dummy function
> gtk_range_calc_value that, by the sound of it, would do this. Two problems
> though. First, the value of the adjustment depends on the type of
> scrollbar, thus a subclass of gtkrange. Second, gtk_range_calc_value takes
> only one gint parameter position (beats me what that means) instead of x
> and y.

hm, first gtk_range_calc_value is a *dead* function, that means it is
a) nowhere used in gtk and
b) will always   return 0.0;

> 
> So the way I see it I have to add a new abstract method to GtkRange
> (gfloat gtk_range_calc_value(GtkRange *range, gint x, gint y)) and leave
> it up to subclasses to define it. 
> 
> Is there a better way? I can't seem to find one. Everything seems to boil
> down to setting the correct adjustment value without knowing anything
> about the type of scrollbar. 

yep, actually gtkrange just needs to support absolut postitioning as well.
while looking at the code i just figured i might try it out and hacked
something up to support the button 2 jump behaviour, patch appended.

the problem with this thing is, it requires a minor api change, that is
  gint (* trough_click)    (GtkRange *range,
                            gint      x,
                            gint      y);
  gint (* trough_keys)     (GtkRange *range,
                            GdkEventKey *key,
                            GtkScrollType *scroll,
                            GtkTroughType *trough);
from GtkRangeClass need to have support for an additional argument gfloat*
which introduces an api change and falls under the feature freeze for 1.0 ;(

note that the bahaviour is still somewhat different from motif, because
the slider just jumps to the specified position and then does nothing.
it actually requires a server grab at this point because the xserver
wouldn't report motion hint masks now cause those are not set for the
trough window.

but it think this should give you a nice start.


> Per Lewau (perle@lysator.liu.se)Student of Computer Science at the 
> 				University of Linkoping, 
> 				Sweden. 

---
ciaoTJ


diff -ru /home/timj/CVS/cvs.gimp.org/gtk+/gtk/gtkenums.h /usr/src/gtk+/gtk/gtkenums.h
--- /home/timj/CVS/cvs.gimp.org/gtk+/gtk/gtkenums.h	Tue Feb 17 04:03:51 1998
+++ /usr/src/gtk+/gtk/gtkenums.h	Tue Feb 17 01:01:22 1998
@@ -149,14 +149,16 @@
   GTK_SCROLL_STEP_BACKWARD,
   GTK_SCROLL_STEP_FORWARD,
   GTK_SCROLL_PAGE_BACKWARD,
-  GTK_SCROLL_PAGE_FORWARD
+  GTK_SCROLL_PAGE_FORWARD,
+  GTK_SCROLL_JUMP
 } GtkScrollType;
 
 typedef enum
 {
   GTK_TROUGH_NONE,
   GTK_TROUGH_START,
-  GTK_TROUGH_END
+  GTK_TROUGH_END,
+  GTK_TROUGH_JUMP,
 } GtkTroughType;
 
 typedef enum
diff -ru /home/timj/CVS/cvs.gimp.org/gtk+/gtk/gtkrange.c /usr/src/gtk+/gtk/gtkrange.c
--- /home/timj/CVS/cvs.gimp.org/gtk+/gtk/gtkrange.c	Sat Feb 28 21:19:34 1998
+++ /usr/src/gtk+/gtk/gtkrange.c	Sat Mar  7 08:36:34 1998
@@ -56,7 +56,8 @@
 static void gtk_real_range_draw_trough         (GtkRange         *range);
 static void gtk_real_range_draw_slider         (GtkRange         *range);
 static gint gtk_real_range_timer               (GtkRange         *range);
-static gint gtk_range_scroll                   (GtkRange         *range);
+static gint gtk_range_scroll                   (GtkRange         *range,
+						gfloat		  abs_pos);
 
 static void gtk_range_add_timer                (GtkRange         *range);
 static void gtk_range_remove_timer             (GtkRange         *range);
@@ -392,18 +393,27 @@
 
   g_return_val_if_fail (range != NULL, GTK_TROUGH_NONE);
   g_return_val_if_fail (GTK_IS_RANGE (range), GTK_TROUGH_NONE);
-
+  
   xthickness = GTK_WIDGET (range)->style->klass->xthickness;
   ythickness = GTK_WIDGET (range)->style->klass->ythickness;
-
+  
   if ((x > xthickness) && (y > ythickness))
     {
       gdk_window_get_size (range->trough, &trough_width, &trough_height);
-
+      
       if ((x < (trough_width - xthickness) && (y < (trough_height - ythickness))))
 	{
+	  gfloat *perc;
+	  
 	  gdk_window_get_position (range->slider, &slider_x, NULL);
 
+	  perc = gtk_object_get_data (GTK_OBJECT (range), "my_key");
+	  if (perc)
+	    {
+	      *perc = ((double) x) / ((double) trough_width);
+	      return GTK_TROUGH_JUMP;
+	    }
+
 	  if (x < slider_x)
 	    return GTK_TROUGH_START;
 	  else
@@ -437,8 +447,17 @@
 
       if ((x < (trough_width - xthickness) && (y < (trough_height - ythickness))))
 	{
+	  gfloat *perc;
+
 	  gdk_window_get_position (range->slider, NULL, &slider_y);
 
+	  perc = gtk_object_get_data (GTK_OBJECT (range), "my_key");
+	  if (perc)
+	    {
+	      *perc = ((double) y) / ((double) trough_height);
+	      return GTK_TROUGH_JUMP;
+	    }
+
 	  if (y < slider_y)
 	    return GTK_TROUGH_START;
 	  else
@@ -579,14 +598,6 @@
     }
 }
 
-gfloat
-gtk_range_calc_value (GtkRange *range,
-		      gint      position)
-{
-  return 0.0;
-}
-
-
 static void
 gtk_range_finalize (GtkObject *object)
 {
@@ -715,6 +726,7 @@
 {
   GtkRange *range;
   gint trough_part;
+  gfloat abs_pos;
 
   g_return_val_if_fail (widget != NULL, FALSE);
   g_return_val_if_fail (GTK_IS_RANGE (widget), FALSE);
@@ -723,8 +735,9 @@
   if (!GTK_WIDGET_HAS_FOCUS (widget))
     gtk_widget_grab_focus (widget);
 
+  abs_pos = -1;
   range = GTK_RANGE (widget);
-  if (!range->button)
+  if (range->button == 0)
     {
       gtk_grab_add (widget);
 
@@ -736,17 +749,26 @@
 	{
 	  range->click_child = RANGE_CLASS (range)->trough;
 
+	  if (range->button == 2)
+	    gtk_object_set_data (GTK_OBJECT (range), "my_key", &abs_pos);
+	  
 	  trough_part = gtk_range_trough_click (range, event->x, event->y);
+	  
+	  if (range->button == 2)
+	    gtk_object_remove_data (GTK_OBJECT (range), "my_key");
 
 	  range->scroll_type = GTK_SCROLL_NONE;
 	  if (trough_part == GTK_TROUGH_START)
 	    range->scroll_type = GTK_SCROLL_PAGE_BACKWARD;
 	  else if (trough_part == GTK_TROUGH_END)
 	    range->scroll_type = GTK_SCROLL_PAGE_FORWARD;
-
+	  else if (trough_part == GTK_TROUGH_JUMP &&
+		   abs_pos >= 0 && abs_pos <= 1)
+	    range->scroll_type = GTK_SCROLL_JUMP;
+	  
 	  if (range->scroll_type != GTK_SCROLL_NONE)
 	    {
-	      gtk_range_scroll (range);
+	      gtk_range_scroll (range, abs_pos);
 	      gtk_range_add_timer (range);
 	    }
 	}
@@ -760,7 +782,7 @@
 	  range->click_child = RANGE_CLASS (range)->step_forw;
 	  range->scroll_type = GTK_SCROLL_STEP_FORWARD;
 
-	  gtk_range_scroll (range);
+	  gtk_range_scroll (range, abs_pos);
 	  gtk_range_add_timer (range);
 	  gtk_range_draw_step_forw (range);
 	}
@@ -769,7 +791,7 @@
 	  range->click_child = RANGE_CLASS (range)->step_back;
 	  range->scroll_type = GTK_SCROLL_STEP_BACKWARD;
 
-	  gtk_range_scroll (range);
+	  gtk_range_scroll (range, abs_pos);
 	  gtk_range_add_timer (range);
 	  gtk_range_draw_step_back (range);
 	}
@@ -907,7 +929,7 @@
       if (scroll != GTK_SCROLL_NONE)
 	{
 	  range->scroll_type = scroll;
-	  gtk_range_scroll (range);
+	  gtk_range_scroll (range, -1);
 	  if (range->old_value != range->adjustment->value)
 	    {
 	      gtk_signal_emit_by_name (GTK_OBJECT (range->adjustment), "value_changed");
@@ -926,7 +948,7 @@
 	{
 	  if (pos == GTK_TROUGH_START)
 	    range->adjustment->value = range->adjustment->lower;
-	  else
+	  else if (pos == GTK_TROUGH_END)
 	    range->adjustment->value =
 	      range->adjustment->upper - range->adjustment->page_size;
 
@@ -1135,7 +1157,7 @@
 	  range->need_timer = FALSE;
 	}
 
-      if (gtk_range_scroll (range))
+      if (gtk_range_scroll (range, -1))
 	return return_val;
     }
 
@@ -1143,7 +1165,8 @@
 }
 
 static gint
-gtk_range_scroll (GtkRange *range)
+gtk_range_scroll (GtkRange *range,
+		  gfloat    abs_pos)
 {
   gfloat new_value;
   gint return_val;
@@ -1159,6 +1182,16 @@
     case GTK_SCROLL_NONE:
       break;
 
+    case GTK_SCROLL_JUMP:
+      if (abs_pos >= 0 && abs_pos <= 1)
+	{
+	  new_value = (range->adjustment->lower +
+		       (range->adjustment->upper - range->adjustment->page_size -
+			range->adjustment->lower) * abs_pos);
+	  printf ("range percentage: %f\n", abs_pos);
+	}
+      break;
+      
     case GTK_SCROLL_STEP_BACKWARD:
       new_value -= range->adjustment->step_increment;
       if (new_value <= range->adjustment->lower)
@@ -1168,7 +1201,7 @@
 	  range->timer = 0;
 	}
       break;
-
+      
     case GTK_SCROLL_STEP_FORWARD:
       new_value += range->adjustment->step_increment;
       if (new_value >= (range->adjustment->upper - range->adjustment->page_size))
@@ -1178,7 +1211,7 @@
 	  range->timer = 0;
 	}
       break;
-
+      
     case GTK_SCROLL_PAGE_BACKWARD:
       new_value -= range->adjustment->page_increment;
       if (new_value <= range->adjustment->lower)
@@ -1188,7 +1221,7 @@
 	  range->timer = 0;
 	}
       break;
-
+      
     case GTK_SCROLL_PAGE_FORWARD:
       new_value += range->adjustment->page_increment;
       if (new_value >= (range->adjustment->upper - range->adjustment->page_size))
@@ -1199,7 +1232,7 @@
 	}
       break;
     }
-
+  
   if (new_value != range->adjustment->value)
     {
       range->adjustment->value = new_value;
diff -ru /home/timj/CVS/cvs.gimp.org/gtk+/gtk/gtkrange.h /usr/src/gtk+/gtk/gtkrange.h
--- /home/timj/CVS/cvs.gimp.org/gtk+/gtk/gtkrange.h	Tue Feb 17 04:05:27 1998
+++ /usr/src/gtk+/gtk/gtkrange.h	Tue Feb 17 01:01:22 1998
@@ -132,8 +132,6 @@
 void           gtk_range_default_vmotion        (GtkRange      *range,
 						 gint           xdelta,
 						 gint           ydelta);
-gfloat         gtk_range_calc_value             (GtkRange      *range,
-						 gint           position);
 
 
 #ifdef __cplusplus



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