#define GOOGLE_DIRECTIONS_STRING "maps.google.com/maps?q=from:%s,%s+to:%s,%s&output=js"
#endif
-#define VIK_TRW_LAYER_TRACK_GC 16
-#define VIK_TRW_LAYER_TRACK_GC_RATES 10
-#define VIK_TRW_LAYER_TRACK_GC_MIN 0
-#define VIK_TRW_LAYER_TRACK_GC_MAX 11
-#define VIK_TRW_LAYER_TRACK_GC_BLACK 12
-#define VIK_TRW_LAYER_TRACK_GC_SLOW 13
-#define VIK_TRW_LAYER_TRACK_GC_AVER 14
-#define VIK_TRW_LAYER_TRACK_GC_FAST 15
+#define VIK_TRW_LAYER_TRACK_GC 6
+#define VIK_TRW_LAYER_TRACK_GCS 10
+#define VIK_TRW_LAYER_TRACK_GC_BLACK 0
+#define VIK_TRW_LAYER_TRACK_GC_SLOW 1
+#define VIK_TRW_LAYER_TRACK_GC_AVER 2
+#define VIK_TRW_LAYER_TRACK_GC_FAST 3
+#define VIK_TRW_LAYER_TRACK_GC_STOP 4
+#define VIK_TRW_LAYER_TRACK_GC_SINGLE 5
#define DRAWMODE_BY_TRACK 0
#define DRAWMODE_BY_SPEED 1
-#define DRAWMODE_ALL_BLACK 2
+#define DRAWMODE_ALL_SAME_COLOR 2
// Note using DRAWMODE_BY_SPEED may be slow especially for vast numbers of trackpoints
// as we are (re)calculating the colour for every point
gdouble track_draw_speed_factor;
GArray *track_gc;
+ GdkGC *track_1color_gc;
+ GdkColor track_color;
GdkGC *current_track_gc;
// Separate GC for a track's potential new point as drawn via separate method
// (compared to the actual track points drawn in the main trw_layer_draw_track function)
struct DrawingParams {
VikViewport *vp;
VikTrwLayer *vtl;
+ VikWindow *vw;
gdouble xmpp, ympp;
guint16 width, height;
gdouble cc; // Cosine factor in track directions
gdouble ss; // Sine factor in track directions
const VikCoord *center;
- gint track_gc_iter;
gboolean one_zone, lat_lon;
gdouble ce1, ce2, cn1, cn2;
};
static void trw_layer_copy_item_cb ( gpointer pass_along[6] );
static void trw_layer_cut_item_cb ( gpointer pass_along[6] );
-static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoint *w, struct LatLon maxmin[2] );
-static void trw_layer_find_maxmin_tracks ( const gchar *name, const VikTrack *trk, struct LatLon maxmin[2] );
+static void trw_layer_find_maxmin_waypoints ( const gpointer id, const VikWaypoint *w, struct LatLon maxmin[2] );
+static void trw_layer_find_maxmin_tracks ( const gpointer id, const VikTrack *trk, struct LatLon maxmin[2] );
static void trw_layer_find_maxmin (VikTrwLayer *vtl, struct LatLon maxmin[2]);
static void trw_layer_new_track_gcs ( VikTrwLayer *vtl, VikViewport *vp );
static void trw_layer_free_track_gcs ( VikTrwLayer *vtl );
-static void trw_layer_draw_track_cb ( const gchar *name, VikTrack *track, struct DrawingParams *dp );
-static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct DrawingParams *dp );
+static void trw_layer_draw_track_cb ( const gpointer id, VikTrack *track, struct DrawingParams *dp );
+static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct DrawingParams *dp );
static void goto_coord ( gpointer *vlp, gpointer vvp, gpointer vl, const VikCoord *coord );
static void trw_layer_goto_track_startpoint ( gpointer pass_along[6] );
#endif
#ifdef VIK_CONFIG_OPENSTREETMAP
static void trw_layer_acquire_osm_cb ( gpointer lav[2] );
+static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] );
#endif
#ifdef VIK_CONFIG_GEOCACHES
static void trw_layer_acquire_geocache_cb ( gpointer lav[2] );
// Most track handling functions can handle operating on the route list
// However these ones are easier in separate functions
static void trw_layer_auto_routes_view ( gpointer lav[2] );
+static void trw_layer_delete_all_routes ( gpointer lav[2] );
static void trw_layer_delete_routes_from_selection ( gpointer lav[2] );
/* pop-up items */
static void trw_layer_properties_item ( gpointer pass_along[7] );
static void trw_layer_goto_waypoint ( gpointer pass_along[6] );
static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[6] );
+static void trw_layer_waypoint_webpage ( gpointer pass_along[6] );
static void trw_layer_realize_waypoint ( gpointer id, VikWaypoint *wp, gpointer pass_along[5] );
static void trw_layer_realize_track ( gpointer id, VikTrack *track, gpointer pass_along[5] );
static gboolean tool_edit_waypoint_click ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
static gboolean tool_edit_waypoint_move ( VikTrwLayer *vtl, GdkEventMotion *event, gpointer data );
static gboolean tool_edit_waypoint_release ( VikTrwLayer *vtl, GdkEventButton *event, gpointer data );
-static gpointer tool_begin_track_create ( VikWindow *vw, VikViewport *vvp);
-static gboolean tool_begin_track_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
+static gpointer tool_new_route_create ( VikWindow *vw, VikViewport *vvp);
+static gboolean tool_new_route_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
static gpointer tool_new_track_create ( VikWindow *vw, VikViewport *vvp);
static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp );
static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMotion *event, VikViewport *vvp );
static VikWaypoint *closest_wp_in_five_pixel_interval ( VikTrwLayer *vtl, VikViewport *vvp, gint x, gint y );
static void waypoint_convert ( const gpointer id, VikWaypoint *wp, VikCoordMode *dest_mode );
-static void track_convert ( const gchar *name, VikTrack *tr, VikCoordMode *dest_mode );
+static void track_convert ( const gpointer id, VikTrack *tr, VikCoordMode *dest_mode );
static gchar *highest_wp_number_get(VikTrwLayer *vtl);
static void highest_wp_number_reset(VikTrwLayer *vtl);
TRUE, // Still need to handle clicks when in PAN mode to disable the potential trackpoint drawing
GDK_CURSOR_IS_PIXMAP, &cursor_addtr_pixbuf },
- { { "BeginTrack", "vik-icon-Begin Track", N_("_Begin Track"), "<control><shift>B", N_("Begin Track"), 0 },
- (VikToolConstructorFunc) tool_begin_track_create, NULL, NULL, NULL,
- (VikToolMouseFunc) tool_begin_track_click, NULL, NULL, (VikToolKeyFunc) NULL,
- FALSE,
- GDK_CURSOR_IS_PIXMAP, &cursor_begintr_pixbuf },
+ { { "CreateRoute", "vik-icon-Create Route", N_("Create _Route"), "<control><shift>B", N_("Create Route"), 0 },
+ (VikToolConstructorFunc) tool_new_route_create, NULL, NULL, NULL,
+ (VikToolMouseFunc) tool_new_route_click,
+ (VikToolMouseMoveFunc) tool_new_track_move, // -\#
+ (VikToolMouseFunc) tool_new_track_release, // -> Reuse these track methods on a route
+ (VikToolKeyFunc) tool_new_track_key_press, // -/#
+ TRUE, // Still need to handle clicks when in PAN mode to disable the potential trackpoint drawing
+ GDK_CURSOR_IS_PIXMAP, &cursor_new_route_pixbuf },
{ { "EditWaypoint", "vik-icon-Edit Waypoint", N_("_Edit Waypoint"), "<control><shift>E", N_("Edit Waypoint"), 0 },
(VikToolConstructorFunc) tool_edit_waypoint_create, NULL, NULL, NULL,
GDK_CURSOR_IS_PIXMAP, &cursor_route_finder_pixbuf },
#endif
};
-enum { TOOL_CREATE_WAYPOINT=0, TOOL_CREATE_TRACK, TOOL_BEGIN_TRACK, TOOL_EDIT_WAYPOINT, TOOL_EDIT_TRACKPOINT, TOOL_SHOW_PICTURE, NUM_TOOLS };
+
+enum {
+ TOOL_CREATE_WAYPOINT=0,
+ TOOL_CREATE_TRACK,
+ TOOL_CREATE_ROUTE,
+ TOOL_EDIT_WAYPOINT,
+ TOOL_EDIT_TRACKPOINT,
+ TOOL_SHOW_PICTURE,
+#ifdef VIK_CONFIG_GOOGLE
+ TOOL_ROUTE_FINDER,
+#endif
+ NUM_TOOLS
+};
/****** PARAMETERS ******/
static gchar *params_groups[] = { N_("Waypoints"), N_("Tracks"), N_("Waypoint Images") };
enum { GROUP_WAYPOINTS, GROUP_TRACKS, GROUP_IMAGES };
-static gchar *params_drawmodes[] = { N_("Draw by Track"), N_("Draw by Speed"), N_("All Tracks Black"), 0 };
+static gchar *params_drawmodes[] = { N_("Draw by Track"), N_("Draw by Speed"), N_("All Tracks Same Color"), NULL };
static gchar *params_wpsymbols[] = { N_("Filled Square"), N_("Square"), N_("Circle"), N_("X"), 0 };
#define MIN_POINT_SIZE 2
NULL };
VikLayerParam trw_layer_params[] = {
- { "tracks_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES },
- { "waypoints_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES },
- { "routes_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES },
-
- { "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Drawing Mode:"), VIK_LAYER_WIDGET_RADIOGROUP, NULL },
- { "drawlines", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Lines"), VIK_LAYER_WIDGET_CHECKBUTTON },
- { "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 0 },
- { "drawdirections", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Direction"), VIK_LAYER_WIDGET_CHECKBUTTON },
- { "trkdirectionsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Direction Size:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 11 },
- { "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Trackpoints"), VIK_LAYER_WIDGET_CHECKBUTTON },
- { "trkpointsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Trackpoint Size:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 10 },
- { "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Elevation"), VIK_LAYER_WIDGET_CHECKBUTTON },
- { "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Draw Elevation Height %:"), VIK_LAYER_WIDGET_HSCALE, params_scales + 9 },
-
- { "drawstops", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Stops"), VIK_LAYER_WIDGET_CHECKBUTTON },
- { "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Min Stop Length (seconds):"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 8 },
-
- { "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track BG Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 6 },
- { "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("Track Background Color"), VIK_LAYER_WIDGET_COLOR, 0 },
- { "speed_factor", VIK_LAYER_PARAM_DOUBLE, GROUP_TRACKS, N_("Draw by Speed Factor (%):"), VIK_LAYER_WIDGET_HSCALE, params_scales + 1 },
-
- { "drawlabels", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Labels"), VIK_LAYER_WIDGET_CHECKBUTTON },
- { "wpfontsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint Font Size:"), VIK_LAYER_WIDGET_COMBOBOX, params_font_sizes, NULL },
- { "wpcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Color:"), VIK_LAYER_WIDGET_COLOR, 0 },
- { "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Text:"), VIK_LAYER_WIDGET_COLOR, 0 },
- { "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Background:"), VIK_LAYER_WIDGET_COLOR, 0 },
- { "wpbgand", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Fake BG Color Translucency:"), VIK_LAYER_WIDGET_CHECKBUTTON, 0 },
- { "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint marker:"), VIK_LAYER_WIDGET_RADIOGROUP, NULL },
- { "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint size:"), VIK_LAYER_WIDGET_SPINBUTTON, params_scales + 7 },
- { "wpsyms", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Waypoint Symbols:"), VIK_LAYER_WIDGET_CHECKBUTTON },
-
- { "drawimages", VIK_LAYER_PARAM_BOOLEAN, GROUP_IMAGES, N_("Draw Waypoint Images"), VIK_LAYER_WIDGET_CHECKBUTTON },
- { "image_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Size (pixels):"), VIK_LAYER_WIDGET_HSCALE, params_scales + 3 },
- { "image_alpha", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Alpha:"), VIK_LAYER_WIDGET_HSCALE, params_scales + 4 },
- { "image_cache_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Memory Cache Size:"), VIK_LAYER_WIDGET_HSCALE, params_scales + 5 },
+ { "tracks_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL },
+ { "waypoints_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL },
+ { "routes_visible", VIK_LAYER_PARAM_BOOLEAN, VIK_LAYER_NOT_IN_PROPERTIES, NULL, 0, NULL, NULL },
+
+ { "drawmode", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Drawing Mode:"), VIK_LAYER_WIDGET_COMBOBOX, params_drawmodes, NULL, NULL },
+ { "trackcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("All Tracks Color:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL,
+ N_("The color used when 'All Tracks Same Color' drawing mode is selected") },
+ { "drawlines", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Lines"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+ { "line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[0], NULL, NULL },
+ { "drawdirections", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Track Direction"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+ { "trkdirectionsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Direction Size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[11], NULL, NULL },
+ { "drawpoints", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Trackpoints"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+ { "trkpointsize", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Trackpoint Size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[10], NULL, NULL },
+ { "drawelevation", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Elevation"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+ { "elevation_factor", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Draw Elevation Height %:"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[9], NULL, NULL },
+
+ { "drawstops", VIK_LAYER_PARAM_BOOLEAN, GROUP_TRACKS, N_("Draw Stops"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL,
+ N_("Whether to draw a marker when trackpoints are at the same position but over the minimum stop length apart in time") },
+ { "stop_length", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Min Stop Length (seconds):"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[8], NULL, NULL },
+
+ { "bg_line_thickness", VIK_LAYER_PARAM_UINT, GROUP_TRACKS, N_("Track BG Thickness:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[6], NULL, NULL},
+ { "trackbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_TRACKS, N_("Track Background Color"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL },
+ { "speed_factor", VIK_LAYER_PARAM_DOUBLE, GROUP_TRACKS, N_("Draw by Speed Factor (%):"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[1], NULL,
+ N_("The percentage factor away from the average speed determining the color used") },
+
+ { "drawlabels", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Labels"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+ { "wpfontsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint Font Size:"), VIK_LAYER_WIDGET_COMBOBOX, params_font_sizes, NULL, NULL },
+ { "wpcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Color:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL },
+ { "wptextcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Waypoint Text:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL },
+ { "wpbgcolor", VIK_LAYER_PARAM_COLOR, GROUP_WAYPOINTS, N_("Background:"), VIK_LAYER_WIDGET_COLOR, NULL, NULL, NULL },
+ { "wpbgand", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Fake BG Color Translucency:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+ { "wpsymbol", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint marker:"), VIK_LAYER_WIDGET_COMBOBOX, params_wpsymbols, NULL, NULL },
+ { "wpsize", VIK_LAYER_PARAM_UINT, GROUP_WAYPOINTS, N_("Waypoint size:"), VIK_LAYER_WIDGET_SPINBUTTON, ¶ms_scales[7], NULL, NULL },
+ { "wpsyms", VIK_LAYER_PARAM_BOOLEAN, GROUP_WAYPOINTS, N_("Draw Waypoint Symbols:"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+
+ { "drawimages", VIK_LAYER_PARAM_BOOLEAN, GROUP_IMAGES, N_("Draw Waypoint Images"), VIK_LAYER_WIDGET_CHECKBUTTON, NULL, NULL, NULL },
+ { "image_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Size (pixels):"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[3], NULL, NULL },
+ { "image_alpha", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Alpha:"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[4], NULL, NULL },
+ { "image_cache_size", VIK_LAYER_PARAM_UINT, GROUP_IMAGES, N_("Image Memory Cache Size:"), VIK_LAYER_WIDGET_HSCALE, ¶ms_scales[5], NULL, NULL },
};
// ENUMERATION MUST BE IN THE SAME ORDER AS THE NAMED PARAMS ABOVE
PARAM_RV,
// Tracks
PARAM_DM,
+ PARAM_TC,
PARAM_DL,
PARAM_LT,
PARAM_DD,
/* Layer Interface function definitions */
static VikTrwLayer* trw_layer_create ( VikViewport *vp );
static void trw_layer_realize ( VikTrwLayer *vtl, VikTreeview *vt, GtkTreeIter *layer_iter );
+static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vvp );
static void trw_layer_free ( VikTrwLayer *trwlayer );
static void trw_layer_draw ( VikTrwLayer *l, gpointer data );
static void trw_layer_change_coord_mode ( VikTrwLayer *vtl, VikCoordMode dest_mode );
(VikLayerFuncCreate) trw_layer_create,
(VikLayerFuncRealize) trw_layer_realize,
- (VikLayerFuncPostRead) trw_layer_verify_thumbnails,
+ (VikLayerFuncPostRead) trw_layer_post_read,
(VikLayerFuncFree) trw_layer_free,
(VikLayerFuncProperties) NULL,
(VikLayerFuncSelectedViewportMenu) trw_layer_show_selected_viewport_menu,
};
-// for copy & paste
-typedef struct {
- guint len;
- guint8 data[0];
-} FlatItem;
-
GType vik_trw_layer_get_type ()
{
static GType vtl_type = 0;
static void trw_layer_copy_item ( VikTrwLayer *vtl, gint subtype, gpointer sublayer, guint8 **item, guint *len )
{
- FlatItem *fi;
guint8 *id;
guint il;
return;
}
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
- {
+ GByteArray *ba = g_byte_array_new ();
+
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
vik_waypoint_marshall ( g_hash_table_lookup ( vtl->waypoints, sublayer ), &id, &il );
- // 'Simple' memory copy of byte array from the marshalling above
- *len = sizeof(FlatItem) + 1 + il; // not sure what the 1 is for yet...
- fi = g_malloc ( *len );
- fi->len = *len;
- memcpy(fi->data, id, il);
} else if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
vik_track_marshall ( g_hash_table_lookup ( vtl->tracks, sublayer ), &id, &il );
- // less magic than before...
- *len = sizeof(FlatItem) + 1 + il;
- fi = g_malloc ( *len );
- fi->len = *len;
- memcpy(fi->data, id, il);
} else {
vik_track_marshall ( g_hash_table_lookup ( vtl->routes, sublayer ), &id, &il );
- // less magic than before...
- *len = sizeof(FlatItem) + 1 + il;
- fi = g_malloc ( *len );
- fi->len = *len;
- memcpy(fi->data, id, il);
}
+ g_byte_array_append ( ba, id, il );
+
g_free(id);
- *item = (guint8 *)fi;
+
+ *len = ba->len;
+ *item = ba->data;
}
static gboolean trw_layer_paste_item ( VikTrwLayer *vtl, gint subtype, guint8 *item, guint len )
{
- FlatItem *fi = (FlatItem *) item;
+ if ( !item )
+ return FALSE;
+
+ gchar *name;
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT && fi )
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
{
VikWaypoint *w;
- gchar *name;
- w = vik_waypoint_unmarshall(fi->data, fi->len);
+ w = vik_waypoint_unmarshall ( item, len );
// When copying - we'll create a new name based on the original
name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_WAYPOINT, w->name);
vik_trw_layer_add_waypoint ( vtl, name, w );
// Consider if redraw necessary for the new item
if ( vtl->vl.visible && vtl->waypoints_visible && w->visible )
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK && fi )
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK )
{
VikTrack *t;
- gchar *name;
- t = vik_track_unmarshall(fi->data, fi->len);
+ t = vik_track_unmarshall ( item, len );
// When copying - we'll create a new name based on the original
name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, t->name);
vik_trw_layer_add_track ( vtl, name, t );
// Consider if redraw necessary for the new item
if ( vtl->vl.visible && vtl->tracks_visible && t->visible )
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
- if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE && fi )
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE )
{
VikTrack *t;
- gchar *name;
- t = vik_track_unmarshall(fi->data, fi->len);
+ t = vik_track_unmarshall ( item, len );
// When copying - we'll create a new name based on the original
name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, t->name);
vik_trw_layer_add_route ( vtl, name, t );
// Consider if redraw necessary for the new item
if ( vtl->vl.visible && vtl->routes_visible && t->visible )
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
return FALSE;
case PARAM_WV: vtl->waypoints_visible = data.b; break;
case PARAM_RV: vtl->routes_visible = data.b; break;
case PARAM_DM: vtl->drawmode = data.u; break;
+ case PARAM_TC:
+ vtl->track_color = data.c;
+ trw_layer_new_track_gcs ( vtl, vp );
+ break;
case PARAM_DP: vtl->drawpoints = data.b; break;
case PARAM_DPS:
if ( data.u >= MIN_POINT_SIZE && data.u <= MAX_POINT_SIZE )
trw_layer_new_track_gcs ( vtl, vp );
}
break;
- case PARAM_BLT: if ( data.u >= 0 && data.u <= 8 && data.u != vtl->bg_line_thickness )
+ case PARAM_BLT: if ( data.u <= 8 && data.u != vtl->bg_line_thickness )
{
vtl->bg_line_thickness = data.u;
trw_layer_new_track_gcs ( vtl, vp );
case PARAM_WV: rv.b = vtl->waypoints_visible; break;
case PARAM_RV: rv.b = vtl->routes_visible; break;
case PARAM_DM: rv.u = vtl->drawmode; break;
+ case PARAM_TC: rv.c = vtl->track_color; break;
case PARAM_DP: rv.b = vtl->drawpoints; break;
case PARAM_DPS: rv.u = vtl->drawpoints_size; break;
case PARAM_DE: rv.b = vtl->drawelevation; break;
static void trw_layer_marshall( VikTrwLayer *vtl, guint8 **data, gint *len )
{
guint8 *pd;
- gchar *dd;
- gsize dl;
gint pl;
- gchar *tmpname;
- FILE *f;
*data = NULL;
- if ((f = fdopen(g_file_open_tmp (NULL, &tmpname, NULL), "r+"))) {
- a_gpx_write_file(vtl, f, NULL);
- vik_layer_marshall_params(VIK_LAYER(vtl), &pd, &pl);
- fclose(f);
- f = NULL;
- g_file_get_contents(tmpname, &dd, &dl, NULL);
- *len = sizeof(pl) + pl + dl;
- *data = g_malloc(*len);
- memcpy(*data, &pl, sizeof(pl));
- memcpy(*data + sizeof(pl), pd, pl);
- memcpy(*data + sizeof(pl) + pl, dd, dl);
-
- g_free(pd);
- g_free(dd);
- g_remove(tmpname);
- g_free(tmpname);
+ // Use byte arrays to store sublayer data
+ // much like done elsewhere e.g. vik_layer_marshall_params()
+ GByteArray *ba = g_byte_array_new ( );
+
+ guint8 *sl_data;
+ guint sl_len;
+
+ guint object_length;
+ guint subtype;
+ // store:
+ // the length of the item
+ // the sublayer type of item
+ // the the actual item
+#define tlm_append(object_pointer, size, type) \
+ subtype = (type); \
+ object_length = (size); \
+ g_byte_array_append ( ba, (guint8 *)&object_length, sizeof(object_length) ); \
+ g_byte_array_append ( ba, (guint8 *)&subtype, sizeof(subtype) ); \
+ g_byte_array_append ( ba, (object_pointer), object_length );
+
+ // Layer parameters first
+ vik_layer_marshall_params(VIK_LAYER(vtl), &pd, &pl);
+ g_byte_array_append ( ba, (guint8 *)&pl, sizeof(pl) ); \
+ g_byte_array_append ( ba, pd, pl );
+ g_free ( pd );
+
+ // Now sublayer data
+ GHashTableIter iter;
+ gpointer key, value;
+
+ // Waypoints
+ g_hash_table_iter_init ( &iter, vtl->waypoints );
+ while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+ vik_waypoint_marshall ( VIK_WAYPOINT(value), &sl_data, &sl_len );
+ tlm_append ( sl_data, sl_len, VIK_TRW_LAYER_SUBLAYER_WAYPOINT );
+ g_free ( sl_data );
+ }
+
+ // Tracks
+ g_hash_table_iter_init ( &iter, vtl->tracks );
+ while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+ vik_track_marshall ( VIK_TRACK(value), &sl_data, &sl_len );
+ tlm_append ( sl_data, sl_len, VIK_TRW_LAYER_SUBLAYER_TRACK );
+ g_free ( sl_data );
+ }
+
+ // Routes
+ g_hash_table_iter_init ( &iter, vtl->routes );
+ while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+ vik_track_marshall ( VIK_TRACK(value), &sl_data, &sl_len );
+ tlm_append ( sl_data, sl_len, VIK_TRW_LAYER_SUBLAYER_ROUTE );
+ g_free ( sl_data );
}
+
+#undef tlm_append
+
+ *data = ba->data;
+ *len = ba->len;
}
static VikTrwLayer *trw_layer_unmarshall( guint8 *data, gint len, VikViewport *vvp )
{
- VikTrwLayer *rv = VIK_TRW_LAYER(vik_layer_create ( VIK_LAYER_TRW, vvp, NULL, FALSE ));
+ VikTrwLayer *vtl = VIK_TRW_LAYER(vik_layer_create ( VIK_LAYER_TRW, vvp, NULL, FALSE ));
gint pl;
- gchar *tmpname;
- FILE *f;
-
+ gint consumed_length;
+ // First the overall layer parameters
memcpy(&pl, data, sizeof(pl));
data += sizeof(pl);
- vik_layer_unmarshall_params ( VIK_LAYER(rv), data, pl, vvp );
+ vik_layer_unmarshall_params ( VIK_LAYER(vtl), data, pl, vvp );
data += pl;
- if (!(f = fdopen(g_file_open_tmp (NULL, &tmpname, NULL), "r+"))) {
- g_critical("couldn't open temp file");
- exit(1);
- }
- fwrite(data, len - pl - sizeof(pl), 1, f);
- rewind(f);
- a_gpx_read_file(rv, f);
- fclose(f);
- f = NULL;
- g_remove(tmpname);
- g_free(tmpname);
- return rv;
+ consumed_length = pl;
+ const gint sizeof_len_and_subtype = sizeof(gint) + sizeof(gint);
+
+#define tlm_size (*(gint *)data)
+ // See marshalling above for order of how this is written
+#define tlm_next \
+ data += sizeof_len_and_subtype + tlm_size;
+
+ // Now the individual sublayers:
+
+ while ( *data && consumed_length < len ) {
+ // Normally four extra bytes at the end of the datastream
+ // (since it's a GByteArray and that's where it's length is stored)
+ // So only attempt read when there's an actual block of sublayer data
+ if ( consumed_length + tlm_size < len ) {
+
+ // Reuse pl to read the subtype from the data stream
+ memcpy(&pl, data+sizeof(gint), sizeof(pl));
+
+ if ( pl == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
+ VikTrack *trk = vik_track_unmarshall ( data + sizeof_len_and_subtype, 0 );
+ gchar *name = g_strdup ( trk->name );
+ vik_trw_layer_add_track ( vtl, name, trk );
+ g_free ( name );
+ }
+ if ( pl == VIK_TRW_LAYER_SUBLAYER_WAYPOINT ) {
+ VikWaypoint *wp = vik_waypoint_unmarshall ( data + sizeof_len_and_subtype, 0 );
+ gchar *name = g_strdup ( wp->name );
+ vik_trw_layer_add_waypoint ( vtl, name, wp );
+ g_free ( name );
+ }
+ if ( pl == VIK_TRW_LAYER_SUBLAYER_ROUTE ) {
+ VikTrack *trk = vik_track_unmarshall ( data + sizeof_len_and_subtype, 0 );
+ gchar *name = g_strdup ( trk->name );
+ vik_trw_layer_add_route ( vtl, name, trk );
+ g_free ( name );
+ }
+ }
+ consumed_length += tlm_size + sizeof_len_and_subtype;
+ tlm_next;
+ }
+ //g_debug ("consumed_length %d vs len %d", consumed_length, len);
+
+ return vtl;
}
// Keep interesting hash function at least visible
static VikTrwLayer* trw_layer_new ( gint drawmode )
{
- if (trw_layer_params[PARAM_DM].widget_data == NULL)
- trw_layer_params[PARAM_DM].widget_data = str_array_to_glist(params_drawmodes);
- if (trw_layer_params[PARAM_WPSYM].widget_data == NULL)
- trw_layer_params[PARAM_WPSYM].widget_data = str_array_to_glist(params_wpsymbols);
-
VikTrwLayer *rv = VIK_TRW_LAYER ( g_object_new ( VIK_TRW_LAYER_TYPE, NULL ) );
vik_layer_set_type ( VIK_LAYER(rv), VIK_LAYER_TRW );
rv->routes = g_hash_table_new_full ( g_direct_hash, g_direct_equal, NULL, (GDestroyNotify) vik_track_free );
rv->routes_iters = g_hash_table_new_full ( g_direct_hash, g_direct_equal, NULL, g_free );
- /* TODO: constants at top */
+ // Default values
rv->waypoints_visible = rv->tracks_visible = rv->routes_visible = TRUE;
rv->drawmode = drawmode;
rv->drawpoints = TRUE;
rv->drawpoints_size = MIN_POINT_SIZE;
rv->drawdirections_size = 5;
- rv->drawstops = FALSE;
- rv->drawelevation = FALSE;
rv->elevation_factor = 30;
rv->stop_length = 60;
rv->drawlines = TRUE;
- rv->wplabellayout = NULL;
- rv->wp_right_click_menu = NULL;
- rv->track_right_click_menu = NULL;
- rv->waypoint_gc = NULL;
- rv->waypoint_text_gc = NULL;
- rv->waypoint_bg_gc = NULL;
- rv->track_gc = NULL;
rv->track_draw_speed_factor = 30.0;
rv->line_thickness = 1;
- rv->bg_line_thickness = 0;
- rv->current_wp = NULL;
- rv->current_wp_id = NULL;
- rv->current_track = NULL;
- rv->current_tpl = NULL;
- rv->current_tp_track = NULL;
- rv->current_tp_id = NULL;
- rv->moving_tp = FALSE;
- rv->moving_wp = FALSE;
rv->draw_sync_done = TRUE;
rv->draw_sync_do = TRUE;
- rv->route_finder_started = FALSE;
- rv->route_finder_check_added_track = FALSE;
- rv->route_finder_current_track = NULL;
- rv->route_finder_append = FALSE;
-
- rv->waypoint_rightclick = FALSE;
- rv->tpwin = NULL;
rv->image_cache = g_queue_new();
rv->image_size = 64;
rv->image_alpha = 255;
rv->image_cache_size = 300;
rv->drawimages = TRUE;
rv->drawlabels = TRUE;
+ // Everything else is 0, FALSE or NULL
+
return rv;
}
{
dp->vtl = vtl;
dp->vp = vp;
+ dp->vw = (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl);
dp->xmpp = vik_viewport_get_xmpp ( vp );
dp->ympp = vik_viewport_get_ympp ( vp );
dp->width = vik_viewport_get_width ( vp );
dp->height = vik_viewport_get_height ( vp );
- dp->cc = vtl->drawdirections_size*cos(45 * DEG2RAD); // Calculate once per vtl update - even if not used
- dp->ss = vtl->drawdirections_size*sin(45 * DEG2RAD); // Calculate once per vtl update - even if not used
+ dp->cc = vtl->drawdirections_size*cos(DEG2RAD(45)); // Calculate once per vtl update - even if not used
+ dp->ss = vtl->drawdirections_size*sin(DEG2RAD(45)); // Calculate once per vtl update - even if not used
dp->center = vik_viewport_get_center ( vp );
dp->one_zone = vik_viewport_is_one_zone ( vp ); /* false if some other projection besides UTM */
dp->cn1 = bottomright.north_south;
dp->cn2 = upperleft.north_south;
}
-
- dp->track_gc_iter = 0;
}
/*
vik_viewport_draw_line ( vvp, gc, x+5, y-5, x-5, y+5 );
}
-static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct DrawingParams *dp, gboolean draw_track_outline )
+static void trw_layer_draw_track ( const gpointer id, VikTrack *track, struct DrawingParams *dp, gboolean draw_track_outline )
{
/* TODO: this function is a mess, get rid of any redundancy */
GList *list = track->trackpoints;
/* admittedly this is not an efficient way to do it because we go through the whole GC thing all over... */
if ( dp->vtl->bg_line_thickness && !draw_track_outline )
- trw_layer_draw_track ( name, track, dp, TRUE );
+ trw_layer_draw_track ( id, track, dp, TRUE );
if ( draw_track_outline )
drawpoints = drawstops = FALSE;
/* if track is member of selected layer or is the current selected track
then draw in the highlight colour.
NB this supercedes the drawmode */
- if ( dp->vtl && ( ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ||
- ( !track->is_route && ( dp->vtl->tracks == vik_window_get_selected_tracks ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) ||
- ( track->is_route && ( dp->vtl->routes == vik_window_get_selected_tracks ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) ||
- track == vik_window_get_selected_track ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) ) {
+ if ( ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) ) ||
+ ( !track->is_route && ( dp->vtl->tracks == vik_window_get_selected_tracks ( dp->vw ) ) ) ||
+ ( track->is_route && ( dp->vtl->routes == vik_window_get_selected_tracks ( dp->vw ) ) ) ||
+ ( track == vik_window_get_selected_track ( dp->vw ) ) ) {
main_gc = vik_viewport_get_gc_highlight (dp->vp);
drawing_highlight = TRUE;
}
- else {
- if ( dp->vtl->drawmode == DRAWMODE_ALL_BLACK )
- dp->track_gc_iter = VIK_TRW_LAYER_TRACK_GC_BLACK;
-
- main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter);
- }
}
- else {
- if ( dp->vtl->drawmode == DRAWMODE_ALL_BLACK )
- dp->track_gc_iter = VIK_TRW_LAYER_TRACK_GC_BLACK;
-
- main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter);
+ if ( !drawing_highlight ) {
+ // Still need to figure out the gc according to the drawing mode:
+ switch ( dp->vtl->drawmode ) {
+ case DRAWMODE_BY_TRACK:
+ if ( dp->vtl->track_1color_gc )
+ g_object_unref ( dp->vtl->track_1color_gc );
+ dp->vtl->track_1color_gc = vik_viewport_new_gc_from_color ( dp->vp, &track->color, dp->vtl->line_thickness );
+ main_gc = dp->vtl->track_1color_gc;
+ break;
+ default:
+ // Mostly for DRAWMODE_ALL_SAME_COLOR
+ // but includes DRAWMODE_BY_SPEED, main_gc is set later on as necessary
+ main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, VIK_TRW_LAYER_TRACK_GC_SINGLE);
+ break;
+ }
}
}
vik_viewport_coord_to_screen ( dp->vp, &(tp->coord), &x, &y );
- if ( (drawpoints) && dp->track_gc_iter < VIK_TRW_LAYER_TRACK_GC )
- {
+ // Draw the first point as something a bit different from the normal points
+ // ATM it's slightly bigger and a triangle
+ if ( drawpoints ) {
GdkPoint trian[3] = { { x, y-(3*tp_size) }, { x-(2*tp_size), y+(2*tp_size) }, {x+(2*tp_size), y+(2*tp_size)} };
vik_viewport_draw_polygon ( dp->vp, main_gc, TRUE, trian, 3 );
}
if ( drawpoints || dp->vtl->drawlines ) {
// setup main_gc for both point and line drawing
if ( !drawing_highlight && (dp->vtl->drawmode == DRAWMODE_BY_SPEED) ) {
- dp->track_gc_iter = track_section_colour_by_speed ( dp->vtl, tp, tp2, average_speed, low_speed, high_speed );
- main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter);
+ main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, track_section_colour_by_speed ( dp->vtl, tp, tp2, average_speed, low_speed, high_speed ) );
}
}
*/
/* stops */
if ( drawstops && VIK_TRACKPOINT(list->next->data)->timestamp - VIK_TRACKPOINT(list->data)->timestamp > dp->vtl->stop_length )
- /* Stop point. Draw 6x circle. */
- vik_viewport_draw_arc ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, 11), TRUE, x-(3*tp_size), y-(3*tp_size), 6*tp_size, 6*tp_size, 0, 360*64 );
+ /* Stop point. Draw 6x circle. Always in redish colour */
+ vik_viewport_draw_arc ( dp->vp, g_array_index(dp->vtl->track_gc, GdkGC *, VIK_TRW_LAYER_TRACK_GC_STOP), TRUE, x-(3*tp_size), y-(3*tp_size), 6*tp_size, 6*tp_size, 0, 360*64 );
/* Regular point - draw 2x square. */
vik_viewport_draw_rectangle ( dp->vp, main_gc, TRUE, x-tp_size, y-tp_size, 2*tp_size, 2*tp_size );
vik_viewport_coord_to_screen ( dp->vp, &(tp->coord), &x, &y );
if ( !drawing_highlight && (dp->vtl->drawmode == DRAWMODE_BY_SPEED) ) {
- dp->track_gc_iter = track_section_colour_by_speed ( dp->vtl, tp, tp2, average_speed, low_speed, high_speed );
- main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, dp->track_gc_iter);
+ main_gc = g_array_index(dp->vtl->track_gc, GdkGC *, track_section_colour_by_speed ( dp->vtl, tp, tp2, average_speed, low_speed, high_speed ));
}
/*
}
}
}
- if ( dp->vtl->drawmode == DRAWMODE_BY_TRACK )
- if ( ++(dp->track_gc_iter) >= VIK_TRW_LAYER_TRACK_GC_MAX )
- dp->track_gc_iter = 0;
}
/* the only reason this exists is so that trw_layer_draw_track can first call itself to draw the white track background */
-static void trw_layer_draw_track_cb ( const gchar *name, VikTrack *track, struct DrawingParams *dp )
+static void trw_layer_draw_track_cb ( const gpointer id, VikTrack *track, struct DrawingParams *dp )
{
- trw_layer_draw_track ( name, track, dp, FALSE );
+ trw_layer_draw_track ( id, track, dp, FALSE );
}
static void cached_pixbuf_free ( CachedPixbuf *cp )
return strcmp ( cp->image, name );
}
-static void trw_layer_draw_waypoint ( const gchar *name, VikWaypoint *wp, struct DrawingParams *dp )
+static void trw_layer_draw_waypoint ( const gpointer id, VikWaypoint *wp, struct DrawingParams *dp )
{
if ( wp->visible )
if ( (!dp->one_zone && !dp->lat_lon) || ( ( dp->lat_lon || wp->coord.utm_zone == dp->center->utm_zone ) &&
if ( x+(w/2) > 0 && y+(h/2) > 0 && x-(w/2) < dp->width && y-(h/2) < dp->height ) /* always draw within boundaries */
{
if ( vik_viewport_get_draw_highlight ( dp->vp ) ) {
- if ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
- dp->vtl->waypoints == vik_window_get_selected_waypoints ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
- wp == vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ) {
+ if ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) ||
+ dp->vtl->waypoints == vik_window_get_selected_waypoints ( dp->vw ) ||
+ wp == vik_window_get_selected_waypoint ( dp->vw ) ) {
// Highlighted - so draw a little border around the chosen one
// single line seems a little weak so draw 2 of them
vik_viewport_draw_rectangle (dp->vp, vik_viewport_get_gc_highlight (dp->vp), FALSE,
/* if highlight mode on, then draw background text in highlight colour */
if ( vik_viewport_get_draw_highlight ( dp->vp ) ) {
- if ( dp->vtl == vik_window_get_selected_trw_layer ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
- dp->vtl->waypoints == vik_window_get_selected_waypoints ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) ||
- wp == vik_window_get_selected_waypoint ( (VikWindow *)VIK_GTK_WINDOW_FROM_LAYER(dp->vtl) ) )
+ if ( dp->vtl == vik_window_get_selected_trw_layer ( dp->vw ) ||
+ dp->vtl->waypoints == vik_window_get_selected_waypoints ( dp->vw ) ||
+ wp == vik_window_get_selected_waypoint ( dp->vw ) )
vik_viewport_draw_rectangle ( dp->vp, vik_viewport_get_gc_highlight (dp->vp), TRUE, label_x - 1, label_y-1,width+2,height+2);
else
vik_viewport_draw_rectangle ( dp->vp, dp->vtl->waypoint_bg_gc, TRUE, label_x - 1, label_y-1,width+2,height+2);
g_object_unref ( vtl->track_bg_gc );
vtl->track_bg_gc = NULL;
}
+ if ( vtl->track_1color_gc )
+ {
+ g_object_unref ( vtl->track_1color_gc );
+ vtl->track_1color_gc = NULL;
+ }
if ( vtl->current_track_gc )
{
g_object_unref ( vtl->current_track_gc );
vtl->track_gc = g_array_sized_new ( FALSE, FALSE, sizeof ( GdkGC * ), VIK_TRW_LAYER_TRACK_GC );
- gc[0] = vik_viewport_new_gc ( vp, "#2d870a", width ); /* below range */
-
- gc[1] = vik_viewport_new_gc ( vp, "#0a8742", width );
- gc[2] = vik_viewport_new_gc ( vp, "#0a8783", width );
- gc[3] = vik_viewport_new_gc ( vp, "#0a4d87", width );
- gc[4] = vik_viewport_new_gc ( vp, "#05469f", width );
- gc[5] = vik_viewport_new_gc ( vp, "#1b059f", width );
- gc[6] = vik_viewport_new_gc ( vp, "#2d059f", width );
- gc[7] = vik_viewport_new_gc ( vp, "#4a059f", width );
- gc[8] = vik_viewport_new_gc ( vp, "#84059f", width );
- gc[9] = vik_viewport_new_gc ( vp, "#96059f", width );
- gc[10] = vik_viewport_new_gc ( vp, "#f22ef2", width );
-
- gc[11] = vik_viewport_new_gc ( vp, "#874200", width ); /* above range */
-
- gc[12] = vik_viewport_new_gc ( vp, "#000000", width ); /* black / no speed data */
+ gc[VIK_TRW_LAYER_TRACK_GC_STOP] = vik_viewport_new_gc ( vp, "#874200", width );
+ gc[VIK_TRW_LAYER_TRACK_GC_BLACK] = vik_viewport_new_gc ( vp, "#000000", width ); // black
gc[VIK_TRW_LAYER_TRACK_GC_SLOW] = vik_viewport_new_gc ( vp, "#E6202E", width ); // red-ish
gc[VIK_TRW_LAYER_TRACK_GC_AVER] = vik_viewport_new_gc ( vp, "#D2CD26", width ); // yellow-ish
gc[VIK_TRW_LAYER_TRACK_GC_FAST] = vik_viewport_new_gc ( vp, "#2B8700", width ); // green-ish
+ gc[VIK_TRW_LAYER_TRACK_GC_SINGLE] = vik_viewport_new_gc_from_color ( vp, &(vtl->track_color), width );
+
g_array_append_vals ( vtl->track_gc, gc, VIK_TRW_LAYER_TRACK_GC );
}
rv->wplabellayout = gtk_widget_create_pango_layout (GTK_WIDGET(vp), NULL);
pango_layout_set_font_description (rv->wplabellayout, GTK_WIDGET(vp)->style->font_desc);
+ gdk_color_parse ( "#000000", &(rv->track_color) ); // Black
+
trw_layer_new_track_gcs ( rv, vp );
rv->waypoint_gc = vik_viewport_new_gc ( vp, "#000000", 2 );
return rv;
}
+#define SMALL_ICON_SIZE 18
+/*
+ * Can accept a null symbol, and may return null value
+ */
+static GdkPixbuf* get_wp_sym_small ( gchar *symbol )
+{
+ GdkPixbuf* wp_icon = a_get_wp_sym (symbol);
+ // ATM a_get_wp_sym returns a cached icon, with the size dependent on the preferences.
+ // So needing a small icon for the treeview may need some resizing:
+ if ( wp_icon && gdk_pixbuf_get_width ( wp_icon ) != SMALL_ICON_SIZE )
+ wp_icon = gdk_pixbuf_scale_simple ( wp_icon, SMALL_ICON_SIZE, SMALL_ICON_SIZE, GDK_INTERP_BILINEAR );
+ return wp_icon;
+}
+
static void trw_layer_realize_track ( gpointer id, VikTrack *track, gpointer pass_along[5] )
{
GtkTreeIter *new_iter = g_malloc(sizeof(GtkTreeIter));
+ GdkPixbuf *pixbuf = NULL;
+
+ if ( track->has_color ) {
+ pixbuf = gdk_pixbuf_new ( GDK_COLORSPACE_RGB, FALSE, 8, SMALL_ICON_SIZE, SMALL_ICON_SIZE );
+ // Annoyingly the GdkColor.pixel does not give the correct color when passed to gdk_pixbuf_fill (even when alloc'ed)
+ // Here is some magic found to do the conversion
+ // http://www.cs.binghamton.edu/~sgreene/cs360-2011s/topics/gtk+-2.20.1/gtk/gtkcolorbutton.c
+ guint32 pixel = ((track->color.red & 0xff00) << 16) |
+ ((track->color.green & 0xff00) << 8) |
+ (track->color.blue & 0xff00);
+
+ gdk_pixbuf_fill ( pixbuf, pixel );
+ }
+
#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], track->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), NULL, TRUE, TRUE );
+ vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], track->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), pixbuf, TRUE, TRUE );
#else
- vik_treeview_add_sublayer ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], track->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), NULL, TRUE, TRUE );
+ vik_treeview_add_sublayer ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], track->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), pixbuf, TRUE, TRUE );
#endif
+ if ( pixbuf )
+ g_object_unref (pixbuf);
+
*new_iter = *((GtkTreeIter *) pass_along[1]);
if ( track->is_route )
g_hash_table_insert ( VIK_TRW_LAYER(pass_along[2])->routes_iters, id, new_iter );
static void trw_layer_realize_waypoint ( gpointer id, VikWaypoint *wp, gpointer pass_along[5] )
{
GtkTreeIter *new_iter = g_malloc(sizeof(GtkTreeIter));
+
#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], wp->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), NULL, TRUE, TRUE );
+ vik_treeview_add_sublayer_alphabetized ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], wp->name, pass_along[2], id, GPOINTER_TO_INT (pass_along[4]), get_wp_sym_small (wp->symbol), TRUE, TRUE );
#else
- vik_treeview_add_sublayer ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], wp->name, pass_along[2], id, GPOINTER_TO_UINT (pass_along[4]), NULL, TRUE, TRUE );
+ vik_treeview_add_sublayer ( (VikTreeview *) pass_along[3], (GtkTreeIter *) pass_along[0], (GtkTreeIter *) pass_along[1], wp->name, pass_along[2], id, GPOINTER_TO_UINT (pass_along[4]), get_wp_sym_small (wp->symbol), TRUE, TRUE );
#endif
*new_iter = *((GtkTreeIter *) pass_along[1]);
return g_hash_table_find ( vtl->routes, (GHRFunc) trw_layer_track_find, (gpointer) name );
}
-static void trw_layer_find_maxmin_waypoints ( const gchar *name, const VikWaypoint *w, struct LatLon maxmin[2] )
+static void trw_layer_find_maxmin_waypoints ( const gpointer id, const VikWaypoint *w, struct LatLon maxmin[2] )
{
static VikCoord fixme;
vik_coord_copy_convert ( &(w->coord), VIK_COORD_LATLON, &fixme );
maxmin[1].lon = VIK_LATLON(&fixme)->lon;
}
-static void trw_layer_find_maxmin_tracks ( const gchar *name, const VikTrack *trk, struct LatLon maxmin[2] )
+static void trw_layer_find_maxmin_tracks ( const gpointer id, const VikTrack *trk, struct LatLon maxmin[2] )
{
GList *tr = trk->trackpoints;
static VikCoord fixme;
static void trw_layer_new_wikipedia_wp_viewport ( gpointer lav[2] )
{
- VikCoord one, two;
- struct LatLon one_ll, two_ll;
struct LatLon maxmin[2] = { {0.0,0.0}, {0.0,0.0} };
-
VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
VikViewport *vvp = vik_window_viewport(vw);
- vik_viewport_screen_to_coord ( vvp, 0, 0, &one);
- vik_viewport_screen_to_coord ( vvp, vik_viewport_get_width(vvp), vik_viewport_get_height(vvp), &two);
- vik_coord_to_latlon(&one, &one_ll);
- vik_coord_to_latlon(&two, &two_ll);
- if (one_ll.lat > two_ll.lat) {
- maxmin[0].lat = one_ll.lat;
- maxmin[1].lat = two_ll.lat;
- }
- else {
- maxmin[0].lat = two_ll.lat;
- maxmin[1].lat = one_ll.lat;
- }
- if (one_ll.lon > two_ll.lon) {
- maxmin[0].lon = one_ll.lon;
- maxmin[1].lon = two_ll.lon;
- }
- else {
- maxmin[0].lon = two_ll.lon;
- maxmin[1].lon = one_ll.lon;
- }
- a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, vlp, maxmin);
+
+ // Note the order is max part first then min part - thus reverse order of use in min_max function:
+ vik_viewport_get_min_max_lat_lon ( vvp, &maxmin[1].lat, &maxmin[0].lat, &maxmin[1].lon, &maxmin[0].lon );
+ a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, maxmin);
+ vik_layers_panel_emit_update ( vlp );
}
static void trw_layer_new_wikipedia_wp_layer ( gpointer lav[2] )
struct LatLon maxmin[2] = { {0.0,0.0}, {0.0,0.0} };
trw_layer_find_maxmin (vtl, maxmin);
- a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, vlp, maxmin);
+ a_geonames_wikipedia_box((VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl)), vtl, maxmin);
+ vik_layers_panel_emit_update ( vlp );
}
#ifdef VIK_CONFIG_GEOTAG
a_acquire ( vw, vlp, vvp, &vik_datasource_osm_interface );
}
+
+/**
+ * Acquire into this TRW Layer from OSM for 'My' Traces
+ */
+static void trw_layer_acquire_osm_my_traces_cb ( gpointer lav[2] )
+{
+ VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
+ VikLayersPanel *vlp = VIK_LAYERS_PANEL(lav[1]);
+ VikWindow *vw = (VikWindow *)(VIK_GTK_WINDOW_FROM_LAYER(vtl));
+ VikViewport *vvp = vik_window_viewport(vw);
+
+ a_acquire ( vw, vlp, vvp, &vik_datasource_osm_my_traces_interface );
+}
#endif
#ifdef VIK_CONFIG_GEOCACHES
vik_layers_panel_emit_update ( vlp );
}
+static void new_track_create_common ( VikTrwLayer *vtl, gchar *name )
+{
+ vtl->current_track = vik_track_new();
+ vtl->current_track->visible = TRUE;
+ if ( vtl->drawmode == DRAWMODE_ALL_SAME_COLOR )
+ // Create track with the preferred colour from the layer properties
+ vtl->current_track->color = vtl->track_color;
+ else
+ gdk_color_parse ( "#000000", &(vtl->current_track->color) );
+ vtl->current_track->has_color = TRUE;
+ vik_trw_layer_add_track ( vtl, name, vtl->current_track );
+}
+
static void trw_layer_new_track ( gpointer lav[2] )
{
VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
if ( ! vtl->current_track ) {
gchar *name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, _("Track")) ;
- vtl->current_track = vik_track_new();
- vtl->current_track->visible = TRUE;
- vik_trw_layer_add_track ( vtl, name, vtl->current_track );
+ new_track_create_common ( vtl, name );
vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK );
}
}
+static void new_route_create_common ( VikTrwLayer *vtl, gchar *name )
+{
+ vtl->current_track = vik_track_new();
+ vtl->current_track->visible = TRUE;
+ vtl->current_track->is_route = TRUE;
+ // By default make all routes red
+ vtl->current_track->has_color = TRUE;
+ gdk_color_parse ( "red", &vtl->current_track->color );
+ vik_trw_layer_add_route ( vtl, name, vtl->current_track );
+}
+
static void trw_layer_new_route ( gpointer lav[2] )
{
VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
if ( ! vtl->current_track ) {
gchar *name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, _("Route")) ;
- vtl->current_track = vik_track_new();
- vtl->current_track->visible = TRUE;
- vtl->current_track->is_route = TRUE;
- vik_trw_layer_add_route ( vtl, name, vtl->current_track );
-
- vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK );// CREATE_ROUTE??
+ new_route_create_common ( vtl, name );
+ vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_ROUTE );
}
}
{
VikTrwLayer *vtl = VIK_TRW_LAYER(lav[0]);
vtl->current_track = NULL;
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
static void trw_layer_auto_tracks_view ( gpointer lav[2] )
}
}
-static void trw_layer_single_waypoint_jump ( const gchar *name, const VikWaypoint *wp, gpointer vvp )
+static void trw_layer_single_waypoint_jump ( const gpointer id, const VikWaypoint *wp, gpointer vvp )
{
/* NB do not care if wp is visible or not */
vik_viewport_set_center_coord ( VIK_VIEWPORT(vvp), &(wp->coord) );
// Make it available only when a new track *not* already in progress
gtk_widget_set_sensitive ( item, ! (gboolean)GPOINTER_TO_INT(vtl->current_track) );
-#ifdef VIK_CONFIG_GEONAMES
- GtkWidget *wikipedia_submenu = gtk_menu_new();
- item = gtk_image_menu_item_new_with_mnemonic ( _("_Add Wikipedia Waypoints") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU) );
- gtk_menu_shell_append(GTK_MENU_SHELL (menu), item);
- gtk_widget_show(item);
- gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), wikipedia_submenu);
-
- item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Layer Bounds") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_FIT, GTK_ICON_SIZE_MENU) );
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_layer), pass_along );
- gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item);
- gtk_widget_show ( item );
-
- item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Current View") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_100, GTK_ICON_SIZE_MENU) );
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_viewport), pass_along );
- gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item);
- gtk_widget_show ( item );
-#endif
-
#ifdef VIK_CONFIG_GEOTAG
item = gtk_menu_item_new_with_mnemonic ( _("Geotag _Images...") );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_geotagging), pass_along );
#endif
GtkWidget *acquire_submenu = gtk_menu_new ();
- item = gtk_image_menu_item_new_with_mnemonic ( _("Ac_quire") );
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Acquire") );
gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_DOWN, GTK_ICON_SIZE_MENU) );
gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
gtk_widget_show ( item );
gtk_widget_show ( item );
#ifdef VIK_CONFIG_GOOGLE
- item = gtk_menu_item_new_with_mnemonic ( _("From G_oogle Directions...") );
+ item = gtk_menu_item_new_with_mnemonic ( _("From Google _Directions...") );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_google_cb), pass_along );
gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
gtk_widget_show ( item );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_osm_cb), pass_along );
gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
gtk_widget_show ( item );
+
+ item = gtk_menu_item_new_with_mnemonic ( _("From _My OSM Traces...") );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_acquire_osm_my_traces_cb), pass_along );
+ gtk_menu_shell_append (GTK_MENU_SHELL (acquire_submenu), item);
+ gtk_widget_show ( item );
+#endif
+
+#ifdef VIK_CONFIG_GEONAMES
+ GtkWidget *wikipedia_submenu = gtk_menu_new();
+ item = gtk_image_menu_item_new_with_mnemonic ( _("From _Wikipedia Waypoints") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_MENU) );
+ gtk_menu_shell_append(GTK_MENU_SHELL (acquire_submenu), item);
+ gtk_widget_show(item);
+ gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), wikipedia_submenu);
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Layer Bounds") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_FIT, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_layer), pass_along );
+ gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item);
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Within _Current View") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_ZOOM_100, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_new_wikipedia_wp_viewport), pass_along );
+ gtk_menu_shell_append (GTK_MENU_SHELL (wikipedia_submenu), item);
+ gtk_widget_show ( item );
#endif
#ifdef VIK_CONFIG_GEOCACHES
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_tracks_from_selection), pass_along );
gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Delete _All Routes") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_all_routes), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
+ gtk_widget_show ( item );
+
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_Delete Routes From Selection...") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_delete_routes_from_selection), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(delete_submenu), item );
+ gtk_widget_show ( item );
item = gtk_image_menu_item_new_with_mnemonic ( _("Delete All _Waypoints") );
gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU) );
// Visibility column always needed for waypoints
#ifdef VIK_CONFIG_ALPHABETIZED_TRW
- vik_treeview_add_sublayer_alphabetized ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), iter, name, vtl, GUINT_TO_POINTER(wp_uuid), VIK_TRW_LAYER_SUBLAYER_WAYPOINT, NULL, TRUE, TRUE );
+ vik_treeview_add_sublayer_alphabetized ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), iter, name, vtl, GUINT_TO_POINTER(wp_uuid), VIK_TRW_LAYER_SUBLAYER_WAYPOINT, get_wp_sym_small (wp->symbol), TRUE, TRUE );
#else
- vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), iter, name, vtl, GUINT_TO_POINTER(wp_uuid), VIK_TRW_LAYER_SUBLAYER_WAYPOINT, NULL, TRUE, TRUE );
+ vik_treeview_add_sublayer ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter), iter, name, vtl, GUINT_TO_POINTER(wp_uuid), VIK_TRW_LAYER_SUBLAYER_WAYPOINT, get_wp_sym_small (wp->symbol), TRUE, TRUE );
#endif
// Actual setting of visibility dependent on the waypoint
vik_treeview_item_set_visible ( VIK_LAYER(vtl)->vt, iter, wp->visible );
}
g_hash_table_insert ( vtl->tracks, GUINT_TO_POINTER(tr_uuid), t );
-
+
+ trw_layer_update_treeview ( vtl, t, GUINT_TO_POINTER(tr_uuid) );
}
// Fake Route UUIDs vi simple increasing integer
g_hash_table_insert ( vtl->routes, GUINT_TO_POINTER(rt_uuid), t );
+ trw_layer_update_treeview ( vtl, t, GUINT_TO_POINTER(rt_uuid) );
}
/* to be called whenever a track has been deleted or may have been changed. */
gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, trk->name);
- VikTrack *trk2 = vik_track_copy ( trk );
+ VikTrack *trk2 = vik_track_copy ( trk, TRUE );
vik_trw_layer_add_track ( vtl_dest, newname, trk2 );
vik_trw_layer_delete_track ( vtl_src, trk );
}
gchar *newname = trw_layer_new_unique_sublayer_name(vtl_dest, type, trk->name);
- VikTrack *trk2 = vik_track_copy ( trk );
+ VikTrack *trk2 = vik_track_copy ( trk, TRUE );
vik_trw_layer_add_route ( vtl_dest, newname, trk2 );
vik_trw_layer_delete_route ( vtl_src, trk );
}
return FALSE;
}
-static void remove_item_from_treeview(const gchar *name, GtkTreeIter *it, VikTreeview * vt)
+static void remove_item_from_treeview ( const gpointer id, GtkTreeIter *it, VikTreeview * vt )
{
vik_treeview_item_delete (vt, it );
}
vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->routes_iter) );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
void vik_trw_layer_delete_all_tracks ( VikTrwLayer *vtl )
vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->tracks_iter) );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
void vik_trw_layer_delete_all_waypoints ( VikTrwLayer *vtl )
vik_treeview_item_delete ( VIK_LAYER(vtl)->vt, &(vtl->waypoints_iter) );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
static void trw_layer_delete_all_tracks ( gpointer lav[2] )
}
}
if ( was_visible )
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
gboolean updated = FALSE;
a_dialog_waypoint ( VIK_GTK_WINDOW_FROM_LAYER(vtl), wp->name, wp, vtl->coord_mode, FALSE, &updated );
+ if ( updated && wp->symbol && pass_along[6] )
+ vik_treeview_item_set_icon ( VIK_LAYER(vtl)->vt, pass_along[6], get_wp_sym_small (wp->symbol) );
+
if ( updated && VIK_LAYER(vtl)->visible )
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
}
else
if ( tr && tr->name )
{
vik_trw_layer_propwin_run ( VIK_GTK_WINDOW_FROM_LAYER(vtl),
- vtl, tr,
+ vtl,
+ tr,
pass_along[1], /* vlp */
- pass_along[5] ); /* vvp */
+ pass_along[5], /* vvp */
+ pass_along[6]); /* iter */
}
}
}
+/*
+ * Update the treeview of the track id - primarily to update the icon
+ */
+void trw_layer_update_treeview ( VikTrwLayer *vtl, VikTrack *trk, gpointer *trk_id )
+{
+ trku_udata udata;
+ udata.trk = trk;
+ udata.uuid = NULL;
+
+ gpointer *trkf = NULL;
+ if ( trk->is_route )
+ trkf = g_hash_table_find ( vtl->routes, (GHRFunc) trw_layer_track_find_uuid, &udata );
+ else
+ trkf = g_hash_table_find ( vtl->tracks, (GHRFunc) trw_layer_track_find_uuid, &udata );
+
+ if ( trkf && udata.uuid ) {
+
+ GtkTreeIter *iter = NULL;
+ if ( trk->is_route )
+ iter = g_hash_table_lookup ( vtl->routes_iters, udata.uuid );
+ else
+ iter = g_hash_table_lookup ( vtl->tracks_iters, udata.uuid );
+
+ if ( iter ) {
+ // TODO: Make this a function
+ GdkPixbuf *pixbuf = gdk_pixbuf_new ( GDK_COLORSPACE_RGB, FALSE, 8, 18, 18);
+ guint32 pixel = ((trk->color.red & 0xff00) << 16) |
+ ((trk->color.green & 0xff00) << 8) |
+ (trk->color.blue & 0xff00);
+ gdk_pixbuf_fill ( pixbuf, pixel );
+ vik_treeview_item_set_icon ( VIK_LAYER(vtl)->vt, iter, pixbuf );
+ g_object_unref (pixbuf);
+ }
+
+ }
+}
+
/*
Parameter 1 -> VikLayersPanel
Parameter 2 -> VikLayer
/* since vlp not set, vl & vvp should be valid instead! */
if ( vl && vvp ) {
vik_viewport_set_center_coord ( VIK_VIEWPORT(vvp), coord );
- vik_layer_emit_update ( VIK_LAYER(vl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vl) );
}
}
}
}
// Copy it
- VikTrack *trk_copy = vik_track_copy ( trk );
+ VikTrack *trk_copy = vik_track_copy ( trk, TRUE );
// Convert
trk_copy->is_route = !trk_copy->is_route;
g_free ( name );
// Update in case color of track / route changes when moving between sublayers
- vik_layer_emit_update ( VIK_LAYER(pass_along[0]), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
}
return;
vtl->current_track = track;
- vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK);
+ vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, track->is_route ? TOOL_CREATE_ROUTE : TOOL_CREATE_TRACK);
if ( track->trackpoints )
goto_coord ( pass_along[1], pass_along[0], pass_along[5], &(((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord) );
static void trw_layer_extend_track_end_route_finder ( gpointer pass_along[6] )
{
VikTrwLayer *vtl = VIK_TRW_LAYER(pass_along[0]);
- VikTrack *track = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] );
+ VikTrack *track = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->routes, pass_along[3] );
+ if ( !track )
+ return;
VikCoord last_coord = (((VikTrackpoint *)g_list_last(track->trackpoints)->data)->coord);
- vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, NUM_TOOLS );
+ vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_ROUTE_FINDER );
vtl->route_finder_coord = last_coord;
vtl->route_finder_current_track = track;
vtl->route_finder_started = TRUE;
if ( pass_along[1] )
vik_layers_panel_emit_update ( VIK_LAYERS_PANEL(pass_along[1]) );
else
- vik_layer_emit_update ( VIK_LAYER(pass_along[0]), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
}
}
for (l = merge_list; l != NULL; l = g_list_next(l))
g_free(l->data);
g_list_free(merge_list);
- vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update( VIK_LAYER(vtl) );
}
}
for (l = append_list; l != NULL; l = g_list_next(l))
g_free(l->data);
g_list_free(append_list);
- vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update( VIK_LAYER(vtl) );
}
}
for (l = append_list; l != NULL; l = g_list_next(l))
g_free(l->data);
g_list_free(append_list);
- vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update( VIK_LAYER(vtl) );
}
}
}
g_list_free(nearby_tracks);
- vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update( VIK_LAYER(vtl) );
}
/**
if ( vtl->current_tpl->next && vtl->current_tpl->prev ) {
gchar *name = trw_layer_new_unique_sublayer_name(vtl, subtype, vtl->current_tp_track->name);
if ( name ) {
- VikTrack *tr = vik_track_new ();
+ VikTrack *tr = vik_track_copy ( vtl->current_tp_track, FALSE );
GList *newglist = g_list_alloc ();
newglist->prev = NULL;
newglist->next = vtl->current_tpl->next;
newglist->data = vik_trackpoint_copy(VIK_TRACKPOINT(vtl->current_tpl->data));
tr->trackpoints = newglist;
- tr->is_route = vtl->current_tp_track->is_route;
- tr->visible = TRUE;
vtl->current_tpl->next->prev = newglist; /* end old track here */
vtl->current_tpl->next = NULL;
else
vtl->current_tp_id = NULL;
- vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+ vik_layer_emit_update(VIK_LAYER(vtl));
}
}
}
gchar *new_tr_name;
VikTrack *tr;
- tr = vik_track_new();
- tr->visible = track->visible;
+ tr = vik_track_copy ( track, FALSE );
tr->trackpoints = (GList *)(iter->data);
new_tr_name = trw_layer_new_unique_sublayer_name ( vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, track->name);
}
// Remove original track and then update the display
vik_trw_layer_delete_track (vtl, track);
- vik_layer_emit_update(VIK_LAYER(pass_along[0]), FALSE);
+ vik_layer_emit_update(VIK_LAYER(pass_along[0]));
}
g_list_free(newlists);
}
gchar *new_tr_name;
VikTrack *tr;
- tr = vik_track_new();
- tr->visible = track->visible;
- tr->is_route = track->is_route;
+ tr = vik_track_copy ( track, FALSE );
tr->trackpoints = (GList *)(iter->data);
if ( track->is_route ) {
vik_trw_layer_delete_route (vtl, track);
else
vik_trw_layer_delete_track (vtl, track);
- vik_layer_emit_update(VIK_LAYER(pass_along[0]), FALSE);
+ vik_layer_emit_update(VIK_LAYER(pass_along[0]));
}
g_list_free(newlists);
}
g_free ( tracks );
// Remove original track
vik_trw_layer_delete_track ( vtl, trk );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
else {
a_dialog_error_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), _("Can not split track as it has no segments"));
g_snprintf(str, 64, tmp_str, removed);
a_dialog_info_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), str);
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
/**
g_snprintf(str, 64, tmp_str, removed);
a_dialog_info_msg (VIK_GTK_WINDOW_FROM_LAYER(vtl), str);
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
}
/**
vik_track_reverse ( track );
- vik_layer_emit_update ( VIK_LAYER(pass_along[0]), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(pass_along[0]) );
}
/**
trw_layer_delete_track_by_name (vtl, l->data, vtl->tracks);
}
g_list_free(delete_list);
- vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update( VIK_LAYER(vtl) );
}
}
trw_layer_delete_track_by_name (vtl, l->data, vtl->routes);
}
g_list_free(delete_list);
- vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update( VIK_LAYER(vtl) );
}
}
trw_layer_delete_waypoint_by_name (vtl, l->data);
}
g_list_free(delete_list);
- vik_layer_emit_update( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update( VIK_LAYER(vtl) );
}
}
static void trw_layer_waypoint_gc_webpage ( gpointer pass_along[6] )
{
- gchar *webpage = g_strdup_printf("http://www.geocaching.com/seek/cache_details.aspx?wp=%s", (gchar *) pass_along[3] );
+ VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
+ if ( !wp )
+ return;
+ gchar *webpage = g_strdup_printf("http://www.geocaching.com/seek/cache_details.aspx?wp=%s", wp->name );
open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), webpage);
g_free ( webpage );
}
+static void trw_layer_waypoint_webpage ( gpointer pass_along[6] )
+{
+ VikWaypoint *wp = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->waypoints, pass_along[3] );
+ if ( !wp )
+ return;
+ if ( !strncmp(wp->comment, "http", 4) ) {
+ open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), wp->comment);
+ } else if ( !strncmp(wp->description, "http", 4) ) {
+ open_url(VIK_GTK_WINDOW_FROM_LAYER(VIK_LAYER(pass_along[0])), wp->description);
+ }
+}
+
static const gchar* trw_layer_sublayer_rename_request ( VikTrwLayer *l, const gchar *newname, gpointer vlp, gint subtype, gpointer sublayer, GtkTreeIter *iter )
{
if ( subtype == VIK_TRW_LAYER_SUBLAYER_WAYPOINT )
if ( wpf ) {
// An existing waypoint has been found with the requested name
if ( ! a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(l),
- _("A waypoint with the name \"%s\" already exists. Really create one with the same name?"),
+ _("A waypoint with the name \"%s\" already exists. Really rename to the same name?"),
newname ) )
return NULL;
}
if ( trkf ) {
// An existing track has been found with the requested name
if ( ! a_dialog_yes_or_no ( VIK_GTK_WINDOW_FROM_LAYER(l),
- _("A track with the name \"%s\" already exists. Really create one with the same name?"),
+ _("A track with the name \"%s\" already exists. Really rename to the same name?"),
newname ) )
return NULL;
}
#ifdef VIK_CONFIG_GOOGLE
static gboolean is_valid_google_route ( VikTrwLayer *vtl, const gpointer track_id )
{
- VikTrack *tr = g_hash_table_lookup ( vtl->tracks, track_id );
+ VikTrack *tr = g_hash_table_lookup ( vtl->routes, track_id );
return ( tr && tr->comment && strlen(tr->comment) > 7 && !strncmp(tr->comment, "from:", 5) );
}
-static void trw_layer_track_google_route_webpage ( gpointer pass_along[6] )
+static void trw_layer_google_route_webpage ( gpointer pass_along[6] )
{
- VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->tracks, pass_along[3] );
+ VikTrack *tr = g_hash_table_lookup ( VIK_TRW_LAYER(pass_along[0])->routes, pass_along[3] );
if ( tr ) {
gchar *escaped = uri_escape ( tr->comment );
gchar *webpage = g_strdup_printf("http://maps.google.com/maps?f=q&hl=en&q=%s", escaped );
#endif
}
+ if ( wp )
+ {
+ if ( ( wp->comment && !strncmp(wp->comment, "http", 4) ) ||
+ ( wp->description && !strncmp(wp->description, "http", 4) )) {
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Visit _Webpage") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_waypoint_webpage), pass_along );
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+ gtk_widget_show ( item );
+ }
+ }
+
}
}
gtk_widget_show ( item );
#ifdef VIK_CONFIG_GOOGLE
- item = gtk_image_menu_item_new_with_mnemonic ( _("Extend _Using Route Finder") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Route Finder", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_extend_track_end_route_finder), pass_along );
- gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
- gtk_widget_show ( item );
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE ) {
+ item = gtk_image_menu_item_new_with_mnemonic ( _("Extend _Using Route Finder") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock ("Route Finder", GTK_ICON_SIZE_MENU) ); // Own icon - see stock_icons in vikwindow.c
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_extend_track_end_route_finder), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
+ }
#endif
// ATM can't upload a single waypoint but can do waypoints to a GPS
}
}
+#ifdef VIK_CONFIG_GOOGLE
+ if ( subtype == VIK_TRW_LAYER_SUBLAYER_ROUTE && is_valid_google_route ( l, sublayer ) )
+ {
+ item = gtk_image_menu_item_new_with_mnemonic ( _("_View Google Directions") );
+ gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) );
+ g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_google_route_webpage), pass_along );
+ gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
+ gtk_widget_show ( item );
+ }
+#endif
+
// Some things aren't usable with routes
if ( subtype == VIK_TRW_LAYER_SUBLAYER_TRACK ) {
#ifdef VIK_CONFIG_OPENSTREETMAP
gtk_widget_show ( item );
#endif
- item = gtk_image_menu_item_new_with_mnemonic ( _("_Upload to GPS...") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_GO_FORWARD, GTK_ICON_SIZE_MENU) );
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_gps_upload_any), pass_along );
- gtk_menu_shell_append ( GTK_MENU_SHELL(upload_submenu), item );
- gtk_widget_show ( item );
-
-#ifdef VIK_CONFIG_GOOGLE
- if ( is_valid_google_route ( l, sublayer ) )
- {
- item = gtk_image_menu_item_new_with_mnemonic ( _("_View Google Directions") );
- gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_NETWORK, GTK_ICON_SIZE_MENU) );
- g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_track_google_route_webpage), pass_along );
- gtk_menu_shell_append ( GTK_MENU_SHELL(menu), item );
- gtk_widget_show ( item );
- }
-#endif
-
item = gtk_image_menu_item_new_with_mnemonic ( _("Use with _Filter") );
gtk_image_menu_item_set_image ( (GtkImageMenuItem*)item, gtk_image_new_from_stock (GTK_STOCK_INDEX, GTK_ICON_SIZE_MENU) );
g_signal_connect_swapped ( G_OBJECT(item), "activate", G_CALLBACK(trw_layer_track_use_with_filter), pass_along );
vtl->current_tpl = NULL;
vtl->current_tp_track = NULL;
vtl->current_tp_id = NULL;
- vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+ vik_layer_emit_update(VIK_LAYER(vtl));
}
}
if ( vtl->current_tp_track )
vik_trw_layer_tpwin_set_tp ( vtl->tpwin, new_tpl, vtl->current_tp_track->name );
- vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+ vik_layer_emit_update(VIK_LAYER(vtl));
}
else
{
{
if ( vtl->current_tp_track )
vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl = vtl->current_tpl->next, vtl->current_tp_track->name );
- vik_layer_emit_update(VIK_LAYER(vtl), FALSE); /* TODO longone: either move or only update if tp is inside drawing window */
+ vik_layer_emit_update(VIK_LAYER(vtl)); /* TODO longone: either move or only update if tp is inside drawing window */
}
else if ( response == VIK_TRW_LAYER_TPWIN_BACK && vtl->current_tpl->prev )
{
if ( vtl->current_tp_track )
vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl = vtl->current_tpl->prev, vtl->current_tp_track->name );
- vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+ vik_layer_emit_update(VIK_LAYER(vtl));
}
else if ( response == VIK_TRW_LAYER_TPWIN_INSERT && vtl->current_tpl->next )
{
trw_layer_insert_tp_after_current_tp ( vtl );
- vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+ vik_layer_emit_update(VIK_LAYER(vtl));
}
else if ( response == VIK_TRW_LAYER_TPWIN_DATA_CHANGED )
- vik_layer_emit_update(VIK_LAYER(vtl), FALSE);
+ vik_layer_emit_update(VIK_LAYER(vtl));
}
static void trw_layer_tpwin_init ( VikTrwLayer *vtl )
vtl->current_wp_id = NULL;
trw_layer_cancel_current_tp ( vtl, FALSE );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
return FALSE;
vtl->current_wp = wp_params.closest_wp;
vtl->current_wp_id = wp_params.closest_wp_id;
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
if ( vtl->tpwin )
vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
}
if ( vtl->tpwin )
vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
}
vtl->current_wp_id = params.closest_wp_id;
/* could make it so don't update if old WP is off screen and new is null but oh well */
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
vtl->current_wp = NULL;
vtl->current_wp_id = NULL;
vtl->waypoint_rightclick = FALSE;
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return FALSE;
}
marker_end_move ( t );
vtl->current_wp->coord = new_coord;
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
/* PUT IN RIGHT PLACE!!! */
return FALSE;
}
-/**** Begin track ***/
-static gpointer tool_begin_track_create ( VikWindow *vw, VikViewport *vvp)
-{
- return vvp;
-}
-
-static gboolean tool_begin_track_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
-{
- vtl->current_track = NULL;
- return tool_new_track_click ( vtl, event, vvp );
-}
-
/*** New track ****/
static gpointer tool_new_track_create ( VikWindow *vw, VikViewport *vvp)
/*
* Actually set the message in statusbar
*/
-static void statusbar_write (const gchar *distance_string, gdouble elev_gain, gdouble elev_loss, VikTrwLayer *vtl )
+static void statusbar_write (gdouble distance, gdouble elev_gain, gdouble elev_loss, gdouble last_step, gdouble angle, VikTrwLayer *vtl )
{
// Only show elevation data when track has some elevation properties
gchar str_gain_loss[64];
str_gain_loss[0] = '\0';
+ gchar str_last_step[64];
+ str_last_step[0] = '\0';
+ gchar *str_total = distance_string (distance);
if ( (elev_gain > 0.1) || (elev_loss > 0.1) ) {
if ( a_vik_get_units_height () == VIK_UNITS_HEIGHT_METRES )
else
g_sprintf(str_gain_loss, _(" - Gain %dft:Loss %dft"), (int)VIK_METERS_TO_FEET(elev_gain), (int)VIK_METERS_TO_FEET(elev_loss));
}
+
+ if ( last_step > 0 ) {
+ gchar *tmp = distance_string (last_step);
+ g_sprintf(str_last_step, _(" - Bearing %3.1f° - Step %s"), RAD2DEG(angle), tmp);
+ g_free ( tmp );
+ }
+
+ VikWindow *vw = VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl));
// Write with full gain/loss information
- gchar *msg = g_strdup_printf ( "%s%s", distance_string, str_gain_loss);
- vik_statusbar_set_message ( vik_window_get_statusbar (VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl))), VIK_STATUSBAR_INFO, msg );
+ gchar *msg = g_strdup_printf ( "Total %s%s%s", str_total, str_last_step, str_gain_loss);
+ vik_statusbar_set_message ( vik_window_get_statusbar (vw), VIK_STATUSBAR_INFO, msg );
g_free ( msg );
+ g_free ( str_total );
}
/*
/* Find out actual distance of current track */
gdouble distance = vik_track_get_length (vtl->current_track);
- gchar *str = distance_string (distance);
- statusbar_write (str, elev_gain, elev_loss, vtl);
-
- g_free (str);
+ statusbar_write (distance, elev_gain, elev_loss, 0, 0, vtl);
}
struct LatLon ll;
vik_viewport_screen_to_coord ( vvp, (gint) event->x, (gint) event->y, &coord );
vik_coord_to_latlon ( &coord, &ll );
- distance = distance + vik_coord_diff( &coord, &(last_tpt->coord));
+ gdouble last_step = vik_coord_diff( &coord, &(last_tpt->coord));
+ distance = distance + last_step;
// Get elevation data
gdouble elev_gain, elev_loss;
elev_loss += last_tpt->altitude - elev_new;
}
}
-
+
gchar *str = distance_string (distance);
PangoLayout *pl = gtk_widget_create_pango_layout (GTK_WIDGET(vvp), NULL);
passalong->drawable = GTK_WIDGET(vvp)->window;
passalong->gc = vtl->current_track_newpoint_gc;
+ gdouble angle;
+ gdouble baseangle;
+ vik_viewport_compute_bearing ( vvp, x1, y1, event->x, event->y, &angle, &baseangle );
+
// Update statusbar with full gain/loss information
- statusbar_write (str, elev_gain, elev_loss, vtl);
+ statusbar_write (distance, elev_gain, elev_loss, last_step, angle, vtl);
g_free (str);
{
if ( vtl->current_track && event->keyval == GDK_Escape ) {
vtl->current_track = NULL;
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
} else if ( vtl->current_track && event->keyval == GDK_BackSpace ) {
/* undo */
g_free ( last->data );
vtl->current_track->trackpoints = g_list_remove_link ( vtl->current_track->trackpoints, last );
}
-
+
update_statusbar ( vtl );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
return FALSE;
}
-static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+/*
+ * Common function to handle trackpoint button requests on either a route or a track
+ * . enables adding a point via normal click
+ * . enables removal of last point via right click
+ * . finishing of the track or route via double clicking
+ */
+static gboolean tool_new_track_or_route_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
{
VikTrackpoint *tp;
return FALSE;
}
- if ( event->button == 3 && vtl->current_track )
+ if ( event->button == 3 )
{
+ if ( !vtl->current_track )
+ return FALSE;
/* undo */
if ( vtl->current_track->trackpoints )
{
}
update_statusbar ( vtl );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
/* undo last, then end */
vtl->current_track = NULL;
}
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
- if ( ! vtl->current_track )
- {
- gchar *name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, _("Track"));
- if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), vtl->tracks, name ) ) )
- {
- vtl->current_track = vik_track_new();
- vtl->current_track->visible = TRUE;
- vik_trw_layer_add_track ( vtl, name, vtl->current_track );
-
- /* incase it was created by begin track */
- vik_window_enable_layer_tool ( VIK_WINDOW(VIK_GTK_WINDOW_FROM_LAYER(vtl)), VIK_LAYER_TRW, TOOL_CREATE_TRACK );
- }
- else
- return TRUE;
- }
tp = vik_trackpoint_new();
vik_viewport_screen_to_coord ( vvp, event->x, event->y, &(tp->coord) );
tp->newsegment = FALSE;
tp->has_timestamp = FALSE;
tp->timestamp = 0;
- vtl->current_track->trackpoints = g_list_append ( vtl->current_track->trackpoints, tp );
- /* Auto attempt to get elevation from DEM data (if it's available) */
- vik_track_apply_dem_data_last_trackpoint ( vtl->current_track );
+
+ if ( vtl->current_track ) {
+ vtl->current_track->trackpoints = g_list_append ( vtl->current_track->trackpoints, tp );
+ /* Auto attempt to get elevation from DEM data (if it's available) */
+ vik_track_apply_dem_data_last_trackpoint ( vtl->current_track );
+ }
vtl->ct_x1 = vtl->ct_x2;
vtl->ct_y1 = vtl->ct_y2;
vtl->ct_x2 = event->x;
vtl->ct_y2 = event->y;
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
+static gboolean tool_new_track_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+{
+ // ----------------------------------------------------- if current is a route - switch to new track
+ if ( event->button == 1 && ( ! vtl->current_track || (vtl->current_track && vtl->current_track->is_route ) ))
+ {
+ gchar *name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_TRACK, _("Track"));
+ if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), vtl->tracks, name, FALSE ) ) )
+ {
+ new_track_create_common ( vtl, name );
+ }
+ else
+ return TRUE;
+ }
+ return tool_new_track_or_route_click ( vtl, event, vvp );
+}
+
static void tool_new_track_release ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
{
if ( event->button == 2 ) {
}
}
+/*** New route ****/
+
+static gpointer tool_new_route_create ( VikWindow *vw, VikViewport *vvp)
+{
+ return vvp;
+}
+
+static gboolean tool_new_route_click ( VikTrwLayer *vtl, GdkEventButton *event, VikViewport *vvp )
+{
+ // -------------------------- if current is a track - switch to new route
+ if ( event->button == 1 && ( ! vtl->current_track || (vtl->current_track && !vtl->current_track->is_route ) ) )
+ {
+ gchar *name = trw_layer_new_unique_sublayer_name(vtl, VIK_TRW_LAYER_SUBLAYER_ROUTE, _("Route"));
+ if ( ( name = a_dialog_new_track ( VIK_GTK_WINDOW_FROM_LAYER(vtl), vtl->routes, name, TRUE ) ) )
+ new_route_create_common ( vtl, name );
+ else
+ return TRUE;
+ }
+ return tool_new_track_or_route_click ( vtl, event, vvp );
+}
+
/*** New waypoint ****/
static gpointer tool_new_waypoint_create ( VikWindow *vw, VikViewport *vvp)
return FALSE;
vik_viewport_screen_to_coord ( vvp, event->x, event->y, &coord );
if (vik_trw_layer_new_waypoint ( vtl, VIK_GTK_WINDOW_FROM_LAYER(vtl), &coord ) && VIK_LAYER(vtl)->visible)
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
vtl->current_tp_track = g_hash_table_lookup ( vtl->tracks, params.closest_track_id );
trw_layer_tpwin_init ( vtl );
set_statusbar_msg_info_trkpt ( vtl, params.closest_tp );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
vtl->current_tp_track = g_hash_table_lookup ( vtl->routes, params.closest_track_id );
trw_layer_tpwin_init ( vtl );
set_statusbar_msg_info_trkpt ( vtl, params.closest_tp );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
if ( vtl->tpwin )
vik_trw_layer_tpwin_set_tp ( vtl->tpwin, vtl->current_tpl, vtl->current_tp_track->name );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
return TRUE;
}
return FALSE;
if ( new_end ) {
vtl->route_finder_coord = *new_end;
g_free ( new_end );
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
/* remove last ' to:...' */
if ( vtl->route_finder_current_track->comment ) {
gchar *last_to = strrchr ( vtl->route_finder_current_track->comment, 't' );
g_ascii_dtostr (startlon, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) start.lon),
g_ascii_dtostr (endlat, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) end.lat),
g_ascii_dtostr (endlon, G_ASCII_DTOSTR_BUF_SIZE, (gdouble) end.lon));
- a_babel_convert_from_url ( vtl, url, "google", NULL, NULL );
+ // NB normally this returns a GPX Route - so subsequent usage of it must lookup via the routes hash
+ a_babel_convert_from_url ( vtl, url, "google", NULL, NULL, NULL );
g_free ( url );
/* see if anything was done -- a track was added or appended to */
vtl->route_finder_check_added_track = FALSE;
vtl->route_finder_append = FALSE;
- vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
+ vik_layer_emit_update ( VIK_LAYER(vtl) );
} else {
vtl->route_finder_started = TRUE;
vtl->route_finder_coord = tmp;
}
/* Params are: vvp, event, last match found or NULL */
-static void tool_show_picture_wp ( char *name, VikWaypoint *wp, gpointer params[3] )
+static void tool_show_picture_wp ( const gpointer id, VikWaypoint *wp, gpointer params[3] )
{
if ( wp->image && wp->visible )
{
***************************************************************************/
-
-
-
-static void image_wp_make_list ( char *name, VikWaypoint *wp, GSList **pics )
+static void image_wp_make_list ( const gpointer id, VikWaypoint *wp, GSList **pics )
{
if ( wp->image && ( ! a_thumbnails_exists ( wp->image ) ) )
*pics = g_slist_append ( *pics, (gpointer) g_strdup ( wp->image ) );
// Redraw to show the thumbnails as they are now created
if ( IS_VIK_LAYER(tctd->vtl) )
- vik_layer_emit_update ( VIK_LAYER(tctd->vtl), TRUE ); // Yes update from background thread
+ vik_layer_emit_update ( VIK_LAYER(tctd->vtl) ); // NB update from background thread
return 0;
}
}
}
+static const gchar* my_track_colors ( gint ii )
+{
+ static const gchar* colors[VIK_TRW_LAYER_TRACK_GCS] = {
+ "#2d870a",
+ "#135D34",
+ "#0a8783",
+ "#0e4d87",
+ "#05469f",
+ "#695CBB",
+ "#2d059f",
+ "#4a059f",
+ "#5A171A",
+ "#96059f"
+ };
+ // Fast and reliable way of returning a colour
+ return colors[(ii % VIK_TRW_LAYER_TRACK_GCS)];
+}
+
+static void trw_layer_track_alloc_colors ( VikTrwLayer *vtl )
+{
+ GHashTableIter iter;
+ gpointer key, value;
+
+ gint ii = 0;
+ // Tracks
+ g_hash_table_iter_init ( &iter, vtl->tracks );
+
+ while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+
+ // Tracks get a random spread of colours if not already assigned
+ if ( ! VIK_TRACK(value)->has_color ) {
+ if ( vtl->drawmode == DRAWMODE_ALL_SAME_COLOR )
+ VIK_TRACK(value)->color = vtl->track_color;
+ else {
+ gdk_color_parse ( my_track_colors (ii), &(VIK_TRACK(value)->color) );
+ }
+ VIK_TRACK(value)->has_color = TRUE;
+ }
+
+ trw_layer_update_treeview ( vtl, VIK_TRACK(value), key );
+
+ ii++;
+ if (ii > VIK_TRW_LAYER_TRACK_GCS)
+ ii = 0;
+ }
+
+ // Routes
+ ii = 0;
+ g_hash_table_iter_init ( &iter, vtl->routes );
+
+ while ( g_hash_table_iter_next (&iter, &key, &value) ) {
+
+ // Routes get an intermix of reds
+ if ( ! VIK_TRACK(value)->has_color ) {
+ if ( ii )
+ gdk_color_parse ( "#FF0000" , &(VIK_TRACK(value)->color) ); // Red
+ else
+ gdk_color_parse ( "#B40916" , &(VIK_TRACK(value)->color) ); // Dark Red
+ VIK_TRACK(value)->has_color = TRUE;
+ }
+
+ trw_layer_update_treeview ( vtl, VIK_TRACK(value), key );
+
+ ii = !ii;
+ }
+}
+
+static void trw_layer_post_read ( VikTrwLayer *vtl, GtkWidget *vp )
+{
+ trw_layer_verify_thumbnails ( vtl, vp );
+ trw_layer_track_alloc_colors ( vtl );
+}
+
VikCoordMode vik_trw_layer_get_coord_mode ( VikTrwLayer *vtl )
{
return vtl->coord_mode;
vik_coord_convert ( &(wp->coord), *dest_mode );
}
-static void track_convert ( const gchar *name, VikTrack *tr, VikCoordMode *dest_mode )
+static void track_convert ( const gpointer id, VikTrack *tr, VikCoordMode *dest_mode )
{
vik_track_convert ( tr, *dest_mode );
}
vtl->coord_mode = dest_mode;
g_hash_table_foreach ( vtl->waypoints, (GHFunc) waypoint_convert, &dest_mode );
g_hash_table_foreach ( vtl->tracks, (GHFunc) track_convert, &dest_mode );
+ g_hash_table_foreach ( vtl->routes, (GHFunc) track_convert, &dest_mode );
}
}