summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Dirk Hohndel <dirk@hohndel.org>2013-03-18 19:39:57 -0700
committerGravatar Dirk Hohndel <dirk@hohndel.org>2013-03-18 19:46:17 -0700
commit14b6551a6af4ae9a7d8d56863636fc91a36ee9c0 (patch)
treeb8a7f944c115c4422a31eb13678279963ac3a478
parent471b944704559f0ec3436c3e71da5752e9742e86 (diff)
downloadsubsurface-14b6551a6af4ae9a7d8d56863636fc91a36ee9c0.tar.gz
Manually remove events in the profile context menu
As logical extension of the ability to add bookmarks and gas changes this adds the ability to remove (any arbitrary) event that happens at the mouse position (specifically, that is within +/- six (scaled) pixels around the x-position (time) of the mouse). That's the same width that the triangle marker occupies which was moved to be centered around the event time in commit 5752e9742e86 ("Finetune event triangle position to have the top point at the event time"). Fixes #60 Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
-rw-r--r--display.h3
-rw-r--r--gtk-gui.c64
-rw-r--r--profile.c8
3 files changed, 63 insertions, 12 deletions
diff --git a/display.h b/display.h
index c76afbc02..4e147061f 100644
--- a/display.h
+++ b/display.h
@@ -48,9 +48,10 @@ typedef enum { SC_SCREEN, SC_PRINT } scale_mode_t;
extern void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale);
extern struct divecomputer *select_dc(struct divecomputer *main);
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 attach_tooltip(int x, int y, int w, int h, const char *text, struct event *event);
extern void get_plot_details(struct graphics_context *gc, int time, char *buf, size_t bufsize);
extern int x_to_time(double x);
+extern int x_abs(double x);
struct options {
enum { PRETTY, TABLE, TWOPERPAGE } type;
diff --git a/gtk-gui.c b/gtk-gui.c
index 2167cba46..33777ed93 100644
--- a/gtk-gui.c
+++ b/gtk-gui.c
@@ -1789,12 +1789,13 @@ void exit_ui(void)
typedef struct {
cairo_rectangle_t rect;
const char *text;
+ struct event *event;
} 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)
+void attach_tooltip(int x, int y, int w, int h, const char *text, struct event *event)
{
cairo_rectangle_t *rect;
tooltip_rects = realloc(tooltip_rects, (tooltips + 1) * sizeof(tooltip_record_t));
@@ -1804,11 +1805,13 @@ void attach_tooltip(int x, int y, int w, int h, const char *text)
rect->width = w;
rect->height = h;
tooltip_rects[tooltips].text = strdup(text);
+ tooltip_rects[tooltips].event = event;
tooltips++;
}
#define INSIDE_RECT(_r,_x,_y) ((_r.x <= _x) && (_r.x + _r.width >= _x) && \
(_r.y <= _y) && (_r.y + _r.height >= _y))
+#define INSIDE_RECT_X(_r, _x) ((_r.x <= _x) && (_r.x + _r.width >= _x))
static gboolean profile_tooltip (GtkWidget *widget, gint x, gint y,
gboolean keyboard_mode, GtkTooltip *tooltip, struct graphics_context *gc)
@@ -1974,14 +1977,16 @@ static void add_gas_change_cb(GtkWidget *menuitem, gpointer data)
}
}
-int confirm_bookmark(int when)
+int confirm_dialog(int when, char *action_text, char *event_text)
{
GtkWidget *dialog, *vbox, *label;
int confirmed;
char buffer[256];
+ char title[80];
- snprintf(buffer, sizeof(buffer), _("Add bookmark event at %d:%02u"), FRACTION(when, 60));
- dialog = gtk_dialog_new_with_buttons(_("Add bookmark"),
+ snprintf(title, sizeof(title), "%s %s", action_text, event_text);
+ snprintf(buffer, sizeof(buffer), _("%s event at %d:%02u"), title, FRACTION(when, 60));
+ dialog = gtk_dialog_new_with_buttons(title,
GTK_WINDOW(main_window),
GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
@@ -2004,21 +2009,54 @@ static void add_bookmark_cb(GtkWidget *menuitem, gpointer data)
double *x = data;
int when = x_to_time(*x);
- if (confirm_bookmark(when)){
+ if (confirm_dialog(when, _("Add"), _("bookmark"))){
add_event(current_dc, when, 8, 0, 0, "bookmark");
mark_divelist_changed(TRUE);
report_dives(FALSE, FALSE);
}
}
-static void popup_profile_menu(GtkWidget *widget, GdkEventButton *event)
+static struct event *event_at_x(double rel_x)
+{
+ /* is there an event marker at this x coordinate */
+ struct event *ret = NULL;
+ int i;
+ int x = x_abs(rel_x);
+
+ for (i = 0; i < tooltips; i++) {
+ if (INSIDE_RECT_X(tooltip_rects[i].rect, x)) {
+ ret = tooltip_rects[i].event;
+ break;
+ }
+ }
+ return ret;
+}
+
+static void remove_event_cb(GtkWidget *menuitem, gpointer data)
+{
+ struct event *event = data;
+ if (confirm_dialog(event->time.seconds, _("Remove"), _(event->name))){
+ struct event **ep = &current_dc->events;
+ while (ep && *ep != event)
+ ep = &(*ep)->next;
+ if (ep) {
+ *ep = event->next;
+ free(event);
+ }
+ mark_divelist_changed(TRUE);
+ report_dives(FALSE, FALSE);
+ }
+}
+
+static void popup_profile_menu(GtkWidget *widget, GdkEventButton *gtk_event)
{
GtkWidget *menu, *menuitem, *image;
static double x;
+ struct event *event;
- if (!event || !current_dive)
+ if (!gtk_event || !current_dive)
return;
- x = event->x;
+ x = gtk_event->x;
menu = gtk_menu_new();
menuitem = gtk_image_menu_item_new_with_label(_("Add gas change event here"));
image = gtk_image_new_from_stock(GTK_STOCK_ADD, GTK_ICON_SIZE_MENU);
@@ -2030,12 +2068,18 @@ static void popup_profile_menu(GtkWidget *widget, GdkEventButton *event)
gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
g_signal_connect(menuitem, "activate", G_CALLBACK(add_bookmark_cb), &x);
gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
-
+ if ((event = event_at_x(x)) != NULL) {
+ menuitem = gtk_image_menu_item_new_with_label(_("Remove event here"));
+ image = gtk_image_new_from_stock(GTK_STOCK_REMOVE, GTK_ICON_SIZE_MENU);
+ gtk_image_menu_item_set_image(GTK_IMAGE_MENU_ITEM(menuitem), image);
+ g_signal_connect(menuitem, "activate", G_CALLBACK(remove_event_cb), event);
+ gtk_menu_shell_append(GTK_MENU_SHELL(menu), menuitem);
+ }
gtk_widget_show_all(menu);
gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, NULL,
- event->button, gtk_get_current_event_time());
+ gtk_event->button, gtk_get_current_event_time());
}
diff --git a/profile.c b/profile.c
index ce2113e68..96a051705 100644
--- a/profile.c
+++ b/profile.c
@@ -150,6 +150,12 @@ int x_to_time(double x)
return (seconds > 0) ? seconds : 0;
}
+/* x offset into the drawing area */
+int x_abs(double x)
+{
+ return x - last_gc.drawing_area.x;
+}
+
static void move_to(struct graphics_context *gc, double x, double y)
{
cairo_move_to(gc->cr, SCALE(gc, x, y));
@@ -423,7 +429,7 @@ static void plot_one_event(struct graphics_context *gc, struct plot_info *pi, st
event->flags == SAMPLE_FLAGS_BEGIN ? C_("Starts with space!"," begin") :
event->flags == SAMPLE_FLAGS_END ? C_("Starts with space!", " end") : "");
}
- attach_tooltip(x-6, y, 12, 12, buffer);
+ attach_tooltip(x-6, y, 12, 12, buffer, event);
}
static void plot_events(struct graphics_context *gc, struct plot_info *pi, struct divecomputer *dc)