From 243016633d31f8225fc4d1475463cd0477cf9505 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sat, 4 May 2013 16:12:43 -0300 Subject: Started the code for the Profile Plotting This small patch adds a new class - ProfileGraphicsView it's a QGraphicsView based class that will holds all graphics-items for the plotting. The setup is simple, just call ui->ListView->plot( dive ) ( that's already a ProfileGraphicsView and magic will happen. Since Im using a QGraphicsView , the size of the canvas doesn't matter and I'm fixing it at 0,0,100,100. when a resize is done, the resizeEvent will be called, fitting the scene's rectangle on the view. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 qt-ui/profilegraphics.cpp (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp new file mode 100644 index 000000000..59a47826f --- /dev/null +++ b/qt-ui/profilegraphics.cpp @@ -0,0 +1,26 @@ +#include "profilegraphics.h" + +#include +#include + +#include + +ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent) +{ + setScene(new QGraphicsScene()); + scene()->setSceneRect(0,0,100,100); +} + +void ProfileGraphicsView::plot(struct dive *d) +{ + qDebug() << "Start the plotting of the dive here."; +} + +void ProfileGraphicsView::resizeEvent(QResizeEvent *event) +{ + // Fits the scene's rectangle on the view. + // 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; +} -- cgit v1.2.3-70-g09d2 From a58412cb3114160c6dadb849582f2ea57ddb2125 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 --- color.h | 80 ++++++++++++++++++++++--------------------- profile.c | 86 ++--------------------------------------------- qt-ui/profilegraphics.cpp | 81 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 125 insertions(+), 122 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') 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..fab17beb7 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; + +/* 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() +{ +#define COLOR(x, y, z) QVector() << x << y << z; + 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 c74dc111675980ddd1a1b256b38a41304c792d89 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 'qt-ui/profilegraphics.cpp') 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 fab17beb7..004c78a47 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 1b1ea35fac63ef7a6909f28e92bc2b4c24c2b7f4 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 --- profile.c | 204 -------------------------------------- profile.h | 15 +++ qt-ui/profilegraphics.cpp | 242 +++++++++++++++++++++++++++++++++++++++++++--- qt-ui/profilegraphics.h | 2 + 4 files changed, 247 insertions(+), 216 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') 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 004c78a47..01ad5ab45 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,213 @@ 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 09597cd2d8729ab368f2e423dbb1ef5235745f58 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 'qt-ui/profilegraphics.cpp') 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 01ad5ab45..891cd81bf 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -309,7 +309,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)); @@ -317,17 +317,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 926224122ebc4cf6a53e3a63eb455293bcfb455d Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sat, 4 May 2013 20:18:16 -0300 Subject: Added the code to plot the actual Graph. This version already plots the dive-graph, with the gradient and all that jazz. One thing that will be easily spotted is that the size of the line is very thick - easily changed, I'm just using the default. As soon as everything is plotted correctly I'll fix the lines. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 32 ++++++++++++++++---------------- qt-ui/profilegraphics.h | 3 +++ 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 891cd81bf..761ef262b 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -337,38 +337,38 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct plot_smoothed_profile(gc, pi); plot_minmax_profile(gc, pi); } +#endif /* 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); + + QGraphicsPolygonItem *neatFill = new QGraphicsPolygonItem(); + QPolygonF p; for (i = 0; i < pi->nr; i++, entry++) - line_to(gc, entry->sec, entry->depth); + p.append( QPointF( SCALE(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); + p.append( QPointF( SCALE(gc, entry->sec, 0) )); } else if (entry->stopdepth < entry->depth) { - line_to(gc, entry->sec, entry->stopdepth); + p.append( QPointF( SCALE(gc, entry->sec, entry->stopdepth) )); } else { - line_to(gc, entry->sec, entry->depth); + p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); } } - cairo_close_path(gc->cr); - cairo_fill(gc->cr); + neatFill->setPolygon(p); + QLinearGradient pat(0.0,0.0,0.0,p.boundingRect().height()); + pat.setColorAt(1, profile_color[DEPTH_BOTTOM].first()); + pat.setColorAt(0, profile_color[DEPTH_TOP].first()); + + neatFill->setBrush(QBrush(pat)); + scene()->addItem(neatFill); +#if 0 /* 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) */ diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 633409b23..a62e55c4d 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -14,6 +14,9 @@ protected: private: void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi); + + QPen defaultPen; + QBrush defaultBrush; }; #endif -- cgit v1.2.3-70-g09d2 From 8353d571643c83514012a84cdc904353d2c4972e Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sat, 4 May 2013 16:12:43 -0300 Subject: Started the code for the Profile Plotting This small patch adds a new class - ProfileGraphicsView it's a QGraphicsView based class that will holds all graphics-items for the plotting. The setup is simple, just call ui->ListView->plot( dive ) ( that's already a ProfileGraphicsView and magic will happen. Since Im using a QGraphicsView , the size of the canvas doesn't matter and I'm fixing it at 0,0,100,100. when a resize is done, the resizeEvent will be called, fitting the scene's rectangle on the view. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- Makefile | 2 ++ qt-ui/mainwindow.cpp | 2 +- qt-ui/mainwindow.ui | 9 +++++++-- qt-ui/profilegraphics.cpp | 26 ++++++++++++++++++++++++++ qt-ui/profilegraphics.h | 17 +++++++++++++++++ 5 files changed, 53 insertions(+), 3 deletions(-) create mode 100644 qt-ui/profilegraphics.cpp create mode 100644 qt-ui/profilegraphics.h (limited to 'qt-ui/profilegraphics.cpp') diff --git a/Makefile b/Makefile index 9961f04c7..338f81a7c 100644 --- a/Makefile +++ b/Makefile @@ -39,6 +39,7 @@ HEADERS = \ qt-ui/plotareascene.h \ qt-ui/starwidget.h \ qt-ui/modeldelegates.h \ + qt-ui/profilegraphics.h \ SOURCES = \ @@ -67,6 +68,7 @@ SOURCES = \ qt-ui/plotareascene.cpp \ qt-ui/starwidget.cpp \ qt-ui/modeldelegates.cpp \ + qt-ui/profilegraphics.cpp \ $(RESFILE) diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index 3f545171e..8ac0ad871 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -67,7 +67,6 @@ void MainWindow::on_actionOpen_triggered() g_error_free(error); error = NULL; } - process_dives(FALSE, FALSE); ui->InfoWidget->reload(); @@ -94,6 +93,7 @@ void MainWindow::dive_selection_changed(const QItemSelection& newSelection, cons continue; select_dive(get_divenr(d)); } + ui->ProfileWidget->plot(get_dive(selected_dive)); } void MainWindow::on_actionSave_triggered() diff --git a/qt-ui/mainwindow.ui b/qt-ui/mainwindow.ui index fe97d98b4..7dfbae746 100644 --- a/qt-ui/mainwindow.ui +++ b/qt-ui/mainwindow.ui @@ -25,7 +25,7 @@ Qt::Horizontal - + @@ -88,7 +88,7 @@ 0 0 763 - 19 + 25 @@ -339,6 +339,11 @@ QTreeView
divelistview.h
+ + ProfileGraphicsView + QGraphicsView +
profilegraphics.h
+
diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp new file mode 100644 index 000000000..59a47826f --- /dev/null +++ b/qt-ui/profilegraphics.cpp @@ -0,0 +1,26 @@ +#include "profilegraphics.h" + +#include +#include + +#include + +ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent) +{ + setScene(new QGraphicsScene()); + scene()->setSceneRect(0,0,100,100); +} + +void ProfileGraphicsView::plot(struct dive *d) +{ + qDebug() << "Start the plotting of the dive here."; +} + +void ProfileGraphicsView::resizeEvent(QResizeEvent *event) +{ + // Fits the scene's rectangle on the view. + // 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; +} diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h new file mode 100644 index 000000000..e3380abcd --- /dev/null +++ b/qt-ui/profilegraphics.h @@ -0,0 +1,17 @@ +#ifndef PROFILEGRAPHICS_H +#define PROFILEGRAPHICS_H + +#include + +class ProfileGraphicsView : public QGraphicsView { +Q_OBJECT +public: + ProfileGraphicsView(QWidget* parent = 0); + void plot(struct dive *d); + +protected: + void resizeEvent(QResizeEvent *event); + +}; + +#endif -- 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 'qt-ui/profilegraphics.cpp') 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 'qt-ui/profilegraphics.cpp') 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 'qt-ui/profilegraphics.cpp') 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 'qt-ui/profilegraphics.cpp') 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 adcae4d913c9e151c17da6b0371b2117c7dabb93 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sat, 4 May 2013 20:18:16 -0300 Subject: Added the code to plot the actual Graph. This version already plots the dive-graph, with the gradient and all that jazz. One thing that will be easily spotted is that the size of the line is very thick - easily changed, I'm just using the default. As soon as everything is plotted correctly I'll fix the lines. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 32 ++++++++++++++++---------------- qt-ui/profilegraphics.h | 3 +++ 2 files changed, 19 insertions(+), 16 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 14ed21c9b..1f0b8efa5 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -341,38 +341,38 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct plot_smoothed_profile(gc, pi); plot_minmax_profile(gc, pi); } +#endif /* 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); + + QGraphicsPolygonItem *neatFill = new QGraphicsPolygonItem(); + QPolygonF p; for (i = 0; i < pi->nr; i++, entry++) - line_to(gc, entry->sec, entry->depth); + p.append( QPointF( SCALE(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); + p.append( QPointF( SCALE(gc, entry->sec, 0) )); } else if (entry->stopdepth < entry->depth) { - line_to(gc, entry->sec, entry->stopdepth); + p.append( QPointF( SCALE(gc, entry->sec, entry->stopdepth) )); } else { - line_to(gc, entry->sec, entry->depth); + p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); } } - cairo_close_path(gc->cr); - cairo_fill(gc->cr); + neatFill->setPolygon(p); + QLinearGradient pat(0.0,0.0,0.0,p.boundingRect().height()); + pat.setColorAt(1, profile_color[DEPTH_BOTTOM].first()); + pat.setColorAt(0, profile_color[DEPTH_TOP].first()); + + neatFill->setBrush(QBrush(pat)); + scene()->addItem(neatFill); +#if 0 /* 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) */ diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 633409b23..a62e55c4d 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -14,6 +14,9 @@ protected: private: void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi); + + QPen defaultPen; + QBrush defaultBrush; }; #endif -- cgit v1.2.3-70-g09d2 From c72609046adcaff2ca5af475113e583cbb943a04 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sun, 5 May 2013 13:42:33 -0300 Subject: Finished the port of the plot_profile code. There are a few regressions, mostly because the text is not being plotted yet and the background of some of the curves are not being applied. This is because QGrapdien is based on the coordinates of the items that I wanna paint, but I'v setted a QGradient that's global and doesn't take this into consideration. all curves are being plotted. in Small resolutions they plot bad. but it's just a matter of redrawing in the correct resolution. the Line widths are being hardcoded now, on the cairo version they weren't, this will need a bit of porting too. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 110 ++++++++++++++++++++++++++-------------------- 1 file changed, 62 insertions(+), 48 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 761ef262b..c5421659c 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -102,7 +102,7 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent { setScene(new QGraphicsScene()); setBackgroundBrush(QColor("#F3F3E6")); - scene()->setSceneRect(0,0,100,100); + scene()->setSceneRect(0,0,1000,1000); fill_profile_color(); } @@ -344,8 +344,11 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct entry = pi->entry; - QGraphicsPolygonItem *neatFill = new QGraphicsPolygonItem(); + QPolygonF p; + QLinearGradient pat(0.0,0.0,0.0,scene()->height()); + QGraphicsPolygonItem *neatFill = 0; + for (i = 0; i < pi->nr; i++, entry++) p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); @@ -353,86 +356,98 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct for (i = 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( SCALE(gc, entry->sec, 0) )); } else if (entry->stopdepth < entry->depth) { p.append( QPointF( SCALE(gc, entry->sec, entry->stopdepth) )); } else { p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); } } - neatFill->setPolygon(p); - QLinearGradient pat(0.0,0.0,0.0,p.boundingRect().height()); + +; pat.setColorAt(1, profile_color[DEPTH_BOTTOM].first()); pat.setColorAt(0, profile_color[DEPTH_TOP].first()); + neatFill = new QGraphicsPolygonItem(); + neatFill->setPolygon(p); neatFill->setBrush(QBrush(pat)); + neatFill->setPen(QPen()); scene()->addItem(neatFill); -#if 0 /* 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); + // TODO: port the prefs.profile_red_ceiling to QSettings + //if (prefs.profile_red_ceiling) { + p.clear(); + pat.setColorAt(0, profile_color[CEILING_SHALLOW].first()); + pat.setColorAt(1, profile_color[CEILING_DEEP].first()); + 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); + p.append( QPointF( SCALE(gc, entry->sec, entry->stopdepth) )); } else { - line_to(gc, entry->sec, entry->depth); + p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); } } else { - line_to(gc, entry->sec, 0); + p.append( QPointF( SCALE(gc, entry->sec, 0) )); } } - cairo_close_path(gc->cr); - cairo_fill(gc->cr); - } + + neatFill = new QGraphicsPolygonItem(); + neatFill->setBrush(QBrush(pat)); + neatFill->setPolygon(p); + neatFill->setPen(QPen()); + scene()->addItem(neatFill); + //} + /* 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); + // TODO: Port the profile_calc_ceiling to QSettings + // if (prefs.profile_calc_ceiling) { + pat.setColorAt(0, profile_color[CALC_CEILING_SHALLOW].first()); + pat.setColorAt(1, profile_color[CALC_CEILING_DEEP].first()); + entry = pi->entry; - move_to(gc, 0, 0); + p.clear(); + p.append( QPointF(0,0)); for (i = 0; i < pi->nr; i++, entry++) { if (entry->ceiling) - line_to(gc, entry->sec, entry->ceiling); + p.append( QPointF( SCALE(gc, entry->sec, entry->ceiling) )); else - line_to(gc, entry->sec, 0); + p.append( QPointF( SCALE(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); - } + p.append( QPointF( SCALE(gc, (entry-1)->sec, 0) )); + neatFill = new QGraphicsPolygonItem(); + neatFill->setPolygon(p); + neatFill->setPen(QPen()); + scene()->addItem(neatFill); + //} + /* 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); + pat.setColorAt(0, profile_color[CEILING_SHALLOW].first()); + pat.setColorAt(1, profile_color[CEILING_DEEP].first()); + entry = pi->entry; - move_to(gc, 0, 0); + p.clear(); + p.append( QPointF(0,0)); for (i = 0; i < pi->nr; i++, entry++) - line_to(gc, entry->sec, entry->depth); + p.append( QPointF( SCALE(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); + p.append( QPointF( SCALE(gc, entry->sec, entry->stopdepth) )); } else { - line_to(gc, entry->sec, entry->depth); + p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); } } - cairo_close_path(gc->cr); - cairo_fill(gc->cr); + + neatFill = new QGraphicsPolygonItem(); + neatFill->setPolygon(p); + neatFill->setPen(QPen()); + neatFill->setBrush(QBrush(pat)); + scene()->addItem(neatFill); /* Now do it again for the velocity colors */ entry = pi->entry; @@ -442,13 +457,12 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct /* 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); + 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 )); + scene()->addItem(colorLine); } -#endif } -- cgit v1.2.3-70-g09d2 From be0f2e0e8de184380047f71f88cbdf0c23e94bd9 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sun, 5 May 2013 13:51:02 -0300 Subject: Enabled some Render Hints for Antialiasing Enabled some Render Hints for Antialiasing and smooth transformations. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 053e3db0f..d5bf177f0 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -105,6 +105,11 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent setScene(new QGraphicsScene()); setBackgroundBrush(QColor("#F3F3E6")); scene()->setSceneRect(0,0,1000,1000); + + setRenderHint(QPainter::Antialiasing); + setRenderHint(QPainter::HighQualityAntialiasing); + setRenderHint(QPainter::SmoothPixmapTransform); + fill_profile_color(); } -- cgit v1.2.3-70-g09d2 From 8e35868b9b09f6417809678bd22cc315a696b706 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Sun, 5 May 2013 19:30:54 -0300 Subject: Fixed some bad drawings Removed the lines of the graphs that doesn't supposed to have lines. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index d5bf177f0..89c3a74fc 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -328,7 +328,6 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct scene()->addItem(line); } - gc->leftx = 0; gc->rightx = maxtime; color = profile_color[MEAN_DEPTH].at(0); @@ -359,6 +358,7 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct 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) )); @@ -373,26 +373,28 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); } } - pat.setColorAt(1, profile_color[DEPTH_BOTTOM].first()); pat.setColorAt(0, profile_color[DEPTH_TOP].first()); neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); neatFill->setBrush(QBrush(pat)); - neatFill->setPen(QPen()); + neatFill->setPen(QPen(QBrush(),0)); scene()->addItem(neatFill); + /* 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) */ // TODO: port the prefs.profile_red_ceiling to QSettings + //if (prefs.profile_red_ceiling) { p.clear(); 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++) { if (entry->ndl == 0 && entry->stopdepth) { if (entry->ndl == 0 && entry->stopdepth < entry->depth) { @@ -408,19 +410,23 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct neatFill = new QGraphicsPolygonItem(); neatFill->setBrush(QBrush(pat)); neatFill->setPolygon(p); - neatFill->setPen(QPen()); + neatFill->setPen(QPen(QBrush(),0)); scene()->addItem(neatFill); //} /* finally, plot the calculated ceiling over all this */ // 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()); entry = pi->entry; p.clear(); - p.append( QPointF(0,0)); + p.append( QPointF(SCALE(gc, 0, 0) )); for (i = 0; i < pi->nr; i++, entry++) { if (entry->ceiling) p.append( QPointF( SCALE(gc, entry->sec, entry->ceiling) )); @@ -430,17 +436,17 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct p.append( QPointF( SCALE(gc, (entry-1)->sec, 0) )); neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); - neatFill->setPen(QPen()); + neatFill->setPen(QPen(QBrush(),0)); + neatFill->setBrush(pat); scene()->addItem(neatFill); //} - /* next show where we have been bad and crossed the dc's ceiling */ pat.setColorAt(0, profile_color[CEILING_SHALLOW].first()); pat.setColorAt(1, profile_color[CEILING_DEEP].first()); entry = pi->entry; p.clear(); - p.append( QPointF(0,0)); + p.append( QPointF(SCALE(gc, 0, 0) )); for (i = 0; i < pi->nr; i++, entry++) p.append( QPointF( SCALE(gc, entry->sec, entry->depth) )); @@ -454,7 +460,7 @@ void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); - neatFill->setPen(QPen()); + neatFill->setPen(QPen(QBrush(),0)); neatFill->setBrush(QBrush(pat)); scene()->addItem(neatFill); -- 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 'qt-ui/profilegraphics.cpp') 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 55f31dc0114a2719c867a8c1210c704f657b646f Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Mon, 6 May 2013 16:29:26 -0300 Subject: Make the text ignores transformations on the scene Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index b52368b11..d4c918ac6 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -493,6 +493,7 @@ void ProfileGraphicsView::plot_text(struct graphics_context *gc, text_render_opt 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); qDebug() << item->pos(); } -- 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 'qt-ui/profilegraphics.cpp') 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 1a8239a240fe14e983da6d9a6048e2fb154ee053 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Mon, 6 May 2013 19:42:39 -0300 Subject: Finish the plotting of the events Beautification of the triangles done, Tooltips are also displaying Some rework on the code - don't know if dirk will accept, I'v changed an if-else-if-else by a ternary operator, since it improves legibility a little bit. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 33 ++++++++++++++++++++------------- 1 file changed, 20 insertions(+), 13 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index b3163add4..9f1f115cb 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -13,6 +13,9 @@ #include "../dive.h" #include "../profile.h" +#include +#include + #define SAC_COLORS_START_IDX SAC_1 #define SAC_COLORS 9 #define VELOCITY_COLORS_START_IDX VELO_STABLE @@ -121,6 +124,10 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent setRenderHint(QPainter::HighQualityAntialiasing); setRenderHint(QPainter::SmoothPixmapTransform); + defaultPen.setJoinStyle(Qt::RoundJoin); + defaultPen.setCapStyle(Qt::RoundCap); + defaultPen.setWidth(2); + fill_profile_color(); } @@ -314,15 +321,18 @@ void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plo int x = SCALEX(gc, ev->time.seconds); int y = SCALEY(gc, depth); + QPen pen = defaultPen; + pen.setBrush(QBrush(profile_color[ALERT_BG].first())); + 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->setPen(pen); triangle->setFlag(QGraphicsItem::ItemIgnoresTransformations); triangle->setPos(x, y); QGraphicsLineItem *line = new QGraphicsLineItem(0,5,0,10, triangle); - line->setPen(QPen(QBrush(Qt::black), 2)); + line->setPen(defaultPen); QGraphicsEllipseItem *ball = new QGraphicsEllipseItem(-1, 12, 2,2, triangle); ball->setBrush(QBrush(Qt::black)); @@ -335,14 +345,11 @@ void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plo 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); - } + + name += (he) ? QString("%1/%2").arg(o2, he) + : (o2 == 21) ? name += tr(":air") + : 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 { @@ -351,11 +358,12 @@ void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plo } 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") : ""; + name += ev->flags == SAMPLE_FLAGS_BEGIN ? tr("Starts with space!"," begin") : + ev->flags == SAMPLE_FLAGS_END ? tr("Starts with space!", " end") : ""; } //attach_tooltip(x-6, y, 12, 12, buffer, ev); + triangle->setToolTip(name); } void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct plot_info *pi) @@ -595,7 +603,6 @@ void ProfileGraphicsView::plot_text(struct graphics_context *gc, text_render_opt item->setPen( QPen(profile_color[BACKGROUND].first())); item->setFlag(QGraphicsItem::ItemIgnoresTransformations); scene()->addItem(item); - qDebug() << item->pos(); } -- cgit v1.2.3-70-g09d2 From c928b9cb94b7e43983aaee46c82074466a6179a6 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Tue, 7 May 2013 15:44:54 -0300 Subject: Added the first overlay of the tooltips, with some test data. The tooltips now can: 1 - be moved around the canvas 2 - dynamically expand / retreat when a new tooltip is added. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 134 ++++++++++++++++++++++++++++++++++++++++++++-- qt-ui/profilegraphics.h | 44 +++++++++++++++ 2 files changed, 175 insertions(+), 3 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 9f1f115cb..eede292d7 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -7,6 +7,9 @@ #include #include #include +#include +#include +#include #include "../color.h" #include "../display.h" @@ -146,13 +149,21 @@ 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; + QSettings s; + s.beginGroup("ProfileMap"); + QPointF toolTipPos = s.value("tooltip_position", QPointF(0,0)).toPointF(); + s.endGroup(); + + toolTip = new ToolTipItem(); + toolTip->setPos(toolTipPos); + + scene()->addItem(toolTip); + struct plot_info *pi; struct divecomputer *dc = &dive->dc; @@ -363,7 +374,8 @@ void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plo } //attach_tooltip(x-6, y, 12, 12, buffer, ev); - triangle->setToolTip(name); + //triangle->setToolTip(name); + toolTip->addToolTip(name); } void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct plot_info *pi) @@ -605,6 +617,16 @@ void ProfileGraphicsView::plot_text(struct graphics_context *gc, text_render_opt scene()->addItem(item); } +void ProfileGraphicsView::addToolTip(const QString& text, const QIcon& icon) +{ + toolTip->addToolTip(text, icon); +} + +void ProfileGraphicsView::removeToolTip(const QString& text) +{ + toolTip->removeToolTip(text); +} + void ProfileGraphicsView::resizeEvent(QResizeEvent *event) { @@ -614,3 +636,109 @@ void ProfileGraphicsView::resizeEvent(QResizeEvent *event) QRectF r = scene()->sceneRect(); fitInView ( r.x() - 50, r.y() -50, r.width() + 100, r.height() + 100); // do a little bit of spacing; } + +void ToolTipItem::addToolTip(const QString& toolTip, const QIcon& icon) +{ + qDebug() << "Tooltip Adicionado" << toolTip; + + QGraphicsPixmapItem *iconItem = 0; + if (!icon.isNull()) { + iconItem = new QGraphicsPixmapItem(icon.pixmap(ICON_SMALL,ICON_SMALL), this); + iconItem->setPos( 4, toolTips.keys().size() * ICON_SMALL + 4); + } + + QGraphicsSimpleTextItem *textItem = new QGraphicsSimpleTextItem(toolTip, this); + textItem->setPos( 4 + ICON_SMALL + 4, toolTips.keys().size() * ICON_SMALL + 4); + textItem->setPen(QPen(Qt::white, 1)); + textItem->setBrush(QBrush(Qt::white)); + textItem->setFlag(ItemIgnoresTransformations); + + toolTips[toolTip] = qMakePair(iconItem, textItem); + expand(); +} + +void ToolTipItem::removeToolTip(const QString& toolTip) +{ + ToolTip toBeRemoved = toolTips[toolTip]; + delete toBeRemoved.first; + delete toBeRemoved.second; + expand(); +} + +void ToolTipItem::clear() +{ + Q_FOREACH(ToolTip t, toolTips) { + delete t.first; + delete t.second; + } + toolTips.clear(); + expand(); +} + +void ToolTipItem::setRect(const QRectF& r) +{ + + // qDeleteAll(childItems()); + if (background) { + childItems().removeAt(childItems().indexOf(background)); + delete background; + } + + rectangle = r; + setBrush(QBrush(Qt::white)); + setPen(QPen(Qt::black, 0.5)); + + QPainterPath border; + border.addRoundedRect(-2, -2, rectangle.width() + 4, rectangle.height()+ 4, 3, 3); + border.addRoundedRect( 0, 0, rectangle.width(), rectangle.height(), 3, 3); + setPath(border); + + QGraphicsRectItem *b = new QGraphicsRectItem(-1, -1, rectangle.width()+1, rectangle.height()+1, this); + b->setFlag(ItemStacksBehindParent); + QColor c = QColor(Qt::black); + c.setAlpha(155); + b->setBrush(c); + background = b; + +} + + +void ToolTipItem::collapse() +{ + QRectF newRect = childrenBoundingRect(); + QPropertyAnimation *animation = new QPropertyAnimation(this, "rect"); + animation->setDuration(100); + animation->setStartValue(boundingRect()); + animation->setEndValue(QRect(0, 0, ICON_SMALL, ICON_SMALL )); + animation->start(QAbstractAnimation::DeleteWhenStopped); +} + +void ToolTipItem::expand() +{ + QRectF newRect = childrenBoundingRect(); + newRect = QRect(0, 0, newRect.width() + 8, newRect.height() + 8); + if (newRect != boundingRect()) { + QRectF newRect = childrenBoundingRect(); + QPropertyAnimation *animation = new QPropertyAnimation(this, "rect"); + animation->setDuration(100); + animation->setStartValue(boundingRect()); + animation->setEndValue(newRect); + animation->start(QAbstractAnimation::DeleteWhenStopped); + } +} + +ToolTipItem::ToolTipItem(QGraphicsItem* parent): QGraphicsPathItem(parent), background(0) +{ + setRect(QRectF(0,0,ICON_SMALL, ICON_SMALL)); + setFlag(QGraphicsItem::ItemIgnoresTransformations); + setFlag(QGraphicsItem::ItemIsMovable); +} + +void ToolTipStatusHandler::mousePressEvent(QGraphicsSceneMouseEvent* event) +{ + QGraphicsItem::mousePressEvent(event); +} + +ToolTipStatusHandler::ToolTipStatusHandler(QObject* parent): QObject(parent), QGraphicsEllipseItem() +{ +} diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 928c8ea89..9ad04674b 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -2,17 +2,59 @@ #define PROFILEGRAPHICS_H #include +#include +#include struct text_render_options; struct graphics_context; struct plot_info; typedef struct text_render_options text_render_options_t; + +class ToolTipItem; +class ToolTipStatusHandler; + +class ToolTipStatusHandler :public QObject, public QGraphicsEllipseItem { +public: + explicit ToolTipStatusHandler(QObject* parent = 0); +protected: + void mousePressEvent(QGraphicsSceneMouseEvent* event); +}; + +class ToolTipItem :public QObject, public QGraphicsPathItem { + Q_OBJECT + Q_PROPERTY(QRectF rect READ boundingRect WRITE setRect) + +public: + enum Status {COLLAPSED, EXPANDED}; + enum {ICON_SMALL = 16, ICON_MEDIUM = 24, ICON_BIG = 32}; + + explicit ToolTipItem(QGraphicsItem* parent = 0); + + void collapse(); + void expand(); + void clear(); + void addToolTip(const QString& toolTip, const QIcon& icon = QIcon()); + void removeToolTip(const QString& toolTip); + +public Q_SLOTS: + void setRect(const QRectF& rect); + +private: + typedef QPair ToolTip; + enum Status status; + QMap toolTips; + QGraphicsRectItem *background; + QRectF rectangle; +}; + class ProfileGraphicsView : public QGraphicsView { Q_OBJECT public: ProfileGraphicsView(QWidget* parent = 0); void plot(struct dive *d); + void addToolTip(const QString& text, const QIcon& icon = QIcon()); + void removeToolTip(const QString& text); protected: void resizeEvent(QResizeEvent *event); @@ -25,6 +67,8 @@ private: QPen defaultPen; QBrush defaultBrush; + ToolTipItem *toolTip; }; + #endif -- cgit v1.2.3-70-g09d2 From d590cb951988976f21bacc39d5ea1581c65d3b20 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Tue, 7 May 2013 16:09:51 -0700 Subject: Adds real support for ToolTips. This patch changes the Event drawing so it can display tooltips. It is now the responsibility of the item to show / hide a tooltip. A bit of code-refactoring got on here too because I was using only QGraphicsItem calls and I wanted to use a hover in / hover out event to show / hide the tooltip. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 181 +++++++++++++++++++++++++++++++++++----------- qt-ui/profilegraphics.h | 39 ++++++---- 2 files changed, 160 insertions(+), 60 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index eede292d7..81d343976 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -10,6 +10,7 @@ #include #include #include +#include #include "../color.h" #include "../display.h" @@ -323,32 +324,13 @@ void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plo } /* 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); - QPen pen = defaultPen; - pen.setBrush(QBrush(profile_color[ALERT_BG].first())); - - QGraphicsPolygonItem *triangle = new QGraphicsPolygonItem(); - triangle->setPolygon(poly); - triangle->setBrush(QBrush(profile_color[ALERT_BG].first())); - triangle->setPen(pen); - triangle->setFlag(QGraphicsItem::ItemIgnoresTransformations); - triangle->setPos(x, y); - - QGraphicsLineItem *line = new QGraphicsLineItem(0,5,0,10, triangle); - line->setPen(defaultPen); - - QGraphicsEllipseItem *ball = new QGraphicsEllipseItem(-1, 12, 2,2, triangle); - ball->setBrush(QBrush(Qt::black)); - - scene()->addItem(triangle); + EventItem *item = new EventItem(); + item->setPos(x, y); + scene()->addItem(item); /* we display the event on screen - so translate */ QString name = tr(ev->name); @@ -373,9 +355,8 @@ void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plo ev->flags == SAMPLE_FLAGS_END ? tr("Starts with space!", " end") : ""; } - //attach_tooltip(x-6, y, 12, 12, buffer, ev); - //triangle->setToolTip(name); - toolTip->addToolTip(name); + item->setToolTipController(toolTip); + item->addToolTip(name); } void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct plot_info *pi) @@ -639,16 +620,16 @@ void ProfileGraphicsView::resizeEvent(QResizeEvent *event) void ToolTipItem::addToolTip(const QString& toolTip, const QIcon& icon) { - qDebug() << "Tooltip Adicionado" << toolTip; - QGraphicsPixmapItem *iconItem = 0; + double yValue = title->boundingRect().height() + SPACING + toolTips.keys().size() * ICON_SMALL + SPACING; + if (!icon.isNull()) { iconItem = new QGraphicsPixmapItem(icon.pixmap(ICON_SMALL,ICON_SMALL), this); - iconItem->setPos( 4, toolTips.keys().size() * ICON_SMALL + 4); + iconItem->setPos( SPACING, yValue); } QGraphicsSimpleTextItem *textItem = new QGraphicsSimpleTextItem(toolTip, this); - textItem->setPos( 4 + ICON_SMALL + 4, toolTips.keys().size() * ICON_SMALL + 4); + textItem->setPos( SPACING + ICON_SMALL + SPACING, yValue); textItem->setPen(QPen(Qt::white, 1)); textItem->setBrush(QBrush(Qt::white)); textItem->setFlag(ItemIgnoresTransformations); @@ -662,6 +643,22 @@ void ToolTipItem::removeToolTip(const QString& toolTip) ToolTip toBeRemoved = toolTips[toolTip]; delete toBeRemoved.first; delete toBeRemoved.second; + toolTips.remove(toolTip); + + int toolTipIndex = 0; + + // We removed a toolTip, let's move the others to the correct location + Q_FOREACH(ToolTip t, toolTips){ + double yValue = title->boundingRect().height() + SPACING + toolTipIndex * ICON_SMALL + SPACING; + + // Icons can be null. + if (t.first) + t.first->setPos(SPACING, yValue); + + t.second->setPos(SPACING + ICON_SMALL + SPACING, yValue); + toolTipIndex++; + } + expand(); } @@ -700,6 +697,7 @@ void ToolTipItem::setRect(const QRectF& r) b->setBrush(c); background = b; + updateTitlePosition(); } @@ -715,30 +713,125 @@ void ToolTipItem::collapse() void ToolTipItem::expand() { - QRectF newRect = childrenBoundingRect(); - newRect = QRect(0, 0, newRect.width() + 8, newRect.height() + 8); - if (newRect != boundingRect()) { - QRectF newRect = childrenBoundingRect(); - QPropertyAnimation *animation = new QPropertyAnimation(this, "rect"); - animation->setDuration(100); - animation->setStartValue(boundingRect()); - animation->setEndValue(newRect); - animation->start(QAbstractAnimation::DeleteWhenStopped); + QRectF currentRect = rectangle; + QRectF nextRectangle; + + double width = 0; + Q_FOREACH(ToolTip t, toolTips) { + if (t.second->boundingRect().width() > width) + width = t.second->boundingRect().width(); } + + double height = toolTips.count() * 18 + title->boundingRect().height() + SPACING; + /* Left padding, Icon Size, space, right padding */ + width += SPACING + ICON_SMALL + SPACING + SPACING; + + if (width < title->boundingRect().width() + SPACING*2) + width = title->boundingRect().width() + SPACING*2; + + if( height < ICON_SMALL) + height = ICON_SMALL; + + nextRectangle.setWidth(width); + nextRectangle.setHeight(height); + + QPropertyAnimation *animation = new QPropertyAnimation(this, "rect"); + animation->setDuration(100); + animation->setStartValue(rectangle); + animation->setEndValue(nextRectangle); + animation->start(QAbstractAnimation::DeleteWhenStopped); + } ToolTipItem::ToolTipItem(QGraphicsItem* parent): QGraphicsPathItem(parent), background(0) { - setRect(QRectF(0,0,ICON_SMALL, ICON_SMALL)); - setFlag(QGraphicsItem::ItemIgnoresTransformations); - setFlag(QGraphicsItem::ItemIsMovable); + title = new QGraphicsSimpleTextItem(tr("Information"), this); + separator = new QGraphicsLineItem(this); + + setFlag(ItemIgnoresTransformations); + setFlag(ItemIsMovable); + + updateTitlePosition(); + setZValue(99); +} + +void ToolTipItem::updateTitlePosition() +{ + 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 ); + setRect(newRect); + } + + title->setPos(boundingRect().width()/2 -title->boundingRect().width()/2, 0); + title->setFlag(ItemIgnoresTransformations); + title->setPen(QPen(Qt::white, 1)); + title->setBrush(Qt::white); + + if (toolTips.size() > 0){ + double x1 = 0; + double y1 = title->pos().y() + SPACING/2 + title->boundingRect().height(); + double x2 = boundingRect().width() - 4; + double y2 = y1; + + separator->setLine(x1, y1, x2, y2); + separator->setFlag(ItemIgnoresTransformations); + separator->setPen(QPen(Qt::white)); + }else{ + separator->setLine(QLineF()); + } +} + +EventItem::EventItem(QGraphicsItem* parent): QGraphicsPolygonItem(parent) +{ + setFlag(ItemIgnoresTransformations); + setFlag(ItemIsFocusable); + setAcceptHoverEvents(true); + + 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)); + + QPen defaultPen ; + defaultPen.setJoinStyle(Qt::RoundJoin); + defaultPen.setCapStyle(Qt::RoundCap); + defaultPen.setWidth(2); + + QPen pen = defaultPen; + pen.setBrush(QBrush(profile_color[ALERT_BG].first())); + + setPolygon(poly); + setBrush(QBrush(profile_color[ALERT_BG].first())); + setPen(pen); + + QGraphicsLineItem *line = new QGraphicsLineItem(0,5,0,10, this); + line->setPen(QPen(Qt::black, 2)); + + QGraphicsEllipseItem *ball = new QGraphicsEllipseItem(-1, 12, 2,2, this); + ball->setBrush(QBrush(Qt::black)); + +} + +void EventItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) +{ + controller->addToolTip(text, icon); +} + +void EventItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) +{ + controller->removeToolTip(text); } -void ToolTipStatusHandler::mousePressEvent(QGraphicsSceneMouseEvent* event) +void EventItem::addToolTip(const QString& t, const QIcon& i) { - QGraphicsItem::mousePressEvent(event); + text = t; + icon = i; } -ToolTipStatusHandler::ToolTipStatusHandler(QObject* parent): QObject(parent), QGraphicsEllipseItem() +void EventItem::setToolTipController(ToolTipItem* c) { + controller = c; } diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 9ad04674b..776b3141e 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -10,26 +10,16 @@ struct graphics_context; struct plot_info; typedef struct text_render_options text_render_options_t; - -class ToolTipItem; -class ToolTipStatusHandler; - -class ToolTipStatusHandler :public QObject, public QGraphicsEllipseItem { -public: - explicit ToolTipStatusHandler(QObject* parent = 0); -protected: - void mousePressEvent(QGraphicsSceneMouseEvent* event); -}; - class ToolTipItem :public QObject, public QGraphicsPathItem { Q_OBJECT + void updateTitlePosition(); Q_PROPERTY(QRectF rect READ boundingRect WRITE setRect) public: - enum Status {COLLAPSED, EXPANDED}; - enum {ICON_SMALL = 16, ICON_MEDIUM = 24, ICON_BIG = 32}; + enum Status{COLLAPSED, EXPANDED}; + enum {ICON_SMALL = 16, ICON_MEDIUM = 24, ICON_BIG = 32, SPACING=4}; - explicit ToolTipItem(QGraphicsItem* parent = 0); + explicit ToolTipItem(QGraphicsItem* parent = 0); void collapse(); void expand(); @@ -42,12 +32,30 @@ public Q_SLOTS: private: typedef QPair ToolTip; - enum Status status; QMap toolTips; QGraphicsRectItem *background; + QGraphicsLineItem *separator; + QGraphicsSimpleTextItem *title; + QRectF rectangle; }; +class EventItem : public QGraphicsPolygonItem{ +public: + explicit EventItem(QGraphicsItem* parent = 0); + void addToolTip(const QString& text,const QIcon& icon = QIcon()); + void setToolTipController(ToolTipItem *controller); + +protected: + void hoverEnterEvent(QGraphicsSceneHoverEvent* event); + void hoverLeaveEvent(QGraphicsSceneHoverEvent* event); + +private: + ToolTipItem *controller; + QString text; + QIcon icon; +}; + class ProfileGraphicsView : public QGraphicsView { Q_OBJECT public: @@ -70,5 +78,4 @@ private: ToolTipItem *toolTip; }; - #endif -- cgit v1.2.3-70-g09d2 From df01a5d35f620d2f33e4283863b729ed9554e23f Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Tue, 7 May 2013 16:12:01 -0700 Subject: Added a bit of documentation on how to use the ToolTips & removed 2 bad-api methods Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 11 ----------- qt-ui/profilegraphics.h | 36 +++++++++++++++++++++++++++++++----- 2 files changed, 31 insertions(+), 16 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 81d343976..a9a7c93f8 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -598,17 +598,6 @@ void ProfileGraphicsView::plot_text(struct graphics_context *gc, text_render_opt scene()->addItem(item); } -void ProfileGraphicsView::addToolTip(const QString& text, const QIcon& icon) -{ - toolTip->addToolTip(text, icon); -} - -void ProfileGraphicsView::removeToolTip(const QString& text) -{ - toolTip->removeToolTip(text); -} - - 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 776b3141e..c1668692d 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -10,7 +10,33 @@ struct graphics_context; struct plot_info; typedef struct text_render_options text_render_options_t; -class ToolTipItem :public QObject, public QGraphicsPathItem { +/**! + * + * 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. + * + **/ +class ToolTipItem :public QObject, public QGraphicsPathItem +{ Q_OBJECT void updateTitlePosition(); Q_PROPERTY(QRectF rect READ boundingRect WRITE setRect) @@ -40,7 +66,8 @@ private: QRectF rectangle; }; -class EventItem : public QGraphicsPolygonItem{ +class EventItem : public QGraphicsPolygonItem +{ public: explicit EventItem(QGraphicsItem* parent = 0); void addToolTip(const QString& text,const QIcon& icon = QIcon()); @@ -56,13 +83,12 @@ private: QIcon icon; }; -class ProfileGraphicsView : public QGraphicsView { +class ProfileGraphicsView : public QGraphicsView +{ Q_OBJECT public: ProfileGraphicsView(QWidget* parent = 0); void plot(struct dive *d); - void addToolTip(const QString& text, const QIcon& icon = QIcon()); - void removeToolTip(const QString& text); protected: void resizeEvent(QResizeEvent *event); -- cgit v1.2.3-70-g09d2 From 76e1436f684117766c5132c4ab69bf7ae50cd2ed Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Tue, 7 May 2013 23:00:05 -0300 Subject: Better design for the ToolTip Handler. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 28 +++++++++++++++++----------- qt-ui/profilegraphics.h | 2 +- 2 files changed, 18 insertions(+), 12 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index a9a7c93f8..e2fed39c5 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -665,25 +665,30 @@ void ToolTipItem::setRect(const QRectF& r) { // qDeleteAll(childItems()); - if (background) { - childItems().removeAt(childItems().indexOf(background)); - delete background; - } + delete background; rectangle = r; setBrush(QBrush(Qt::white)); setPen(QPen(Qt::black, 0.5)); + // Creates a 2pixels border QPainterPath border; - border.addRoundedRect(-2, -2, rectangle.width() + 4, rectangle.height()+ 4, 3, 3); - border.addRoundedRect( 0, 0, rectangle.width(), rectangle.height(), 3, 3); + border.addRoundedRect(-4, -4, rectangle.width() + 8, rectangle.height() + 10, 3, 3); + border.addRoundedRect(-1, -1, rectangle.width() + 3, rectangle.height() + 4, 3, 3); setPath(border); - QGraphicsRectItem *b = new QGraphicsRectItem(-1, -1, rectangle.width()+1, rectangle.height()+1, this); - b->setFlag(ItemStacksBehindParent); + QPainterPath bg; + bg.addRoundedRect( -1, -1, rectangle.width() + 3, rectangle.height() + 4, 3, 3); + QColor c = QColor(Qt::black); c.setAlpha(155); + + QGraphicsPathItem *b = new QGraphicsPathItem(bg, this); + b->setFlag(ItemStacksBehindParent); + b->setFlags(ItemIgnoresTransformations); b->setBrush(c); + b->setPen(QPen(QBrush(Qt::transparent), 0)); + b->setZValue(-10); background = b; updateTitlePosition(); @@ -753,7 +758,7 @@ void ToolTipItem::updateTitlePosition() setRect(newRect); } - title->setPos(boundingRect().width()/2 -title->boundingRect().width()/2, 0); + title->setPos(boundingRect().width()/2 - title->boundingRect().width()/2 -1, 0); title->setFlag(ItemIgnoresTransformations); title->setPen(QPen(Qt::white, 1)); title->setBrush(Qt::white); @@ -761,14 +766,15 @@ void ToolTipItem::updateTitlePosition() if (toolTips.size() > 0){ double x1 = 0; double y1 = title->pos().y() + SPACING/2 + title->boundingRect().height(); - double x2 = boundingRect().width() - 4; + double x2 = boundingRect().width() - 10; double y2 = y1; separator->setLine(x1, y1, x2, y2); separator->setFlag(ItemIgnoresTransformations); separator->setPen(QPen(Qt::white)); + separator->show(); }else{ - separator->setLine(QLineF()); + separator->hide(); } } diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index c1668692d..1c9238bee 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -59,7 +59,7 @@ public Q_SLOTS: private: typedef QPair ToolTip; QMap toolTips; - QGraphicsRectItem *background; + QGraphicsPathItem *background; QGraphicsLineItem *separator; QGraphicsSimpleTextItem *title; -- cgit v1.2.3-70-g09d2 From 2089c124a582ac95c4e9adb9362446572ff791f7 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Wed, 8 May 2013 07:22:23 -0300 Subject: Work on the tooltips - WIP. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 37 ++++++++++++++----------------------- qt-ui/profilegraphics.h | 7 +------ 2 files changed, 15 insertions(+), 29 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index e2fed39c5..550a5ec57 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -123,6 +123,7 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent setScene(new QGraphicsScene()); setBackgroundBrush(QColor("#F3F3E6")); scene()->setSceneRect(0,0,1000,1000); + scene()->installEventFilter(this); setRenderHint(QPainter::Antialiasing); setRenderHint(QPainter::HighQualityAntialiasing); @@ -135,6 +136,16 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent fill_profile_color(); } +bool ProfileGraphicsView::eventFilter(QObject* obj, QEvent* event) +{ + // This will "Eat" the default tooltip behavior. + if (event->type() == QEvent::GraphicsSceneHelp){ + event->ignore(); + return true; + } + return QGraphicsView::eventFilter(obj, event); +} + static void plot_set_scale(scale_mode_t scale) { switch (scale) { @@ -355,8 +366,9 @@ void ProfileGraphicsView::plot_one_event(struct graphics_context *gc, struct plo ev->flags == SAMPLE_FLAGS_END ? tr("Starts with space!", " end") : ""; } - item->setToolTipController(toolTip); - item->addToolTip(name); + //item->setToolTipController(toolTip); + //item->addToolTip(name); + item->setToolTip(name); } void ProfileGraphicsView::plot_depth_profile(struct graphics_context *gc, struct plot_info *pi) @@ -809,24 +821,3 @@ EventItem::EventItem(QGraphicsItem* parent): QGraphicsPolygonItem(parent) ball->setBrush(QBrush(Qt::black)); } - -void EventItem::hoverEnterEvent(QGraphicsSceneHoverEvent* event) -{ - controller->addToolTip(text, icon); -} - -void EventItem::hoverLeaveEvent(QGraphicsSceneHoverEvent* event) -{ - controller->removeToolTip(text); -} - -void EventItem::addToolTip(const QString& t, const QIcon& i) -{ - text = t; - icon = i; -} - -void EventItem::setToolTipController(ToolTipItem* c) -{ - controller = c; -} diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 1c9238bee..ca1eb8983 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -70,12 +70,6 @@ class EventItem : public QGraphicsPolygonItem { public: explicit EventItem(QGraphicsItem* parent = 0); - void addToolTip(const QString& text,const QIcon& icon = QIcon()); - void setToolTipController(ToolTipItem *controller); - -protected: - void hoverEnterEvent(QGraphicsSceneHoverEvent* event); - void hoverLeaveEvent(QGraphicsSceneHoverEvent* event); private: ToolTipItem *controller; @@ -89,6 +83,7 @@ Q_OBJECT public: ProfileGraphicsView(QWidget* parent = 0); void plot(struct dive *d); + bool eventFilter(QObject* obj, QEvent* event); protected: void resizeEvent(QResizeEvent *event); -- cgit v1.2.3-70-g09d2 From ce8d30b938b80c334eb0869650c3c463084ae018 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Wed, 8 May 2013 16:21:49 -0300 Subject: Make tooltips works Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 11 +++++++++++ qt-ui/profilegraphics.h | 1 + 2 files changed, 12 insertions(+) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 550a5ec57..508251232 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "../color.h" #include "../display.h" @@ -136,6 +137,16 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent fill_profile_color(); } +void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) +{ + toolTip->clear(); + 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()); + } +} + bool ProfileGraphicsView::eventFilter(QObject* obj, QEvent* event) { // This will "Eat" the default tooltip behavior. diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index ca1eb8983..d607e2615 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -87,6 +87,7 @@ public: protected: void resizeEvent(QResizeEvent *event); + void mouseMoveEvent(QMouseEvent* event); private: void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi); -- 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 'qt-ui/profilegraphics.cpp') 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 688276b6f200c5d8b44ab5b6092265a93f7c0b41 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Wed, 8 May 2013 17:48:20 -0300 Subject: Fix moving the ToolTip box with the mouse. When I changed the way that the tooltip box behaved, I accidentaly 'ate' the mouseMoveEvent, it was being used only to show tooltips instead of everything that it should have. this simple patch fixes it. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 1d1b5530c..271bd43ab 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -141,6 +141,7 @@ void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) if (!item->toolTip().isEmpty()) toolTip->addToolTip(item->toolTip()); } + QGraphicsView::mouseMoveEvent(event); } bool ProfileGraphicsView::eventFilter(QObject* obj, QEvent* event) -- 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 'qt-ui/profilegraphics.cpp') 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 656b58f20554f31bd25ec7a2c3b65a1b19046062 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Wed, 8 May 2013 15:46:16 -0700 Subject: Add tooltip data and cleanup size calculations Tomaz' code had a fixed height per tooltip item and some rather suspicious logic how to position them (and how to size the surrounding box), based on a fixed height in pixels per item - which of course fails if you use larger fonts or multi line items. This uses the bounding rects to correctly calculate the sizes and populates the tooltip with the other dive data that we already had in a helper function. This also fixes a small formatting issue for gas change events. Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index b3893ed90..93502f637 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -135,6 +135,10 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) { toolTip->clear(); + int time = (mapToScene(event->pos()).x() * gc.maxtime) / scene()->sceneRect().width(); + char buffer[500]; + get_plot_details(&gc, time, buffer, 500); + toolTip->addToolTip(QString(buffer)); QList items = scene()->items(mapToScene(event->pos()), Qt::IntersectsItemShape, Qt::DescendingOrder, transform()); Q_FOREACH(QGraphicsItem *item, items) { if (!item->toolTip().isEmpty()) @@ -356,9 +360,10 @@ void ProfileGraphicsView::plot_one_event(struct event *ev) unsigned int he = ev->value >> 16; unsigned int o2 = ev->value & 0xffff; + name += ": "; name += (he) ? QString("%1/%2").arg(o2, he) - : (o2 == 21) ? name += tr(":air") - : QString("%1 %% %2").arg(o2).arg("O" UTF8_SUBSCRIPT_2); + : (o2 == 21) ? name += tr("air") + : 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); @@ -664,8 +669,10 @@ void ProfileGraphicsView::plot_temperature_profile() void ToolTipItem::addToolTip(const QString& toolTip, const QIcon& icon) { QGraphicsPixmapItem *iconItem = 0; - double yValue = title->boundingRect().height() + SPACING + toolTips.keys().size() * ICON_SMALL + SPACING; - + double yValue = title->boundingRect().height() + SPACING; + Q_FOREACH(ToolTip t, toolTips) { + yValue += t.second->boundingRect().height(); + } if (!icon.isNull()) { iconItem = new QGraphicsPixmapItem(icon.pixmap(ICON_SMALL,ICON_SMALL), this); iconItem->setPos(SPACING, yValue); @@ -764,13 +771,12 @@ void ToolTipItem::expand() QRectF currentRect = rectangle; QRectF nextRectangle; - double width = 0; + double width = 0, height = title->boundingRect().height() + SPACING; Q_FOREACH(ToolTip t, toolTips) { if (t.second->boundingRect().width() > width) width = t.second->boundingRect().width(); + height += t.second->boundingRect().height(); } - - double height = toolTips.count() * 18 + title->boundingRect().height() + SPACING; /* Left padding, Icon Size, space, right padding */ width += SPACING + ICON_SMALL + SPACING + SPACING; -- cgit v1.2.3-70-g09d2 From 880870b46cce3b964d1ef3e472ec3c94544b5c25 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Wed, 8 May 2013 16:30:02 -0700 Subject: Show the dive computer name in the profile window And clean up some obsolete Gtk related stuff that is no longer relevant for the Qt port. Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 31 +++++++------------------------ 1 file changed, 7 insertions(+), 24 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 93502f637..46e040132 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -189,8 +189,6 @@ void ProfileGraphicsView::plot(struct dive *dive) struct divecomputer *dc = &dive->dc; - // This was passed around in the Cairo version / needed? - // const char *nickname; // Fix this for printing / screen later. // plot_set_scale(scale_mode_t); @@ -224,13 +222,6 @@ void ProfileGraphicsView::plot(struct dive *dive) */ calculate_max_limits(dive, dc, &gc); - /* - * 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. - */ QRectF drawing_area = scene()->sceneRect(); gc.maxx = (drawing_area.width() - 2 * drawing_area.x()); gc.maxy = (drawing_area.height() - 2 * drawing_area.y()); @@ -256,29 +247,21 @@ void ProfileGraphicsView::plot(struct dive *dive) plot_depth_text(gc, pi); plot_cylinder_pressure_text(gc, pi); plot_deco_text(gc, pi); +#endif - /* 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); + gc.leftx = 0; gc.rightx = 1.0; + gc.topy = 0; gc.bottomy = 1.0; /* Put the dive computer name in the lower left corner */ + const char *nickname; 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); + text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, MIDDLE}; + plot_text(&computer, 0, 1, nickname); } - +#if 0 if (PP_GRAPHS_ENABLED) { plot_pp_gas_profile(gc, pi); plot_pp_text(gc, pi); -- cgit v1.2.3-70-g09d2 From d120fed21191f547db1b2bc3a04a9ce389faec0f Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Wed, 8 May 2013 16:53:00 -0700 Subject: Add bounding box to profile Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 46e040132..50791e14c 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -248,9 +248,13 @@ void ProfileGraphicsView::plot(struct dive *dive) plot_cylinder_pressure_text(gc, pi); plot_deco_text(gc, pi); #endif - - gc.leftx = 0; gc.rightx = 1.0; - gc.topy = 0; gc.bottomy = 1.0; + /* Bounding box */ + QColor color = profile_color[TIME_GRID].at(0); + QPen pen = QPen(color); + pen.setWidth(1); + QGraphicsRectItem *rect = new QGraphicsRectItem(scene()->sceneRect()); + rect->setPen(pen); + scene()->addItem(rect); /* Put the dive computer name in the lower left corner */ const char *nickname; @@ -259,7 +263,7 @@ void ProfileGraphicsView::plot(struct dive *dive) nickname = dc->model; if (nickname) { text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, MIDDLE}; - plot_text(&computer, 0, 1, nickname); + plot_text(&computer, gc.leftx, gc.bottomy, nickname); } #if 0 if (PP_GRAPHS_ENABLED) { -- 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 'qt-ui/profilegraphics.cpp') 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 17c6db6a5b05b3ac1f85d136e86a0072e15e46cd Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 15:04:10 -0300 Subject: Shows the correct color for the CylinderPressure Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 32bd87d14..3baf2b008 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -116,6 +116,7 @@ extern int evn_used; ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent) { + gc.printer = false; setScene(new QGraphicsScene()); setBackgroundBrush(QColor("#F3F3E6")); scene()->setSceneRect(0,0,1000,1000); @@ -330,8 +331,7 @@ void ProfileGraphicsView::plot_cylinder_pressure(struct dive *dive, struct divec } } - // QColor c = get_sac_color(sac, dive->sac); Buggy TODO: fix. - QColor c = QColor(Qt::darkGreen); + QColor c = get_sac_color(sac, dive->sac); if (lift_pen) { if (!first_plot && entry->cylinderindex == last_index) { -- 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 'qt-ui/profilegraphics.cpp') 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 'qt-ui/profilegraphics.cpp') 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 'qt-ui/profilegraphics.cpp') 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 'qt-ui/profilegraphics.cpp') 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 b794c23099f97cefd0a65b070fc9aa9dd5523e87 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 17:30:16 -0300 Subject: Plot pp Text This patch plots the PP text, but when I plotted I realized that the gc.pi.mapp is being calculated wrong, probably something went wrong on the calculations - it's comming zered always. So, only one line & text is plotted. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 23 ++++++++++++++++++++++- qt-ui/profilegraphics.h | 2 +- 2 files changed, 23 insertions(+), 2 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 5425cae32..91e230e91 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -273,7 +273,7 @@ void ProfileGraphicsView::plot(struct dive *dive) //if (PP_GRAPHS_ENABLED) { plot_pp_gas_profile(); - // plot_pp_text(gc, pi); + plot_pp_text(); //} #if 0 @@ -294,6 +294,27 @@ void ProfileGraphicsView::plot(struct dive *dive) #endif } +void ProfileGraphicsView::plot_pp_text() +{ + double pp, dpp, m; + int hpos; + static text_render_options_t tro = {PP_TEXT_SIZE, PP_LINES, LEFT, MIDDLE}; + + setup_pp_limits(&gc); + pp = floor(gc.pi.maxpp * 10.0) / 10.0 + 0.2; + dpp = pp > 4 ? 1.0 : 0.5; + 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)); + item->setPen(QPen(c)); + scene()->addItem(item); + plot_text(&tro, hpos + 30, m, QString::number(m)); + } +} + void ProfileGraphicsView::plot_pp_gas_profile() { int i; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 6ed41de1e..ca0aaedf9 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -106,7 +106,7 @@ private: void plot_pressure_value(int mbar, int sec, int xalign, int yalign); void plot_deco_text(); void plot_pp_gas_profile(); - + void plot_pp_text(); QColor get_sac_color(int sac, int avg_sac); QPen defaultPen; -- 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 'qt-ui/profilegraphics.cpp') 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 5978afbcd88965aae8d67b5d3f20bd9d18c0bfb5 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 18:29:18 -0300 Subject: Use a Default pen to make the configuration easier. Created a default pen that has 'cosmetic' enabled, A cosmetic line doesn't change it's width no matter what zoom level we apply. Also , changed everything that used a line to have that as default pen instead. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 93 +++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 35 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 625dfdf10..8fa8e94a6 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -129,6 +129,7 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent defaultPen.setJoinStyle(Qt::RoundJoin); defaultPen.setCapStyle(Qt::RoundCap); defaultPen.setWidth(2); + defaultPen.setCosmetic(true); fill_profile_color(); } @@ -253,9 +254,8 @@ void ProfileGraphicsView::plot(struct dive *dive) plot_deco_text(); /* Bounding box */ - QColor color = profile_color[TIME_GRID].at(0); - QPen pen = QPen(color); - pen.setWidth(1); + QPen pen = defaultPen; + pen.setColor(profile_color[TIME_GRID].at(0)); QGraphicsRectItem *rect = new QGraphicsRectItem(scene()->sceneRect()); rect->setPen(pen); scene()->addItem(rect); @@ -338,7 +338,9 @@ void ProfileGraphicsView::plot_pp_text() qDebug() << pp << dpp; for (m = 0.0; m <= pp; m += dpp) { QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(0, m), SCALEGC(hpos, m)); - item->setPen(QPen(c)); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); scene()->addItem(item); plot_text(&tro, hpos + 30, m, QString::number(m)); } @@ -362,7 +364,9 @@ void ProfileGraphicsView::plot_pp_gas_profile() 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)); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); scene()->addItem(item); from = to; } @@ -379,7 +383,9 @@ void ProfileGraphicsView::plot_pp_gas_profile() 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)); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); scene()->addItem(item); from = to; } @@ -399,7 +405,9 @@ void ProfileGraphicsView::plot_pp_gas_profile() 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)); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); scene()->addItem(item); from = to; } @@ -416,7 +424,9 @@ void ProfileGraphicsView::plot_pp_gas_profile() 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)); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); scene()->addItem(item); from = to; } @@ -434,7 +444,9 @@ void ProfileGraphicsView::plot_pp_gas_profile() 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)); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); scene()->addItem(item); from = to; } @@ -676,7 +688,9 @@ void ProfileGraphicsView::plot_cylinder_pressure(struct dive *dive, struct divec 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)); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); scene()->addItem(item); } else { first_plot = FALSE; @@ -686,7 +700,9 @@ void ProfileGraphicsView::plot_cylinder_pressure(struct dive *dive, struct divec } else { to = QPointF(SCALEGC(entry->sec, mbar)); QGraphicsLineItem *item = new QGraphicsLineItem(from.x(), from.y(), to.x(), to.y()); - item->setPen(QPen(c, 2)); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); scene()->addItem(item); } @@ -831,12 +847,13 @@ void ProfileGraphicsView::plot_depth_profile() last_gc = gc; - QColor color; - color = profile_color[TIME_GRID].at(0); + QColor c = profile_color[TIME_GRID].at(0); for (i = incr; i < maxtime; i += incr) { - QGraphicsLineItem *line = new QGraphicsLineItem(SCALEGC(i, 0), SCALEGC(i, 1)); - line->setPen(QPen(color)); - scene()->addItem(line); + QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(i, 0), SCALEGC(i, 1)); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); + scene()->addItem(item); } /* now the text on the time markers */ @@ -864,23 +881,27 @@ void ProfileGraphicsView::plot_depth_profile() } maxline = MAX(gc.pi.maxdepth + marker, maxdepth * 2 / 3); - color = profile_color[DEPTH_GRID].at(0); + c = profile_color[DEPTH_GRID].at(0); for (i = marker; i < maxline; i += marker) { - QGraphicsLineItem *line = new QGraphicsLineItem(SCALEGC(0, i), SCALEGC(1, i)); - line->setPen(QPen(color)); - scene()->addItem(line); + QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(0, i), SCALEGC(1, i)); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); + scene()->addItem(item); } gc.leftx = 0; gc.rightx = maxtime; - color = profile_color[MEAN_DEPTH].at(0); + c = profile_color[MEAN_DEPTH].at(0); /* Show mean depth */ if (! gc.printer) { - QGraphicsLineItem *line = new QGraphicsLineItem(SCALEGC(0, gc.pi.meandepth), + QGraphicsLineItem *item = 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); + QPen pen(defaultPen); + pen.setColor(c); + item->setPen(pen); + scene()->addItem(item); } #if 0 @@ -924,7 +945,7 @@ void ProfileGraphicsView::plot_depth_profile() neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); neatFill->setBrush(QBrush(pat)); - neatFill->setPen(QPen(QBrush(),0)); + neatFill->setPen(QPen(QBrush(Qt::transparent),0)); scene()->addItem(neatFill); @@ -955,7 +976,7 @@ void ProfileGraphicsView::plot_depth_profile() neatFill = new QGraphicsPolygonItem(); neatFill->setBrush(QBrush(pat)); neatFill->setPolygon(p); - neatFill->setPen(QPen(QBrush(),0)); + neatFill->setPen(QPen(QBrush(Qt::NoBrush),0)); scene()->addItem(neatFill); //} @@ -978,7 +999,7 @@ void ProfileGraphicsView::plot_depth_profile() p.append(QPointF(SCALEGC((entry-1)->sec, 0))); neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); - neatFill->setPen(QPen(QBrush(),0)); + neatFill->setPen(QPen(QBrush(Qt::NoBrush),0)); neatFill->setBrush(pat); scene()->addItem(neatFill); //} @@ -1002,7 +1023,7 @@ void ProfileGraphicsView::plot_depth_profile() neatFill = new QGraphicsPolygonItem(); neatFill->setPolygon(p); - neatFill->setPen(QPen(QBrush(),0)); + neatFill->setPen(QPen(QBrush(Qt::NoBrush),0)); neatFill->setBrush(QBrush(pat)); scene()->addItem(neatFill); @@ -1015,9 +1036,11 @@ void ProfileGraphicsView::plot_depth_profile() * representing the vertical velocity, so we need to * chop this into short segments */ depth = entry->depth; - 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); + QGraphicsLineItem *item = new QGraphicsLineItem(SCALEGC(entry[-1].sec, entry[-1].depth), SCALEGC(sec, depth)); + QPen pen(defaultPen); + pen.setColor(profile_color[ (color_indice_t) (VELOCITY_COLORS_START_IDX + entry->velocity)].first()); + item->setPen(pen); + scene()->addItem(item); } } @@ -1033,7 +1056,6 @@ void ProfileGraphicsView::plot_text(text_render_options_t *tro, double x, double 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); } @@ -1071,7 +1093,9 @@ void ProfileGraphicsView::plot_temperature_profile() 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)); + QPen pen(defaultPen); + pen.setColor(color); + item->setPen(pen); scene()->addItem(item); from = to; } @@ -1096,10 +1120,8 @@ void ToolTipItem::addToolTip(const QString& toolTip, const QIcon& icon) QGraphicsSimpleTextItem *textItem = new QGraphicsSimpleTextItem(toolTip, this); textItem->setPos(SPACING + ICON_SMALL + SPACING, yValue); - textItem->setPen(QPen(Qt::white, 1)); textItem->setBrush(QBrush(Qt::white)); textItem->setFlag(ItemIgnoresTransformations); - toolTips[toolTip] = qMakePair(iconItem, textItem); expand(); } @@ -1270,6 +1292,7 @@ EventItem::EventItem(QGraphicsItem* parent): QGraphicsPolygonItem(parent) defaultPen.setJoinStyle(Qt::RoundJoin); defaultPen.setCapStyle(Qt::RoundCap); defaultPen.setWidth(2); + defaultPen.setCosmetic(true); QPen pen = defaultPen; pen.setBrush(QBrush(profile_color[ALERT_BG].first())); -- 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 'qt-ui/profilegraphics.cpp') 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 acdb5d97ebe88a75933089a80b1ce844c4375851 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 9 May 2013 19:59:55 -0300 Subject: The Zoom is working just like the GTK Version. This code enables Zoom in / Out with the Wheel, and it also enables panning by moving the mouse around. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 38 +++++++++++++++++++++++++++++++------- qt-ui/profilegraphics.h | 2 ++ 2 files changed, 33 insertions(+), 7 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index ad6cbb172..44af49e7c 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) +ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent) , dive(0) { gc.printer = false; setScene(new QGraphicsScene()); @@ -131,9 +131,27 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent defaultPen.setWidth(2); defaultPen.setCosmetic(true); + setHorizontalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); + setVerticalScrollBarPolicy ( Qt::ScrollBarAlwaysOff ); + fill_profile_color(); } +void ProfileGraphicsView::wheelEvent(QWheelEvent* event) +{ + setTransformationAnchor(QGraphicsView::AnchorUnderMouse); + + // Scale the view / do the zoom + double scaleFactor = 1.15; + if(event->delta() > 0) { + // Zoom in + scale(scaleFactor, scaleFactor); + } else { + // Zooming out + scale(1.0 / scaleFactor, 1.0 / scaleFactor); + } +} + void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) { toolTip->clear(); @@ -146,6 +164,10 @@ void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) if (!item->toolTip().isEmpty()) toolTip->addToolTip(item->toolTip()); } + + // Pan on mouseMove code. + ensureVisible(event->pos().x(), event->pos().y(), 10, 10, 100, 100); + QGraphicsView::mouseMoveEvent(event); } @@ -172,13 +194,16 @@ static void plot_set_scale(scale_mode_t scale) } } -void ProfileGraphicsView::plot(struct dive *dive) +void ProfileGraphicsView::plot(struct dive *d) { scene()->clear(); + dive = d; if(!dive) return; + scene()->setSceneRect(0,0, viewport()->width()-50, viewport()->height()-50); + QSettings s; s.beginGroup("ProfileMap"); QPointF toolTipPos = s.value("tooltip_position", QPointF(0,0)).toPointF(); @@ -294,6 +319,9 @@ void ProfileGraphicsView::plot(struct dive *dive) pi->nr = 0; } #endif + + QRectF curerntRect = scene()->itemsBoundingRect(); + scene()->setSceneRect( -10, -10, curerntRect.width() + 10, curerntRect.height() +10 ); } void ProfileGraphicsView::plot_depth_scale() @@ -1061,11 +1089,7 @@ void ProfileGraphicsView::plot_text(text_render_options_t *tro, double x, double void ProfileGraphicsView::resizeEvent(QResizeEvent *event) { - // Fits the scene's rectangle on the view. - // 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; + plot(dive); } void ProfileGraphicsView::plot_temperature_profile() diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 268226843..76179b956 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -67,6 +67,7 @@ public: protected: void resizeEvent(QResizeEvent *event); void mouseMoveEvent(QMouseEvent* event); + void wheelEvent(QWheelEvent* event); private: void plot_depth_profile(); @@ -93,6 +94,7 @@ private: QBrush defaultBrush; ToolTipItem *toolTip; graphics_context gc; + struct dive *dive; }; #endif -- cgit v1.2.3-70-g09d2 From 93d3af768b86602b3b13062705cb2d12db82b5a2 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Fri, 10 May 2013 10:30:24 -0300 Subject: Uses the correct rectangle to englobe the profile grid. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 44af49e7c..4d900aa73 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -249,9 +249,9 @@ void ProfileGraphicsView::plot(struct dive *d) */ calculate_max_limits(dive, dc, &gc); - QRectF drawing_area = scene()->sceneRect(); - gc.maxx = (drawing_area.width() - 2 * drawing_area.x()); - gc.maxy = (drawing_area.height() - 2 * drawing_area.y()); + QRectF profile_grid_area = scene()->sceneRect(); + gc.maxx = (profile_grid_area.width() - 2 * profile_grid_area.x()); + gc.maxy = (profile_grid_area.height() - 2 * profile_grid_area.y()); dc = select_dc(dc); @@ -281,7 +281,7 @@ void ProfileGraphicsView::plot(struct dive *d) /* Bounding box */ QPen pen = defaultPen; pen.setColor(profile_color[TIME_GRID].at(0)); - QGraphicsRectItem *rect = new QGraphicsRectItem(scene()->sceneRect()); + QGraphicsRectItem *rect = new QGraphicsRectItem(profile_grid_area); rect->setPen(pen); scene()->addItem(rect); @@ -296,10 +296,10 @@ void ProfileGraphicsView::plot(struct dive *d) } - //if (PP_GRAPHS_ENABLED) { + if (PP_GRAPHS_ENABLED) { plot_pp_gas_profile(); plot_pp_text(); - //} + } /* now shift the translation back by half the margin; -- cgit v1.2.3-70-g09d2 From 2052e44ba19b4bc9689792bbff2170fc3426d42a Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Fri, 10 May 2013 11:07:44 -0300 Subject: Fix Tooltip Positions, code cleanup Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 32 +++++++++++++++++++++----------- qt-ui/profilegraphics.h | 1 + 2 files changed, 22 insertions(+), 11 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 4d900aa73..9441f3ae3 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -142,6 +142,7 @@ void ProfileGraphicsView::wheelEvent(QWheelEvent* event) setTransformationAnchor(QGraphicsView::AnchorUnderMouse); // Scale the view / do the zoom + QPoint toolTipPos = mapFromScene(toolTip->pos()); double scaleFactor = 1.15; if(event->delta() > 0) { // Zoom in @@ -150,23 +151,16 @@ void ProfileGraphicsView::wheelEvent(QWheelEvent* event) // Zooming out scale(1.0 / scaleFactor, 1.0 / scaleFactor); } + toolTip->setPos(mapToScene(toolTipPos).x(), mapToScene(toolTipPos).y()); } void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) { - toolTip->clear(); - int time = (mapToScene(event->pos()).x() * gc.maxtime) / scene()->sceneRect().width(); - char buffer[500]; - get_plot_details(&gc, time, buffer, 500); - toolTip->addToolTip(QString(buffer)); - 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()); - } + toolTip->refresh(&gc, mapToScene(event->pos())); - // Pan on mouseMove code. + QPoint toolTipPos = mapFromScene(toolTip->pos()); ensureVisible(event->pos().x(), event->pos().y(), 10, 10, 100, 100); + toolTip->setPos(mapToScene(toolTipPos).x(), mapToScene(toolTipPos).y()); QGraphicsView::mouseMoveEvent(event); } @@ -1172,6 +1166,22 @@ void ToolTipItem::removeToolTip(const QString& toolTip) expand(); } +void ToolTipItem::refresh(struct graphics_context *gc, QPointF pos) +{ + clear(); + int time = (pos.x() * gc->maxtime) / scene()->sceneRect().width(); + char buffer[500]; + get_plot_details(gc, time, buffer, 500); + addToolTip(QString(buffer)); + + QList items = scene()->items(pos, Qt::IntersectsItemShape, Qt::DescendingOrder, transform()); + Q_FOREACH(QGraphicsItem *item, items) { + if (!item->toolTip().isEmpty()) + addToolTip(item->toolTip()); + } + +} + void ToolTipItem::clear() { Q_FOREACH(ToolTip t, toolTips) { diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 76179b956..b9b57db08 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -31,6 +31,7 @@ public: void clear(); void addToolTip(const QString& toolTip, const QIcon& icon = QIcon()); void removeToolTip(const QString& toolTip); + void refresh(struct graphics_context* gc, QPointF pos); public Q_SLOTS: void setRect(const QRectF& rect); -- cgit v1.2.3-70-g09d2 From ea5353025f58aaaf31d7cf9d1ca92c93d9357c16 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Fri, 10 May 2013 11:45:07 -0300 Subject: Only drag the tooltip panel when not zooming. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 18 +++++++++++++----- qt-ui/profilegraphics.h | 1 + 2 files changed, 14 insertions(+), 5 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 9441f3ae3..aeeccc875 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -144,12 +144,13 @@ void ProfileGraphicsView::wheelEvent(QWheelEvent* event) // Scale the view / do the zoom QPoint toolTipPos = mapFromScene(toolTip->pos()); double scaleFactor = 1.15; - if(event->delta() > 0) { - // Zoom in + if(event->delta() > 0 && zoomLevel <= 10) { scale(scaleFactor, scaleFactor); - } else { + zoomLevel++; + } else if (zoomLevel >= 0) { // Zooming out scale(1.0 / scaleFactor, 1.0 / scaleFactor); + zoomLevel--; } toolTip->setPos(mapToScene(toolTipPos).x(), mapToScene(toolTipPos).y()); } @@ -162,7 +163,9 @@ void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) ensureVisible(event->pos().x(), event->pos().y(), 10, 10, 100, 100); toolTip->setPos(mapToScene(toolTipPos).x(), mapToScene(toolTipPos).y()); - QGraphicsView::mouseMoveEvent(event); + if (zoomLevel < 0){ + QGraphicsView::mouseMoveEvent(event); + } } bool ProfileGraphicsView::eventFilter(QObject* obj, QEvent* event) @@ -192,7 +195,12 @@ void ProfileGraphicsView::plot(struct dive *d) { scene()->clear(); - dive = d; + if (dive != d){ + resetTransform(); + zoomLevel = 0; + dive = d; + } + if(!dive) return; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index b9b57db08..288c9230a 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -96,6 +96,7 @@ private: ToolTipItem *toolTip; graphics_context gc; struct dive *dive; + int zoomLevel; }; #endif -- cgit v1.2.3-70-g09d2 From 9a403330673ffe1812a46e2afe4f473ca39f672b Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Fri, 10 May 2013 12:00:56 -0300 Subject: Fix showing the stuff on the canvas in the right positions. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index aeeccc875..71aebd19f 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -163,9 +163,8 @@ void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) ensureVisible(event->pos().x(), event->pos().y(), 10, 10, 100, 100); toolTip->setPos(mapToScene(toolTipPos).x(), mapToScene(toolTipPos).y()); - if (zoomLevel < 0){ + if (zoomLevel < 0) QGraphicsView::mouseMoveEvent(event); - } } bool ProfileGraphicsView::eventFilter(QObject* obj, QEvent* event) @@ -322,8 +321,7 @@ void ProfileGraphicsView::plot(struct dive *d) } #endif - QRectF curerntRect = scene()->itemsBoundingRect(); - scene()->setSceneRect( -10, -10, curerntRect.width() + 10, curerntRect.height() +10 ); + scene()->setSceneRect(scene()->itemsBoundingRect()); } void ProfileGraphicsView::plot_depth_scale() -- cgit v1.2.3-70-g09d2 From bfef1d021970c57ce007fb4c29d62b0a1f4e13a2 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 10 May 2013 08:56:56 -0700 Subject: Fix some compiler warnings Passing the alignment as int instead of float or double was actually a bug as CENTER is defined as (-0.5) ... Signed-off-by: Dirk Hohndel --- profile.h | 2 +- qt-ui/profilegraphics.cpp | 4 +--- qt-ui/profilegraphics.h | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/profile.h b/profile.h index 89324530a..2b2c7bff5 100644 --- a/profile.h +++ b/profile.h @@ -14,7 +14,7 @@ struct graphics_context; struct plot_info; struct plot_data { unsigned int in_deco:1; - unsigned int cylinderindex; + int cylinderindex; int sec; /* pressure[0] is sensor pressure * pressure[1] is interpolated pressure */ diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 71aebd19f..5607cb3b8 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -550,7 +550,7 @@ void ProfileGraphicsView::plot_cylinder_pressure_text() } } -void ProfileGraphicsView::plot_pressure_value(int mbar, int sec, int xalign, int yalign) +void ProfileGraphicsView::plot_pressure_value(int mbar, int sec, double xalign, double yalign) { int pressure; const char *unit; @@ -1234,7 +1234,6 @@ void ToolTipItem::setRect(const QRectF& r) void ToolTipItem::collapse() { - QRectF newRect = childrenBoundingRect(); QPropertyAnimation *animation = new QPropertyAnimation(this, "rect"); animation->setDuration(100); animation->setStartValue(boundingRect()); @@ -1244,7 +1243,6 @@ void ToolTipItem::collapse() void ToolTipItem::expand() { - QRectF currentRect = rectangle; QRectF nextRectangle; double width = 0, height = title->boundingRect().height() + SPACING; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 288c9230a..a2033ca75 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -83,7 +83,7 @@ private: 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); + void plot_pressure_value(int mbar, int sec, double xalign, double yalign); void plot_deco_text(); void plot_pp_gas_profile(); void plot_pp_text(); -- cgit v1.2.3-70-g09d2 From b3b1b3f58f39d1b87028908691b46d89a12d2143 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Fri, 10 May 2013 13:03:16 -0300 Subject: Change the plot text so it receives a QPointF instead of x,y, and a Parent Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 24 ++++++++++++------------ qt-ui/profilegraphics.h | 2 +- 2 files changed, 13 insertions(+), 13 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 71aebd19f..01f627622 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -293,7 +293,7 @@ void ProfileGraphicsView::plot(struct dive *d) nickname = dc->model; if (nickname) { text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, MIDDLE}; - plot_text(&computer, gc.leftx, gc.bottomy, nickname); + plot_text(&computer, QPointF(gc.leftx, gc.bottomy), nickname); } @@ -347,7 +347,7 @@ void ProfileGraphicsView::plot_depth_scale() * 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)); + plot_text(&tro, QPointF(-0.002, i), QString::number(d)); } } @@ -369,7 +369,7 @@ void ProfileGraphicsView::plot_pp_text() pen.setColor(c); item->setPen(pen); scene()->addItem(item); - plot_text(&tro, hpos + 30, m, QString::number(m)); + plot_text(&tro, QPointF(hpos + 30, m), QString::number(m)); } } @@ -508,7 +508,7 @@ void ProfileGraphicsView::plot_deco_text() 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)); + plot_text(&tro, QPointF(x, y), QString("GF %1/%2").arg(prefs.gflow * 100).arg(prefs.gfhigh * 100)); } } @@ -557,7 +557,7 @@ void ProfileGraphicsView::plot_pressure_value(int mbar, int sec, int xalign, int 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)); + plot_text(&tro, QPointF(sec, mbar), QString("%1 %2").arg(pressure).arg(unit)); } void ProfileGraphicsView::plot_depth_text() @@ -611,7 +611,7 @@ void ProfileGraphicsView::plot_depth_sample(struct plot_data *entry,text_render_ d = get_depth_units(entry->depth, &decimals, NULL); - plot_text(tro, sec, entry->depth, QString("%1").arg(d)); // , decimals, d); + plot_text(tro, QPointF(sec, entry->depth), QString("%1").arg(d)); // , decimals, d); } @@ -660,7 +660,7 @@ void ProfileGraphicsView::plot_single_temp_text(int sec, int mkelvin) 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" + plot_text(&tro, QPointF(sec, mkelvin), QString("%1%2").arg(deg).arg(unit)); //"%.2g%s" } void ProfileGraphicsView::plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc) @@ -888,11 +888,11 @@ void ProfileGraphicsView::plot_depth_profile() if (maxtime < 600) { /* Be a bit more verbose with shorter dives */ for (i = incr; i < maxtime; i += incr) - plot_text(&tro, i, 1, QString("%1:%2").arg(i/60).arg(i%60)); + plot_text(&tro, QPointF(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(&tro, i, 1, QString::number(i/60)); + plot_text(&tro, QPointF(i, 1), QString::number(i/60)); } /* Depth markers: every 30 ft or 10 m*/ @@ -1071,15 +1071,15 @@ void ProfileGraphicsView::plot_depth_profile() } } -void ProfileGraphicsView::plot_text(text_render_options_t *tro, double x, double y, const QString& text) +void ProfileGraphicsView::plot_text(text_render_options_t *tro,const QPointF& pos, const QString& text, QGraphicsItem *parent) { QFontMetrics fm(font()); double dx = tro->hpos * (fm.width(text)); double dy = tro->vpos * (fm.height()); - QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem(text); - QPointF point(SCALEGC(x, y)); // This is neded because of the SCALE macro. + QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem(text, parent); + QPointF point(SCALEGC(pos.x(), pos.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())); diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 288c9230a..996c5927a 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -72,7 +72,7 @@ protected: private: void plot_depth_profile(); - void plot_text(text_render_options_t *tro, double x, double y, const QString &text); + void plot_text(text_render_options_t *tro, const QPointF& pos, const QString &text, QGraphicsItem *parent = 0); void plot_events(struct divecomputer *dc); void plot_one_event(struct event *event); void plot_temperature_profile(); -- cgit v1.2.3-70-g09d2 From c129902793446cda9137f2b44c59d5840e4eeaec Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 10 May 2013 08:56:56 -0700 Subject: Fix some compiler warnings Passing the alignment as int instead of float or double was actually a bug as CENTER is defined as (-0.5) ... Signed-off-by: Dirk Hohndel --- profile.h | 2 +- qt-ui/profilegraphics.cpp | 4 +--- qt-ui/profilegraphics.h | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/profile.h b/profile.h index 89324530a..2b2c7bff5 100644 --- a/profile.h +++ b/profile.h @@ -14,7 +14,7 @@ struct graphics_context; struct plot_info; struct plot_data { unsigned int in_deco:1; - unsigned int cylinderindex; + int cylinderindex; int sec; /* pressure[0] is sensor pressure * pressure[1] is interpolated pressure */ diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 01f627622..9c21028d9 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -550,7 +550,7 @@ void ProfileGraphicsView::plot_cylinder_pressure_text() } } -void ProfileGraphicsView::plot_pressure_value(int mbar, int sec, int xalign, int yalign) +void ProfileGraphicsView::plot_pressure_value(int mbar, int sec, double xalign, double yalign) { int pressure; const char *unit; @@ -1234,7 +1234,6 @@ void ToolTipItem::setRect(const QRectF& r) void ToolTipItem::collapse() { - QRectF newRect = childrenBoundingRect(); QPropertyAnimation *animation = new QPropertyAnimation(this, "rect"); animation->setDuration(100); animation->setStartValue(boundingRect()); @@ -1244,7 +1243,6 @@ void ToolTipItem::collapse() void ToolTipItem::expand() { - QRectF currentRect = rectangle; QRectF nextRectangle; double width = 0, height = title->boundingRect().height() + SPACING; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 996c5927a..08dffd6a3 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -83,7 +83,7 @@ private: 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); + void plot_pressure_value(int mbar, int sec, double xalign, double yalign); void plot_deco_text(); void plot_pp_gas_profile(); void plot_pp_text(); -- cgit v1.2.3-70-g09d2 From 1fec7d849c69e7e6cca71c268e9331a4a52ad6e8 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Fri, 10 May 2013 13:57:36 -0300 Subject: Fixed Zoom and Positioning of the Ruler Items The items are still being placed far from each other when zooming in - I need a bit of help with the math for that. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 48 ++++++++++++++++++++++++++++++++--------------- qt-ui/profilegraphics.h | 8 +++++++- 2 files changed, 40 insertions(+), 16 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 9c21028d9..c01022799 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -119,7 +119,6 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent gc.printer = false; setScene(new QGraphicsScene()); setBackgroundBrush(QColor("#F3F3E6")); - scene()->setSceneRect(0,0,1000,1000); scene()->installEventFilter(this); setRenderHint(QPainter::Antialiasing); @@ -160,7 +159,12 @@ void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) toolTip->refresh(&gc, mapToScene(event->pos())); QPoint toolTipPos = mapFromScene(toolTip->pos()); - ensureVisible(event->pos().x(), event->pos().y(), 10, 10, 100, 100); + + double dx = sceneRect().x(); + double dy = sceneRect().y(); + + ensureVisible(event->pos().x() + dx, event->pos().y() + dy, 1, 1); + toolTip->setPos(mapToScene(toolTipPos).x(), mapToScene(toolTipPos).y()); if (zoomLevel < 0) @@ -287,15 +291,16 @@ void ProfileGraphicsView::plot(struct dive *d) scene()->addItem(rect); /* Put the dive computer name in the lower left corner */ - const char *nickname; - nickname = get_dc_nickname(dc->model, dc->deviceid); - if (!nickname || *nickname == '\0') - nickname = dc->model; - if (nickname) { + QString nick(get_dc_nickname(dc->model, dc->deviceid)); + if (nick.isEmpty()) + nick = QString(dc->model); + + if (!nick.isEmpty()) { text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, MIDDLE}; - plot_text(&computer, QPointF(gc.leftx, gc.bottomy), nickname); + diveComputer = plot_text(&computer, QPointF(gc.leftx, gc.bottomy), nick); } - + // The Time ruler should be right after the DiveComputer: + timeMarkers->setPos(0, diveComputer->y()); if (PP_GRAPHS_ENABLED) { plot_pp_gas_profile(); @@ -321,7 +326,11 @@ void ProfileGraphicsView::plot(struct dive *d) } #endif - scene()->setSceneRect(scene()->itemsBoundingRect()); + QRectF r = scene()->itemsBoundingRect(); + scene()->setSceneRect(r.x() - 15, r.y() -15, r.width() + 30, r.height() + 30); + if(zoomLevel == 0){ + fitInView(sceneRect()); + } } void ProfileGraphicsView::plot_depth_scale() @@ -345,10 +354,13 @@ void ProfileGraphicsView::plot_depth_scale() * 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 */ + depthMarkers = new QGraphicsRectItem(); for (i = marker; i <= gc.pi.maxdepth + marker; i += marker) { double d = get_depth_units(i, NULL, NULL); - plot_text(&tro, QPointF(-0.002, i), QString::number(d)); + plot_text(&tro, QPointF(-0.002, i), QString::number(d), depthMarkers); } + scene()->addItem(depthMarkers); + depthMarkers->setPos(depthMarkers->pos().x() - 10, 0); } void ProfileGraphicsView::plot_pp_text() @@ -883,17 +895,20 @@ void ProfileGraphicsView::plot_depth_profile() scene()->addItem(item); } + timeMarkers = new QGraphicsRectItem(); /* now the text on the time markers */ 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(&tro, QPointF(i, 1), QString("%1:%2").arg(i/60).arg(i%60)); + plot_text(&tro, QPointF(i, 0), QString("%1:%2").arg(i/60).arg(i%60), timeMarkers); } else { /* Only render the time on every second marker for normal dives */ for (i = incr; i < maxtime; i += 2 * incr) - plot_text(&tro, QPointF(i, 1), QString::number(i/60)); + plot_text(&tro, QPointF(i, 0), QString("%1").arg(QString::number(i/60)), timeMarkers); } + timeMarkers->setPos(0,0); + scene()->addItem(timeMarkers); /* Depth markers: every 30 ft or 10 m*/ gc.leftx = 0; gc.rightx = 1.0; @@ -1071,7 +1086,7 @@ void ProfileGraphicsView::plot_depth_profile() } } -void ProfileGraphicsView::plot_text(text_render_options_t *tro,const QPointF& pos, const QString& text, QGraphicsItem *parent) +QGraphicsSimpleTextItem *ProfileGraphicsView::plot_text(text_render_options_t *tro,const QPointF& pos, const QString& text, QGraphicsItem *parent) { QFontMetrics fm(font()); @@ -1084,7 +1099,10 @@ void ProfileGraphicsView::plot_text(text_render_options_t *tro,const QPointF& po item->setPos(point.x() + dx, point.y() +dy); item->setBrush(QBrush(profile_color[tro->color].first())); item->setFlag(QGraphicsItem::ItemIgnoresTransformations); - scene()->addItem(item); + + if(!parent) + scene()->addItem(item); + return item; } void ProfileGraphicsView::resizeEvent(QResizeEvent *event) diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 08dffd6a3..cd87276e3 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -72,7 +72,7 @@ protected: private: void plot_depth_profile(); - void plot_text(text_render_options_t *tro, const QPointF& pos, const QString &text, QGraphicsItem *parent = 0); + QGraphicsSimpleTextItem* plot_text(text_render_options_t *tro, const QPointF& pos, const QString &text, QGraphicsItem *parent = 0); void plot_events(struct divecomputer *dc); void plot_one_event(struct event *event); void plot_temperature_profile(); @@ -97,6 +97,12 @@ private: graphics_context gc; struct dive *dive; int zoomLevel; + + // Top Level Items. + QGraphicsItem* profileGrid; + QGraphicsItem* timeMarkers; + QGraphicsItem* depthMarkers; + QGraphicsItem* diveComputer; }; #endif -- cgit v1.2.3-70-g09d2 From 56c4cced536b8b1bb7282f263deb24640632e884 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Fri, 10 May 2013 14:18:33 -0300 Subject: Fixed loading the first dive via command line on the profile. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 12 +++++++++++- qt-ui/profilegraphics.h | 1 + 2 files changed, 12 insertions(+), 1 deletion(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index c01022799..c2f71be11 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -194,16 +194,26 @@ static void plot_set_scale(scale_mode_t scale) } } +void ProfileGraphicsView::showEvent(QShowEvent* event) +{ + if (dive) + plot(dive); +} + void ProfileGraphicsView::plot(struct dive *d) { - scene()->clear(); + scene()->clear(); if (dive != d){ resetTransform(); zoomLevel = 0; dive = d; } + if(!isVisible()){ + return; + } + if(!dive) return; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index cd87276e3..7cf88cbc3 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -69,6 +69,7 @@ protected: void resizeEvent(QResizeEvent *event); void mouseMoveEvent(QMouseEvent* event); void wheelEvent(QWheelEvent* event); + void showEvent(QShowEvent* event); private: void plot_depth_profile(); -- cgit v1.2.3-70-g09d2 From ad8f96cd6efdec59cbec7e10571de2e9c2496d9e Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Fri, 10 May 2013 15:52:06 -0300 Subject: Crash fixed on clicking on the canvas while no dive is loaded. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 5607cb3b8..c1e51ac25 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) +ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent) , dive(0), toolTip(0) { gc.printer = false; setScene(new QGraphicsScene()); @@ -139,6 +139,9 @@ ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent void ProfileGraphicsView::wheelEvent(QWheelEvent* event) { + if (!toolTip) + return; + setTransformationAnchor(QGraphicsView::AnchorUnderMouse); // Scale the view / do the zoom @@ -157,6 +160,9 @@ void ProfileGraphicsView::wheelEvent(QWheelEvent* event) void ProfileGraphicsView::mouseMoveEvent(QMouseEvent* event) { + if (!toolTip) + return; + toolTip->refresh(&gc, mapToScene(event->pos())); QPoint toolTipPos = mapFromScene(toolTip->pos()); -- 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 'qt-ui/profilegraphics.cpp') 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 06d296a17da927131ef8de511d0f9bf56dab0535 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 10 May 2013 21:07:49 -0700 Subject: Improve the text labels in the profile Only 1 decimal, please. Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index c6a2669ef..d606d8260 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -617,14 +617,14 @@ void ProfileGraphicsView::plot_text_samples() if (entry->depth < 2000) continue; - if ((entry == entry->max[2]) && entry->depth != last) { + if ((entry == entry->max[2]) && entry->depth / 100 != last) { plot_depth_sample(entry, &deep); - last = entry->depth; + last = entry->depth / 100; } - if ((entry == entry->min[2]) && entry->depth != last) { + if ((entry == entry->min[2]) && entry->depth / 100 != last) { plot_depth_sample(entry, &shallow); - last = entry->depth; + last = entry->depth / 100; } if (entry->depth != last) @@ -639,7 +639,7 @@ void ProfileGraphicsView::plot_depth_sample(struct plot_data *entry,text_render_ d = get_depth_units(entry->depth, &decimals, NULL); - plot_text(tro, QPointF(sec, entry->depth), QString("%1").arg(d)); // , decimals, d); + plot_text(tro, QPointF(sec, entry->depth), QString("%1").arg(d, 0, 'f', 1)); } @@ -688,7 +688,7 @@ void ProfileGraphicsView::plot_single_temp_text(int sec, int mkelvin) 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, QPointF(sec, mkelvin), QString("%1%2").arg(deg).arg(unit)); //"%.2g%s" + plot_text(&tro, QPointF(sec, mkelvin), QString("%1%2").arg(deg, 0, 'f', 1).arg(unit)); //"%.2g%s" } void ProfileGraphicsView::plot_cylinder_pressure(struct dive *dive, struct divecomputer *dc) @@ -1112,7 +1112,7 @@ QGraphicsSimpleTextItem *ProfileGraphicsView::plot_text(text_render_options_t *t QGraphicsSimpleTextItem *item = new QGraphicsSimpleTextItem(text, parent); QPointF point(SCALEGC(pos.x(), pos.y())); // This is neded because of the SCALE macro. - item->setPos(point.x() + dx, point.y() +dy); + item->setPos(point.x() + dx, point.y() + dy); item->setBrush(QBrush(profile_color[tro->color].first())); item->setFlag(QGraphicsItem::ItemIgnoresTransformations); -- cgit v1.2.3-70-g09d2 From d62d1124cfed290a8f9c0cc8d5c4a83de5308e84 Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sat, 11 May 2013 22:52:02 -0700 Subject: Fix crash if we have no divecomputer information The string we print is lame, but it keeps things consistent (and prevents us from dereferencing functions in uninitialized objects). Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index d606d8260..54b0df8b1 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -311,10 +311,11 @@ void ProfileGraphicsView::plot(struct dive *d) if (nick.isEmpty()) nick = QString(dc->model); - if (!nick.isEmpty()) { - text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, MIDDLE}; - diveComputer = plot_text(&computer, QPointF(gc.leftx, gc.bottomy), nick); - } + if (nick.isEmpty()) + nick = tr("unknown divecomputer"); + + text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, MIDDLE}; + diveComputer = plot_text(&computer, QPointF(gc.leftx, gc.bottomy), nick); // The Time ruler should be right after the DiveComputer: timeMarkers->setPos(0, diveComputer->y()); -- cgit v1.2.3-70-g09d2 From 32941cb84f27ddc4397857afed84bb156f983e4e Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Sat, 11 May 2013 22:56:53 -0700 Subject: Don't print temperatures that are below 200K That threshold is of course ridiculous and arbitrary - but it seems like a good assumption to make that anything below that is DEFINITELY not valid data. Because of the way the scene grows automatically in Qt, printing these texts would squish the profile into one thin line. Signed-off-by: Dirk Hohndel --- qt-ui/profilegraphics.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 54b0df8b1..751d685e5 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -671,15 +671,15 @@ void ProfileGraphicsView::plot_temperature_text() (abs(mkelvin - last_printed_temp) < 400)) continue; last = sec; - - plot_single_temp_text(sec,mkelvin); + if (mkelvin > 200000) + 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)) + if (last_temperature > 200000 && + ((abs(last_temperature - last_printed_temp) > 500) || ((double)last / (double)sec < 0.75))) plot_single_temp_text(sec, last_temperature); } -- cgit v1.2.3-70-g09d2 From 61373eaccf506d022e3c31715b31c2b9432b6f49 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Mon, 13 May 2013 15:28:17 -0300 Subject: Fix segfault on mouseOver at the Profile with an invalid dive selected ( trip ) Signed-off-by: Tomaz Canabrava --- qt-ui/maintab.cpp | 4 ++-- qt-ui/mainwindow.cpp | 5 +++++ qt-ui/mainwindow.h | 2 ++ qt-ui/profilegraphics.cpp | 12 +++++++----- 4 files changed, 16 insertions(+), 7 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp index edacf45a4..a43ae563d 100644 --- a/qt-ui/maintab.cpp +++ b/qt-ui/maintab.cpp @@ -140,8 +140,8 @@ void MainTab::updateDiveInfo(int dive) * 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); +// 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/mainwindow.cpp b/qt-ui/mainwindow.cpp index 3ba4e6881..3766e2187 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -43,6 +43,8 @@ MainWindow::MainWindow() : ui(new Ui::MainWindow()), ui->ListWidget->setCurrentIndex(sortModel->index(0,0, firstDiveOrTrip)); else ui->ListWidget->setCurrentIndex(firstDiveOrTrip); + +#if 0 QAction *actionNextDive = new QAction(this); addAction(actionNextDive); actionNextDive->setShortcut(Qt::Key_Down); @@ -51,6 +53,7 @@ MainWindow::MainWindow() : ui(new Ui::MainWindow()), addAction(actionPreviousDive); actionPreviousDive->setShortcut(Qt::Key_Up); connect(actionPreviousDive, SIGNAL(triggered()), this, SLOT(previousDive_triggered())); +#endif } void MainWindow::redrawProfile() @@ -58,6 +61,7 @@ void MainWindow::redrawProfile() ui->ProfileWidget->plot(get_dive(selected_dive)); } +#if 0 void MainWindow::nextDive_triggered() { // Get the current Selection: @@ -147,6 +151,7 @@ void MainWindow::previousDive_triggered() } } } +#endif void MainWindow::on_actionNew_triggered() { diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h index 8c07d048c..124f70f33 100644 --- a/qt-ui/mainwindow.h +++ b/qt-ui/mainwindow.h @@ -69,9 +69,11 @@ private Q_SLOTS: void on_actionAboutSubsurface_triggered(); void on_actionUserManual_triggered(); +#if 0 /* keyboard actions */ void nextDive_triggered(); void previousDive_triggered(); +#endif void dive_selection_changed(const QItemSelection& newSelection, const QItemSelection& oldSelection); diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 751d685e5..571214f6f 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -214,15 +214,13 @@ void ProfileGraphicsView::plot(struct dive *d) resetTransform(); zoomLevel = 0; dive = d; + toolTip = 0; } - if(!isVisible()){ + if(!isVisible() || !dive){ return; } - if(!dive) - return; - scene()->setSceneRect(0,0, viewport()->width()-50, viewport()->height()-50); QSettings s; @@ -1278,8 +1276,12 @@ void ToolTipItem::collapse() void ToolTipItem::expand() { - QRectF nextRectangle; + if (!title){ + return; + } + + QRectF nextRectangle; double width = 0, height = title->boundingRect().height() + SPACING; Q_FOREACH(ToolTip t, toolTips) { if (t.second->boundingRect().width() > width) -- cgit v1.2.3-70-g09d2 From f9598f062cf8684dd92ac56530c3758e3b1a6d9d Mon Sep 17 00:00:00 2001 From: Henrik Brautaset Aronsen Date: Tue, 14 May 2013 09:28:30 +0200 Subject: Clean up some typos Cosmetic commit to clean up some of the annoying typos in qt-ui Signed-off-by: Henrik Brautaset Aronsen Signed-off-by: Dirk Hohndel --- qt-ui/divelistview.cpp | 6 +++--- qt-ui/maintab.cpp | 4 ++-- qt-ui/models.cpp | 16 ++++++++-------- qt-ui/models.h | 10 +++++----- qt-ui/profilegraphics.cpp | 4 ++-- 5 files changed, 20 insertions(+), 20 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp index a209118e0..d192d84aa 100644 --- a/qt-ui/divelistview.cpp +++ b/qt-ui/divelistview.cpp @@ -61,9 +61,9 @@ void DiveListView::selectionChanged(const QItemSelection& selected, const QItemS Q_FOREACH(const QModelIndex& index, deselected.indexes()) { const QAbstractItemModel *model = index.model(); struct dive *dive = (struct dive*) model->data(index, TreeItemDT::DIVE_ROLE).value(); - if (!dive) { // is's a trip! + if (!dive) { // it's a trip! if (model->rowCount(index)) { - expand(index); // leave this - even if it looks like it shouldn't be here. looks like I'v found a Qt bug. + expand(index); // leave this - even if it looks like it shouldn't be here. looks like I've found a Qt bug. // the subselection is removed, but the painting is not. this cleans the area. } } else if (!parents.contains(index.parent())) { @@ -74,7 +74,7 @@ void DiveListView::selectionChanged(const QItemSelection& selected, const QItemS Q_FOREACH(const QModelIndex& index, selected.indexes()) { const QAbstractItemModel *model = index.model(); struct dive *dive = (struct dive*) model->data(index, TreeItemDT::DIVE_ROLE).value(); - if (!dive) { // is's a trip! + if (!dive) { // it's a trip! if (model->rowCount(index)) { QItemSelection selection; selection.select(index.child(0,0), index.child(model->rowCount(index) -1 , 0)); diff --git a/qt-ui/maintab.cpp b/qt-ui/maintab.cpp index d8a966ae1..70cb3caea 100644 --- a/qt-ui/maintab.cpp +++ b/qt-ui/maintab.cpp @@ -90,7 +90,7 @@ void MainTab::updateDiveInfo(int dive) // it will be called whenever a new dive is selected // I'm already populating the 'notes' box // to show how it can be done. - // If you are unsure what's the name of anything, + // If you are unsure about the name of something, // open the file maintab.ui on the designer // click on the item and check its objectName, // the access is ui->objectName from here on. @@ -136,7 +136,7 @@ void MainTab::updateDiveInfo(int dive) ui->airPressureText->clear(); } /* statisticsTab*/ - /* we can access the stats_selection struct but how to we ensure the relevant dives are selected + /* we can access the stats_selection struct, but how do 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. */ diff --git a/qt-ui/models.cpp b/qt-ui/models.cpp index 68ab402cd..0b933aeb1 100644 --- a/qt-ui/models.cpp +++ b/qt-ui/models.cpp @@ -336,13 +336,13 @@ void TankInfoModel::update() TreeItemDT::~TreeItemDT() { - qDeleteAll(childs); + qDeleteAll(children); } int TreeItemDT::row() const { if (parent) - return parent->childs.indexOf(const_cast(this)); + return parent->children.indexOf(const_cast(this)); return 0; } @@ -637,7 +637,7 @@ const TreeItemDT* parentItem = (!parent.isValid()) ? rootItem : static_cast(parent.internalPointer()); - TreeItemDT* childItem = parentItem->childs[row]; + TreeItemDT* childItem = parentItem->children[row]; return (childItem) ? createIndex(row, column, childItem) : QModelIndex(); } @@ -665,7 +665,7 @@ int DiveTripModel::rowCount(const QModelIndex& parent) const else parentItem = static_cast(parent.internalPointer()); - int amount = parentItem->childs.count(); + int amount = parentItem->children.count(); return amount; } @@ -684,19 +684,19 @@ void DiveTripModel::setupModelData() if (!trip) { diveItem->parent = rootItem; - rootItem->childs.push_back(diveItem); + rootItem->children.push_back(diveItem); continue; } if (!trips.keys().contains(trip)) { TripItem* tripItem = new TripItem(); tripItem->trip = trip; tripItem->parent = rootItem; - tripItem->childs.push_back(diveItem); + tripItem->children.push_back(diveItem); trips[trip] = tripItem; - rootItem->childs.push_back(tripItem); + rootItem->children.push_back(tripItem); continue; } TripItem* tripItem = trips[trip]; - tripItem->childs.push_back(diveItem); + tripItem->children.push_back(diveItem); } } diff --git a/qt-ui/models.h b/qt-ui/models.h index 307cdf5c3..ac533fd71 100644 --- a/qt-ui/models.h +++ b/qt-ui/models.h @@ -14,7 +14,7 @@ #include "../divelist.h" /* Encapsulates the tank_info global variable - * to show on Qt`s Model View System.*/ + * to show on Qt's Model View System.*/ class TankInfoModel : public QAbstractTableModel { Q_OBJECT public: @@ -50,9 +50,9 @@ public: void clear(); void update(); private: - /* Since the dive doesn`t stores the number of cylinders that - * it has ( max 8 ) and since I don`t want to make a - * model-for-each-dive, let`s hack this here instead. */ + /* Since the dive doesn't stores the number of cylinders that + * it has (max 8) and since I don't want to make a + * model-for-each-dive, let's hack this here instead. */ QMap usedRows; }; @@ -94,7 +94,7 @@ public: virtual QVariant data ( int column, int role ) const; int row() const; - QList childs; + QList children; TreeItemDT *parent; }; diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 571214f6f..8f25f1932 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -663,7 +663,7 @@ void ProfileGraphicsView::plot_temperature_text() /* 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 */ + * 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)) @@ -806,7 +806,7 @@ void ProfileGraphicsView::plot_one_event(struct event *ev) int i, depth = 0; struct plot_info *pi = &gc.pi; - /* is plotting this event disabled? */ + /* is plotting of this event disabled? */ if (ev->name) { for (i = 0; i < evn_used; i++) { if (! strcmp(ev->name, ev_namelist[i].ev_name)) { -- cgit v1.2.3-70-g09d2 From e3cb36498d97750a9a961be21f5adb9073fa6863 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 16 May 2013 15:43:38 -0300 Subject: Fixed the loading of some maps On some maps, the lack of setting up the dc before plotting the dive-computer nick caused a division by zero, breaking the correct visualization of the dive. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 8f25f1932..e5212be1e 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -312,6 +312,9 @@ void ProfileGraphicsView::plot(struct dive *d) if (nick.isEmpty()) nick = tr("unknown divecomputer"); + gc.leftx = 0; gc.rightx = 1.0; + gc.topy = 0; gc.bottomy = 1.0; + text_render_options_t computer = {DC_TEXT_SIZE, TIME_TEXT, LEFT, MIDDLE}; diveComputer = plot_text(&computer, QPointF(gc.leftx, gc.bottomy), nick); // The Time ruler should be right after the DiveComputer: -- cgit v1.2.3-70-g09d2 From d39b1aedcd9dedecfca54c91661a81406b80c6ec Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 16 May 2013 16:00:33 -0300 Subject: Fix loading a second dive, after the first file was loaded. This patch fixes loading a second dive-file after the first one had been loaded. it simply clears some information and makes sure that the current selected dive is invalid when the file closes. I also did a bit of code cleanup on this one to make things simpler in the future. Signed-off-by: Tomaz Canabrava Signed-off-by: Dirk Hohndel --- qt-ui/divelistview.cpp | 19 +++++++++++++++++++ qt-ui/divelistview.h | 2 ++ qt-ui/mainwindow.cpp | 33 +++++++-------------------------- qt-ui/mainwindow.h | 2 -- qt-ui/profilegraphics.cpp | 19 ++++++++++++------- qt-ui/profilegraphics.h | 1 + 6 files changed, 41 insertions(+), 35 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/divelistview.cpp b/qt-ui/divelistview.cpp index d2354d910..bed0599b0 100644 --- a/qt-ui/divelistview.cpp +++ b/qt-ui/divelistview.cpp @@ -11,12 +11,31 @@ #include #include #include +#include DiveListView::DiveListView(QWidget *parent) : QTreeView(parent), mouseClickSelection(false) { setUniformRowHeights(true); setItemDelegateForColumn(TreeItemDT::RATING, new StarWidgetsDelegate()); + QSortFilterProxyModel *model = new QSortFilterProxyModel(this); + setModel(model); +} + +void DiveListView::reload() +{ + QSortFilterProxyModel *m = qobject_cast(model()); + QAbstractItemModel *oldModel = m->sourceModel(); + oldModel->deleteLater(); + m->setSourceModel(new DiveTripModel(this)); + sortByColumn(0, Qt::DescendingOrder); + QModelIndex firstDiveOrTrip = m->index(0,0); + if (firstDiveOrTrip.isValid()){ + if (m->index(0,0, firstDiveOrTrip).isValid()) + setCurrentIndex(m->index(0,0, firstDiveOrTrip)); + else + setCurrentIndex(firstDiveOrTrip); + } } void DiveListView::setModel(QAbstractItemModel* model) diff --git a/qt-ui/divelistview.h b/qt-ui/divelistview.h index ce6238d25..09830b7b5 100644 --- a/qt-ui/divelistview.h +++ b/qt-ui/divelistview.h @@ -29,6 +29,8 @@ public: void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent*); void setSelection(const QRect& rect, QItemSelectionModel::SelectionFlags command); + void reload(); + Q_SIGNALS: void currentDiveChanged(int divenr); private: diff --git a/qt-ui/mainwindow.cpp b/qt-ui/mainwindow.cpp index d676549d1..e555473ca 100644 --- a/qt-ui/mainwindow.cpp +++ b/qt-ui/mainwindow.cpp @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -27,24 +26,14 @@ #include "modeldelegates.h" #include "models.h" -MainWindow::MainWindow() : ui(new Ui::MainWindow()), - model(new DiveTripModel(this)), - sortModel(new QSortFilterProxyModel()) +MainWindow::MainWindow() : ui(new Ui::MainWindow()) { ui->setupUi(this); readSettings(); - sortModel->setSourceModel(model); - ui->ListWidget->setModel(sortModel); setWindowIcon(QIcon(":subsurface-icon")); connect(ui->ListWidget, SIGNAL(currentDiveChanged(int)), this, SLOT(current_dive_changed(int))); ui->ProfileWidget->setFocusProxy(ui->ListWidget); - - QModelIndex firstDiveOrTrip = sortModel->index(0,0); - if (sortModel->index(0,0, firstDiveOrTrip).isValid()) - ui->ListWidget->setCurrentIndex(sortModel->index(0,0, firstDiveOrTrip)); - else - ui->ListWidget->setCurrentIndex(firstDiveOrTrip); - + ui->ListWidget->reload(); ui->ListWidget->setFocus(); } @@ -89,16 +78,7 @@ void MainWindow::on_actionOpen_triggered() ui->InfoWidget->reload(); - model->deleteLater(); - model = new DiveTripModel(this); - sortModel->setSourceModel(model); - ui->ListWidget->sortByColumn(0, Qt::DescendingOrder); - - QModelIndex firstDiveOrTrip = sortModel->index(0,0); - if (sortModel->index(0,0, firstDiveOrTrip).isValid()) - ui->ListWidget->setCurrentIndex(sortModel->index(0,0, firstDiveOrTrip)); - else - ui->ListWidget->setCurrentIndex(firstDiveOrTrip); + ui->ListWidget->reload(); ui->ListWidget->setFocus(); } @@ -120,8 +100,6 @@ void MainWindow::on_actionClose_triggered() while (dive_table.nr) delete_single_dive(0); - mark_divelist_changed(FALSE); - /* clear the selection and the statistics */ selected_dive = -1; @@ -131,6 +109,8 @@ void MainWindow::on_actionClose_triggered() ui->InfoWidget->clearStats(); ui->InfoWidget->clearInfo(); ui->InfoWidget->clearEquipment(); + ui->ProfileWidget->clear(); + ui->ListWidget->reload(); clear_events(); #if USE_GTK_UI @@ -349,7 +329,8 @@ void MainWindow::readSettings() ui->ListWidget->resizeColumnToContents(i); } ui->ListWidget->collapseAll(); - ui->ListWidget->scrollTo(sortModel->index(0,0), QAbstractItemView::PositionAtCenter); + ui->ListWidget->scrollTo(ui->ListWidget->model()->index(0,0), QAbstractItemView::PositionAtCenter); + settings.endGroup(); settings.beginGroup("Units"); GET_UNIT(v, "feet", length, units::METERS, units::FEET); diff --git a/qt-ui/mainwindow.h b/qt-ui/mainwindow.h index 04392ada9..60f0d4609 100644 --- a/qt-ui/mainwindow.h +++ b/qt-ui/mainwindow.h @@ -76,8 +76,6 @@ protected: private: Ui::MainWindow *ui; - DiveTripModel *model; - QSortFilterProxyModel *sortModel; QAction *actionNextDive; QAction *actionPreviousDive; diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index e5212be1e..8ab4aa845 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -206,16 +206,21 @@ void ProfileGraphicsView::showEvent(QShowEvent* event) plot(dive); } +void ProfileGraphicsView::clear() +{ + scene()->clear(); + resetTransform(); + zoomLevel = 0; + toolTip = 0; +} + void ProfileGraphicsView::plot(struct dive *d) { + if (dive == d) + return; - scene()->clear(); - if (dive != d){ - resetTransform(); - zoomLevel = 0; - dive = d; - toolTip = 0; - } + clear(); + dive = d; if(!isVisible() || !dive){ return; diff --git a/qt-ui/profilegraphics.h b/qt-ui/profilegraphics.h index 7cf88cbc3..453b8cf03 100644 --- a/qt-ui/profilegraphics.h +++ b/qt-ui/profilegraphics.h @@ -64,6 +64,7 @@ public: ProfileGraphicsView(QWidget* parent = 0); void plot(struct dive *d); bool eventFilter(QObject* obj, QEvent* event); + void clear(); protected: void resizeEvent(QResizeEvent *event); -- cgit v1.2.3-70-g09d2 From 2f35c940261fe0f5fdb2723072553c036492e608 Mon Sep 17 00:00:00 2001 From: Tomaz Canabrava Date: Thu, 16 May 2013 21:25:31 -0300 Subject: Fix loading a dive via command line. Signed-off-by: Tomaz Canabrava --- qt-ui/profilegraphics.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'qt-ui/profilegraphics.cpp') diff --git a/qt-ui/profilegraphics.cpp b/qt-ui/profilegraphics.cpp index 8ab4aa845..637c7fe95 100644 --- a/qt-ui/profilegraphics.cpp +++ b/qt-ui/profilegraphics.cpp @@ -202,8 +202,14 @@ static void plot_set_scale(scale_mode_t scale) void ProfileGraphicsView::showEvent(QShowEvent* event) { - if (dive) - plot(dive); + // Program just opened, + // but the dive was not ploted. + // force a replot by modifying the dive + // hold by the view, and issuing a plot. + if (dive){ + dive = 0; + plot(get_dive(selected_dive)); + } } void ProfileGraphicsView::clear() -- cgit v1.2.3-70-g09d2