Re: Mouse wheel support for gtk+




Guillaume Laurent <glaurent@worldnet.fr> writes:

> Grant Likely <grantlikely@home.com> writes:
> 
> > I've been messing around with adding support for mouse wheels to gtk+,
> > and I'm wondering if anybody else has been working on the same thing.
> 
> Yes, me and Nick Lopez <kimo_sabe@atdot.org> (seperately).
> 
> > As a temporary measure, I've modified the gtkrange widget to allow
> > scrolling with a mouse wheel.
> 
> This is more or less what we both tried first :-). Nick then provided
> a much more complete patch for several other widgets.
> 
> BTW, Owen, I mailed you about that and this coordinate translation
> thing you had mentionned a few weeks ago, but got no reply. Isn't
> there any chances we could get this in for 1.2 ?

Well, I've previously considered this to be something that
is sort of a frill, and not worth pushing for for 1.2,
now that we are in freeze.

But I must admit that when I was home over the break, and
using a scrollwheel mouse, I noticed that it is one of 
those things that, when you have it, is sort of hard
to leave alone and not twiddle. And it felt strange
to have it do nothing under X. So I guess it would
be a selling point for GTK+ to have it work.

I don't like the idea of patching widgets one by one;
I'd rather have a comprehensive solution. Thinking about
it some more, it's hard to do a comprehensive, clean
solution without get_scroll_adjustments signal similar
to the set_scroll_adjustments we have now. Since I don't
want to add that during the freeze. So I think it
is better to substitute brevity for cleanliness

The following is a quick patch to make scrollwheels work
for range controls and for almost any widget inside of
scrolled window.

I'm not sure that the use of adj->step_increment is right -
it's probably too small. But, adj->page_size seems to
big to me. (Both of these feelings are without actually 
having a suitable mouse to test it with.) Maybe it
should be page_size/3 or sqrt (step_size * page_size).

Regards,
                                        Owen

==

Index: gtkviewport.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkviewport.c,v
retrieving revision 1.31
diff -u -r1.31 gtkviewport.c
--- gtkviewport.c	1999/01/15 16:00:36	1.31
+++ gtkviewport.c	1999/01/26 15:37:19
@@ -430,7 +430,9 @@
   attributes.colormap = gtk_widget_get_colormap (widget);
 
   event_mask = gtk_widget_get_events (widget) | GDK_EXPOSURE_MASK;
-  attributes.event_mask = event_mask;
+  /* We select on button_press_mask so that button 4-5 scrolls are trapped.
+   */
+  attributes.event_mask = event_mask | GDK_BUTTON_PRESS_MASK;
 
   attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
 
Index: gtkmain.c
===================================================================
RCS file: /cvs/gnome/gtk+/gtk/gtkmain.c,v
retrieving revision 1.106
diff -u -r1.106 gtkmain.c
--- gtkmain.c	1999/01/18 18:48:05	1.106
+++ gtkmain.c	1999/01/26 15:37:19
@@ -29,6 +29,7 @@
 #include "gtkmain.h"
 #include "gtkpreview.h"
 #include "gtkrc.h"
+#include "gtkscrolledwindow.h"
 #include "gtkselection.h"
 #include "gtksignal.h"
 #include "gtktable.h"
@@ -629,7 +630,7 @@
     {
       grab_widget = event_widget;
     }
-  
+
   /* Not all events get sent to the grabbing widget.
    * The delete, destroy, expose, focus change and resize
    *  events still get sent to the event widget because
@@ -675,7 +676,48 @@
     case GDK_VISIBILITY_NOTIFY:
       gtk_widget_event (event_widget, event);
       break;
-      
+
+    case GDK_BUTTON_PRESS:
+    case GDK_2BUTTON_PRESS:
+    case GDK_3BUTTON_PRESS:
+    /* We treat button 4-5 specially, assume we have
+     * a MS-style scrollwheel mouse, and try to find
+     * a plausible widget to scroll. We also trap
+     * button 4-5 double and triple clicks here, since
+     * they will be generated if the user scrolls quickly.
+     */
+      if ((grab_widget == event_widget) &&
+	  (event->button.button == 4 || event->button.button == 5))
+	{
+	  GtkWidget *range = NULL;
+	  GtkWidget *scrollwin;
+	  
+	  if (GTK_IS_RANGE (event_widget))
+	    range = event_widget;
+	  else
+	    {
+	      scrollwin = gtk_widget_get_ancestor (event_widget,
+						   GTK_TYPE_SCROLLED_WINDOW);
+	      if (scrollwin)
+		range = GTK_SCROLLED_WINDOW (scrollwin)->vscrollbar;
+	    }
+	  
+	  if (range && GTK_WIDGET_VISIBLE (range))
+	    {
+	      if (event->type == GDK_BUTTON_PRESS)
+		{
+		  GtkAdjustment *adj = GTK_RANGE (range)->adjustment;
+		  gtk_adjustment_set_value (adj, adj->value + 
+					    ((event->button.button == 4) ? 
+					         -adj->step_increment : 
+					          adj->step_increment));
+		}
+	      break;
+	    }
+	}
+      gtk_propagate_event (grab_widget, event);
+      break;
+
     case GDK_KEY_PRESS:
     case GDK_KEY_RELEASE:
       if (key_snoopers)
@@ -685,9 +727,6 @@
 	}
       /* else fall through */
     case GDK_MOTION_NOTIFY:
-    case GDK_BUTTON_PRESS:
-    case GDK_2BUTTON_PRESS:
-    case GDK_3BUTTON_PRESS:
     case GDK_BUTTON_RELEASE:
     case GDK_PROXIMITY_IN:
     case GDK_PROXIMITY_OUT:



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