Here is a potential fix along the lines of my idea as to what is wrong for the 
track information redraw problem.
(Reset the drawing rather than the 'GDK_INVERT' method)

A far as I can tell this works on my Linux machine and should be better under 
Windows - but I have no way of testing it.

If someone (i.e. Mathieu) could build+test it at some point that would be great.

I'll then look to tidy it up and include it properly.


Be Seeing You - Rob.
If at first you don't succeed,
then skydiving isn't for you.
                                          
From 1a3375fedf42458c3f0da8a81abdd767f619f871 Mon Sep 17 00:00:00 2001
From: Rob Norris <rw_nor...@hotmail.com>
Date: Wed, 29 Aug 2012 21:25:47 +0100
Subject: [PATCH] Rework the create track drawing with a specific GC on which
 to draw the next potential point.

This means this GC is reset on each update and then redrawn.
This should be more reliable than trying to undraw previous information via the GDK_INVERT method, especially for Windows systems.

This is a Work In Progress and the commit needs to be tidied up a bit.
---
 src/viktrwlayer.c |   89 +++++++++++++++++++++++++++++++++++++++++++++--------
 1 file changed, 77 insertions(+), 12 deletions(-)

diff --git a/src/viktrwlayer.c b/src/viktrwlayer.c
index d485496..d2b822f 100644
--- a/src/viktrwlayer.c
+++ b/src/viktrwlayer.c
@@ -141,6 +141,9 @@ struct _VikTrwLayer {
   gdouble track_draw_speed_factor;
   GArray *track_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)
+  GdkGC *current_track_newpoint_gc;
   GdkGC *track_bg_gc;
   GdkGC *waypoint_gc;
   GdkGC *waypoint_text_gc;
@@ -1514,6 +1517,11 @@ static void trw_layer_free_track_gcs ( VikTrwLayer *vtl )
     g_object_unref ( vtl->current_track_gc );
     vtl->current_track_gc = NULL;
   }
+  if ( vtl->current_track_newpoint_gc )
+  {
+    g_object_unref ( vtl->current_track_newpoint_gc );
+    vtl->current_track_newpoint_gc = NULL;
+  }
 
   if ( ! vtl->track_gc )
     return;
@@ -1540,6 +1548,12 @@ static void trw_layer_new_track_gcs ( VikTrwLayer *vtl, VikViewport *vp )
   vtl->current_track_gc = vik_viewport_new_gc ( vp, "#FF0000", 2 );
   gdk_gc_set_line_attributes ( vtl->current_track_gc, 2, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND );
 
+  // 'newpoint' gc is exactly the same as the current track gc
+  if ( vtl->current_track_newpoint_gc )
+    g_object_unref ( vtl->current_track_newpoint_gc );
+  vtl->current_track_newpoint_gc = vik_viewport_new_gc ( vp, "#FF0000", 2 );
+  gdk_gc_set_line_attributes ( vtl->current_track_newpoint_gc, 2, GDK_LINE_ON_OFF_DASH, GDK_CAP_ROUND, GDK_JOIN_ROUND );
+
   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 */
@@ -5727,13 +5741,31 @@ static gpointer tool_new_track_create ( VikWindow *vw, VikViewport *vvp)
   return vvp;
 }
 
+// TODO: Remove unused variables
 typedef struct {
   VikTrwLayer *vtl;
   VikViewport *vvp;
   gint x1,y1,x2,y2,x3,y3;
   const gchar* str;
+  GdkDrawable *drawable;
+  GdkGC *gc;
+  GdkPixmap *pixmap;
 } new_track_move_passalong_t;
 
+static gboolean trw_draw_current_track ( gpointer data )
+{
+  new_track_move_passalong_t *ntmp = (new_track_move_passalong_t*) data;
+  gdk_threads_enter();
+  gdk_draw_drawable (ntmp->drawable,
+		     ntmp->gc,
+		     ntmp->pixmap,
+		     0, 0, 0, 0, -1, -1);
+  ntmp->vtl->ct_sync_done = TRUE;
+  gdk_threads_leave();
+  return FALSE;
+}
+
+// TODO Remove
 /* sync and undraw, but only when we have time */
 static gboolean ct_sync ( gpointer passalong )
 {
@@ -5826,15 +5858,40 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo
 {
   /* if we haven't sync'ed yet, we don't have time to do more. */
   if ( vtl->ct_sync_done && vtl->current_track && vtl->current_track->trackpoints ) {
-    GList *iter = vtl->current_track->trackpoints;
+    GList *iter = g_list_last ( vtl->current_track->trackpoints );
+
+    static GdkPixmap *pixmap = NULL;
+    int w1, h1, w2, h2;
+    // Need to check in case window has been resized
+    w1 = vik_viewport_get_width(vvp);
+    h1 = vik_viewport_get_height(vvp);
+    if (!pixmap) {
+      pixmap = gdk_pixmap_new ( GTK_WIDGET(vvp)->window, w1, h1, -1 );
+    }
+    gdk_drawable_get_size (pixmap, &w2, &h2);
+    if (w1 != w2 || h1 != h2) {
+      g_object_unref ( G_OBJECT ( pixmap ) );
+      pixmap = gdk_pixmap_new ( GTK_WIDGET(vvp)->window, w1, h1, -1 );
+    }
+
+    // Reset to background
+    gdk_draw_drawable (pixmap,
+                       vtl->current_track_newpoint_gc,
+                       vik_viewport_get_pixmap(vvp),
+                       0, 0, 0, 0, -1, -1);
+
     new_track_move_passalong_t *passalong;
     gint x1, y1;
 
-    while ( iter->next )
-      iter = iter->next;
-    gdk_gc_set_function ( vtl->current_track_gc, GDK_INVERT );
     vik_viewport_coord_to_screen ( vvp, &(VIK_TRACKPOINT(iter->data)->coord), &x1, &y1 );
-    vik_viewport_draw_line ( vvp, vtl->current_track_gc, x1, y1, event->x, event->y );
+
+    // FOR SCREEN OVERLAYS WE MUST DRAW INTO THIS PIXMAP (when using the reset method)
+    //  otherwise using vik_viewport_draw_* functions puts the data into the base pixmap,
+    //  thus when we come to reset to the background it would include what we have already drawn!!
+    gdk_draw_line ( pixmap,
+                    vtl->current_track_newpoint_gc,
+                    x1, y1, event->x, event->y );
+    // Using this reset method should be more reliable than trying to undraw previous efforts via the GDK_INVERT method
 
     /* Find out actual distance of current track */
     gdouble distance = vik_track_get_length (vtl->current_track);
@@ -5870,11 +5927,14 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo
     /* offset from cursor a bit */
     xd = event->x + 10;
     yd = event->y - 10;
-    /* note attempted setting text using pango layouts - but the 'undraw' technique didn't work */
-    vik_viewport_draw_string (vvp, gdk_font_from_description (pango_font_description_from_string ("Sans 8")), vtl->current_track_gc, xd, yd, str);
-
-    gdk_gc_set_function ( vtl->current_track_gc, GDK_COPY );
-
+    // TODO: it is worth using pango a layout?
+    // TODO: maybe a background rectangle to make the text more visible (as per Ruler information)
+    gdk_draw_string (pixmap,
+                     gdk_font_from_description (pango_font_description_from_string ("Sans 8")),
+                     vtl->current_track_newpoint_gc,
+                     xd, yd, str);
+
+    // TODO: minimize passalong to what is now actually used...
     passalong = g_new(new_track_move_passalong_t,1); /* freed by sync */
     passalong->vtl = vtl;
     passalong->vvp = vvp;
@@ -5884,13 +5944,18 @@ static VikLayerToolFuncStatus tool_new_track_move ( VikTrwLayer *vtl, GdkEventMo
     passalong->y2 = event->y;
     passalong->x3 = xd;
     passalong->y3 = yd;
-    passalong->str = str;
+    passalong->pixmap = pixmap;
+    passalong->drawable = GTK_WIDGET(vvp)->window;
+    passalong->gc = vtl->current_track_newpoint_gc;
+    //passalong->str = str;
 
     // Update statusbar with full gain/loss information
     statusbar_write (str, elev_gain, elev_loss, vtl);
 
+    g_free ((gpointer)str);
+
     /* this will sync and undraw when we have time to */
-    g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, ct_sync, passalong, NULL);
+    g_idle_add_full (G_PRIORITY_HIGH_IDLE + 10, trw_draw_current_track, passalong, NULL);
     vtl->ct_sync_done = FALSE;
     return VIK_LAYER_TOOL_ACK_GRAB_FOCUS;
   }
-- 
1.7.10.4

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Viking-devel mailing list
Viking-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/viking-devel
Viking home page: http://viking.sf.net/

Reply via email to