2006-09-22 Tommi Komulainen <tommi.komulainen@nokia.com>
authorMichael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
Fri, 22 Sep 2006 14:16:11 +0000 (14:16 +0000)
committerMichael Dominic Kostrzewa <michael.kostrzewa@nokia.com>
Fri, 22 Sep 2006 14:16:11 +0000 (14:16 +0000)
* hildon-widgets/hildon-volumebar.h (HildonVolumebarPrivate)
* hildon-widgets/hildon-volumebar.c (hildon_volumebar_size_allocate,
hildon_volumebar_realize, hildon_volumebar_unrealize,
hildon_volumebar_map, hildon_volumebar_unmap,
hildon_volumebar_notify, hildon_volumebar_class_init): Add a
input-only event window to catch button-press events anywhere in the
widget when the widget is insensitive. NB#6214

* hildon-widgets/hildon-hvolumebar.c (hildon_hvolumebar_size_allocate):
* hildon-widgets/hildon-vvolumebar.c (hildon_vvolumebar_size_allocate):
Chain to parent so that the event window is properly resized.

ChangeLog
hildon-widgets/hildon-hvolumebar.c
hildon-widgets/hildon-volumebar-private.h
hildon-widgets/hildon-volumebar.c
hildon-widgets/hildon-vvolumebar.c

index a7d4c61..cd8cc10 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2006-09-22  Tommi Komulainen  <tommi.komulainen@nokia.com>
+
+       * hildon-widgets/hildon-volumebar.h (HildonVolumebarPrivate)
+       * hildon-widgets/hildon-volumebar.c (hildon_volumebar_size_allocate,
+       hildon_volumebar_realize, hildon_volumebar_unrealize,
+       hildon_volumebar_map, hildon_volumebar_unmap,
+       hildon_volumebar_notify, hildon_volumebar_class_init): Add a
+       input-only event window to catch button-press events anywhere in the
+       widget when the widget is insensitive. NB#6214
+
+       * hildon-widgets/hildon-hvolumebar.c (hildon_hvolumebar_size_allocate): 
+       * hildon-widgets/hildon-vvolumebar.c (hildon_vvolumebar_size_allocate): 
+       Chain to parent so that the event window is properly resized.
+
 2006-09-22  Michael Dominic Kostrzewa  <michael.kostrzewa@nokia.com> 
 
        * hildon-widgets-plugins/hildon-color-chooser-dialog-hsv.c:
index e0fa651..b1925c9 100644 (file)
@@ -238,7 +238,7 @@ hildon_hvolumebar_size_allocate(GtkWidget * widget,
         allocation->height = DEFAULT_BAR_HEIGHT;
     }
 
-    widget->allocation = *allocation;
+    GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
 
     if (priv->tbutton && GTK_WIDGET_VISIBLE(priv->tbutton)) {
 
index f4c873b..e13bdba 100644 (file)
@@ -38,6 +38,7 @@ struct _HildonVolumebarPrivate {
   HildonVolumebarRange *volumebar;
   GtkToggleButton      *tbutton;
   gboolean              is_toolbar; /* is inside toolbar (for horizontal volumebar) */
+  GdkWindow            *event_window; /* input-only window to catch insensitive presses */
 };
 
 void _hildon_volumebar_mute_toggled(HildonVolumebar * self);
index 75dc7d4..75008c2 100644 (file)
@@ -70,6 +70,14 @@ static gboolean
 hildon_volumebar_key_press(GtkWidget * widget,
                            GdkEventKey * event);
 
+static void hildon_volumebar_size_allocate (GtkWidget *widget,
+                                           GtkAllocation *allocation);
+static void hildon_volumebar_realize (GtkWidget *widget);
+static void hildon_volumebar_unrealize (GtkWidget *widget);
+static void hildon_volumebar_map (GtkWidget *widget);
+static void hildon_volumebar_unmap (GtkWidget *widget);
+static void hildon_volumebar_notify (GObject *self, GParamSpec *param);
+
 
 enum 
 {
@@ -129,6 +137,11 @@ hildon_volumebar_class_init(HildonVolumebarClass *volumebar_class)
        override forall method */
     volumebar_class->mute_toggled = mute_toggled;
     container_class->forall = hildon_child_forall;
+    widget_class->size_allocate = hildon_volumebar_size_allocate;
+    widget_class->realize = hildon_volumebar_realize;
+    widget_class->unrealize = hildon_volumebar_unrealize;
+    widget_class->map = hildon_volumebar_map;
+    widget_class->unmap = hildon_volumebar_unmap;
     widget_class->key_press_event = hildon_volumebar_key_press;
     object_class->destroy = hildon_volumebar_destroy;
 
@@ -155,6 +168,7 @@ hildon_volumebar_class_init(HildonVolumebarClass *volumebar_class)
                                                  gtk_marshal_VOID__VOID,
                                                  G_TYPE_NONE, 0);
     
+    gobject_class->notify = hildon_volumebar_notify;
     gobject_class->set_property = hildon_volumebar_set_property;
     gobject_class->get_property = hildon_volumebar_get_property; 
 
@@ -212,6 +226,90 @@ hildon_volumebar_init(HildonVolumebar * volumebar)
 }
 
 static void
+hildon_volumebar_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
+{
+    HildonVolumebarPrivate *priv;
+
+    priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+    if (GTK_WIDGET_CLASS (parent_class)->size_allocate)
+       GTK_WIDGET_CLASS (parent_class)->size_allocate (widget, allocation);
+
+    if (GTK_WIDGET_REALIZED (widget))
+       gdk_window_move_resize (priv->event_window,
+                               allocation->x, allocation->y,
+                               allocation->width, allocation->height);
+}
+
+static void
+hildon_volumebar_realize (GtkWidget *widget)
+{
+    HildonVolumebarPrivate *priv;
+    GdkWindowAttr attributes;
+    gint attributes_mask;
+
+    priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+    GTK_WIDGET_CLASS(parent_class)->realize(widget);
+
+    attributes.window_type = GDK_WINDOW_CHILD;
+    attributes.x = widget->allocation.x;
+    attributes.y = widget->allocation.y;
+    attributes.width = widget->allocation.width;
+    attributes.height = widget->allocation.height;
+    attributes.wclass = GDK_INPUT_ONLY;
+    attributes.event_mask = GDK_BUTTON_PRESS_MASK;
+
+    attributes_mask = GDK_WA_X | GDK_WA_Y;
+
+    priv->event_window = gdk_window_new (widget->window,
+                                        &attributes, attributes_mask);
+    gdk_window_set_user_data (priv->event_window, widget);
+}
+
+static void
+hildon_volumebar_unrealize (GtkWidget *widget)
+{
+    HildonVolumebarPrivate *priv;
+
+    priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+    if (priv->event_window) {
+       gdk_window_set_user_data (priv->event_window, NULL);
+       gdk_window_destroy (priv->event_window);
+       priv->event_window = NULL;
+    }
+
+    GTK_WIDGET_CLASS(parent_class)->unrealize(widget);
+}
+
+static void
+hildon_volumebar_map (GtkWidget *widget)
+{
+    HildonVolumebarPrivate *priv;
+
+    priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+    GTK_WIDGET_CLASS(parent_class)->map(widget);
+
+    /* the event window must be on top of all other widget windows, so show it
+     * last */
+    if (!GTK_WIDGET_SENSITIVE (widget))
+       gdk_window_show (priv->event_window);
+}
+
+static void hildon_volumebar_unmap (GtkWidget *widget)
+{
+    HildonVolumebarPrivate *priv;
+
+    priv = HILDON_VOLUMEBAR_GET_PRIVATE(widget);
+
+    gdk_window_hide (priv->event_window);
+
+    GTK_WIDGET_CLASS(parent_class)->unmap(widget);
+}
+
+static void
 hildon_child_forall(GtkContainer * container,
                     gboolean include_internals,
                     GtkCallback callback, gpointer callback_data)
@@ -232,6 +330,27 @@ hildon_child_forall(GtkContainer * container,
     (*callback) (GTK_WIDGET(priv->volumebar), callback_data);
 }
 
+static void
+hildon_volumebar_notify (GObject *self, GParamSpec *param)
+{
+    HildonVolumebarPrivate *priv;
+
+    priv = HILDON_VOLUMEBAR_GET_PRIVATE(self);
+
+    if (GTK_WIDGET_MAPPED (self)) {
+       /* show/hide the event window on sensitivity change */
+       if (g_str_equal (param->name, "sensitive")) {
+           if (GTK_WIDGET_SENSITIVE (self))
+               gdk_window_hide (priv->event_window);
+           else
+               gdk_window_show (priv->event_window);
+       }
+    }
+
+    if (G_OBJECT_CLASS(parent_class)->notify)
+       G_OBJECT_CLASS(parent_class)->notify (self, param);
+}
+
 static void 
 hildon_volumebar_destroy(GtkObject * self)
 {
index 1069f9b..73d742e 100644 (file)
@@ -190,7 +190,7 @@ hildon_vvolumebar_size_allocate(GtkWidget * widget,
         allocation->width = DEFAULT_BAR_WIDTH;
     }
 
-    widget->allocation = *allocation;
+    GTK_WIDGET_CLASS(parent_class)->size_allocate(widget, allocation);
 
     if (priv->volumebar && GTK_WIDGET_VISIBLE(priv->volumebar)) {
         /* Allocate space for the slider */