]> err.no Git - libchamplain/commitdiff
Implement ChamplainSelectionLayer
authorPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Mon, 6 Jul 2009 15:38:34 +0000 (16:38 +0100)
committerPierre-Luc Beaudoin <pierre-luc@pierlux.com>
Tue, 28 Jul 2009 21:23:16 +0000 (17:23 -0400)
champlain/champlain-selection-layer.c
champlain/champlain-selection-layer.h
docs/reference/libchamplain-docs.sgml
docs/reference/libchamplain-sections.txt

index 5e52209de4c1aa889073bf19332aec7d7f5cffca..a99a988b6894f58e1e76e23ba6fa00099c5c8fbc 100644 (file)
@@ -47,10 +47,9 @@ enum
   PROP_0
 };
 
-typedef struct _ChamplainSelectionLayerPrivate ChamplainSelectionLayerPrivate;
-
 struct _ChamplainSelectionLayerPrivate {
-  gpointer spacer;
+  ChamplainSelectionMode mode;
+  GList *selection;
 };
 
 static void
@@ -92,10 +91,79 @@ champlain_selection_layer_class_init (ChamplainSelectionLayerClass *klass)
   object_class->set_property = champlain_selection_layer_set_property;
 }
 
+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);
+    }
+}
index f8938fb7571351c3a924ca369ebacdb956d4a882..3ab47670900cc4127d35006dc0c3c76f86cdf3e8 100644 (file)
@@ -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
index a0ed186ef1d6251768186865d5ea3c4a8426061e..996c718b8fb008da5b47dd16d41b596a36592454 100644 (file)
@@ -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"/>
index 0feeae7c7e7626d0e4cb994faf305edd1105db99..a2c86d08fb3800d7b971fd4aa61275b876b4eb1f 100644 (file)
@@ -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>