summaryrefslogtreecommitdiffstats
path: root/src/widgets/ruler.cpp
diff options
context:
space:
mode:
authorAlex Valavanis <valavanisalex@gmail.com>2012-12-26 12:53:09 +0000
committerAlex Valavanis <valavanisalex@googlemail.com>2012-12-26 12:53:09 +0000
commit81839e6ebd1007f4674e65e5908ec4fd46fb64a6 (patch)
treec4aca2f1cd215b124ddbda20cc93c015c4eff4f8 /src/widgets/ruler.cpp
parentruler: (GIMP merge) Allow label size to be specified as a style property (diff)
downloadinkscape-81839e6ebd1007f4674e65e5908ec4fd46fb64a6.tar.gz
inkscape-81839e6ebd1007f4674e65e5908ec4fd46fb64a6.zip
ruler: (GIMP merge) Add track_widget API and fix GTK+ 3 build failure in color slider
(bzr r11988)
Diffstat (limited to 'src/widgets/ruler.cpp')
-rw-r--r--src/widgets/ruler.cpp164
1 files changed, 164 insertions, 0 deletions
diff --git a/src/widgets/ruler.cpp b/src/widgets/ruler.cpp
index 851af640a..31ef28c61 100644
--- a/src/widgets/ruler.cpp
+++ b/src/widgets/ruler.cpp
@@ -78,6 +78,8 @@ typedef struct
gint xsrc;
gint ysrc;
+
+ GList *track_widgets;
} SPRulerPrivate;
#define SP_RULER_GET_PRIVATE(ruler) \
@@ -99,6 +101,7 @@ static SPRulerMetric const sp_ruler_metrics[] = {
};
+static void sp_ruler_dispose (GObject *object);
static void sp_ruler_set_property (GObject *object,
guint prop_id,
const GValue *value,
@@ -158,6 +161,7 @@ sp_ruler_class_init (SPRulerClass *klass)
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ object_class->dispose = sp_ruler_dispose;
object_class->set_property = sp_ruler_set_property;
object_class->get_property = sp_ruler_get_property;
@@ -273,6 +277,18 @@ sp_ruler_init (SPRuler *ruler)
sp_ruler_set_metric(ruler, SP_PX);
}
+static void
+sp_ruler_dispose (GObject *object)
+{
+ SPRuler *ruler = SP_RULER (object);
+ SPRulerPrivate *priv = SP_RULER_GET_PRIVATE (ruler);
+
+ while (priv->track_widgets)
+ sp_ruler_remove_track_widget (ruler, GTK_WIDGET(priv->track_widgets->data));
+
+ G_OBJECT_CLASS (parent_class)->dispose (object);
+}
+
/**
* sp_ruler_set_range:
@@ -912,6 +928,154 @@ sp_ruler_update_position (SPRuler *ruler,
}
}
+/* Returns TRUE if a translation should be done */
+static gboolean
+gtk_widget_get_translation_to_window (GtkWidget *widget,
+ GdkWindow *window,
+ int *x,
+ int *y)
+{
+ GdkWindow *w, *widget_window;
+
+ if (! gtk_widget_get_has_window (widget))
+ {
+ GtkAllocation allocation;
+
+ gtk_widget_get_allocation (widget, &allocation);
+
+ *x = -allocation.x;
+ *y = -allocation.y;
+ }
+ else
+ {
+ *x = 0;
+ *y = 0;
+ }
+
+ widget_window = gtk_widget_get_window (widget);
+
+ for (w = window;
+ w && w != widget_window;
+ w = gdk_window_get_effective_parent (w))
+ {
+ gdouble px, py;
+
+ gdk_window_coords_to_parent (w, *x, *y, &px, &py);
+
+ *x += px;
+ *y += px;
+ }
+
+ if (w == NULL)
+ {
+ *x = 0;
+ *y = 0;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static void
+sp_ruler_event_to_widget_coords (GtkWidget *widget,
+ GdkWindow *window,
+ gdouble event_x,
+ gdouble event_y,
+ gint *widget_x,
+ gint *widget_y)
+{
+ gint tx, ty;
+
+ if (gtk_widget_get_translation_to_window (widget, window, &tx, &ty))
+ {
+ event_x += tx;
+ event_y += ty;
+ }
+
+ *widget_x = event_x;
+ *widget_y = event_y;
+}
+
+static gboolean
+sp_ruler_track_widget_motion_notify (GtkWidget *widget,
+ GdkEventMotion *mevent,
+ SPRuler *ruler)
+{
+ gint widget_x;
+ gint widget_y;
+ gint ruler_x;
+ gint ruler_y;
+
+ widget = gtk_get_event_widget (reinterpret_cast<GdkEvent *>(mevent));
+
+ sp_ruler_event_to_widget_coords (widget, mevent->window,
+ mevent->x, mevent->y,
+ &widget_x, &widget_y);
+
+ if (gtk_widget_translate_coordinates (widget, GTK_WIDGET (ruler),
+ widget_x, widget_y,
+ &ruler_x, &ruler_y))
+ {
+ sp_ruler_update_position (ruler, ruler_x, ruler_y);
+ }
+
+ return FALSE;
+}
+
+void
+sp_ruler_add_track_widget (SPRuler *ruler,
+ GtkWidget *widget)
+{
+ SPRulerPrivate *priv;
+
+ g_return_if_fail (SP_IS_RULER (ruler));
+ g_return_if_fail (GTK_IS_WIDGET (ruler));
+
+ priv = SP_RULER_GET_PRIVATE (ruler);
+
+ g_return_if_fail (g_list_find (priv->track_widgets, widget) == NULL);
+
+ priv->track_widgets = g_list_prepend (priv->track_widgets, widget);
+
+ g_signal_connect (widget, "motion-notify-event",
+ G_CALLBACK (sp_ruler_track_widget_motion_notify),
+ ruler);
+ g_signal_connect (widget, "destroy",
+ G_CALLBACK (sp_ruler_remove_track_widget),
+ ruler);
+}
+
+/**
+ * sp_ruler_remove_track_widget:
+ * @ruler: an #SPRuler
+ * @widget: the track widget to remove
+ *
+ * Removes a previously added track widget from the ruler. See
+ * sp_ruler_add_track_widget().
+ */
+void
+sp_ruler_remove_track_widget (SPRuler *ruler,
+ GtkWidget *widget)
+{
+ SPRulerPrivate *priv;
+
+ g_return_if_fail (SP_IS_RULER (ruler));
+ g_return_if_fail (GTK_IS_WIDGET (ruler));
+
+ priv = SP_RULER_GET_PRIVATE (ruler);
+
+ g_return_if_fail (g_list_find (priv->track_widgets, widget) != NULL);
+
+ priv->track_widgets = g_list_remove (priv->track_widgets, widget);
+
+ g_signal_handlers_disconnect_by_func (widget,
+ (gpointer) G_CALLBACK (sp_ruler_track_widget_motion_notify),
+ ruler);
+ g_signal_handlers_disconnect_by_func (widget,
+ (gpointer) G_CALLBACK (sp_ruler_remove_track_widget),
+ ruler);
+}
+
/**
* sp_ruler_set_position:
* @ruler: a #SPRuler