mirror of
				https://github.com/subsurface/subsurface.git
				synced 2025-02-19 22:16:15 +00:00 
			
		
		
		
	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 <tcanabrava@kde.org>
This commit is contained in:
		
							parent
							
								
									c74dc11167
								
							
						
					
					
						commit
						1b1ea35fac
					
				
					 4 changed files with 247 additions and 216 deletions
				
			
		
							
								
								
									
										204
									
								
								profile.c
									
										
									
									
									
								
							
							
						
						
									
										204
									
								
								profile.c
									
										
									
									
									
								
							| 
						 | 
					@ -58,11 +58,6 @@ struct plot_data {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if USE_GTK_UI
 | 
					#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
 | 
					/* keep the last used gc around so we can invert the SCALEX calculation in
 | 
				
			||||||
 * order to calculate a time value for an x coordinate */
 | 
					 * order to calculate a time value for an x coordinate */
 | 
				
			||||||
static struct graphics_context last_gc;
 | 
					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)
 | 
					static int setup_temperature_limits(struct graphics_context *gc, struct plot_info *pi)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								profile.h
									
										
									
									
									
								
							
							
						
						
									
										15
									
								
								profile.h
									
										
									
									
									
								
							| 
						 | 
					@ -19,6 +19,21 @@ struct plot_info;
 | 
				
			||||||
void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc);
 | 
					void calculate_max_limits(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc);
 | 
				
			||||||
struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc);
 | 
					struct plot_info *create_plot_info(struct dive *dive, struct divecomputer *dc, struct graphics_context *gc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * 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
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,7 +2,9 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <QGraphicsScene>
 | 
					#include <QGraphicsScene>
 | 
				
			||||||
#include <QResizeEvent>
 | 
					#include <QResizeEvent>
 | 
				
			||||||
 | 
					#include <QGraphicsLineItem>
 | 
				
			||||||
 | 
					#include <QPen>
 | 
				
			||||||
 | 
					#include <QBrush>
 | 
				
			||||||
#include <QDebug>
 | 
					#include <QDebug>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "../color.h"
 | 
					#include "../color.h"
 | 
				
			||||||
| 
						 | 
					@ -15,6 +17,12 @@
 | 
				
			||||||
#define VELOCITY_COLORS_START_IDX VELO_STABLE
 | 
					#define VELOCITY_COLORS_START_IDX VELO_STABLE
 | 
				
			||||||
#define VELOCITY_COLORS 5
 | 
					#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;
 | 
					static double plot_scale = SCALE_SCREEN;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
| 
						 | 
					@ -93,6 +101,7 @@ void fill_profile_color()
 | 
				
			||||||
ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent)
 | 
					ProfileGraphicsView::ProfileGraphicsView(QWidget* parent) : QGraphicsView(parent)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	setScene(new QGraphicsScene());
 | 
						setScene(new QGraphicsScene());
 | 
				
			||||||
 | 
						setBackgroundBrush(QColor("#F3F3E6"));
 | 
				
			||||||
	scene()->setSceneRect(0,0,100,100);
 | 
						scene()->setSceneRect(0,0,100,100);
 | 
				
			||||||
	fill_profile_color();
 | 
						fill_profile_color();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -112,6 +121,13 @@ static void plot_set_scale(scale_mode_t scale)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ProfileGraphicsView::plot(struct dive *dive)
 | 
					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 plot_info *pi;
 | 
				
			||||||
	struct divecomputer *dc = &dive->dc;
 | 
						struct divecomputer *dc = &dive->dc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -151,13 +167,6 @@ void ProfileGraphicsView::plot(struct dive *dive)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	calculate_max_limits(dive, dc, &gc);
 | 
						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
 | 
						 * We don't use "cairo_translate()" because that doesn't
 | 
				
			||||||
	 * scale line width etc. But the actual scaling we need
 | 
						 * scale line width etc. But the actual scaling we need
 | 
				
			||||||
| 
						 | 
					@ -165,16 +174,18 @@ void ProfileGraphicsView::plot(struct dive *dive)
 | 
				
			||||||
	 *
 | 
						 *
 | 
				
			||||||
	 * Snif. What a pity.
 | 
						 * Snif. What a pity.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	gc->maxx = (drawing_area->width - 2*drawing_area->x);
 | 
						QRectF drawing_area = scene()->sceneRect();
 | 
				
			||||||
	gc->maxy = (drawing_area->height - 2*drawing_area->y);
 | 
						gc.maxx = (drawing_area.width() - 2*drawing_area.x());
 | 
				
			||||||
 | 
						gc.maxy = (drawing_area.height() - 2*drawing_area.y());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dc = select_dc(dc);
 | 
						dc = select_dc(dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* This is per-dive-computer. Right now we just do the first one */
 | 
						/* 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 */
 | 
						/* Depth profile */
 | 
				
			||||||
	plot_depth_profile(gc, pi);
 | 
						plot_depth_profile(&gc, pi);
 | 
				
			||||||
 | 
					#if 0
 | 
				
			||||||
	plot_events(gc, pi, dc);
 | 
						plot_events(gc, pi, dc);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Temperature profile */
 | 
						/* Temperature profile */
 | 
				
			||||||
| 
						 | 
					@ -233,6 +244,213 @@ void ProfileGraphicsView::plot(struct dive *dive)
 | 
				
			||||||
#endif
 | 
					#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)
 | 
					void ProfileGraphicsView::resizeEvent(QResizeEvent *event)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	// Fits the scene's rectangle on the view.
 | 
						// Fits the scene's rectangle on the view.
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -12,6 +12,8 @@ public:
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
	void resizeEvent(QResizeEvent *event);
 | 
						void resizeEvent(QResizeEvent *event);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						void plot_depth_profile(struct graphics_context *gc, struct plot_info *pi);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue