diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-11-11 13:20:32 +0100 |
---|---|---|
committer | Dirk Hohndel <dirk@hohndel.org> | 2012-11-11 14:44:10 +0100 |
commit | 01e8984d7d3b6da1196766b3b411151a5a7a5053 (patch) | |
tree | ecea8ec90dcf28b23ec45fad582ded34fbdedc3c | |
parent | fe4f13f184ffb97ee4b6dbd4138a9d8ae3aabd14 (diff) | |
download | subsurface-01e8984d7d3b6da1196766b3b411151a5a7a5053.tar.gz |
Create tool-tip with depth/pressure for the whole profile area
This extends on our current tooltip logic (which shows events when you
mouse over them) to show tooltips for the whole profile area.
If you mouse over an event, that is still shown in the tooltip, but
even in the absense of events, the tooltip will be active, and mousing
over the profile area will show the time, depth and pressure.
This can certainly be improved upon further, but even in this form it is
useful.
Fixes #9
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-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; + } + } + } } |