From 8677721e85a344e29782cfc2ab838edb8da9215b Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 3 May 2013 11:04:51 -0700 Subject: Remove the majority of the Gtk related code - rip all Gtk code from qt-gui.cpp - don't compile Gtk specific files - don't link against Gtk libraries - don't compile modules we don't use at all (yet) - use #if USE_GTK_UI on the remaining files to disable Gtk related parts - disable the non-functional Cochran support while I'm at it Signed-off-by: Dirk Hohndel --- profile.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 18960fcff..bd395f127 100644 --- a/profile.c +++ b/profile.c @@ -136,6 +136,8 @@ static const color_t profile_color[] = { }; +#if USE_GTK_UI + /* Scale to 0,0 -> maxx,maxy */ #define SCALEX(gc,x) (((x)-gc->leftx)/(gc->rightx-gc->leftx)*gc->maxx) #define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy) @@ -189,8 +191,7 @@ static void pattern_add_color_stop_rgba(struct graphics_context *gc, cairo_patte struct rgba rgb = col->media[gc->printer]; cairo_pattern_add_color_stop_rgba(pat, o, rgb.r, rgb.g, rgb.b, rgb.a); } - -#define ROUND_UP(x,y) ((((x)+(y)-1)/(y))*(y)) +#endif /* USE_GTK_UI */ /* debugging tool - not normally used */ static void dump_pi (struct plot_info *pi) @@ -215,6 +216,8 @@ static void dump_pi (struct plot_info *pi) printf(" }\n"); } +#define ROUND_UP(x,y) ((((x)+(y)-1)/(y))*(y)) + /* * When showing dive profiles, we scale things to the * current dive. However, we don't scale past less than @@ -276,6 +279,7 @@ typedef struct { #define MIDDLE (0) #define BOTTOM (-1) +#if USE_GTK_UI static void plot_text(struct graphics_context *gc, const text_render_options_t *tro, double x, double y, const char *fmt, ...) { @@ -308,6 +312,7 @@ static void plot_text(struct graphics_context *gc, const text_render_options_t * set_source_rgba(gc, tro->color); cairo_show_text(cr, buffer); } +#endif /* USE_GTK_UI */ /* collect all event names and whether we display them */ struct ev_select { @@ -357,6 +362,7 @@ void remember_event(const char *eventname) evn_used++; } +#if USE_GTK_UI static void plot_one_event(struct graphics_context *gc, struct plot_info *pi, struct event *event) { int i, depth = 0; @@ -1027,6 +1033,7 @@ static void set_sac_color(struct graphics_context *gc, int sac, int avg_sac) set_source_rgba(gc, SAC_DEFAULT); } } +#endif /* USE_GTK_UI */ /* Get local sac-rate (in ml/min) between entry1 and entry2 */ static int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive) @@ -1065,6 +1072,7 @@ static int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, str #define SAC_WINDOW 45 /* sliding window in seconds for current SAC calculation */ +#if USE_GTK_UI static void plot_cylinder_pressure(struct graphics_context *gc, struct plot_info *pi, struct dive *dive, struct divecomputer *dc) { @@ -1189,6 +1197,7 @@ static void plot_deco_text(struct graphics_context *gc, struct plot_info *pi) plot_text(gc, &tro, x, y, "GF %.0f/%.0f", prefs.gflow * 100, prefs.gfhigh * 100); } } +#endif /* USE_GTK_UI */ static void analyze_plot_info_minmax_minute(struct plot_data *entry, struct plot_data *first, struct plot_data *last, int index) { @@ -1259,6 +1268,7 @@ static velocity_t velocity(int speed) return v; } + static struct plot_info *analyze_plot_info(struct plot_info *pi) { int i; @@ -1974,6 +1984,7 @@ static struct plot_info *create_plot_info(struct dive *dive, struct divecomputer return analyze_plot_info(pi); } +#if USE_GTK_UI static void plot_set_scale(scale_mode_t scale) { switch (scale) { @@ -1986,6 +1997,7 @@ static void plot_set_scale(scale_mode_t scale) break; } } +#endif /* make sure you pass this the FIRST dc - it just walks the list */ static int nr_dcs(struct divecomputer *main) @@ -2015,6 +2027,7 @@ struct divecomputer *select_dc(struct divecomputer *main) return main; } +#if USE_GTK_UI void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale) { struct plot_info *pi; @@ -2132,6 +2145,7 @@ void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale) pi->nr = 0; } } +#endif /* USE_GTK_UI */ static void plot_string(struct plot_data *entry, char *buf, size_t bufsize, int depth, int pressure, int temp, gboolean has_ndl) -- cgit v1.2.3-70-g09d2 From 060e5c764cc66e54f422928e3921fd08dff31f69 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 3 May 2013 13:32:23 -0700 Subject: Matching build fixes for cross built Windows Signed-off-by: Dirk Hohndel --- linux.c | 2 ++ macos.c | 3 +++ packaging/windows/subsurface.res | Bin 18056 -> 0 bytes profile.c | 2 ++ windows.c | 7 +++++++ 5 files changed, 14 insertions(+) delete mode 100644 packaging/windows/subsurface.res (limited to 'profile.c') diff --git a/linux.c b/linux.c index 51d1ce75d..33a846f9b 100644 --- a/linux.c +++ b/linux.c @@ -2,7 +2,9 @@ /* implements Linux specific functions */ #include "dive.h" #include "display.h" +#if USE_GTK_UI #include "display-gtk.h" +#endif #include #include diff --git a/macos.c b/macos.c index d28ea1dae..b43849f87 100644 --- a/macos.c +++ b/macos.c @@ -2,7 +2,10 @@ /* implements Mac OS X specific functions */ #include #include "dive.h" +#include "display.h" +#if USE_GTK_UI #include "display-gtk.h" +#endif /* USE_GTK_UI */ #include #include #include diff --git a/packaging/windows/subsurface.res b/packaging/windows/subsurface.res deleted file mode 100644 index 616cf5ea9..000000000 Binary files a/packaging/windows/subsurface.res and /dev/null differ diff --git a/profile.c b/profile.c index bd395f127..f30ff1d06 100644 --- a/profile.c +++ b/profile.c @@ -6,7 +6,9 @@ #include "dive.h" #include "display.h" +#if USE_GTK_UI #include "display-gtk.h" +#endif #include "divelist.h" #include "color.h" #include "libdivecomputer/parser.h" diff --git a/windows.c b/windows.c index 94e3dc546..d6cb531ae 100644 --- a/windows.c +++ b/windows.c @@ -1,7 +1,10 @@ /* windows.c */ /* implements Windows specific functions */ #include "dive.h" +#include "display.h" +#if USE_GTK_UI #include "display-gtk.h" +#endif #include #include @@ -128,6 +131,7 @@ void subsurface_close_conf(void) RegCloseKey(hkey); } +#if USE_GTK_UI int subsurface_fill_device_list(GtkListStore *store) { const int bufdef = 512; @@ -194,6 +198,7 @@ int subsurface_fill_device_list(GtkListStore *store) } return index; } +#endif /* USE_GTK_UI */ const char *subsurface_icon_name() { @@ -231,11 +236,13 @@ const char *subsurface_gettext_domainpath(char *argv0) return "./share/locale"; } +#if USE_GTK_UI void subsurface_ui_setup(GtkSettings *settings, GtkWidget *menubar, GtkWidget *vbox, GtkUIManager *ui_manager) { gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0); } +#endif /* USE_GTK_UI */ /* barely documented API */ extern int __wgetmainargs(int *, wchar_t ***, wchar_t ***, int, int *); -- cgit v1.2.3-70-g09d2 From 98414ac9a9ab927b475088a982ebaf8200c647c8 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 3 May 2013 14:16:09 -0700 Subject: Fix compiler warnings Doing this on Arch Linux with gcc 4.8.0 helped find one real bug. The rest are simply changes to make static functions externally visible (as they are kept around to eventually become helpers used by Qt) which for now avoids the warnings. Signed-off-by: Dirk Hohndel --- divelist.c | 6 +++--- download-dialog.c | 6 +++--- equipment.c | 2 +- profile.c | 16 +++++++++------- 4 files changed, 16 insertions(+), 14 deletions(-) (limited to 'profile.c') diff --git a/divelist.c b/divelist.c index e22dd331a..deab1b05c 100644 --- a/divelist.c +++ b/divelist.c @@ -620,12 +620,12 @@ char *get_nitrox_string(struct dive *dive) o2low = (o2low + 5) / 10; if (he) - snprintf(buffer, sizeof(buffer), "%d/%d", o2, he); + snprintf(buffer, MAX_NITROX_STRING, "%d/%d", o2, he); else if (o2) if (o2 == o2low) - snprintf(buffer, sizeof(buffer), "%d", o2); + snprintf(buffer, MAX_NITROX_STRING, "%d", o2); else - snprintf(buffer, sizeof(buffer), "%d" UTF8_ELLIPSIS "%d", o2low, o2); + snprintf(buffer, MAX_NITROX_STRING, "%d" UTF8_ELLIPSIS "%d", o2low, o2); else strcpy(buffer, _("air")); } diff --git a/download-dialog.c b/download-dialog.c index 729f3a6b6..e12b07abd 100644 --- a/download-dialog.c +++ b/download-dialog.c @@ -81,7 +81,7 @@ int is_default_dive_computer_device(const char *name) return default_dive_computer_device && !strcmp(name, default_dive_computer_device); } -static void set_default_dive_computer(const char *vendor, const char *product) +void set_default_dive_computer(const char *vendor, const char *product) { if (!vendor || !*vendor) return; @@ -99,7 +99,7 @@ static void set_default_dive_computer(const char *vendor, const char *product) subsurface_set_conf("dive_computer_product", product); } -static void set_default_dive_computer_device(const char *name) +void set_default_dive_computer_device(const char *name) { if (!name || !*name) return; @@ -159,7 +159,7 @@ static GtkWidget *import_dive_computer(device_data_t *data, GtkDialog *dialog) #endif /* create a list of lists and keep the elements sorted */ -static void add_dc(const char *vendor, const char *product, dc_descriptor_t *descriptor) +void add_dc(const char *vendor, const char *product, dc_descriptor_t *descriptor) { struct vendor *dcl = dc_list; struct vendor **dclp = &dc_list; diff --git a/equipment.c b/equipment.c index 93f26dab1..4c692f33b 100644 --- a/equipment.c +++ b/equipment.c @@ -112,7 +112,7 @@ void convert_volume_pressure(int ml, int mbar, double *v, double *p) *v = volume; } -static int convert_weight(int grams, double *m) +int convert_weight(int grams, double *m) { int decimals = 1; /* not sure - do people do less than whole lbs/kg ? */ double weight; diff --git a/profile.c b/profile.c index f30ff1d06..b9a633cf6 100644 --- a/profile.c +++ b/profile.c @@ -18,7 +18,10 @@ int selected_dive = 0; char zoomed_plot = 0; char dc_number = 0; +#if USE_GTK_UI static double plot_scale = SCALE_SCREEN; +#endif + static struct plot_data *last_pi_entry = NULL; #define cairo_set_line_width_scaled(cr, w) \ @@ -228,7 +231,7 @@ static void dump_pi (struct plot_info *pi) * We also need to add 180 seconds at the end so the min/max * plots correctly */ -static int get_maxtime(struct plot_info *pi) +int get_maxtime(struct plot_info *pi) { int seconds = pi->maxtime; if (zoomed_plot) { @@ -251,7 +254,7 @@ static int get_maxtime(struct plot_info *pi) /* get the maximum depth to which we want to plot * take into account the additional verical space needed to plot * partial pressure graphs */ -static int get_maxdepth(struct plot_info *pi) +int get_maxdepth(struct plot_info *pi) { unsigned mm = pi->maxdepth; int md; @@ -1018,8 +1021,7 @@ static int get_cylinder_pressure_range(struct graphics_context *gc, struct plot_ * as compared to avg_sac; the calculation simply maps the delta between * sac and avg_sac to indexes 0 .. (SAC_COLORS - 1) with everything * more than 6000 ml/min below avg_sac mapped to 0 */ - -static void set_sac_color(struct graphics_context *gc, int sac, int avg_sac) +void set_sac_color(struct graphics_context *gc, int sac, int avg_sac) { int sac_index = 0; int delta = sac - avg_sac + 7000; @@ -1038,7 +1040,7 @@ static void set_sac_color(struct graphics_context *gc, int sac, int avg_sac) #endif /* USE_GTK_UI */ /* Get local sac-rate (in ml/min) between entry1 and entry2 */ -static int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive) +int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive) { int index = entry1->cylinderindex; cylinder_t *cyl; @@ -1597,7 +1599,7 @@ static void check_gas_change_events(struct dive *dive, struct divecomputer *dc, set_cylinder_index(pi, i, cylinderindex, ~0u); } -static void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc) +void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc) { struct plot_info *pi; int maxdepth; @@ -1953,7 +1955,7 @@ static void calculate_deco_information(struct dive *dive, struct divecomputer *d * sides, so that you can do end-points without having to worry * about it. */ -static struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc) +struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc) { struct plot_info *pi; -- cgit v1.2.3-70-g09d2 From ec4d4566adc59d5fa2642c5f4ca12653b3f384a3 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sat, 4 May 2013 16:41:49 -0300 Subject: Converted the Colors.h code to Qt The colors on colors.h were done to fill a special struct by Subsurface - I removed that structure and replaced the code that generated the map of colors to a QMap. I know that this changes are not very 'welcomed', but C++ has issues on creating & initializing complex static members, this was the best way that I could think of. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- color.h | 80 ++++++++++++++++++++++--------------------- profile.c | 86 ++--------------------------------------------- qt-ui/profilegraphics.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 122 deletions(-) (limited to 'profile.c') diff --git a/color.h b/color.h index 5d88fb5f7..f2013bcc9 100644 --- a/color.h +++ b/color.h @@ -4,54 +4,56 @@ /* The colors are named by picking the closest match from http://chir.ag/projects/name-that-color */ +#include + // Greens -#define CAMARONE1 { 0.0, 0.4, 0.0, 1 } -#define FUNGREEN1 { 0.0, 0.4, 0.2, 1 } -#define FUNGREEN1_HIGH_TRANS { 0.0, 0.4, 0.2, 0.25 } -#define KILLARNEY1 { 0.2, 0.4, 0.2, 1 } -#define APPLE1 { 0.2, 0.6, 0.2, 1 } -#define APPLE1_MED_TRANS { 0.2, 0.6, 0.2, 0.5 } -#define APPLE1_HIGH_TRANS { 0.2, 0.6, 0.2, 0.25 } -#define LIMENADE1 { 0.4, 0.8, 0.0, 1 } -#define ATLANTIS1 { 0.4, 0.8, 0.2, 1 } -#define ATLANTIS2 { 0.6, 0.8, 0.2, 1 } -#define RIOGRANDE1 { 0.8, 0.8, 0.0, 1 } -#define EARLSGREEN1 { 0.8, 0.8, 0.2, 1 } -#define FORESTGREEN1 { 0.1, 0.5, 0.1, 1 } +#define CAMARONE1 QColor::fromRgbF( 0.0, 0.4, 0.0, 1 ) +#define FUNGREEN1 QColor::fromRgbF( 0.0, 0.4, 0.2, 1 ) +#define FUNGREEN1_HIGH_TRANS QColor::fromRgbF( 0.0, 0.4, 0.2, 0.25 ) +#define KILLARNEY1 QColor::fromRgbF( 0.2, 0.4, 0.2, 1 ) +#define APPLE1 QColor::fromRgbF( 0.2, 0.6, 0.2, 1 ) +#define APPLE1_MED_TRANS QColor::fromRgbF( 0.2, 0.6, 0.2, 0.5 ) +#define APPLE1_HIGH_TRANS QColor::fromRgbF( 0.2, 0.6, 0.2, 0.25 ) +#define LIMENADE1 QColor::fromRgbF( 0.4, 0.8, 0.0, 1 ) +#define ATLANTIS1 QColor::fromRgbF( 0.4, 0.8, 0.2, 1 ) +#define ATLANTIS2 QColor::fromRgbF( 0.6, 0.8, 0.2, 1 ) +#define RIOGRANDE1 QColor::fromRgbF( 0.8, 0.8, 0.0, 1 ) +#define EARLSGREEN1 QColor::fromRgbF( 0.8, 0.8, 0.2, 1 ) +#define FORESTGREEN1 QColor::fromRgbF( 0.1, 0.5, 0.1, 1 ) // Reds -#define PERSIANRED1 { 0.8, 0.2, 0.2, 1 } -#define TUSCANY1 { 0.8, 0.4, 0.2, 1 } -#define PIRATEGOLD1 { 0.8, 0.5, 0.0, 1 } -#define HOKEYPOKEY1 { 0.8, 0.6, 0.2, 1 } -#define CINNABAR1 { 0.9, 0.3, 0.2, 1 } -#define REDORANGE1 { 1.0, 0.2, 0.2, 1 } -#define REDORANGE1_HIGH_TRANS { 1.0, 0.2, 0.2, 0.25 } -#define REDORANGE1_MED_TRANS { 1.0, 0.2, 0.2, 0.5 } -#define RED1_MED_TRANS { 1.0, 0.0, 0.0, 0.5 } -#define RED1 { 1.0, 0.0, 0.0, 1 } +#define PERSIANRED1 QColor::fromRgbF( 0.8, 0.2, 0.2, 1 ) +#define TUSCANY1 QColor::fromRgbF( 0.8, 0.4, 0.2, 1 ) +#define PIRATEGOLD1 QColor::fromRgbF( 0.8, 0.5, 0.0, 1 ) +#define HOKEYPOKEY1 QColor::fromRgbF( 0.8, 0.6, 0.2, 1 ) +#define CINNABAR1 QColor::fromRgbF( 0.9, 0.3, 0.2, 1 ) +#define REDORANGE1 QColor::fromRgbF( 1.0, 0.2, 0.2, 1 ) +#define REDORANGE1_HIGH_TRANS QColor::fromRgbF( 1.0, 0.2, 0.2, 0.25 ) +#define REDORANGE1_MED_TRANS QColor::fromRgbF( 1.0, 0.2, 0.2, 0.5 ) +#define RED1_MED_TRANS QColor::fromRgbF( 1.0, 0.0, 0.0, 0.5 ) +#define RED1 QColor::fromRgbF( 1.0, 0.0, 0.0, 1 ) // Monochromes -#define BLACK1_LOW_TRANS { 0.0, 0.0, 0.0, 0.75 } -#define BLACK1_HIGH_TRANS { 0.0, 0.0, 0.0, 0.25 } -#define TUNDORA1_MED_TRANS { 0.3, 0.3, 0.3, 0.5 } -#define MERCURY1_MED_TRANS { 0.9, 0.9, 0.9, 0.5 } -#define CONCRETE1_LOWER_TRANS { 0.95, 0.95, 0.95, 0.9 } -#define WHITE1_MED_TRANS { 1.0, 1.0, 1.0, 0.5 } -#define WHITE1 { 1.0, 1.0, 1.0, 1 } +#define BLACK1_LOW_TRANS QColor::fromRgbF( 0.0, 0.0, 0.0, 0.75 ) +#define BLACK1_HIGH_TRANS QColor::fromRgbF( 0.0, 0.0, 0.0, 0.25 ) +#define TUNDORA1_MED_TRANS QColor::fromRgbF( 0.3, 0.3, 0.3, 0.5 ) +#define MERCURY1_MED_TRANS QColor::fromRgbF( 0.9, 0.9, 0.9, 0.5 ) +#define CONCRETE1_LOWER_TRANS QColor::fromRgbF( 0.95, 0.95, 0.95, 0.9 ) +#define WHITE1_MED_TRANS QColor::fromRgbF( 1.0, 1.0, 1.0, 0.5 ) +#define WHITE1 QColor::fromRgbF( 1.0, 1.0, 1.0, 1 ) // Blues -#define GOVERNORBAY2 { 0.2, 0.2, 0.7, 1 } -#define GOVERNORBAY1_MED_TRANS { 0.2, 0.2, 0.8, 0.5 } -#define ROYALBLUE2 { 0.2, 0.2, 0.9, 1 } -#define ROYALBLUE2_LOW_TRANS { 0.2, 0.2, 0.9, 0.75 } +#define GOVERNORBAY2 QColor::fromRgbF( 0.2, 0.2, 0.7, 1 ) +#define GOVERNORBAY1_MED_TRANS QColor::fromRgbF( 0.2, 0.2, 0.8, 0.5 ) +#define ROYALBLUE2 QColor::fromRgbF( 0.2, 0.2, 0.9, 1 ) +#define ROYALBLUE2_LOW_TRANS QColor::fromRgbF( 0.2, 0.2, 0.9, 0.75 ) // Yellows / BROWNS -#define SPRINGWOOD1 { 0.95, 0.95, 0.9, 1 } -#define BROOM1_LOWER_TRANS { 1.0, 1.0, 0.1, 0.9 } -#define PEANUT { 0.5, 0.2, 0.1, 1.0 } -#define PEANUT_MED_TRANS { 0.5, 0.2, 0.1, 0.5 } +#define SPRINGWOOD1 QColor::fromRgbF( 0.95, 0.95, 0.9, 1 ) +#define BROOM1_LOWER_TRANS QColor::fromRgbF( 1.0, 1.0, 0.1, 0.9 ) +#define PEANUT QColor::fromRgbF( 0.5, 0.2, 0.1, 1.0 ) +#define PEANUT_MED_TRANS QColor::fromRgbF( 0.5, 0.2, 0.1, 0.5 ) // Magentas -#define MEDIUMREDVIOLET1_HIGHER_TRANS { 0.7, 0.2, 0.7, 0.1 } +#define MEDIUMREDVIOLET1_HIGHER_TRANS QColor::fromRgbF( 0.7, 0.2, 0.7, 0.1 ) #endif diff --git a/profile.c b/profile.c index b9a633cf6..fa0a24a06 100644 --- a/profile.c +++ b/profile.c @@ -10,7 +10,7 @@ #include "display-gtk.h" #endif #include "divelist.h" -#include "color.h" + #include "libdivecomputer/parser.h" #include "libdivecomputer/version.h" @@ -59,88 +59,6 @@ struct plot_data { #define INTERPOLATED_PRESSURE(_entry) (_entry)->pressure[INTERPOLATED_PR] #define GET_PRESSURE(_entry) (SENSOR_PRESSURE(_entry) ? : INTERPOLATED_PRESSURE(_entry)) -#define SAC_COLORS_START_IDX SAC_1 -#define SAC_COLORS 9 -#define VELOCITY_COLORS_START_IDX VELO_STABLE -#define VELOCITY_COLORS 5 - -typedef enum { - /* SAC colors. Order is important, the SAC_COLORS_START_IDX define above. */ - SAC_1, SAC_2, SAC_3, SAC_4, SAC_5, SAC_6, SAC_7, SAC_8, SAC_9, - - /* Velocity colors. Order is still important, ref VELOCITY_COLORS_START_IDX. */ - VELO_STABLE, VELO_SLOW, VELO_MODERATE, VELO_FAST, VELO_CRAZY, - - /* gas colors */ - PO2, PO2_ALERT, PN2, PN2_ALERT, PHE, PHE_ALERT, PP_LINES, - - /* Other colors */ - TEXT_BACKGROUND, ALERT_BG, ALERT_FG, EVENTS, SAMPLE_DEEP, SAMPLE_SHALLOW, - SMOOTHED, MINUTE, TIME_GRID, TIME_TEXT, DEPTH_GRID, MEAN_DEPTH, DEPTH_TOP, - DEPTH_BOTTOM, TEMP_TEXT, TEMP_PLOT, SAC_DEFAULT, BOUNDING_BOX, PRESSURE_TEXT, BACKGROUND, - CEILING_SHALLOW, CEILING_DEEP, CALC_CEILING_SHALLOW, CALC_CEILING_DEEP -} color_indice_t; - -typedef struct { - /* media[0] is screen, media[1] is b/w printer media[2] is color printer */ - struct rgba { - double r,g,b,a; - } media[3]; -} color_t; - -/* [color indice] = {{screen color, b/w printer color, color printer}} printer & screen colours could be different */ -static const color_t profile_color[] = { - [SAC_1] = {{FUNGREEN1, BLACK1_LOW_TRANS, FUNGREEN1}}, - [SAC_2] = {{APPLE1, BLACK1_LOW_TRANS, APPLE1}}, - [SAC_3] = {{ATLANTIS1, BLACK1_LOW_TRANS, ATLANTIS1}}, - [SAC_4] = {{ATLANTIS2, BLACK1_LOW_TRANS, ATLANTIS2}}, - [SAC_5] = {{EARLSGREEN1, BLACK1_LOW_TRANS, EARLSGREEN1}}, - [SAC_6] = {{HOKEYPOKEY1, BLACK1_LOW_TRANS, HOKEYPOKEY1}}, - [SAC_7] = {{TUSCANY1, BLACK1_LOW_TRANS, TUSCANY1}}, - [SAC_8] = {{CINNABAR1, BLACK1_LOW_TRANS, CINNABAR1}}, - [SAC_9] = {{REDORANGE1, BLACK1_LOW_TRANS, REDORANGE1}}, - - [VELO_STABLE] = {{CAMARONE1, BLACK1_LOW_TRANS, CAMARONE1}}, - [VELO_SLOW] = {{LIMENADE1, BLACK1_LOW_TRANS, LIMENADE1}}, - [VELO_MODERATE] = {{RIOGRANDE1, BLACK1_LOW_TRANS, RIOGRANDE1}}, - [VELO_FAST] = {{PIRATEGOLD1, BLACK1_LOW_TRANS, PIRATEGOLD1}}, - [VELO_CRAZY] = {{RED1, BLACK1_LOW_TRANS, RED1}}, - - [PO2] = {{APPLE1, BLACK1_LOW_TRANS, APPLE1}}, - [PO2_ALERT] = {{RED1, BLACK1_LOW_TRANS, RED1}}, - [PN2] = {{BLACK1_LOW_TRANS, BLACK1_LOW_TRANS, BLACK1_LOW_TRANS}}, - [PN2_ALERT] = {{RED1, BLACK1_LOW_TRANS, RED1}}, - [PHE] = {{PEANUT, BLACK1_LOW_TRANS, PEANUT}}, - [PHE_ALERT] = {{RED1, BLACK1_LOW_TRANS, RED1}}, - [PP_LINES] = {{BLACK1_HIGH_TRANS, BLACK1_HIGH_TRANS, BLACK1_HIGH_TRANS}}, - - [TEXT_BACKGROUND] = {{CONCRETE1_LOWER_TRANS, WHITE1, CONCRETE1_LOWER_TRANS}}, - [ALERT_BG] = {{BROOM1_LOWER_TRANS, BLACK1_LOW_TRANS, BROOM1_LOWER_TRANS}}, - [ALERT_FG] = {{BLACK1_LOW_TRANS, BLACK1_LOW_TRANS, BLACK1_LOW_TRANS}}, - [EVENTS] = {{REDORANGE1, BLACK1_LOW_TRANS, REDORANGE1}}, - [SAMPLE_DEEP] = {{PERSIANRED1, BLACK1_LOW_TRANS, PERSIANRED1}}, - [SAMPLE_SHALLOW] = {{PERSIANRED1, BLACK1_LOW_TRANS, PERSIANRED1}}, - [SMOOTHED] = {{REDORANGE1_HIGH_TRANS, BLACK1_LOW_TRANS, REDORANGE1_HIGH_TRANS}}, - [MINUTE] = {{MEDIUMREDVIOLET1_HIGHER_TRANS, BLACK1_LOW_TRANS, MEDIUMREDVIOLET1_HIGHER_TRANS}}, - [TIME_GRID] = {{WHITE1, BLACK1_HIGH_TRANS, TUNDORA1_MED_TRANS}}, - [TIME_TEXT] = {{FORESTGREEN1, BLACK1_LOW_TRANS, FORESTGREEN1}}, - [DEPTH_GRID] = {{WHITE1, BLACK1_HIGH_TRANS, TUNDORA1_MED_TRANS}}, - [MEAN_DEPTH] = {{REDORANGE1_MED_TRANS, BLACK1_LOW_TRANS, REDORANGE1_MED_TRANS}}, - [DEPTH_BOTTOM] = {{GOVERNORBAY1_MED_TRANS, BLACK1_HIGH_TRANS, GOVERNORBAY1_MED_TRANS}}, - [DEPTH_TOP] = {{MERCURY1_MED_TRANS, WHITE1_MED_TRANS, MERCURY1_MED_TRANS}}, - [TEMP_TEXT] = {{GOVERNORBAY2, BLACK1_LOW_TRANS, GOVERNORBAY2}}, - [TEMP_PLOT] = {{ROYALBLUE2_LOW_TRANS, BLACK1_LOW_TRANS, ROYALBLUE2_LOW_TRANS}}, - [SAC_DEFAULT] = {{WHITE1, BLACK1_LOW_TRANS, FORESTGREEN1}}, - [BOUNDING_BOX] = {{WHITE1, BLACK1_LOW_TRANS, TUNDORA1_MED_TRANS}}, - [PRESSURE_TEXT] = {{KILLARNEY1, BLACK1_LOW_TRANS, KILLARNEY1}}, - [BACKGROUND] = {{SPRINGWOOD1, BLACK1_LOW_TRANS, SPRINGWOOD1}}, - [CEILING_SHALLOW] = {{REDORANGE1_HIGH_TRANS, BLACK1_HIGH_TRANS, REDORANGE1_HIGH_TRANS}}, - [CEILING_DEEP] = {{RED1_MED_TRANS, BLACK1_HIGH_TRANS, RED1_MED_TRANS}}, - [CALC_CEILING_SHALLOW] = {{FUNGREEN1_HIGH_TRANS, BLACK1_HIGH_TRANS, FUNGREEN1_HIGH_TRANS}}, - [CALC_CEILING_DEEP] = {{APPLE1_HIGH_TRANS, BLACK1_HIGH_TRANS, APPLE1_HIGH_TRANS}}, - -}; - #if USE_GTK_UI /* Scale to 0,0 -> maxx,maxy */ @@ -270,11 +188,13 @@ int get_maxdepth(struct plot_info *pi) return md; } +#if 0 typedef struct { double size; color_indice_t color; double hpos, vpos; } text_render_options_t; +#endif #define RIGHT (-1.0) #define CENTER (-0.5) diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 59a47826f..a878c1363 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -5,10 +5,91 @@ #include +#include "../color.h" + +#define SAC_COLORS_START_IDX SAC_1 +#define SAC_COLORS 9 +#define VELOCITY_COLORS_START_IDX VELO_STABLE +#define VELOCITY_COLORS 5 + +typedef enum { + /* SAC colors. Order is important, the SAC_COLORS_START_IDX define above. */ + SAC_1, SAC_2, SAC_3, SAC_4, SAC_5, SAC_6, SAC_7, SAC_8, SAC_9, + + /* Velocity colors. Order is still important, ref VELOCITY_COLORS_START_IDX. */ + VELO_STABLE, VELO_SLOW, VELO_MODERATE, VELO_FAST, VELO_CRAZY, + + /* gas colors */ + PO2, PO2_ALERT, PN2, PN2_ALERT, PHE, PHE_ALERT, PP_LINES, + + /* Other colors */ + TEXT_BACKGROUND, ALERT_BG, ALERT_FG, EVENTS, SAMPLE_DEEP, SAMPLE_SHALLOW, + SMOOTHED, MINUTE, TIME_GRID, TIME_TEXT, DEPTH_GRID, MEAN_DEPTH, DEPTH_TOP, + DEPTH_BOTTOM, TEMP_TEXT, TEMP_PLOT, SAC_DEFAULT, BOUNDING_BOX, PRESSURE_TEXT, BACKGROUND, + CEILING_SHALLOW, CEILING_DEEP, CALC_CEILING_SHALLOW, CALC_CEILING_DEEP +} color_indice_t; + +#define COLOR(x, y, z) QVector() << x << y << z; +/* profile_color[color indice] = COLOR(screen color, b/w printer color, color printer}} printer & screen colours could be different */ +QMap > profile_color; +void fill_profile_color() +{ + profile_color[SAC_1] = COLOR(FUNGREEN1, BLACK1_LOW_TRANS, FUNGREEN1); + profile_color[SAC_2] = COLOR(APPLE1, BLACK1_LOW_TRANS, APPLE1); + profile_color[SAC_3] = COLOR(ATLANTIS1, BLACK1_LOW_TRANS, ATLANTIS1); + profile_color[SAC_4] = COLOR(ATLANTIS2, BLACK1_LOW_TRANS, ATLANTIS2); + profile_color[SAC_5] = COLOR(EARLSGREEN1, BLACK1_LOW_TRANS, EARLSGREEN1); + profile_color[SAC_6] = COLOR(HOKEYPOKEY1, BLACK1_LOW_TRANS, HOKEYPOKEY1); + profile_color[SAC_7] = COLOR(TUSCANY1, BLACK1_LOW_TRANS, TUSCANY1); + profile_color[SAC_8] = COLOR(CINNABAR1, BLACK1_LOW_TRANS, CINNABAR1); + profile_color[SAC_9] = COLOR(REDORANGE1, BLACK1_LOW_TRANS, REDORANGE1); + + profile_color[VELO_STABLE] = COLOR(CAMARONE1, BLACK1_LOW_TRANS, CAMARONE1); + profile_color[VELO_SLOW] = COLOR(LIMENADE1, BLACK1_LOW_TRANS, LIMENADE1); + profile_color[VELO_MODERATE] = COLOR(RIOGRANDE1, BLACK1_LOW_TRANS, RIOGRANDE1); + profile_color[VELO_FAST] = COLOR(PIRATEGOLD1, BLACK1_LOW_TRANS, PIRATEGOLD1); + profile_color[VELO_CRAZY] = COLOR(RED1, BLACK1_LOW_TRANS, RED1); + + profile_color[PO2] = COLOR(APPLE1, BLACK1_LOW_TRANS, APPLE1); + profile_color[PO2_ALERT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1); + profile_color[PN2] = COLOR(BLACK1_LOW_TRANS, BLACK1_LOW_TRANS, BLACK1_LOW_TRANS); + profile_color[PN2_ALERT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1); + profile_color[PHE] = COLOR(PEANUT, BLACK1_LOW_TRANS, PEANUT); + profile_color[PHE_ALERT] = COLOR(RED1, BLACK1_LOW_TRANS, RED1); + profile_color[PP_LINES] = COLOR(BLACK1_HIGH_TRANS, BLACK1_HIGH_TRANS, BLACK1_HIGH_TRANS); + + profile_color[TEXT_BACKGROUND] = COLOR(CONCRETE1_LOWER_TRANS, WHITE1, CONCRETE1_LOWER_TRANS); + profile_color[ALERT_BG] = COLOR(BROOM1_LOWER_TRANS, BLACK1_LOW_TRANS, BROOM1_LOWER_TRANS); + profile_color[ALERT_FG] = COLOR(BLACK1_LOW_TRANS, BLACK1_LOW_TRANS, BLACK1_LOW_TRANS); + profile_color[EVENTS] = COLOR(REDORANGE1, BLACK1_LOW_TRANS, REDORANGE1); + profile_color[SAMPLE_DEEP] = COLOR(PERSIANRED1, BLACK1_LOW_TRANS, PERSIANRED1); + profile_color[SAMPLE_SHALLOW] = COLOR(PERSIANRED1, BLACK1_LOW_TRANS, PERSIANRED1); + profile_color[SMOOTHED] = COLOR(REDORANGE1_HIGH_TRANS, BLACK1_LOW_TRANS, REDORANGE1_HIGH_TRANS); + profile_color[MINUTE] = COLOR(MEDIUMREDVIOLET1_HIGHER_TRANS, BLACK1_LOW_TRANS, MEDIUMREDVIOLET1_HIGHER_TRANS); + profile_color[TIME_GRID] = COLOR(WHITE1, BLACK1_HIGH_TRANS, TUNDORA1_MED_TRANS); + profile_color[TIME_TEXT] = COLOR(FORESTGREEN1, BLACK1_LOW_TRANS, FORESTGREEN1); + profile_color[DEPTH_GRID] = COLOR(WHITE1, BLACK1_HIGH_TRANS, TUNDORA1_MED_TRANS); + profile_color[MEAN_DEPTH] = COLOR(REDORANGE1_MED_TRANS, BLACK1_LOW_TRANS, REDORANGE1_MED_TRANS); + profile_color[DEPTH_BOTTOM] = COLOR(GOVERNORBAY1_MED_TRANS, BLACK1_HIGH_TRANS, GOVERNORBAY1_MED_TRANS); + profile_color[DEPTH_TOP] = COLOR(MERCURY1_MED_TRANS, WHITE1_MED_TRANS, MERCURY1_MED_TRANS); + profile_color[TEMP_TEXT] = COLOR(GOVERNORBAY2, BLACK1_LOW_TRANS, GOVERNORBAY2); + profile_color[TEMP_PLOT] = COLOR(ROYALBLUE2_LOW_TRANS, BLACK1_LOW_TRANS, ROYALBLUE2_LOW_TRANS); + profile_color[SAC_DEFAULT] = COLOR(WHITE1, BLACK1_LOW_TRANS, FORESTGREEN1); + profile_color[BOUNDING_BOX] = COLOR(WHITE1, BLACK1_LOW_TRANS, TUNDORA1_MED_TRANS); + profile_color[PRESSURE_TEXT] = COLOR(KILLARNEY1, BLACK1_LOW_TRANS, KILLARNEY1); + profile_color[BACKGROUND] = COLOR(SPRINGWOOD1, BLACK1_LOW_TRANS, SPRINGWOOD1); + profile_color[CEILING_SHALLOW] = COLOR(REDORANGE1_HIGH_TRANS, BLACK1_HIGH_TRANS, REDORANGE1_HIGH_TRANS); + profile_color[CEILING_DEEP] = COLOR(RED1_MED_TRANS, BLACK1_HIGH_TRANS, RED1_MED_TRANS); + profile_color[CALC_CEILING_SHALLOW] = COLOR(FUNGREEN1_HIGH_TRANS, BLACK1_HIGH_TRANS, FUNGREEN1_HIGH_TRANS); + profile_color[CALC_CEILING_DEEP] = COLOR(APPLE1_HIGH_TRANS, BLACK1_HIGH_TRANS, APPLE1_HIGH_TRANS); +} +#undef COLOR + ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent) { setScene(new QGraphicsScene()); scene()->setSceneRect(0,0,100,100); + fill_profile_color(); } void ProfileGraphicsView::plot(struct dive *d) -- cgit v1.2.3-70-g09d2 From fa82ba60798be8b5e20277527053199916888b16 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sat, 4 May 2013 17:24:23 -0300 Subject: Moved the plot from the cairo version to the Qt version Started working on the Qt version of the Plot, initially nothing is printed - but this is not a bad thing, the program doesn't explodes too. :) some work had to be done about the 'bool/gboolean' stuff so I removed all gbooleans in the code that I'v encountered. A new file was created ( profile.h ) so I could put the signatures of helper methods that cairo used to call. till now the code computes the max limits. Next patch the first drawing will be made. Signed-off-by: Tomaz Canabrava --- display.h | 27 ++++++--- profile.c | 123 ---------------------------------------- profile.h | 25 +++++++++ qt-ui/profilegraphics.cpp | 140 +++++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 182 insertions(+), 133 deletions(-) create mode 100644 profile.h (limited to 'profile.c') diff --git a/display.h b/display.h index b1a034e88..bc60c059f 100644 --- a/display.h +++ b/display.h @@ -1,18 +1,26 @@ #ifndef DISPLAY_H #define DISPLAY_H -#include - #ifdef __cplusplus extern "C" { +#else +#if __STDC_VERSION__ >= 199901L +#include +#else +typedef int bool; +#endif #endif #define SCALE_SCREEN 1.0 -#define SCALE_PRINT (1.0 / get_screen_dpi()) +#warning "PORT THE get_screen_dpi to Qt" +#define SCALE_PRINT 1.0 +//#define SCALE_PRINT (1.0 / get_screen_dpi()) extern void repaint_dive(void); extern void do_print(void); -extern gdouble get_screen_dpi(void); + +// Commented out because I don't know how to get the dpi on a paint device yet. +// extern gdouble get_screen_dpi(void); /* Plot info with smoothing, velocity indication * and one-, two- and three-minute minimums and maximums */ @@ -24,10 +32,15 @@ struct plot_info { int mintemp, maxtemp; double endtempcoord; double maxpp; - gboolean has_ndl; + bool has_ndl; struct plot_data *entry; }; +/* +// I'm not sure if this is needed anymore - but keeping this here +// so I wont break stuff trying to redo the well. +*/ + /* * Cairo scaling really is horribly horribly mis-designed. * @@ -38,8 +51,6 @@ struct plot_info { */ struct graphics_context { int printer; - cairo_t *cr; - cairo_rectangle_t drawing_area; double maxx, maxy; double leftx, rightx; double topy, bottomy; @@ -61,7 +72,7 @@ struct options { enum { PRETTY, TABLE, TWOPERPAGE } type; int print_selected; int color_selected; - gboolean notes_up; + bool notes_up; int profile_height, notes_height, tanks_height; }; diff --git a/profile.c b/profile.c index fa0a24a06..3f413f4ed 100644 --- a/profile.c +++ b/profile.c @@ -18,9 +18,6 @@ int selected_dive = 0; char zoomed_plot = 0; char dc_number = 0; -#if USE_GTK_UI -static double plot_scale = SCALE_SCREEN; -#endif static struct plot_data *last_pi_entry = NULL; @@ -1951,126 +1948,6 @@ struct divecomputer *select_dc(struct divecomputer *main) return main; } -#if USE_GTK_UI -void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t scale) -{ - struct plot_info *pi; - struct divecomputer *dc = &dive->dc; - cairo_rectangle_t *drawing_area = &gc->drawing_area; - const char *nickname; - - plot_set_scale(scale); - - if (!dc->samples) { - static struct sample fake[4]; - static struct divecomputer fakedc; - fakedc = dive->dc; - fakedc.sample = fake; - fakedc.samples = 4; - - /* The dive has no samples, so create a few fake ones. This assumes an - ascent/descent rate of 9 m/min, which is just below the limit for FAST. */ - int duration = dive->dc.duration.seconds; - int maxdepth = dive->dc.maxdepth.mm; - int asc_desc_time = dive->dc.maxdepth.mm*60/9000; - if (asc_desc_time * 2 >= duration) - asc_desc_time = duration / 2; - fake[1].time.seconds = asc_desc_time; - fake[1].depth.mm = maxdepth; - fake[2].time.seconds = duration - asc_desc_time; - fake[2].depth.mm = maxdepth; - fake[3].time.seconds = duration * 1.00; - fakedc.events = dc->events; - dc = &fakedc; - } - - /* - * Set up limits that are independent of - * the dive computer - */ - calculate_max_limits(dive, dc, gc); - - /* shift the drawing area so we have a nice margin around it */ - cairo_translate(gc->cr, drawing_area->x, drawing_area->y); - cairo_set_line_width_scaled(gc->cr, 1); - cairo_set_line_cap(gc->cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_join(gc->cr, CAIRO_LINE_JOIN_ROUND); - - /* - * We don't use "cairo_translate()" because that doesn't - * scale line width etc. But the actual scaling we need - * do set up ourselves.. - * - * Snif. What a pity. - */ - gc->maxx = (drawing_area->width - 2*drawing_area->x); - gc->maxy = (drawing_area->height - 2*drawing_area->y); - - dc = select_dc(dc); - - /* This is per-dive-computer. Right now we just do the first one */ - pi = create_plot_info(dive, dc, gc); - - /* Depth profile */ - plot_depth_profile(gc, pi); - plot_events(gc, pi, dc); - - /* Temperature profile */ - plot_temperature_profile(gc, pi); - - /* Cylinder pressure plot */ - plot_cylinder_pressure(gc, pi, dive, dc); - - /* Text on top of all graphs.. */ - plot_temperature_text(gc, pi); - plot_depth_text(gc, pi); - plot_cylinder_pressure_text(gc, pi); - plot_deco_text(gc, pi); - - /* Bounding box last */ - gc->leftx = 0; gc->rightx = 1.0; - gc->topy = 0; gc->bottomy = 1.0; - - set_source_rgba(gc, BOUNDING_BOX); - cairo_set_line_width_scaled(gc->cr, 1); - move_to(gc, 0, 0); - line_to(gc, 0, 1); - line_to(gc, 1, 1); - line_to(gc, 1, 0); - cairo_close_path(gc->cr); - cairo_stroke(gc->cr); - - /* Put the dive computer name in the lower left corner */ - nickname = get_dc_nickname(dc->model, dc->deviceid); - if (!nickname || *nickname == '\0') - nickname = dc->model; - if (nickname) { - static const text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, MIDDLE}; - plot_text(gc, &computer, 0, 1, "%s", nickname); - } - - if (PP_GRAPHS_ENABLED) { - plot_pp_gas_profile(gc, pi); - plot_pp_text(gc, pi); - } - - /* now shift the translation back by half the margin; - * this way we can draw the vertical scales on both sides */ - cairo_translate(gc->cr, -drawing_area->x / 2.0, 0); - gc->maxx += drawing_area->x; - gc->leftx = -(drawing_area->x / drawing_area->width) / 2.0; - gc->rightx = 1.0 - gc->leftx; - - plot_depth_scale(gc, pi); - - if (gc->printer) { - free(pi->entry); - last_pi_entry = pi->entry = NULL; - pi->nr = 0; - } -} -#endif /* USE_GTK_UI */ - static void plot_string(struct plot_data *entry, char *buf, size_t bufsize, int depth, int pressure, int temp, gboolean has_ndl) { diff --git a/profile.h b/profile.h new file mode 100644 index 000000000..66d1ee190 --- /dev/null +++ b/profile.h @@ -0,0 +1,25 @@ +#ifndef PROFILE_H +#define PROFILE_H + +#ifdef __cplusplus +extern "C" { +#else +#if __STDC_VERSION__ >= 199901L +#include +#else +typedef int bool; +#endif +#endif + +struct dive; +struct divecomputer; +struct graphics_context; +struct plot_info; + +void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); +struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); + +#ifdef __cplusplus +} +#endif +#endif diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index a878c1363..e500432fc 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -6,12 +6,17 @@ #include #include "../color.h" +#include "../display.h" +#include "../dive.h" +#include "../profile.h" #define SAC_COLORS_START_IDX SAC_1 #define SAC_COLORS 9 #define VELOCITY_COLORS_START_IDX VELO_STABLE #define VELOCITY_COLORS 5 +static double plot_scale = SCALE_SCREEN; + typedef enum { /* SAC colors. Order is important, the SAC_COLORS_START_IDX define above. */ SAC_1, SAC_2, SAC_3, SAC_4, SAC_5, SAC_6, SAC_7, SAC_8, SAC_9, @@ -92,9 +97,140 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent fill_profile_color(); } -void ProfileGraphicsView::plot(struct dive *d) +static void plot_set_scale(scale_mode_t scale) +{ + switch (scale) { + default: + case SC_SCREEN: + plot_scale = SCALE_SCREEN; + break; + case SC_PRINT: + plot_scale = SCALE_PRINT; + break; + } +} + +void ProfileGraphicsView::plot(struct dive *dive) { - qDebug() << "Start the plotting of the dive here."; + struct plot_info *pi; + struct divecomputer *dc = &dive->dc; + + // This was passed around in the Cairo version / needed? + graphics_context gc; + const char *nickname; + + // Fix this for printing / screen later. + // plot_set_scale( scale_mode_t); + + if (!dc->samples) { + static struct sample fake[4]; + static struct divecomputer fakedc; + fakedc = dive->dc; + fakedc.sample = fake; + fakedc.samples = 4; + + /* The dive has no samples, so create a few fake ones. This assumes an + ascent/descent rate of 9 m/min, which is just below the limit for FAST. */ + int duration = dive->dc.duration.seconds; + int maxdepth = dive->dc.maxdepth.mm; + int asc_desc_time = dive->dc.maxdepth.mm*60/9000; + if (asc_desc_time * 2 >= duration) + asc_desc_time = duration / 2; + fake[1].time.seconds = asc_desc_time; + fake[1].depth.mm = maxdepth; + fake[2].time.seconds = duration - asc_desc_time; + fake[2].depth.mm = maxdepth; + fake[3].time.seconds = duration * 1.00; + fakedc.events = dc->events; + dc = &fakedc; + } + + /* + * Set up limits that are independent of + * the dive computer + */ + calculate_max_limits(dive, dc, &gc); + +#if 0 + /* shift the drawing area so we have a nice margin around it */ + cairo_translate(gc->cr, drawing_area->x, drawing_area->y); + cairo_set_line_width_scaled(gc->cr, 1); + cairo_set_line_cap(gc->cr, CAIRO_LINE_CAP_ROUND); + cairo_set_line_join(gc->cr, CAIRO_LINE_JOIN_ROUND); + + /* + * We don't use "cairo_translate()" because that doesn't + * scale line width etc. But the actual scaling we need + * do set up ourselves.. + * + * Snif. What a pity. + */ + gc->maxx = (drawing_area->width - 2*drawing_area->x); + gc->maxy = (drawing_area->height - 2*drawing_area->y); + + dc = select_dc(dc); + + /* This is per-dive-computer. Right now we just do the first one */ + pi = create_plot_info(dive, dc, gc); + + /* Depth profile */ + plot_depth_profile(gc, pi); + plot_events(gc, pi, dc); + + /* Temperature profile */ + plot_temperature_profile(gc, pi); + + /* Cylinder pressure plot */ + plot_cylinder_pressure(gc, pi, dive, dc); + + /* Text on top of all graphs.. */ + plot_temperature_text(gc, pi); + plot_depth_text(gc, pi); + plot_cylinder_pressure_text(gc, pi); + plot_deco_text(gc, pi); + + /* Bounding box last */ + gc->leftx = 0; gc->rightx = 1.0; + gc->topy = 0; gc->bottomy = 1.0; + + set_source_rgba(gc, BOUNDING_BOX); + cairo_set_line_width_scaled(gc->cr, 1); + move_to(gc, 0, 0); + line_to(gc, 0, 1); + line_to(gc, 1, 1); + line_to(gc, 1, 0); + cairo_close_path(gc->cr); + cairo_stroke(gc->cr); + + /* Put the dive computer name in the lower left corner */ + nickname = get_dc_nickname(dc->model, dc->deviceid); + if (!nickname || *nickname == '\0') + nickname = dc->model; + if (nickname) { + static const text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, MIDDLE}; + plot_text(gc, &computer, 0, 1, "%s", nickname); + } + + if (PP_GRAPHS_ENABLED) { + plot_pp_gas_profile(gc, pi); + plot_pp_text(gc, pi); + } + + /* now shift the translation back by half the margin; + * this way we can draw the vertical scales on both sides */ + cairo_translate(gc->cr, -drawing_area->x / 2.0, 0); + gc->maxx += drawing_area->x; + gc->leftx = -(drawing_area->x / drawing_area->width) / 2.0; + gc->rightx = 1.0 - gc->leftx; + + plot_depth_scale(gc, pi); + + if (gc->printer) { + free(pi->entry); + last_pi_entry = pi->entry = NULL; + pi->nr = 0; + } +#endif } void ProfileGraphicsView::resizeEvent(QResizeEvent *event) -- cgit v1.2.3-70-g09d2 From 19048b98e59aedb4d03490095c646d337d47e38b Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sat, 4 May 2013 19:20:49 -0300 Subject: Start plotting something. The first plotting method was removed from profile.c to profilegraphics.cpp and some conversion ( almost 1 to 1 ) was made so that the code could work. Since the code is big - this commit has just a part of it working - it plots the grid. but already works for testing the resizing of the window and Zooming ( unimplemented ) Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- profile.c | 204 -------------------------------------- profile.h | 15 +++ qt-ui/profilegraphics.cpp | 246 +++++++++++++++++++++++++++++++++++++++++++--- qt-ui/profilegraphics.h | 2 + 4 files changed, 251 insertions(+), 216 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 3f413f4ed..be6efa1e6 100644 --- a/profile.c +++ b/profile.c @@ -58,11 +58,6 @@ struct plot_data { #if USE_GTK_UI -/* Scale to 0,0 -> maxx,maxy */ -#define SCALEX(gc,x) (((x)-gc->leftx)/(gc->rightx-gc->leftx)*gc->maxx) -#define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy) -#define SCALE(gc,x,y) SCALEX(gc,x),SCALEY(gc,y) - /* keep the last used gc around so we can invert the SCALEX calculation in * order to calculate a time value for an x coordinate */ static struct graphics_context last_gc; @@ -611,205 +606,6 @@ static void plot_pp_gas_profile(struct graphics_context *gc, struct plot_info *p } } -static void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi) -{ - int i, incr; - cairo_t *cr = gc->cr; - int sec, depth; - struct plot_data *entry; - int maxtime, maxdepth, marker, maxline; - int increments[8] = { 10, 20, 30, 60, 5*60, 10*60, 15*60, 30*60 }; - - /* Get plot scaling limits */ - maxtime = get_maxtime(pi); - maxdepth = get_maxdepth(pi); - - gc->maxtime = maxtime; - - /* Time markers: at most every 10 seconds, but no more than 12 markers. - * We start out with 10 seconds and increment up to 30 minutes, - * depending on the dive time. - * This allows for 6h dives - enough (I hope) for even the craziest - * divers - but just in case, for those 8h depth-record-breaking dives, - * we double the interval if this still doesn't get us to 12 or fewer - * time markers */ - i = 0; - while (maxtime / increments[i] > 12 && i < 7) - i++; - incr = increments[i]; - while (maxtime / incr > 12) - incr *= 2; - - gc->leftx = 0; gc->rightx = maxtime; - gc->topy = 0; gc->bottomy = 1.0; - - last_gc = *gc; - - set_source_rgba(gc, TIME_GRID); - cairo_set_line_width_scaled(gc->cr, 2); - - for (i = incr; i < maxtime; i += incr) { - move_to(gc, i, 0); - line_to(gc, i, 1); - } - cairo_stroke(cr); - - /* now the text on the time markers */ - text_render_options_t tro = {DEPTH_TEXT_SIZE, TIME_TEXT, CENTER, TOP}; - if (maxtime < 600) { - /* Be a bit more verbose with shorter dives */ - for (i = incr; i < maxtime; i += incr) - plot_text(gc, &tro, i, 1, "%02d:%02d", i/60, i%60); - } else { - /* Only render the time on every second marker for normal dives */ - for (i = incr; i < maxtime; i += 2 * incr) - plot_text(gc, &tro, i, 1, "%d", i/60); - } - /* Depth markers: every 30 ft or 10 m*/ - gc->leftx = 0; gc->rightx = 1.0; - gc->topy = 0; gc->bottomy = maxdepth; - switch (prefs.units.length) { - case METERS: marker = 10000; break; - case FEET: marker = 9144; break; /* 30 ft */ - } - maxline = MAX(pi->maxdepth + marker, maxdepth * 2 / 3); - set_source_rgba(gc, DEPTH_GRID); - for (i = marker; i < maxline; i += marker) { - move_to(gc, 0, i); - line_to(gc, 1, i); - } - cairo_stroke(cr); - - gc->leftx = 0; gc->rightx = maxtime; - - /* Show mean depth */ - if (! gc->printer) { - set_source_rgba(gc, MEAN_DEPTH); - move_to(gc, 0, pi->meandepth); - line_to(gc, pi->entry[pi->nr - 1].sec, pi->meandepth); - cairo_stroke(cr); - } - - /* - * These are good for debugging text placement etc, - * but not for actual display.. - */ - if (0) { - plot_smoothed_profile(gc, pi); - plot_minmax_profile(gc, pi); - } - - /* Do the depth profile for the neat fill */ - gc->topy = 0; gc->bottomy = maxdepth; - - cairo_pattern_t *pat; - pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0 * plot_scale); - pattern_add_color_stop_rgba (gc, pat, 1, DEPTH_BOTTOM); - pattern_add_color_stop_rgba (gc, pat, 0, DEPTH_TOP); - - cairo_set_source(gc->cr, pat); - cairo_pattern_destroy(pat); - cairo_set_line_width_scaled(gc->cr, 2); - - entry = pi->entry; - move_to(gc, 0, 0); - for (i = 0; i < pi->nr; i++, entry++) - line_to(gc, entry->sec, entry->depth); - - /* Show any ceiling we may have encountered */ - for (i = pi->nr - 1; i >= 0; i--, entry--) { - if (entry->ndl) { - /* non-zero NDL implies this is a safety stop, no ceiling */ - line_to(gc, entry->sec, 0); - } else if (entry->stopdepth < entry->depth) { - line_to(gc, entry->sec, entry->stopdepth); - } else { - line_to(gc, entry->sec, entry->depth); - } - } - cairo_close_path(gc->cr); - cairo_fill(gc->cr); - - /* if the user wants the deco ceiling more visible, do that here (this - * basically draws over the background that we had allowed to shine - * through so far) */ - if (prefs.profile_red_ceiling) { - pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0 * plot_scale); - pattern_add_color_stop_rgba (gc, pat, 0, CEILING_SHALLOW); - pattern_add_color_stop_rgba (gc, pat, 1, CEILING_DEEP); - cairo_set_source(gc->cr, pat); - cairo_pattern_destroy(pat); - entry = pi->entry; - move_to(gc, 0, 0); - for (i = 0; i < pi->nr; i++, entry++) { - if (entry->ndl == 0 && entry->stopdepth) { - if (entry->ndl == 0 && entry->stopdepth < entry->depth) { - line_to(gc, entry->sec, entry->stopdepth); - } else { - line_to(gc, entry->sec, entry->depth); - } - } else { - line_to(gc, entry->sec, 0); - } - } - cairo_close_path(gc->cr); - cairo_fill(gc->cr); - } - /* finally, plot the calculated ceiling over all this */ - if (prefs.profile_calc_ceiling) { - pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0 * plot_scale); - pattern_add_color_stop_rgba (gc, pat, 0, CALC_CEILING_SHALLOW); - pattern_add_color_stop_rgba (gc, pat, 1, CALC_CEILING_DEEP); - cairo_set_source(gc->cr, pat); - cairo_pattern_destroy(pat); - entry = pi->entry; - move_to(gc, 0, 0); - for (i = 0; i < pi->nr; i++, entry++) { - if (entry->ceiling) - line_to(gc, entry->sec, entry->ceiling); - else - line_to(gc, entry->sec, 0); - } - line_to(gc, (entry-1)->sec, 0); /* make sure we end at 0 */ - cairo_close_path(gc->cr); - cairo_fill(gc->cr); - } - /* next show where we have been bad and crossed the dc's ceiling */ - pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0 * plot_scale); - pattern_add_color_stop_rgba (gc, pat, 0, CEILING_SHALLOW); - pattern_add_color_stop_rgba (gc, pat, 1, CEILING_DEEP); - cairo_set_source(gc->cr, pat); - cairo_pattern_destroy(pat); - entry = pi->entry; - move_to(gc, 0, 0); - for (i = 0; i < pi->nr; i++, entry++) - line_to(gc, entry->sec, entry->depth); - - for (i = pi->nr - 1; i >= 0; i--, entry--) { - if (entry->ndl == 0 && entry->stopdepth > entry->depth) { - line_to(gc, entry->sec, entry->stopdepth); - } else { - line_to(gc, entry->sec, entry->depth); - } - } - cairo_close_path(gc->cr); - cairo_fill(gc->cr); - - /* Now do it again for the velocity colors */ - entry = pi->entry; - for (i = 1; i < pi->nr; i++) { - entry++; - sec = entry->sec; - /* we want to draw the segments in different colors - * representing the vertical velocity, so we need to - * chop this into short segments */ - depth = entry->depth; - set_source_rgba(gc, VELOCITY_COLORS_START_IDX + entry->velocity); - move_to(gc, entry[-1].sec, entry[-1].depth); - line_to(gc, sec, depth); - cairo_stroke(cr); - } -} static int setup_temperature_limits(struct graphics_context *gc, struct plot_info *pi) { diff --git a/profile.h b/profile.h index 66d1ee190..1ad6625db 100644 --- a/profile.h +++ b/profile.h @@ -19,6 +19,21 @@ struct plot_info; void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); +/* + * When showing dive profiles, we scale things to the + * current dive. However, we don't scale past less than + * 30 minutes or 90 ft, just so that small dives show + * up as such unless zoom is enabled. + * We also need to add 180 seconds at the end so the min/max + * plots correctly + */ +int get_maxtime(struct plot_info *pi); + +/* get the maximum depth to which we want to plot + * take into account the additional verical space needed to plot + * partial pressure graphs */ +int get_maxdepth(struct plot_info *pi); + #ifdef __cplusplus } #endif diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index e500432fc..f9d528831 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -2,7 +2,9 @@ #include #include - +#include +#include +#include #include #include "../color.h" @@ -15,6 +17,12 @@ #define VELOCITY_COLORS_START_IDX VELO_STABLE #define VELOCITY_COLORS 5 +/* Scale to 0,0 -> maxx,maxy */ +#define SCALEX(gc,x) (((x)-gc->leftx)/(gc->rightx-gc->leftx)*gc->maxx) +#define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy) +#define SCALE(gc,x,y) SCALEX(gc,x),SCALEY(gc,y) + +static struct graphics_context last_gc; static double plot_scale = SCALE_SCREEN; typedef enum { @@ -93,6 +101,7 @@ void fill_profile_color() ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent) { setScene(new QGraphicsScene()); + setBackgroundBrush(QColor("#F3F3E6")); scene()->setSceneRect(0,0,100,100); fill_profile_color(); } @@ -112,6 +121,13 @@ static void plot_set_scale(scale_mode_t scale) void ProfileGraphicsView::plot(struct dive *dive) { + // Clear the items before drawing this dive. + qDeleteAll(scene()->items()); + scene()->clear(); + + if(!dive) + return; + struct plot_info *pi; struct divecomputer *dc = &dive->dc; @@ -151,13 +167,6 @@ void ProfileGraphicsView::plot(struct dive *dive) */ calculate_max_limits(dive, dc, &gc); -#if 0 - /* shift the drawing area so we have a nice margin around it */ - cairo_translate(gc->cr, drawing_area->x, drawing_area->y); - cairo_set_line_width_scaled(gc->cr, 1); - cairo_set_line_cap(gc->cr, CAIRO_LINE_CAP_ROUND); - cairo_set_line_join(gc->cr, CAIRO_LINE_JOIN_ROUND); - /* * We don't use "cairo_translate()" because that doesn't * scale line width etc. But the actual scaling we need @@ -165,16 +174,18 @@ void ProfileGraphicsView::plot(struct dive *dive) * * Snif. What a pity. */ - gc->maxx = (drawing_area->width - 2*drawing_area->x); - gc->maxy = (drawing_area->height - 2*drawing_area->y); + QRectF drawing_area = scene()->sceneRect(); + gc.maxx = (drawing_area.width() - 2 * drawing_area.x()); + gc.maxy = (drawing_area.height() - 2 * drawing_area.y()); dc = select_dc(dc); /* This is per-dive-computer. Right now we just do the first one */ - pi = create_plot_info(dive, dc, gc); + pi = create_plot_info(dive, dc, &gc); /* Depth profile */ - plot_depth_profile(gc, pi); + plot_depth_profile(&gc, pi); +#if 0 plot_events(gc, pi, dc); /* Temperature profile */ @@ -233,6 +244,217 @@ void ProfileGraphicsView::plot(struct dive *dive) #endif } + +void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct plot_info *pi) +{ + int i, incr; + int sec, depth; + struct plot_data *entry; + int maxtime, maxdepth, marker, maxline; + int increments[8] = { 10, 20, 30, 60, 5*60, 10*60, 15*60, 30*60 }; + + /* Get plot scaling limits */ + maxtime = get_maxtime(pi); + maxdepth = get_maxdepth(pi); + + gc->maxtime = maxtime; + + /* Time markers: at most every 10 seconds, but no more than 12 markers. + * We start out with 10 seconds and increment up to 30 minutes, + * depending on the dive time. + * This allows for 6h dives - enough (I hope) for even the craziest + * divers - but just in case, for those 8h depth-record-breaking dives, + * we double the interval if this still doesn't get us to 12 or fewer + * time markers */ + i = 0; + while (maxtime / increments[i] > 12 && i < 7) + i++; + incr = increments[i]; + while (maxtime / incr > 12) + incr *= 2; + + gc->leftx = 0; gc->rightx = maxtime; + gc->topy = 0; gc->bottomy = 1.0; + + last_gc = *gc; + + QColor color; + color = profile_color[TIME_GRID].at(0); + for (i = incr; i < maxtime; i += incr) { + QGraphicsLineItem *line = new QGraphicsLineItem(SCALE(gc, i, 0), SCALE(gc, i, 1)); + line->setPen(QPen(color)); + scene()->addItem(line); + } + +#if 0 + /* now the text on the time markers */ + text_render_options_t tro = {DEPTH_TEXT_SIZE, TIME_TEXT, CENTER, TOP}; + if (maxtime < 600) { + /* Be a bit more verbose with shorter dives */ + for (i = incr; i < maxtime; i += incr) + plot_text(gc, &tro, i, 1, "%02d:%02d", i/60, i%60); + } else { + /* Only render the time on every second marker for normal dives */ + for (i = incr; i < maxtime; i += 2 * incr) + plot_text(gc, &tro, i, 1, "%d", i/60); + } +#endif + + /* Depth markers: every 30 ft or 10 m*/ + gc->leftx = 0; gc->rightx = 1.0; + gc->topy = 0; gc->bottomy = maxdepth; + switch (prefs.units.length) { + case units::METERS: + marker = 10000; + break; + case units::FEET: + marker = 9144; + break; /* 30 ft */ + } + maxline = MAX(pi->maxdepth + marker, maxdepth * 2 / 3); + + color = profile_color[TIME_GRID].at(0); + + for (i = marker; i < maxline; i += marker) { + QGraphicsLineItem *line = new QGraphicsLineItem(SCALE(gc, 0, i), SCALE(gc, 1, i)); + line->setPen(QPen(color)); + scene()->addItem(line); + } + +#if 0 + gc->leftx = 0; gc->rightx = maxtime; + + /* Show mean depth */ + if (! gc->printer) { + set_source_rgba(gc, MEAN_DEPTH); + move_to(gc, 0, pi->meandepth); + line_to(gc, pi->entry[pi->nr - 1].sec, pi->meandepth); + cairo_stroke(cr); + } + + /* + * These are good for debugging text placement etc, + * but not for actual display.. + */ + if (0) { + plot_smoothed_profile(gc, pi); + plot_minmax_profile(gc, pi); + } + + /* Do the depth profile for the neat fill */ + gc->topy = 0; gc->bottomy = maxdepth; + + cairo_pattern_t *pat; + pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0 * plot_scale); + pattern_add_color_stop_rgba (gc, pat, 1, DEPTH_BOTTOM); + pattern_add_color_stop_rgba (gc, pat, 0, DEPTH_TOP); + + cairo_set_source(gc->cr, pat); + cairo_pattern_destroy(pat); + cairo_set_line_width_scaled(gc->cr, 2); + + entry = pi->entry; + move_to(gc, 0, 0); + for (i = 0; i < pi->nr; i++, entry++) + line_to(gc, entry->sec, entry->depth); + + /* Show any ceiling we may have encountered */ + for (i = pi->nr - 1; i >= 0; i--, entry--) { + if (entry->ndl) { + /* non-zero NDL implies this is a safety stop, no ceiling */ + line_to(gc, entry->sec, 0); + } else if (entry->stopdepth < entry->depth) { + line_to(gc, entry->sec, entry->stopdepth); + } else { + line_to(gc, entry->sec, entry->depth); + } + } + cairo_close_path(gc->cr); + cairo_fill(gc->cr); + + /* if the user wants the deco ceiling more visible, do that here (this + * basically draws over the background that we had allowed to shine + * through so far) */ + if (prefs.profile_red_ceiling) { + pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0 * plot_scale); + pattern_add_color_stop_rgba (gc, pat, 0, CEILING_SHALLOW); + pattern_add_color_stop_rgba (gc, pat, 1, CEILING_DEEP); + cairo_set_source(gc->cr, pat); + cairo_pattern_destroy(pat); + entry = pi->entry; + move_to(gc, 0, 0); + for (i = 0; i < pi->nr; i++, entry++) { + if (entry->ndl == 0 && entry->stopdepth) { + if (entry->ndl == 0 && entry->stopdepth < entry->depth) { + line_to(gc, entry->sec, entry->stopdepth); + } else { + line_to(gc, entry->sec, entry->depth); + } + } else { + line_to(gc, entry->sec, 0); + } + } + cairo_close_path(gc->cr); + cairo_fill(gc->cr); + } + /* finally, plot the calculated ceiling over all this */ + if (prefs.profile_calc_ceiling) { + pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0 * plot_scale); + pattern_add_color_stop_rgba (gc, pat, 0, CALC_CEILING_SHALLOW); + pattern_add_color_stop_rgba (gc, pat, 1, CALC_CEILING_DEEP); + cairo_set_source(gc->cr, pat); + cairo_pattern_destroy(pat); + entry = pi->entry; + move_to(gc, 0, 0); + for (i = 0; i < pi->nr; i++, entry++) { + if (entry->ceiling) + line_to(gc, entry->sec, entry->ceiling); + else + line_to(gc, entry->sec, 0); + } + line_to(gc, (entry-1)->sec, 0); /* make sure we end at 0 */ + cairo_close_path(gc->cr); + cairo_fill(gc->cr); + } + /* next show where we have been bad and crossed the dc's ceiling */ + pat = cairo_pattern_create_linear (0.0, 0.0, 0.0, 256.0 * plot_scale); + pattern_add_color_stop_rgba (gc, pat, 0, CEILING_SHALLOW); + pattern_add_color_stop_rgba (gc, pat, 1, CEILING_DEEP); + cairo_set_source(gc->cr, pat); + cairo_pattern_destroy(pat); + entry = pi->entry; + move_to(gc, 0, 0); + for (i = 0; i < pi->nr; i++, entry++) + line_to(gc, entry->sec, entry->depth); + + for (i = pi->nr - 1; i >= 0; i--, entry--) { + if (entry->ndl == 0 && entry->stopdepth > entry->depth) { + line_to(gc, entry->sec, entry->stopdepth); + } else { + line_to(gc, entry->sec, entry->depth); + } + } + cairo_close_path(gc->cr); + cairo_fill(gc->cr); + + /* Now do it again for the velocity colors */ + entry = pi->entry; + for (i = 1; i < pi->nr; i++) { + entry++; + sec = entry->sec; + /* we want to draw the segments in different colors + * representing the vertical velocity, so we need to + * chop this into short segments */ + depth = entry->depth; + set_source_rgba(gc, VELOCITY_COLORS_START_IDX + entry->velocity); + move_to(gc, entry[-1].sec, entry[-1].depth); + line_to(gc, sec, depth); + cairo_stroke(cr); + } +#endif +} + + void ProfileGraphicsView::resizeEvent(QResizeEvent *event) { // Fits the scene's rectangle on the view. diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index e3380abcd..633409b23 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -12,6 +12,8 @@ public: protected: void resizeEvent(QResizeEvent *event); +private: + void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi); }; #endif -- cgit v1.2.3-70-g09d2 From f269f8649644c5726fcd79ead443b0bb605a798d Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sat, 4 May 2013 19:36:40 -0300 Subject: Plot of the Mean Deph The mean depth now is plotted correctly. I wanted to do more stuff on this commit, but since it required that a few things on profile.c got moved to profile.h, commited to not have a huge blob for review. Signed-off-by: Tomaz Canabrava --- profile.c | 27 ++------------------------- profile.h | 28 +++++++++++++++++++++++++++- qt-ui/profilegraphics.cpp | 13 +++++++------ 3 files changed, 36 insertions(+), 32 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index be6efa1e6..161415e88 100644 --- a/profile.c +++ b/profile.c @@ -11,6 +11,7 @@ #endif #include "divelist.h" +#include "profile.h" #include "libdivecomputer/parser.h" #include "libdivecomputer/version.h" @@ -24,31 +25,7 @@ static struct plot_data *last_pi_entry = NULL; #define cairo_set_line_width_scaled(cr, w) \ cairo_set_line_width((cr), (w) * plot_scale); -typedef enum { STABLE, SLOW, MODERATE, FAST, CRAZY } velocity_t; - -struct plot_data { - unsigned int in_deco:1; - unsigned int cylinderindex; - int sec; - /* pressure[0] is sensor pressure - * pressure[1] is interpolated pressure */ - int pressure[2]; - int temperature; - /* Depth info */ - int depth; - int ceiling; - int ndl; - int stoptime; - int stopdepth; - int cns; - int smoothed; - double po2, pn2, phe; - double mod, ead, end, eadd; - velocity_t velocity; - struct plot_data *min[3]; - struct plot_data *max[3]; - int avg[3]; -}; + #define SENSOR_PR 0 #define INTERPOLATED_PR 1 diff --git a/profile.h b/profile.h index 1ad6625db..2c293fa7d 100644 --- a/profile.h +++ b/profile.h @@ -11,10 +11,36 @@ typedef int bool; #endif #endif -struct dive; +#include "dive.h" + +typedef enum { STABLE, SLOW, MODERATE, FAST, CRAZY } velocity_t; + struct divecomputer; struct graphics_context; struct plot_info; +struct plot_data { + unsigned int in_deco:1; + unsigned int cylinderindex; + int sec; + /* pressure[0] is sensor pressure + * pressure[1] is interpolated pressure */ + int pressure[2]; + int temperature; + /* Depth info */ + int depth; + int ceiling; + int ndl; + int stoptime; + int stopdepth; + int cns; + int smoothed; + double po2, pn2, phe; + double mod, ead, end, eadd; + velocity_t velocity; + struct plot_data *min[3]; + struct plot_data *max[3]; + int avg[3]; +}; void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index f9d528831..14ed21c9b 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -313,7 +313,7 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct } maxline = MAX(pi->maxdepth + marker, maxdepth * 2 / 3); - color = profile_color[TIME_GRID].at(0); + color = profile_color[DEPTH_GRID].at(0); for (i = marker; i < maxline; i += marker) { QGraphicsLineItem *line = new QGraphicsLineItem(SCALE(gc, 0, i), SCALE(gc, 1, i)); @@ -321,17 +321,18 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct scene()->addItem(line); } -#if 0 + gc->leftx = 0; gc->rightx = maxtime; + color = profile_color[MEAN_DEPTH].at(0); /* Show mean depth */ if (! gc->printer) { - set_source_rgba(gc, MEAN_DEPTH); - move_to(gc, 0, pi->meandepth); - line_to(gc, pi->entry[pi->nr - 1].sec, pi->meandepth); - cairo_stroke(cr); + QGraphicsLineItem *line = new QGraphicsLineItem(SCALE(gc, 0, pi->meandepth), SCALE(gc, pi->entry[pi->nr - 1].sec, pi->meandepth)); + line->setPen(QPen(color)); + scene()->addItem(line); } +#if 0 /* * These are good for debugging text placement etc, * but not for actual display.. -- cgit v1.2.3-70-g09d2 From 1b392b35bca24ce25da9073dbe9a1bb0186c47af Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Mon, 6 May 2013 15:35:17 -0300 Subject: Port the plot text method to Qt, also test it by actually plotting something The plot_text function from the cairo-methods are now ported on the qt version. this patch moves around some code since quite defines are already used and I didn't want to reinvent the whell. Original code used varargs, but I prefered to change it , so now it receives just a reference to a QString object and the string must be constructed before sending, using the .arg methods. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- display-gtk.h | 16 --------------- profile.c | 51 ----------------------------------------------- profile.h | 24 ++++++++++++++++++++++ qt-ui/profilegraphics.cpp | 36 ++++++++++++++++++++++++--------- qt-ui/profilegraphics.h | 6 ++++++ 5 files changed, 57 insertions(+), 76 deletions(-) (limited to 'profile.c') diff --git a/display-gtk.h b/display-gtk.h index 736616b1a..634f05cab 100644 --- a/display-gtk.h +++ b/display-gtk.h @@ -90,22 +90,6 @@ typedef gint (*sort_func_t)(GtkTreeModel *model, GtkTreeIter *b, gpointer user_data); -#define ALIGN_LEFT 1 -#define ALIGN_RIGHT 2 -#define INVISIBLE 4 -#define UNSORTABLE 8 -#define EDITABLE 16 - -#ifndef TEXT_SCALE -#define TEXT_SCALE 1.0 -#endif - -#define DEPTH_TEXT_SIZE (10 * TEXT_SCALE) -#define PRESSURE_TEXT_SIZE (10 * TEXT_SCALE) -#define DC_TEXT_SIZE (10.5 * TEXT_SCALE) -#define PP_TEXT_SIZE (11 * TEXT_SCALE) -#define TEMP_TEXT_SIZE (12 * TEXT_SCALE) - extern GtkTreeViewColumn *tree_view_column(GtkWidget *tree_view, int index, const char *title, data_func_t data_func, unsigned int flags); extern GtkTreeViewColumn *tree_view_column_add_pixbuf(GtkWidget *tree_view, data_func_t data_func, GtkTreeViewColumn *col); diff --git a/profile.c b/profile.c index 161415e88..15fb0ff42 100644 --- a/profile.c +++ b/profile.c @@ -157,57 +157,6 @@ int get_maxdepth(struct plot_info *pi) return md; } -#if 0 -typedef struct { - double size; - color_indice_t color; - double hpos, vpos; -} text_render_options_t; -#endif - -#define RIGHT (-1.0) -#define CENTER (-0.5) -#define LEFT (0.0) - -#define TOP (1) -#define MIDDLE (0) -#define BOTTOM (-1) - -#if USE_GTK_UI -static void plot_text(struct graphics_context *gc, const text_render_options_t *tro, - double x, double y, const char *fmt, ...) -{ - cairo_t *cr = gc->cr; - cairo_font_extents_t fe; - cairo_text_extents_t extents; - double dx, dy; - char buffer[256]; - va_list args; - - va_start(args, fmt); - vsnprintf(buffer, sizeof(buffer), fmt, args); - va_end(args); - - cairo_set_font_size(cr, tro->size * plot_scale); - cairo_font_extents(cr, &fe); - cairo_text_extents(cr, buffer, &extents); - dx = tro->hpos * (extents.width + extents.x_bearing); - dy = tro->vpos * (extents.height + fe.descent); - move_to(gc, x, y); - cairo_rel_move_to(cr, dx, dy); - - cairo_text_path(cr, buffer); - set_source_rgba(gc, TEXT_BACKGROUND); - cairo_stroke(cr); - - move_to(gc, x, y); - cairo_rel_move_to(cr, dx, dy); - - set_source_rgba(gc, tro->color); - cairo_show_text(cr, buffer); -} -#endif /* USE_GTK_UI */ - /* collect all event names and whether we display them */ struct ev_select { char *ev_name; diff --git a/profile.h b/profile.h index b3cc48a68..8f58082d1 100644 --- a/profile.h +++ b/profile.h @@ -54,6 +54,30 @@ int get_maxtime(struct plot_info *pi); * partial pressure graphs */ int get_maxdepth(struct plot_info *pi); +#define ALIGN_LEFT 1 +#define ALIGN_RIGHT 2 +#define INVISIBLE 4 +#define UNSORTABLE 8 +#define EDITABLE 16 + +#ifndef TEXT_SCALE +#define TEXT_SCALE 1.0 +#endif + +#define DEPTH_TEXT_SIZE (10 * TEXT_SCALE) +#define PRESSURE_TEXT_SIZE (10 * TEXT_SCALE) +#define DC_TEXT_SIZE (10.5 * TEXT_SCALE) +#define PP_TEXT_SIZE (11 * TEXT_SCALE) +#define TEMP_TEXT_SIZE (12 * TEXT_SCALE) + +#define RIGHT (-1.0) +#define CENTER (-0.5) +#define LEFT (0.0) + +#define TOP (1) +#define MIDDLE (0) +#define BOTTOM (-1) + #ifdef __cplusplus } #endif diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 89c3a74fc..b52368b11 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -100,6 +100,12 @@ void fill_profile_color() } #undef COLOR +struct text_render_options{ + double size; + color_indice_t color; + double hpos, vpos; +}; + ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent) { setScene(new QGraphicsScene()); @@ -293,19 +299,17 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct scene()->addItem(line); } -#if 0 /* now the text on the time markers */ - text_render_options_t tro = {DEPTH_TEXT_SIZE, TIME_TEXT, CENTER, TOP}; + struct text_render_options tro = {DEPTH_TEXT_SIZE, TIME_TEXT, CENTER, TOP}; if (maxtime < 600) { /* Be a bit more verbose with shorter dives */ for (i = incr; i < maxtime; i += incr) - plot_text(gc, &tro, i, 1, "%02d:%02d", i/60, i%60); + plot_text(gc, &tro, i, 1, QString("%1:%2").arg(i/60).arg(i%60)); } else { /* Only render the time on every second marker for normal dives */ for (i = incr; i < maxtime; i += 2 * incr) - plot_text(gc, &tro, i, 1, "%d", i/60); + plot_text(gc, &tro, i, 1, QString::number(i/60)); } -#endif /* Depth markers: every 30 ft or 10 m*/ gc->leftx = 0; gc->rightx = 1.0; @@ -418,9 +422,6 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct // TODO: Port the profile_calc_ceiling to QSettings // if (prefs.profile_calc_ceiling) { - qDebug() << "CALC_CEILING_SHALLOW" << profile_color[CALC_CEILING_SHALLOW].first(); - qDebug() << "CALC_CEILING_DEEP" << profile_color[CALC_CEILING_DEEP].first(); - pat.setColorAt(0, profile_color[CALC_CEILING_SHALLOW].first()); pat.setColorAt(1, profile_color[CALC_CEILING_DEEP].first()); @@ -479,6 +480,23 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct } } +void ProfileGraphicsView::plot_text(struct graphics_context *gc, text_render_options_t *tro, double x, double y, const QString& text) +{ + QFontMetrics fm(font()); + + double dx = tro->hpos * (fm.width(text)); + double dy = tro->vpos * (fm.height()); + + QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem(text); + QPointF point( SCALE(gc, x, y) ); // This is neded because of the SCALE macro. + + item->setPos(point.x() + dx, point.y() +dy ); + item->setBrush( QBrush(profile_color[tro->color].first())); + item->setPen( QPen(profile_color[BACKGROUND].first())); + scene()->addItem(item); + qDebug() << item->pos(); +} + void ProfileGraphicsView::resizeEvent(QResizeEvent *event) { @@ -486,5 +504,5 @@ void ProfileGraphicsView::resizeEvent(QResizeEvent *event) // I can pass some parameters to this - // like Qt::IgnoreAspectRatio or Qt::KeepAspectRatio QRectF r = scene()->sceneRect(); - fitInView ( r.x() - 2, r.y() -2, r.width() + 4, r.height() + 4); // do a little bit of spacing; + fitInView ( r.x() - 50, r.y() -50, r.width() + 100, r.height() + 100); // do a little bit of spacing; } diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index a62e55c4d..0b472f8b5 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -3,6 +3,11 @@ #include +struct text_render_options; +struct graphics_context; +struct plot_info; +typedef struct text_render_options text_render_options_t; + class ProfileGraphicsView : public QGraphicsView { Q_OBJECT public: @@ -14,6 +19,7 @@ protected: private: void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi); + void plot_text(struct graphics_context *gc, text_render_options_t *tro, double x, double y, const QString &text); QPen defaultPen; QBrush defaultBrush; -- cgit v1.2.3-70-g09d2 From 867435442b8f6f4094d7075be2cbc697d1618c26 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Mon, 6 May 2013 18:58:18 -0300 Subject: Plotting the Events done There are subtle differences, the Cairo version looks prettier - but that's fixable. I did a small triangle and a exclamation mark on it. maybe a gradient would make a good difference there. this item has a ItemIgnoresTransformation tag, so scalling, rotating or zooming will not change it's size. The tooltips are not yet ported. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- profile.c | 100 ++------------------------------------------ profile.h | 5 +++ qt-ui/profilegraphics.cpp | 104 +++++++++++++++++++++++++++++++++++++++++++++- qt-ui/profilegraphics.h | 2 + 4 files changed, 113 insertions(+), 98 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 15fb0ff42..2a8d5e4ed 100644 --- a/profile.c +++ b/profile.c @@ -158,13 +158,9 @@ int get_maxdepth(struct plot_info *pi) } /* collect all event names and whether we display them */ -struct ev_select { - char *ev_name; - gboolean plot_ev; -}; -static struct ev_select *ev_namelist; -static int evn_allocated; -static int evn_used; +struct ev_select *ev_namelist; +int evn_allocated; +int evn_used; int evn_foreach(void (*callback)(const char *, int *, void *), void *data) { @@ -205,95 +201,7 @@ void remember_event(const char *eventname) evn_used++; } -#if USE_GTK_UI -static void plot_one_event(struct graphics_context *gc, struct plot_info *pi, struct event *event) -{ - int i, depth = 0; - int x,y; - char buffer[256]; - - /* is plotting this event disabled? */ - if (event->name) { - for (i = 0; i < evn_used; i++) { - if (! strcmp(event->name, ev_namelist[i].ev_name)) { - if (ev_namelist[i].plot_ev) - break; - else - return; - } - } - } - if (event->time.seconds < 30 && !strcmp(event->name, "gaschange")) - /* a gas change in the first 30 seconds is the way of some dive computers - * to tell us the gas that is used; let's not plot a marker for that */ - return; - - for (i = 0; i < pi->nr; i++) { - struct plot_data *data = pi->entry + i; - if (event->time.seconds < data->sec) - break; - depth = data->depth; - } - /* draw a little triangular marker and attach tooltip */ - x = SCALEX(gc, event->time.seconds); - y = SCALEY(gc, depth); - set_source_rgba(gc, ALERT_BG); - cairo_move_to(gc->cr, x-6, y+12); - cairo_line_to(gc->cr, x+6, y+12); - cairo_line_to(gc->cr, x , y); - cairo_line_to(gc->cr, x-6, y+12); - cairo_stroke_preserve(gc->cr); - cairo_fill(gc->cr); - set_source_rgba(gc, ALERT_FG); - cairo_move_to(gc->cr, x, y+3); - cairo_line_to(gc->cr, x, y+7); - cairo_move_to(gc->cr, x, y+10); - cairo_line_to(gc->cr, x, y+10); - cairo_stroke(gc->cr); - /* we display the event on screen - so translate */ - if (event->value) { - if (event->name && !strcmp(event->name, "gaschange")) { - unsigned int he = event->value >> 16; - unsigned int o2 = event->value & 0xffff; - if (he) { - snprintf(buffer, sizeof(buffer), "%s:%u/%u", - _(event->name), o2, he); - } else { - if (o2 == 21) - snprintf(buffer, sizeof(buffer), "%s:%s", - _(event->name), _("air")); - else - snprintf(buffer, sizeof(buffer), "%s:%u%% %s", - _(event->name), o2, "O" UTF8_SUBSCRIPT_2); - } - } else if (event->name && !strcmp(event->name, "SP change")) { - snprintf(buffer, sizeof(buffer), "%s:%0.1f", _(event->name), (double) event->value / 1000); - } else { - snprintf(buffer, sizeof(buffer), "%s:%d", _(event->name), event->value); - } - } else if (event->name && !strcmp(event->name, "SP change")) { - snprintf(buffer, sizeof(buffer), _("Bailing out to OC")); - } else { - snprintf(buffer, sizeof(buffer), "%s%s", _(event->name), - 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, event); -} - -static void plot_events(struct graphics_context *gc, struct plot_info *pi, struct divecomputer *dc) -{ - struct event *event = dc->events; - - if (gc->printer) - return; - - while (event) { - plot_one_event(gc, pi, event); - event = event->next; - } -} - +#if 0 static void render_depth_sample(struct graphics_context *gc, struct plot_data *entry, const text_render_options_t *tro) { int sec = entry->sec, decimals; diff --git a/profile.h b/profile.h index 8f58082d1..d22589c68 100644 --- a/profile.h +++ b/profile.h @@ -39,6 +39,11 @@ struct plot_data { void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); +struct ev_select { + char *ev_name; + bool plot_ev; +}; + /* * When showing dive profiles, we scale things to the * current dive. However, we don't scale past less than diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index d4c918ac6..b3163add4 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "../color.h" #include "../display.h" @@ -106,6 +107,10 @@ struct text_render_options{ double hpos, vpos; }; +extern struct ev_select *ev_namelist; +extern int evn_allocated; +extern int evn_used; + ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent) { setScene(new QGraphicsScene()); @@ -198,9 +203,9 @@ void ProfileGraphicsView::plot(struct dive *dive) /* Depth profile */ plot_depth_profile(&gc, pi); -#if 0 - plot_events(gc, pi, dc); + plot_events(&gc, pi, dc); +#if 0 /* Temperature profile */ plot_temperature_profile(gc, pi); @@ -257,6 +262,101 @@ void ProfileGraphicsView::plot(struct dive *dive) #endif } +void ProfileGraphicsView::plot_events(struct graphics_context *gc, struct plot_info *pi, struct divecomputer *dc) +{ + struct event *event = dc->events; + +// if (gc->printer){ +// return; +// } + + while (event) { + plot_one_event(gc, pi, event); + event = event->next; + } +} + +void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plot_info *pi, struct event *ev) +{ + int i, depth = 0; + + /* is plotting this event disabled? */ + if (ev->name) { + for (i = 0; i < evn_used; i++) { + if (! strcmp(ev->name, ev_namelist[i].ev_name)) { + if (ev_namelist[i].plot_ev) + break; + else + return; + } + } + } + + if (ev->time.seconds < 30 && !strcmp(ev->name, "gaschange")) + /* a gas change in the first 30 seconds is the way of some dive computers + * to tell us the gas that is used; let's not plot a marker for that */ + return; + + for (i = 0; i < pi->nr; i++) { + struct plot_data *data = pi->entry + i; + if (ev->time.seconds < data->sec) + break; + depth = data->depth; + } + + /* draw a little triangular marker and attach tooltip */ + QPolygonF poly; + poly.push_back(QPointF(-8, 16)); + poly.push_back(QPointF(8, 16)); + poly.push_back(QPointF(0, 0)); + poly.push_back(QPointF(-8, 16)); + + int x = SCALEX(gc, ev->time.seconds); + int y = SCALEY(gc, depth); + + QGraphicsPolygonItem *triangle = new QGraphicsPolygonItem(); + triangle->setPolygon(poly); + triangle->setBrush(QBrush(profile_color[ALERT_BG].first())); + triangle->setPen(QPen(QBrush(profile_color[ALERT_FG].first()), 1)); + triangle->setFlag(QGraphicsItem::ItemIgnoresTransformations); + triangle->setPos(x, y); + + QGraphicsLineItem *line = new QGraphicsLineItem(0,5,0,10, triangle); + line->setPen(QPen(QBrush(Qt::black), 2)); + + QGraphicsEllipseItem *ball = new QGraphicsEllipseItem(-1, 12, 2,2, triangle); + ball->setBrush(QBrush(Qt::black)); + + scene()->addItem(triangle); + + /* we display the event on screen - so translate */ + QString name = tr(ev->name); + if (ev->value) { + if (ev->name && name == "gaschange") { + unsigned int he = ev->value >> 16; + unsigned int o2 = ev->value & 0xffff; + if (he) { + name += QString("%1/%2").arg(o2, he); + } else { + if (o2 == 21) + name += tr(":air"); + else + name += QString("%1 %% %2").arg(o2).arg("O" UTF8_SUBSCRIPT_2); + } + } else if (ev->name && !strcmp(ev->name, "SP change")) { + name += QString(":%1").arg( (double) ev->value / 1000 ); + } else { + name += QString(":%1").arg(ev->value); + } + } else if (ev->name && name == "SP change") { + name += tr("Bailing out to OC"); + } else { + //name += ev->flags == SAMPLE_FLAGS_BEGIN ? C_("Starts with space!"," begin") : + // ev->flags == SAMPLE_FLAGS_END ? C_("Starts with space!", " end") : ""; + } + + //attach_tooltip(x-6, y, 12, 12, buffer, ev); +} void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct plot_info *pi) { diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 0b472f8b5..928c8ea89 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -20,6 +20,8 @@ protected: private: void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi); void plot_text(struct graphics_context *gc, text_render_options_t *tro, double x, double y, const QString &text); + void plot_events(struct graphics_context *gc, struct plot_info *pi, struct divecomputer *dc); + void plot_one_event(struct graphics_context *gc, struct plot_info *pi, struct event *event); QPen defaultPen; QBrush defaultBrush; -- cgit v1.2.3-70-g09d2 From ef7ace9926276f401cceb45d546a7134eeea0f00 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Wed, 8 May 2013 17:46:28 -0300 Subject: Plot the temperature Graph Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- profile.c | 79 ++++++++++++++++------------------------------- profile.h | 5 +++ qt-ui/profilegraphics.cpp | 45 ++++++++++++++++++++++----- qt-ui/profilegraphics.h | 1 + 4 files changed, 70 insertions(+), 60 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 2a8d5e4ed..f68822009 100644 --- a/profile.c +++ b/profile.c @@ -201,6 +201,32 @@ void remember_event(const char *eventname) evn_used++; } +int setup_temperature_limits(struct graphics_context *gc, struct plot_info *pi) +{ + int maxtime, mintemp, maxtemp, delta; + + /* Get plot scaling limits */ + maxtime = get_maxtime(pi); + mintemp = pi->mintemp; + maxtemp = pi->maxtemp; + + gc->leftx = 0; gc->rightx = maxtime; + /* Show temperatures in roughly the lower third, but make sure the scale + is at least somewhat reasonable */ + delta = maxtemp - mintemp; + if (delta < 3000) /* less than 3K in fluctuation */ + delta = 3000; + gc->topy = maxtemp + delta*2; + + if (PP_GRAPHS_ENABLED) + gc->bottomy = mintemp - delta * 2; + else + gc->bottomy = mintemp - delta / 3; + + pi->endtempcoord = SCALEY(gc, pi->mintemp); + return maxtemp && maxtemp >= mintemp; +} + #if 0 static void render_depth_sample(struct graphics_context *gc, struct plot_data *entry, const text_render_options_t *tro) { @@ -441,31 +467,7 @@ static void plot_pp_gas_profile(struct graphics_context *gc, struct plot_info *p } -static int setup_temperature_limits(struct graphics_context *gc, struct plot_info *pi) -{ - int maxtime, mintemp, maxtemp, delta; - /* Get plot scaling limits */ - maxtime = get_maxtime(pi); - mintemp = pi->mintemp; - maxtemp = pi->maxtemp; - - gc->leftx = 0; gc->rightx = maxtime; - /* Show temperatures in roughly the lower third, but make sure the scale - is at least somewhat reasonable */ - delta = maxtemp - mintemp; - if (delta < 3000) /* less than 3K in fluctuation */ - delta = 3000; - gc->topy = maxtemp + delta*2; - - if (PP_GRAPHS_ENABLED) - gc->bottomy = mintemp - delta * 2; - else - gc->bottomy = mintemp - delta / 3; - - pi->endtempcoord = SCALEY(gc, pi->mintemp); - return maxtemp && maxtemp >= mintemp; -} static void plot_single_temp_text(struct graphics_context *gc, int sec, int mkelvin) { @@ -515,35 +517,6 @@ static void plot_temperature_text(struct graphics_context *gc, struct plot_info plot_single_temp_text(gc, sec, last_temperature); } -static void plot_temperature_profile(struct graphics_context *gc, struct plot_info *pi) -{ - int i; - cairo_t *cr = gc->cr; - int last = 0; - - if (!setup_temperature_limits(gc, pi)) - return; - - cairo_set_line_width_scaled(gc->cr, 2); - set_source_rgba(gc, TEMP_PLOT); - for (i = 0; i < pi->nr; i++) { - struct plot_data *entry = pi->entry + i; - int mkelvin = entry->temperature; - int sec = entry->sec; - if (!mkelvin) { - if (!last) - continue; - mkelvin = last; - } - if (last) - line_to(gc, sec, mkelvin); - else - move_to(gc, sec, mkelvin); - last = mkelvin; - } - cairo_stroke(cr); -} - /* gets both the actual start and end pressure as well as the scaling factors */ static int get_cylinder_pressure_range(struct graphics_context *gc, struct plot_info *pi) { diff --git a/profile.h b/profile.h index d22589c68..62affe04e 100644 --- a/profile.h +++ b/profile.h @@ -38,6 +38,7 @@ struct plot_data { void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); +int setup_temperature_limits(struct graphics_context *gc, struct plot_info *pi); struct ev_select { char *ev_name; @@ -83,6 +84,10 @@ int get_maxdepth(struct plot_info *pi); #define MIDDLE (0) #define BOTTOM (-1) +#define SCALEX(gc,x) (((x)-gc->leftx)/(gc->rightx-gc->leftx)*gc->maxx) +#define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy) +#define SCALE(gc,x,y) SCALEX(gc,x),SCALEY(gc,y) + #ifdef __cplusplus } #endif diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 508251232..1d1b5530c 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -26,10 +26,6 @@ #define VELOCITY_COLORS_START_IDX VELO_STABLE #define VELOCITY_COLORS 5 -/* Scale to 0,0 -> maxx,maxy */ -#define SCALEX(gc,x) (((x)-gc->leftx)/(gc->rightx-gc->leftx)*gc->maxx) -#define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy) -#define SCALE(gc,x,y) SCALEX(gc,x),SCALEY(gc,y) static struct graphics_context last_gc; static double plot_scale = SCALE_SCREEN; @@ -246,10 +242,10 @@ void ProfileGraphicsView::plot(struct dive *dive) plot_depth_profile(&gc, pi); plot_events(&gc, pi, dc); -#if 0 - /* Temperature profile */ - plot_temperature_profile(gc, pi); + /* Temperature profile */ + plot_temperature_profile(&gc, pi); +#if 0 /* Cylinder pressure plot */ plot_cylinder_pressure(gc, pi, dive, dc); @@ -630,6 +626,41 @@ void ProfileGraphicsView::resizeEvent(QResizeEvent *event) fitInView ( r.x() - 50, r.y() -50, r.width() + 100, r.height() + 100); // do a little bit of spacing; } +void ProfileGraphicsView::plot_temperature_profile(struct graphics_context *gc, struct plot_info *pi) +{ + int last = 0; + + if (!setup_temperature_limits(gc, pi)) + return; + + QPointF from; + QPointF to; + QColor color = profile_color[TEMP_PLOT].first(); + + for (int i = 0; i < pi->nr; i++) { + struct plot_data *entry = pi->entry + i; + int mkelvin = entry->temperature; + int sec = entry->sec; + if (!mkelvin) { + if (!last) + continue; + mkelvin = last; + } + if (last){ + to = QPointF(SCALE(gc, sec, mkelvin)); + //qDebug() << from << to; + QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); + item->setPen(QPen(color, 2*plot_scale)); + scene()->addItem(item); + from = to; + } + else{ + from = QPointF(SCALE(gc, sec, mkelvin)); + } + last = mkelvin; + } +} + void ToolTipItem::addToolTip(const QString& toolTip, const QIcon& icon) { QGraphicsPixmapItem *iconItem = 0; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index d607e2615..becad197a 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -94,6 +94,7 @@ private: void plot_text(struct graphics_context *gc, text_render_options_t *tro, double x, double y, const QString &text); void plot_events(struct graphics_context *gc, struct plot_info *pi, struct divecomputer *dc); void plot_one_event(struct graphics_context *gc, struct plot_info *pi, struct event *event); + void plot_temperature_profile(struct graphics_context *gc, struct plot_info *pi); QPen defaultPen; QBrush defaultBrush; -- cgit v1.2.3-70-g09d2 From 6f06c31d0b9db9ffae45d409557864469ab169b0 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Wed, 8 May 2013 14:56:06 -0700 Subject: Stop passing around gc and pi Make the graphics_context part of the ProfileGraphicsView and remember that the plot info is already a part of the graphics_context (we kept passing around both of them in the Gtk code... pointless but a leftover from before adding the pi to the gc...) Signed-off-by: Dirk Hohndel --- display.h | 2 +- profile.c | 4 +- profile.h | 4 ++ qt-ui/profilegraphics.cpp | 179 +++++++++++++++++++++++----------------------- qt-ui/profilegraphics.h | 12 ++-- 5 files changed, 103 insertions(+), 98 deletions(-) (limited to 'profile.c') diff --git a/display.h b/display.h index 047d00589..8567bc955 100644 --- a/display.h +++ b/display.h @@ -58,7 +58,7 @@ extern void plot(struct graphics_context *gc, struct dive *dive, scale_mode_t sc 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, struct event *event); -extern void get_plot_details(struct graphics_context *gc, int time, char *buf, size_t bufsize); +extern void get_plot_details(struct graphics_context *gc, int time, char *buf, int bufsize); extern int x_to_time(double x); extern int x_abs(double x); diff --git a/profile.c b/profile.c index f68822009..85fb9f3e2 100644 --- a/profile.c +++ b/profile.c @@ -1551,7 +1551,7 @@ struct divecomputer *select_dc(struct divecomputer *main) return main; } -static void plot_string(struct plot_data *entry, char *buf, size_t bufsize, +static void plot_string(struct plot_data *entry, char *buf, int bufsize, int depth, int pressure, int temp, gboolean has_ndl) { int pressurevalue, mod, ead, end, eadd; @@ -1635,7 +1635,7 @@ static void plot_string(struct plot_data *entry, char *buf, size_t bufsize, free(buf2); } -void get_plot_details(struct graphics_context *gc, int time, char *buf, size_t bufsize) +void get_plot_details(struct graphics_context *gc, int time, char *buf, int bufsize) { struct plot_info *pi = &gc->pi; int pressure = 0, temp = 0; diff --git a/profile.h b/profile.h index 62affe04e..13e417785 100644 --- a/profile.h +++ b/profile.h @@ -84,6 +84,10 @@ int get_maxdepth(struct plot_info *pi); #define MIDDLE (0) #define BOTTOM (-1) +#define SCALEXGC(x) (((x) - gc.leftx) / (gc.rightx - gc.leftx) * gc.maxx) +#define SCALEYGC(y) (((y) - gc.topy) / (gc.bottomy - gc.topy) * gc.maxy) +#define SCALEGC(x,y) SCALEXGC(x),SCALEYGC(y) + #define SCALEX(gc,x) (((x)-gc->leftx)/(gc->rightx-gc->leftx)*gc->maxx) #define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy) #define SCALE(gc,x,y) SCALEX(gc,x),SCALEY(gc,y) diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 271bd43ab..b3893ed90 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -26,7 +26,6 @@ #define VELOCITY_COLORS_START_IDX VELO_STABLE #define VELOCITY_COLORS 5 - static struct graphics_context last_gc; static double plot_scale = SCALE_SCREEN; @@ -136,8 +135,8 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) { toolTip->clear(); - QList items = scene()->items( mapToScene(event->pos() ), Qt::IntersectsItemShape, Qt::DescendingOrder, transform()); - Q_FOREACH(QGraphicsItem *item, items){ + QList items = scene()->items(mapToScene(event->pos()), Qt::IntersectsItemShape, Qt::DescendingOrder, transform()); + Q_FOREACH(QGraphicsItem *item, items) { if (!item->toolTip().isEmpty()) toolTip->addToolTip(item->toolTip()); } @@ -147,7 +146,7 @@ void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) bool ProfileGraphicsView::eventFilter(QObject* obj, QEvent* event) { // This will "Eat" the default tooltip behavior. - if (event->type() == QEvent::GraphicsSceneHelp){ + if (event->type() == QEvent::GraphicsSceneHelp) { event->ignore(); return true; } @@ -184,15 +183,13 @@ void ProfileGraphicsView::plot(struct dive *dive) scene()->addItem(toolTip); - struct plot_info *pi; struct divecomputer *dc = &dive->dc; // This was passed around in the Cairo version / needed? - graphics_context gc; - const char *nickname; + // const char *nickname; // Fix this for printing / screen later. - // plot_set_scale( scale_mode_t); + // plot_set_scale(scale_mode_t); if (!dc->samples) { static struct sample fake[4]; @@ -237,15 +234,15 @@ void ProfileGraphicsView::plot(struct dive *dive) dc = select_dc(dc); /* This is per-dive-computer. Right now we just do the first one */ - pi = create_plot_info(dive, dc, &gc); + gc.pi = *create_plot_info(dive, dc, &gc); /* Depth profile */ - plot_depth_profile(&gc, pi); + plot_depth_profile(); - plot_events(&gc, pi, dc); + plot_events(dc); /* Temperature profile */ - plot_temperature_profile(&gc, pi); + plot_temperature_profile(); #if 0 /* Cylinder pressure plot */ plot_cylinder_pressure(gc, pi, dive, dc); @@ -300,7 +297,7 @@ void ProfileGraphicsView::plot(struct dive *dive) #endif } -void ProfileGraphicsView::plot_events(struct graphics_context *gc, struct plot_info *pi, struct divecomputer *dc) +void ProfileGraphicsView::plot_events(struct divecomputer *dc) { struct event *event = dc->events; @@ -309,14 +306,15 @@ void ProfileGraphicsView::plot_events(struct graphics_context *gc, struct plot_i // } while (event) { - plot_one_event(gc, pi, event); + plot_one_event(event); event = event->next; } } -void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plot_info *pi, struct event *ev) +void ProfileGraphicsView::plot_one_event(struct event *ev) { int i, depth = 0; + struct plot_info *pi = &gc.pi; /* is plotting this event disabled? */ if (ev->name) { @@ -344,8 +342,8 @@ void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plo /* draw a little triangular marker and attach tooltip */ - int x = SCALEX(gc, ev->time.seconds); - int y = SCALEY(gc, depth); + int x = SCALEXGC(ev->time.seconds); + int y = SCALEYGC(depth); EventItem *item = new EventItem(); item->setPos(x, y); @@ -363,7 +361,7 @@ void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plo : QString("%1 %% %2").arg(o2).arg("O" UTF8_SUBSCRIPT_2); } else if (ev->name && !strcmp(ev->name, "SP change")) { - name += QString(":%1").arg( (double) ev->value / 1000 ); + name += QString(":%1").arg((double) ev->value / 1000); } else { name += QString(":%1").arg(ev->value); } @@ -379,7 +377,7 @@ void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plo item->setToolTip(name); } -void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct plot_info *pi) +void ProfileGraphicsView::plot_depth_profile() { int i, incr; int sec, depth; @@ -388,10 +386,10 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct int increments[8] = { 10, 20, 30, 60, 5*60, 10*60, 15*60, 30*60 }; /* Get plot scaling limits */ - maxtime = get_maxtime(pi); - maxdepth = get_maxdepth(pi); + maxtime = get_maxtime(&gc.pi); + maxdepth = get_maxdepth(&gc.pi); - gc->maxtime = maxtime; + gc.maxtime = maxtime; /* Time markers: at most every 10 seconds, but no more than 12 markers. * We start out with 10 seconds and increment up to 30 minutes, @@ -407,15 +405,15 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct while (maxtime / incr > 12) incr *= 2; - gc->leftx = 0; gc->rightx = maxtime; - gc->topy = 0; gc->bottomy = 1.0; + gc.leftx = 0; gc.rightx = maxtime; + gc.topy = 0; gc.bottomy = 1.0; - last_gc = *gc; + last_gc = gc; QColor color; color = profile_color[TIME_GRID].at(0); for (i = incr; i < maxtime; i += incr) { - QGraphicsLineItem *line = new QGraphicsLineItem(SCALE(gc, i, 0), SCALE(gc, i, 1)); + QGraphicsLineItem *line = new QGraphicsLineItem(SCALEGC(i, 0), SCALEGC(i, 1)); line->setPen(QPen(color)); scene()->addItem(line); } @@ -425,16 +423,16 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct if (maxtime < 600) { /* Be a bit more verbose with shorter dives */ for (i = incr; i < maxtime; i += incr) - plot_text(gc, &tro, i, 1, QString("%1:%2").arg(i/60).arg(i%60)); + plot_text(&tro, i, 1, QString("%1:%2").arg(i/60).arg(i%60)); } else { /* Only render the time on every second marker for normal dives */ for (i = incr; i < maxtime; i += 2 * incr) - plot_text(gc, &tro, i, 1, QString::number(i/60)); + plot_text(&tro, i, 1, QString::number(i/60)); } /* Depth markers: every 30 ft or 10 m*/ - gc->leftx = 0; gc->rightx = 1.0; - gc->topy = 0; gc->bottomy = maxdepth; + gc.leftx = 0; gc.rightx = 1.0; + gc.topy = 0; gc.bottomy = maxdepth; switch (prefs.units.length) { case units::METERS: marker = 10000; @@ -443,22 +441,23 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct marker = 9144; break; /* 30 ft */ } - maxline = MAX(pi->maxdepth + marker, maxdepth * 2 / 3); + maxline = MAX(gc.pi.maxdepth + marker, maxdepth * 2 / 3); color = profile_color[DEPTH_GRID].at(0); for (i = marker; i < maxline; i += marker) { - QGraphicsLineItem *line = new QGraphicsLineItem(SCALE(gc, 0, i), SCALE(gc, 1, i)); + QGraphicsLineItem *line = new QGraphicsLineItem(SCALEGC(0, i), SCALEGC(1, i)); line->setPen(QPen(color)); scene()->addItem(line); } - gc->leftx = 0; gc->rightx = maxtime; + gc.leftx = 0; gc.rightx = maxtime; color = profile_color[MEAN_DEPTH].at(0); /* Show mean depth */ - if (! gc->printer) { - QGraphicsLineItem *line = new QGraphicsLineItem(SCALE(gc, 0, pi->meandepth), SCALE(gc, pi->entry[pi->nr - 1].sec, pi->meandepth)); + if (! gc.printer) { + QGraphicsLineItem *line = new QGraphicsLineItem(SCALEGC(0, gc.pi.meandepth), + SCALEGC(gc.pi.entry[gc.pi.nr - 1].sec, gc.pi.meandepth)); line->setPen(QPen(color)); scene()->addItem(line); } @@ -475,27 +474,27 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct #endif /* Do the depth profile for the neat fill */ - gc->topy = 0; gc->bottomy = maxdepth; + gc.topy = 0; gc.bottomy = maxdepth; - entry = pi->entry; + entry = gc.pi.entry; QPolygonF p; QLinearGradient pat(0.0,0.0,0.0,scene()->height()); QGraphicsPolygonItem *neatFill = NULL; - p.append( QPointF(SCALE(gc, 0, 0) )); - for (i = 0; i < pi->nr; i++, entry++) - p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); + p.append(QPointF(SCALEGC(0, 0))); + for (i = 0; i < gc.pi.nr; i++, entry++) + p.append(QPointF(SCALEGC(entry->sec, entry->depth))); /* Show any ceiling we may have encountered */ - for (i = pi->nr - 1; i >= 0; i--, entry--) { + for (i = gc.pi.nr - 1; i >= 0; i--, entry--) { if (entry->ndl) { /* non-zero NDL implies this is a safety stop, no ceiling */ - p.append( QPointF( SCALE(gc, entry->sec, 0) )); + p.append(QPointF(SCALEGC(entry->sec, 0))); } else if (entry->stopdepth < entry->depth) { - p.append( QPointF( SCALE(gc, entry->sec, entry->stopdepth) )); + p.append(QPointF(SCALEGC(entry->sec, entry->stopdepth))); } else { - p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); + p.append(QPointF(SCALEGC(entry->sec, entry->depth))); } } pat.setColorAt(1, profile_color[DEPTH_BOTTOM].first()); @@ -518,17 +517,17 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct pat.setColorAt(0, profile_color[CEILING_SHALLOW].first()); pat.setColorAt(1, profile_color[CEILING_DEEP].first()); - entry = pi->entry; - p.append( QPointF(SCALE(gc, 0, 0) )); - for (i = 0; i < pi->nr; i++, entry++) { + entry = gc.pi.entry; + p.append(QPointF(SCALEGC(0, 0))); + for (i = 0; i < gc.pi.nr; i++, entry++) { if (entry->ndl == 0 && entry->stopdepth) { if (entry->ndl == 0 && entry->stopdepth < entry->depth) { - p.append( QPointF( SCALE(gc, entry->sec, entry->stopdepth) )); + p.append(QPointF(SCALEGC(entry->sec, entry->stopdepth))); } else { - p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); + p.append(QPointF(SCALEGC(entry->sec, entry->depth))); } } else { - p.append( QPointF( SCALE(gc, entry->sec, 0) )); + p.append(QPointF(SCALEGC(entry->sec, 0))); } } @@ -546,16 +545,16 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct pat.setColorAt(0, profile_color[CALC_CEILING_SHALLOW].first()); pat.setColorAt(1, profile_color[CALC_CEILING_DEEP].first()); - entry = pi->entry; + entry = gc.pi.entry; p.clear(); - p.append( QPointF(SCALE(gc, 0, 0) )); - for (i = 0; i < pi->nr; i++, entry++) { + p.append(QPointF(SCALEGC(0, 0))); + for (i = 0; i < gc.pi.nr; i++, entry++) { if (entry->ceiling) - p.append( QPointF( SCALE(gc, entry->sec, entry->ceiling) )); + p.append(QPointF(SCALEGC(entry->sec, entry->ceiling))); else - p.append( QPointF( SCALE(gc, entry->sec, 0) )); + p.append(QPointF(SCALEGC(entry->sec, 0))); } - p.append( QPointF( SCALE(gc, (entry-1)->sec, 0) )); + p.append(QPointF(SCALEGC((entry-1)->sec, 0))); neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); neatFill->setPen(QPen(QBrush(),0)); @@ -566,17 +565,17 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct pat.setColorAt(0, profile_color[CEILING_SHALLOW].first()); pat.setColorAt(1, profile_color[CEILING_DEEP].first()); - entry = pi->entry; + entry = gc.pi.entry; p.clear(); - p.append( QPointF(SCALE(gc, 0, 0) )); - for (i = 0; i < pi->nr; i++, entry++) - p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); + p.append(QPointF(SCALEGC(0, 0))); + for (i = 0; i < gc.pi.nr; i++, entry++) + p.append(QPointF(SCALEGC(entry->sec, entry->depth))); - for (i = pi->nr - 1; i >= 0; i--, entry--) { + for (i = gc.pi.nr - 1; i >= 0; i--, entry--) { if (entry->ndl == 0 && entry->stopdepth > entry->depth) { - p.append( QPointF( SCALE(gc, entry->sec, entry->stopdepth) )); + p.append(QPointF(SCALEGC(entry->sec, entry->stopdepth))); } else { - p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); + p.append(QPointF(SCALEGC(entry->sec, entry->depth))); } } @@ -587,21 +586,21 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct scene()->addItem(neatFill); /* Now do it again for the velocity colors */ - entry = pi->entry; - for (i = 1; i < pi->nr; i++) { + entry = gc.pi.entry; + for (i = 1; i < gc.pi.nr; i++) { entry++; sec = entry->sec; /* we want to draw the segments in different colors * representing the vertical velocity, so we need to * chop this into short segments */ depth = entry->depth; - QGraphicsLineItem *colorLine = new QGraphicsLineItem( SCALE(gc, entry[-1].sec, entry[-1].depth), SCALE(gc, sec, depth)); - colorLine->setPen(QPen(QBrush(profile_color[ (color_indice_t) (VELOCITY_COLORS_START_IDX + entry->velocity)].first()), 2 )); + QGraphicsLineItem *colorLine = new QGraphicsLineItem(SCALEGC(entry[-1].sec, entry[-1].depth), SCALEGC(sec, depth)); + colorLine->setPen(QPen(QBrush(profile_color[ (color_indice_t) (VELOCITY_COLORS_START_IDX + entry->velocity)].first()), 2)); scene()->addItem(colorLine); } } -void ProfileGraphicsView::plot_text(struct graphics_context *gc, text_render_options_t *tro, double x, double y, const QString& text) +void ProfileGraphicsView::plot_text(text_render_options_t *tro, double x, double y, const QString& text) { QFontMetrics fm(font()); @@ -609,11 +608,11 @@ void ProfileGraphicsView::plot_text(struct graphics_context *gc, text_render_opt double dy = tro->vpos * (fm.height()); QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem(text); - QPointF point( SCALE(gc, x, y) ); // This is neded because of the SCALE macro. + QPointF point(SCALEGC(x, y)); // This is neded because of the SCALE macro. - item->setPos(point.x() + dx, point.y() +dy ); - item->setBrush( QBrush(profile_color[tro->color].first())); - item->setPen( QPen(profile_color[BACKGROUND].first())); + item->setPos(point.x() + dx, point.y() +dy); + item->setBrush(QBrush(profile_color[tro->color].first())); + item->setPen(QPen(profile_color[BACKGROUND].first())); item->setFlag(QGraphicsItem::ItemIgnoresTransformations); scene()->addItem(item); } @@ -624,22 +623,22 @@ void ProfileGraphicsView::resizeEvent(QResizeEvent *event) // I can pass some parameters to this - // like Qt::IgnoreAspectRatio or Qt::KeepAspectRatio QRectF r = scene()->sceneRect(); - fitInView ( r.x() - 50, r.y() -50, r.width() + 100, r.height() + 100); // do a little bit of spacing; + fitInView (r.x() - 50, r.y() -50, r.width() + 100, r.height() + 100); // do a little bit of spacing; } -void ProfileGraphicsView::plot_temperature_profile(struct graphics_context *gc, struct plot_info *pi) +void ProfileGraphicsView::plot_temperature_profile() { int last = 0; - if (!setup_temperature_limits(gc, pi)) + if (!setup_temperature_limits(&gc, &gc.pi)) return; QPointF from; QPointF to; QColor color = profile_color[TEMP_PLOT].first(); - for (int i = 0; i < pi->nr; i++) { - struct plot_data *entry = pi->entry + i; + for (int i = 0; i < gc.pi.nr; i++) { + struct plot_data *entry = gc.pi.entry + i; int mkelvin = entry->temperature; int sec = entry->sec; if (!mkelvin) { @@ -647,8 +646,8 @@ void ProfileGraphicsView::plot_temperature_profile(struct graphics_context *gc, continue; mkelvin = last; } - if (last){ - to = QPointF(SCALE(gc, sec, mkelvin)); + if (last) { + to = QPointF(SCALEGC(sec, mkelvin)); //qDebug() << from << to; QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); item->setPen(QPen(color, 2*plot_scale)); @@ -656,7 +655,7 @@ void ProfileGraphicsView::plot_temperature_profile(struct graphics_context *gc, from = to; } else{ - from = QPointF(SCALE(gc, sec, mkelvin)); + from = QPointF(SCALEGC(sec, mkelvin)); } last = mkelvin; } @@ -669,11 +668,11 @@ void ToolTipItem::addToolTip(const QString& toolTip, const QIcon& icon) if (!icon.isNull()) { iconItem = new QGraphicsPixmapItem(icon.pixmap(ICON_SMALL,ICON_SMALL), this); - iconItem->setPos( SPACING, yValue); + iconItem->setPos(SPACING, yValue); } QGraphicsSimpleTextItem *textItem = new QGraphicsSimpleTextItem(toolTip, this); - textItem->setPos( SPACING + ICON_SMALL + SPACING, yValue); + textItem->setPos(SPACING + ICON_SMALL + SPACING, yValue); textItem->setPen(QPen(Qt::white, 1)); textItem->setBrush(QBrush(Qt::white)); textItem->setFlag(ItemIgnoresTransformations); @@ -692,7 +691,7 @@ void ToolTipItem::removeToolTip(const QString& toolTip) int toolTipIndex = 0; // We removed a toolTip, let's move the others to the correct location - Q_FOREACH(ToolTip t, toolTips){ + Q_FOREACH(ToolTip t, toolTips) { double yValue = title->boundingRect().height() + SPACING + toolTipIndex * ICON_SMALL + SPACING; // Icons can be null. @@ -733,7 +732,7 @@ void ToolTipItem::setRect(const QRectF& r) setPath(border); QPainterPath bg; - bg.addRoundedRect( -1, -1, rectangle.width() + 3, rectangle.height() + 4, 3, 3); + bg.addRoundedRect(-1, -1, rectangle.width() + 3, rectangle.height() + 4, 3, 3); QColor c = QColor(Qt::black); c.setAlpha(155); @@ -756,7 +755,7 @@ void ToolTipItem::collapse() QPropertyAnimation *animation = new QPropertyAnimation(this, "rect"); animation->setDuration(100); animation->setStartValue(boundingRect()); - animation->setEndValue(QRect(0, 0, ICON_SMALL, ICON_SMALL )); + animation->setEndValue(QRect(0, 0, ICON_SMALL, ICON_SMALL)); animation->start(QAbstractAnimation::DeleteWhenStopped); } @@ -778,7 +777,7 @@ void ToolTipItem::expand() if (width < title->boundingRect().width() + SPACING*2) width = title->boundingRect().width() + SPACING*2; - if( height < ICON_SMALL) + if(height < ICON_SMALL) height = ICON_SMALL; nextRectangle.setWidth(width); @@ -806,10 +805,10 @@ ToolTipItem::ToolTipItem(QGraphicsItem* parent): QGraphicsPathItem(parent), back void ToolTipItem::updateTitlePosition() { - if (rectangle.width() < title->boundingRect().width() + SPACING*4 ){ + if (rectangle.width() < title->boundingRect().width() + SPACING*4) { QRectF newRect = rectangle; newRect.setWidth(title->boundingRect().width() + SPACING*4); - newRect.setHeight( newRect.height() ? newRect.height() : ICON_SMALL ); + newRect.setHeight(newRect.height() ? newRect.height() : ICON_SMALL); setRect(newRect); } @@ -818,7 +817,7 @@ void ToolTipItem::updateTitlePosition() title->setPen(QPen(Qt::white, 1)); title->setBrush(Qt::white); - if (toolTips.size() > 0){ + if (toolTips.size() > 0) { double x1 = 0; double y1 = title->pos().y() + SPACING/2 + title->boundingRect().height(); double x2 = boundingRect().width() - 10; @@ -828,7 +827,7 @@ void ToolTipItem::updateTitlePosition() separator->setFlag(ItemIgnoresTransformations); separator->setPen(QPen(Qt::white)); separator->show(); - }else{ + } else { separator->hide(); } } diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index becad197a..e1cb417f9 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -1,6 +1,7 @@ #ifndef PROFILEGRAPHICS_H #define PROFILEGRAPHICS_H +#include "../display.h" #include #include #include @@ -90,15 +91,16 @@ protected: void mouseMoveEvent(QMouseEvent* event); private: - void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi); - void plot_text(struct graphics_context *gc, text_render_options_t *tro, double x, double y, const QString &text); - void plot_events(struct graphics_context *gc, struct plot_info *pi, struct divecomputer *dc); - void plot_one_event(struct graphics_context *gc, struct plot_info *pi, struct event *event); - void plot_temperature_profile(struct graphics_context *gc, struct plot_info *pi); + void plot_depth_profile(); + void plot_text(text_render_options_t *tro, double x, double y, const QString &text); + void plot_events(struct divecomputer *dc); + void plot_one_event(struct event *event); + void plot_temperature_profile(); QPen defaultPen; QBrush defaultBrush; ToolTipItem *toolTip; + graphics_context gc; }; #endif -- cgit v1.2.3-70-g09d2 From 9554cb57673f3dc4818b9578ea607526c813242e Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 00:24:03 -0300 Subject: Plot of the Cylinder Pressure over time. a few code was moved around, a macro that contained the form of x ? : y; had to be rewritten to x ? x : y since c++ doesn't allow ternarys without the middle operator. The color-choosing for the Cylinder Pressure broke on the Qt port - but it's a small issue. I'm painting everyone as 'dark green' now, will fix that later. Signed-off-by: Tomaz Canabrava --- profile.c | 114 ++++------------------------------------------ profile.h | 12 +++++ qt-ui/profilegraphics.cpp | 100 ++++++++++++++++++++++++++++++++++++++-- qt-ui/profilegraphics.h | 3 ++ 4 files changed, 121 insertions(+), 108 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 85fb9f3e2..61bbd12ce 100644 --- a/profile.c +++ b/profile.c @@ -25,14 +25,6 @@ static struct plot_data *last_pi_entry = NULL; #define cairo_set_line_width_scaled(cr, w) \ cairo_set_line_width((cr), (w) * plot_scale); - - -#define SENSOR_PR 0 -#define INTERPOLATED_PR 1 -#define SENSOR_PRESSURE(_entry) (_entry)->pressure[SENSOR_PR] -#define INTERPOLATED_PRESSURE(_entry) (_entry)->pressure[INTERPOLATED_PR] -#define GET_PRESSURE(_entry) (SENSOR_PRESSURE(_entry) ? : INTERPOLATED_PRESSURE(_entry)) - #if USE_GTK_UI /* keep the last used gc around so we can invert the SCALEX calculation in @@ -518,46 +510,28 @@ static void plot_temperature_text(struct graphics_context *gc, struct plot_info } /* gets both the actual start and end pressure as well as the scaling factors */ -static int get_cylinder_pressure_range(struct graphics_context *gc, struct plot_info *pi) + +#endif /* USE_GTK_UI */ + +int get_cylinder_pressure_range(struct graphics_context *gc) { gc->leftx = 0; - gc->rightx = get_maxtime(pi); + gc->rightx = get_maxtime(&gc->pi); if (PP_GRAPHS_ENABLED) - gc->bottomy = -pi->maxpressure * 0.75; + gc->bottomy = -gc->pi.maxpressure * 0.75; else gc->bottomy = 0; - gc->topy = pi->maxpressure * 1.5; - if (!pi->maxpressure) + gc->topy = gc->pi.maxpressure * 1.5; + if (!gc->pi.maxpressure) return FALSE; - while (pi->endtempcoord <= SCALEY(gc, pi->minpressure - (gc->topy) * 0.1)) + while (gc->pi.endtempcoord <= SCALEY(gc, gc->pi.minpressure - (gc->topy) * 0.1)) gc->bottomy -= gc->topy * 0.1; return TRUE; } -/* set the color for the pressure plot according to temporary sac rate - * as compared to avg_sac; the calculation simply maps the delta between - * sac and avg_sac to indexes 0 .. (SAC_COLORS - 1) with everything - * more than 6000 ml/min below avg_sac mapped to 0 */ -void set_sac_color(struct graphics_context *gc, int sac, int avg_sac) -{ - int sac_index = 0; - int delta = sac - avg_sac + 7000; - - if (!gc->printer) { - sac_index = delta / 2000; - if (sac_index < 0) - sac_index = 0; - if (sac_index > SAC_COLORS - 1) - sac_index = SAC_COLORS - 1; - set_source_rgba(gc, SAC_COLORS_START_IDX + sac_index); - } else { - set_source_rgba(gc, SAC_DEFAULT); - } -} -#endif /* USE_GTK_UI */ /* Get local sac-rate (in ml/min) between entry1 and entry2 */ int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive) @@ -590,78 +564,8 @@ int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct div return airuse / atm * 60 / duration; } -/* calculate the current SAC in ml/min and convert to int */ -#define GET_LOCAL_SAC(_entry1, _entry2, _dive) \ - get_local_sac(_entry1, _entry2, _dive) - -#define SAC_WINDOW 45 /* sliding window in seconds for current SAC calculation */ - #if USE_GTK_UI -static void plot_cylinder_pressure(struct graphics_context *gc, struct plot_info *pi, - struct dive *dive, struct divecomputer *dc) -{ - int i; - int last = -1, last_index = -1; - int lift_pen = FALSE; - int first_plot = TRUE; - int sac = 0; - struct plot_data *last_entry = NULL; - - if (!get_cylinder_pressure_range(gc, pi)) - return; - - cairo_set_line_width_scaled(gc->cr, 2); - - for (i = 0; i < pi->nr; i++) { - int mbar; - struct plot_data *entry = pi->entry + i; - mbar = GET_PRESSURE(entry); - if (entry->cylinderindex != last_index) { - lift_pen = TRUE; - last_entry = NULL; - } - if (!mbar) { - lift_pen = TRUE; - continue; - } - if (!last_entry) { - last = i; - last_entry = entry; - sac = GET_LOCAL_SAC(entry, pi->entry + i + 1, dive); - } else { - int j; - sac = 0; - for (j = last; j < i; j++) - sac += GET_LOCAL_SAC(pi->entry + j, pi->entry + j + 1, dive); - sac /= (i - last); - if (entry->sec - last_entry->sec >= SAC_WINDOW) { - last++; - last_entry = pi->entry + last; - } - } - set_sac_color(gc, sac, dive->sac); - if (lift_pen) { - if (!first_plot && entry->cylinderindex == last_index) { - /* if we have a previous event from the same tank, - * draw at least a short line */ - int prev_pr; - prev_pr = GET_PRESSURE(entry - 1); - move_to(gc, (entry-1)->sec, prev_pr); - line_to(gc, entry->sec, mbar); - } else { - first_plot = FALSE; - move_to(gc, entry->sec, mbar); - } - lift_pen = FALSE; - } else { - line_to(gc, entry->sec, mbar); - } - cairo_stroke(gc->cr); - move_to(gc, entry->sec, mbar); - last_index = entry->cylinderindex; - } -} static void plot_pressure_value(struct graphics_context *gc, int mbar, int sec, int xalign, int yalign) diff --git a/profile.h b/profile.h index 13e417785..9389641d5 100644 --- a/profile.h +++ b/profile.h @@ -39,6 +39,7 @@ struct plot_data { void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); int setup_temperature_limits(struct graphics_context *gc, struct plot_info *pi); +int get_cylinder_pressure_range(struct graphics_context *gc); struct ev_select { char *ev_name; @@ -60,6 +61,9 @@ int get_maxtime(struct plot_info *pi); * partial pressure graphs */ int get_maxdepth(struct plot_info *pi); +int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive); + + #define ALIGN_LEFT 1 #define ALIGN_RIGHT 2 #define INVISIBLE 4 @@ -92,6 +96,14 @@ int get_maxdepth(struct plot_info *pi); #define SCALEY(gc,y) (((y)-gc->topy)/(gc->bottomy-gc->topy)*gc->maxy) #define SCALE(gc,x,y) SCALEX(gc,x),SCALEY(gc,y) +#define SENSOR_PR 0 +#define INTERPOLATED_PR 1 +#define SENSOR_PRESSURE(_entry) (_entry)->pressure[SENSOR_PR] +#define INTERPOLATED_PRESSURE(_entry) (_entry)->pressure[INTERPOLATED_PR] +#define GET_PRESSURE(_entry) (SENSOR_PRESSURE(_entry) ? SENSOR_PRESSURE(_entry) : INTERPOLATED_PRESSURE(_entry)) + +#define SAC_WINDOW 45 /* sliding window in seconds for current SAC calculation */ + #ifdef __cplusplus } #endif diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 50791e14c..32bd87d14 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -238,10 +238,10 @@ void ProfileGraphicsView::plot(struct dive *dive) /* Temperature profile */ plot_temperature_profile(); -#if 0 - /* Cylinder pressure plot */ - plot_cylinder_pressure(gc, pi, dive, dc); + /* Cylinder pressure plot */ + plot_cylinder_pressure(dive, dc); +#if 0 /* Text on top of all graphs.. */ plot_temperature_text(gc, pi); plot_depth_text(gc, pi); @@ -288,6 +288,100 @@ void ProfileGraphicsView::plot(struct dive *dive) #endif } +void ProfileGraphicsView::plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc) +{ + int i; + int last = -1, last_index = -1; + int lift_pen = FALSE; + int first_plot = TRUE; + int sac = 0; + struct plot_data *last_entry = NULL; + + if (!get_cylinder_pressure_range(&gc)) + return; + + QPointF from, to; + for (i = 0; i < gc.pi.nr; i++) { + int mbar; + struct plot_data *entry = gc.pi.entry + i; + + mbar = GET_PRESSURE(entry); + if (entry->cylinderindex != last_index) { + lift_pen = TRUE; + last_entry = NULL; + } + if (!mbar) { + lift_pen = TRUE; + continue; + } + if (!last_entry) { + last = i; + last_entry = entry; + sac = get_local_sac(entry, gc.pi.entry + i + 1, dive); + } else { + int j; + sac = 0; + for (j = last; j < i; j++) + sac += get_local_sac(gc.pi.entry + j, gc.pi.entry + j + 1, dive); + sac /= (i - last); + if (entry->sec - last_entry->sec >= SAC_WINDOW) { + last++; + last_entry = gc.pi.entry + last; + } + } + + // QColor c = get_sac_color(sac, dive->sac); Buggy TODO: fix. + QColor c = QColor(Qt::darkGreen); + + if (lift_pen) { + if (!first_plot && entry->cylinderindex == last_index) { + /* if we have a previous event from the same tank, + * draw at least a short line */ + int prev_pr; + prev_pr = GET_PRESSURE(entry - 1); + + QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC((entry-1)->sec, prev_pr), SCALEGC(entry->sec, mbar)); + item->setPen(QPen(c, 2)); + scene()->addItem(item); + } else { + first_plot = FALSE; + from = QPointF(SCALEGC(entry->sec, mbar)); + } + lift_pen = FALSE; + } else { + to = QPointF(SCALEGC(entry->sec, mbar)); + QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); + item->setPen(QPen(c, 2)); + scene()->addItem(item); + } + + + from = QPointF(SCALEGC(entry->sec, mbar)); + last_index = entry->cylinderindex; + } +} + + +/* set the color for the pressure plot according to temporary sac rate + * as compared to avg_sac; the calculation simply maps the delta between + * sac and avg_sac to indexes 0 .. (SAC_COLORS - 1) with everything + * more than 6000 ml/min below avg_sac mapped to 0 */ +QColor ProfileGraphicsView::get_sac_color(int sac, int avg_sac) +{ + int sac_index = 0; + int delta = sac - avg_sac + 7000; + + if (!gc.printer) { + sac_index = delta / 2000; + if (sac_index < 0) + sac_index = 0; + if (sac_index > SAC_COLORS - 1) + sac_index = SAC_COLORS - 1; + return profile_color[ (color_indice_t) (SAC_COLORS_START_IDX + sac_index)].first(); + } + return profile_color[SAC_DEFAULT].first(); +} + void ProfileGraphicsView::plot_events(struct divecomputer *dc) { struct event *event = dc->events; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index e1cb417f9..7f166574d 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -96,6 +96,9 @@ private: void plot_events(struct divecomputer *dc); void plot_one_event(struct event *event); void plot_temperature_profile(); + void plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc); + + QColor get_sac_color(int sac, int avg_sac); QPen defaultPen; QBrush defaultBrush; -- cgit v1.2.3-70-g09d2 From c62e8e5baa647bfa2e4773bc611eaef7985a7bb7 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 15:28:50 -0300 Subject: Plotting temperature text. Signed-off-by: Tomaz Canabrava --- profile.c | 49 ++-------------------------------------- profile.h | 2 +- qt-ui/profilegraphics.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++--- qt-ui/profilegraphics.h | 3 ++- 4 files changed, 59 insertions(+), 52 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 61bbd12ce..3905a029c 100644 --- a/profile.c +++ b/profile.c @@ -193,10 +193,11 @@ void remember_event(const char *eventname) evn_used++; } -int setup_temperature_limits(struct graphics_context *gc, struct plot_info *pi) +int setup_temperature_limits(struct graphics_context *gc) { int maxtime, mintemp, maxtemp, delta; + struct plot_info *pi = &gc->pi; /* Get plot scaling limits */ maxtime = get_maxtime(pi); mintemp = pi->mintemp; @@ -461,53 +462,7 @@ static void plot_pp_gas_profile(struct graphics_context *gc, struct plot_info *p -static void plot_single_temp_text(struct graphics_context *gc, int sec, int mkelvin) -{ - double deg; - const char *unit; - static const text_render_options_t tro = {TEMP_TEXT_SIZE, TEMP_TEXT, LEFT, TOP}; - - deg = get_temp_units(mkelvin, &unit); - - plot_text(gc, &tro, sec, mkelvin, "%.2g%s", deg, unit); -} - -static void plot_temperature_text(struct graphics_context *gc, struct plot_info *pi) -{ - int i; - int last = -300, sec = 0; - int last_temperature = 0, last_printed_temp = 0; - - if (!setup_temperature_limits(gc, pi)) - return; - - for (i = 0; i < pi->nr; i++) { - struct plot_data *entry = pi->entry+i; - int mkelvin = entry->temperature; - sec = entry->sec; - if (!mkelvin) - continue; - last_temperature = mkelvin; - /* don't print a temperature - * if it's been less than 5min and less than a 2K change OR - * if it's been less than 2min OR if the change from the - * last print is less than .4K (and therefore less than 1F */ - if (((sec < last + 300) && (abs(mkelvin - last_printed_temp) < 2000)) || - (sec < last + 120) || - (abs(mkelvin - last_printed_temp) < 400)) - continue; - last = sec; - plot_single_temp_text(gc,sec,mkelvin); - last_printed_temp = mkelvin; - } - /* it would be nice to print the end temperature, if it's - * different or if the last temperature print has been more - * than a quarter of the dive back */ - if ((abs(last_temperature - last_printed_temp) > 500) || - ((double)last / (double)sec < 0.75)) - plot_single_temp_text(gc, sec, last_temperature); -} /* gets both the actual start and end pressure as well as the scaling factors */ diff --git a/profile.h b/profile.h index 9389641d5..73c5152f9 100644 --- a/profile.h +++ b/profile.h @@ -38,7 +38,7 @@ struct plot_data { void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc); -int setup_temperature_limits(struct graphics_context *gc, struct plot_info *pi); +int setup_temperature_limits(struct graphics_context *gc); int get_cylinder_pressure_range(struct graphics_context *gc); struct ev_select { diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 3baf2b008..53d943e09 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -242,10 +242,13 @@ void ProfileGraphicsView::plot(struct dive *dive) /* Cylinder pressure plot */ plot_cylinder_pressure(dive, dc); -#if 0 + /* Text on top of all graphs.. */ - plot_temperature_text(gc, pi); + plot_temperature_text(); + plot_depth_text(gc, pi); + +#if 0 plot_cylinder_pressure_text(gc, pi); plot_deco_text(gc, pi); #endif @@ -289,6 +292,54 @@ void ProfileGraphicsView::plot(struct dive *dive) #endif } +void ProfileGraphicsView::plot_temperature_text() +{ + int i; + int last = -300, sec = 0; + int last_temperature = 0, last_printed_temp = 0; + plot_info *pi = &gc.pi; + + if (!setup_temperature_limits(&gc)) + return; + + for (i = 0; i < pi->nr; i++) { + struct plot_data *entry = pi->entry+i; + int mkelvin = entry->temperature; + sec = entry->sec; + + if (!mkelvin) + continue; + last_temperature = mkelvin; + /* don't print a temperature + * if it's been less than 5min and less than a 2K change OR + * if it's been less than 2min OR if the change from the + * last print is less than .4K (and therefore less than 1F */ + if (((sec < last + 300) && (abs(mkelvin - last_printed_temp) < 2000)) || + (sec < last + 120) || + (abs(mkelvin - last_printed_temp) < 400)) + continue; + last = sec; + + plot_single_temp_text(sec,mkelvin); + last_printed_temp = mkelvin; + } + /* it would be nice to print the end temperature, if it's + * different or if the last temperature print has been more + * than a quarter of the dive back */ + if ((abs(last_temperature - last_printed_temp) > 500) || + ((double)last / (double)sec < 0.75)) + plot_single_temp_text(sec, last_temperature); +} + +void ProfileGraphicsView::plot_single_temp_text(int sec, int mkelvin) +{ + double deg; + const char *unit; + static text_render_options_t tro = {TEMP_TEXT_SIZE, TEMP_TEXT, LEFT, TOP}; + deg = get_temp_units(mkelvin, &unit); + plot_text(&tro, sec, mkelvin, QString("%1%2").arg(deg).arg(unit)); //"%.2g%s" +} + void ProfileGraphicsView::plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc) { int i; @@ -716,7 +767,7 @@ void ProfileGraphicsView::plot_temperature_profile() { int last = 0; - if (!setup_temperature_limits(&gc, &gc.pi)) + if (!setup_temperature_limits(&gc)) return; QPointF from; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 7f166574d..d6c30dda2 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -97,7 +97,8 @@ private: void plot_one_event(struct event *event); void plot_temperature_profile(); void plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc); - + void plot_temperature_text(); + void plot_single_temp_text(int sec, int mkelvin); QColor get_sac_color(int sac, int avg_sac); QPen defaultPen; -- cgit v1.2.3-70-g09d2 From d6d1a10195e1d14bafb5987d5f7b8e776a82b4be Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 15:37:43 -0300 Subject: Plotting depth text. Signed-off-by: Tomaz Canabrava --- profile.c | 51 ------------------------------------------ qt-ui/profilegraphics.cpp | 57 ++++++++++++++++++++++++++++++++++++++++++++++- qt-ui/profilegraphics.h | 4 ++++ 3 files changed, 60 insertions(+), 52 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 3905a029c..67f83f0a6 100644 --- a/profile.c +++ b/profile.c @@ -221,57 +221,6 @@ int setup_temperature_limits(struct graphics_context *gc) } #if 0 -static void render_depth_sample(struct graphics_context *gc, struct plot_data *entry, const text_render_options_t *tro) -{ - int sec = entry->sec, decimals; - double d; - - d = get_depth_units(entry->depth, &decimals, NULL); - - plot_text(gc, tro, sec, entry->depth, "%.*f", decimals, d); -} - -static void plot_text_samples(struct graphics_context *gc, struct plot_info *pi) -{ - static const text_render_options_t deep = {14, SAMPLE_DEEP, CENTER, TOP}; - static const text_render_options_t shallow = {14, SAMPLE_SHALLOW, CENTER, BOTTOM}; - int i; - int last = -1; - - for (i = 0; i < pi->nr; i++) { - struct plot_data *entry = pi->entry + i; - - if (entry->depth < 2000) - continue; - - if ((entry == entry->max[2]) && entry->depth != last) { - render_depth_sample(gc, entry, &deep); - last = entry->depth; - } - - if ((entry == entry->min[2]) && entry->depth != last) { - render_depth_sample(gc, entry, &shallow); - last = entry->depth; - } - - if (entry->depth != last) - last = -1; - } -} - -static void plot_depth_text(struct graphics_context *gc, struct plot_info *pi) -{ - int maxtime, maxdepth; - - /* Get plot scaling limits */ - maxtime = get_maxtime(pi); - maxdepth = get_maxdepth(pi); - - gc->leftx = 0; gc->rightx = maxtime; - gc->topy = 0; gc->bottomy = maxdepth; - - plot_text_samples(gc, pi); -} static void plot_smoothed_profile(struct graphics_context *gc, struct plot_info *pi) { diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 53d943e09..158cec286 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -246,7 +246,7 @@ void ProfileGraphicsView::plot(struct dive *dive) /* Text on top of all graphs.. */ plot_temperature_text(); - plot_depth_text(gc, pi); + plot_depth_text(); #if 0 plot_cylinder_pressure_text(gc, pi); @@ -292,6 +292,61 @@ void ProfileGraphicsView::plot(struct dive *dive) #endif } +void ProfileGraphicsView::plot_depth_text() +{ + int maxtime, maxdepth; + + /* Get plot scaling limits */ + maxtime = get_maxtime(&gc.pi); + maxdepth = get_maxdepth(&gc.pi); + + gc.leftx = 0; gc.rightx = maxtime; + gc.topy = 0; gc.bottomy = maxdepth; + + plot_text_samples(); +} + +void ProfileGraphicsView::plot_text_samples() +{ + static text_render_options_t deep = {14, SAMPLE_DEEP, CENTER, TOP}; + static text_render_options_t shallow = {14, SAMPLE_SHALLOW, CENTER, BOTTOM}; + int i; + int last = -1; + + struct plot_info* pi = &gc.pi; + + for (i = 0; i < pi->nr; i++) { + struct plot_data *entry = pi->entry + i; + + if (entry->depth < 2000) + continue; + + if ((entry == entry->max[2]) && entry->depth != last) { + plot_depth_sample(entry, &deep); + last = entry->depth; + } + + if ((entry == entry->min[2]) && entry->depth != last) { + plot_depth_sample(entry, &shallow); + last = entry->depth; + } + + if (entry->depth != last) + last = -1; + } +} + +void ProfileGraphicsView::plot_depth_sample(struct plot_data *entry,text_render_options_t *tro) +{ + int sec = entry->sec, decimals; + double d; + + d = get_depth_units(entry->depth, &decimals, NULL); + + plot_text(tro, sec, entry->depth, QString("%1").arg(d)); // , decimals, d); +} + + void ProfileGraphicsView::plot_temperature_text() { int i; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index d6c30dda2..c1c3c2837 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -99,6 +99,10 @@ private: void plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc); void plot_temperature_text(); void plot_single_temp_text(int sec, int mkelvin); + void plot_depth_text(); + void plot_text_samples(); + void plot_depth_sample(struct plot_data *entry, text_render_options_t *tro); + QColor get_sac_color(int sac, int avg_sac); QPen defaultPen; -- cgit v1.2.3-70-g09d2 From e62eb58ab5004fdeaee56b986d7f9b4c3f23619a Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 15:42:38 -0300 Subject: Plotting cylinder pressure text. Signed-off-by: Tomaz Canabrava --- profile.c | 49 ---------------------------------------------- qt-ui/profilegraphics.cpp | 50 ++++++++++++++++++++++++++++++++++++++++++++++- qt-ui/profilegraphics.h | 2 ++ 3 files changed, 51 insertions(+), 50 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 67f83f0a6..15fc2a920 100644 --- a/profile.c +++ b/profile.c @@ -470,55 +470,6 @@ int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct div #if USE_GTK_UI - -static void plot_pressure_value(struct graphics_context *gc, int mbar, int sec, - int xalign, int yalign) -{ - int pressure; - const char *unit; - - pressure = get_pressure_units(mbar, &unit); - text_render_options_t tro = {PRESSURE_TEXT_SIZE, PRESSURE_TEXT, xalign, yalign}; - plot_text(gc, &tro, sec, mbar, "%d %s", pressure, unit); -} - -static void plot_cylinder_pressure_text(struct graphics_context *gc, struct plot_info *pi) -{ - int i; - int mbar, cyl; - int seen_cyl[MAX_CYLINDERS] = { FALSE, }; - int last_pressure[MAX_CYLINDERS] = { 0, }; - int last_time[MAX_CYLINDERS] = { 0, }; - struct plot_data *entry; - - if (!get_cylinder_pressure_range(gc, pi)) - return; - - cyl = -1; - for (i = 0; i < pi->nr; i++) { - entry = pi->entry + i; - mbar = GET_PRESSURE(entry); - - if (!mbar) - continue; - if (cyl != entry->cylinderindex) { - cyl = entry->cylinderindex; - if (!seen_cyl[cyl]) { - plot_pressure_value(gc, mbar, entry->sec, LEFT, BOTTOM); - seen_cyl[cyl] = TRUE; - } - } - last_pressure[cyl] = mbar; - last_time[cyl] = entry->sec; - } - - for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) { - if (last_time[cyl]) { - plot_pressure_value(gc, last_pressure[cyl], last_time[cyl], CENTER, TOP); - } - } -} - static void plot_deco_text(struct graphics_context *gc, struct plot_info *pi) { if (prefs.profile_calc_ceiling) { diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 158cec286..787182389 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -248,8 +248,8 @@ void ProfileGraphicsView::plot(struct dive *dive) plot_depth_text(); + plot_cylinder_pressure_text(); #if 0 - plot_cylinder_pressure_text(gc, pi); plot_deco_text(gc, pi); #endif /* Bounding box */ @@ -292,6 +292,54 @@ void ProfileGraphicsView::plot(struct dive *dive) #endif } +void ProfileGraphicsView::plot_cylinder_pressure_text() +{ + int i; + int mbar, cyl; + int seen_cyl[MAX_CYLINDERS] = { FALSE, }; + int last_pressure[MAX_CYLINDERS] = { 0, }; + int last_time[MAX_CYLINDERS] = { 0, }; + struct plot_data *entry; + struct plot_info *pi = &gc.pi; + + if (!get_cylinder_pressure_range(&gc)) + return; + + cyl = -1; + for (i = 0; i < pi->nr; i++) { + entry = pi->entry + i; + mbar = GET_PRESSURE(entry); + + if (!mbar) + continue; + if (cyl != entry->cylinderindex) { + cyl = entry->cylinderindex; + if (!seen_cyl[cyl]) { + plot_pressure_value(mbar, entry->sec, LEFT, BOTTOM); + seen_cyl[cyl] = TRUE; + } + } + last_pressure[cyl] = mbar; + last_time[cyl] = entry->sec; + } + + for (cyl = 0; cyl < MAX_CYLINDERS; cyl++) { + if (last_time[cyl]) { + plot_pressure_value(last_pressure[cyl], last_time[cyl], CENTER, TOP); + } + } +} + +void ProfileGraphicsView::plot_pressure_value(int mbar, int sec, int xalign, int yalign) +{ + int pressure; + const char *unit; + + pressure = get_pressure_units(mbar, &unit); + static text_render_options_t tro = {PRESSURE_TEXT_SIZE, PRESSURE_TEXT, xalign, yalign}; + plot_text(&tro, sec, mbar, QString("%1 %2").arg(pressure).arg(unit)); +} + void ProfileGraphicsView::plot_depth_text() { int maxtime, maxdepth; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index c1c3c2837..39f98f65f 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -102,6 +102,8 @@ private: void plot_depth_text(); void plot_text_samples(); void plot_depth_sample(struct plot_data *entry, text_render_options_t *tro); + void plot_cylinder_pressure_text(); + void plot_pressure_value(int mbar, int sec, int xalign, int yalign); QColor get_sac_color(int sac, int avg_sac); -- cgit v1.2.3-70-g09d2 From 25d65ab97d80b80465e346f749a71e1664244301 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 15:47:39 -0300 Subject: Plotting deco text. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- profile.c | 134 +++++------------------------------------- profile.h | 2 + qt-ui/profilegraphics.cpp | 147 +++++++++++++++++++++++++++++++++++++++++++--- qt-ui/profilegraphics.h | 2 + 4 files changed, 159 insertions(+), 126 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 15fc2a920..2dc82e37b 100644 --- a/profile.c +++ b/profile.c @@ -220,6 +220,22 @@ int setup_temperature_limits(struct graphics_context *gc) return maxtemp && maxtemp >= mintemp; } +void setup_pp_limits(struct graphics_context *gc) +{ + int maxdepth; + + gc->leftx = 0; + gc->rightx = get_maxtime(&gc->pi); + + /* the maxdepth already includes extra vertical space - and if + * we use 1.5 times the corresponding pressure as maximum partial + * pressure the graph seems to look fine*/ + maxdepth = get_maxdepth(&gc->pi); + gc->topy = 1.5 * (maxdepth + 10000) / 10000.0 * SURFACE_PRESSURE / 1000; + gc->bottomy = -gc->topy / 20; +} + + #if 0 static void plot_smoothed_profile(struct graphics_context *gc, struct plot_info *pi) @@ -290,21 +306,6 @@ static void plot_depth_scale(struct graphics_context *gc, struct plot_info *pi) } } -static void setup_pp_limits(struct graphics_context *gc, struct plot_info *pi) -{ - int maxdepth; - - gc->leftx = 0; - gc->rightx = get_maxtime(pi); - - /* the maxdepth already includes extra vertical space - and if - * we use 1.5 times the corresponding pressure as maximum partial - * pressure the graph seems to look fine*/ - maxdepth = get_maxdepth(pi); - gc->topy = 1.5 * (maxdepth + 10000) / 10000.0 * SURFACE_PRESSURE / 1000; - gc->bottomy = -gc->topy / 20; -} - static void plot_pp_text(struct graphics_context *gc, struct plot_info *pi) { double pp, dpp, m; @@ -324,95 +325,6 @@ static void plot_pp_text(struct graphics_context *gc, struct plot_info *pi) } } -static void plot_pp_gas_profile(struct graphics_context *gc, struct plot_info *pi) -{ - int i; - struct plot_data *entry; - - setup_pp_limits(gc, pi); - - if (prefs.pp_graphs.pn2) { - set_source_rgba(gc, PN2); - entry = pi->entry; - move_to(gc, entry->sec, entry->pn2); - for (i = 1; i < pi->nr; i++) { - entry++; - if (entry->pn2 < prefs.pp_graphs.pn2_threshold) - line_to(gc, entry->sec, entry->pn2); - else - move_to(gc, entry->sec, entry->pn2); - } - cairo_stroke(gc->cr); - - set_source_rgba(gc, PN2_ALERT); - entry = pi->entry; - move_to(gc, entry->sec, entry->pn2); - for (i = 1; i < pi->nr; i++) { - entry++; - if (entry->pn2 >= prefs.pp_graphs.pn2_threshold) - line_to(gc, entry->sec, entry->pn2); - else - move_to(gc, entry->sec, entry->pn2); - } - cairo_stroke(gc->cr); - } - if (prefs.pp_graphs.phe) { - set_source_rgba(gc, PHE); - entry = pi->entry; - move_to(gc, entry->sec, entry->phe); - for (i = 1; i < pi->nr; i++) { - entry++; - if (entry->phe < prefs.pp_graphs.phe_threshold) - line_to(gc, entry->sec, entry->phe); - else - move_to(gc, entry->sec, entry->phe); - } - cairo_stroke(gc->cr); - - set_source_rgba(gc, PHE_ALERT); - entry = pi->entry; - move_to(gc, entry->sec, entry->phe); - for (i = 1; i < pi->nr; i++) { - entry++; - if (entry->phe >= prefs.pp_graphs.phe_threshold) - line_to(gc, entry->sec, entry->phe); - else - move_to(gc, entry->sec, entry->phe); - } - cairo_stroke(gc->cr); - } - if (prefs.pp_graphs.po2) { - set_source_rgba(gc, PO2); - entry = pi->entry; - move_to(gc, entry->sec, entry->po2); - for (i = 1; i < pi->nr; i++) { - entry++; - if (entry->po2 < prefs.pp_graphs.po2_threshold) - line_to(gc, entry->sec, entry->po2); - else - move_to(gc, entry->sec, entry->po2); - } - cairo_stroke(gc->cr); - - set_source_rgba(gc, PO2_ALERT); - entry = pi->entry; - move_to(gc, entry->sec, entry->po2); - for (i = 1; i < pi->nr; i++) { - entry++; - if (entry->po2 >= prefs.pp_graphs.po2_threshold) - line_to(gc, entry->sec, entry->po2); - else - move_to(gc, entry->sec, entry->po2); - } - cairo_stroke(gc->cr); - } -} - - - - - - /* gets both the actual start and end pressure as well as the scaling factors */ #endif /* USE_GTK_UI */ @@ -468,20 +380,6 @@ int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct div return airuse / atm * 60 / duration; } -#if USE_GTK_UI - -static void plot_deco_text(struct graphics_context *gc, struct plot_info *pi) -{ - if (prefs.profile_calc_ceiling) { - float x = gc->leftx + (gc->rightx - gc->leftx) / 2; - float y = gc->topy = 1.0; - text_render_options_t tro = {PRESSURE_TEXT_SIZE, PRESSURE_TEXT, CENTER, -0.2}; - gc->bottomy = 0.0; - plot_text(gc, &tro, x, y, "GF %.0f/%.0f", prefs.gflow * 100, prefs.gfhigh * 100); - } -} -#endif /* USE_GTK_UI */ - static void analyze_plot_info_minmax_minute(struct plot_data *entry, struct plot_data *first, struct plot_data *last, int index) { struct plot_data *p = entry; diff --git a/profile.h b/profile.h index 73c5152f9..89324530a 100644 --- a/profile.h +++ b/profile.h @@ -63,6 +63,8 @@ int get_maxdepth(struct plot_info *pi); int get_local_sac(struct plot_data *entry1, struct plot_data *entry2, struct dive *dive); +void setup_pp_limits(struct graphics_context *gc); + #define ALIGN_LEFT 1 #define ALIGN_RIGHT 2 diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 787182389..5425cae32 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -249,9 +249,9 @@ void ProfileGraphicsView::plot(struct dive *dive) plot_depth_text(); plot_cylinder_pressure_text(); -#if 0 - plot_deco_text(gc, pi); -#endif + + plot_deco_text(); + /* Bounding box */ QColor color = profile_color[TIME_GRID].at(0); QPen pen = QPen(color); @@ -269,12 +269,14 @@ void ProfileGraphicsView::plot(struct dive *dive) text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, MIDDLE}; plot_text(&computer, gc.leftx, gc.bottomy, nickname); } -#if 0 - if (PP_GRAPHS_ENABLED) { - plot_pp_gas_profile(gc, pi); - plot_pp_text(gc, pi); - } + + //if (PP_GRAPHS_ENABLED) { + plot_pp_gas_profile(); + // plot_pp_text(gc, pi); + //} + +#if 0 /* now shift the translation back by half the margin; * this way we can draw the vertical scales on both sides */ cairo_translate(gc->cr, -drawing_area->x / 2.0, 0); @@ -292,6 +294,135 @@ void ProfileGraphicsView::plot(struct dive *dive) #endif } +void ProfileGraphicsView::plot_pp_gas_profile() +{ + int i; + struct plot_data *entry; + struct plot_info *pi = &gc.pi; + + setup_pp_limits(&gc); + QColor c; + QPointF from, to; + //if (prefs.pp_graphs.pn2) { + c = profile_color[PN2].first(); + entry = pi->entry; + from = QPointF(SCALEGC(entry->sec, entry->pn2)); + for (i = 1; i < pi->nr; i++) { + entry++; + if (entry->pn2 < prefs.pp_graphs.pn2_threshold){ + to = QPointF(SCALEGC(entry->sec, entry->pn2)); + QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); + item->setPen(QPen(c)); + scene()->addItem(item); + from = to; + } + else{ + from = QPointF(SCALEGC(entry->sec, entry->pn2)); + } + } + + c = profile_color[PN2_ALERT].first(); + entry = pi->entry; + from = QPointF(SCALEGC(entry->sec, entry->pn2)); + for (i = 1; i < pi->nr; i++) { + entry++; + if (entry->pn2 >= prefs.pp_graphs.pn2_threshold){ + to = QPointF(SCALEGC(entry->sec, entry->pn2)); + QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); + item->setPen(QPen(c)); + scene()->addItem(item); + from = to; + } + else{ + from = QPointF(SCALEGC(entry->sec, entry->pn2)); + } + } + //} + + //if (prefs.pp_graphs.phe) { + c = profile_color[PHE].first(); + entry = pi->entry; + + from = QPointF(SCALEGC(entry->sec, entry->phe)); + for (i = 1; i < pi->nr; i++) { + entry++; + if (entry->phe < prefs.pp_graphs.phe_threshold){ + to = QPointF(SCALEGC(entry->sec, entry->phe)); + QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); + item->setPen(QPen(c)); + scene()->addItem(item); + from = to; + } + else{ + from = QPointF(SCALEGC(entry->sec, entry->phe)); + } + } + + c = profile_color[PHE_ALERT].first(); + entry = pi->entry; + from = QPointF(SCALEGC(entry->sec, entry->phe)); + for (i = 1; i < pi->nr; i++) { + entry++; + if (entry->phe >= prefs.pp_graphs.phe_threshold){ + to = QPointF(SCALEGC(entry->sec, entry->phe)); + QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); + item->setPen(QPen(c)); + scene()->addItem(item); + from = to; + } + else{ + from = QPointF(SCALEGC(entry->sec, entry->phe)); + } + } + //} + //if (prefs.pp_graphs.po2) { + c = profile_color[PO2].first(); + entry = pi->entry; + from = QPointF(SCALEGC(entry->sec, entry->po2)); + for (i = 1; i < pi->nr; i++) { + entry++; + if (entry->po2 < prefs.pp_graphs.po2_threshold){ + to = QPointF(SCALEGC(entry->sec, entry->po2)); + QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); + item->setPen(QPen(c)); + scene()->addItem(item); + from = to; + } + else{ + from = QPointF(SCALEGC(entry->sec, entry->po2)); + } + } + + c = profile_color[PO2_ALERT].first(); + entry = pi->entry; + from = QPointF(SCALEGC(entry->sec, entry->po2)); + for (i = 1; i < pi->nr; i++) { + entry++; + if (entry->po2 >= prefs.pp_graphs.po2_threshold){ + to = QPointF(SCALEGC(entry->sec, entry->po2)); + QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); + item->setPen(QPen(c)); + scene()->addItem(item); + from = to; + } + else{ + from = QPointF(SCALEGC(entry->sec, entry->po2)); + } + } + //} +} + +void ProfileGraphicsView::plot_deco_text() +{ + if (prefs.profile_calc_ceiling) { + float x = gc.leftx + (gc.rightx - gc.leftx) / 2; + float y = gc.topy = 1.0; + static text_render_options_t tro = {PRESSURE_TEXT_SIZE, PRESSURE_TEXT, CENTER, -0.2}; + gc.bottomy = 0.0; + plot_text(&tro, x, y, QString("GF %1/%2").arg(prefs.gflow * 100).arg(prefs.gfhigh * 100)); + } +} + void ProfileGraphicsView::plot_cylinder_pressure_text() { int i; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 39f98f65f..6ed41de1e 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -104,6 +104,8 @@ private: void plot_depth_sample(struct plot_data *entry, text_render_options_t *tro); void plot_cylinder_pressure_text(); void plot_pressure_value(int mbar, int sec, int xalign, int yalign); + void plot_deco_text(); + void plot_pp_gas_profile(); QColor get_sac_color(int sac, int avg_sac); -- cgit v1.2.3-70-g09d2 From cb8198b5243df425b6baa4d2fa4b5edb619b2855 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 18:02:52 -0300 Subject: Plot the vertical ruler on the left of the profile. Plot the numbers on the left of the profile. It seems that everythign is being plotted - But I can see that there are coordinate-errors on the code. ( the GTK one plots some curves below of the dive, but the Qt one is overlapping - probably the way that I'm using the gc information) Need to investigate a bit. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- profile.c | 25 ------------------------- qt-ui/profilegraphics.cpp | 41 +++++++++++++++++++++++++++++++++++------ qt-ui/profilegraphics.h | 2 ++ 3 files changed, 37 insertions(+), 31 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 2dc82e37b..980db4f54 100644 --- a/profile.c +++ b/profile.c @@ -281,31 +281,6 @@ static void plot_minmax_profile(struct graphics_context *gc, struct plot_info *p plot_minmax_profile_minute(gc, pi, 0); } -static void plot_depth_scale(struct graphics_context *gc, struct plot_info *pi) -{ - int i, maxdepth, marker; - static const text_render_options_t tro = {DEPTH_TEXT_SIZE, SAMPLE_DEEP, RIGHT, MIDDLE}; - - /* Depth markers: every 30 ft or 10 m*/ - maxdepth = get_maxdepth(pi); - gc->topy = 0; gc->bottomy = maxdepth; - - switch (prefs.units.length) { - case METERS: marker = 10000; break; - case FEET: marker = 9144; break; /* 30 ft */ - } - set_source_rgba(gc, DEPTH_GRID); - /* don't write depth labels all the way to the bottom as - * there may be other graphs below the depth plot (like - * partial pressure graphs) where this would look out - * of place - so we only make sure that we print the next - * marker below the actual maxdepth of the dive */ - for (i = marker; i <= pi->maxdepth + marker; i += marker) { - double d = get_depth_units(i, NULL, NULL); - plot_text(gc, &tro, -0.002, i, "%.0f", d); - } -} - static void plot_pp_text(struct graphics_context *gc, struct plot_info *pi) { double pp, dpp, m; diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 91e230e91..625dfdf10 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -276,16 +276,18 @@ void ProfileGraphicsView::plot(struct dive *dive) plot_pp_text(); //} -#if 0 + /* now shift the translation back by half the margin; * this way we can draw the vertical scales on both sides */ - cairo_translate(gc->cr, -drawing_area->x / 2.0, 0); - gc->maxx += drawing_area->x; - gc->leftx = -(drawing_area->x / drawing_area->width) / 2.0; - gc->rightx = 1.0 - gc->leftx; + //cairo_translate(gc->cr, -drawing_area->x / 2.0, 0); + + //gc->maxx += drawing_area->x; + //gc->leftx = -(drawing_area->x / drawing_area->width) / 2.0; + //gc->rightx = 1.0 - gc->leftx; - plot_depth_scale(gc, pi); + plot_depth_scale(); +#if 0 if (gc->printer) { free(pi->entry); last_pi_entry = pi->entry = NULL; @@ -294,6 +296,33 @@ void ProfileGraphicsView::plot(struct dive *dive) #endif } +void ProfileGraphicsView::plot_depth_scale() +{ + int i, maxdepth, marker; + static text_render_options_t tro = {DEPTH_TEXT_SIZE, SAMPLE_DEEP, RIGHT, MIDDLE}; + + /* Depth markers: every 30 ft or 10 m*/ + maxdepth = get_maxdepth(&gc.pi); + gc.topy = 0; gc.bottomy = maxdepth; + + switch (prefs.units.length) { + case units::METERS: marker = 10000; break; + case units::FEET: marker = 9144; break; /* 30 ft */ + } + + QColor c(profile_color[DEPTH_GRID].first()); + + /* don't write depth labels all the way to the bottom as + * there may be other graphs below the depth plot (like + * partial pressure graphs) where this would look out + * of place - so we only make sure that we print the next + * marker below the actual maxdepth of the dive */ + for (i = marker; i <= gc.pi.maxdepth + marker; i += marker) { + double d = get_depth_units(i, NULL, NULL); + plot_text(&tro, -0.002, i, QString::number(d)); + } +} + void ProfileGraphicsView::plot_pp_text() { double pp, dpp, m; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index ca0aaedf9..394a97a9f 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -107,6 +107,8 @@ private: void plot_deco_text(); void plot_pp_gas_profile(); void plot_pp_text(); + void plot_depth_scale(); + QColor get_sac_color(int sac, int avg_sac); QPen defaultPen; -- cgit v1.2.3-70-g09d2 From 9cc089f9f61a876057799e540c56178d4449fdce Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 18:45:58 -0300 Subject: Removed unused code that I'm sure it's safe to delete. Signed-off-by: Tomaz Canabrava --- profile.c | 70 ----------------------------------------------- qt-ui/profilegraphics.cpp | 2 -- qt-ui/profilegraphics.h | 28 ++----------------- 3 files changed, 3 insertions(+), 97 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index 980db4f54..ed5d01850 100644 --- a/profile.c +++ b/profile.c @@ -41,40 +41,6 @@ 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)); -} - -static void line_to(struct graphics_context *gc, double x, double y) -{ - cairo_line_to(gc->cr, SCALE(gc, x, y)); -} - -static void set_source_rgba(struct graphics_context *gc, color_indice_t c) -{ - const color_t *col = &profile_color[c]; - struct rgba rgb = col->media[gc->printer]; - double r = rgb.r; - double g = rgb.g; - double b = rgb.b; - double a = rgb.a; - - cairo_set_source_rgba(gc->cr, r, g, b, a); -} - -void init_profile_background(struct graphics_context *gc) -{ - set_source_rgba(gc, BACKGROUND); -} - -static void pattern_add_color_stop_rgba(struct graphics_context *gc, cairo_pattern_t *pat, double o, color_indice_t c) -{ - const color_t *col = &profile_color[c]; - struct rgba rgb = col->media[gc->printer]; - cairo_pattern_add_color_stop_rgba(pat, o, rgb.r, rgb.g, rgb.b, rgb.a); -} #endif /* USE_GTK_UI */ /* debugging tool - not normally used */ @@ -281,27 +247,6 @@ static void plot_minmax_profile(struct graphics_context *gc, struct plot_info *p plot_minmax_profile_minute(gc, pi, 0); } -static void plot_pp_text(struct graphics_context *gc, struct plot_info *pi) -{ - double pp, dpp, m; - int hpos; - static const text_render_options_t tro = {PP_TEXT_SIZE, PP_LINES, LEFT, MIDDLE}; - - setup_pp_limits(gc, pi); - pp = floor(pi->maxpp * 10.0) / 10.0 + 0.2; - dpp = pp > 4 ? 1.0 : 0.5; - hpos = pi->entry[pi->nr - 1].sec; - set_source_rgba(gc, PP_LINES); - for (m = 0.0; m <= pp; m += dpp) { - move_to(gc, 0, m); - line_to(gc, hpos, m); - cairo_stroke(gc->cr); - plot_text(gc, &tro, hpos + 30, m, "%.1f", m); - } -} - -/* gets both the actual start and end pressure as well as the scaling factors */ - #endif /* USE_GTK_UI */ int get_cylinder_pressure_range(struct graphics_context *gc) @@ -1140,21 +1085,6 @@ struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, s return analyze_plot_info(pi); } -#if USE_GTK_UI -static void plot_set_scale(scale_mode_t scale) -{ - switch (scale) { - default: - case SC_SCREEN: - plot_scale = SCALE_SCREEN; - break; - case SC_PRINT: - plot_scale = SCALE_PRINT; - break; - } -} -#endif - /* make sure you pass this the FIRST dc - it just walks the list */ static int nr_dcs(struct divecomputer *main) { diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 8fa8e94a6..ad6cbb172 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -335,7 +335,6 @@ void ProfileGraphicsView::plot_pp_text() hpos = gc.pi.entry[gc.pi.nr - 1].sec; QColor c = profile_color[PP_LINES].first(); - qDebug() << pp << dpp; for (m = 0.0; m <= pp; m += dpp) { QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(0, m), SCALEGC(hpos, m)); QPen pen(defaultPen); @@ -1091,7 +1090,6 @@ void ProfileGraphicsView::plot_temperature_profile() } if (last) { to = QPointF(SCALEGC(sec, mkelvin)); - //qDebug() << from << to; QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); QPen pen(defaultPen); pen.setColor(color); diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 394a97a9f..268226843 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -11,31 +11,9 @@ struct graphics_context; struct plot_info; typedef struct text_render_options text_render_options_t; -/**! - * - * Hookay, so, if you wanna extend the ToolTips that are displayed - * in the Profile Graph, there's one 'toolTip' widget already on it, - * you can just pass it to your Reimplementation of QGraphiscItem - * and do the following: - * - * EventItem::setController(ToolTipItem *c) - * { - * controller = c; - * } - * - * void EventItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) - * { - * controller->addToolTip(text, icon); - * } - * - * void EventItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) - * { - * controller->removeToolTip(text); - * } - * - * Remember to removeToolTip when you don't want it to be displayed. - * - **/ +/* To use a tooltip, simply ->setToolTip on the QGraphicsItem that you want + * or, if it's a "global" tooltip, set it on the mouseMoveEvent of the ProfileGraphicsView. + */ class ToolTipItem :public QObject, public QGraphicsPathItem { Q_OBJECT -- cgit v1.2.3-70-g09d2 From 97a044d41f67757de1e5bd0694f6502af1be4f4c Mon Sep 17 00:00:00 2001 From: Amit Chaudhuri Date: Fri, 10 May 2013 23:56:05 +0100 Subject: Tweaks to maintab Align statistics tab labels as per infotab. Amend helper function to show degree symbol for temp measurements. Change order of member initialisation list to match order of decl (ProfileGraphicsView::ProfileGraphicsView) Signed-off-by: Amit Chaudhuri Signed-off-by: Dirk Hohndel --- profile.c | 2 +- qt-gui.cpp | 6 ++++-- qt-ui/maintab.cpp | 14 ++++++++++++++ qt-ui/profilegraphics.cpp | 2 +- 4 files changed, 20 insertions(+), 4 deletions(-) (limited to 'profile.c') diff --git a/profile.c b/profile.c index ed5d01850..276641bb2 100644 --- a/profile.c +++ b/profile.c @@ -263,7 +263,7 @@ int get_cylinder_pressure_range(struct graphics_context *gc) return FALSE; while (gc->pi.endtempcoord <= SCALEY(gc, gc->pi.minpressure - (gc->topy) * 0.1)) - gc->bottomy -= gc->topy * 0.1; + gc->bottomy -= gc->topy * 0.1 * gc->maxy/abs(gc->maxy); return TRUE; } diff --git a/qt-gui.cpp b/qt-gui.cpp index d70e00379..e3a8ad5aa 100644 --- a/qt-gui.cpp +++ b/qt-gui.cpp @@ -171,10 +171,12 @@ QString get_temperature_string(temperature_t temp, bool showunit) { if (prefs.units.temperature == units::CELSIUS) { double celsius = mkelvin_to_C(temp.mkelvin); - return QString("%1%2").arg(celsius, 0, 'f', 1).arg(showunit ? _("C") : ""); + return QString("%1%2%3").arg(celsius, 0, 'f', 1).arg(showunit ? (UTF8_DEGREE): "") + .arg(showunit ? _("C") : ""); } else { double fahrenheit = mkelvin_to_F(temp.mkelvin); - return QString("%1%2").arg(fahrenheit, 0, 'f', 1).arg(showunit ? _("F") : ""); + return QString("%1%2%3").arg(fahrenheit, 0, 'f', 1).arg(showunit ? (UTF8_DEGREE): "") + .arg(showunit ? _("F") : ""); } } diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp index e1ac7c275..edacf45a4 100644 --- a/qt-ui/maintab.cpp +++ b/qt-ui/maintab.cpp @@ -29,6 +29,12 @@ MainTab::MainTab(QWidget *parent) : QTabWidget(parent), if (label) label->setAlignment(Qt::AlignHCenter); } + QList statisticsTabWidgets = ui->statisticsTab->children(); + Q_FOREACH( QObject* obj, statisticsTabWidgets ){ + QLabel* label = qobject_cast(obj); + if (label) + label->setAlignment(Qt::AlignHCenter); + } } void MainTab::clearEquipment() @@ -95,6 +101,7 @@ void MainTab::updateDiveInfo(int dive) UPDATE_TEXT(d, suit); UPDATE_TEXT(d, divemaster); UPDATE_TEXT(d, buddy); + /* infoTab */ if (d) { ui->rating->setCurrentStars(d->rating); ui->maximumDepthText->setText(get_depth_string(d->maxdepth, TRUE)); @@ -128,6 +135,13 @@ void MainTab::updateDiveInfo(int dive) ui->gasUsedText->setText(QString()); ui->airPressureText->setText(QString()); } + /* statisticsTab*/ + /* we can access the stats_selection struct but how to we ensure the relevant dives are selected + * if we don't use the gtk widget to drive this? + * Maybe call process_selected_dives? Or re-write to query our Qt list view. + */ + qDebug("max temp %u",stats_selection.max_temp); + qDebug("min temp %u",stats_selection.min_temp); } void MainTab::on_addCylinder_clicked() diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 6e699fe51..c6a2669ef 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -114,7 +114,7 @@ extern struct ev_select *ev_namelist; extern int evn_allocated; extern int evn_used; -ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent) , dive(0), toolTip(0) +ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent), toolTip(0) , dive(0) { gc.printer = false; setScene(new QGraphicsScene()); -- cgit v1.2.3-70-g09d2 From 30297ebd4bbe9d3048e7c4401b3b4b22c24305e0 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 16 May 2013 15:42:20 -0300 Subject: Correctly set the unselected dive. The selected dive was being set to zero when the program started, but zero is actually the first dive. There were workarounds on the gtk code for that probably Signed-off-by: Tomaz Canabrava --- divelist-gtk.c | 2 +- gtk-gui.c | 4 ++-- profile.c | 2 +- qt-ui/mainwindow.cpp | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) (limited to 'profile.c') diff --git a/divelist-gtk.c b/divelist-gtk.c index 0c26430c1..fc90cdf26 100644 --- a/divelist-gtk.c +++ b/divelist-gtk.c @@ -1268,7 +1268,7 @@ static void delete_selected_dives_cb(GtkWidget *menuitem, GtkTreePath *path) /* if no dives are selected at this point clear the display widgets */ if (!amount_selected) { - selected_dive = 0; + selected_dive = -1; process_selected_dives(); clear_stats_widgets(); clear_equipment_widgets(); diff --git a/gtk-gui.c b/gtk-gui.c index 389257817..d24456251 100644 --- a/gtk-gui.c +++ b/gtk-gui.c @@ -315,7 +315,7 @@ static void file_close(GtkWidget *w, gpointer data) mark_divelist_changed(FALSE); /* clear the selection and the statistics */ - selected_dive = 0; + selected_dive = -1; process_selected_dives(); clear_stats_widgets(); clear_events(); @@ -1840,7 +1840,7 @@ void MainWindow::on_actionClose_triggered() mark_divelist_changed(FALSE); /* clear the selection and the statistics */ - selected_dive = 0; + selected_dive = -1; process_selected_dives(); clear_stats_widgets(); clear_events(); diff --git a/profile.c b/profile.c index 276641bb2..41e6724bb 100644 --- a/profile.c +++ b/profile.c @@ -15,7 +15,7 @@ #include "libdivecomputer/parser.h" #include "libdivecomputer/version.h" -int selected_dive = 0; +int selected_dive = -1; char zoomed_plot = 0; char dc_number = 0; diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index 0b7f9f25d..d676549d1 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -123,7 +123,7 @@ void MainWindow::on_actionClose_triggered() mark_divelist_changed(FALSE); /* clear the selection and the statistics */ - selected_dive = 0; + selected_dive = -1; //WARNING: Port this to Qt. //process_selected_dives(); -- cgit v1.2.3-70-g09d2