aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/idoscalemenuitem.c237
1 files changed, 61 insertions, 176 deletions
diff --git a/src/idoscalemenuitem.c b/src/idoscalemenuitem.c
index f355b64..85caa59 100644
--- a/src/idoscalemenuitem.c
+++ b/src/idoscalemenuitem.c
@@ -23,10 +23,6 @@
#include <gtk/gtk.h>
#include "idoscalemenuitem.h"
-static void ido_scale_menu_item_size_request (GtkWidget *widget,
- GtkRequisition *requisition);
-static void ido_scale_menu_item_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation);
static GObject* ido_scale_menu_item_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_params);
@@ -42,25 +38,23 @@ static void ido_scale_menu_item_forall (GtkContainer
gboolean include_internals,
GtkCallback callback,
gpointer data);
-static void ido_scale_menu_item_construct_child (IdoScaleMenuItem *item);
static gboolean ido_scale_menu_item_button_press_event (GtkWidget *menuitem,
GdkEventButton *event);
static gboolean ido_scale_menu_item_button_release_event (GtkWidget *menuitem,
GdkEventButton *event);
static gboolean ido_scale_menu_item_motion_notify_event (GtkWidget *menuitem,
GdkEventMotion *event);
+static gboolean ido_scale_menu_item_expose (GtkWidget *widget,
+ GdkEventExpose *event);
struct _IdoScaleMenuItemPrivate {
GtkWidget *scale;
GtkAdjustment *adjustment;
+ GtkWidget *offscreen;
};
enum {
PROP_0,
- PROP_MIN,
- PROP_MAX,
- PROP_STEP,
- PROP_VALUE,
PROP_ADJUSTMENT
};
@@ -96,14 +90,12 @@ ido_scale_menu_item_class_init (IdoScaleMenuItemClass *item_class)
container_class->forall = ido_scale_menu_item_forall;
- widget_class->size_request = ido_scale_menu_item_size_request;
- widget_class->size_allocate = ido_scale_menu_item_size_allocate;
-
widget_class->button_press_event = ido_scale_menu_item_button_press_event;
widget_class->button_release_event = ido_scale_menu_item_button_release_event;
widget_class->motion_notify_event = ido_scale_menu_item_motion_notify_event;
widget_class->scroll_event = ido_scale_menu_item_scroll_event;
widget_class->state_changed = ido_scale_menu_item_state_changed;
+ widget_class->expose_event = ido_scale_menu_item_expose;
gobject_class->constructor = ido_scale_menu_item_constructor;
gobject_class->set_property = ido_scale_menu_item_set_property;
@@ -141,14 +133,7 @@ ido_scale_menu_item_set_property (GObject *object,
switch (prop_id)
{
case PROP_ADJUSTMENT:
- if (!priv->scale)
- {
- priv->adjustment = g_value_get_object (value);
- priv->scale = gtk_hscale_new (priv->adjustment);
- gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE);
- }
-
- ido_scale_menu_item_construct_child (menu_item);
+ gtk_range_set_adjustment (GTK_RANGE (priv->scale), g_value_get_object (value));
break;
@@ -180,6 +165,42 @@ ido_scale_menu_item_get_property (GObject *object,
}
}
+static gboolean
+offscreen_damage (GtkWidget *widget,
+ GdkEventExpose *event,
+ GtkWidget *menuitem)
+{
+ gtk_widget_queue_draw (menuitem);
+
+ return TRUE;
+}
+
+static gboolean
+ido_scale_menu_item_expose (GtkWidget *widget,
+ GdkEventExpose *event)
+{
+ IdoScaleMenuItemPrivate *priv = GET_PRIVATE (widget);
+
+ if (GTK_WIDGET_DRAWABLE (widget))
+ {
+ GdkPixbuf *pixbuf = gtk_offscreen_window_get_pixbuf (GTK_OFFSCREEN_WINDOW (priv->offscreen));
+
+ gdk_draw_pixbuf (widget->window,
+ widget->style->black_gc,
+ pixbuf,
+ 0, 0,
+ widget->allocation.x, widget->allocation.y,
+ gdk_pixbuf_get_width (pixbuf),
+ gdk_pixbuf_get_height (pixbuf),
+ GDK_RGB_DITHER_NORMAL,
+ 0, 0);
+
+ g_object_unref (pixbuf);
+ }
+
+ return TRUE;
+}
+
static GObject*
ido_scale_menu_item_constructor (GType type,
guint n_construct_properties,
@@ -194,10 +215,21 @@ ido_scale_menu_item_constructor (GType type,
priv = GET_PRIVATE (object);
- if (priv->scale != NULL)
- {
- ido_scale_menu_item_construct_child (IDO_SCALE_MENU_ITEM (object));
- }
+ priv->offscreen = gtk_offscreen_window_new ();
+
+ priv->scale = gtk_hscale_new_with_range (0.0, 100.0, 1.0);
+ gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE);
+ gtk_widget_set_size_request (priv->scale, 95, 21);
+ gtk_container_add (GTK_CONTAINER (priv->offscreen), priv->scale);
+ gtk_widget_show (priv->scale);
+ gtk_widget_show (priv->offscreen);
+
+ gtk_widget_queue_draw (priv->offscreen);
+
+ g_signal_connect (priv->offscreen,
+ "damage-event",
+ G_CALLBACK (offscreen_damage),
+ object);
return object;
}
@@ -220,123 +252,15 @@ ido_scale_menu_item_forall (GtkContainer *container,
(* callback) (priv->scale, data);
}
-static void
-ido_scale_menu_item_size_request (GtkWidget *widget,
- GtkRequisition *requisition)
-{
- IdoScaleMenuItem *item;
- IdoScaleMenuItemPrivate *priv;
- GtkWidget *parent;
- GtkPackDirection dir;
- gint child_width = 0;
- gint child_height = 0;
-
- parent = gtk_widget_get_parent (widget);
- item = IDO_SCALE_MENU_ITEM (widget);
- priv = GET_PRIVATE (item);
-
- if (GTK_IS_MENU_BAR (parent))
- dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
- else
- dir = GTK_PACK_DIRECTION_LTR;
-
- if (priv->scale && GTK_WIDGET_VISIBLE (priv->scale))
- {
- GtkRequisition child_requisition;
-
- gtk_widget_size_request (priv->scale,
- &child_requisition);
-
- child_width = child_requisition.width;
- child_height = child_requisition.height;
- }
-
- GTK_WIDGET_CLASS (ido_scale_menu_item_parent_class)->size_request (widget, requisition);
-
- if (dir == GTK_PACK_DIRECTION_LTR || dir == GTK_PACK_DIRECTION_RTL)
- requisition->height = MAX (requisition->height, child_height);
- else
- requisition->width = MAX (requisition->width, child_width);
-}
-
-static void
-ido_scale_menu_item_size_allocate (GtkWidget *widget,
- GtkAllocation *allocation)
-{
- IdoScaleMenuItem *item;
- IdoScaleMenuItemPrivate *priv;
- GtkWidget *parent;
- GtkPackDirection dir;
-
- item = IDO_SCALE_MENU_ITEM (widget);
- priv = GET_PRIVATE (item);
- parent = gtk_widget_get_parent (widget);
-
- if (GTK_IS_MENU_BAR (parent))
- dir = gtk_menu_bar_get_child_pack_direction (GTK_MENU_BAR (parent));
- else
- dir = GTK_PACK_DIRECTION_LTR;
-
- GTK_WIDGET_CLASS (ido_scale_menu_item_parent_class)->size_allocate (widget, allocation);
-
- if (priv->scale && GTK_WIDGET_VISIBLE (priv->scale))
- {
- GtkRequisition child_requisition;
- GtkAllocation child_allocation;
- gint x, y, offset;
-
- gtk_widget_get_child_requisition (priv->scale,
- &child_requisition);
-
- if (dir == GTK_PACK_DIRECTION_LTR || dir == GTK_PACK_DIRECTION_RTL)
- {
- offset = GTK_CONTAINER (item)->border_width + widget->style->xthickness;
-
- if ((gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR) ==
- (dir == GTK_PACK_DIRECTION_LTR))
- {
- x = offset + (GTK_MENU_ITEM (item)->toggle_size - child_requisition.width) / 2;
- }
- else
- {
- // TODO rtl
- }
- }
- else
- {
- offset = GTK_CONTAINER (item)->border_width + widget->style->ythickness;
-
- // TODO vertical
- }
-
- y = widget->allocation.height / 2 - child_requisition.height / 2;
-
- child_allocation.width = allocation->width;
- child_allocation.height = child_requisition.height;
- child_allocation.x = widget->allocation.x + MAX (x, 0);
- child_allocation.y = widget->allocation.y + MAX (y, 0);
-
- gtk_widget_size_allocate (priv->scale, &child_allocation);
- }
-}
-
static gboolean
ido_scale_menu_item_button_press_event (GtkWidget *menuitem,
GdkEventButton *event)
{
GtkWidget *scale = GET_PRIVATE (IDO_SCALE_MENU_ITEM (menuitem))->scale;
- event->x = 0;
- event->y = 0;
-
- //gtk_grab_add (scale);
- //gtk_grab_remove (menuitem->parent);
-
gtk_widget_event (scale, (GdkEvent *)event);
- //g_signal_stop_emission_by_name (menuitem->parent, "hide");
-
- return FALSE;
+ return TRUE;
}
static gboolean
@@ -344,11 +268,14 @@ ido_scale_menu_item_button_release_event (GtkWidget *menuitem,
GdkEventButton *event)
{
GtkWidget *scale = GET_PRIVATE (IDO_SCALE_MENU_ITEM (menuitem))->scale;
+ GdkWindow *tmp = event->window;
- //gtk_grab_remove (scale);
+ event->window = GTK_RANGE (scale)->event_window;
gtk_widget_event (scale, (GdkEvent *) event);
+ event->window = tmp;
+
return TRUE;
}
@@ -362,48 +289,6 @@ ido_scale_menu_item_motion_notify_event (GtkWidget *menuitem,
return TRUE;
}
-static void
-ido_scale_menu_item_construct_child (IdoScaleMenuItem *item)
-{
- IdoScaleMenuItemPrivate *priv = GET_PRIVATE (item);
- GtkWidget *scale = NULL;
-
- if (priv->scale)
- {
- scale = g_object_ref (priv->scale);
- if (scale->parent)
- {
- gtk_container_remove (GTK_CONTAINER (scale->parent), scale);
- }
- }
-
- priv->scale = NULL;
-
- priv->scale = gtk_hscale_new (priv->adjustment);
- gtk_widget_set_can_focus (priv->scale, TRUE);
- gtk_scale_set_draw_value (GTK_SCALE (priv->scale), FALSE);
-
- if (GTK_BIN (item)->child)
- gtk_container_remove (GTK_CONTAINER (item),
- GTK_BIN (item)->child);
-
- if (scale)
- {
- priv->scale = scale;
- g_object_set (priv->scale,
- "visible", TRUE,
- "no-show-all", TRUE,
- NULL);
-
- gtk_container_add (GTK_CONTAINER (item), scale);
- gtk_widget_show_all (scale);
-
- g_object_unref (scale);
-
- return;
- }
-}
-
/**
* ido_scale_menu_item_new: