summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--display.h6
-rw-r--r--gtk-gui.c48
-rw-r--r--print.c6
-rw-r--r--profile.c43
4 files changed, 84 insertions, 19 deletions
diff --git a/display.h b/display.h
index 880a8b7be..6eea822aa 100644
--- a/display.h
+++ b/display.h
@@ -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;
diff --git a/gtk-gui.c b/gtk-gui.c
index 025cd1e45..ea335749c 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -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);
diff --git a/print.c b/print.c
index 62317c15e..9ce367508 100644
--- a/print.c
+++ b/print.c
@@ -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);
}
diff --git a/profile.c b/profile.c
index 065934746..c8ce440d6 100644
--- a/profile.c
+++ b/profile.c
@@ -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;
+ }
+ }
+ }
}