From: Pierre-Luc Beaudoin Date: Mon, 6 Jul 2009 15:38:34 +0000 (+0100) Subject: Implement ChamplainSelectionLayer X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=20c2f583780aeb4d0e7b09219b8c56ce4b896af9;p=libchamplain Implement ChamplainSelectionLayer --- 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 @@ -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); + } +} 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 +#include #include #include @@ -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 @@ I. View API Reference + 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 + +
+champlain-selection-layer +ChamplainSelectionLayer +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 + +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 +