[libchamplain] Implement ChamplainSelectionLayer



commit 20c2f583780aeb4d0e7b09219b8c56ce4b896af9
Author: Pierre-Luc Beaudoin <pierre-luc pierlux com>
Date:   Mon Jul 6 16:38:34 2009 +0100

    Implement ChamplainSelectionLayer

 champlain/champlain-selection-layer.c    |  156 +++++++++++++++++++++++++++++-
 champlain/champlain-selection-layer.h    |   32 ++++++
 docs/reference/libchamplain-docs.sgml    |    1 +
 docs/reference/libchamplain-sections.txt |   24 +++++
 4 files changed, 210 insertions(+), 3 deletions(-)
---
diff --git a/champlain/champlain-selection-layer.c b/champlain/champlain-selection-layer.c
index 5e52209..a99a988 100644
--- a/champlain/champlain-selection-layer.c
+++ b/champlain/champlain-selection-layer.c
@@ -47,10 +47,9 @@ enum
   PROP_0
 };
 
-typedef struct _ChamplainSelectionLayerPrivate ChamplainSelectionLayerPrivate;
-
 struct _ChamplainSelectionLayerPrivate {
-  gpointer spacer;
+  ChamplainSelectionMode mode;
+  GList *selection;
 };
 
 static void
@@ -93,9 +92,78 @@ champlain_selection_layer_class_init (ChamplainSelectionLayerClass *klass)
 }
 
 static void
+real_select (ChamplainSelectionLayer *layer,
+    ChamplainBaseMarker *marker,
+    gboolean append)
+{
+  g_print ("Select %p\n", marker);
+
+  if (layer->priv->mode == CHAMPLAIN_SELECTION_SINGLE)
+    {
+      /* Clear previous selection */
+      champlain_selection_layer_unselect (layer, marker);
+
+      /* Add selection */
+      g_object_ref (marker);
+      layer->priv->selection = g_list_prepend (layer->priv->selection, marker);
+    }
+  else if (layer->priv->mode == CHAMPLAIN_SELECTION_MULTIPLE)
+    {
+      /* Clear previous selection */
+      if (!append)
+        champlain_selection_layer_unselect_all (layer);
+
+      /* Add selection */
+      g_object_ref (marker);
+      layer->priv->selection = g_list_append (layer->priv->selection, marker);
+    }
+}
+
+static gboolean
+marker_clicked_cb (ClutterActor *actor,
+    ClutterButtonEvent *event,
+    gpointer user_data)
+{
+
+  real_select (CHAMPLAIN_SELECTION_LAYER (user_data),
+      CHAMPLAIN_BASE_MARKER (actor), (event->modifier_state & CLUTTER_CONTROL_MASK));
+
+  return FALSE;
+}
+
+static void
+layer_add_cb (ClutterGroup *layer,
+    ClutterActor *actor,
+    gpointer data)
+{
+  ChamplainBaseMarker *marker = CHAMPLAIN_BASE_MARKER (actor);
+
+  clutter_actor_set_reactive (actor, TRUE);
+
+  g_signal_connect (G_OBJECT (marker), "button-release-event",
+      G_CALLBACK (marker_clicked_cb), layer);
+}
+
+static void
+layer_remove_cb (ClutterGroup *layer,
+    ClutterActor *actor,
+    gpointer data)
+{
+  g_signal_handlers_disconnect_by_func (G_OBJECT (actor),
+      G_CALLBACK (marker_clicked_cb), layer);
+}
+
+static void
 champlain_selection_layer_init (ChamplainSelectionLayer *self)
 {
+  self->priv = GET_PRIVATE (self);
+  self->priv->mode = CHAMPLAIN_SELECTION_SINGLE;
+  self->priv->selection = NULL;
 
+  g_signal_connect_after (G_OBJECT (self), "actor-added",
+      G_CALLBACK (layer_add_cb), NULL);
+  g_signal_connect_after (G_OBJECT (self), "actor-removed",
+      G_CALLBACK (layer_remove_cb), NULL);
 }
 
 /**
@@ -110,3 +178,85 @@ champlain_selection_layer_new ()
 {
   return g_object_new (CHAMPLAIN_TYPE_SELECTION_LAYER, NULL);
 }
+
+/**
+ * champlain_selection_get_selected:
+ *
+ * This function will return NULL if in CHAMPLAIN_SELETION_MULTIPLE.
+ *
+ * Returns the selected #ChamplainBaseMarker or NULL if none is selected.
+ *
+ * Since: 0.4
+ */
+ChamplainBaseMarker *
+champlain_selection_layer_get_selected (ChamplainSelectionLayer *layer)
+{
+  if (layer->priv->mode == CHAMPLAIN_SELECTION_SINGLE &&
+      layer->priv->selection != NULL)
+    {
+      return layer->priv->selection->data;
+    }
+
+  return NULL;
+}
+
+/**
+ * champlain_selection_get_selected_markers:
+ *
+ * Returns the list of selected #ChamplainBaseMarker or NULL if none is selected.
+ * You shouldn't free that list.
+ *
+ * Since: 0.4
+ */
+const GList *
+champlain_selection_layer_get_selected_markers (ChamplainSelectionLayer *layer)
+{
+  return layer->priv->selection;
+}
+
+/**
+ * champlain_selection_count_selected_markers:
+ *
+ * Returns the number of selected #ChamplainBaseMarker
+ *
+ * Since: 0.4
+ */
+guint
+champlain_selection_layer_count_selected_markers (ChamplainSelectionLayer *layer)
+{
+  return g_list_length (layer->priv->selection);
+}
+
+void 
+champlain_selection_layer_select (ChamplainSelectionLayer *layer,
+    ChamplainBaseMarker *marker)
+{
+  real_select (layer, marker, TRUE);
+}
+
+void
+champlain_selection_layer_unselect_all (ChamplainSelectionLayer *layer)
+{
+  GList *selection = layer->priv->selection;
+
+  while (selection != NULL)
+    {
+      g_object_unref (selection->data);
+      selection = g_list_delete_link (selection, selection);
+    }
+  layer->priv->selection = selection;
+}
+
+void
+champlain_selection_layer_unselect (ChamplainSelectionLayer *layer,
+    ChamplainBaseMarker *marker)
+{
+  GList *selection;
+
+  selection = g_list_find (layer->priv->selection, marker);
+  if (selection != NULL)
+    {
+      g_object_unref (selection->data);
+      layer->priv->selection = g_list_delete_link (layer->priv->selection, selection);
+    }
+}
diff --git a/champlain/champlain-selection-layer.h b/champlain/champlain-selection-layer.h
index f8938fb..3ab4767 100644
--- a/champlain/champlain-selection-layer.h
+++ b/champlain/champlain-selection-layer.h
@@ -24,6 +24,7 @@
 #define CHAMPLAIN_SELECTION_LAYER_H
 
 #include <champlain/champlain-defines.h>
+#include <champlain/champlain-base-marker.h>
 #include <champlain/champlain-layer.h>
 
 #include <glib-object.h>
@@ -48,8 +49,26 @@ G_BEGIN_DECLS
 #define CHAMPLAIN_SELECTION_LAYER_GET_CLASS(obj) \
   (G_TYPE_INSTANCE_GET_CLASS ((obj), CHAMPLAIN_TYPE_SELECTION_LAYER, ChamplainSelectionLayerClass))
 
+typedef struct _ChamplainSelectionLayerPrivate ChamplainSelectionLayerPrivate;
+
+/**
+ * ChamplainSelectionMode:
+ * @CHAMPLAIN_SELECTION_NONE: No marker can be selected.
+ * @CHAMPLAIN_SELECTION_SINGLE: Only one marker can be selected.
+ * @CHAMPLAIN_SELECTION_MULTIPLE: Multiple marker can be selected.
+ *
+ * Selection mode
+ */
+typedef enum {
+  CHAMPLAIN_SELECTION_NONE,
+  CHAMPLAIN_SELECTION_SINGLE,
+  CHAMPLAIN_SELECTION_MULTIPLE
+} ChamplainSelectionMode;
+
 typedef struct {
   ChamplainLayer parent;
+
+  ChamplainSelectionLayerPrivate *priv;
 } ChamplainSelectionLayer;
 
 typedef struct {
@@ -60,6 +79,19 @@ GType champlain_selection_layer_get_type (void);
 
 ChamplainLayer * champlain_selection_layer_new (void);
 
+ChamplainBaseMarker * champlain_selection_layer_get_selected (ChamplainSelectionLayer *layer);
+const GList *champlain_selection_layer_get_selected_markers (ChamplainSelectionLayer *layer);
+guint champlain_selection_layer_count_selected_markers (ChamplainSelectionLayer *layer);
+
+void champlain_selection_layer_select (ChamplainSelectionLayer *layer,
+    ChamplainBaseMarker *marker);
+void champlain_selection_layer_unselect (ChamplainSelectionLayer *layer,
+    ChamplainBaseMarker *marker);
+gboolean champlain_selection_layer_marker_is_selected (ChamplainSelectionLayer *layer,
+    ChamplainBaseMarker *marker);
+void champlain_selection_layer_select_all (ChamplainSelectionLayer *layer);
+void champlain_selection_layer_unselect_all (ChamplainSelectionLayer *layer);
+
 G_END_DECLS
 
 #endif
diff --git a/docs/reference/libchamplain-docs.sgml b/docs/reference/libchamplain-docs.sgml
index a0ed186..996c718 100644
--- a/docs/reference/libchamplain-docs.sgml
+++ b/docs/reference/libchamplain-docs.sgml
@@ -42,6 +42,7 @@
     <title>I. View API Reference</title>
     <xi:include href="xml/champlain-view.xml"/>
     <xi:include href="xml/champlain-layer.xml"/>
+    <xi:include href="xml/champlain-selection-layer.xml"/>
     <xi:include href="xml/champlain-base-marker.xml"/>
     <xi:include href="xml/champlain-marker.xml"/>
     <xi:include href="xml/champlain-polygon.xml"/>
diff --git a/docs/reference/libchamplain-sections.txt b/docs/reference/libchamplain-sections.txt
index 0feeae7..a2c86d0 100644
--- a/docs/reference/libchamplain-sections.txt
+++ b/docs/reference/libchamplain-sections.txt
@@ -407,3 +407,27 @@ CHAMPLAIN_POLYGON_CLASS
 CHAMPLAIN_IS_POLYGON_CLASS
 CHAMPLAIN_POLYGON_GET_CLASS
 </SECTION>
+
+<SECTION>
+<FILE>champlain-selection-layer</FILE>
+<TITLE>ChamplainSelectionLayer</TITLE>
+ChamplainSelectionMode
+ChamplainSelectionLayer
+champlain_selection_layer_new
+champlain_selection_layer_get_selected
+champlain_selection_layer_get_selected_markers
+champlain_selection_layer_count_selected_markers
+champlain_selection_layer_select
+champlain_selection_layer_unselect
+champlain_selection_layer_marker_is_selected
+champlain_selection_layer_select_all
+champlain_selection_layer_unselect_all
+<SUBSECTION Standard>
+CHAMPLAIN_IS_SELECTION_LAYER
+CHAMPLAIN_IS_SELECTION_LAYER_CLASS
+CHAMPLAIN_SELECTION_LAYER
+CHAMPLAIN_SELECTION_LAYER_CLASS
+CHAMPLAIN_SELECTION_LAYER_GET_CLASS
+CHAMPLAIN_TYPE_SELECTION_LAYER
+champlain_selection_layer_get_type
+</SECTION>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]