diff options
-rw-r--r-- | display.h | 6 | ||||
-rw-r--r-- | gtk-gui.c | 48 | ||||
-rw-r--r-- | print.c | 6 | ||||
-rw-r--r-- | profile.c | 43 |
4 files changed, 84 insertions, 19 deletions
@@ -21,16 +21,20 @@ extern void do_print(void); struct graphics_context { int printer; cairo_t *cr; + cairo_rectangle_t drawing_area; double maxx, maxy; double leftx, rightx; double topy, bottomy; + unsigned int maxtime; + void *plot_info; }; typedef enum { SC_SCREEN, SC_PRINT } scale_mode_t; -extern void plot(struct graphics_context *gc, cairo_rectangle_t *drawing_area, struct dive *dive, scale_mode_t scale); +extern void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale); extern void init_profile_background(struct graphics_context *gc); extern void attach_tooltip(int x, int y, int w, int h, const char *text); +extern void get_plot_details(struct graphics_context *gc, int time, char *buf, size_t bufsize); struct options { enum { PRETTY, TABLE, ONEPERPAGE } type; @@ -1300,21 +1300,44 @@ void attach_tooltip(int x, int y, int w, int h, const char *text) (_r.y <= _y) && (_r.y + _r.height >= _y)) static gboolean profile_tooltip (GtkWidget *widget, gint x, gint y, - gboolean keyboard_mode, GtkTooltip *tooltip, gpointer user_data) + gboolean keyboard_mode, GtkTooltip *tooltip, struct graphics_context *gc) { int i; - cairo_rectangle_t *drawing_area = user_data; + cairo_rectangle_t *drawing_area = &gc->drawing_area; gint tx = x - drawing_area->x; /* get transformed coordinates */ gint ty = y - drawing_area->y; + gint width, height, time = -1; + char buffer[80], plot[80]; + const char *event = ""; + + if (tx < 0 || ty < 0) + return FALSE; + + width = drawing_area->width - 2*drawing_area->x; + height = drawing_area->height - 2*drawing_area->y; + if (width <= 0 || height <= 0) + return FALSE; + + if (tx > width || ty > height) + return FALSE; + + time = (tx * gc->maxtime) / width; /* are we over an event marker ? */ for (i = 0; i < tooltips; i++) { if (INSIDE_RECT(tooltip_rects[i].rect, tx, ty)) { - gtk_tooltip_set_text(tooltip,tooltip_rects[i].text); - return TRUE; /* show tooltip */ + event = tooltip_rects[i].text; + break; } } - return FALSE; /* don't show tooltip */ + get_plot_details(gc, time, plot, sizeof(plot)); + + snprintf(buffer, sizeof(buffer), " %d:%02d%c%s%c%s", time / 60, time % 60, + *plot ? '\n' : ' ', plot, + *event ? '\n' : ' ', event); + gtk_tooltip_set_text(tooltip, buffer); + return TRUE; + } static int zoom_x = -1, zoom_y = -1; @@ -1322,19 +1345,18 @@ static int zoom_x = -1, zoom_y = -1; static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data) { struct dive *dive = current_dive; - struct graphics_context gc = { .printer = 0 }; - static cairo_rectangle_t drawing_area; + static struct graphics_context gc = { .printer = 0 }; /* the drawing area gives TOTAL width * height - x,y is used as the topx/topy offset * so effective drawing area is width-2x * height-2y */ - drawing_area.width = widget->allocation.width; - drawing_area.height = widget->allocation.height; - drawing_area.x = MIN(50,drawing_area.width / 20.0); - drawing_area.y = MIN(50,drawing_area.height / 20.0); + gc.drawing_area.width = widget->allocation.width; + gc.drawing_area.height = widget->allocation.height; + gc.drawing_area.x = MIN(50,gc.drawing_area.width / 20.0); + gc.drawing_area.y = MIN(50,gc.drawing_area.height / 20.0); gc.cr = gdk_cairo_create(widget->window); g_object_set(widget, "has-tooltip", TRUE, NULL); - g_signal_connect(widget, "query-tooltip", G_CALLBACK(profile_tooltip), &drawing_area); + g_signal_connect(widget, "query-tooltip", G_CALLBACK(profile_tooltip), &gc); init_profile_background(&gc); cairo_paint(gc.cr); @@ -1349,7 +1371,7 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer tooltip_rects = NULL; } tooltips = 0; - plot(&gc, &drawing_area, dive, SC_SCREEN); + plot(&gc, dive, SC_SCREEN); } cairo_destroy(gc.cr); @@ -300,13 +300,13 @@ static void show_dive_table(struct dive *dive, cairo_t *cr, double w, static void show_dive_profile(struct dive *dive, cairo_t *cr, double w, double h) { - cairo_rectangle_t drawing_area = { w/20.0, h/20.0, w, h}; struct graphics_context gc = { .printer = 1, - .cr = cr + .cr = cr, + .drawing_area = { w/20.0, h/20.0, w, h}, }; cairo_save(cr); - plot(&gc, &drawing_area, dive, SC_PRINT); + plot(&gc, dive, SC_PRINT); cairo_restore(cr); } @@ -900,6 +900,8 @@ static void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi maxtime = get_maxtime(pi); maxdepth = get_maxdepth(pi); + gc->maxtime = maxtime; + /* Time markers: at most every 10 seconds, but no more than 12 markers. * We start out with 10 seconds and increment up to 30 minutes, * depending on the dive time. @@ -1908,11 +1910,12 @@ static void plot_set_scale(scale_mode_t scale) } } -void plot(struct graphics_context *gc, cairo_rectangle_t *drawing_area, struct dive *dive, scale_mode_t scale) +void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale) { struct plot_info *pi; static struct sample fake[4]; struct sample *sample = dive->sample; + cairo_rectangle_t *drawing_area = &gc->drawing_area; int nr = dive->samples; plot_set_scale(scale); @@ -1994,5 +1997,41 @@ void plot(struct graphics_context *gc, cairo_rectangle_t *drawing_area, struct d plot_depth_scale(gc, pi); - free(pi); + if (gc->printer) { + free(pi); + } else { + free(gc->plot_info); + gc->plot_info = pi; + } +} + +static void plot_string(struct plot_data *entry, char *buf, size_t bufsize) +{ + int depth_decimals, pressure; + const char *depth_unit, *pressure_unit; + double depth; + + depth = get_depth_units(entry->depth, &depth_decimals, &depth_unit); + pressure = get_pressure_units(GET_PRESSURE(entry), &pressure_unit); + + snprintf(buf, bufsize, "%.*f %s\n%d %s", + depth_decimals, depth, depth_unit, + pressure, pressure_unit); +} + +void get_plot_details(struct graphics_context *gc, int time, char *buf, size_t bufsize) +{ + struct plot_info *pi = gc->plot_info; + + *buf = 0; + if (pi) { + int i; + for (i = 0; i < pi->nr; i++) { + struct plot_data *entry = pi->entry + i; + if (entry->sec >= time) { + plot_string(entry, buf, bufsize); + break; + } + } + } } |