Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // graphwidget.h
- #ifndef GRAPHWIDGET_H
- #define GRAPHWIDGET_H
- #include <QtGui/QWidget>
- #include <QtGui/QPainter>
- #include <QtCore/QVector>
- #include <QtCore/QPointF>
- #include <QtCore/QSet>
- #include <QtGui/QMouseEvent>
- #include <QtCore/QTime>
- #include <QtCore/QDebug>
- #include <cmath>
- class Path {
- QVector < QPointF > v_data;
- QColor s_color;
- public:
- inline QColor color() { return s_color; }
- inline void setColor(QColor clr) { s_color = clr; }
- inline QVector < QPointF > data() { return v_data; }
- inline QPointF& operator[] (int i) { return v_data[i]; }
- inline void addPoint(const QPointF& pnt) { v_data.append(pnt); }
- inline int size() { return v_data.size(); }
- void resize(int size) { v_data.resize(size); }
- Path(const QVector<double> &x, const QVector<double> &y);
- Path();
- };
- class GraphWidget : public QWidget
- {
- QSet <Path*> paths;
- QPointF trans;
- double s_scale;
- QPoint prevPos;
- protected:
- virtual void paintEvent(QPaintEvent*);
- virtual void mouseMoveEvent ( QMouseEvent *);
- virtual void mousePressEvent ( QMouseEvent *);
- virtual void mouseDoubleClickEvent ( QMouseEvent *);
- virtual void keyPressEvent(QKeyEvent *);
- virtual void wheelEvent(QWheelEvent*);
- public:
- static const int defaultScale = 40;
- static const int maxScale = 100;
- static const int minScale = 3;
- inline int xToCanvX(double a_x) { return a_x*s_scale + trans.x() + width()/2; }
- inline int yToCanvY(double a_y) { return -a_y*s_scale + trans.y() + height()/2; }
- inline double canvXToDec(int a_x) { return (a_x - trans.x() - width()/2)/s_scale; }
- inline double canvYToDec(int a_y) { return (-a_y + trans.y() + height()/2)/s_scale; }
- inline double minX() { return canvXToDec(0); }
- inline double maxX() { return canvXToDec(width()); }
- inline void setScale(double s) { if (s>minScale && s<maxScale) s_scale = s; }
- inline double scale() { return s_scale; }
- bool addPath(Path* p);
- Path* takePath(Path* p);
- void clearPaths(bool del = false);
- inline int pathCount() { return paths.size(); }
- GraphWidget(QWidget *parent=NULL);
- };
- #endif // GRAPHWIDGET_H
- // graphwidget.cpp
- #include "graphwidget.h"
- Path::Path(const QVector<double> &x, const QVector<double> &y)
- {
- Path();
- int N = std::min(x.size(), y.size());
- for (int i=0; i<=N; i++)
- {
- v_data.append(QPointF(x[i], y[i]));
- }
- }
- Path::Path() : s_color(Qt::red)
- {
- }
- GraphWidget::GraphWidget(QWidget *parent/*=NULL*/) : QWidget(parent), trans(0, 0), s_scale(defaultScale)
- {
- setFocusPolicy(Qt::StrongFocus);
- }
- bool GraphWidget::addPath(Path* p)
- {
- if (!paths.contains(p))
- {
- paths.insert(p);
- return true;
- }
- else
- return false;
- }
- Path* GraphWidget::takePath(Path *p)
- {
- paths.remove(p);
- return p;
- }
- void GraphWidget::clearPaths(bool del /* = no */)
- {
- if (del)
- foreach (Path* p, paths)
- delete p;
- paths.clear();
- }
- void GraphWidget::paintEvent(QPaintEvent *event)
- {
- QTime t; t.start();
- QPainter p(this);
- p.fillRect(this->rect(), Qt::white);
- p.drawLine( 0, height()/2 + trans.y(), width(), height()/2 + trans.y() );
- p.drawLine( width()/2 + trans.x(), 0, width()/2 + trans.x(), height() );
- int i;
- int dash3;
- const int dashL=3;
- int dashF=height()/2 - dashL/2 + trans.y();
- int dashT=dashF+dashL;
- int maxp = ceil(canvXToDec(width()));
- for (i=floor(canvXToDec(0)); i <= maxp ; i++)
- {
- dash3 = xToCanvX(i);
- p.drawLine(dash3, dashF, dash3, dashT);
- p.drawText(dash3, dashF, QString::number(i));
- }
- dashF = width()/2 - dashL/2 + trans.x();
- dashT = dashF+dashL;
- maxp = ceil(canvYToDec(0));
- int toI = std::min(maxp, -1);
- for (i=floor(canvYToDec(height())); i <= toI; i++)
- {
- dash3 = yToCanvY(i);
- p.drawLine(dashF, dash3, dashT, dash3);
- p.drawText(dashT, dash3, QString::number(i));
- }
- for (i=std::min(maxp+1, 1); i <= maxp; i++) // longer, but i don't want "if" here
- {
- dash3 = yToCanvY(i);
- p.drawLine(dashF, dash3, dashF+dashL, dash3);
- p.drawText(dashF+dashL, dash3, QString::number(i));
- }
- QPointF fr, to;
- p.setRenderHint(QPainter::Antialiasing, true);
- foreach (Path *path, paths)
- {
- if (path->size()<=0)
- break;
- p.setPen(path->color());
- for (i=1; i<path->size(); i++)
- {
- p.drawLine( xToCanvX((*path)[i-1].x()), yToCanvY((*path)[i-1].y()),
- xToCanvX((*path)[i].x()), yToCanvY((*path)[i].y()) );
- }
- }
- p.end();
- qDebug() << "Render time: " << t.elapsed();
- }
- void GraphWidget::mousePressEvent(QMouseEvent *event)
- {
- prevPos = event->pos();
- }
- void GraphWidget::mouseMoveEvent(QMouseEvent *event)
- {
- trans += event->pos() - prevPos;
- prevPos = event->pos();
- repaint();
- }
- void GraphWidget::mouseDoubleClickEvent(QMouseEvent *event)
- {
- trans.setX(0);
- trans.setY(0);
- s_scale = defaultScale;
- repaint();
- }
- void GraphWidget::keyPressEvent(QKeyEvent *event)
- {
- double oldscale = s_scale;
- switch (event->key())
- {
- case Qt::Key_Plus:
- setScale(s_scale * 1.5);break;
- case Qt::Key_Minus:
- setScale(s_scale/1.5);break;
- case Qt::Key_0:
- s_scale = defaultScale;
- trans.setX(0);
- trans.setY(0);
- break;
- case Qt::Key_Up:
- trans.setY(trans.y()-10);break;
- case Qt::Key_Down:
- trans.setY(trans.y()+10);break;
- case Qt::Key_Left:
- trans.setX(trans.x()-10);break;
- case Qt::Key_Right:
- trans.setX(trans.x()+10);break;
- }
- if (oldscale != s_scale)
- repaint();
- }
- void GraphWidget::wheelEvent(QWheelEvent *e)
- {
- setScale(s_scale*std::pow(1.5, e->delta() / 100));
- repaint();
- }
Advertisement
Add Comment
Please, Sign In to add comment