[gnome-system-tools] Port EMap widget to GtkScrollable
- From: Milan Bouchet-Valat <milanbv src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-system-tools] Port EMap widget to GtkScrollable
- Date: Sun, 12 Dec 2010 17:45:54 +0000 (UTC)
commit f4a3531461587c64406e639e9b6b0ce94ac9021c
Author: Milan Bouchet-Valat <nalimilan club fr>
Date: Sat Dec 11 19:38:30 2010 +0100
Port EMap widget to GtkScrollable
Needed to build with GTK3.
src/time/e-map/e-map.c | 409 ++++++++++++++++++++++++++++++++----------------
1 files changed, 273 insertions(+), 136 deletions(-)
---
diff --git a/src/time/e-map/e-map.c b/src/time/e-map/e-map.c
index 8f3ca29..5366ef5 100644
--- a/src/time/e-map/e-map.c
+++ b/src/time/e-map/e-map.c
@@ -41,8 +41,8 @@
/* */
-#define E_MAP_GET_WIDTH(map) gtk_adjustment_get_upper((map)->priv->hadj)
-#define E_MAP_GET_HEIGHT(map) gtk_adjustment_get_upper((map)->priv->vadj)
+#define E_MAP_GET_WIDTH(map) gtk_adjustment_get_upper((map)->priv->hadjustment)
+#define E_MAP_GET_HEIGHT(map) gtk_adjustment_get_upper((map)->priv->vadjustment)
/* Zoom state - keeps track of animation hacks */
@@ -78,8 +78,13 @@ struct _EMapPrivate {
gboolean frozen, smooth_zoom;
/* Adjustments for scrolling */
- GtkAdjustment *hadj;
- GtkAdjustment *vadj;
+ GtkAdjustment *hadjustment;
+ GtkAdjustment *vadjustment;
+
+ /* GtkScrollablePolicy needs to be checked when
+ * driving the scrollable adjustment values */
+ guint hscroll_policy : 1;
+ guint vscroll_policy : 1;
/* Current scrolling offsets */
gint xofs, yofs;
@@ -98,19 +103,49 @@ struct _EMapPrivate {
guint tween_id;
};
+/* Properties */
+
+enum {
+ PROP_0,
+
+ /* For scrollable interface */
+ PROP_HADJUSTMENT,
+ PROP_VADJUSTMENT,
+ PROP_HSCROLL_POLICY,
+ PROP_VSCROLL_POLICY
+};
+
/* Internal prototypes */
static void e_map_finalize (GObject *object);
+static void e_map_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static void e_map_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec);
static void e_map_realize (GtkWidget *widget);
static void e_map_unrealize (GtkWidget *widget);
-static void e_map_size_request (GtkWidget *widget, GtkRequisition *requisition);
+static void e_map_get_preferred_height (GtkWidget *widget, gint *minimum_height, gint *natural_height);
+static void e_map_get_preferred_width (GtkWidget *widget, gint *minimum_width, gint *natural_width);
static void e_map_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
static gint e_map_button_press (GtkWidget *widget, GdkEventButton *event);
static gint e_map_button_release (GtkWidget *widget, GdkEventButton *event);
static gint e_map_motion (GtkWidget *widget, GdkEventMotion *event);
static gint e_map_expose (GtkWidget *widget, GdkEventExpose *event);
static gint e_map_key_press (GtkWidget *widget, GdkEventKey *event);
-static void e_map_set_scroll_adjustments (GtkWidget *widget, GtkAdjustment *hadj, GtkAdjustment *vadj);
+
+/* GtkScrollable implementation */
+static void e_map_set_hadjustment_values (EMap *map);
+static void e_map_set_vadjustment_values (EMap *map);
+static void e_map_set_hadjustment (EMap *map,
+ GtkAdjustment *adjustment);
+static void e_map_set_vadjustment (EMap *map,
+ GtkAdjustment *adjustment);
+static void e_map_adjustment_changed (GtkAdjustment *adjustment,
+ EMap *map);
static void e_map_get_current_location (EMap *map, double *longitude, double *latitude);
static void e_map_world_to_render_surface (EMap *map, gdouble world_longitude, gdouble world_latitude,
@@ -120,7 +155,6 @@ static void set_scroll_area (EMap *view, gint width, gint height);
static void center_at (EMap *map, double longitude, double latitude);
static void scroll_to (EMap *view, gint x, gint y);
static gint load_map_background (EMap *view, gchar *name);
-static void adjustment_changed_cb (GtkAdjustment *adj, gpointer data);
static void update_and_paint (EMap *map);
static void update_render_point (EMap *map, EMapPoint *point);
static void repaint_point (EMap *map, EMapPoint *point);
@@ -230,10 +264,11 @@ e_map_tween_new (EMap *view, guint msecs, double longitude_offset, double latitu
gtk_widget_queue_draw (GTK_WIDGET (view));
}
-G_DEFINE_TYPE (
- EMap,
- e_map,
- GTK_TYPE_WIDGET)
+G_DEFINE_TYPE_WITH_CODE (
+ EMap,
+ e_map,
+ GTK_TYPE_WIDGET,
+ G_IMPLEMENT_INTERFACE (GTK_TYPE_SCROLLABLE, NULL))
static void
e_map_tween_new_from (EMap *view, guint msecs, double longitude, double latitude, double zoom)
@@ -265,17 +300,14 @@ e_map_class_init (EMapClass *class)
widget_class = (GtkWidgetClass *) class;
gobject_class->finalize = e_map_finalize;
+ gobject_class->set_property = e_map_set_property;
+ gobject_class->get_property = e_map_get_property;
- class->set_scroll_adjustments = e_map_set_scroll_adjustments;
- widget_class->set_scroll_adjustments_signal = g_signal_new ("set_scroll_adjustments",
- G_OBJECT_CLASS_TYPE (gobject_class),
- G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
- G_STRUCT_OFFSET (EMapClass, set_scroll_adjustments),
- NULL, NULL,
- g_cclosure_user_marshal_VOID__OBJECT_OBJECT,
- G_TYPE_NONE, 2,
- GTK_TYPE_ADJUSTMENT,
- GTK_TYPE_ADJUSTMENT);
+ /* Scrollable interface properties */
+ g_object_class_override_property (gobject_class, PROP_HADJUSTMENT, "hadjustment");
+ g_object_class_override_property (gobject_class, PROP_VADJUSTMENT, "vadjustment");
+ g_object_class_override_property (gobject_class, PROP_HSCROLL_POLICY, "hscroll-policy");
+ g_object_class_override_property (gobject_class, PROP_VSCROLL_POLICY, "vscroll-policy");
widget_class->realize = e_map_realize;
widget_class->unrealize = e_map_unrealize;
@@ -331,15 +363,6 @@ e_map_finalize (GObject *object)
e_map_tween_destroy (view, priv->tweens->data);
e_map_stop_tweening (view);
- g_signal_handlers_disconnect_by_func (priv->hadj, adjustment_changed_cb, view);
- g_signal_handlers_disconnect_by_func (priv->vadj, adjustment_changed_cb, view);
-
- g_object_unref ((priv->hadj));
- priv->hadj = NULL;
-
- g_object_unref ((priv->vadj));
- priv->vadj = NULL;
-
if (priv->map_pixbuf)
{
g_object_unref (priv->map_pixbuf);
@@ -355,6 +378,70 @@ e_map_finalize (GObject *object)
G_OBJECT_CLASS (e_map_parent_class)->finalize (object);
}
+static void
+e_map_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ EMap *map;
+
+ map = E_MAP (object);
+
+ switch (prop_id)
+ {
+ case PROP_HADJUSTMENT:
+ e_map_set_hadjustment (map, g_value_get_object (value));
+ break;
+ case PROP_VADJUSTMENT:
+ e_map_set_vadjustment (map, g_value_get_object (value));
+ break;
+ case PROP_HSCROLL_POLICY:
+ map->priv->hscroll_policy = g_value_get_enum (value);
+ gtk_widget_queue_resize (GTK_WIDGET (map));
+ break;
+ case PROP_VSCROLL_POLICY:
+ map->priv->vscroll_policy = g_value_get_enum (value);
+ gtk_widget_queue_resize (GTK_WIDGET (map));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+e_map_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ EMap *map;
+
+ map = E_MAP (object);
+
+ switch (prop_id)
+ {
+ case PROP_HADJUSTMENT:
+ g_value_set_object (value, map->priv->hadjustment);
+ break;
+ case PROP_VADJUSTMENT:
+ g_value_set_object (value, map->priv->vadjustment);
+ break;
+ case PROP_HSCROLL_POLICY:
+ g_value_set_enum (value, map->priv->hscroll_policy);
+ break;
+ case PROP_VSCROLL_POLICY:
+ g_value_set_enum (value, map->priv->vscroll_policy);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
/* Realize handler for the map view */
static void
@@ -594,70 +681,6 @@ e_map_expose (GtkWidget *widget, GdkEventExpose *event)
return FALSE;
}
-/* Set_scroll_adjustments handler for the map view */
-
-static void
-e_map_set_scroll_adjustments (GtkWidget *widget, GtkAdjustment *hadj, GtkAdjustment *vadj)
-{
- EMap *view;
- EMapPrivate *priv;
- gboolean need_adjust;
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (E_IS_MAP (widget));
-
- view = E_MAP (widget);
- priv = view->priv;
-
- if (hadj) g_return_if_fail (GTK_IS_ADJUSTMENT (hadj));
- else hadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
-
- if (vadj) g_return_if_fail (GTK_IS_ADJUSTMENT (vadj));
- else vadj = GTK_ADJUSTMENT (gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0));
-
- if (priv->hadj && priv->hadj != hadj)
- {
- g_signal_handlers_disconnect_by_func (priv->hadj,
- adjustment_changed_cb,
- view);
- g_object_unref (priv->hadj);
- }
-
- if (priv->vadj && priv->vadj != vadj)
- {
- g_signal_handlers_disconnect_by_func (priv->vadj,
- adjustment_changed_cb,
- view);
- g_object_unref (priv->vadj);
- }
-
- need_adjust = FALSE;
-
- if (priv->hadj != hadj)
- {
- priv->hadj = hadj;
- g_object_ref_sink (priv->hadj);
-
- g_signal_connect (priv->hadj, "value_changed",
- G_CALLBACK (adjustment_changed_cb), view);
-
- need_adjust = TRUE;
- }
-
- if (priv->vadj != vadj)
- {
- priv->vadj = vadj;
- g_object_ref_sink (priv->vadj);
-
- g_signal_connect (priv->vadj, "value_changed",
- G_CALLBACK (adjustment_changed_cb), view);
-
- need_adjust = TRUE;
- }
-
- if (need_adjust) adjustment_changed_cb (NULL, view);
-}
-
/* Key press handler for the map view */
static gint
@@ -707,18 +730,18 @@ e_map_key_press (GtkWidget *widget, GdkEventKey *event)
gint upper;
gint x, y;
- page_size = gtk_adjustment_get_page_size (priv->hadj);
- upper = gtk_adjustment_get_upper (priv->hadj);
+ page_size = gtk_adjustment_get_page_size (priv->hadjustment);
+ upper = gtk_adjustment_get_upper (priv->hadjustment);
x = CLAMP (priv->xofs + xofs, 0, upper - page_size);
- page_size = gtk_adjustment_get_page_size (priv->vadj);
- upper = gtk_adjustment_get_upper (priv->vadj);
+ page_size = gtk_adjustment_get_page_size (priv->vadjustment);
+ upper = gtk_adjustment_get_upper (priv->vadjustment);
y = CLAMP (priv->yofs + yofs, 0, upper - page_size);
scroll_to (view, x, y);
- gtk_adjustment_set_value (priv->hadj, x);
- gtk_adjustment_set_value (priv->vadj, y);
+ gtk_adjustment_set_value (priv->hadjustment, x);
+ gtk_adjustment_set_value (priv->vadjustment, y);
}
return TRUE;
@@ -1072,6 +1095,42 @@ load_map_background (EMap *view, gchar *name)
}
static void
+set_scroll_area (EMap *view, int width, int height)
+{
+ EMapPrivate *priv;
+ GtkAllocation allocation;
+
+ priv = view->priv;
+
+ if (!gtk_widget_get_realized (GTK_WIDGET (view))) return;
+ if (!priv->hadjustment || !priv->vadjustment) return;
+
+ g_object_freeze_notify (G_OBJECT (priv->hadjustment));
+ g_object_freeze_notify (G_OBJECT (priv->vadjustment));
+
+ gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
+
+ priv->xofs = CLAMP (priv->xofs, 0, width - allocation.width);
+ priv->yofs = CLAMP (priv->yofs, 0, height - allocation.height);
+
+ gtk_adjustment_configure (priv->hadjustment,
+ priv->xofs,
+ 0, width,
+ SCROLL_STEP_SIZE,
+ allocation.width / 2,
+ allocation.width);
+ gtk_adjustment_configure (priv->vadjustment,
+ priv->yofs,
+ 0, height,
+ SCROLL_STEP_SIZE,
+ allocation.height / 2,
+ allocation.height);
+
+ g_object_thaw_notify (G_OBJECT (priv->hadjustment));
+ g_object_thaw_notify (G_OBJECT (priv->vadjustment));
+}
+
+static void
update_render_surface (EMap *map,
gboolean render_overlays)
{
@@ -1225,8 +1284,8 @@ center_at (EMap *map, double longitude, double latitude)
x = CLAMP (x - (allocation.width / 2), 0, pb_width - allocation.width);
y = CLAMP (y - (allocation.height / 2), 0, pb_height - allocation.height);
- gtk_adjustment_set_value (priv->hadj, x);
- gtk_adjustment_set_value (priv->vadj, y);
+ gtk_adjustment_set_value (priv->hadjustment, x);
+ gtk_adjustment_set_value (priv->vadjustment, y);
gtk_widget_queue_draw (GTK_WIDGET (map));
}
@@ -1267,55 +1326,133 @@ e_map_get_current_location (EMap *map, double *longitude, double *latitude)
longitude, latitude);
}
-/* Callback used when an adjustment is changed */
+/* GtkScrollable implementation */
static void
-adjustment_changed_cb (GtkAdjustment *adj, gpointer data)
+e_map_set_hadjustment_values (EMap *map)
{
- EMap *view;
- gint hadj_value;
- gint vadj_value;
+ GtkAllocation allocation;
+ EMapPrivate *priv = map->priv;
+ GtkAdjustment *adj = priv->hadjustment;
+ gdouble old_value;
+ gdouble new_value;
+ gdouble new_upper;
+
+ gtk_widget_get_allocation (GTK_WIDGET (map), &allocation);
+
+ old_value = gtk_adjustment_get_value (adj);
+ new_upper = MAX (allocation.width, gdk_pixbuf_get_width (priv->map_pixbuf));
+
+ g_object_set (adj,
+ "lower", 0.0,
+ "upper", new_upper,
+ "page-size", (gdouble)allocation.height,
+ "step-increment", allocation.height * 0.1,
+ "page-increment", allocation.height * 0.9,
+ NULL);
+
+ new_value = CLAMP (old_value, 0, new_upper - allocation.width);
+ if (new_value != old_value)
+ gtk_adjustment_set_value (adj, new_value);
+}
- view = E_MAP (data);
+static void
+e_map_set_vadjustment_values (EMap *map)
+{
+ GtkAllocation allocation;
+ EMapPrivate *priv = map->priv;
+ GtkAdjustment *adj = priv->vadjustment;
+ gdouble old_value;
+ gdouble new_value;
+ gdouble new_upper;
+
+ gtk_widget_get_allocation (GTK_WIDGET (map), &allocation);
+
+ old_value = gtk_adjustment_get_value (adj);
+ new_upper = MAX (allocation.height, gdk_pixbuf_get_height (priv->map_pixbuf));
+
+ g_object_set (adj,
+ "lower", 0.0,
+ "upper", new_upper,
+ "page-size", (gdouble)allocation.height,
+ "step-increment", allocation.height * 0.1,
+ "page-increment", allocation.height * 0.9,
+ NULL);
+
+ new_value = CLAMP (old_value, 0, new_upper - allocation.height);
+ if (new_value != old_value)
+ gtk_adjustment_set_value (adj, new_value);
+}
- hadj_value = gtk_adjustment_get_value (view->priv->hadj);
- vadj_value = gtk_adjustment_get_value (view->priv->vadj);
+static void
+e_map_set_hadjustment (EMap *map, GtkAdjustment *adjustment)
+{
+ EMapPrivate *priv = map->priv;
- scroll_to (view, hadj_value, vadj_value);
+ if (adjustment && priv->hadjustment == adjustment)
+ return;
+
+ if (priv->hadjustment != NULL)
+ {
+ g_signal_handlers_disconnect_matched (priv->hadjustment,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, map);
+ g_object_unref (priv->hadjustment);
+ }
+
+ if (!adjustment)
+ adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
+
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (e_map_adjustment_changed), map);
+ priv->hadjustment = g_object_ref_sink (adjustment);
+ e_map_set_hadjustment_values (map);
+
+ g_object_notify (G_OBJECT (map), "hadjustment");
}
static void
-set_scroll_area (EMap *view, gint width, gint height)
+e_map_set_vadjustment (EMap *map, GtkAdjustment *adjustment)
{
- EMapPrivate *priv;
- GtkAllocation allocation;
+ EMapPrivate *priv = map->priv;
- priv = view->priv;
+ if (adjustment && priv->vadjustment == adjustment)
+ return;
- if (!gtk_widget_get_realized (GTK_WIDGET (view))) return;
- if (!priv->hadj || !priv->vadj) return;
+ if (priv->vadjustment != NULL)
+ {
+ g_signal_handlers_disconnect_matched (priv->vadjustment,
+ G_SIGNAL_MATCH_DATA,
+ 0, 0, NULL, NULL, map);
+ g_object_unref (priv->vadjustment);
+ }
- g_object_freeze_notify (G_OBJECT (priv->hadj));
- g_object_freeze_notify (G_OBJECT (priv->vadj));
+ if (!adjustment)
+ adjustment = gtk_adjustment_new (0.0, 0.0, 0.0,
+ 0.0, 0.0, 0.0);
- gtk_widget_get_allocation (GTK_WIDGET (view), &allocation);
+ g_signal_connect (adjustment, "value-changed",
+ G_CALLBACK (e_map_adjustment_changed), map);
+ priv->vadjustment = g_object_ref_sink (adjustment);
+ e_map_set_vadjustment_values (map);
- priv->xofs = CLAMP (priv->xofs, 0, width - allocation.width);
- priv->yofs = CLAMP (priv->yofs, 0, height - allocation.height);
+ g_object_notify (G_OBJECT (map), "vadjustment");
+}
- gtk_adjustment_configure (priv->hadj,
- priv->xofs,
- 0, width,
- SCROLL_STEP_SIZE,
- allocation.width / 2,
- allocation.width);
- gtk_adjustment_configure (priv->vadj,
- priv->yofs,
- 0, height,
- SCROLL_STEP_SIZE,
- allocation.height / 2,
- allocation.height);
+static void
+e_map_adjustment_changed (GtkAdjustment *adjustment, EMap *map)
+{
+ EMapPrivate *priv = map->priv;
+
+ if (gtk_widget_get_realized (GTK_WIDGET (map)))
+ {
+ gint hadj_value;
+ gint vadj_value;
+
+ hadj_value = gtk_adjustment_get_value (priv->hadjustment);
+ vadj_value = gtk_adjustment_get_value (priv->vadjustment);
- g_object_thaw_notify (G_OBJECT (priv->hadj));
- g_object_thaw_notify (G_OBJECT (priv->vadj));
+ scroll_to (map, hadj_value, vadj_value);
+ }
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]