]> git.street.me.uk Git - andy/viking.git/commitdiff
SF#2564997: Enable specific track colours in default draw by track mode.
authorRob Norris <rw_norris@hotmail.com>
Sat, 27 Oct 2012 10:51:38 +0000 (11:51 +0100)
committerRob Norris <rw_norris@hotmail.com>
Sat, 5 Jan 2013 12:47:39 +0000 (12:47 +0000)
Colours are allocated automatically (as previously) if no colour has been assigned.
Colour of the track is shown in the treeview as well.
The colour is saved in .vik files.
Changing the colour is available in the track's properties dialog.
By default new routes are red, so tweaked route icons to match.

src/gpspoint.c
src/icons/cursor_new_route.png
src/icons/vik_new_route_18.png
src/viktrack.c
src/viktrack.h
src/viktrwlayer.c
src/viktrwlayer.h
src/viktrwlayer_propwin.c
src/viktrwlayer_propwin.h

index 8278577948f81f7887a800cc1082ad7499d8097d..06c0f0157d04e6daa363bcedaac4d962a633054f 100644 (file)
@@ -77,6 +77,7 @@ static struct LatLon line_latlon;
 static gchar *line_name;
 static gchar *line_comment;
 static gchar *line_description;
+static gchar *line_color;
 static gchar *line_image;
 static gchar *line_symbol;
 static gboolean line_newsegment = FALSE;
@@ -273,6 +274,12 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f ) {
         line_description = NULL;
       }
 
+      if ( line_color )
+      {
+        if ( gdk_color_parse ( line_color, &(pl->color) ) )
+        pl->has_color = TRUE;
+      }
+
       pl->trackpoints = NULL;
       vik_trw_layer_filein_add_track ( trw, line_name, pl );
       g_free ( line_name );
@@ -305,12 +312,15 @@ gboolean a_gpspoint_read_file(VikTrwLayer *trw, FILE *f ) {
       g_free ( line_comment );
     if (line_description)
       g_free ( line_description );
+    if (line_color)
+      g_free ( line_color );
     if (line_image)
       g_free ( line_image );
     if (line_symbol)
       g_free ( line_symbol );
     line_comment = NULL;
     line_description = NULL;
+    line_color = NULL;
     line_image = NULL;
     line_symbol = NULL;
     line_type = GPSPOINT_TYPE_NONE;
@@ -419,6 +429,11 @@ static void gpspoint_process_key_and_value ( const gchar *key, gint key_len, con
     if (line_description == NULL)
       line_description = deslashndup ( value, value_len );
   }
+  else if (key_len == 5 && strncasecmp( key, "color", key_len ) == 0 && value != NULL)
+  {
+    if (line_color == NULL)
+      line_color = deslashndup ( value, value_len );
+  }
   else if (key_len == 5 && strncasecmp( key, "image", key_len ) == 0 && value != NULL)
   {
     if (line_image == NULL)
@@ -592,6 +607,10 @@ static void a_gpspoint_write_track ( const gpointer id, const VikTrack *trk, FIL
     g_free ( tmp );
   }
 
+  if ( trk->has_color ) {
+    fprintf ( f, " color=#%.2x%.2x%.2x", (int)(trk->color.red/256),(int)(trk->color.green/256),(int)(trk->color.blue/256));
+  }
+
   if ( ! trk->visible ) {
     fprintf ( f, " visible=\"n\"" );
   }
index 826b61c7f20a0b5bb6f52b2e3f621148270ed6ea..c3dbd35045571920f66f778e43172b03ea09ac31 100644 (file)
Binary files a/src/icons/cursor_new_route.png and b/src/icons/cursor_new_route.png differ
index b3e0987770d9b4262892e1ce80ff9a7213168982..cb2c6bcbe3f3a9a110463e15d962df9c575b82c3 100644 (file)
Binary files a/src/icons/vik_new_route_18.png and b/src/icons/vik_new_route_18.png differ
index 91e060f193fe27ed16c5c0ff29094e45361dd527..269466832d1795997e35fce0c5ec77f678b5da45 100644 (file)
@@ -129,6 +129,8 @@ VikTrack *vik_track_copy ( const VikTrack *tr )
   GList *tp_iter = tr->trackpoints;
   new_tr->visible = tr->visible;
   new_tr->is_route = tr->is_route;
+  new_tr->has_color = tr->has_color;
+  new_tr->color = tr->color;
   new_tr->trackpoints = NULL;
   while ( tp_iter )
   {
@@ -1266,6 +1268,8 @@ VikTrack *vik_track_unmarshall (guint8 *data, guint datalen)
   /* basic properties: */
   new_tr->visible = ((VikTrack *)data)->visible;
   new_tr->is_route = ((VikTrack *)data)->is_route;
+  new_tr->has_color = ((VikTrack *)data)->has_color;
+  new_tr->color = ((VikTrack *)data)->color;
 
   data += sizeof(*new_tr);
 
index 4e6661af460396d3a02f2765895961f4eb271986..1381a2db156af5d940d99a97771bf30a3ab4ee9d 100644 (file)
@@ -69,8 +69,10 @@ struct _VikTrack {
   gchar *comment;
   gchar *description;
   guint8 ref_count;
-  GtkWidget *property_dialog;
   gchar *name;
+  GtkWidget *property_dialog;
+  gboolean has_color;
+  GdkColor color;
 };
 
 VikTrack *vik_track_new();
index 4402f96995c9298bcd33a327f556b6febfb6e39f..3634fc67e710d5fea92b40e7c135ed47a57c4ec8 100644 (file)
 #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 5
+#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 DRAWMODE_BY_TRACK 0
 #define DRAWMODE_BY_SPEED 1
@@ -148,6 +147,7 @@ struct _VikTrwLayer {
 
   gdouble track_draw_speed_factor;
   GArray *track_gc;
+  GdkGC *track_1color_gc;
   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)
@@ -222,7 +222,6 @@ struct DrawingParams {
   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;
 };
@@ -554,6 +553,7 @@ static VikTrwLayer* trw_layer_new ( gint drawmode );
 /* 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 );
@@ -600,7 +600,7 @@ VikLayerInterface vik_trw_layer_interface = {
 
   (VikLayerFuncCreate)                  trw_layer_create,
   (VikLayerFuncRealize)                 trw_layer_realize,
-  (VikLayerFuncPostRead)                trw_layer_verify_thumbnails,
+  (VikLayerFuncPostRead)                trw_layer_post_read,
   (VikLayerFuncFree)                    trw_layer_free,
 
   (VikLayerFuncProperties)              NULL,
@@ -1078,52 +1078,29 @@ static VikTrwLayer* trw_layer_new ( gint drawmode )
   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;
 }
 
@@ -1198,8 +1175,6 @@ static void init_drawing_params ( struct DrawingParams *dp, VikTrwLayer *vtl, Vi
     dp->cn1 = bottomright.north_south;
     dp->cn2 = upperleft.north_south;
   }
-
-  dp->track_gc_iter = 0;
 }
 
 /*
@@ -1288,18 +1263,22 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
        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_BLACK
+        // 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_BLACK);
+        break;
+      }
     }
   }
 
@@ -1311,8 +1290,9 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
 
     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 );
     }
@@ -1361,8 +1341,7 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
         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 ) );
           }
         }
 
@@ -1379,8 +1358,8 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
             */
             /* 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 );
@@ -1462,8 +1441,7 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
             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 ));
            }
 
            /*
@@ -1493,9 +1471,6 @@ static void trw_layer_draw_track ( const gchar *name, VikTrack *track, struct Dr
       }
     }
   }
-  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 */
@@ -1709,6 +1684,11 @@ static void trw_layer_free_track_gcs ( VikTrwLayer *vtl )
     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 );
@@ -1757,22 +1737,8 @@ static void trw_layer_new_track_gcs ( VikTrwLayer *vtl, VikViewport *vp )
 
   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
@@ -1832,12 +1798,29 @@ static void trw_layer_realize_track ( gpointer id, VikTrack *track, gpointer pas
 {
   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 );
@@ -3128,17 +3111,24 @@ static void trw_layer_new_track ( gpointer lav[2] )
   }
 }
 
+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 );
-
+    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 );
   }
 }
@@ -3546,7 +3536,8 @@ void vik_trw_layer_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *t )
   }
 
   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
@@ -3580,6 +3571,7 @@ void vik_trw_layer_add_route ( VikTrwLayer *vtl, gchar *name, VikTrack *t )
 
   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. */
@@ -4135,13 +4127,52 @@ static void trw_layer_properties_item ( gpointer pass_along[7] )
     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
@@ -4941,6 +4972,7 @@ static void trw_layer_split_at_selected_trackpoint ( VikTrwLayer *vtl, gint subt
       newglist->data = vik_trackpoint_copy(VIK_TRACKPOINT(vtl->current_tpl->data));
       tr->trackpoints = newglist;
       tr->is_route = vtl->current_tp_track->is_route;
+      tr->color = vtl->current_tp_track->color;
       tr->visible = TRUE;
 
       vtl->current_tpl->next->prev = newglist; /* end old track here */
@@ -5117,6 +5149,7 @@ static void trw_layer_split_by_n_points ( gpointer pass_along[6] )
       tr = vik_track_new();
       tr->visible = track->visible;
       tr->is_route = track->is_route;
+      tr->color = track->color;
       tr->trackpoints = (GList *)(iter->data);
 
       if ( track->is_route ) {
@@ -7519,7 +7552,7 @@ static gboolean tool_new_track_key_press ( VikTrwLayer *vtl, GdkEventKey *event,
       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 );
@@ -7651,12 +7684,7 @@ static gboolean tool_new_route_click ( VikTrwLayer *vtl, GdkEventButton *event,
   {
     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 ) ) )
-    {
-      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 );
-    }
+      new_route_create_common ( vtl, name );
     else
       return TRUE;
   }
@@ -8060,6 +8088,75 @@ void trw_layer_verify_thumbnails ( VikTrwLayer *vtl, GtkWidget *vp )
   }
 }
 
+static const gchar* my_track_colors ( gint ii )
+{
+  static const gchar* colors[VIK_TRW_LAYER_TRACK_GCS] = {
+    "#2d870a",
+    "#0a8742",
+    "#0a8783",
+    "#0e4d87",
+    "#05469f",
+    "#1b059f",
+    "#2d059f",
+    "#4a059f",
+    "#84059f",
+    "#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 ) {
+      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;
index 3ccbb55981c1b62148cd9a8ac95849a729151a34..7d0b9da91e686b926061cac42921724482c180dc 100644 (file)
@@ -98,6 +98,8 @@ void trw_layer_verify_thumbnails ( VikTrwLayer *vtl, GtkWidget *vp );
 // Other functions only for use by other trw_layer subwindows
 gchar *trw_layer_new_unique_sublayer_name ( VikTrwLayer *vtl, gint sublayer_type, const gchar *name );
 
+void trw_layer_update_treeview ( VikTrwLayer *vtl, VikTrack *trk, gpointer *trk_id );
+
 G_END_DECLS
 
 #endif
index 78fca4d9bcffa93894c73c4345f3dbf9ac742abd..f728d0f934e655a0646c6f49ad2ef969f9b1e9fe 100644 (file)
@@ -100,6 +100,7 @@ typedef struct _propwidgets {
   gboolean  configure_dialog;
   VikTrwLayer *vtl;
   VikTrack *tr;
+  gpointer  trk_id;
   VikViewport *vvp;
   VikLayersPanel *vlp;
   gint      profile_width;
@@ -124,6 +125,7 @@ typedef struct _propwidgets {
   GtkWidget *w_time_start;
   GtkWidget *w_time_end;
   GtkWidget *w_time_dur;
+  GtkWidget *w_color;
   GtkWidget *w_cur_dist; /*< Current distance */
   GtkWidget *w_cur_elevation;
   GtkWidget *w_cur_gradient_dist; /*< Current distance on gradient graph */
@@ -2617,6 +2619,9 @@ static void propwin_response_cb( GtkDialog *dialog, gint resp, PropWidgets *widg
     case GTK_RESPONSE_ACCEPT:
       vik_track_set_comment(tr, gtk_entry_get_text(GTK_ENTRY(widgets->w_comment)));
       vik_track_set_description(tr, gtk_entry_get_text(GTK_ENTRY(widgets->w_description)));
+      gtk_color_button_get_color ( GTK_COLOR_BUTTON(widgets->w_color), &(tr->color) );
+      trw_layer_update_treeview ( widgets->vtl, widgets->tr, widgets->trk_id );
+      vik_layer_emit_update ( VIK_LAYER(vtl), FALSE );
       break;
     case VIK_TRW_LAYER_PROPWIN_REVERSE:
       vik_track_reverse(tr);
@@ -2756,13 +2761,19 @@ static GtkWidget *create_graph_page ( GtkWidget *graph,
   return vbox;
 }
 
-void vik_trw_layer_propwin_run ( GtkWindow *parent, VikTrwLayer *vtl, VikTrack *tr, gpointer vlp, VikViewport *vvp )
+void vik_trw_layer_propwin_run ( GtkWindow *parent,
+                                 VikTrwLayer *vtl,
+                                 VikTrack *tr,
+                                 gpointer vlp,
+                                 VikViewport *vvp,
+                                 gpointer *trk_id )
 {
   PropWidgets *widgets = prop_widgets_new();
   widgets->vtl = vtl;
   widgets->vvp = vvp;
   widgets->vlp = vlp;
   widgets->tr = tr;
+  widgets->trk_id = trk_id;
   widgets->profile_width  = PROPWIN_PROFILE_WIDTH;
   widgets->profile_height = PROPWIN_PROFILE_HEIGHT;
   gchar *title = g_strdup_printf(_("%s - Track Properties"), tr->name);
@@ -2813,7 +2824,8 @@ void vik_trw_layer_propwin_run ( GtkWindow *parent, VikTrwLayer *vtl, VikTrack *
     N_("<b>Total Elevation Gain/Loss:</b>"),
     N_("<b>Start:</b>"),
     N_("<b>End:</b>"),
-    N_("<b>Duration:</b>") };
+    N_("<b>Duration:</b>"),
+    N_("<b>Color:</b>") };
   static gchar tmp_buf[50];
   gdouble tmp_speed;
 
@@ -3024,6 +3036,8 @@ void vik_trw_layer_propwin_run ( GtkWindow *parent, VikTrwLayer *vtl, VikTrack *
     widgets->w_time_dur = content[cnt++] = gtk_label_new(_("No Data"));
   }
 
+  widgets->w_color = content[cnt++] = gtk_color_button_new_with_color ( &(tr->color) );
+
   table = GTK_TABLE(gtk_table_new (cnt, 2, FALSE));
   gtk_table_set_col_spacing (table, 0, 10);
   for (i=0; i<cnt; i++) {
index b34f5efd29f8f990737104cd41d92794ce80ac50..6db02f3e28124d637ccf5379cc0fe647afa5eb99 100644 (file)
@@ -1,3 +1,4 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
 /*
  * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
  *
@@ -32,7 +33,12 @@ G_BEGIN_DECLS
 #define VIK_TRW_LAYER_PROPWIN_DEL_DUP 3
 #define VIK_TRW_LAYER_PROPWIN_SPLIT_MARKER 4
 
-void vik_trw_layer_propwin_run ( GtkWindow *parent, VikTrwLayer *vtl, VikTrack *tr, gpointer vlp, VikViewport *vvp );
+void vik_trw_layer_propwin_run ( GtkWindow *parent,
+                                                                VikTrwLayer *vtl,
+                                                                VikTrack *tr,
+                                                                gpointer vlp,
+                                                                VikViewport *vvp,
+                                                                gpointer *trk_id );
 
 /**
  * Update this property dialog