mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-05 10:40:42 +00:00
Warning: Mega Graphing system overhaul.. not finished yet
This commit is contained in:
parent
4e7ccde8e3
commit
439720c2e3
@ -8,6 +8,7 @@
|
||||
#include <QVector>
|
||||
#include "SleepLib/profiles.h"
|
||||
#include "gFlagsLine.h"
|
||||
#include "gYAxis.h"
|
||||
|
||||
gFlagsGroup::gFlagsGroup()
|
||||
{
|
||||
@ -30,15 +31,10 @@ qint64 gFlagsGroup::Maxx()
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gFlagsGroup::Plot(gGraphWindow &w, float scrx, float scry)
|
||||
void gFlagsGroup::paint(gGraph &w, int left, int top, int width, int height)
|
||||
{
|
||||
if (!m_visible) return;
|
||||
//if (!m_day) return;
|
||||
int start_px=w.GetLeftMargin();
|
||||
int start_py=w.GetBottomMargin();
|
||||
int width=scrx-(w.GetLeftMargin()+w.GetRightMargin())-1;
|
||||
int height=scry-(w.GetTopMargin()+w.GetBottomMargin());
|
||||
|
||||
|
||||
QVector<gFlagsLine *> lvisible;
|
||||
for (int i=0;i<layers.size();i++) {
|
||||
@ -50,31 +46,56 @@ void gFlagsGroup::Plot(gGraphWindow &w, float scrx, float scry)
|
||||
}
|
||||
}
|
||||
int vis=lvisible.size();
|
||||
float barh=float(height)/float(vis);
|
||||
float linetop=top;
|
||||
|
||||
static QColor col1=QColor(0xd0,0xff,0xd0,0xff);
|
||||
static QColor col2=QColor(0xff,0xff,0xff,0xff);
|
||||
|
||||
for (int i=0;i<lvisible.size();i++) {
|
||||
lvisible[i]->line_num=i;
|
||||
lvisible[i]->total_lines=vis;
|
||||
lvisible[i]->Plot(w,scrx,scry);
|
||||
// Alternating box color
|
||||
QColor * barcol=&col2;
|
||||
if (i & 1)
|
||||
barcol=&col1;
|
||||
|
||||
//int qo=0;
|
||||
//if (evil_intel_graphics_card) qo=1;
|
||||
|
||||
// Draw the bars with filled quads
|
||||
w.qglColor(*barcol);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(left, linetop);
|
||||
glVertex2f(left, linetop+barh);
|
||||
glVertex2f(left+width-1, linetop+barh);
|
||||
glVertex2f(left+width-1, linetop);
|
||||
glEnd();
|
||||
|
||||
// Paint the actual flags
|
||||
lvisible[i]->paint(w,left,linetop,width,barh);
|
||||
linetop+=barh;
|
||||
}
|
||||
|
||||
// Draw the outer rectangle outline
|
||||
glColor3f (0.0F, 0.0F, 0.0F);
|
||||
glLineWidth (1);
|
||||
glBegin (GL_LINE_LOOP);
|
||||
glVertex2f (start_px-1, start_py);
|
||||
glVertex2f (start_px-1, start_py+height);
|
||||
glVertex2f (start_px+width,start_py+height);
|
||||
glVertex2f (start_px+width, start_py);
|
||||
glVertex2f (left-1, top);
|
||||
glVertex2f (left-1, top+height);
|
||||
glVertex2f (left+width, top+height);
|
||||
glVertex2f (left+width, top);
|
||||
glEnd ();
|
||||
|
||||
}
|
||||
|
||||
|
||||
gFlagsLine::gFlagsLine(ChannelID code,QColor flag_color,QString label,bool always_visible,FlagType flt)
|
||||
:gLayer(code),m_label(label),m_always_visible(always_visible),m_flt(flt),m_flag_color(flag_color)
|
||||
:Layer(code),m_label(label),m_always_visible(always_visible),m_flt(flt),m_flag_color(flag_color)
|
||||
{
|
||||
}
|
||||
gFlagsLine::~gFlagsLine()
|
||||
{
|
||||
}
|
||||
void gFlagsLine::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
void gFlagsLine::paint(gGraph & w,int left, int top, int width, int height)
|
||||
{
|
||||
if (!m_visible) return;
|
||||
if (!m_day) return;
|
||||
@ -82,7 +103,7 @@ void gFlagsLine::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
double minx;
|
||||
double maxx;
|
||||
|
||||
if (w.BlockZoom()) {
|
||||
if (w.blockZoom()) {
|
||||
minx=w.rmin_x;
|
||||
maxx=w.rmax_x;
|
||||
} else {
|
||||
@ -93,38 +114,8 @@ void gFlagsLine::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
double xx=maxx-minx;
|
||||
if (xx<=0) return;
|
||||
|
||||
int start_px=w.GetLeftMargin();
|
||||
int start_py=w.GetBottomMargin();
|
||||
int width=scrx-(w.GetLeftMargin()+w.GetRightMargin())-1;
|
||||
int height=scry-(w.GetTopMargin()+w.GetBottomMargin());
|
||||
|
||||
double xmult=width/xx;
|
||||
|
||||
static QColor col1=QColor(0xd0,0xff,0xd0,0xff);
|
||||
static QColor col2=QColor(0xff,0xff,0xff,0xff);
|
||||
|
||||
|
||||
float line_h=float(height-2)/float(total_lines);
|
||||
line_h=line_h;
|
||||
float line_top=(start_py+height-line_h)-line_num*line_h;
|
||||
|
||||
// Alternating box color
|
||||
QColor * barcol=&col2;
|
||||
if (line_num & 1)
|
||||
barcol=&col1;
|
||||
|
||||
int qo=0;
|
||||
//if (evil_intel_graphics_card) qo=1;
|
||||
|
||||
// Filled rectangle
|
||||
w.qglColor(*barcol);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2f(start_px+qo, line_top);
|
||||
glVertex2f(start_px+qo, line_top+line_h);
|
||||
glVertex2f(start_px+width-1, line_top+line_h);
|
||||
glVertex2f(start_px+width-1, line_top);
|
||||
glEnd();
|
||||
|
||||
qint32 vertcnt=0;
|
||||
GLshort * vertarray=vertex_array[0];
|
||||
qint32 quadcnt=0;
|
||||
@ -137,13 +128,14 @@ void gFlagsLine::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
// Draw text label
|
||||
float x,y;
|
||||
GetTextExtent(m_label,x,y);
|
||||
//w.qglColor(Qt::black);
|
||||
w.qglColor(Qt::black);
|
||||
//w.renderText(start_px-x-10,(scry-line_top)-(line_h/2)+(y/2),m_label);
|
||||
DrawText(w,m_label,start_px-x-10,(scry-line_top)-(line_h/2)+(y/2));
|
||||
//DrawText(w,m_label);
|
||||
w.renderText(m_label,left-x-10,top+(height/2)+(y/2));
|
||||
float x1,x2;
|
||||
|
||||
float top=floor(line_top)+2;
|
||||
float bottom=top+floor(line_h)-3;
|
||||
float bartop=top+2;
|
||||
float bottom=top+height-2;
|
||||
bool verts_exceeded=false;
|
||||
qint64 X,Y;
|
||||
for (QVector<Session *>::iterator s=m_day->begin();s!=m_day->end(); s++) {
|
||||
@ -156,24 +148,24 @@ void gFlagsLine::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
Y=X-(el.data(i)*1000);
|
||||
if (Y < minx) continue;
|
||||
if (X > maxx) break;
|
||||
x1=(X - minx) * xmult + w.GetLeftMargin();
|
||||
x1=(X - minx) * xmult + left;
|
||||
if (m_flt==FT_Bar) {
|
||||
vertarray[vertcnt++]=x1;
|
||||
vertarray[vertcnt++]=top;
|
||||
vertarray[vertcnt++]=bartop;
|
||||
vertarray[vertcnt++]=x1;
|
||||
vertarray[vertcnt++]=bottom;
|
||||
if (vertcnt>maxverts) { verts_exceeded=true; break; }
|
||||
} else if (m_flt==FT_Span) {
|
||||
x2=(Y-minx)*xmult+w.GetLeftMargin();
|
||||
x2=(Y-minx)*xmult+left;
|
||||
//w1=x2-x1;
|
||||
quadarray[quadcnt++]=x1;
|
||||
quadarray[quadcnt++]=top;
|
||||
quadarray[quadcnt++]=bartop;
|
||||
quadarray[quadcnt++]=x1;
|
||||
quadarray[quadcnt++]=bottom;
|
||||
quadarray[quadcnt++]=x2;
|
||||
quadarray[quadcnt++]=bottom;
|
||||
quadarray[quadcnt++]=x2;
|
||||
quadarray[quadcnt++]=top;
|
||||
quadarray[quadcnt++]=bartop;
|
||||
if (quadcnt>maxverts) { verts_exceeded=true; break; }
|
||||
}
|
||||
}
|
||||
@ -181,8 +173,8 @@ void gFlagsLine::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
if (verts_exceeded) {
|
||||
qWarning() << "maxverts exceeded in gFlagsLine::plot()";
|
||||
}
|
||||
glScissor(w.GetLeftMargin(),w.GetBottomMargin(),width,height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
// glScissor(left,top,width,height);
|
||||
//glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
bool antialias=pref["UseAntiAliasing"].toBool();
|
||||
if (antialias) {
|
||||
@ -209,5 +201,5 @@ void gFlagsLine::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
//glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
@ -1,24 +1,24 @@
|
||||
/********************************************************************
|
||||
/*
|
||||
gFlagsLine Header
|
||||
Copyright (c)2011 Mark Watkins <jedimark@users.sourceforge.net>
|
||||
License: GPL
|
||||
*********************************************************************/
|
||||
*/
|
||||
|
||||
#ifndef GFLAGSLINE_H
|
||||
#define GFLAGSLINE_H
|
||||
|
||||
#include "graphlayer.h"
|
||||
#include "gGraphView.h"
|
||||
|
||||
class gFlagsGroup;
|
||||
|
||||
class gFlagsLine:public gLayer
|
||||
class gFlagsLine:public Layer
|
||||
{
|
||||
friend class gFlagsGroup;
|
||||
public:
|
||||
gFlagsLine(ChannelID code,QColor col=Qt::black,QString label="",bool always_visible=false,FlagType flt=FT_Bar);
|
||||
virtual ~gFlagsLine();
|
||||
|
||||
virtual void Plot(gGraphWindow & w,float scrx,float scry);
|
||||
virtual void paint(gGraph & w,int left, int top, int width, int height);
|
||||
bool isAlwaysVisible() { return m_always_visible; }
|
||||
void setAlwaysVisible(bool b) { m_always_visible=b; }
|
||||
QString label() { return m_label; }
|
||||
@ -33,16 +33,15 @@ class gFlagsLine:public gLayer
|
||||
QColor m_flag_color;
|
||||
};
|
||||
|
||||
class gFlagsGroup:public gLayerGroup
|
||||
class gFlagsGroup:public LayerGroup
|
||||
{
|
||||
public:
|
||||
gFlagsGroup();
|
||||
virtual ~gFlagsGroup();
|
||||
|
||||
virtual void Plot(gGraphWindow &w, float scrx, float scry);
|
||||
virtual void paint(gGraph & w,int left, int top, int width, int height);
|
||||
virtual qint64 Minx();
|
||||
virtual qint64 Maxx();
|
||||
|
||||
};
|
||||
|
||||
#endif // GFLAGSLINE_H
|
||||
|
978
Graphs/gGraphView.cpp
Normal file
978
Graphs/gGraphView.cpp
Normal file
@ -0,0 +1,978 @@
|
||||
#include <cmath>
|
||||
#include "gGraphView.h"
|
||||
|
||||
Layer::Layer(ChannelID code)
|
||||
{
|
||||
m_code = code;
|
||||
m_visible = true;
|
||||
m_movable = false;
|
||||
|
||||
m_day=NULL;
|
||||
m_miny=m_maxy=0;
|
||||
m_minx=m_maxx=0;
|
||||
m_order=0;
|
||||
m_width=m_height=0;
|
||||
m_X=m_Y=0;
|
||||
m_position=LayerCenter;
|
||||
}
|
||||
|
||||
Layer::~Layer()
|
||||
{
|
||||
}
|
||||
|
||||
void Layer::SetDay(Day * d)
|
||||
{
|
||||
m_day=d;
|
||||
if (!d) return;
|
||||
|
||||
m_minx=d->first(m_code);
|
||||
m_maxx=d->last(m_code);
|
||||
m_miny=d->min(m_code);
|
||||
m_maxy=d->max(m_code);
|
||||
}
|
||||
|
||||
bool Layer::isEmpty()
|
||||
{
|
||||
if (m_day && (m_day->count(m_code)!=0))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
void Layer::setLayout(LayerPosition position, short width, short height, short order)
|
||||
{
|
||||
m_position=position;
|
||||
m_width=width;
|
||||
m_height=height;
|
||||
m_order=order;
|
||||
}
|
||||
|
||||
LayerGroup::LayerGroup() :
|
||||
Layer(EmptyChannel)
|
||||
{
|
||||
}
|
||||
LayerGroup::~LayerGroup()
|
||||
{
|
||||
}
|
||||
bool LayerGroup::isEmpty()
|
||||
{
|
||||
if (!m_day)
|
||||
return true;
|
||||
bool empty=true;
|
||||
for (int i=0;i<layers.size();i++) {
|
||||
if (layers[i]->isEmpty()) {
|
||||
empty=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return empty;
|
||||
}
|
||||
void LayerGroup::SetDay(Day * d)
|
||||
{
|
||||
for (int i=0;i<layers.size();i++) {
|
||||
layers[i]->SetDay(d);
|
||||
}
|
||||
m_day=d;
|
||||
}
|
||||
|
||||
void LayerGroup::AddLayer(Layer *l)
|
||||
{
|
||||
layers.push_back(l);
|
||||
}
|
||||
|
||||
qint64 LayerGroup::Minx()
|
||||
{
|
||||
bool first=true;
|
||||
qint64 m=0,t;
|
||||
for (int i=0;i<layers.size();i++) {
|
||||
t=layers[i]->Minx();
|
||||
if (!t) continue;
|
||||
if (first) {
|
||||
m=t;
|
||||
first=false;
|
||||
} else
|
||||
if (m>t) m=t;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
qint64 LayerGroup::Maxx()
|
||||
{
|
||||
bool first=true;
|
||||
qint64 m=0,t;
|
||||
for (int i=0;i<layers.size();i++) {
|
||||
t=layers[i]->Maxx();
|
||||
if (!t) continue;
|
||||
if (first) {
|
||||
m=t;
|
||||
first=false;
|
||||
} else
|
||||
if (m<t) m=t;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
EventDataType LayerGroup::Miny()
|
||||
{
|
||||
bool first=true;
|
||||
EventDataType m=0,t;
|
||||
for (int i=0;i<layers.size();i++) {
|
||||
t=layers[i]->Miny();
|
||||
if (t==layers[i]->Minx()) continue;
|
||||
if (first) {
|
||||
m=t;
|
||||
first=false;
|
||||
} else {
|
||||
if (m>t) m=t;
|
||||
}
|
||||
}
|
||||
return m;
|
||||
}
|
||||
EventDataType LayerGroup::Maxy()
|
||||
{
|
||||
bool first=true;
|
||||
EventDataType m=0,t;
|
||||
for (int i=0;i<layers.size();i++) {
|
||||
t=layers[i]->Maxy();
|
||||
if (t==layers[i]->Miny()) continue;
|
||||
if (first) {
|
||||
m=t;
|
||||
first=false;
|
||||
} else
|
||||
if (m<t) m=t;
|
||||
}
|
||||
return m;
|
||||
}
|
||||
|
||||
|
||||
|
||||
gGraph::gGraph(gGraphView *graphview,QString title,int height) :
|
||||
m_graphview(graphview),
|
||||
m_title(title),
|
||||
m_height(height),
|
||||
m_visible(true)
|
||||
{
|
||||
m_min_height=50;
|
||||
m_layers.clear();
|
||||
if (graphview) {
|
||||
graphview->AddGraph(this);
|
||||
} else {
|
||||
qWarning() << "gGraph created without a gGraphView container.. Naughty programmer!! Bad!!!";
|
||||
}
|
||||
m_margintop=10;
|
||||
m_marginbottom=10;
|
||||
m_marginleft=5;
|
||||
m_marginright=10;
|
||||
}
|
||||
gGraph::~gGraph()
|
||||
{
|
||||
}
|
||||
bool gGraph::isEmpty()
|
||||
{
|
||||
bool empty=true;
|
||||
for (QVector<Layer *>::iterator l=m_layers.begin();l!=m_layers.end();l++) {
|
||||
if (!(*l)->isEmpty()) {
|
||||
empty=false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return empty;
|
||||
}
|
||||
|
||||
void gGraph::invalidate()
|
||||
{ // this may not be necessary, as scrollbar & resize issues a full redraw..
|
||||
|
||||
//m_lastbounds.setWidth(m_graphview->width());
|
||||
m_lastbounds.setY(m_graphview->findTop(this));
|
||||
m_lastbounds.setX(gGraphView::titleWidth);
|
||||
m_lastbounds.setHeight(m_height * m_graphview->scaleY());
|
||||
m_lastbounds.setWidth(m_graphview->width()-gGraphView::titleWidth);
|
||||
int i=0;
|
||||
//m_lastbounds.setHeight(0);
|
||||
}
|
||||
|
||||
void gGraph::repaint()
|
||||
{
|
||||
if (m_lastbounds.height()>0) {
|
||||
//glScissor(0,m_lastbounds.y(),m_lastbounds.width(),m_lastbounds.height());
|
||||
// m_graphview->swapBuffers(); // how fast is this??
|
||||
//glEnable(GL_SCISSOR_BOX);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(1,1,1,1.0); // Gradient End
|
||||
glVertex2i(0,m_lastbounds.y());
|
||||
glVertex2i(gGraphView::titleWidth,m_lastbounds.y());
|
||||
glVertex2i(gGraphView::titleWidth,m_lastbounds.y()+height());
|
||||
glVertex2i(0,m_lastbounds.y()+height());
|
||||
glEnd();
|
||||
|
||||
paint(m_lastbounds.x(),m_lastbounds.y(),m_lastbounds.width(),m_lastbounds.height());
|
||||
m_graphview->swapBuffers();
|
||||
//glDisable(GL_SCISSOR_BOX);
|
||||
} else {
|
||||
qDebug() << "Wanted to redraw graph" << m_title << "but previous bounds were invalid.. Issuing a slower full redraw instead. Todo: Find out why.";
|
||||
m_graphview->updateGL();
|
||||
}
|
||||
}
|
||||
|
||||
void gGraph::qglColor(QColor col)
|
||||
{
|
||||
m_graphview->qglColor(col);
|
||||
}
|
||||
void gGraph::renderText(QString text, int x,int y, float angle, QColor color, QFont *font)
|
||||
{
|
||||
// GL Font drawing is ass in Qt.. :(
|
||||
// I tried queuing this but got crappy memory leaks.. for now I don't give a crap if this is slow.
|
||||
|
||||
QPainter *painter=m_graphview->painter;
|
||||
painter->endNativePainting();
|
||||
QBrush b(color);
|
||||
painter->setBrush(b);
|
||||
painter->setFont(*font);
|
||||
if (angle==0) {
|
||||
painter->drawText(x,y,text);
|
||||
} else {
|
||||
float w,h;
|
||||
GetTextExtent(text, w, h, font);
|
||||
|
||||
painter->translate(x,y);
|
||||
painter->rotate(-angle);
|
||||
painter->drawText(floor(-w/2.0),floor(-h/2.0),text);
|
||||
painter->rotate(+angle);
|
||||
painter->translate(-x,-y);
|
||||
}
|
||||
painter->beginNativePainting();
|
||||
}
|
||||
|
||||
|
||||
void gGraph::paint(int originX, int originY, int width, int height)
|
||||
{
|
||||
m_lastbounds=QRect(originX,originY,width,height);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(1,1,1,1.0); // Gradient End
|
||||
glVertex2i(originX,originY);
|
||||
glVertex2i(originX+width,originY);
|
||||
glColor4f(1,1,1.0,1.0); // Gradient End
|
||||
glVertex2i(originX+width,originY+height);
|
||||
glVertex2i(originX,originY+height);
|
||||
glEnd();
|
||||
glColor4f(0,0,0,1);
|
||||
renderText(title(),20,originY+height/2,90);
|
||||
|
||||
left=0,right=0,top=0,bottom=0;
|
||||
|
||||
int tmp;
|
||||
|
||||
originX+=m_marginleft;
|
||||
originY+=m_margintop;
|
||||
width-=m_marginleft+m_marginright;
|
||||
height-=m_margintop+m_marginbottom;
|
||||
|
||||
for (int i=0;i<m_layers.size();i++) {
|
||||
Layer *ll=m_layers[i];
|
||||
tmp=ll->Height();
|
||||
if (ll->position()==LayerTop) top+=tmp;
|
||||
if (ll->position()==LayerBottom) bottom+=tmp;
|
||||
}
|
||||
|
||||
for (int i=0;i<m_layers.size();i++) {
|
||||
Layer *ll=m_layers[i];
|
||||
tmp=ll->Width();
|
||||
if (ll->position()==LayerLeft) {
|
||||
ll->paint(*this,originX+left,originY+top,tmp,height-top-bottom);
|
||||
left+=tmp;
|
||||
}
|
||||
if (ll->position()==LayerRight) {
|
||||
right+=tmp;
|
||||
ll->paint(*this,originX+width-right,originY+top,tmp,height-top-bottom);
|
||||
}
|
||||
}
|
||||
|
||||
bottom=0; top=0;
|
||||
for (int i=0;i<m_layers.size();i++) {
|
||||
Layer *ll=m_layers[i];
|
||||
tmp=ll->Height();
|
||||
if (ll->position()==LayerTop) {
|
||||
ll->paint(*this,originX+left,originY+top,width-left-right,tmp);
|
||||
top+=tmp;
|
||||
}
|
||||
if (ll->position()==LayerBottom) {
|
||||
bottom+=tmp;
|
||||
ll->paint(*this,originX+left,originY+height-bottom,width-left-right,tmp);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i=0;i<m_layers.size();i++) {
|
||||
Layer *ll=m_layers[i];
|
||||
if (ll->position()==LayerCenter) {
|
||||
ll->paint(*this,originX+left,originY+top,width-left-right,height-top-bottom);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gGraph::AddLayer(Layer * l,LayerPosition position, short width, short height, short order, bool movable, short x, short y)
|
||||
{
|
||||
l->setLayout(position,width,height,order);
|
||||
l->setMovable(movable);
|
||||
l->setPos(x,y);
|
||||
m_layers.push_back(l);
|
||||
}
|
||||
void gGraph::mouseMoveEvent(QMouseEvent * event)
|
||||
{
|
||||
// qDebug() << m_title << "Move" << event->pos() << m_graphview->pointClicked();
|
||||
int y=event->pos().y();
|
||||
int x=event->pos().x();
|
||||
int x2,y2;
|
||||
int w=m_width-(m_graphview->titleWidth+right+m_marginright);
|
||||
int h=m_height-(bottom+m_marginbottom);
|
||||
double xx=max_x-min_x;
|
||||
double xmult=xx/w;
|
||||
if (x>left+m_marginleft && x<m_width-(m_graphview->titleWidth+right+m_marginright) && y>top+m_margintop && y<m_height-(bottom+m_marginbottom)) { // main area
|
||||
x-=left+m_marginleft;
|
||||
y-=top+m_margintop;
|
||||
//qDebug() << m_title << "Moved" << x << y << left << right << top << bottom << m_width << m_height;
|
||||
}
|
||||
}
|
||||
void gGraph::mousePressEvent(QMouseEvent * event)
|
||||
{
|
||||
int y=event->pos().y();
|
||||
int x=event->pos().x();
|
||||
int w=m_width-(m_graphview->titleWidth+right+m_marginright);
|
||||
int h=m_height-(bottom+m_marginbottom);
|
||||
int x2,y2;
|
||||
double xx=max_x-min_x;
|
||||
double xmult=xx/w;
|
||||
if (x>left+m_marginleft && x<m_width-(m_graphview->titleWidth+right+m_marginright) && y>top+m_margintop && y<m_height-(bottom+m_marginbottom)) { // main area
|
||||
x-=left+m_marginleft;
|
||||
y-=top+m_margintop;
|
||||
qDebug() << m_title << "Clicked" << x << y << left << right << top << bottom << m_width << m_height;
|
||||
}
|
||||
}
|
||||
void gGraph::mouseReleaseEvent(QMouseEvent * event)
|
||||
{
|
||||
int y=event->pos().y();
|
||||
int x=event->pos().x();
|
||||
int w=m_width-(m_graphview->titleWidth+m_marginleft+left+right+m_marginright);
|
||||
int h=m_height-(bottom+m_marginbottom);
|
||||
int x2,y2;
|
||||
double xx=max_x-min_x;
|
||||
double xmult=xx/double(w);
|
||||
if (x>left+m_marginleft && x<w+m_marginleft+left && y>top+m_margintop && y<h) { // main area
|
||||
if (event->button() & Qt::RightButton) {
|
||||
// zoom out.
|
||||
} else if (event->button() & Qt::LeftButton) {
|
||||
x-=left+m_marginleft;
|
||||
y-=top+m_margintop;
|
||||
x2=m_graphview->pointClicked().x()-left-m_marginleft;
|
||||
y2=m_graphview->pointClicked().y()-top-m_margintop;
|
||||
qint64 j1=min_x+xmult*x;
|
||||
qint64 j2=min_x+xmult*x2;
|
||||
qint64 a1=MIN(j1,j2)
|
||||
qint64 a2=MAX(j1,j2)
|
||||
m_graphview->SetXBounds(a1,a2);
|
||||
qDebug() << m_title << "Released" << min_x << max_x << j1 << j2 << x << y << x2 << y2 << left << right << top << bottom << m_width << m_height;
|
||||
}
|
||||
// qDebug() << m_title << "Released" << event->pos() << m_graphview->pointClicked() << left << top;
|
||||
}
|
||||
}
|
||||
void gGraph::mouseWheelEvent(QMouseEvent * event)
|
||||
{
|
||||
qDebug() << m_title << "Wheel" << event->x() << event->y();
|
||||
}
|
||||
void gGraph::mouseDoubleClickEvent(QMouseEvent * event)
|
||||
{
|
||||
// qDebug() << m_title << "Double Clicked" << event->x() << event->y();
|
||||
}
|
||||
void gGraph::keyPressEvent(QKeyEvent * event)
|
||||
{
|
||||
qDebug() << m_title << "Key Pressed" << event->key();
|
||||
}
|
||||
|
||||
// margin recalcs..
|
||||
void gGraph::resize(int width, int height)
|
||||
{
|
||||
m_height=height;
|
||||
m_width=width;
|
||||
}
|
||||
|
||||
qint64 gGraph::MinX()
|
||||
{
|
||||
bool first=true;
|
||||
qint64 val=0,tmp;
|
||||
for (QVector<Layer *>::iterator l=m_layers.begin();l!=m_layers.end();l++) {
|
||||
if ((*l)->isEmpty()) continue;
|
||||
tmp=(*l)->Minx();
|
||||
if (!tmp) continue;
|
||||
if (first) {
|
||||
val=tmp;
|
||||
first=false;
|
||||
} else {
|
||||
if (tmp < val) val = tmp;
|
||||
}
|
||||
}
|
||||
if (val) rmin_x=val;
|
||||
return val;
|
||||
}
|
||||
qint64 gGraph::MaxX()
|
||||
{
|
||||
bool first=true;
|
||||
qint64 val=0,tmp;
|
||||
for (QVector<Layer *>::iterator l=m_layers.begin();l!=m_layers.end();l++) {
|
||||
if ((*l)->isEmpty()) continue;
|
||||
tmp=(*l)->Maxx();
|
||||
if (!tmp) continue;
|
||||
if (first) {
|
||||
val=tmp;
|
||||
first=false;
|
||||
} else {
|
||||
if (tmp > val) val = tmp;
|
||||
}
|
||||
}
|
||||
if (val) rmax_x=val;
|
||||
return val;
|
||||
}
|
||||
EventDataType gGraph::MinY()
|
||||
{
|
||||
bool first=true;
|
||||
EventDataType val=0,tmp;
|
||||
for (QVector<Layer *>::iterator l=m_layers.begin();l!=m_layers.end();l++) {
|
||||
if ((*l)->isEmpty()) continue;
|
||||
tmp=(*l)->Miny();
|
||||
if (tmp==0 && tmp==(*l)->Maxy()) continue;
|
||||
if (first) {
|
||||
val=tmp;
|
||||
first=false;
|
||||
} else {
|
||||
if (tmp < val) val = tmp;
|
||||
}
|
||||
}
|
||||
return rmin_y=val;
|
||||
}
|
||||
EventDataType gGraph::MaxY()
|
||||
{
|
||||
bool first=true;
|
||||
EventDataType val=0,tmp;
|
||||
for (QVector<Layer *>::iterator l=m_layers.begin();l!=m_layers.end();l++) {
|
||||
if ((*l)->isEmpty()) continue;
|
||||
tmp=(*l)->Maxy();
|
||||
if (tmp==0 && tmp==(*l)->Miny()) continue;
|
||||
if (first) {
|
||||
val=tmp;
|
||||
first=false;
|
||||
} else {
|
||||
if (tmp > val) val = tmp;
|
||||
}
|
||||
}
|
||||
return rmax_y=val;
|
||||
}
|
||||
|
||||
void gGraph::SetMinX(qint64 v)
|
||||
{
|
||||
min_x=v;
|
||||
}
|
||||
void gGraph::SetMaxX(qint64 v)
|
||||
{
|
||||
max_x=v;
|
||||
}
|
||||
void gGraph::SetMinY(EventDataType v)
|
||||
{
|
||||
min_y=v;
|
||||
}
|
||||
void gGraph::SetMaxY(EventDataType v)
|
||||
{
|
||||
max_y=v;
|
||||
}
|
||||
|
||||
// Sets a new Min & Max X clipping, refreshing the graph and all it's layers.
|
||||
void gGraph::SetXBounds(qint64 minx, qint64 maxx)
|
||||
{
|
||||
min_x=minx;
|
||||
max_x=maxx;
|
||||
|
||||
//repaint();
|
||||
//m_graphview->updateGL();
|
||||
}
|
||||
int gGraph::flipY(int y)
|
||||
{
|
||||
return m_graphview->height()-y;
|
||||
}
|
||||
|
||||
void gGraph::ResetBounds()
|
||||
{
|
||||
min_x=MinX();
|
||||
max_x=MaxX();
|
||||
min_y=MinY();
|
||||
max_y=MaxY();
|
||||
}
|
||||
|
||||
|
||||
gGraphView::gGraphView(QWidget *parent) :
|
||||
QGLWidget(parent),
|
||||
m_offsetY(0),m_offsetX(0),m_scaleY(1.0),m_scrollbar(NULL)
|
||||
{
|
||||
m_sizer_index=m_graph_index=0;
|
||||
m_button_down=m_graph_dragging=m_sizer_dragging=false;
|
||||
this->setMouseTracking(true);
|
||||
InitGraphs();
|
||||
}
|
||||
gGraphView::~gGraphView()
|
||||
{
|
||||
for (int i=0;i<m_graphs.size();i++) {
|
||||
delete m_graphs[i];
|
||||
}
|
||||
m_graphs.clear();
|
||||
if (m_scrollbar) {
|
||||
this->disconnect(SIGNAL(sliderMoved(int)),this);
|
||||
}
|
||||
}
|
||||
|
||||
void gGraphView::AddGraph(gGraph *g)
|
||||
{
|
||||
if (!m_graphs.contains(g)) {
|
||||
m_graphs.push_back(g);
|
||||
|
||||
updateScrollBar();
|
||||
}
|
||||
}
|
||||
float gGraphView::totalHeight()
|
||||
{
|
||||
float th=0;
|
||||
for (int i=0;i<m_graphs.size();i++) {
|
||||
if (m_graphs[i]->isEmpty()) continue;
|
||||
th += m_graphs[i]->height() + graphSpacer;
|
||||
}
|
||||
return ceil(th);
|
||||
}
|
||||
float gGraphView::findTop(gGraph * graph)
|
||||
{
|
||||
float th=-m_offsetY;
|
||||
for (int i=0;i<m_graphs.size();i++) {
|
||||
if (m_graphs[i]==graph) break;
|
||||
if (m_graphs[i]->isEmpty()) continue;
|
||||
th += m_graphs[i]->height()*m_scaleY + graphSpacer;
|
||||
}
|
||||
//th-=m_offsetY;
|
||||
return ceil(th);
|
||||
}
|
||||
float gGraphView::scaleHeight()
|
||||
{
|
||||
float th=0;
|
||||
for (int i=0;i<m_graphs.size();i++) {
|
||||
if (m_graphs[i]->isEmpty()) continue;
|
||||
th += m_graphs[i]->height() * m_scaleY + graphSpacer;
|
||||
}
|
||||
return ceil(th);
|
||||
}
|
||||
void gGraphView::resizeEvent(QResizeEvent *e)
|
||||
{
|
||||
QGLWidget::resizeEvent(e); // This ques a redraw event..
|
||||
|
||||
updateScale();
|
||||
for (int i=0;i<m_graphs.size();i++) {
|
||||
m_graphs[i]->resize(e->size().width(),m_graphs[i]->height()*m_scaleY);
|
||||
}
|
||||
}
|
||||
void gGraphView::scrollbarValueChanged(int val)
|
||||
{
|
||||
//qDebug() << "Scrollbar Changed" << val;
|
||||
m_offsetY=val;
|
||||
updateGL(); // do this on a timer?
|
||||
}
|
||||
void gGraphView::ResetBounds()
|
||||
{
|
||||
for (int i=0;i<m_graphs.size();i++) {
|
||||
m_graphs[i]->ResetBounds();
|
||||
}
|
||||
updateScale();
|
||||
}
|
||||
|
||||
void gGraphView::SetXBounds(qint64 minx, qint64 maxx)
|
||||
{
|
||||
for (int i=0;i<m_graphs.size();i++) {
|
||||
m_graphs[i]->SetXBounds(minx,maxx);
|
||||
}
|
||||
updateGL();
|
||||
}
|
||||
void gGraphView::updateScale()
|
||||
{
|
||||
float th=totalHeight(); // height of all graphs
|
||||
float h=height(); // height of main widget
|
||||
|
||||
if (th < h) {
|
||||
m_scaleY=h / th; // less graphs than fits on screen, so scale to fit
|
||||
} else {
|
||||
m_scaleY=1.0;
|
||||
}
|
||||
updateScrollBar();
|
||||
}
|
||||
|
||||
void gGraphView::updateScrollBar()
|
||||
{
|
||||
if (!m_scrollbar) return;
|
||||
|
||||
if (!m_graphs.size()) return;
|
||||
|
||||
float th=scaleHeight(); // height of all graphs
|
||||
float h=height(); // height of main widget
|
||||
|
||||
float vis=0;
|
||||
for (int i=0;i<m_graphs.size();i++) vis+=m_graphs[i]->isEmpty() ? 0 : 1;
|
||||
|
||||
if (th<h) { // less graphs than fits on screen
|
||||
|
||||
m_scrollbar->setMaximum(0); // turn scrollbar off.
|
||||
|
||||
} else { // more graphs than fit on screen
|
||||
//m_scaleY=1.0;
|
||||
float avgheight=th/vis;
|
||||
m_scrollbar->setPageStep(avgheight);
|
||||
m_scrollbar->setSingleStep(avgheight/8.0);
|
||||
m_scrollbar->setMaximum(th-height());
|
||||
if (m_offsetY>th-height()) {
|
||||
m_offsetY=th-height();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void gGraphView::setScrollBar(MyScrollBar *sb)
|
||||
{
|
||||
m_scrollbar=sb;
|
||||
m_scrollbar->setMinimum(0);
|
||||
updateScrollBar();
|
||||
this->connect(m_scrollbar,SIGNAL(valueChanged(int)),SLOT(scrollbarValueChanged(int)));
|
||||
}
|
||||
void gGraphView::initializeGL()
|
||||
{
|
||||
setAutoFillBackground(false);
|
||||
setAutoBufferSwap(false);
|
||||
glDisable(GL_LIGHTING);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void gGraphView::resizeGL(int w, int h)
|
||||
{
|
||||
glViewport(0, 0, w, h);
|
||||
glMatrixMode(GL_PROJECTION);
|
||||
glLoadIdentity();
|
||||
|
||||
glOrtho(0, w, h, 0, -1, 1);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glLoadIdentity();
|
||||
}
|
||||
|
||||
void gGraphView::paintGL()
|
||||
{
|
||||
if (width()<=0) return;
|
||||
if (height()<=0) return;
|
||||
|
||||
|
||||
QPainter qp(this);
|
||||
qp.beginNativePainting();
|
||||
painter=&qp;
|
||||
|
||||
glClearColor(255,255,255,255);
|
||||
//glClearDepth(1);
|
||||
glClear(GL_COLOR_BUFFER_BIT);// | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
//glEnable(GL_BLEND);
|
||||
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(1.0,1.0,1.0,1.0); // Gradient start
|
||||
glVertex2f(0, height());
|
||||
glVertex2f(0, 0);
|
||||
|
||||
glColor4f(0.8,0.8,1.0,1.0); // Gradient End
|
||||
glVertex2f(width(), 0);
|
||||
glVertex2f(width(), height());
|
||||
|
||||
glEnd();
|
||||
|
||||
float px=titleWidth-m_offsetX;
|
||||
float py=-m_offsetY;
|
||||
int numgraphs=m_graphs.size();
|
||||
float h,w;
|
||||
//ax=px;//-m_offsetX;
|
||||
if (!numgraphs) {
|
||||
QString ts="No Data";
|
||||
|
||||
} else
|
||||
for (int i=0;i<numgraphs;i++) {
|
||||
if (m_graphs[i]->isEmpty()) continue;
|
||||
|
||||
h=m_graphs[i]->height() * m_scaleY;
|
||||
|
||||
// set clipping?
|
||||
|
||||
if (py > height())
|
||||
break; // we are done.. can't draw anymore
|
||||
|
||||
if ((py + h + graphSpacer) >= 0) {
|
||||
w=width();
|
||||
m_graphs[i]->paint(px,py,width()-titleWidth,h);
|
||||
glColor4f(0,0,0,1);
|
||||
//if (i<numgraphs-1) {
|
||||
glBegin(GL_QUADS);
|
||||
glColor4f(.3,.3,.3,1.0);
|
||||
glVertex2i(0,py+h);
|
||||
glVertex2i(w,py+h);
|
||||
glVertex2i(w,py+h+graphSpacer);
|
||||
glVertex2i(0,py+h+graphSpacer);
|
||||
glEnd();
|
||||
//}
|
||||
}
|
||||
py+=h;
|
||||
//if (i<numgraphs-1)
|
||||
py+=graphSpacer;
|
||||
py=ceil(py);
|
||||
}
|
||||
|
||||
//glDisable(GL_TEXTURE_2D);
|
||||
//glDisable(GL_DEPTH_TEST);
|
||||
qp.endNativePainting();
|
||||
qp.end();
|
||||
|
||||
swapBuffers(); // Dump to screen.
|
||||
}
|
||||
|
||||
// For manual scrolling
|
||||
void gGraphView::setOffsetY(int offsetY)
|
||||
{
|
||||
m_offsetY=offsetY;
|
||||
//issue full redraw..
|
||||
updateGL();
|
||||
}
|
||||
|
||||
// For manual X scrolling (not really needed)
|
||||
void gGraphView::setOffsetX(int offsetX)
|
||||
{
|
||||
m_offsetX=offsetX;
|
||||
//issue redraw
|
||||
updateGL();
|
||||
}
|
||||
|
||||
void gGraphView::mouseMoveEvent(QMouseEvent * event)
|
||||
{
|
||||
int x=event->x();
|
||||
int y=event->y();
|
||||
|
||||
if (m_sizer_dragging) { // Resize handle being dragged
|
||||
float my=y - m_sizer_point.y();
|
||||
//qDebug() << "Sizer moved vertically" << m_sizer_index << my*m_scaleY;
|
||||
float h=m_graphs[m_sizer_index]->height();
|
||||
h+=my / m_scaleY;
|
||||
if (h > m_graphs[m_sizer_index]->minHeight()) {
|
||||
m_graphs[m_sizer_index]->setHeight(h);
|
||||
m_sizer_point.setX(x);
|
||||
m_sizer_point.setY(y);
|
||||
updateScrollBar();
|
||||
updateGL();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_graph_dragging) { // Title bar being dragged to reorder
|
||||
gGraph *p;
|
||||
int yy=m_sizer_point.y();
|
||||
bool empty;
|
||||
if (y < yy) {
|
||||
|
||||
for (int i=m_graph_index-1;i>=0;i--) {
|
||||
empty=m_graphs[i]->isEmpty();
|
||||
// swapping upwards.
|
||||
int yy2=yy-graphSpacer-m_graphs[i]->height()*m_scaleY;
|
||||
yy2+=m_graphs[m_graph_index]->height()*m_scaleY;
|
||||
if (y<yy2) {
|
||||
qDebug() << "Graph Reorder" << m_graph_index;
|
||||
p=m_graphs[m_graph_index];
|
||||
m_graphs[m_graph_index]=m_graphs[i];
|
||||
m_graphs[i]=p;
|
||||
if (!empty) {
|
||||
m_sizer_point.setY(yy-graphSpacer-m_graphs[m_graph_index]->height()*m_scaleY);
|
||||
updateGL();
|
||||
}
|
||||
m_graph_index--;
|
||||
}
|
||||
if (!empty) break;
|
||||
|
||||
}
|
||||
} else if (y > yy+graphSpacer+m_graphs[m_graph_index]->height()*m_scaleY) {
|
||||
// swapping downwards
|
||||
qDebug() << "Graph Reorder" << m_graph_index;
|
||||
for (int i=m_graph_index+1;i<m_graphs.size();i++) {
|
||||
empty=m_graphs[i]->isEmpty();
|
||||
p=m_graphs[m_graph_index];
|
||||
m_graphs[m_graph_index]=m_graphs[i];
|
||||
m_graphs[i]=p;
|
||||
if (!empty) {
|
||||
m_sizer_point.setY(yy+graphSpacer+m_graphs[m_graph_index]->height()*m_scaleY);
|
||||
updateGL();
|
||||
}
|
||||
m_graph_index++;
|
||||
if (!empty) break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
float py = -m_offsetY;
|
||||
float h;
|
||||
|
||||
for (int i=0; i < m_graphs.size(); i++) {
|
||||
|
||||
if (m_graphs[i]->isEmpty()) continue;
|
||||
|
||||
h=m_graphs[i]->height() * m_scaleY;
|
||||
if (py > height())
|
||||
break; // we are done.. can't draw anymore
|
||||
|
||||
if ((py + h + graphSpacer) >= 0) {
|
||||
if ((y >= py) && (y < py + h)) {
|
||||
if (x >= titleWidth) {
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
QPoint p(x-titleWidth,y-py);
|
||||
QMouseEvent e(event->type(),p,event->button(),event->buttons(),event->modifiers());
|
||||
m_graphs[i]->mouseMoveEvent(&e);
|
||||
} else {
|
||||
this->setCursor(Qt::OpenHandCursor);
|
||||
}
|
||||
} else if ((y >= py + h) && (y <= py + h + graphSpacer + 1)) {
|
||||
this->setCursor(Qt::SplitVCursor);
|
||||
}
|
||||
|
||||
}
|
||||
py+=h;
|
||||
py+=graphSpacer; // do we want the extra spacer down the bottom?
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void gGraphView::mousePressEvent(QMouseEvent * event)
|
||||
{
|
||||
int x=event->x();
|
||||
int y=event->y();
|
||||
|
||||
float py=-m_offsetY;
|
||||
float h;
|
||||
|
||||
for (int i=0;i<m_graphs.size();i++) {
|
||||
|
||||
if (m_graphs[i]->isEmpty()) continue;
|
||||
|
||||
h=m_graphs[i]->height()*m_scaleY;
|
||||
if (py>height())
|
||||
break; // we are done.. can't draw anymore
|
||||
|
||||
if ((py + h + graphSpacer) >= 0) {
|
||||
if ((y >= py) && (y < py + h)) {
|
||||
//qDebug() << "Clicked" << i;
|
||||
if (x < titleWidth) { // clicked on title to drag graph..
|
||||
m_graph_dragging=true;
|
||||
m_graph_index=i;
|
||||
m_sizer_point.setX(x);
|
||||
m_sizer_point.setY(py); // point at top of graph..
|
||||
this->setCursor(Qt::ClosedHandCursor);
|
||||
} else { // send event to graph..
|
||||
m_global_point_clicked=QPoint(x,y);
|
||||
m_point_clicked=QPoint (x-titleWidth,y-py);
|
||||
|
||||
QMouseEvent e(event->type(),m_point_clicked,event->button(),event->buttons(),event->modifiers());
|
||||
m_graphs[i]->mousePressEvent(&e);
|
||||
m_graph_index=i;
|
||||
m_button_down=true;
|
||||
//m_graphs[i]->mousePressEvent(event);
|
||||
}
|
||||
} else if ((y >= py + h) && (y <= py + h + graphSpacer + 1)) {
|
||||
this->setCursor(Qt::SplitVCursor);
|
||||
m_sizer_dragging=true;
|
||||
m_sizer_index=i;
|
||||
m_sizer_point.setX(x);
|
||||
m_sizer_point.setY(y);
|
||||
//qDebug() << "Sizer clicked" << i;
|
||||
}
|
||||
|
||||
}
|
||||
py+=h;
|
||||
py+=graphSpacer; // do we want the extra spacer down the bottom?
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void gGraphView::mouseReleaseEvent(QMouseEvent * event)
|
||||
{
|
||||
this->setCursor(Qt::ArrowCursor);
|
||||
|
||||
if (m_sizer_dragging) {
|
||||
m_sizer_dragging=false;
|
||||
return;
|
||||
}
|
||||
if (m_graph_dragging) {
|
||||
m_graph_dragging=false;
|
||||
return;
|
||||
}
|
||||
if (m_button_down) {
|
||||
m_button_down=false;
|
||||
int x1=m_global_point_clicked.x()-event->x();
|
||||
int y1=m_global_point_clicked.y()-event->y();
|
||||
|
||||
QPoint p(m_point_clicked.x()-x1,m_point_clicked.y()-y1);
|
||||
QMouseEvent e(event->type(),p,event->button(),event->buttons(),event->modifiers());
|
||||
m_graphs[m_graph_index]->mouseReleaseEvent(&e);
|
||||
}
|
||||
int x=event->x();
|
||||
int y=event->y();
|
||||
}
|
||||
|
||||
void gGraphView::mouseDoubleClickEvent(QMouseEvent * event)
|
||||
{
|
||||
// A single click gets sent first.. Need to set a timer to check for this event..
|
||||
|
||||
int x=event->x();
|
||||
int y=event->y();
|
||||
|
||||
float py=-m_offsetY;
|
||||
float h;
|
||||
|
||||
for (int i=0;i<m_graphs.size();i++) {
|
||||
|
||||
if (m_graphs[i]->isEmpty()) continue;
|
||||
|
||||
h=m_graphs[i]->height()*m_scaleY;
|
||||
if (py>height())
|
||||
break; // we are done.. can't draw anymore
|
||||
|
||||
if ((py + h + graphSpacer) >= 0) {
|
||||
if ((y >= py) && (y <= py + h)) {
|
||||
if (x < titleWidth) {
|
||||
// What to do when double clicked on the graph title ??
|
||||
} else {
|
||||
// send event to graph..
|
||||
m_graphs[i]->mouseDoubleClickEvent(event);
|
||||
}
|
||||
} else if ((y >= py + h) && (y <= py + h + graphSpacer + 1)) {
|
||||
// What to do when double clicked on the resize handle?
|
||||
}
|
||||
|
||||
}
|
||||
py+=h;
|
||||
py+=graphSpacer; // do we want the extra spacer down the bottom?
|
||||
}
|
||||
}
|
||||
void gGraphView::wheelEvent(QWheelEvent * event)
|
||||
{
|
||||
// Hmm.. I could optionalize this to change mousewheel behaviour without affecting the scrollbar now..
|
||||
|
||||
m_scrollbar->SendWheelEvent(event); // Just forwarding the event to scrollbar for now..
|
||||
}
|
||||
|
||||
void gGraphView::keyPressEvent(QKeyEvent * event)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
MyScrollBar::MyScrollBar(QWidget * parent)
|
||||
:QScrollBar(parent)
|
||||
{
|
||||
}
|
||||
void MyScrollBar::SendWheelEvent(QWheelEvent * e)
|
||||
{
|
||||
wheelEvent(e);
|
||||
}
|
255
Graphs/gGraphView.h
Normal file
255
Graphs/gGraphView.h
Normal file
@ -0,0 +1,255 @@
|
||||
#ifndef GGRAPHVIEW_H
|
||||
#define GGRAPHVIEW_H
|
||||
|
||||
#include <QGLWidget>
|
||||
#include <QScrollBar>
|
||||
#include <QResizeEvent>
|
||||
#include <SleepLib/day.h>
|
||||
#include <Graphs/glcommon.h>
|
||||
|
||||
|
||||
#define MIN(a,b) (((a)<(b)) ? (a) : (b));
|
||||
#define MAX(a,b) (((a)<(b)) ? (b) : (a));
|
||||
|
||||
class gGraphView;
|
||||
class gGraph;
|
||||
|
||||
class MyScrollBar:public QScrollBar
|
||||
{
|
||||
public:
|
||||
MyScrollBar(QWidget * parent=0);
|
||||
void SendWheelEvent(QWheelEvent * e);
|
||||
};
|
||||
|
||||
enum LayerPosition { LayerLeft, LayerRight, LayerTop, LayerBottom, LayerCenter, LayerOverlay };
|
||||
|
||||
class Layer
|
||||
{
|
||||
friend class gGraph;
|
||||
public:
|
||||
Layer(ChannelID code);
|
||||
virtual ~Layer();
|
||||
|
||||
virtual void SetDay(Day * d);
|
||||
virtual void SetCode(ChannelID c) { m_code=c; }
|
||||
const ChannelID & code() { return m_code; }
|
||||
virtual bool isEmpty();
|
||||
|
||||
virtual qint64 Minx() { if (m_day) return m_day->first(); return m_minx; }
|
||||
virtual qint64 Maxx() { if (m_day) return m_day->last(); return m_maxx; }
|
||||
virtual EventDataType Miny() { return m_miny; }
|
||||
virtual EventDataType Maxy() { return m_maxy; }
|
||||
virtual void setMinY(EventDataType val) { m_miny=val; }
|
||||
virtual void setMaxY(EventDataType val) { m_maxy=val; }
|
||||
virtual void setMinX(qint64 val) { m_minx=val; }
|
||||
virtual void setMaxX(qint64 val) { m_maxx=val; }
|
||||
|
||||
void setVisible(bool b) { m_visible=b; }
|
||||
bool visible() { return m_visible; }
|
||||
|
||||
void setMovable(bool b) { m_movable=b; }
|
||||
bool movable() { return m_movable; }
|
||||
|
||||
virtual void paint(gGraph & gv,int left,int top,int width, int height)=0;
|
||||
|
||||
void setLayout(LayerPosition position, short width, short height, short order);
|
||||
void setPos(short x, short y) { m_X=x; m_Y=y; }
|
||||
|
||||
int Width() { return m_width; }
|
||||
int Height() { return m_height; }
|
||||
|
||||
LayerPosition position() { return m_position; }
|
||||
//void X() { return m_X; }
|
||||
//void Y() { return m_Y; }
|
||||
|
||||
|
||||
protected:
|
||||
//QRect bounds; // bounds, relative to top of individual graph.
|
||||
Day *m_day;
|
||||
bool m_visible;
|
||||
bool m_movable;
|
||||
qint64 m_minx,m_maxx;
|
||||
EventDataType m_miny,m_maxy;
|
||||
ChannelID m_code;
|
||||
short m_width; // reserved x pixels needed for this layer. 0==Depends on position..
|
||||
short m_height; // reserved y pixels needed for this layer. both 0 == expand to all free area.
|
||||
short m_X; // offset for repositionable layers..
|
||||
short m_Y;
|
||||
short m_order; // order for positioning..
|
||||
LayerPosition m_position;
|
||||
};
|
||||
|
||||
class LayerGroup:public Layer
|
||||
{
|
||||
public:
|
||||
LayerGroup();
|
||||
virtual ~LayerGroup();
|
||||
virtual void AddLayer(Layer *l);
|
||||
|
||||
virtual qint64 Minx();
|
||||
virtual qint64 Maxx();
|
||||
virtual EventDataType Miny();
|
||||
virtual EventDataType Maxy();
|
||||
virtual bool isEmpty();
|
||||
virtual void SetDay(Day * d);
|
||||
|
||||
protected:
|
||||
QVector<Layer *> layers;
|
||||
};
|
||||
|
||||
class gGraph
|
||||
{
|
||||
friend class gGraphView;
|
||||
public:
|
||||
gGraph(gGraphView * graphview=NULL, QString title="",int height=100);
|
||||
virtual ~gGraph();
|
||||
|
||||
void setVisible(bool b) { m_visible=b; }
|
||||
bool visible() { return m_visible; }
|
||||
|
||||
float height() { return m_height; }
|
||||
void setHeight(float height) { m_height=height; }
|
||||
|
||||
int minHeight() { return m_min_height; }
|
||||
void setMinHeight(int height) { m_min_height=height; }
|
||||
|
||||
int maxHeight() { return m_max_height; }
|
||||
void setMaxHeight(int height) { m_max_height=height; }
|
||||
|
||||
bool isEmpty();
|
||||
|
||||
void AddLayer(Layer * l,LayerPosition position=LayerCenter, short pixelsX=0, short pixelsY=0, short order=0, bool movable=false, short x=0, short y=0);
|
||||
|
||||
void qglColor(QColor col);
|
||||
void renderText(QString text, int x,int y, float angle=0.0, QColor color=Qt::black, QFont *font=defaultfont);
|
||||
|
||||
QString title() { return m_title; }
|
||||
|
||||
virtual void repaint(); // Repaint individual graph..
|
||||
|
||||
virtual void ResetBounds();
|
||||
virtual void SetXBounds(qint64 minx, qint64 maxx);
|
||||
|
||||
virtual qint64 MinX();
|
||||
virtual qint64 MaxX();
|
||||
virtual EventDataType MinY();
|
||||
virtual EventDataType MaxY();
|
||||
|
||||
virtual void SetMinX(qint64 v);
|
||||
virtual void SetMaxX(qint64 v);
|
||||
virtual void SetMinY(EventDataType v);
|
||||
virtual void SetMaxY(EventDataType v);
|
||||
|
||||
void resize(int width, int height); // margin recalcs..
|
||||
|
||||
qint64 max_x,min_x,max_y,min_y;
|
||||
qint64 rmax_x,rmin_x,rmax_y,rmin_y;
|
||||
|
||||
bool blockZoom() { return m_blockzoom; }
|
||||
void setBlockZoom(bool b) { m_blockzoom=b; }
|
||||
int flipY(int y); // flip GL coordinates
|
||||
|
||||
protected:
|
||||
virtual void paint(int originX, int originY, int width, int height);
|
||||
void invalidate();
|
||||
|
||||
virtual void mouseWheelEvent(QMouseEvent * event);
|
||||
virtual void mouseMoveEvent(QMouseEvent * event);
|
||||
virtual void mousePressEvent(QMouseEvent * event);
|
||||
virtual void mouseReleaseEvent(QMouseEvent * event);
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent * event);
|
||||
virtual void keyPressEvent(QKeyEvent * event);
|
||||
|
||||
gGraphView * m_graphview;
|
||||
QString m_title;
|
||||
QVector<Layer *> m_layers;
|
||||
float m_height,m_width;
|
||||
|
||||
int m_marginleft, m_marginright, m_margintop, m_marginbottom;
|
||||
|
||||
int left,right,top,bottom; // dirty magin hacks..
|
||||
|
||||
int m_min_height;
|
||||
int m_max_height;
|
||||
bool m_visible;
|
||||
bool m_blockzoom;
|
||||
QRect m_lastbounds;
|
||||
|
||||
};
|
||||
|
||||
class gGraphView : public QGLWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit gGraphView(QWidget *parent = 0);
|
||||
virtual ~gGraphView();
|
||||
void AddGraph(gGraph *g);
|
||||
|
||||
void setScrollBar(MyScrollBar *sb);
|
||||
MyScrollBar * scrollBar() { return m_scrollbar; }
|
||||
static const int titleWidth=30;
|
||||
static const int graphSpacer=4;
|
||||
|
||||
float findTop(gGraph * graph);
|
||||
|
||||
float scaleY() { return m_scaleY; }
|
||||
|
||||
void ResetBounds();
|
||||
void SetXBounds(qint64 minx, qint64 maxx);
|
||||
|
||||
bool hasGraphs() { return m_graphs.size()>0; }
|
||||
|
||||
QPoint pointClicked() { return m_point_clicked; }
|
||||
QPoint globalPointClicked() { return m_global_point_clicked; }
|
||||
|
||||
QPainter *painter;
|
||||
protected:
|
||||
|
||||
float totalHeight();
|
||||
float scaleHeight();
|
||||
|
||||
virtual void initializeGL();
|
||||
virtual void paintGL();
|
||||
virtual void resizeGL(int width, int height);
|
||||
virtual void resizeEvent(QResizeEvent *);
|
||||
|
||||
|
||||
void setOffsetY(int offsetY);
|
||||
void setOffsetX(int offsetX);
|
||||
|
||||
virtual void mouseMoveEvent(QMouseEvent * event);
|
||||
virtual void mousePressEvent(QMouseEvent * event);
|
||||
virtual void mouseReleaseEvent(QMouseEvent * event);
|
||||
virtual void mouseDoubleClickEvent(QMouseEvent * event);
|
||||
virtual void wheelEvent(QWheelEvent * event);
|
||||
virtual void keyPressEvent(QKeyEvent * event);
|
||||
|
||||
void updateScrollBar();
|
||||
void updateScale(); // update scale & Scrollbar
|
||||
|
||||
QVector<gGraph *> m_graphs;
|
||||
int m_offsetY,m_offsetX; // Scroll Offsets
|
||||
float m_scaleY;
|
||||
|
||||
bool m_sizer_dragging;
|
||||
int m_sizer_index;
|
||||
|
||||
bool m_button_down;
|
||||
QPoint m_point_clicked;
|
||||
QPoint m_global_point_clicked;
|
||||
QPoint m_sizer_point;
|
||||
|
||||
MyScrollBar * m_scrollbar;
|
||||
|
||||
bool m_graph_dragging;
|
||||
int m_graph_index;
|
||||
|
||||
signals:
|
||||
|
||||
|
||||
public slots:
|
||||
void scrollbarValueChanged(int val);
|
||||
|
||||
};
|
||||
|
||||
#endif // GGRAPHVIEW_H
|
@ -12,7 +12,7 @@
|
||||
|
||||
#define EXTRA_ASSERTS 1
|
||||
gLineChart::gLineChart(ChannelID code,QColor col,bool square_plot, bool disable_accel)
|
||||
:gLayer(code),m_square_plot(square_plot),m_disable_accel(disable_accel)
|
||||
:Layer(code),m_square_plot(square_plot),m_disable_accel(disable_accel)
|
||||
{
|
||||
m_line_color=col;
|
||||
m_report_empty=false;
|
||||
@ -23,21 +23,20 @@ gLineChart::~gLineChart()
|
||||
|
||||
|
||||
// Time Domain Line Chart
|
||||
void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
void gLineChart::paint(gGraph & w,int left, int top, int width, int height)
|
||||
{
|
||||
const int max_drawlist_size=4096;
|
||||
QPoint m_drawlist[max_drawlist_size];
|
||||
|
||||
if (!m_visible)
|
||||
return;
|
||||
|
||||
if (!m_day)
|
||||
return;
|
||||
int start_px=w.GetLeftMargin();
|
||||
int start_py=w.GetBottomMargin();
|
||||
int width=scrx-(w.GetLeftMargin()+w.GetRightMargin());
|
||||
int height=scry-(w.GetTopMargin()+w.GetBottomMargin())-2;
|
||||
if (width<40)
|
||||
|
||||
if (width<0)
|
||||
return;
|
||||
|
||||
EventDataType miny,maxy;
|
||||
double minx,maxx;
|
||||
miny=w.min_y, maxy=w.max_y, maxx=w.max_x, minx=w.min_x;
|
||||
@ -80,10 +79,10 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
}
|
||||
|
||||
double xx=maxx-minx;
|
||||
double xmult=double(width-1)/xx;
|
||||
double xmult=double(width)/xx;
|
||||
|
||||
EventDataType yy=maxy-miny;
|
||||
EventDataType ymult=EventDataType(height)/yy; // time to pixel conversion multiplier
|
||||
EventDataType ymult=EventDataType(height-2)/yy; // time to pixel conversion multiplier
|
||||
|
||||
// Return on screwy min/max conditions
|
||||
if (xx<0)
|
||||
@ -107,13 +106,14 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
w.qglColor(Qt::black);
|
||||
glLineWidth (1);
|
||||
glBegin (GL_LINE_LOOP);
|
||||
glVertex2f (start_px, start_py);
|
||||
glVertex2f (start_px, start_py+height+2);
|
||||
glVertex2f (start_px+width,start_py+height+2);
|
||||
glVertex2f (start_px+width, start_py);
|
||||
glVertex2i (left, top);
|
||||
glVertex2i (left, top+height);
|
||||
glVertex2i (left+width,top+height);
|
||||
glVertex2i (left+width, top);
|
||||
glEnd ();
|
||||
}
|
||||
width--;
|
||||
height-=2;
|
||||
|
||||
qint32 vertcnt=0;
|
||||
GLshort * vertarray=vertex_array[0];
|
||||
@ -245,8 +245,8 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
} // else just start from the beginning
|
||||
}
|
||||
|
||||
int xst=start_px+1;
|
||||
int yst=start_py+1;
|
||||
int xst=left+1;
|
||||
int yst=top+height-1;
|
||||
|
||||
double time;
|
||||
EventDataType data;
|
||||
@ -307,19 +307,19 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
}
|
||||
// Plot compressed accelerated vertex list
|
||||
if (maxz>width) {
|
||||
qDebug() << "gLineChart::Plot() maxz exceeded graph width" << "maxz = " << maxz << "width =" << width << "scrx =" <<scrx;
|
||||
qDebug() << "gLineChart::Plot() maxz exceeded graph width" << "maxz = " << maxz << "width =" << width;
|
||||
maxz=width;
|
||||
}
|
||||
float ax1,ay1;
|
||||
for (int i=minz+1;i<maxz-1;i++) {
|
||||
for (int i=minz;i<maxz;i++) {
|
||||
// ax1=(m_drawlist[i-1].x()+m_drawlist[i].x()+m_drawlist[i+1].x())/3.0;
|
||||
// ay1=(m_drawlist[i-1].y()+m_drawlist[i].y()+m_drawlist[i+1].y())/3.0;
|
||||
ax1=m_drawlist[i].x();
|
||||
ay1=m_drawlist[i].y();
|
||||
vertarray[vertcnt++]=xst+i;
|
||||
vertarray[vertcnt++]=yst+ax1;
|
||||
vertarray[vertcnt++]=yst-ax1;
|
||||
vertarray[vertcnt++]=xst+i;
|
||||
vertarray[vertcnt++]=yst+ay1;
|
||||
vertarray[vertcnt++]=yst-ay1;
|
||||
|
||||
if (vertcnt>=maxverts) break;
|
||||
}
|
||||
@ -335,7 +335,7 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
data=dat[i];//el.data(i);
|
||||
|
||||
px=xst+((time - minx) * xmult); // Scale the time scale X to pixel scale X
|
||||
py=yst+((data - ymin) * nmult); // Same for Y scale, with precomputed gain
|
||||
py=yst-((data - ymin) * nmult); // Same for Y scale, with precomputed gain
|
||||
|
||||
if (firstpx) {
|
||||
lastpx=px;
|
||||
@ -381,10 +381,10 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
|
||||
px=xst+((time - minx) * xmult); // Scale the time scale X to pixel scale X
|
||||
//py=yst+((data - ymin) * nmult); // Same for Y scale with precomputed gain
|
||||
py=yst+((data - miny) * ymult); // Same for Y scale with precomputed gain
|
||||
py=yst-((data - miny) * ymult); // Same for Y scale with precomputed gain
|
||||
|
||||
if (px<start_px) px=start_px;
|
||||
if (px>start_px+width) px=start_px+width;
|
||||
if (px<left) px=left;
|
||||
if (px>left+width) px=left+width;
|
||||
if (firstpx) {
|
||||
firstpx=false;
|
||||
} else {
|
||||
@ -429,7 +429,7 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
QString msg="No Waveform Available";
|
||||
float x,y;
|
||||
GetTextExtent(msg,x,y,bigfont);
|
||||
DrawText(w,msg,start_px+(width/2.0)-(x/2.0),scry-w.GetBottomMargin()-height/2.0+y/2.0,0,Qt::gray,bigfont);
|
||||
//DrawText(w,msg,left+(width/2.0)-(x/2.0),scry-w.GetBottomMargin()-height/2.0+y/2.0,0,Qt::gray,bigfont);
|
||||
}
|
||||
} else {
|
||||
|
||||
@ -443,8 +443,22 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
|
||||
|
||||
// Crop to inside the margins.
|
||||
glScissor(w.GetLeftMargin(),w.GetBottomMargin(),width,height+2);
|
||||
int h1=top+height;
|
||||
int h2=height;
|
||||
if (h1<0) {
|
||||
h2=h1+height;
|
||||
h1=0;
|
||||
}
|
||||
glScissor(left,w.flipY(top+height+2),width+1,height+1);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
/*w.qglColor(Qt::black);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2i(0,0);
|
||||
glVertex2i(2000,0);
|
||||
glVertex2i(2000,1200);
|
||||
glVertex2i(0,1200);
|
||||
glEnd(); */
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
bool antialias=pref["UseAntiAliasing"].toBool();
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
@ -469,6 +483,6 @@ void gLineChart::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
glFinish();
|
||||
glFlush();
|
||||
}
|
||||
|
||||
|
@ -10,16 +10,16 @@
|
||||
#include <QVector>
|
||||
#include "SleepLib/event.h"
|
||||
#include "SleepLib/day.h"
|
||||
#include "graphwindow.h"
|
||||
#include "graphlayer.h"
|
||||
#include "gGraphView.h"
|
||||
//#include "graphlayer.h"
|
||||
|
||||
class gLineChart:public gLayer
|
||||
class gLineChart:public Layer
|
||||
{
|
||||
public:
|
||||
gLineChart(ChannelID code,const QColor col=QColor("black"), bool square_plot=false,bool disable_accel=false);
|
||||
virtual ~gLineChart();
|
||||
|
||||
virtual void Plot(gGraphWindow & w,float scrx,float scry);
|
||||
virtual void paint(gGraph & w,int left, int top, int width, int height);
|
||||
|
||||
void SetSquarePlot(bool b) { m_square_plot=b; }
|
||||
bool GetSquarePlot() { return m_square_plot; }
|
||||
|
@ -1,15 +1,15 @@
|
||||
/********************************************************************
|
||||
/*
|
||||
gLineOverlayBar Implementation
|
||||
Copyright (c)2011 Mark Watkins <jedimark@users.sourceforge.net>
|
||||
License: GPL
|
||||
*********************************************************************/
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "SleepLib/profiles.h"
|
||||
#include "gLineOverlay.h"
|
||||
|
||||
gLineOverlayBar::gLineOverlayBar(ChannelID code,QColor col,QString label,FlagType flt)
|
||||
:gLayer(code),m_label(label),m_flt(flt)
|
||||
:Layer(code),m_label(label),m_flt(flt)
|
||||
{
|
||||
m_flag_color=col;
|
||||
}
|
||||
@ -17,17 +17,18 @@ gLineOverlayBar::~gLineOverlayBar()
|
||||
{
|
||||
}
|
||||
|
||||
void gLineOverlayBar::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
void gLineOverlayBar::paint(gGraph & w, int left, int topp, int width, int height)
|
||||
{
|
||||
if (!m_visible) return;
|
||||
if (!m_day) return;
|
||||
|
||||
//int start_px=w.GetLeftMargin();
|
||||
int start_py=w.GetBottomMargin();
|
||||
int width=scrx-(w.GetLeftMargin()+w.GetRightMargin());
|
||||
int height=scry-(w.GetTopMargin()+w.GetBottomMargin());
|
||||
int start_py=topp;
|
||||
//int width=scrx-(w.GetLeftMargin()+w.GetRightMargin());
|
||||
//int height=scry-(w.GetTopMargin()+w.GetBottomMargin());
|
||||
|
||||
double xx=w.max_x-w.min_x;
|
||||
double yy=w.max_y-w.min_y;
|
||||
if (xx<=0) return;
|
||||
|
||||
float x1,x2;
|
||||
@ -35,8 +36,8 @@ void gLineOverlayBar::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
float x,y;
|
||||
|
||||
// Crop to inside the margins.
|
||||
glScissor(w.GetLeftMargin(),w.GetBottomMargin(),width,height);
|
||||
glEnable(GL_SCISSOR_TEST);
|
||||
// glScissor(left,topp,width,height);
|
||||
// glEnable(GL_SCISSOR_TEST);
|
||||
|
||||
qint32 vertcnt=0;
|
||||
GLshort * vertarray=vertex_array[0];
|
||||
@ -49,7 +50,7 @@ void gLineOverlayBar::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
return;
|
||||
}
|
||||
|
||||
float bottom=start_py+25, top=start_py+height-25;
|
||||
float bottom=start_py+height-25, top=start_py+25;
|
||||
|
||||
double X;
|
||||
double Y;
|
||||
@ -75,9 +76,11 @@ void gLineOverlayBar::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
if (X > w.max_x) break;
|
||||
}
|
||||
|
||||
x1=w.x2p(X);
|
||||
//x1=w.x2p(X);
|
||||
x1=double(width)/double(xx)*double(X-w.min_x)+left;
|
||||
if (m_flt==FT_Span) {
|
||||
x2=w.x2p(Y);
|
||||
//x2=w.x2p(Y);
|
||||
x2=double(width)/double(xx)*double(X-w.min_x)+left;
|
||||
//double w1=x2-x1;
|
||||
quadarray[quadcnt++]=x1;
|
||||
quadarray[quadcnt++]=start_py;
|
||||
@ -94,7 +97,7 @@ void gLineOverlayBar::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
if (pref["AlwaysShowOverlayBars"].toBool() || (xx<3600000.0)) {
|
||||
// show the fat dots in the middle
|
||||
pointarray[pointcnt++]=x1;
|
||||
pointarray[pointcnt++]=w.y2p(20);
|
||||
pointarray[pointcnt++]=double(height)/double(yy)*double(-20-w.min_y)+topp;
|
||||
if (pointcnt>=maxverts) { verts_exceeded=true; break; }
|
||||
} else {
|
||||
// thin lines down the bottom
|
||||
@ -126,7 +129,8 @@ void gLineOverlayBar::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
if (vertcnt>=maxverts) { verts_exceeded=true; break; }
|
||||
if (xx<(1800000)) {
|
||||
GetTextExtent(m_label,x,y);
|
||||
DrawText(w,m_label,x1-(x/2),scry-(start_py+height-30+y));
|
||||
//DrawText(w,m_label,x1-(x/2),scry-(start_py+height-30+y));
|
||||
w.renderText(m_label,x1-(x/2),top-y+3);
|
||||
//w.renderText(x1-(x/2),scry-(start_py+height-30+y),label);
|
||||
}
|
||||
|
||||
@ -168,6 +172,6 @@ void gLineOverlayBar::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
glDisable(GL_LINE_SMOOTH);
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
//glDisable(GL_SCISSOR_TEST);
|
||||
}
|
||||
|
||||
|
@ -7,15 +7,15 @@
|
||||
#ifndef GLINEOVERLAY_H
|
||||
#define GLINEOVERLAY_H
|
||||
|
||||
#include "graphlayer.h"
|
||||
#include "gGraphView.h"
|
||||
|
||||
class gLineOverlayBar:public gLayer
|
||||
class gLineOverlayBar:public Layer
|
||||
{
|
||||
public:
|
||||
gLineOverlayBar(ChannelID code,QColor col,QString _label="",FlagType _flt=FT_Bar);
|
||||
virtual ~gLineOverlayBar();
|
||||
|
||||
virtual void Plot(gGraphWindow & w,float scrx,float scry);
|
||||
virtual void paint(gGraph & w,int left, int top, int width, int height);
|
||||
virtual EventDataType Miny() { return 0; }
|
||||
virtual EventDataType Maxy() { return 0; }
|
||||
virtual bool isEmpty() { return true; }
|
||||
|
@ -12,7 +12,7 @@ const int divisors[]={86400000,2880000,14400000,7200000,3600000,2700000,1800000,
|
||||
const int divcnt=sizeof(divisors)/sizeof(int);
|
||||
|
||||
gXAxis::gXAxis(QColor col)
|
||||
:gLayer(EmptyChannel)
|
||||
:Layer(EmptyChannel)
|
||||
{
|
||||
m_line_color=col;
|
||||
m_text_color=col;
|
||||
@ -27,26 +27,24 @@ gXAxis::gXAxis(QColor col)
|
||||
QTime t2=d.toUTC().time();
|
||||
tz_offset=t2.secsTo(t1)/60L;
|
||||
tz_offset*=60000L;
|
||||
//offset=0;
|
||||
|
||||
}
|
||||
gXAxis::~gXAxis()
|
||||
{
|
||||
}
|
||||
void gXAxis::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
void gXAxis::paint(gGraph & w,int left,int top, int width, int height)
|
||||
{
|
||||
double px,py;
|
||||
|
||||
int start_px=w.GetLeftMargin();
|
||||
int start_py=w.GetBottomMargin();
|
||||
int width=scrx-(w.GetLeftMargin()+w.GetRightMargin());
|
||||
int start_px=left;
|
||||
int start_py=top;
|
||||
//int width=scrx-(w.GetLeftMargin()+w.GetRightMargin());
|
||||
// float height=scry-(w.GetTopMargin()+w.GetBottomMargin());
|
||||
|
||||
if (width<40)
|
||||
return;
|
||||
qint64 minx;
|
||||
qint64 maxx;
|
||||
if (w.BlockZoom()) {
|
||||
if (w.blockZoom()) {
|
||||
minx=w.rmin_x;
|
||||
maxx=w.rmax_x;
|
||||
} else {
|
||||
@ -132,23 +130,23 @@ void gXAxis::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
|
||||
double xmult=double(width)/double(xx);
|
||||
double step_pixels=double(step/10.0)*xmult;
|
||||
py=start_px+double(aligned_start-minx)*xmult;
|
||||
py=left+double(aligned_start-minx)*xmult;
|
||||
for (int i=0;i<10;i++) {
|
||||
py-=step_pixels;
|
||||
if (py<start_px) continue;
|
||||
vertarray[vertcnt++]=py;
|
||||
vertarray[vertcnt++]=start_py;
|
||||
vertarray[vertcnt++]=top;
|
||||
vertarray[vertcnt++]=py;
|
||||
vertarray[vertcnt++]=start_py-4;
|
||||
vertarray[vertcnt++]=top+4;
|
||||
}
|
||||
w.qglColor(Qt::black);
|
||||
for (qint64 i=aligned_start;i<maxx;i+=step) {
|
||||
px=double(i-minx)*xmult;
|
||||
px+=start_px;
|
||||
px+=left;
|
||||
vertarray[vertcnt++]=px;
|
||||
vertarray[vertcnt++]=start_py;
|
||||
vertarray[vertcnt++]=top;
|
||||
vertarray[vertcnt++]=px;
|
||||
vertarray[vertcnt++]=start_py-6;
|
||||
vertarray[vertcnt++]=top+6;
|
||||
qint64 j=i+tz_offset;
|
||||
int ms=j % 1000;
|
||||
int m=(j/60000L) % 60L;
|
||||
@ -168,15 +166,16 @@ void gXAxis::Plot(gGraphWindow & w,float scrx,float scry)
|
||||
}
|
||||
|
||||
//w.renderText(px-(x/2),scry-(w.GetBottomMargin()-18),tmpstr);
|
||||
DrawText(w,tmpstr,px-(x/2),scry-(w.GetBottomMargin()-18),0);
|
||||
//DrawText(w,tmpstr,,0);
|
||||
w.renderText(tmpstr,px-(x/2),top+18);
|
||||
py=px;
|
||||
for (int j=1;j<10;j++) {
|
||||
py+=step_pixels;
|
||||
if (py>=scrx-w.GetRightMargin()) break;
|
||||
if (py>=left+width) break;
|
||||
vertarray[vertcnt++]=py;
|
||||
vertarray[vertcnt++]=start_py;
|
||||
vertarray[vertcnt++]=top;
|
||||
vertarray[vertcnt++]=py;
|
||||
vertarray[vertcnt++]=start_py-4;
|
||||
vertarray[vertcnt++]=top+4;
|
||||
if (vertcnt>=maxverts) {
|
||||
break;
|
||||
}
|
||||
|
@ -1,19 +1,19 @@
|
||||
/********************************************************************
|
||||
/*
|
||||
gXAxis Header
|
||||
Copyright (c)2011 Mark Watkins <jedimark@users.sourceforge.net>
|
||||
License: GPL
|
||||
*********************************************************************/
|
||||
*/
|
||||
|
||||
#ifndef GXAXIS_H
|
||||
#define GXAXIS_H
|
||||
#include "graphlayer.h"
|
||||
#include "gGraphView.h"
|
||||
|
||||
class gXAxis:public gLayer
|
||||
class gXAxis:public Layer
|
||||
{
|
||||
public:
|
||||
gXAxis(QColor col=QColor("black"));
|
||||
virtual ~gXAxis();
|
||||
virtual void Plot(gGraphWindow & w,float scrx,float scry);
|
||||
virtual void paint(gGraph & w,int left,int top, int width, int height);
|
||||
static const int Margin=25; // How much room does this take up. (Bottom margin)
|
||||
void SetShowMinorLines(bool b) { m_show_minor_lines=b; }
|
||||
void SetShowMajorLines(bool b) { m_show_major_lines=b; }
|
||||
|
@ -8,8 +8,13 @@
|
||||
#include <QDebug>
|
||||
#include "gYAxis.h"
|
||||
|
||||
gYSpacer::gYSpacer(int spacer)
|
||||
:Layer(EmptyChannel)
|
||||
{
|
||||
};
|
||||
|
||||
gYAxis::gYAxis(QColor col)
|
||||
:gLayer(EmptyChannel)
|
||||
:Layer(EmptyChannel)
|
||||
{
|
||||
m_line_color=col;
|
||||
m_text_color=col;
|
||||
@ -23,7 +28,7 @@ gYAxis::gYAxis(QColor col)
|
||||
gYAxis::~gYAxis()
|
||||
{
|
||||
}
|
||||
void gYAxis::Plot(gGraphWindow &w,float scrx,float scry)
|
||||
void gYAxis::paint(gGraph & w,int left,int top, int width, int height)
|
||||
{
|
||||
float x,y;
|
||||
int labelW=0;
|
||||
@ -79,11 +84,6 @@ void gYAxis::Plot(gGraphWindow &w,float scrx,float scry)
|
||||
//if ((w.max_x-w.min_x)==0)
|
||||
// return;
|
||||
|
||||
int start_px=w.GetLeftMargin();
|
||||
int start_py=w.GetBottomMargin();
|
||||
int width=scrx-(w.GetRightMargin()+start_px);
|
||||
int topm=w.GetTopMargin();
|
||||
int height=scry-(topm+start_py);
|
||||
if (height<0) return;
|
||||
|
||||
QString fd="0";
|
||||
@ -92,8 +92,6 @@ void gYAxis::Plot(gGraphWindow &w,float scrx,float scry)
|
||||
double max_yticks=round(height / (y+15.0)); // plus spacing between lines
|
||||
double yt=1/max_yticks;
|
||||
|
||||
|
||||
|
||||
double mxy=MAX(fabs(maxy),fabs(miny));
|
||||
double mny=miny;
|
||||
if (miny<0) {
|
||||
@ -138,81 +136,57 @@ void gYAxis::Plot(gGraphWindow &w,float scrx,float scry)
|
||||
qDebug() << "Would exeed maxverts. Should be another two bounds exceeded messages after this. (I can do a minor optimisation by disabling the other checks if this turns out to be consistent)" << q << maxverts;
|
||||
}
|
||||
|
||||
|
||||
/*for (double i=miny+(min_ytick/2.0); i<maxy; i+=min_ytick) {
|
||||
ty=(i - miny) * ymult;
|
||||
h=(start_py+height)-ty;
|
||||
vertarray[vertcnt++]=start_px-4;
|
||||
vertarray[vertcnt++]=h;
|
||||
vertarray[vertcnt++]=start_px;
|
||||
vertarray[vertcnt++]=h;
|
||||
if (m_show_minor_lines) {// && (i > miny)) {
|
||||
double z=(min_ytick/5)*ymult;
|
||||
double g=h;
|
||||
for (int i=0;i<4;i++) {
|
||||
g+=z;
|
||||
minorvertarray[minorvertcnt++]=start_px+1;
|
||||
minorvertarray[minorvertcnt++]=g;
|
||||
minorvertarray[minorvertcnt++]=start_px+width;
|
||||
minorvertarray[minorvertcnt++]=g;
|
||||
}
|
||||
}
|
||||
if (vertcnt>=maxverts) { // Should only need to check one.. The above check should be enough.
|
||||
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.Title() << "graph" << "MinY =" <<miny << "MaxY =" << maxy << "min_ytick=" <<min_ytick;
|
||||
break;
|
||||
}
|
||||
} */
|
||||
|
||||
w.qglColor(m_text_color);
|
||||
for (double i=miny; i<=maxy+min_ytick-0.00001; i+=min_ytick) {
|
||||
ty=(i - miny) * ymult;
|
||||
fd=Format(i*m_yaxis_scale); // Override this as a function.
|
||||
GetTextExtent(fd,x,y);
|
||||
if (x>labelW) labelW=x;
|
||||
h=start_py+ty;
|
||||
h=top+height-ty;
|
||||
//w.renderText(start_px-12-x,scry-(h-(y/2.0)),fd);
|
||||
DrawText(w,fd,start_px-8-x,scry-(h-(y/2.0)),0,m_text_color);
|
||||
//DrawText(w,fd,left+width-8-x,(h+(y/2.0)),0,m_text_color);
|
||||
w.renderText(fd,left+width-8-x,(h+(y/2.0)),0,m_text_color);
|
||||
|
||||
vertarray[vertcnt++]=start_px-4;
|
||||
vertarray[vertcnt++]=left+width-4;
|
||||
vertarray[vertcnt++]=h;
|
||||
vertarray[vertcnt++]=start_px;
|
||||
vertarray[vertcnt++]=left+width;
|
||||
vertarray[vertcnt++]=h;
|
||||
|
||||
if (m_show_major_lines && (i > miny)) {
|
||||
/*if (m_show_major_lines && (i > miny)) {
|
||||
majorvertarray[majorvertcnt++]=start_px;
|
||||
majorvertarray[majorvertcnt++]=h;
|
||||
majorvertarray[majorvertcnt++]=start_px+width;
|
||||
majorvertarray[majorvertcnt++]=h;
|
||||
}
|
||||
} */
|
||||
double z=(min_ytick/4)*ymult;
|
||||
double g=h;
|
||||
for (int i=0;i<3;i++) {
|
||||
g+=z;
|
||||
if (g>start_py+height) break;
|
||||
vertarray[vertcnt++]=start_px-3;
|
||||
if (g>top+height) break;
|
||||
vertarray[vertcnt++]=left+width-3;
|
||||
vertarray[vertcnt++]=g;
|
||||
vertarray[vertcnt++]=start_px;
|
||||
vertarray[vertcnt++]=left+width;
|
||||
vertarray[vertcnt++]=g;
|
||||
if (vertcnt>=maxverts) {
|
||||
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.Title() << "graph" << "MinY =" <<miny << "MaxY =" << maxy << "min_ytick=" <<min_ytick;
|
||||
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<miny << "MaxY =" << maxy << "min_ytick=" <<min_ytick;
|
||||
break;
|
||||
}
|
||||
if (m_show_minor_lines) {// && (i > miny)) {
|
||||
/*if (m_show_minor_lines) {// && (i > miny)) {
|
||||
minorvertarray[minorvertcnt++]=start_px;
|
||||
minorvertarray[minorvertcnt++]=g;
|
||||
minorvertarray[minorvertcnt++]=start_px+width;
|
||||
minorvertarray[minorvertcnt++]=g;
|
||||
}
|
||||
} */
|
||||
}
|
||||
if (vertcnt>=maxverts) {
|
||||
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.Title() << "graph" << "MinY =" <<miny << "MaxY =" << maxy << "min_ytick=" <<min_ytick;
|
||||
qWarning() << "vertarray bounds exceeded in gYAxis for " << w.title() << "graph" << "MinY =" <<miny << "MaxY =" << maxy << "min_ytick=" <<min_ytick;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
if (vertcnt>=maxverts) {
|
||||
qWarning() << "yAxis tickers and display should be corrupted, because something dumb is happening in " << w.Title() << "graph";
|
||||
qWarning() << "yAxis tickers and display should be corrupted, because something dumb is happening in " << w.title() << "graph";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -7,14 +7,26 @@
|
||||
#ifndef GYAXIS_H
|
||||
#define GYAXIS_H
|
||||
|
||||
#include "graphlayer.h"
|
||||
#include "gGraphView.h"
|
||||
|
||||
class gYAxis:public gLayer
|
||||
class gYSpacer:public Layer
|
||||
{
|
||||
public:
|
||||
gYSpacer(int spacer=20);
|
||||
virtual void paint(gGraph & w,int left,int top, int width, int height) {}
|
||||
|
||||
};
|
||||
|
||||
/*class gYGrid:public Layer
|
||||
{
|
||||
};*/
|
||||
|
||||
class gYAxis:public Layer
|
||||
{
|
||||
public:
|
||||
gYAxis(QColor col=QColor("black"));
|
||||
virtual ~gYAxis();
|
||||
virtual void Plot(gGraphWindow & w,float scrx,float scry);
|
||||
virtual void paint(gGraph & w,int left,int top, int width, int height);
|
||||
void SetShowMinorLines(bool b) { m_show_minor_lines=b; }
|
||||
void SetShowMajorLines(bool b) { m_show_major_lines=b; }
|
||||
bool ShowMinorLines() { return m_show_minor_lines; }
|
||||
|
@ -1,8 +1,8 @@
|
||||
/********************************************************************
|
||||
/*
|
||||
glcommon GL code & font stuff
|
||||
Copyright (c)2011 Mark Watkins <jedimark@users.sourceforge.net>
|
||||
License: GPL
|
||||
*********************************************************************/
|
||||
*/
|
||||
|
||||
#include <QApplication>
|
||||
#include <QFontMetrics>
|
||||
|
@ -1,8 +1,8 @@
|
||||
/********************************************************************
|
||||
/*
|
||||
glcommon GL code & font stuff Header
|
||||
Copyright (c)2011 Mark Watkins <jedimark@users.sourceforge.net>
|
||||
License: GPL
|
||||
*********************************************************************/
|
||||
*/
|
||||
|
||||
#ifndef GLCOMMON_H
|
||||
#define GLCOMMON_H
|
||||
|
@ -1,8 +1,8 @@
|
||||
/********************************************************************
|
||||
/*
|
||||
gLayer Headers
|
||||
Copyright (c)2011 Mark Watkins <jedimark@users.sourceforge.net>
|
||||
License: GPL
|
||||
*********************************************************************/
|
||||
*/
|
||||
|
||||
#ifndef GRAPHLAYER_H
|
||||
#define GRAPHLAYER_H
|
||||
@ -36,6 +36,7 @@ public:
|
||||
virtual bool isVisible() { return m_visible; }
|
||||
virtual bool isEmpty();
|
||||
inline const ChannelID & code() { return m_code; }
|
||||
|
||||
protected:
|
||||
Day *m_day;
|
||||
bool m_visible;
|
||||
|
@ -114,11 +114,11 @@ void InitMapsWithoutAwesomeInitializerLists()
|
||||
CPAP_PressureSupport=CPAP_CODES.Get(CT_Graph,QObject::tr("Pressure Support"),QObject::tr("Pressure Support"),"PS"),
|
||||
CPAP_Snore=CPAP_CODES.Get(CT_Graph,QObject::tr("Snore"),QObject::tr("Snore"),"Snore"),
|
||||
CPAP_Leak=CPAP_CODES.Get(CT_Graph,QObject::tr("Leak Rate"),QObject::tr("Leak Rate"),"Leak"),
|
||||
CPAP_RespiratoryRate=CPAP_CODES.Get(CT_Graph,QObject::tr("Respiratory Rate"),QObject::tr("Respiratory Rate"),"RR"),
|
||||
CPAP_RespiratoryRate=CPAP_CODES.Get(CT_Graph,QObject::tr("Respiratory Rate"),QObject::tr("Resp. Rate"),"RR"),
|
||||
CPAP_TidalVolume=CPAP_CODES.Get(CT_Graph,QObject::tr("Tidal Volume"),QObject::tr("Tidal Volume"),"TV"),
|
||||
CPAP_MinuteVentilation=CPAP_CODES.Get(CT_Graph,QObject::tr("Minute Ventilation"),QObject::tr("Minute Ventilation"),"MV"),
|
||||
CPAP_MinuteVentilation=CPAP_CODES.Get(CT_Graph,QObject::tr("Minute Ventilation"),QObject::tr("Minute Vent."),"MV"),
|
||||
CPAP_PatientTriggeredBreaths=CPAP_CODES.Get(CT_Graph,QObject::tr("Patient Triggered Breaths"),QObject::tr("Patient Trig Breaths"),"PTB"),
|
||||
CPAP_FlowLimitGraph=CPAP_CODES.Get(CT_Graph,QObject::tr("Flow Limitation Graph"),QObject::tr("Flow Limitation"),"FLG"),
|
||||
CPAP_FlowLimitGraph=CPAP_CODES.Get(CT_Graph,QObject::tr("Flow Limitation Graph"),QObject::tr("Flow Limit."),"FLG"),
|
||||
CPAP_TherapyPressure=CPAP_CODES.Get(CT_Graph,QObject::tr("Therapy Pressure"),QObject::tr("Therapy Pressure"),"TP"),
|
||||
CPAP_ExpiratoryPressure=CPAP_CODES.Get(CT_Graph,QObject::tr("Expiratory Pressure"),QObject::tr("Expiratory Pressure"),"EXP"),
|
||||
CPAP_RespiratoryEvent=CPAP_CODES.Get(CT_Graph,QObject::tr("Respiratory Event"),QObject::tr("Respiratory Event"),"RESPEv"),
|
||||
|
@ -57,7 +57,8 @@ SOURCES += main.cpp\
|
||||
Graphs/gSessionTime.cpp \
|
||||
qextserialport/qextserialport.cpp \
|
||||
Graphs/gSplitter.cpp \
|
||||
preferencesdialog.cpp
|
||||
preferencesdialog.cpp \
|
||||
Graphs/gGraphView.cpp
|
||||
|
||||
unix:SOURCES += qextserialport/posix_qextserialport.cpp
|
||||
unix:!macx:SOURCES += qextserialport/qextserialenumerator_unix.cpp
|
||||
@ -108,7 +109,8 @@ HEADERS += \
|
||||
qextserialport/qextserialport.h \
|
||||
qextserialport/qextserialenumerator.h \
|
||||
Graphs/gSplitter.h \
|
||||
preferencesdialog.h
|
||||
preferencesdialog.h \
|
||||
Graphs/gGraphView.h
|
||||
|
||||
|
||||
FORMS += \
|
||||
|
313
daily.cpp
313
daily.cpp
@ -29,40 +29,6 @@
|
||||
const int min_height=150;
|
||||
const int default_height=150;
|
||||
|
||||
MyScrollArea::MyScrollArea(QWidget *parent, Daily * daily)
|
||||
:QScrollArea(parent),m_daily(daily)
|
||||
{
|
||||
timer=new QTimer(this);
|
||||
m_time.start();
|
||||
}
|
||||
MyScrollArea::~MyScrollArea()
|
||||
{
|
||||
delete timer;
|
||||
}
|
||||
void MyScrollArea::scrollContentsBy(int dx, int dy)
|
||||
{
|
||||
QScrollArea::scrollContentsBy(dx,dy);
|
||||
//m_daily->RedrawGraphs();
|
||||
//gGraphWindow g;
|
||||
#ifdef Q_WS_MAC
|
||||
if (timer->isActive()) timer->stop();
|
||||
timer->setSingleShot(true);
|
||||
timer->setInterval(200);
|
||||
connect(timer,SIGNAL(timeout()),SLOT(UpdateGraphs()));
|
||||
timer->start();
|
||||
m_time.start();
|
||||
//m_daily->RedrawGraphs();
|
||||
#endif
|
||||
}
|
||||
void MyScrollArea::UpdateGraphs()
|
||||
{
|
||||
if (m_time.elapsed()<200)
|
||||
return;
|
||||
m_time.start();
|
||||
qDebug() << "Redraw!";
|
||||
m_daily->RedrawGraphs();
|
||||
}
|
||||
|
||||
Daily::Daily(QWidget *parent,QGLWidget * shared, MainWindow *mw)
|
||||
:QWidget(parent),mainwin(mw), ui(new Ui::Daily)
|
||||
{
|
||||
@ -75,8 +41,125 @@ Daily::Daily(QWidget *parent,QGLWidget * shared, MainWindow *mw)
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
layout=new QHBoxLayout(ui->graphMainArea);
|
||||
layout->setSpacing(0);
|
||||
layout->setMargin(0);
|
||||
layout->setContentsMargins(0,0,0,0);
|
||||
ui->graphMainArea->setLayout(layout);
|
||||
//ui->graphMainArea->setLayout(layout);
|
||||
|
||||
scrollArea=new MyScrollArea(ui->graphMainArea,this);
|
||||
ui->graphMainArea->setAutoFillBackground(false);
|
||||
|
||||
GraphView=new gGraphView(ui->graphMainArea);
|
||||
GraphView->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
|
||||
|
||||
scrollbar=new MyScrollBar(ui->graphMainArea);
|
||||
scrollbar->setOrientation(Qt::Vertical);
|
||||
scrollbar->setSizePolicy(QSizePolicy::Maximum,QSizePolicy::Expanding);
|
||||
scrollbar->setMaximumWidth(20);
|
||||
|
||||
GraphView->setScrollBar(scrollbar);
|
||||
layout->addWidget(GraphView,1);
|
||||
layout->addWidget(scrollbar,0);
|
||||
|
||||
|
||||
SF=new gGraph(GraphView,"Event Flags",180);
|
||||
FRW=new gGraph(GraphView,"Flow Rate",180);
|
||||
MP=new gGraph(GraphView,"Mask Pressure",180);
|
||||
PRD=new gGraph(GraphView,"Pressure",180);
|
||||
LEAK=new gGraph(GraphView,"Leak",180);
|
||||
SNORE=new gGraph(GraphView,"Snore",180);
|
||||
RR=new gGraph(GraphView,"Respiratory Rate",180);
|
||||
TV=new gGraph(GraphView,"Tidal Volume",180);
|
||||
MV=new gGraph(GraphView,"Minute Ventilation",180);
|
||||
FLG=new gGraph(GraphView,"Flow Limitation Graph",180);
|
||||
|
||||
gFlagsGroup *fg=new gFlagsGroup();
|
||||
fg->AddLayer((new gFlagsLine(CPAP_CSR,QColor("light green"),"CSR",false,FT_Span)));
|
||||
fg->AddLayer((new gFlagsLine(CPAP_ClearAirway,QColor("purple"),"CA",true)));
|
||||
fg->AddLayer((new gFlagsLine(CPAP_Obstructive,QColor("#40c0ff"),"OA",true)));
|
||||
fg->AddLayer((new gFlagsLine(CPAP_Apnea,QColor("dark green"),"A")));
|
||||
fg->AddLayer((new gFlagsLine(CPAP_Hypopnea,QColor("blue"),"H",true)));
|
||||
fg->AddLayer((new gFlagsLine(CPAP_FlowLimit,QColor("black"),"FL")));
|
||||
fg->AddLayer((new gFlagsLine(CPAP_RERA,QColor("gold"),"RE")));
|
||||
fg->AddLayer((new gFlagsLine(CPAP_VSnore,QColor("red"),"VS")));
|
||||
//fg->AddLayer(AddCPAP(new gFlagsLine(flags[8],QColor("dark green"),"U0E")));
|
||||
//fg->AddLayer(AddCPAP(new gFlagsLine(flags[10],QColor("red"),"VS2"));
|
||||
SF->AddLayer(AddCPAP(fg));
|
||||
SF->AddLayer(new gYSpacer(),LayerLeft,gYAxis::Margin);
|
||||
SF->AddLayer(new gXAxis(),LayerBottom,0,gXAxis::Margin);
|
||||
|
||||
PRD->AddLayer(AddCPAP(new gLineChart(CPAP_Pressure,QColor("dark green"),true)));
|
||||
PRD->AddLayer(AddCPAP(new gLineChart(CPAP_EPAP,Qt::blue,true)));
|
||||
PRD->AddLayer(AddCPAP(new gLineChart(CPAP_IPAP,Qt::red,true)));
|
||||
PRD->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
|
||||
PRD->AddLayer(new gXAxis(),LayerBottom,0,20);
|
||||
|
||||
gLineChart *l;
|
||||
l=new gLineChart(CPAP_FlowRate,Qt::black,false,false);
|
||||
AddCPAP(l);
|
||||
FRW->AddLayer(l);
|
||||
FRW->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
|
||||
FRW->AddLayer(new gXAxis(),LayerBottom,0,20);
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_CSR,QColor("light green"),"CSR",FT_Span)));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_Hypopnea,QColor("blue"),"H")));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_PressurePulse,QColor("red"),"PR",FT_Dot)));
|
||||
//FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_Pressure,QColor("white"),"P",FT_Dot)));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(PRS1_Unknown0B,QColor("blue"),"0B",FT_Dot)));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(PRS1_Unknown10,QColor("orange"),"10",FT_Dot)));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(PRS1_Unknown0E,QColor("yellow"),"0E",FT_Dot)));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_RERA,QColor("gold"),"RE")));
|
||||
//FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_Unknown0E,QColor("dark green"),"U0E")));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_Apnea,QColor("dark green"),"A")));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_VSnore,QColor("red"),"VS")));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_FlowLimit,QColor("black"),"FL")));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_Obstructive,QColor("#40c0ff"),"OA")));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_ClearAirway,QColor("purple"),"CA")));
|
||||
|
||||
LEAK->AddLayer(AddCPAP(new gLineChart(CPAP_Leak,Qt::darkYellow,true)));
|
||||
LEAK->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
|
||||
LEAK->AddLayer(new gXAxis(),LayerBottom,0,20);
|
||||
|
||||
SNORE->AddLayer(AddCPAP(new gLineChart(CPAP_Snore,Qt::darkGray,true)));
|
||||
SNORE->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
|
||||
SNORE->AddLayer(new gXAxis(),LayerBottom,0,20);
|
||||
|
||||
MP->AddLayer(AddCPAP(new gLineChart(CPAP_MaskPressure,Qt::blue,false)));
|
||||
MP->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
|
||||
MP->AddLayer(new gXAxis(),LayerBottom,0,20);
|
||||
|
||||
RR->AddLayer(AddCPAP(new gLineChart(CPAP_RespiratoryRate,Qt::darkMagenta,true)));
|
||||
RR->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
|
||||
RR->AddLayer(new gXAxis(),LayerBottom,0,20);
|
||||
|
||||
MV->AddLayer(AddCPAP(new gLineChart(CPAP_MinuteVentilation,Qt::darkCyan,true)));
|
||||
MV->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
|
||||
MV->AddLayer(new gXAxis(),LayerBottom,0,20);
|
||||
|
||||
TV->AddLayer(AddCPAP(new gLineChart(CPAP_TidalVolume,Qt::magenta,true)));
|
||||
TV->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
|
||||
TV->AddLayer(new gXAxis(),LayerBottom,0,20);
|
||||
|
||||
FLG->AddLayer(AddCPAP(new gLineChart(CPAP_FlowLimitGraph,Qt::darkBlue,true)));
|
||||
FLG->AddLayer(new gYAxis(),LayerLeft,gYAxis::Margin);
|
||||
FLG->AddLayer(new gXAxis(),LayerBottom,0,20);
|
||||
|
||||
//AddGraph(SF);
|
||||
//AddGraph(FRW);
|
||||
//AddGraph(PRD);
|
||||
|
||||
NoData=new QLabel(tr("No data"),ui->graphMainArea);
|
||||
NoData->setAlignment(Qt::AlignCenter);
|
||||
QFont font("FreeSans",20); //NoData->font();
|
||||
//font.setBold(true);
|
||||
NoData->setFont(font);
|
||||
layout->addWidget(NoData,1);
|
||||
NoData->hide();
|
||||
|
||||
layout->layout();
|
||||
|
||||
|
||||
/* scrollArea=new MyScrollArea(ui->graphMainArea,this);
|
||||
ui->graphLayout->addWidget(scrollArea,1);
|
||||
ui->graphLayout->setSpacing(0);
|
||||
ui->graphLayout->setMargin(0);
|
||||
@ -98,9 +181,6 @@ Daily::Daily(QWidget *parent,QGLWidget * shared, MainWindow *mw)
|
||||
//gSplitter(Qt::Vertical,ui->scrollArea);
|
||||
//splitter->setStyleSheet("QSplitter::handle { background-color: 'light grey'; }");
|
||||
//splitter->setHandleWidth(3);
|
||||
#ifdef Q_WS_MAC
|
||||
//splitter->setOpaqueResize(false);
|
||||
#endif
|
||||
|
||||
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
|
||||
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
|
||||
@ -142,7 +222,7 @@ Daily::Daily(QWidget *parent,QGLWidget * shared, MainWindow *mw)
|
||||
TAP=new gGraphWindow(NULL,"",(QGLWidget* )NULL);
|
||||
TAP_EAP=new gGraphWindow(NULL,"",(QGLWidget* )NULL);
|
||||
TAP_IAP=new gGraphWindow(NULL,"",(QGLWidget* )NULL);
|
||||
G_AHI=new gGraphWindow(NULL,"",(QGLWidget* )NULL);
|
||||
G_AHI=new gGraphWindow(NULL,"",(QGLWidget* )NULL); */
|
||||
|
||||
/*QGLFormat fmt;
|
||||
fmt.setDepth(false);
|
||||
@ -153,7 +233,7 @@ Daily::Daily(QWidget *parent,QGLWidget * shared, MainWindow *mw)
|
||||
//fmt.setDefaultFormat(fmt);
|
||||
offscreen_context=new QGLContext(fmt); */
|
||||
|
||||
SF->SetLeftMargin(SF->GetLeftMargin()+gYAxis::Margin);
|
||||
/*SF->SetLeftMargin(SF->GetLeftMargin()+gYAxis::Margin);
|
||||
SF->SetBlockZoom(true);
|
||||
SF->AddLayer(new gXAxis());
|
||||
SF->setMinimumHeight(min_height);
|
||||
@ -220,6 +300,7 @@ Daily::Daily(QWidget *parent,QGLWidget * shared, MainWindow *mw)
|
||||
g->ReportEmpty(true);
|
||||
AddCPAP(g);
|
||||
FRW->AddLayer(g);
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_CSR,QColor("light green"),"CSR",FT_Span)));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_Hypopnea,QColor("blue"),"H")));
|
||||
FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_PressurePulse,QColor("red"),"PR",FT_Dot)));
|
||||
//FRW->AddLayer(AddCPAP(new gLineOverlayBar(CPAP_Pressure,QColor("white"),"P",FT_Dot)));
|
||||
@ -313,7 +394,7 @@ Daily::Daily(QWidget *parent,QGLWidget * shared, MainWindow *mw)
|
||||
SPO2->AddLayer(new gYAxis());
|
||||
SPO2->AddLayer(AddOXI(new gLineChart(OXI_SPO2,Qt::blue,true)));
|
||||
SPO2->AddLayer(AddOXI(new gLineOverlayBar(OXI_SPO2Drop,Qt::red,"SC",FT_Bar)));
|
||||
SPO2->setMinimumHeight(min_height);
|
||||
SPO2->setMinimumHeight(min_height); */
|
||||
|
||||
/*fg=new gFlagsGroup();
|
||||
fg->AddLayer(AddOXI(new gFlagsLine(OXI_PulseChange,QColor("orange"),"PUL",true)));
|
||||
@ -332,7 +413,7 @@ Daily::Daily(QWidget *parent,QGLWidget * shared, MainWindow *mw)
|
||||
// SPO2->hide();
|
||||
// PULSE->hide();
|
||||
|
||||
gSegmentChart *seg;
|
||||
/*gSegmentChart *seg;
|
||||
|
||||
TAP_EAP->SetMargins(0,0,0,0);
|
||||
TAP_EAP->AddLayer(AddCPAP(seg=new gTAPGraph(CPAP_EPAP)));
|
||||
@ -362,12 +443,6 @@ Daily::Daily(QWidget *parent,QGLWidget * shared, MainWindow *mw)
|
||||
G_AHI->SetGradientBackground(false);
|
||||
G_AHI->hide();
|
||||
|
||||
NoData=new QLabel(tr("No data"),parental);
|
||||
NoData->setAlignment(Qt::AlignCenter);
|
||||
QFont font("FreeSans",20); //NoData->font();
|
||||
//font.setBold(true);
|
||||
NoData->setFont(font);
|
||||
NoData->hide();
|
||||
|
||||
splitter->addWidget(NoData);
|
||||
//int i=splitter->indexOf(NoData);
|
||||
@ -444,7 +519,7 @@ Daily::Daily(QWidget *parent,QGLWidget * shared, MainWindow *mw)
|
||||
GraphAction.push_back(action);
|
||||
}
|
||||
|
||||
} else show_graph_menu=NULL;
|
||||
} else show_graph_menu=NULL; */
|
||||
}
|
||||
|
||||
Daily::~Daily()
|
||||
@ -456,13 +531,7 @@ Daily::~Daily()
|
||||
// delete splitter;
|
||||
delete ui;
|
||||
}
|
||||
void Daily::AddGraph(gGraphWindow *w)
|
||||
{
|
||||
Graphs.push_back(w);
|
||||
|
||||
splitter->addWidget(w);
|
||||
w->SetSplitter(splitter);
|
||||
}
|
||||
void Daily::resizeEvent (QResizeEvent * event)
|
||||
{
|
||||
//const QSize &size=event->size();
|
||||
@ -603,7 +672,7 @@ void Daily::ResetGraphLayout()
|
||||
}
|
||||
void Daily::ShowHideGraphs()
|
||||
{
|
||||
int vis=0;
|
||||
/* int vis=0;
|
||||
for (int i=0;i<Graphs.size();i++) {
|
||||
if (Graphs[i]->isEmpty()) {
|
||||
GraphAction[i]->setVisible(false);
|
||||
@ -623,7 +692,7 @@ void Daily::ShowHideGraphs()
|
||||
//splitter->setMaximumHeight(vis*default_height);
|
||||
splitter->layout();
|
||||
//splitter->update();
|
||||
RedrawGraphs();
|
||||
RedrawGraphs(); */
|
||||
}
|
||||
void Daily::Load(QDate date)
|
||||
{
|
||||
@ -652,78 +721,22 @@ void Daily::Load(QDate date)
|
||||
UpdateCPAPGraphs(cpap);
|
||||
UpdateEventsTree(ui->treeWidget,cpap);
|
||||
|
||||
GraphView->ResetBounds();
|
||||
|
||||
GraphView->updateGL();
|
||||
if (!cpap && !oxi) {
|
||||
GraphLayout->setMinimumHeight(0);
|
||||
//splitter->setMinimumHeight(0);
|
||||
scrollbar->hide();
|
||||
GraphView->hide();
|
||||
NoData->setText(tr("No data for ")+date.toString(Qt::SystemLocaleLongDate));
|
||||
NoData->show();
|
||||
|
||||
for (int i=0;i<Graphs.size();i++) {
|
||||
GraphAction[i]->setVisible(false);
|
||||
Graphs[i]->hide();
|
||||
}
|
||||
spacer->hide();
|
||||
|
||||
} else {
|
||||
NoData->hide();
|
||||
int vis=0;
|
||||
scrollArea->setUpdatesEnabled(false);
|
||||
for (int i=0;i<Graphs.size();i++) {
|
||||
Graphs[i]->setUpdatesEnabled(false);
|
||||
if (Graphs[i]->isEmpty()) {
|
||||
GraphAction[i]->setVisible(false);
|
||||
Graphs[i]->hide();
|
||||
} else {
|
||||
GraphAction[i]->setVisible(true);
|
||||
if (GraphAction[i]->isChecked()) {
|
||||
Graphs[i]->ResetBounds();
|
||||
Graphs[i]->show();
|
||||
vis++;
|
||||
} else {
|
||||
Graphs[i]->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!cpap) {
|
||||
GraphAction[0]->setVisible(false);
|
||||
SF->hide();
|
||||
vis--;
|
||||
|
||||
}
|
||||
//splitter->layout();
|
||||
for (int i=0;i<Graphs.size();i++) {
|
||||
Graphs[i]->setUpdatesEnabled(true);
|
||||
}
|
||||
spacer->show();
|
||||
//splitter->addStrut(vis*default_height);
|
||||
//QSize aa(this->width(),vis*default_height);
|
||||
//splitter->SetMinimumSize(aa);
|
||||
//splitter->SetFixedSize(aa);
|
||||
|
||||
GraphLayout->setMinimumHeight(vis*default_height+20);
|
||||
|
||||
|
||||
//splitter->setMinimumHeight(0);
|
||||
//splitter->setMinimumHeight(vis*default_height);
|
||||
//if (vis>4) {
|
||||
//splitter->setMaximumHeight(vis*default_height);
|
||||
//} //else {
|
||||
// }
|
||||
// splitter->blockSignals(true);
|
||||
|
||||
splitter->setSpacing(0);
|
||||
splitter->setMargin(0);
|
||||
splitter->layout();
|
||||
scrollArea->setUpdatesEnabled(true);
|
||||
scrollArea->update();
|
||||
//ui->scrollArea->update();
|
||||
//splitter->layout();
|
||||
|
||||
// spacer->show();
|
||||
GraphView->show();
|
||||
scrollbar->show();
|
||||
}
|
||||
|
||||
//splitter->update();
|
||||
RedrawGraphs();
|
||||
//RedrawGraphs();
|
||||
|
||||
QString epr,modestr;
|
||||
float iap90,eap90;
|
||||
@ -740,7 +753,6 @@ void Daily::Load(QDate date)
|
||||
}
|
||||
modestr=channel[CPAP_Mode].optionString(mode);
|
||||
|
||||
|
||||
float ahi=(cpap->count(CPAP_Obstructive)+cpap->count(CPAP_Hypopnea)+cpap->count(CPAP_ClearAirway)+cpap->count(CPAP_Apnea))/cpap->hours();
|
||||
float csr=(100.0/cpap->hours())*(cpap->sum(CPAP_CSR)/3600.0);
|
||||
float uai=cpap->count(CPAP_Apnea)/cpap->hours();
|
||||
@ -808,34 +820,25 @@ void Daily::Load(QDate date)
|
||||
// ^^ Scratch that.. pie now includes text..
|
||||
|
||||
if (pref["EnableGraphSnapshots"].toBool()) { // AHI Pie Chart
|
||||
if (ahi+rei+fli>0) {
|
||||
html+="</tr>\n<tr><td colspan=4 align=center><i>"+tr("Event Breakdown")+"</i></td></tr>\n";
|
||||
G_AHI->setFixedSize(gwwidth,120);
|
||||
QPixmap pixmap=G_AHI->renderPixmap(gwwidth,120,false); //gwwidth,gwheight,false);
|
||||
QByteArray byteArray;
|
||||
QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
pixmap.save(&buffer, "PNG");
|
||||
html += "<tr><td colspan=4 align=center><img src=\"data:image/png;base64," + byteArray.toBase64() + "\"></td></tr>\n";
|
||||
} else {
|
||||
html += "<tr><td colspan=4 align=center><img src=\"qrc:/docs/0.0.gif\"></td></tr>\n";
|
||||
// if (ahi+rei+fli>0) {
|
||||
// html+="</tr>\n<tr><td colspan=4 align=center><i>"+tr("Event Breakdown")+"</i></td></tr>\n";
|
||||
// G_AHI->setFixedSize(gwwidth,120);
|
||||
// QPixmap pixmap=G_AHI->renderPixmap(gwwidth,120,false); //gwwidth,gwheight,false);
|
||||
// QByteArray byteArray;
|
||||
// QBuffer buffer(&byteArray); // use buffer to store pixmap into byteArray
|
||||
// buffer.open(QIODevice::WriteOnly);
|
||||
// pixmap.save(&buffer, "PNG");
|
||||
// html += "<tr><td colspan=4 align=center><img src=\"data:image/png;base64," + byteArray.toBase64() + "\"></td></tr>\n";
|
||||
// } else {
|
||||
// html += "<tr><td colspan=4 align=center><img src=\"qrc:/docs/0.0.gif\"></td></tr>\n";
|
||||
// }
|
||||
}
|
||||
}
|
||||
}
|
||||
html+="</table>"
|
||||
"<table cellspacing=0 cellpadding=0 border=0 width='100%'>\n";
|
||||
html+="</table>";
|
||||
html+="<table cellspacing=0 cellpadding=0 border=0 width='100%'>\n";
|
||||
if (cpap || oxi) {
|
||||
html+="<tr height='2'><td colspan=5 height='2'><hr></td></tr>\n";
|
||||
|
||||
/* if (mode==MODE_BIPAP) {
|
||||
html+="<tr><td colspan=4 align='center'><i>"+tr("90% EPAP ")+QString().sprintf("%.2f",eap90)+tr("cmH2O")+"</td></tr>\n"
|
||||
"<tr><td colspan=4 align='center'><i>"+tr("90% IPAP ")+QString().sprintf("%.2f",iap90)+tr("cmH2O")+"</td></tr>\n";
|
||||
} else if (mode==MODE_APAP) {
|
||||
html+=("<tr><td colspan=4 align='center'><i>")+tr("90% Auto Pressure ")+QString().sprintf("%.2f",p90)+("</i></td></tr>\n"); //cpap->summary_weighted_avg(CPAP_PressurePercentValue)
|
||||
} else if (mode==MODE_CPAP) {
|
||||
html+=("<tr><td colspan=4 align='center'><i>")+tr("CPAP Pressure ")+QString().sprintf("%.2f",cpap->max(CPAP_Pressure))+("</i></td></tr>\n");
|
||||
}*/
|
||||
|
||||
//html+=("<tr><td colspan=4 align=center> </td></tr>\n");
|
||||
|
||||
html+=("<tr><td> </td><td><b>Min</b></td><td><b>Avg</b></td><td><b>90%</b></td><td><b>Max</b></td></tr>");
|
||||
@ -876,7 +879,7 @@ void Daily::Load(QDate date)
|
||||
|
||||
if (cpap) {
|
||||
if (pref["EnableGraphSnapshots"].toBool()) {
|
||||
if (cpap->channelExists(CPAP_Pressure)) {
|
||||
/* if (cpap->channelExists(CPAP_Pressure)) {
|
||||
html+=("<tr><td colspan=4 align=center><i>")+tr("Time@Pressure")+("</i></td></tr>\n");
|
||||
TAP->setFixedSize(gwwidth,30);
|
||||
QPixmap pixmap=TAP->renderPixmap(gwwidth,30,false);
|
||||
@ -906,7 +909,8 @@ void Daily::Load(QDate date)
|
||||
buffer.open(QIODevice::WriteOnly);
|
||||
pixmap.save(&buffer, "PNG");
|
||||
html+="<tr><td colspan=4 align=center><img src=\"data:image/png;base64," + byteArray.toBase64() + "\"></td></tr>\n";
|
||||
}
|
||||
} */
|
||||
|
||||
}
|
||||
html+="</table><hr height=2><table cellpadding=0 cellspacing=0 border=0 width=100%>";
|
||||
html+="<tr><td align=center>SessionID</td><td align=center>Date</td><td align=center>Start</td><td align=center>End</td></tr>";
|
||||
@ -925,7 +929,7 @@ void Daily::Load(QDate date)
|
||||
html+="<hr><div align=center><i>One or more waveform record for this session had faulty source data. Some waveform overlay points may not match up correctly.</i></div>";
|
||||
}
|
||||
}
|
||||
html+="</html>";
|
||||
html+="</body></html>";
|
||||
|
||||
ui->webView->setHtml(html);
|
||||
|
||||
@ -1084,7 +1088,7 @@ void Daily::UpdateCPAPGraphs(Day *day)
|
||||
if (day) {
|
||||
day->OpenEvents();
|
||||
}
|
||||
for (QList<gLayer *>::iterator g=CPAPData.begin();g!=CPAPData.end();g++) {
|
||||
for (QList<Layer *>::iterator g=CPAPData.begin();g!=CPAPData.end();g++) {
|
||||
(*g)->SetDay(day);
|
||||
}
|
||||
};
|
||||
@ -1096,16 +1100,16 @@ void Daily::UpdateOXIGraphs(Day *day)
|
||||
if (day) {
|
||||
day->OpenEvents();
|
||||
}
|
||||
for (QList<gLayer *>::iterator g=OXIData.begin();g!=OXIData.end();g++) {
|
||||
for (QList<Layer *>::iterator g=OXIData.begin();g!=OXIData.end();g++) {
|
||||
(*g)->SetDay(day);
|
||||
}
|
||||
}
|
||||
|
||||
void Daily::RedrawGraphs()
|
||||
{
|
||||
for (int i=0;i<Graphs.size();i++) {
|
||||
/*for (int i=0;i<Graphs.size();i++) {
|
||||
Graphs[i]->updateGL();
|
||||
}
|
||||
} */
|
||||
}
|
||||
|
||||
void Daily::on_treeWidget_itemSelectionChanged()
|
||||
@ -1118,7 +1122,8 @@ void Daily::on_treeWidget_itemSelectionChanged()
|
||||
d=d.fromString(item->text(1),"yyyy-MM-dd HH:mm:ss");
|
||||
double st=(d.addSecs(-120)).toMSecsSinceEpoch();
|
||||
double et=(d.addSecs(120)).toMSecsSinceEpoch();
|
||||
FRW->SetXBounds(st,et);
|
||||
GraphView->SetXBounds(st,et);
|
||||
/*FRW->SetXBounds(st,et);
|
||||
MP->SetXBounds(st,et);
|
||||
SF->SetXBounds(st,et);
|
||||
PRD->SetXBounds(st,et);
|
||||
@ -1127,7 +1132,7 @@ void Daily::on_treeWidget_itemSelectionChanged()
|
||||
MV->SetXBounds(st,et);
|
||||
TV->SetXBounds(st,et);
|
||||
RR->SetXBounds(st,et);
|
||||
FLG->SetXBounds(st,et);
|
||||
FLG->SetXBounds(st,et); */
|
||||
}
|
||||
}
|
||||
|
||||
|
64
daily.h
64
daily.h
@ -8,40 +8,27 @@
|
||||
#define DAILY_H
|
||||
|
||||
|
||||
#include <QScrollArea>
|
||||
#include <QMenu>
|
||||
#include <QAction>
|
||||
#include <QWidget>
|
||||
#include <QTreeWidget>
|
||||
#include <QLabel>
|
||||
#include <QtOpenGL/QGLContext>
|
||||
#include <QScrollBar>
|
||||
#include <QWebPluginFactory>
|
||||
|
||||
#include <SleepLib/profiles.h>
|
||||
#include <Graphs/graphwindow.h>
|
||||
//#include <Graphs/graphwindow.h>
|
||||
#include "mainwindow.h"
|
||||
#include "Graphs/gSplitter.h"
|
||||
#include "Graphs/gGraphView.h"
|
||||
|
||||
//#include "Graphs/gSplitter.h"
|
||||
#include "Graphs/gLineChart.h"
|
||||
#include "Graphs/gFlagsLine.h"
|
||||
//#include "Graphs/gFlagsLine.h"
|
||||
namespace Ui {
|
||||
class Daily;
|
||||
}
|
||||
|
||||
class Daily;
|
||||
class MyScrollArea:public QScrollArea
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
MyScrollArea(QWidget * parent, Daily * daily);
|
||||
virtual ~MyScrollArea();
|
||||
protected slots:
|
||||
void UpdateGraphs();
|
||||
protected:
|
||||
virtual void scrollContentsBy(int dx, int dy);
|
||||
|
||||
Daily *m_daily;
|
||||
QTimer *timer;
|
||||
QTime m_time;
|
||||
};
|
||||
|
||||
class MainWindow;
|
||||
class Daily : public QWidget
|
||||
@ -53,7 +40,7 @@ public:
|
||||
~Daily();
|
||||
void ReloadGraphs();
|
||||
void ResetGraphLayout();
|
||||
QGLWidget *SharedWidget() { return SF; }
|
||||
QGLWidget *SharedWidget() { return GraphView; }
|
||||
void RedrawGraphs();
|
||||
|
||||
private slots:
|
||||
@ -86,23 +73,23 @@ private:
|
||||
//gPointData *tap,*tap_eap,*tap_iap,*g_ahi,*frw,*prd,*leak,*pressure_iap,*pressure_eap,*snore;
|
||||
//gPointData *pulse,*spo2,*rr,*mv,*tv,*mp,*flg,*ptb;
|
||||
|
||||
gFlagsGroup *fg;
|
||||
gGraphWindow *PRD,*FRW,*G_AHI,*TAP,*LEAK,*SF,*TAP_EAP,*TAP_IAP,*PULSE,*SPO2,
|
||||
//gFlagsGroup *fg;
|
||||
gGraph *PRD,*FRW,*G_AHI,*TAP,*LEAK,*SF,*TAP_EAP,*TAP_IAP,*PULSE,*SPO2,
|
||||
*SNORE,*RR,*MP,*MV,*TV,*FLG,*PTB,*OF,*INTPULSE,*INTSPO2, *THPR,
|
||||
*PLETHY,*TI,*TE, *RE, *IE;
|
||||
|
||||
gLineChart *pressure, *epap, *ipap;
|
||||
//gLineChart *pressure, *epap, *ipap;
|
||||
|
||||
QList<gLayer *> OXIData;
|
||||
QList<gLayer *> CPAPData;
|
||||
QVector<gGraphWindow *> Graphs;
|
||||
QList<Layer *> OXIData;
|
||||
QList<Layer *> CPAPData;
|
||||
//QVector<gGraph *> Graphs;
|
||||
QVector<QAction *> GraphAction;
|
||||
QGLContext *offscreen_context;
|
||||
|
||||
QList<int> splitter_sizes;
|
||||
gLayer * AddCPAP(gLayer *d) { CPAPData.push_back(d); return d; }
|
||||
gLayer * AddOXI(gLayer *d) { OXIData.push_back(d); return d; }
|
||||
void AddGraph(gGraphWindow *w);
|
||||
Layer * AddCPAP(Layer *d) { CPAPData.push_back(d); return d; }
|
||||
Layer * AddOXI(Layer *d) { OXIData.push_back(d); return d; }
|
||||
//void AddGraph(gGraph *w);
|
||||
void UpdateCPAPGraphs(Day *day);
|
||||
void UpdateOXIGraphs(Day *day);
|
||||
|
||||
@ -110,22 +97,15 @@ private:
|
||||
Ui::Daily *ui;
|
||||
Profile *profile;
|
||||
QDate previous_date;
|
||||
QScrollArea *scrollArea;
|
||||
QVBoxLayout *splitter;
|
||||
//QScrollArea *scrollArea;
|
||||
//QVBoxLayout *splitter;
|
||||
QLabel *NoData;
|
||||
QWidget *spacer;
|
||||
QMenu *show_graph_menu;
|
||||
QWidget *GraphLayout;
|
||||
gGraphView *GraphView;
|
||||
MyScrollBar *scrollbar;
|
||||
QHBoxLayout *layout;
|
||||
};
|
||||
|
||||
/*class AHIGraph:public QWebPluginFactory
|
||||
{
|
||||
public:
|
||||
AHIGraph(QObject * parent = 0);
|
||||
virtual ~AHIGraph();
|
||||
virtual QObject * create ( const QString & mimeType, const QUrl & url, const QStringList & argumentNames, const QStringList & argumentValues) const;
|
||||
virtual QList<Plugin> plugins () const;
|
||||
//virtual void refreshPlugins ();
|
||||
}; */
|
||||
|
||||
#endif // DAILY_H
|
||||
|
52
daily.ui
52
daily.ui
@ -32,22 +32,10 @@
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="orientation">
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<widget class="QCalendarWidget" name="calendar">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
@ -57,7 +45,13 @@
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>180</height>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
@ -67,7 +61,7 @@
|
||||
</font>
|
||||
</property>
|
||||
<property name="firstDayOfWeek">
|
||||
<enum>Qt::Sunday</enum>
|
||||
<enum>Qt::Monday</enum>
|
||||
</property>
|
||||
<property name="gridVisible">
|
||||
<bool>false</bool>
|
||||
@ -83,12 +77,24 @@
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>16777215</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="baseSize">
|
||||
<size>
|
||||
<width>300</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Sans Serif</family>
|
||||
@ -114,6 +120,12 @@
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QWebView" name="webView">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<family>Sans Serif</family>
|
||||
@ -476,14 +488,12 @@
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="graphMainArea" native="true">
|
||||
<layout class="QVBoxLayout" name="graphLayout">
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
|
@ -83,9 +83,10 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
|
||||
pref["AppName"]="SleepyHead";
|
||||
QString Version=QString("%1.%2.%3").arg(major_version).arg(minor_version).arg(revision_number);
|
||||
if (pref.Exists("VersionString") && pref["VersionString"]!=Version) {
|
||||
QMessageBox::warning(this,"Potential Crash Warning","This is a new version of SleepyHead. If you experience a crash right after clicking Ok, you will need to manually delete the SleepApp folder (it's located in your Documents folder), and things should then work normally.",QMessageBox::Ok);
|
||||
}
|
||||
//if (pref.Exists("VersionString") && pref["VersionString"]!=Version) {
|
||||
//QMessageBox::warning(this,"Potential Crash Warning","This is a new version of SleepyHead. If you experience a crash right after clicking Ok, you will need to manually delete the SleepApp folder (it's located in your Documents folder), and things should then work normally.",QMessageBox::Ok);
|
||||
QMessageBox::warning(this,"Notice","Hi, I'm currently in the middle of a large rewrite of graphing system components. Things aren't finished and some features are missing.. The mac/windows scrolling glitches show be gone now, but the new mouse handling isn't complete (ie, things will suck). This annoying message will go away when I'm done with it.",QMessageBox::Ok);
|
||||
//}
|
||||
pref["VersionString"]=Version;
|
||||
|
||||
if (!pref.Exists("Profile")) pref["Profile"]=getUserName();
|
||||
@ -122,9 +123,10 @@ MainWindow::MainWindow(QWidget *parent) :
|
||||
|
||||
//overview=new Overview(ui->tabWidget,daily->SharedWidget());
|
||||
//ui->tabWidget->insertTab(2,overview,tr("Overview"));
|
||||
|
||||
oximetry=new Oximetry(ui->tabWidget,daily->SharedWidget());
|
||||
ui->tabWidget->insertTab(3,oximetry,tr("Oximetry"));
|
||||
oximetry=NULL;
|
||||
//overview=NULL;
|
||||
// oximetry=new Oximetry(ui->tabWidget,daily->SharedWidget());
|
||||
//ui->tabWidget->insertTab(3,oximetry,tr("Oximetry"));
|
||||
|
||||
ui->tabWidget->setCurrentWidget(ui->welcome);
|
||||
|
||||
|
@ -16,7 +16,7 @@
|
||||
|
||||
const int major_version=0;
|
||||
const int minor_version=8;
|
||||
const int revision_number=2;
|
||||
const int revision_number=4;
|
||||
|
||||
namespace Ui {
|
||||
class MainWindow;
|
||||
|
@ -19,7 +19,7 @@ Oximetry::Oximetry(QWidget *parent,QGLWidget * shared) :
|
||||
ui(new Ui::Oximetry)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
port=NULL;
|
||||
/* port=NULL;
|
||||
portname="";
|
||||
QString prof=pref["Profile"].toString();
|
||||
profile=Profiles::Get(prof);
|
||||
@ -91,7 +91,7 @@ Oximetry::Oximetry(QWidget *parent,QGLWidget * shared) :
|
||||
Graphs[i]->SetSplitter(splitter);
|
||||
}
|
||||
|
||||
on_RefreshPortsButton_clicked();
|
||||
on_RefreshPortsButton_clicked(); */
|
||||
}
|
||||
|
||||
Oximetry::~Oximetry()
|
||||
|
Loading…
Reference in New Issue
Block a user