]> git.tdb.fi Git - ext/subsurface.git/commitdiff
Replace event text with small red triangle and tooltip
authorDirk Hohndel <dirk@hohndel.org>
Tue, 4 Oct 2011 19:27:55 +0000 (12:27 -0700)
committerDirk Hohndel <dirk@hohndel.org>
Tue, 4 Oct 2011 19:27:55 +0000 (12:27 -0700)
We draw a little red triangle (of hardcoded size - not sure if this SHOULD
scale with the size of the plot... I like it better if it doesn't) to the
left of an event.

We then maintain an array of rectangles that each circumscribe one of
those event triangles and if the mouse pointer enters one of these
rectangles then we display (after a short delay) a tooltip with the event
text.

Manually creating these rectangles, maintaining the coordinate offset,
checking if we are inside one of these rectangles and then showing a
tooltip... this all seems like there should be gtk functions to do this by
default... but if there are then I failed to find them. So instead I
manually implemented the necessary logic.

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
display.h
gtk-gui.c
profile.c

index c441a7dd2410c5401e083a686fb1a5aea495b6de..a3bc8ab1dc2dde94b851895495e532a46704c9f8 100644 (file)
--- a/display.h
+++ b/display.h
@@ -24,5 +24,6 @@ struct graphics_context {
 
 extern void plot(struct graphics_context *gc, cairo_rectangle_int_t *drawing_area, struct dive *dive);
 extern void set_source_rgb(struct graphics_context *gc, double r, double g, double b);
+extern void attach_tooltip(int x, int y, int w, int h, const char *text);
 
 #endif
index a5728e2c8e5149e54d30c79cd95df02e40f6665e..1419e2d69a74a7924bed78d76b86041c80115e6c 100644 (file)
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -670,6 +670,48 @@ void run_ui(void)
        gtk_main();
 }
 
+typedef struct {
+       cairo_rectangle_int_t rect;
+       const char *text;
+} tooltip_record_t;
+
+static tooltip_record_t *tooltip_rects;
+static int tooltips;
+
+void attach_tooltip(int x, int y, int w, int h, const char *text)
+{
+       cairo_rectangle_int_t *rect;
+       tooltip_rects = realloc(tooltip_rects, (tooltips + 1) * sizeof(tooltip_record_t));
+       rect = &tooltip_rects[tooltips].rect;
+       rect->x = x;
+       rect->y = y;
+       rect->width = w;
+       rect->height = h;
+       tooltip_rects[tooltips].text = text;
+       tooltips++;
+}
+
+#define INSIDE_RECT(_r,_x,_y)  ((_r.x <= _x) && (_r.x + _r.width >= _x) && \
+                               (_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)
+{
+       int i;
+       cairo_rectangle_int_t *drawing_area = user_data;
+       gint tx = x - drawing_area->x; /* get transformed coordinates */
+       gint ty = y - drawing_area->y;
+
+       /* 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 */
+               }
+       }
+       return FALSE; /* don't show tooltip */
+}
+
 static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
 {
        struct dive *dive = current_dive;
@@ -684,11 +726,19 @@ static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer
        drawing_area.y = 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);
        set_source_rgb(&gc, 0, 0, 0);
        cairo_paint(gc.cr);
 
-       if (dive)
+       if (dive) {
+               if (tooltip_rects) {
+                       free(tooltip_rects);
+                       tooltip_rects = NULL;
+               }
+               tooltips = 0;
                plot(&gc, &drawing_area, dive);
+       }
        cairo_destroy(gc.cr);
 
        return FALSE;
index 6f19902026e48bef55fcfec7c14b6e16cb759ce9..f40742c4a354c22e905c75ea21d096bdc4289092 100644 (file)
--- a/profile.c
+++ b/profile.c
@@ -160,6 +160,7 @@ static void plot_text(struct graphics_context *gc, const text_render_options_t *
 static void plot_one_event(struct graphics_context *gc, struct plot_info *pi, struct event *event, const text_render_options_t *tro)
 {
        int i, depth = 0;
+       int x,y;
 
        for (i = 0; i < pi->nr; i++) {
                struct plot_data *data = pi->entry + i;
@@ -167,7 +168,17 @@ static void plot_one_event(struct graphics_context *gc, struct plot_info *pi, st
                        break;
                depth = data->val;
        }
-       plot_text(gc, tro, event->time.seconds, depth, "%s", event->name);
+       /* draw a little tirangular marker and attach tooltip */
+       x = SCALEX(gc, event->time.seconds);
+       y = SCALEY(gc, depth);
+       set_source_rgba(gc, 1.0, 0.1, 0.1, 0.5);
+       cairo_move_to(gc->cr, x-6, y-3);
+       cairo_line_to(gc->cr, x  , y-3);
+       cairo_line_to(gc->cr, x-3, y+3);
+       cairo_line_to(gc->cr, x-6, y-3);
+       cairo_stroke_preserve(gc->cr);
+       cairo_fill(gc->cr);
+       attach_tooltip(x-6, y-3, 6, 6, event->name);
 }
 
 static void plot_events(struct graphics_context *gc, struct plot_info *pi, struct dive *dive)