[libchamplain: 18/45] Add swappable user layer clones.
- From: Jiří Techet <jiritechet src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libchamplain: 18/45] Add swappable user layer clones.
- Date: Sun, 14 Aug 2016 12:29:49 +0000 (UTC)
commit b38e4a89afa5eb8de8bccf043157d762b3d7c7ee
Author: Marius Stanciu <stanciumarius94 gmail com>
Date: Fri Jun 24 22:40:31 2016 +0300
Add swappable user layer clones.
The real user_layers actor is swapped with clones depending
on cursor position.
champlain/champlain-view.c | 119 +++++++++++++++++++++++++++++++++++++-------
1 files changed, 101 insertions(+), 18 deletions(-)
---
diff --git a/champlain/champlain-view.c b/champlain/champlain-view.c
index ad1cb3c..45e7ef7 100644
--- a/champlain/champlain-view.c
+++ b/champlain/champlain-view.c
@@ -153,15 +153,21 @@ struct _ChamplainViewPrivate
ClutterActor *zoom_layer; /* zoom_layer */
ClutterActor *map_layer; /* map_layer */
/* map_layer clones */
- ClutterActor *user_layers; /* user_layers */
+ ClutterActor *user_layers; /* user_layers and clones */
ClutterActor *zoom_overlay_actor; /* zoom_overlay_actor */
ClutterActor *license_actor; /* license_actor */
ClutterContent *background_content;
gboolean hwrap;
- GList *clones;
gint num_clones;
+ GList *map_clones;
+ /* There are num_clones user layer slots, overlayed on the map clones.
+ * The first slot initially contains the real user_layers actor, and the
+ * rest contain clones. Whenever the cursor enters a clone slot, its content
+ * is swapped with the real one so as to ensure reactiveness to events.
+ */
+ GList *user_layer_slots;
gdouble viewport_x;
gdouble viewport_y;
@@ -213,6 +219,7 @@ struct _ChamplainViewPrivate
G_DEFINE_TYPE (ChamplainView, champlain_view, CLUTTER_TYPE_ACTOR);
+static void exclusive_destroy_clone(ClutterActor *clone);
static void update_clones (ChamplainView *view);
static gboolean scroll_event (ClutterActor *actor,
ClutterScrollEvent *event,
@@ -235,6 +242,12 @@ static void viewport_pos_changed_cb (GObject *gobject,
static gboolean kinetic_scroll_button_press_cb (ClutterActor *actor,
ClutterButtonEvent *event,
ChamplainView *view);
+static void swap_user_layer_slots (ChamplainView *view,
+ gint original_index,
+ gint clone_index);
+static gboolean clone_enter_cb (ClutterActor *actor,
+ ClutterCrossingEvent *event,
+ ChamplainView *view);
static void load_visible_tiles (ChamplainView *view,
gboolean relocate);
static gboolean view_set_zoom_level_at (ChamplainView *view,
@@ -1143,6 +1156,14 @@ view_size_changed_cb (ChamplainView *view,
priv->viewport_height = height;
}
+static void
+exclusive_destroy_clone (ClutterActor *clone)
+{
+ if (!CLUTTER_IS_CLONE (clone))
+ return;
+
+ clutter_actor_destroy (clone);
+}
static void
update_clones (ChamplainView *view)
@@ -1159,26 +1180,47 @@ update_clones (ChamplainView *view)
priv->num_clones = ceil (view_width / map_size) + 1;
- if (priv->clones != NULL)
+ if (priv->map_clones != NULL)
{
- g_list_free_full (priv->clones, (GDestroyNotify) clutter_actor_destroy);
- priv->clones = NULL;
+ /* Only destroy clones, skip the real user_layers actor */
+ g_list_free_full (priv->user_layer_slots, (GDestroyNotify) exclusive_destroy_clone);
+ g_list_free_full (priv->map_clones, (GDestroyNotify) clutter_actor_destroy);
+
+ priv->map_clones = NULL;
+ priv->user_layer_slots = NULL;
}
+
+ /* Inserting the real user layer in the first slot */
+ priv->user_layer_slots = g_list_append (priv->user_layer_slots, priv->user_layers);
+ clutter_actor_set_x (priv->user_layers, 0);
+
+ /* A fixed width is needed to ensure actors don't get resized when moved */
+ clutter_actor_set_width (priv->user_layers, map_size);
for (i = 0; i < priv->num_clones; i++)
{
- ClutterActor *clone_right = clutter_clone_new (priv->map_layer);
-
- clutter_actor_set_x (clone_right, (i + 1) * map_size);
-
- /* user layers can wrap the map_width, make sure they remain visible */
- clutter_actor_insert_child_below (priv->viewport_container, clone_right,
+ /* Map layer clones */
+ ClutterActor *map_clone = clutter_clone_new (priv->map_layer);
+ clutter_actor_set_x (map_clone, (i + 1) * map_size);
+ clutter_actor_insert_child_below (priv->viewport_container, map_clone,
+ NULL);
+
+ priv->map_clones = g_list_prepend (priv->map_clones, map_clone);
+
+ /* User layer clones */
+ ClutterActor *clone_user = clutter_clone_new (priv->user_layers);
+ clutter_actor_set_x (clone_user, (i + 1) * map_size);
+ clutter_actor_insert_child_below (priv->viewport_container, clone_user,
priv->user_layers);
- priv->clones = g_list_prepend (priv->clones, clone_right);
+ clutter_actor_set_reactive (clone_user, TRUE);
+ clutter_actor_set_width (priv->user_layers, map_size);
+ g_signal_connect (clone_user, "enter-event",
+ G_CALLBACK (clone_enter_cb), view);
+
+ /* Inserting the user layer clones in the following slots */
+ priv->user_layer_slots = g_list_append (priv->user_layer_slots, clone_user);
}
-
- // TODO: position user_layers into the center of the map
}
@@ -1239,7 +1281,8 @@ champlain_view_init (ChamplainView *view)
priv->goto_duration = 0;
priv->goto_mode = CLUTTER_EASE_IN_OUT_CIRC;
priv->num_clones = 0;
- priv->clones = NULL;
+ priv->map_clones = NULL;
+ priv->user_layer_slots = NULL;
priv->hwrap = FALSE;
clutter_actor_set_background_color (CLUTTER_ACTOR (view), &color);
@@ -1364,6 +1407,43 @@ viewport_pos_changed_cb (G_GNUC_UNUSED GObject *gobject,
}
}
+
+static void
+swap_user_layer_slots (ChamplainView *view,
+ gint original_index,
+ gint clone_index)
+{
+ ChamplainViewPrivate *priv = view->priv;
+ gint map_width = get_map_width (view);
+
+ GList *original_slot = g_list_nth (priv->user_layer_slots, original_index);
+ GList *clone_slot = g_list_nth (priv->user_layer_slots, clone_index);
+
+ ClutterActor *clone = clone_slot->data;
+
+ original_slot->data = clone;
+ clone_slot->data = priv->user_layers;
+
+ clutter_actor_set_x (clone, original_index * map_width);
+ clutter_actor_set_x (priv->user_layers, clone_index * map_width);
+}
+
+
+static gboolean
+clone_enter_cb (ClutterActor *clone,
+ G_GNUC_UNUSED ClutterCrossingEvent *event,
+ ChamplainView *view)
+{
+ ChamplainViewPrivate *priv = view->priv;
+
+ gint original_index = g_list_index (priv->user_layer_slots, priv->user_layers);
+ gint clone_index = g_list_index (priv->user_layer_slots, clone);
+
+ swap_user_layer_slots (view, original_index, clone_index);
+
+ return TRUE;
+ }
+
static gboolean
kinetic_scroll_button_press_cb (G_GNUC_UNUSED ClutterActor *actor,
ClutterButtonEvent *event,
@@ -2677,8 +2757,10 @@ champlain_view_set_horizontal_wrap (ChamplainView *view,
update_clones (view);
else
{
- g_list_free_full (priv->clones, (GDestroyNotify) clutter_actor_destroy);
- priv->clones = NULL;
+ g_list_free_full (priv->map_clones, (GDestroyNotify) clutter_actor_destroy);
+ g_list_free_full (priv->user_layer_slots, (GDestroyNotify) exclusive_destroy_clone);
+ priv->map_clones = NULL;
+ priv->user_layer_slots = NULL;
}
resize_viewport (view);
@@ -2831,11 +2913,12 @@ show_zoom_actor (ChamplainView *view,
if (priv->hwrap)
{
- GList *old_clone = priv->clones;
+ GList *old_clone = priv->map_clones;
for (i = 0; i < priv->num_clones; i++)
{
ClutterActor *clone_right = clutter_clone_new (tile_container);
clutter_actor_hide (CLUTTER_ACTOR (old_clone->data));
+ clutter_actor_set_reactive (CLUTTER_ACTOR (old_clone->data), FALSE);
gfloat tiles_x;
clutter_actor_get_position (tile_container, &tiles_x, NULL);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]