+
+}
+#undef LINES
+
+/**
+ * Draw all graphs
+ */
+static void draw_all_graphs ( GtkWidget *widget, gpointer *pass_along, gboolean resized )
+{
+ VikTrack *tr = pass_along[0];
+ PropWidgets *widgets = pass_along[2];
+
+ // Draw graphs even if they are not visible
+
+ GList *child = NULL;
+ GtkWidget *image = NULL;
+ GtkWidget *window = gtk_widget_get_toplevel(widget);
+ gdouble pc = NAN;
+
+ // Draw elevations
+ if (widgets->elev_box != NULL) {
+
+ // Saved image no longer any good as we've resized, so we remove it here
+ if (resized && widgets->elev_graph_saved_img.img) {
+ g_object_unref(widgets->elev_graph_saved_img.img);
+ widgets->elev_graph_saved_img.img = NULL;
+ widgets->elev_graph_saved_img.saved = FALSE;
+ }
+
+ child = gtk_container_get_children(GTK_CONTAINER(widgets->elev_box));
+ draw_elevations (GTK_WIDGET(child->data), tr, widgets );
+
+ image = GTK_WIDGET(child->data);
+ g_list_free(child);
+
+ // Ensure marker is redrawn if necessary
+ if (widgets->is_marker_drawn) {
+
+ pc = tp_percentage_by_distance ( tr, widgets->marker_tp, widgets->track_length );
+ gdouble marker_x = 0.0;
+ if (!isnan(pc)) {
+ marker_x = (pc * widgets->profile_width) + MARGIN + (image->allocation.width/2 - widgets->profile_width/2 - MARGIN/2);
+ save_image_and_draw_graph_mark(image,
+ marker_x,
+ image->allocation.width,
+ window->style->black_gc,
+ &widgets->elev_graph_saved_img,
+ widgets->profile_width,
+ widgets->profile_height,
+ &widgets->is_marker_drawn);
+ }
+ }
+ }
+
+ // Draw speeds
+ if (widgets->speed_box != NULL) {
+
+ // Saved image no longer any good as we've resized
+ if (resized && widgets->speed_graph_saved_img.img) {
+ g_object_unref(widgets->speed_graph_saved_img.img);
+ widgets->speed_graph_saved_img.img = NULL;
+ widgets->speed_graph_saved_img.saved = FALSE;
+ }
+
+ child = gtk_container_get_children(GTK_CONTAINER(widgets->speed_box));
+ draw_vt (GTK_WIDGET(child->data), tr, widgets );
+
+ image = GTK_WIDGET(child->data);
+ g_list_free(child);
+
+ // Ensure marker is redrawn if necessary
+ if (widgets->is_marker_drawn) {
+
+ pc = tp_percentage_by_time ( tr, widgets->marker_tp );
+
+ gdouble marker_x = 0.0;
+ if (!isnan(pc)) {
+ marker_x = (pc * widgets->profile_width) + MARGIN + (image->allocation.width/2 - widgets->profile_width/2 - MARGIN/2);
+ save_image_and_draw_graph_mark(image,
+ marker_x,
+ image->allocation.width,
+ window->style->black_gc,
+ &widgets->speed_graph_saved_img,
+ widgets->profile_width,
+ widgets->profile_height,
+ &widgets->is_marker_drawn);
+ }
+ }
+ }
+}
+
+/**
+ * Configure/Resize the profile & speed/time images
+ */
+static gboolean configure_event ( GtkWidget *widget, GdkEventConfigure *event, gpointer *pass_along )
+{
+ PropWidgets *widgets = pass_along[2];
+
+ if (widgets->configure_dialog) {
+ // Determine size offsets between dialog size and size for images
+ // Only on the initialisation of the dialog
+ widgets->profile_width_offset = event->width - widgets->profile_width;
+ widgets->profile_height_offset = event->height - widgets->profile_height;
+ widgets->configure_dialog = FALSE;
+
+ // Without this the settting, the dialog will only grow in vertical size - one can not then make it smaller!
+ gtk_widget_set_size_request ( widget, widgets->profile_width+widgets->profile_width_offset, widgets->profile_height );
+ // In fact this allows one to compress it a bit more vertically as I don't add on the height offset
+ }
+ else {
+ widgets->profile_width_old = widgets->profile_width;
+ widgets->profile_height_old = widgets->profile_height;
+ }
+
+ // Now adjust From Dialog size to get image size
+ widgets->profile_width = event->width - widgets->profile_width_offset;
+ widgets->profile_height = event->height - widgets->profile_height_offset;
+
+ // ATM we receive configure_events when the dialog is moved and so no further action is necessary
+ if ( !widgets->configure_dialog &&
+ (widgets->profile_width_old == widgets->profile_width) && (widgets->profile_height_old == widgets->profile_height) )
+ return FALSE;
+
+ // Draw stuff
+ draw_all_graphs ( widget, pass_along, TRUE );
+
+ return FALSE;
+}
+
+/**
+ * Create height profile widgets including the image and callbacks
+ */
+GtkWidget *vik_trw_layer_create_profile ( GtkWidget *window, VikTrack *tr, gpointer vlp, VikViewport *vvp, PropWidgets *widgets, gdouble *min_alt, gdouble *max_alt)
+{
+ GdkPixmap *pix;
+ GtkWidget *image;
+ GtkWidget *eventbox;
+ gpointer *pass_along;
+
+ // First allocation
+ widgets->altitudes = vik_track_make_elevation_map ( tr, widgets->profile_width );
+
+ if ( widgets->altitudes == NULL ) {
+ *min_alt = *max_alt = VIK_DEFAULT_ALTITUDE;
+ return NULL;
+ }
+
+ minmax_array(widgets->altitudes, min_alt, max_alt, TRUE, widgets->profile_width);
+
+ pix = gdk_pixmap_new( window->window, widgets->profile_width + MARGIN, widgets->profile_height, -1 );
+ image = gtk_image_new_from_pixmap ( pix, NULL );
+
+ g_object_unref ( G_OBJECT(pix) );
+
+ pass_along = g_malloc ( sizeof(gpointer) * 4 ); /* FIXME: mem leak -- never be freed */
+ pass_along[0] = tr;
+ pass_along[1] = vlp;
+ pass_along[2] = vvp;
+ pass_along[3] = widgets;
+
+ eventbox = gtk_event_box_new ();
+ g_signal_connect ( G_OBJECT(eventbox), "button_press_event", G_CALLBACK(track_profile_click), pass_along );
+ g_signal_connect ( G_OBJECT(eventbox), "motion_notify_event", G_CALLBACK(track_profile_move), pass_along );
+ g_signal_connect_swapped ( G_OBJECT(eventbox), "destroy", G_CALLBACK(g_free), pass_along );
+ gtk_container_add ( GTK_CONTAINER(eventbox), image );
+ gtk_widget_set_events (eventbox, GDK_BUTTON_PRESS_MASK | GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_STRUCTURE_MASK);
+
+ return eventbox;
+}
+
+/**
+ * Create speed/time widgets including the image and callbacks
+ */
+GtkWidget *vik_trw_layer_create_vtdiag ( GtkWidget *window, VikTrack *tr, gpointer vlp, VikViewport *vvp, PropWidgets *widgets)
+{
+ GdkPixmap *pix;
+ GtkWidget *image;
+ GtkWidget *eventbox;
+ gpointer *pass_along;
+
+ // First allocation
+ widgets->speeds = vik_track_make_speed_map ( tr, widgets->profile_width );
+ if ( widgets->speeds == NULL )
+ return NULL;
+
+ pass_along = g_malloc ( sizeof(gpointer) * 4 ); /* FIXME: mem leak -- never be freed */
+ pass_along[0] = tr;
+ pass_along[1] = vlp;
+ pass_along[2] = vvp;
+ pass_along[3] = widgets;
+
+ pix = gdk_pixmap_new( window->window, widgets->profile_width + MARGIN, widgets->profile_height, -1 );
+ image = gtk_image_new_from_pixmap ( pix, NULL );
+
+#if 0
+ /* XXX this can go out, it's just a helpful dev tool */
+ {
+ int j;
+ GdkGC **colors[8] = { window->style->bg_gc,
+ window->style->fg_gc,
+ window->style->light_gc,
+ window->style->dark_gc,
+ window->style->mid_gc,
+ window->style->text_gc,
+ window->style->base_gc,
+ window->style->text_aa_gc };
+ for (i=0; i<5; i++) {
+ for (j=0; j<8; j++) {
+ gdk_draw_rectangle(GDK_DRAWABLE(pix), colors[j][i],
+ TRUE, i*20, j*20, 20, 20);
+ gdk_draw_rectangle(GDK_DRAWABLE(pix), window->style->black_gc,
+ FALSE, i*20, j*20, 20, 20);
+ }
+ }
+ }
+#endif
+
+ g_object_unref ( G_OBJECT(pix) );