From 68a1ff9cf56576ee3e3f32e08bc7f7ad2b03697f Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sun, 15 Jan 2012 13:19:39 -0800 Subject: Separate out single dive statistics and total statistics Right now this just changes the infrastructure - nothing outside of statistics.c is modified. This is simply in preparation to split out the single dive info and the total dive statistics in the future (as we are creating more info and more stats and they will overflow the screen area available - so this will turn into two notebook tabs). This commit does not change any functionality. Signed-off-by: Dirk Hohndel --- statistics.c | 184 +++++++++++++++++++++++++++++++++++------------------------ 1 file changed, 108 insertions(+), 76 deletions(-) diff --git a/statistics.c b/statistics.c index 9510030d7..60b4776bc 100644 --- a/statistics.c +++ b/statistics.c @@ -29,17 +29,22 @@ typedef struct { *sac, *otu, *o2he, - *gas_used, - *total_time, + *gas_used; +} single_stat_widget_t; + +static single_stat_widget_t single_w; + +typedef struct { + GtkWidget *total_time, *avg_time, *max_overall_depth, *avg_overall_depth, *min_sac, *avg_sac, *max_sac; -} info_stat_widget_t; +} total_stats_widget_t; -static info_stat_widget_t info_stat_w; +static total_stats_widget_t stats_w; typedef struct { duration_t total_time; @@ -49,9 +54,9 @@ typedef struct { volume_t max_sac; volume_t min_sac; volume_t avg_sac; -} info_stat_t; +} stats_t; -static info_stat_t info_stat; +static stats_t stats; static void process_all_dives(struct dive *dive, struct dive **prev_dive) { @@ -60,7 +65,7 @@ static void process_all_dives(struct dive *dive, struct dive **prev_dive) int old_tt, sac_time = 0; *prev_dive = NULL; - memset(&info_stat, 0, sizeof(info_stat)); + memset(&stats, 0, sizeof(stats)); /* this relies on the fact that the dives in the dive_table * are in chronological order */ for (idx = 0; idx < dive_table.nr; idx++) { @@ -70,21 +75,21 @@ static void process_all_dives(struct dive *dive, struct dive **prev_dive) if (idx > 0) *prev_dive = dive_table.dives[idx-1]; } - old_tt = info_stat.total_time.seconds; - info_stat.total_time.seconds += dp->duration.seconds; - if (dp->maxdepth.mm > info_stat.max_depth.mm) - info_stat.max_depth.mm = dp->maxdepth.mm; - info_stat.avg_depth.mm = (1.0 * old_tt * info_stat.avg_depth.mm + - dp->duration.seconds * dp->meandepth.mm) / info_stat.total_time.seconds; + old_tt = stats.total_time.seconds; + stats.total_time.seconds += dp->duration.seconds; + if (dp->maxdepth.mm > stats.max_depth.mm) + stats.max_depth.mm = dp->maxdepth.mm; + stats.avg_depth.mm = (1.0 * old_tt * stats.avg_depth.mm + + dp->duration.seconds * dp->meandepth.mm) / stats.total_time.seconds; if (dp->sac > 2800) { /* less than .1 cuft/min (2800ml/min) is bogus */ int old_sac_time = sac_time; sac_time += dp->duration.seconds; - info_stat.avg_sac.mliter = (1.0 * old_sac_time * info_stat.avg_sac.mliter + + stats.avg_sac.mliter = (1.0 * old_sac_time * stats.avg_sac.mliter + dp->duration.seconds * dp->sac) / sac_time ; - if (dp->sac > info_stat.max_sac.mliter) - info_stat.max_sac.mliter = dp->sac; - if (info_stat.min_sac.mliter == 0 || dp->sac < info_stat.min_sac.mliter) - info_stat.min_sac.mliter = dp->sac; + if (dp->sac > stats.max_sac.mliter) + stats.max_sac.mliter = dp->sac; + if (stats.min_sac.mliter == 0 || dp->sac < stats.min_sac.mliter) + stats.min_sac.mliter = dp->sac; } } } @@ -117,7 +122,7 @@ static char * get_time_string(int seconds, int maxdays) return buf; } -void show_dive_stats(struct dive *dive) +static void show_single_dive_stats(struct dive *dive) { char buf[80]; double value; @@ -137,28 +142,28 @@ void show_dive_stats(struct dive *dive) tm->tm_mday, tm->tm_year + 1900, tm->tm_hour, tm->tm_min); - set_label(info_stat_w.date, buf); - set_label(info_stat_w.dive_time, "%d min", (dive->duration.seconds + 30) / 60); + set_label(single_w.date, buf); + set_label(single_w.dive_time, "%d min", (dive->duration.seconds + 30) / 60); if (prev_dive) - set_label(info_stat_w.surf_intv, + set_label(single_w.surf_intv, get_time_string(dive->when - (prev_dive->when + prev_dive->duration.seconds), 4)); else - set_label(info_stat_w.surf_intv, "unknown"); + set_label(single_w.surf_intv, "unknown"); value = get_depth_units(dive->maxdepth.mm, &decimals, &unit); - set_label(info_stat_w.max_depth, "%.*f %s", decimals, value, unit); + set_label(single_w.max_depth, "%.*f %s", decimals, value, unit); value = get_depth_units(dive->meandepth.mm, &decimals, &unit); - set_label(info_stat_w.avg_depth, "%.*f %s", decimals, value, unit); + set_label(single_w.avg_depth, "%.*f %s", decimals, value, unit); if (dive->watertemp.mkelvin) { value = get_temp_units(dive->watertemp.mkelvin, &unit); - set_label(info_stat_w.water_temp, "%.1f %s", value, unit); + set_label(single_w.water_temp, "%.1f %s", value, unit); } else - set_label(info_stat_w.water_temp, ""); + set_label(single_w.water_temp, ""); value = get_volume_units(dive->sac, &decimals, &unit); if (value > 0) { - set_label(info_stat_w.sac, "%.*f %s/min", decimals, value, unit); + set_label(single_w.sac, "%.*f %s/min", decimals, value, unit); } else - set_label(info_stat_w.sac, ""); - set_label(info_stat_w.otu, "%d", dive->otu); + set_label(single_w.sac, ""); + set_label(single_w.otu, "%d", dive->otu); offset = 0; gas_used = 0; buf[0] = '\0'; @@ -185,25 +190,38 @@ void show_dive_stats(struct dive *dive) if (cyl->type.size.mliter && start && end) gas_used += cyl->type.size.mliter / 1000.0 * (start - end); } - set_label(info_stat_w.o2he, buf); + set_label(single_w.o2he, buf); if (gas_used) { value = get_volume_units(gas_used, &decimals, &unit); - set_label(info_stat_w.gas_used, "%.*f %s", decimals, value, unit); + set_label(single_w.gas_used, "%.*f %s", decimals, value, unit); } else - set_label(info_stat_w.gas_used, ""); - /* and now do the statistics */ - set_label(info_stat_w.total_time, get_time_string(info_stat.total_time.seconds, 0)); - set_label(info_stat_w.avg_time, get_time_string(info_stat.total_time.seconds / dive_table.nr, 0)); - value = get_depth_units(info_stat.max_depth.mm, &decimals, &unit); - set_label(info_stat_w.max_overall_depth, "%.*f %s", decimals, value, unit); - value = get_depth_units(info_stat.avg_depth.mm, &decimals, &unit); - set_label(info_stat_w.avg_overall_depth, "%.*f %s", decimals, value, unit); - value = get_volume_units(info_stat.max_sac.mliter, &decimals, &unit); - set_label(info_stat_w.max_sac, "%.*f %s/min", decimals, value, unit); - value = get_volume_units(info_stat.min_sac.mliter, &decimals, &unit); - set_label(info_stat_w.min_sac, "%.*f %s/min", decimals, value, unit); - value = get_volume_units(info_stat.avg_sac.mliter, &decimals, &unit); - set_label(info_stat_w.avg_sac, "%.*f %s/min", decimals, value, unit); + set_label(single_w.gas_used, ""); +} + +static void show_total_dive_stats(struct dive *dive) +{ + double value; + int decimals; + const char *unit; + + set_label(stats_w.total_time, get_time_string(stats.total_time.seconds, 0)); + set_label(stats_w.avg_time, get_time_string(stats.total_time.seconds / dive_table.nr, 0)); + value = get_depth_units(stats.max_depth.mm, &decimals, &unit); + set_label(stats_w.max_overall_depth, "%.*f %s", decimals, value, unit); + value = get_depth_units(stats.avg_depth.mm, &decimals, &unit); + set_label(stats_w.avg_overall_depth, "%.*f %s", decimals, value, unit); + value = get_volume_units(stats.max_sac.mliter, &decimals, &unit); + set_label(stats_w.max_sac, "%.*f %s/min", decimals, value, unit); + value = get_volume_units(stats.min_sac.mliter, &decimals, &unit); + set_label(stats_w.min_sac, "%.*f %s/min", decimals, value, unit); + value = get_volume_units(stats.avg_sac.mliter, &decimals, &unit); + set_label(stats_w.avg_sac, "%.*f %s/min", decimals, value, unit); +} + +void show_dive_stats(struct dive *dive) +{ + show_single_dive_stats(dive); + show_total_dive_stats(dive); } void flush_dive_stats_changes(struct dive *dive) @@ -224,64 +242,78 @@ static GtkWidget *new_info_label_in_frame(GtkWidget *box, const char *label) return label_widget; } -GtkWidget *stats_widget(void) +static GtkWidget *total_stats_widget(GtkWidget *vbox) { - GtkWidget *vbox, *hbox, *infoframe, *statsframe, *framebox; + GtkWidget *hbox, *statsframe, *framebox; - vbox = gtk_vbox_new(FALSE, 3); - - infoframe = gtk_frame_new("Dive Info"); - gtk_box_pack_start(GTK_BOX(vbox), infoframe, TRUE, FALSE, 3); + statsframe = gtk_frame_new("Statistics"); + gtk_box_pack_start(GTK_BOX(vbox), statsframe, TRUE, FALSE, 3); framebox = gtk_vbox_new(FALSE, 3); - gtk_container_add(GTK_CONTAINER(infoframe), framebox); + gtk_container_add(GTK_CONTAINER(statsframe), framebox); /* first row */ hbox = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3); - info_stat_w.date = new_info_label_in_frame(hbox, "Date"); - info_stat_w.dive_time = new_info_label_in_frame(hbox, "Dive Time"); - info_stat_w.surf_intv = new_info_label_in_frame(hbox, "Surf Intv"); + stats_w.total_time = new_info_label_in_frame(hbox, "Total Time"); + stats_w.avg_time = new_info_label_in_frame(hbox, "Avg Time"); + stats_w.max_overall_depth = new_info_label_in_frame(hbox, "Max Depth"); + stats_w.avg_overall_depth = new_info_label_in_frame(hbox, "Avg Depth"); /* second row */ hbox = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3); - info_stat_w.max_depth = new_info_label_in_frame(hbox, "Max Depth"); - info_stat_w.avg_depth = new_info_label_in_frame(hbox, "Avg Depth"); - info_stat_w.water_temp = new_info_label_in_frame(hbox, "Water Temp"); + stats_w.max_sac = new_info_label_in_frame(hbox, "Max SAC"); + stats_w.min_sac = new_info_label_in_frame(hbox, "Min SAC"); + stats_w.avg_sac = new_info_label_in_frame(hbox, "Avg SAC"); - /* third row */ - hbox = gtk_hbox_new(FALSE, 3); - gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3); + return vbox; +} + +static GtkWidget *single_stats_widget(void) +{ - info_stat_w.sac = new_info_label_in_frame(hbox, "SAC"); - info_stat_w.otu = new_info_label_in_frame(hbox, "OTU"); - info_stat_w.o2he = new_info_label_in_frame(hbox, "O" UTF8_SUBSCRIPT_2 " / He"); - info_stat_w.gas_used = new_info_label_in_frame(hbox, "Gas Used"); + GtkWidget *vbox, *hbox, *infoframe, *framebox; - statsframe = gtk_frame_new("Statistics"); - gtk_box_pack_start(GTK_BOX(vbox), statsframe, TRUE, FALSE, 3); + vbox = gtk_vbox_new(FALSE, 3); + + infoframe = gtk_frame_new("Dive Info"); + gtk_box_pack_start(GTK_BOX(vbox), infoframe, TRUE, FALSE, 3); framebox = gtk_vbox_new(FALSE, 3); - gtk_container_add(GTK_CONTAINER(statsframe), framebox); + gtk_container_add(GTK_CONTAINER(infoframe), framebox); /* first row */ hbox = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3); - info_stat_w.total_time = new_info_label_in_frame(hbox, "Total Time"); - info_stat_w.avg_time = new_info_label_in_frame(hbox, "Avg Time"); - info_stat_w.max_overall_depth = new_info_label_in_frame(hbox, "Max Depth"); - info_stat_w.avg_overall_depth = new_info_label_in_frame(hbox, "Avg Depth"); + single_w.date = new_info_label_in_frame(hbox, "Date"); + single_w.dive_time = new_info_label_in_frame(hbox, "Dive Time"); + single_w.surf_intv = new_info_label_in_frame(hbox, "Surf Intv"); /* second row */ hbox = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3); - info_stat_w.max_sac = new_info_label_in_frame(hbox, "Max SAC"); - info_stat_w.min_sac = new_info_label_in_frame(hbox, "Min SAC"); - info_stat_w.avg_sac = new_info_label_in_frame(hbox, "Avg SAC"); + single_w.max_depth = new_info_label_in_frame(hbox, "Max Depth"); + single_w.avg_depth = new_info_label_in_frame(hbox, "Avg Depth"); + single_w.water_temp = new_info_label_in_frame(hbox, "Water Temp"); + + /* third row */ + hbox = gtk_hbox_new(FALSE, 3); + gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3); + + single_w.sac = new_info_label_in_frame(hbox, "SAC"); + single_w.otu = new_info_label_in_frame(hbox, "OTU"); + single_w.o2he = new_info_label_in_frame(hbox, "O" UTF8_SUBSCRIPT_2 " / He"); + single_w.gas_used = new_info_label_in_frame(hbox, "Gas Used"); return vbox; } + +GtkWidget* stats_widget(void) +{ + GtkWidget *vbox = single_stats_widget(); + return total_stats_widget(vbox); +} -- cgit v1.2.3-70-g09d2 From 788ebc0500b12fb502b82473c1459ccca06345a5 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sun, 15 Jan 2012 14:29:08 -0800 Subject: Create separate single dive and total stats pages No additional statistics added, yet. Signed-off-by: Dirk Hohndel --- display-gtk.h | 3 ++- gtk-gui.c | 22 ++++++++++++---------- statistics.c | 14 ++++---------- 3 files changed, 18 insertions(+), 21 deletions(-) diff --git a/display-gtk.h b/display-gtk.h index b55dc9616..f43e3746f 100644 --- a/display-gtk.h +++ b/display-gtk.h @@ -61,7 +61,8 @@ extern GtkWidget *dive_profile_widget(void); extern GtkWidget *dive_info_frame(void); extern GtkWidget *extended_dive_info_widget(void); extern GtkWidget *equipment_widget(void); -extern GtkWidget *stats_widget(void); +extern GtkWidget *single_stats_widget(void); +extern GtkWidget *total_stats_widget(void); extern GtkWidget *cylinder_list_widget(void); extern GtkWidget *dive_list_create(void); diff --git a/gtk-gui.c b/gtk-gui.c index e16d60e2d..45185c016 100644 --- a/gtk-gui.c +++ b/gtk-gui.c @@ -646,10 +646,8 @@ void init_ui(int *argcp, char ***argvp) { GtkWidget *win; GtkWidget *notebook; - GtkWidget *dive_info; + GtkWidget *nb_page; GtkWidget *dive_list; - GtkWidget *equipment; - GtkWidget *stats; GtkWidget *menubar; GtkWidget *vbox; GdkScreen *screen; @@ -735,16 +733,20 @@ void init_ui(int *argcp, char ***argvp) gtk_paned_add2(GTK_PANED(hpane), dive_profile); /* Frame for extended dive info */ - dive_info = extended_dive_info_widget(); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), dive_info, gtk_label_new("Dive Notes")); + nb_page = extended_dive_info_widget(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new("Dive Notes")); /* Frame for dive equipment */ - equipment = equipment_widget(); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), equipment, gtk_label_new("Equipment")); + nb_page = equipment_widget(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new("Equipment")); - /* Frame for dive statistics */ - stats = stats_widget(); - gtk_notebook_append_page(GTK_NOTEBOOK(notebook), stats, gtk_label_new("Info & Stats")); + /* Frame for single dive statistics */ + nb_page = single_stats_widget(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new("Dive Info")); + + /* Frame for total dive statistics */ + nb_page = total_stats_widget(); + gtk_notebook_append_page(GTK_NOTEBOOK(notebook), nb_page, gtk_label_new("Overall Stats")); gtk_widget_set_app_paintable(win, TRUE); gtk_widget_show_all(win); diff --git a/statistics.c b/statistics.c index 60b4776bc..5017fe0b2 100644 --- a/statistics.c +++ b/statistics.c @@ -242,10 +242,11 @@ static GtkWidget *new_info_label_in_frame(GtkWidget *box, const char *label) return label_widget; } -static GtkWidget *total_stats_widget(GtkWidget *vbox) +GtkWidget *total_stats_widget(void) { + GtkWidget *vbox, *hbox, *statsframe, *framebox; - GtkWidget *hbox, *statsframe, *framebox; + vbox = gtk_vbox_new(FALSE, 3); statsframe = gtk_frame_new("Statistics"); gtk_box_pack_start(GTK_BOX(vbox), statsframe, TRUE, FALSE, 3); @@ -272,9 +273,8 @@ static GtkWidget *total_stats_widget(GtkWidget *vbox) return vbox; } -static GtkWidget *single_stats_widget(void) +GtkWidget *single_stats_widget(void) { - GtkWidget *vbox, *hbox, *infoframe, *framebox; vbox = gtk_vbox_new(FALSE, 3); @@ -311,9 +311,3 @@ static GtkWidget *single_stats_widget(void) return vbox; } - -GtkWidget* stats_widget(void) -{ - GtkWidget *vbox = single_stats_widget(); - return total_stats_widget(vbox); -} -- cgit v1.2.3-70-g09d2 From dfb94e5470565bc5ad1fd2d0678ef427706bed6c Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sun, 15 Jan 2012 15:21:56 -0800 Subject: Add statistics for longest, shortest, and shallowest dive I don't really like calling the shallowest dive "min depth", but all other texts that I could come up with that were reasonably short weren't any better... Signed-off-by: Dirk Hohndel --- statistics.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/statistics.c b/statistics.c index 5017fe0b2..2669d5302 100644 --- a/statistics.c +++ b/statistics.c @@ -37,7 +37,10 @@ static single_stat_widget_t single_w; typedef struct { GtkWidget *total_time, *avg_time, + *shortest_time, + *longest_time, *max_overall_depth, + *min_overall_depth, *avg_overall_depth, *min_sac, *avg_sac, @@ -49,7 +52,10 @@ static total_stats_widget_t stats_w; typedef struct { duration_t total_time; /* avg_time is simply total_time / nr -- let's not keep this */ + duration_t shortest_time; + duration_t longest_time; depth_t max_depth; + depth_t min_depth; depth_t avg_depth; volume_t max_sac; volume_t min_sac; @@ -66,6 +72,10 @@ static void process_all_dives(struct dive *dive, struct dive **prev_dive) *prev_dive = NULL; memset(&stats, 0, sizeof(stats)); + if (dive_table.nr > 0) { + stats.shortest_time.seconds = dive_table.dives[0]->duration.seconds; + stats.min_depth.mm = dive_table.dives[0]->maxdepth.mm; + } /* this relies on the fact that the dives in the dive_table * are in chronological order */ for (idx = 0; idx < dive_table.nr; idx++) { @@ -77,8 +87,14 @@ static void process_all_dives(struct dive *dive, struct dive **prev_dive) } old_tt = stats.total_time.seconds; stats.total_time.seconds += dp->duration.seconds; + if (dp->duration.seconds > stats.longest_time.seconds) + stats.longest_time.seconds = dp->duration.seconds; + if (dp->duration.seconds < stats.shortest_time.seconds) + stats.shortest_time.seconds = dp->duration.seconds; if (dp->maxdepth.mm > stats.max_depth.mm) stats.max_depth.mm = dp->maxdepth.mm; + if (dp->maxdepth.mm < stats.min_depth.mm) + stats.min_depth.mm = dp->maxdepth.mm; stats.avg_depth.mm = (1.0 * old_tt * stats.avg_depth.mm + dp->duration.seconds * dp->meandepth.mm) / stats.total_time.seconds; if (dp->sac > 2800) { /* less than .1 cuft/min (2800ml/min) is bogus */ @@ -206,8 +222,12 @@ static void show_total_dive_stats(struct dive *dive) set_label(stats_w.total_time, get_time_string(stats.total_time.seconds, 0)); set_label(stats_w.avg_time, get_time_string(stats.total_time.seconds / dive_table.nr, 0)); + set_label(stats_w.longest_time, get_time_string(stats.longest_time.seconds, 0)); + set_label(stats_w.shortest_time, get_time_string(stats.shortest_time.seconds, 0)); value = get_depth_units(stats.max_depth.mm, &decimals, &unit); set_label(stats_w.max_overall_depth, "%.*f %s", decimals, value, unit); + value = get_depth_units(stats.min_depth.mm, &decimals, &unit); + set_label(stats_w.min_overall_depth, "%.*f %s", decimals, value, unit); value = get_depth_units(stats.avg_depth.mm, &decimals, &unit); set_label(stats_w.avg_overall_depth, "%.*f %s", decimals, value, unit); value = get_volume_units(stats.max_sac.mliter, &decimals, &unit); @@ -220,6 +240,8 @@ static void show_total_dive_stats(struct dive *dive) void show_dive_stats(struct dive *dive) { + /* they have to be called in this order, as 'total' depends on + * calculations done in 'single' */ show_single_dive_stats(dive); show_total_dive_stats(dive); } @@ -259,10 +281,18 @@ GtkWidget *total_stats_widget(void) stats_w.total_time = new_info_label_in_frame(hbox, "Total Time"); stats_w.avg_time = new_info_label_in_frame(hbox, "Avg Time"); + stats_w.longest_time = new_info_label_in_frame(hbox, "Longest Dive"); + stats_w.shortest_time = new_info_label_in_frame(hbox, "Shortest Dive"); + + /* second row */ + hbox = gtk_hbox_new(FALSE, 3); + gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3); + stats_w.max_overall_depth = new_info_label_in_frame(hbox, "Max Depth"); + stats_w.min_overall_depth = new_info_label_in_frame(hbox, "Min Depth"); stats_w.avg_overall_depth = new_info_label_in_frame(hbox, "Avg Depth"); - /* second row */ + /* third row */ hbox = gtk_hbox_new(FALSE, 3); gtk_box_pack_start(GTK_BOX(framebox), hbox, TRUE, FALSE, 3); -- cgit v1.2.3-70-g09d2