summaryrefslogtreecommitdiffstats
path: root/gtk-gui.c
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2011-10-04 12:27:55 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2011-10-04 12:27:55 -0700
commit53f809ccca43354f443bb8e02621a5625eb38fde (patch)
tree00e6066c4d9ab9eaeb065aaf6752fd21e0c423cb /gtk-gui.c
parentb72ade0e78825dd97add4c7607c574df351abed0 (diff)
downloadsubsurface-53f809ccca43354f443bb8e02621a5625eb38fde.tar.gz
Replace event text with small red triangle and tooltip
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>
Diffstat (limited to 'gtk-gui.c')
-rw-r--r--gtk-gui.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/gtk-gui.c b/gtk-gui.c
index a5728e2c8..1419e2d69 100644
--- 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;