[gtk+] GtkMagnifier: Add a resizing mode
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+] GtkMagnifier: Add a resizing mode
- Date: Sun, 21 Dec 2014 00:24:59 +0000 (UTC)
commit 10d0ca0a3d5536a5c9926998e54775a8b0fd8b2c
Author: Matthias Clasen <mclasen redhat com>
Date: Sat Dec 20 19:16:46 2014 -0500
GtkMagnifier: Add a resizing mode
In addition to the fixed-size mode that is used by the text view,
add a mode in which the magnifier requests enough size to render
the entire inspected widget at the current magnification. In this
mode, the magnifier will update its size when the size of the
inspected widget changes. Also, make the magnifier redraw on its
own whenever the inspected widget draws.
gtk/gtkmagnifier.c | 194 ++++++++++++++++++++++++++++++++++++++++++++-
gtk/gtkmagnifierprivate.h | 4 +
2 files changed, 197 insertions(+), 1 deletions(-)
---
diff --git a/gtk/gtkmagnifier.c b/gtk/gtkmagnifier.c
index 0af11b7..04f15bc 100644
--- a/gtk/gtkmagnifier.c
+++ b/gtk/gtkmagnifier.c
@@ -22,6 +22,7 @@
enum {
PROP_INSPECTED = 1,
+ PROP_RESIZE,
PROP_MAGNIFICATION
};
@@ -33,6 +34,9 @@ struct _GtkMagnifierPrivate
gdouble magnification;
gint x;
gint y;
+ gboolean resize;
+ gulong draw_handler;
+ gulong resize_handler;
};
G_DEFINE_TYPE_WITH_PRIVATE (GtkMagnifier, _gtk_magnifier,
@@ -54,6 +58,10 @@ _gtk_magnifier_set_property (GObject *object,
_gtk_magnifier_set_magnification (GTK_MAGNIFIER (object),
g_value_get_double (value));
break;
+ case PROP_RESIZE:
+ _gtk_magnifier_set_resize (GTK_MAGNIFIER (object),
+ g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
}
@@ -79,6 +87,9 @@ _gtk_magnifier_get_property (GObject *object,
case PROP_MAGNIFICATION:
g_value_set_double (value, priv->magnification);
break;
+ case PROP_RESIZE:
+ g_value_set_boolean (value, priv->resize);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, param_id, pspec);
}
@@ -96,12 +107,17 @@ _gtk_magnifier_draw (GtkWidget *widget,
magnifier = GTK_MAGNIFIER (widget);
priv = _gtk_magnifier_get_instance_private (magnifier);
+ if (priv->inspected == NULL)
+ return FALSE;
+
if (!gtk_widget_is_visible (priv->inspected))
return FALSE;
gtk_widget_get_allocation (widget, &allocation);
gtk_widget_get_allocation (priv->inspected, &inspected_alloc);
- cairo_translate (cr, allocation.width / 2, allocation.height / 2);
+
+ if (!priv->resize)
+ cairo_translate (cr, allocation.width / 2, allocation.height / 2);
x = CLAMP (priv->x, 0, inspected_alloc.width);
y = CLAMP (priv->y, 0, inspected_alloc.height);
@@ -109,13 +125,134 @@ _gtk_magnifier_draw (GtkWidget *widget,
cairo_save (cr);
cairo_scale (cr, priv->magnification, priv->magnification);
cairo_translate (cr, -x, -y);
+ g_signal_handler_block (priv->inspected, priv->draw_handler);
gtk_widget_draw (priv->inspected, cr);
+ g_signal_handler_unblock (priv->inspected, priv->draw_handler);
cairo_restore (cr);
return TRUE;
}
static void
+gtk_magnifier_get_preferred_width (GtkWidget *widget,
+ gint *minimum_width,
+ gint *natural_width)
+{
+ GtkMagnifier *magnifier;
+ GtkMagnifierPrivate *priv;
+ gint width;
+
+ magnifier = GTK_MAGNIFIER (widget);
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->resize && priv->inspected)
+ width = priv->magnification * gtk_widget_get_allocated_width (priv->inspected);
+ else
+ width = 0;
+
+ *minimum_width = width;
+ *natural_width = width;
+}
+
+static void
+gtk_magnifier_get_preferred_height (GtkWidget *widget,
+ gint *minimum_height,
+ gint *natural_height)
+{
+ GtkMagnifier *magnifier;
+ GtkMagnifierPrivate *priv;
+ gint height;
+
+ magnifier = GTK_MAGNIFIER (widget);
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->resize && priv->inspected)
+ height = priv->magnification * gtk_widget_get_allocated_height (priv->inspected);
+ else
+ height = 0;
+
+ *minimum_height = height;
+ *natural_height = height;
+}
+
+static void
+resize_handler (GtkWidget *widget,
+ GtkAllocation *alloc,
+ GtkWidget *magnifier)
+{
+ gtk_widget_queue_resize (magnifier);
+}
+
+static void
+connect_resize_handler (GtkMagnifier *magnifier)
+{
+ GtkMagnifierPrivate *priv;
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->inspected && priv->resize)
+ priv->resize_handler = g_signal_connect (priv->inspected, "size-allocate",
+ G_CALLBACK (resize_handler), magnifier);
+}
+
+static void
+disconnect_resize_handler (GtkMagnifier *magnifier)
+{
+ GtkMagnifierPrivate *priv;
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->resize_handler)
+ {
+ g_signal_handler_disconnect (priv->inspected, priv->resize_handler);
+ priv->resize_handler = 0;
+ }
+}
+
+static gboolean
+draw_handler (GtkWidget *widget,
+ cairo_t *cr,
+ GtkWidget *magnifier)
+{
+ gtk_widget_queue_draw (magnifier);
+ return FALSE;
+}
+
+static void
+connect_draw_handler (GtkMagnifier *magnifier)
+{
+ GtkMagnifierPrivate *priv;
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->inspected)
+ priv->draw_handler = g_signal_connect (priv->inspected, "draw",
+ G_CALLBACK (draw_handler), magnifier);
+}
+
+static void
+disconnect_draw_handler (GtkMagnifier *magnifier)
+{
+ GtkMagnifierPrivate *priv;
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->draw_handler)
+ {
+ g_signal_handler_disconnect (priv->inspected, priv->draw_handler);
+ priv->draw_handler = 0;
+ }
+}
+
+static void
+_gtk_magnifier_destroy (GtkWidget *widget)
+{
+ _gtk_magnifier_set_inspected (GTK_MAGNIFIER (widget), NULL);
+
+ GTK_WIDGET_CLASS (_gtk_magnifier_parent_class)->destroy (widget);
+}
+
+static void
_gtk_magnifier_class_init (GtkMagnifierClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
@@ -124,7 +261,10 @@ _gtk_magnifier_class_init (GtkMagnifierClass *klass)
object_class->set_property = _gtk_magnifier_set_property;
object_class->get_property = _gtk_magnifier_get_property;
+ widget_class->destroy = _gtk_magnifier_destroy;
widget_class->draw = _gtk_magnifier_draw;
+ widget_class->get_preferred_width = gtk_magnifier_get_preferred_width;
+ widget_class->get_preferred_height = gtk_magnifier_get_preferred_height;
g_object_class_install_property (object_class,
PROP_INSPECTED,
@@ -140,6 +280,13 @@ _gtk_magnifier_class_init (GtkMagnifierClass *klass)
P_("magnification"),
1, G_MAXDOUBLE, 1,
G_PARAM_READWRITE));
+ g_object_class_install_property (object_class,
+ PROP_RESIZE,
+ g_param_spec_boolean ("resize",
+ P_("resize"),
+ P_("resize"),
+ FALSE,
+ G_PARAM_READWRITE));
}
static void
@@ -156,6 +303,7 @@ _gtk_magnifier_init (GtkMagnifier *magnifier)
gtk_widget_set_has_window (widget, FALSE);
priv->magnification = 1;
+ priv->resize = FALSE;
}
GtkWidget *
@@ -193,7 +341,14 @@ _gtk_magnifier_set_inspected (GtkMagnifier *magnifier,
if (priv->inspected == inspected)
return;
+ disconnect_draw_handler (magnifier);
+ disconnect_resize_handler (magnifier);
+
priv->inspected = inspected;
+
+ connect_draw_handler (magnifier);
+ connect_resize_handler (magnifier);
+
g_object_notify (G_OBJECT (magnifier), "inspected");
}
@@ -252,6 +407,9 @@ _gtk_magnifier_set_magnification (GtkMagnifier *magnifier,
priv->magnification = magnification;
g_object_notify (G_OBJECT (magnifier), "magnification");
+ if (priv->resize)
+ gtk_widget_queue_resize (GTK_WIDGET (magnifier));
+
if (gtk_widget_is_visible (GTK_WIDGET (magnifier)))
gtk_widget_queue_draw (GTK_WIDGET (magnifier));
}
@@ -267,3 +425,37 @@ _gtk_magnifier_get_magnification (GtkMagnifier *magnifier)
return priv->magnification;
}
+
+void
+_gtk_magnifier_set_resize (GtkMagnifier *magnifier,
+ gboolean resize)
+{
+ GtkMagnifierPrivate *priv;
+
+ g_return_if_fail (GTK_IS_MAGNIFIER (magnifier));
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ if (priv->resize == resize)
+ return;
+
+ priv->resize = resize;
+
+ gtk_widget_queue_resize (GTK_WIDGET (magnifier));
+ if (resize)
+ connect_resize_handler (magnifier);
+ else
+ disconnect_resize_handler (magnifier);
+}
+
+gboolean
+_gtk_magnifier_get_resize (GtkMagnifier *magnifier)
+{
+ GtkMagnifierPrivate *priv;
+
+ g_return_val_if_fail (GTK_IS_MAGNIFIER (magnifier), FALSE);
+
+ priv = _gtk_magnifier_get_instance_private (magnifier);
+
+ return priv->resize;
+}
diff --git a/gtk/gtkmagnifierprivate.h b/gtk/gtkmagnifierprivate.h
index 5e91690..84b79e1 100644
--- a/gtk/gtkmagnifierprivate.h
+++ b/gtk/gtkmagnifierprivate.h
@@ -59,6 +59,10 @@ void _gtk_magnifier_set_magnification (GtkMagnifier *magnifier,
gdouble magnification);
gdouble _gtk_magnifier_get_magnification (GtkMagnifier *magnifier);
+void _gtk_magnifier_set_resize (GtkMagnifier *magnifier,
+ gboolean resize);
+gboolean _gtk_magnifier_get_resize (GtkMagnifier *magnifier);
+
G_END_DECLS
#endif /* __GTK_MAGNIFIER_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]