From: Pierre-Luc Beaudoin Date: Thu, 29 Jan 2009 20:27:08 +0000 (+0200) Subject: Implement Click-on-the-map feature X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2c83d4734a6221e654601110ed09660bdd7ba029;p=libchamplain Implement Click-on-the-map feature --- diff --git a/champlain/champlainlayer.c b/champlain/champlainlayer.c index bfe9ae7..f9304e2 100644 --- a/champlain/champlainlayer.c +++ b/champlain/champlainlayer.c @@ -16,6 +16,17 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * SECTION:champlainlayer + * @short_description: A container for #ChamplainMarker + * + * A ChamplainLayer is little more than a #ClutterContainer. It keeps the + * markers ordered so that they display correctly. + * + * Use #clutter_container_add to add markers to the layer and + * #clutter_container_remove to remove them. + */ + #include "config.h" #include "champlainlayer.h" diff --git a/champlain/champlainmarker.c b/champlain/champlainmarker.c index d9bdf76..ba1b5af 100644 --- a/champlain/champlainmarker.c +++ b/champlain/champlainmarker.c @@ -16,6 +16,23 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * SECTION:champlainmarker + * @short_description: A marker to identify points of interest on a map + * + * Markers reprensent points of interest on a map. Markers need to be placed on + * a layer (a #ClutterGroup). Layers have to be added to a #ChamplainView for + * the markers to show on the map. + * + * A marker is nothing more than a regular #ClutterActor. You can draw on it + * what ever you want. Don't forget to set the anchor position in the marker + * using #champlain_marker_set_anchor. Set the markers position on the map + * using #champlain_marker_set_position. + * + * Champlain has a default type of markers with text. To create one, + * use #champlain_marker_new_with_label. + */ + #include "config.h" #include "champlaindefines.h" diff --git a/champlain/champlainview.c b/champlain/champlainview.c index 749d6d6..eaec4ed 100644 --- a/champlain/champlainview.c +++ b/champlain/champlainview.c @@ -16,6 +16,36 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +/** + * SECTION:champlainview + * @short_description: A #ClutterActor to display maps + * + * The #ChamplainView is a ClutterActor to display maps. It supports two modes + * of scrolling: + * + * Push: the normal behavior where the maps doesn't move + * after the user stopped scrolling; + * Kinetic: the iPhone-like behavior where the maps + * decelerate after the user stopped scrolling. + * + * + * You can use the same #ChamplainView to display many types of maps. In + * Champlain they are called map sources. You can change the #map-source + * property at anytime to replace the current displayed map. + * + * The maps are downloaded from Internet from open maps sources (like + * OpenStreetMap). Maps are divided + * in tiles for each zoom level. When a tile is requested, #ChamplainView will + * first check if it is in cache (in the user's cache dir under champlain). If + * an error occurs during download, an error tile will be displayed (if not in + * offline mode). + * + * The button-press-event and button-release-event signals are emitted each + * time a mouse button is pressed on the @view. Coordinates can be converted with + * #champlain_view_get_coords_from_event. + */ + #include "config.h" #include "champlaindefines.h" @@ -39,7 +69,6 @@ enum { /* normal signals */ - SIGNAL_TBD, LAST_SIGNAL }; @@ -57,10 +86,9 @@ enum }; #define PADDING 10 -// static guint champlain_view_signals[LAST_SIGNAL] = { 0, }; - -#define CHAMPLAIN_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), CHAMPLAIN_TYPE_VIEW, ChamplainViewPrivate)) +//static guint signals[LAST_SIGNAL] = { 0, }; +#define CHAMPLAIN_VIEW_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE((obj), CHAMPLAIN_TYPE_VIEW, ChamplainViewPrivate)) struct _ChamplainViewPrivate { ClutterActor *stage; @@ -108,7 +136,8 @@ static void viewport_x_changed_cb(GObject *gobject, GParamSpec *arg1, ChamplainV static void notify_marker_reposition_cb(ChamplainMarker *marker, GParamSpec *arg1, ChamplainView *view); static void layer_add_marker_cb (ClutterGroup *layer, ChamplainMarker *marker, ChamplainView *view); static void connect_marker_notify_cb (ChamplainMarker *marker, ChamplainView *view); -static gboolean finger_scroll_clicked (ClutterActor *actor, ClutterButtonEvent *event, ChamplainView *view); +static gboolean finger_scroll_button_press_cb (ClutterActor *actor, + ClutterButtonEvent *event, ChamplainView *view); static void update_license (ChamplainView *view); static void license_set_position (ChamplainView *view); @@ -697,9 +726,9 @@ update_license (ChamplainView *view) } static gboolean -finger_scroll_clicked (ClutterActor *actor, - ClutterButtonEvent *event, - ChamplainView *view) +finger_scroll_button_press_cb (ClutterActor *actor, + ClutterButtonEvent *event, + ChamplainView *view) { ChamplainViewPrivate *priv = CHAMPLAIN_VIEW_GET_PRIVATE (view); @@ -795,9 +824,9 @@ champlain_view_new (ChamplainViewMode mode) g_signal_connect (priv->finger_scroll, "button-press-event", - G_CALLBACK (finger_scroll_clicked), + G_CALLBACK (finger_scroll_button_press_cb), view); - + // Setup user_layers priv->user_layers = clutter_group_new(); clutter_actor_show(priv->user_layers); @@ -962,8 +991,22 @@ champlain_view_add_layer (ChamplainView *view, ClutterActor *layer) clutter_container_foreach(CLUTTER_CONTAINER(layer), CLUTTER_CALLBACK(connect_marker_notify_cb), view); } -gboolean -champlain_view_get_coords_from_event (ChamplainView *view, ClutterEvent *event, gdouble *lat, gdouble *lon) +/** + * champlain_view_get_coords_from_event: + * @view: a #ChamplainView + * @event: a #ClutterEvent + * @latitude: a variable where to put the latitude of the event + * @longitude: a variable where to put the longitude of the event + * + * Returns a new #ChamplainView ready to be used as a #ClutterActor. + * + * Since: 0.2.8 + */ +gboolean +champlain_view_get_coords_from_event (ChamplainView *view, + ClutterEvent *event, + gdouble *latitude, + gdouble *longitude) { g_return_val_if_fail(CHAMPLAIN_IS_VIEW(view), FALSE); g_return_val_if_fail(event, FALSE); // Apparently there isn't a more precise test @@ -978,21 +1021,21 @@ champlain_view_get_coords_from_event (ChamplainView *view, ClutterEvent *event, { ClutterButtonEvent *e = (ClutterButtonEvent*) event; x = e->x; - y = e->y; + y = e->y; } break; case CLUTTER_SCROLL: { ClutterScrollEvent *e = (ClutterScrollEvent*) event; x = e->x; - y = e->y; + y = e->y; } break; case CLUTTER_MOTION: { ClutterMotionEvent *e = (ClutterMotionEvent*) event; x = e->x; - y = e->y; + y = e->y; } break; case CLUTTER_ENTER: @@ -1000,15 +1043,19 @@ champlain_view_get_coords_from_event (ChamplainView *view, ClutterEvent *event, { ClutterCrossingEvent *e = (ClutterCrossingEvent*) event; x = e->x; - y = e->y; + y = e->y; } break; default: - return FALSE; + return FALSE; } - if (lat) - *lat = viewport_get_latitude_at(priv, priv->viewport_size.y + y + priv->map->current_level->anchor.y); - if (lon) - *lon = viewport_get_longitude_at(priv, priv->viewport_size.x + x + priv->map->current_level->anchor.x); + + if (latitude) + *latitude = viewport_get_latitude_at (priv, + priv->viewport_size.y + y + priv->map->current_level->anchor.y); + if (longitude) + *longitude = viewport_get_longitude_at (priv, + priv->viewport_size.x + x + priv->map->current_level->anchor.x); + return TRUE; } diff --git a/demos/launcher.c b/demos/launcher.c index 73ac02a..b3867f7 100644 --- a/demos/launcher.c +++ b/demos/launcher.c @@ -19,19 +19,35 @@ #include static gboolean -montreal_click (ClutterActor *actor, - ClutterButtonEvent *event, - ChamplainView * view) +map_view_button_release_cb (ClutterActor *actor, + ClutterButtonEvent *event, + ChamplainView * view) { gdouble lat, lon; - g_print("Montreal was clicked!\n"); + if (event->button != 1 || event->click_count > 1) + return; + + g_print("Map was clicked at "); if (champlain_view_get_coords_from_event (view, event, &lat, &lon)) g_print("%f, %f \n", lat, lon); return TRUE; } +static gboolean +montreal_click (ClutterActor *actor, + ClutterButtonEvent *event, + ChamplainView * view) +{ + if (event->button != 1 || event->click_count > 1) + return; + + g_print("Montreal was clicked\n"); + + return TRUE; +} + static ClutterActor* create_marker_layer (ChamplainView *view) { @@ -79,6 +95,9 @@ main (int argc, clutter_actor_set_size (stage, 800, 600); actor = champlain_view_new (CHAMPLAIN_VIEW_MODE_KINETIC); + clutter_actor_set_reactive (actor, TRUE); + g_signal_connect_after (actor, "button-release-event", + G_CALLBACK (map_view_button_release_cb), actor); champlain_view_set_size (CHAMPLAIN_VIEW (actor), 800, 600); diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am index 36ed995..4cbfb84 100644 --- a/docs/reference/Makefile.am +++ b/docs/reference/Makefile.am @@ -31,7 +31,11 @@ MKTMPL_OPTIONS= # Extra options to supply to gtkdoc-fixref. Not normally needed. # e.g. FIXXREF_OPTIONS=--extra-dir=../gdk-pixbuf/html --extra-dir=../gdk/html -FIXXREF_OPTIONS= +FIXXREF_OPTIONS= \ + --extra-dir=$(PREFIX)/share/gtk-doc/html/gobject \ + --extra-dir=$(PREFIX)/share/gtk-doc/html/glib \ + --extra-dir=$(PREFIX)/share/gtk-doc/html/clutter + # Used for dependencies. The docs will be rebuilt if any of these change. # e.g. HFILE_GLOB=$(top_srcdir)/gtk/*.h diff --git a/docs/reference/libchamplain-sections.txt b/docs/reference/libchamplain-sections.txt index 99ba812..6d92b95 100644 --- a/docs/reference/libchamplain-sections.txt +++ b/docs/reference/libchamplain-sections.txt @@ -9,6 +9,7 @@ champlain_view_new champlain_view_center_on champlain_view_zoom_in champlain_view_zoom_out +champlain_view_get_coords_from_event CHAMPLAIN_VIEW CHAMPLAIN_IS_VIEW diff --git a/docs/reference/tmpl/champlainmarker.sgml b/docs/reference/tmpl/champlainmarker.sgml deleted file mode 100644 index 8445098..0000000 --- a/docs/reference/tmpl/champlainmarker.sgml +++ /dev/null @@ -1,83 +0,0 @@ - -ChamplainMarker - - -A marker to identify points of interest on a map - - -Markers reprensent points of interest on a map. Markers need to be placed on a layer (a #ClutterGroup). Layers have to be added to a #ChamplainView for the markers to show on the map. - -A marker is nothing more than a regular #ClutterActor. You can draw on it what ever you want. Don't forget to set the anchor position in the marker using #champlain_marker_set_anchor. Set the markers position on the map using #champlain_marker_set_position. - -Champlain has a default type of markers with text. To create one, use #champlain_marker_new_with_label. - - - - - - - - - - - - - - -@group: -@priv: - - - - - - -@Returns: - - - - - - - -@label: -@font: -@text_color: -@marker_color: -@Returns: - - - - - - - -@filename: -@error: -@Returns: - - - - - - - -@filename: -@width: -@height: -@anchor_x: -@anchor_y: -@error: -@Returns: - - - - - - - -@marker: -@longitude: -@latitude: - - diff --git a/docs/reference/tmpl/champlainview.sgml b/docs/reference/tmpl/champlainview.sgml deleted file mode 100644 index 8360395..0000000 --- a/docs/reference/tmpl/champlainview.sgml +++ /dev/null @@ -1,134 +0,0 @@ - -ChamplainView - - -A #ClutterActor to display maps - - - -The #ChamplainView is a ClutterActor to display maps. It supports two modes of scrolling: - - Push: the normal behavior where the maps doesn't move after the user stopped scrolling; - Kinetic: the iPhone-like behavior where the maps decelerate after the user stopped scrolling. - - - -You can use the same #ChamplainView to display many types of maps. In Champlain they are called map sources. You can change the #map-source property at anytime to replace the current displayed map. - - -The maps are downloaded from Internet from open maps sources (like OpenStreetMap). Maps are divided in tiles for each zoom level. When a tile is requested, #ChamplainView will first check if it is in cache (in -the user's cache dir under champlain). If an error occurs during download, an error tile will be displayed (if not in offline mode). - - - - - - - - - - - - - - - - - - - -@CHAMPLAIN_MAP_SOURCE_DEBUG: -@CHAMPLAIN_MAP_SOURCE_OPENSTREETMAP: -@CHAMPLAIN_MAP_SOURCE_OPENARIALMAP: -@CHAMPLAIN_MAP_SOURCE_MAPSFORFREE_RELIEF: -@CHAMPLAIN_MAP_SOURCE_COUNT: - - - - - - -@CHAMPLAIN_VIEW_MODE_PUSH: -@CHAMPLAIN_VIEW_MODE_KINETIC: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -@mode: -@Returns: - - - - - - - -@view: -@latitude: -@longitude: - - - - - - - -@champlainView: - - - - - - - -@champlainView: - - diff --git a/tidy/tidy-finger-scroll.c b/tidy/tidy-finger-scroll.c index 4bd6ad1..d404d72 100644 --- a/tidy/tidy-finger-scroll.c +++ b/tidy/tidy-finger-scroll.c @@ -359,6 +359,7 @@ button_release_event_cb (ClutterActor *actor, TidyFingerScrollPrivate *priv = scroll->priv; ClutterActor *child = tidy_scroll_view_get_child (TIDY_SCROLL_VIEW(scroll)); gboolean decelerating = FALSE; + gboolean moved = TRUE; if (event->button != 1) return FALSE; @@ -536,6 +537,8 @@ button_release_event_cb (ClutterActor *actor, } /* Reset motion event buffer */ + if (priv->last_motion <= 1) + moved = FALSE; priv->last_motion = 0; if (!decelerating) @@ -546,7 +549,8 @@ button_release_event_cb (ClutterActor *actor, /* Pass through events to children. * FIXME: this probably breaks click-count. */ - clutter_event_put ((ClutterEvent *)event); + if (moved == FALSE) + clutter_event_put ((ClutterEvent *)event); return TRUE; }