10 #define ROUND_UP(x,y) ((((x)+(y)-1)/(y))*(y))
11 #define MAX(x,y) ((x) > (y) ? (x) : (y))
13 static int round_seconds_up(int seconds)
15 return MAX(30, ROUND_UP(seconds, 60*10));
18 static int round_feet_up(int feet)
20 return MAX(45, ROUND_UP(feet+5, 15));
23 /* Scale to 0,0 -> maxx,maxy */
24 #define SCALE(x,y) (x)*maxx/scalex+topx,(y)*maxy/scaley+topy
26 static void plot(cairo_t *cr, int w, int h, struct dive *dive, int samples, struct sample *sample)
29 double topx, topy, maxx, maxy;
30 double scalex, scaley;
31 int maxtime, maxdepth;
32 int begins, sec, depth;
39 cairo_set_line_width(cr, 2);
41 /* Get plot scaling limits */
42 maxtime = round_seconds_up(dive->duration.seconds);
43 maxdepth = round_feet_up(to_feet(dive->maxdepth));
45 /* Depth markers: every 15 ft */
48 cairo_set_source_rgba(cr, 1, 1, 1, 0.5);
49 for (i = 15; i < maxdepth; i += 15) {
50 cairo_move_to(cr, SCALE(0, i));
51 cairo_line_to(cr, SCALE(1, i));
54 /* Time markers: every 5 min */
57 for (i = 5*60; i < maxtime; i += 5*60) {
58 cairo_move_to(cr, SCALE(i, 0));
59 cairo_line_to(cr, SCALE(i, 1));
66 cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.80);
67 begins = sample->time.seconds;
68 cairo_move_to(cr, SCALE(sample->time.seconds, to_feet(sample->depth)));
69 for (i = 1; i < dive->samples; i++) {
71 sec = sample->time.seconds;
72 depth = to_feet(sample->depth);
73 cairo_line_to(cr, SCALE(sec, depth));
76 cairo_line_to(cr, SCALE(sec, 0));
77 cairo_line_to(cr, SCALE(begins, 0));
79 cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.20);
80 cairo_fill_preserve(cr);
81 cairo_set_source_rgba(cr, 1, 0.2, 0.2, 0.80);
84 /* Bounding box last */
85 scalex = scaley = 1.0;
86 cairo_set_source_rgb(cr, 1, 1, 1);
87 cairo_move_to(cr, SCALE(0,0));
88 cairo_line_to(cr, SCALE(0,1));
89 cairo_line_to(cr, SCALE(1,1));
90 cairo_line_to(cr, SCALE(1,0));
96 static gboolean expose_event(GtkWidget *widget, GdkEventExpose *event, gpointer data)
98 struct dive *dive = dive_table.dives[selected_dive];
102 w = widget->allocation.width;
103 h = widget->allocation.height;
105 cr = gdk_cairo_create(widget->window);
106 cairo_set_source_rgb(cr, 0, 0, 0);
110 plot(cr, w, h, dive, dive->samples, dive->sample);
117 GtkWidget *dive_profile_frame(void)
122 frame = gtk_frame_new("Dive profile");
123 gtk_widget_show(frame);
124 da = gtk_drawing_area_new();
125 gtk_widget_set_size_request(da, 450, 350);
126 g_signal_connect(da, "expose_event", G_CALLBACK(expose_event), NULL);
127 gtk_container_add(GTK_CONTAINER(frame), da);