mirror of
https://gitlab.com/pholy/OSCAR-code.git
synced 2025-04-04 18:20:42 +00:00
772 lines
23 KiB
C++
772 lines
23 KiB
C++
/* gGraphView Header
|
|
*
|
|
* Copyright (c) 2019-2024 The OSCAR Team
|
|
* Copyright (c) 2011-2015 Mark Watkins
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU General Public
|
|
* License. See the file COPYING in the main directory of the source code
|
|
* for more details. */
|
|
|
|
#ifndef GGRAPHVIEW_H
|
|
#define GGRAPHVIEW_H
|
|
|
|
#include <QMainWindow>
|
|
#include <QScrollBar>
|
|
#include <QResizeEvent>
|
|
#include <QThread>
|
|
#include <QMutex>
|
|
#include <QSemaphore>
|
|
#include <QWaitCondition>
|
|
#include <QPixmap>
|
|
#include <QRect>
|
|
#include <QPixmapCache>
|
|
#include <QMenu>
|
|
#include <QCheckBox>
|
|
#include <QComboBox>
|
|
#include <QDoubleSpinBox>
|
|
#include <QToolButton>
|
|
#include <QTimer>
|
|
#include <QElapsedTimer>
|
|
#include <QGestureEvent>
|
|
#include <QPinchGesture>
|
|
|
|
#ifndef BROKEN_OPENGL_BUILD
|
|
#if QT_VERSION < QT_VERSION_CHECK(5,4,0)
|
|
#include <QGLWidget>
|
|
#else
|
|
#include <QOpenGLWidget>
|
|
#endif
|
|
#endif
|
|
|
|
#include <Graphs/gGraph.h>
|
|
#include <Graphs/glcommon.h>
|
|
#include <SleepLib/day.h>
|
|
|
|
|
|
class MinMaxWidget:public QWidget
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
explicit MinMaxWidget(gGraph * graph, QWidget *parent);
|
|
~MinMaxWidget() {}
|
|
|
|
void createLayout();
|
|
|
|
void setMin(double d) {
|
|
minbox->setValue(d);
|
|
}
|
|
void setMax(double d) {
|
|
maxbox->setValue(d);
|
|
}
|
|
double min() { return minbox->value(); }
|
|
double max() { return maxbox->value(); }
|
|
void setComboIndex(int i) { combobox->setCurrentIndex(i); }
|
|
int comboIndex() { return combobox->currentIndex(); }
|
|
|
|
// void setChecked(bool b) { checkbox->setChecked(b); }
|
|
// bool checked() { return checkbox->isChecked(); }
|
|
|
|
public slots:
|
|
void onMinChanged(double d);
|
|
void onMaxChanged(double d);
|
|
void onComboChanged(int idx);
|
|
void onResetClicked();
|
|
protected:
|
|
gGraph * graph;
|
|
QComboBox *combobox;
|
|
// QCheckBox *checkbox;
|
|
QDoubleSpinBox *minbox;
|
|
QDoubleSpinBox *maxbox;
|
|
double step;
|
|
QToolButton * reset;
|
|
};
|
|
|
|
enum FlagType { FT_Bar, FT_Dot, FT_Span };
|
|
|
|
|
|
//void setEmptyImage(QString text, QPixmap pixmap);
|
|
|
|
class MyLabel:public QWidget
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
MyLabel(QWidget * parent);
|
|
virtual ~MyLabel();
|
|
|
|
void setText(QString text);
|
|
void setAlignment(Qt::Alignment alignment);
|
|
|
|
void setFont(QFont & font);
|
|
QFont & font() { return m_font; }
|
|
|
|
virtual void paintEvent(QPaintEvent *);
|
|
|
|
QFont m_font;
|
|
QString m_text;
|
|
Qt::Alignment m_alignment;
|
|
QElapsedTimer time;
|
|
protected slots:
|
|
void doRedraw();
|
|
|
|
};
|
|
|
|
class gGraphView;
|
|
|
|
const int textque_max = 512;
|
|
|
|
/*! \struct TextQue
|
|
\brief Holds a single item of text for the drawing queue
|
|
*/
|
|
struct TextQue {
|
|
TextQue() {
|
|
}
|
|
TextQue(short x, short y, float angle, QString text, QColor color, QFont * font, bool antialias):
|
|
x(x), y(y), angle(angle), text(text), color(color), font(font), antialias(antialias)
|
|
{
|
|
}
|
|
TextQue(const TextQue & copy) {
|
|
x=copy.x;
|
|
y=copy.y;
|
|
text=copy.text;
|
|
angle=copy.angle;
|
|
color=copy.color;
|
|
font=copy.font;
|
|
antialias=copy.antialias;
|
|
}
|
|
|
|
//! \variable contains the x axis screen position to draw the text
|
|
short x;
|
|
//! \variable contains the y axis screen position to draw the text
|
|
short y;
|
|
//! \variable the angle in degrees for drawing rotated text
|
|
float angle;
|
|
//! \variable the actual text to draw
|
|
QString text;
|
|
//! \variable the color the text will be drawn in
|
|
QColor color;
|
|
//! \variable a pointer to the QFont to use to draw this text
|
|
QFont *font;
|
|
//! \variable whether to use antialiasing to draw this text
|
|
bool antialias;
|
|
};
|
|
|
|
struct TextQueRect {
|
|
TextQueRect() {
|
|
}
|
|
TextQueRect(QRectF r, quint32 flags, QString text, float angle, QColor color, QFont * font, bool antialias):
|
|
rect(r), flags(flags), text(text), angle(angle), color(color), font(font), antialias(antialias)
|
|
{
|
|
}
|
|
TextQueRect(const TextQueRect & copy) {
|
|
rect = copy.rect;
|
|
flags = copy.flags;
|
|
text = copy.text;
|
|
angle = copy.angle;
|
|
color = copy.color;
|
|
font = copy.font;
|
|
antialias = copy.antialias;
|
|
}
|
|
|
|
//! \variable contains the QRect containing the text object
|
|
QRectF rect;
|
|
//! \variable Qt alignment flags..
|
|
quint32 flags;
|
|
//! \variable the actual text to draw
|
|
QString text;
|
|
//! \variable the angle in degrees for drawing rotated text
|
|
float angle;
|
|
//! \variable the color the text will be drawn in
|
|
QColor color;
|
|
//! \variable a pointer to the QFont to use to draw this text
|
|
QFont *font;
|
|
//! \variable whether to use antialiasing to draw this text
|
|
bool antialias;
|
|
};
|
|
|
|
/*! \class MyScrollBar
|
|
\brief An custom scrollbar to interface with gGraphWindow
|
|
*/
|
|
class MyScrollBar : public QScrollBar
|
|
{
|
|
public:
|
|
MyScrollBar(QWidget *parent = nullptr)
|
|
: QScrollBar(parent)
|
|
{ }
|
|
|
|
void SendWheelEvent(QWheelEvent *e) {
|
|
wheelEvent(e);
|
|
}
|
|
};
|
|
|
|
/*! \class gThread
|
|
\brief Part of the Threaded drawing code
|
|
|
|
This is currently broken, as Qt didn't behave anyway, and it offered no performance improvement drawing-wise
|
|
*/
|
|
class gThread : public QThread
|
|
{
|
|
public:
|
|
gThread(gGraphView *g);
|
|
~gThread();
|
|
|
|
//! \brief Start thread process
|
|
void run();
|
|
|
|
//! \brief Kill thread process
|
|
void die() { m_running = false; }
|
|
QMutex mutex;
|
|
|
|
protected:
|
|
gGraphView *graphview;
|
|
volatile bool m_running;
|
|
};
|
|
|
|
/*! \class gToolTip
|
|
\brief Popup Tooltip to display information over the OpenGL graphs
|
|
*/
|
|
class gToolTip : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
//! \brief Initializes the ToolTip object, and connects the timeout to the gGraphView object
|
|
gToolTip(gGraphView *graphview);
|
|
virtual ~gToolTip();
|
|
|
|
/*! \fn virtual void display(QString text, int x, int y, int timeout=2000);
|
|
\brief Set the tooltips display message, position, and timeout value
|
|
*/
|
|
virtual void display(QString text, int x, int y, ToolTipAlignment align = TT_AlignCenter, int timeout = 0,bool alwaysShow=false);
|
|
|
|
//! \brief Draw the tooltip
|
|
virtual void paint(QPainter &paint); //actually paints it.
|
|
|
|
//! \brief Close the tooltip early.
|
|
virtual void cancel();
|
|
|
|
//! \brief Returns true if the tooltip is currently visible
|
|
virtual bool visible() { return m_visible; }
|
|
|
|
virtual QRect calculateRect(QPainter &painter);
|
|
|
|
protected:
|
|
gGraphView *m_graphview;
|
|
QTimer *timer;
|
|
QPoint m_pos;
|
|
int tw, th;
|
|
QString m_text;
|
|
bool m_visible;
|
|
int m_spacer;
|
|
QImage m_image;
|
|
ToolTipAlignment m_alignment;
|
|
QFont* m_font=defaultfont;
|
|
|
|
protected slots:
|
|
|
|
//! \brief Timeout to hide tooltip, and redraw without it.
|
|
virtual void timerDone();
|
|
};
|
|
|
|
class gParentToolTip : public gToolTip
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
gParentToolTip(gGraphView *graphview);
|
|
~gParentToolTip();
|
|
using gToolTip::display;
|
|
virtual void display(gGraphView* gv,QString text,int verticalOffset, int alignOffset , ToolTipAlignment align = TT_AlignCenter, int timeout = 0,QFont *font = defaultfont) ;
|
|
virtual void cancel();
|
|
virtual bool visible();
|
|
virtual QRect calculateRect(QPainter &painter);
|
|
using gToolTip::paint;
|
|
virtual void paint(QPainter &paint,int width,int height) ;
|
|
private:
|
|
int m_verticalOffset;
|
|
int m_alignOffset;
|
|
int m_width;
|
|
int m_height;
|
|
bool m_parent_visible;
|
|
int m_timeout;
|
|
protected slots:
|
|
virtual void timerDone();
|
|
};
|
|
|
|
struct SelectionHistoryItem {
|
|
SelectionHistoryItem() {
|
|
minx=maxx=0;
|
|
}
|
|
SelectionHistoryItem(quint64 m1, quint64 m2) {
|
|
minx=m1;
|
|
maxx=m2;
|
|
}
|
|
|
|
SelectionHistoryItem(const SelectionHistoryItem & copy) {
|
|
minx = copy.minx;
|
|
maxx = copy.maxx;
|
|
}
|
|
quint64 minx;
|
|
quint64 maxx;
|
|
|
|
SelectionHistoryItem& operator=(const SelectionHistoryItem& other) = default;
|
|
};
|
|
|
|
class MyDockWindow:public QMainWindow
|
|
{
|
|
public:
|
|
MyDockWindow(QWidget * parent, Qt::WindowFlags flags) : QMainWindow(parent, flags) {}
|
|
void closeEvent(QCloseEvent *event);
|
|
};
|
|
|
|
|
|
|
|
/*! \class gGraphView
|
|
\brief Main OpenGL Graph Area, derived from QGLWidget
|
|
|
|
This widget contains a list of graphs, and provides the means to display them, scroll via an attached
|
|
scrollbar, change the order around, and resize individual graphs.
|
|
|
|
It replaced QScrollArea and multiple QGLWidgets graphs, and a very buggy QSplitter.
|
|
|
|
It led to quite a performance increase over the old Qt method.
|
|
|
|
*/
|
|
class gGraphView
|
|
#ifdef BROKEN_OPENGL_BUILD
|
|
:public QWidget
|
|
#elif QT_VERSION < QT_VERSION_CHECK(5,4,0)
|
|
:public QGLWidget
|
|
#else
|
|
:public QOpenGLWidget
|
|
#endif
|
|
{
|
|
friend class gGraph;
|
|
Q_OBJECT
|
|
public:
|
|
/*! \fn explicit gGraphView(QWidget *parent = 0,gGraphView * shared=0);
|
|
\brief Constructs a new gGraphView object (main graph area)
|
|
\param QWidget * parent
|
|
\param gGraphView * shared
|
|
|
|
The shared parameter allows for OpenGL context sharing.
|
|
But this must not be shared with Printers snapshot gGraphView object,
|
|
or it will lead to display/font corruption
|
|
*/
|
|
explicit gGraphView(QWidget *parent = 0, gGraphView *shared = 0, QWidget *caller = 0);
|
|
virtual ~gGraphView();
|
|
void closeEvent(QCloseEvent * event) override;
|
|
|
|
//! \brief Add gGraph g to this gGraphView, in the requested graph-linkage group
|
|
void addGraph(gGraph *g, short group = 0);
|
|
|
|
//! \brief The width of the vertical text Title area for all graphs
|
|
static const int titleWidth = 30;
|
|
|
|
//! \brief The splitter is drawn inside this gap
|
|
static const int graphSpacer = 4;
|
|
|
|
bool contains(QString name) {
|
|
for (int i=0; i<m_graphs.size(); ++i) {
|
|
if (m_graphs[i]->name() == name) return true;
|
|
}
|
|
return false;
|
|
}
|
|
gGraph *operator [](QString name) {
|
|
for (int i=0; i<m_graphs.size(); ++i) {
|
|
if (m_graphs[i]->name() == name) return m_graphs[i];
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
//! \brief Finds the top pixel position of the supplied graph
|
|
float findTop(gGraph *graph);
|
|
|
|
//! \brief Returns the scaleY value, which is used when laying out less graphs than fit on the screen.
|
|
float scaleY() { return m_scaleY; }
|
|
|
|
//! \brief Sets the scaleY value, which is used when laying out less graphs than fit on the screen.
|
|
void setScaleY(float sy) { m_scaleY = sy; }
|
|
|
|
//! \brief Returns the current selected time range
|
|
void GetXBounds(qint64 &st, qint64 &et);
|
|
|
|
//! \brief Returns the maximum time range bounds
|
|
void GetRXBounds(qint64 &st, qint64 &et);
|
|
|
|
//! \brief Resets the time range to default for this day. Refreshing the display if refresh==true.
|
|
void ResetBounds(bool refresh = true);
|
|
|
|
//! \brief Supplies time range to all graph objects in linked group, refreshing if requested
|
|
void SetXBounds(qint64 minx, qint64 maxx, short group = 0, bool refresh = true);
|
|
|
|
QString settingsFilename (QString title,QString folderName="" ,QString ext=".shg");
|
|
|
|
//! \brief Saves the current graph order, heights, min & Max Y values to disk
|
|
void SaveSettings(QString title,QString folderName="");
|
|
|
|
//! \brief Loads the current graph order, heights, min & max Y values from disk
|
|
bool LoadSettings(QString title,QString folderName="");
|
|
|
|
//! \brief Saves the current (initial) graph order, heights, min & Max Y values for future recovery
|
|
void SaveDefaultSettings();
|
|
|
|
//! \brief Reset the current graph order, heights, min & max Y values to match default values
|
|
void resetGraphOrder(bool pinFirst);
|
|
|
|
//! \brief Reset the current graph order, heights, min & max Y values to match default values
|
|
void resetGraphOrder(bool pinFirst, const QList<QString> graphOrder);
|
|
|
|
//! \brief Returns the graph object matching the supplied name, nullptr if it does not exist.
|
|
gGraph *findGraph(QString name);
|
|
|
|
//! \brief Returns the graph object matching the graph title, nullptr if it does not exist.
|
|
gGraph *findGraphTitle(QString title);
|
|
|
|
//! \brief Returns true if control key is down during select operation
|
|
inline bool metaSelect() const { return m_metaselect; }
|
|
|
|
//! \brief Returns true if currently selecting data with mouse
|
|
inline bool selectionInProgress() const { return m_button_down; }
|
|
|
|
inline float printScaleX() const { return print_scaleX; }
|
|
inline float printScaleY() const { return print_scaleY; }
|
|
inline void setPrintScaleX(float x) { print_scaleX = x; }
|
|
inline void setPrintScaleY(float y) { print_scaleY = y; }
|
|
|
|
void saveHistory() {
|
|
history.push_front(SelectionHistoryItem(m_minx, m_maxx));
|
|
if (history.size() > max_history) {
|
|
history.pop_back();
|
|
}
|
|
}
|
|
|
|
//! \brief Returns true if all Graph objects contain NO day data. ie, graph area is completely empty.
|
|
bool isEmpty();
|
|
|
|
Day * day() { return m_day; }
|
|
|
|
//! \brief Tell all graphs to deslect any highlighted areas
|
|
void deselect();
|
|
|
|
QPoint pointClicked() const { return m_point_clicked; }
|
|
void setPointClicked(QPoint p) { m_point_clicked = p; }
|
|
|
|
//! \brief Set a redraw timer for ms milliseconds, clearing any previous redraw timer.
|
|
void timedRedraw(int ms=0);
|
|
|
|
gGraph *m_selected_graph;
|
|
gToolTip *m_tooltip;
|
|
gParentToolTip *m_parent_tooltip;
|
|
QTimer *timer;
|
|
|
|
//! \brief Add the Text information to the Text Drawing Queue (called by gGraphs renderText method)
|
|
void AddTextQue(const QString &text, QRectF rect, quint32 flags, float angle = 0.0,
|
|
QColor color = Qt::black, QFont *font = defaultfont, bool antialias = true);
|
|
|
|
//! \brief Add the Text information to the Text Drawing Queue (called by gGraphs renderText method)
|
|
void AddTextQue(const QString &text, short x, short y, float angle = 0.0,
|
|
QColor color = Qt::black, QFont *font = defaultfont, bool antialias = true);
|
|
|
|
// //! \brief Draw all Text in the text drawing queue
|
|
// void DrawTextQue();
|
|
|
|
//! \brief Draw all text components using QPainter object painter
|
|
void DrawTextQue(QPainter &painter);
|
|
|
|
//! \brief Draw all text components using QPainter object painter using Pixmapcache
|
|
void DrawTextQueCached(QPainter &painter);
|
|
|
|
//! \brief Returns number of graphs contained (whether they are visible or not)
|
|
int size() const { return m_graphs.size(); }
|
|
|
|
//! \brief Return individual graph by index value
|
|
gGraph *operator[](int i) { return m_graphs[i]; }
|
|
|
|
//! \brief Returns the custom scrollbar object linked to this gGraphArea
|
|
MyScrollBar *scrollBar() const { return m_scrollbar; }
|
|
|
|
//! \brief Sets the custom scrollbar object linked to this gGraphArea
|
|
void setScrollBar(MyScrollBar *sb);
|
|
|
|
//! \brief Calculates the correct scrollbar parameters for all visible, non empty graphs.
|
|
void updateScrollBar();
|
|
|
|
//! \brief Called on resize, fits graphs when too few to show, by scaling to fit screen size. Calls updateScrollBar()
|
|
void updateScale(); // update scale & Scrollbar
|
|
|
|
//! \brief Returns a count of all visible, non-empty Graphs.
|
|
int visibleGraphs();
|
|
|
|
//! \brief Returns the horizontal travel of the mouse, for use in Mouse Handling code.
|
|
int horizTravel() const { return m_horiz_travel; }
|
|
|
|
//! \brief Sets the message displayed when there are no graphs to draw
|
|
void setEmptyText(QString s) { m_emptytext = s; }
|
|
|
|
//! \brief Returns the message displayed when there are no graphs to draw
|
|
QString emptyText() { return m_emptytext; }
|
|
|
|
//! \brief Sets the message displayed when there are no graphs to draw
|
|
void setEmptyImage(QPixmap pm) { this->m_emptyimage = pm; }
|
|
|
|
inline const float &devicePixelRatio() { return m_dpr; }
|
|
void setDevicePixelRatio(float dpr) { m_dpr = dpr; }
|
|
|
|
#ifdef ENABLE_THREADED_DRAWING
|
|
QMutex text_mutex;
|
|
QMutex gl_mutex;
|
|
QSemaphore *masterlock;
|
|
bool useThreads() { return m_idealthreads > 1; }
|
|
QVector<gThread *> m_threads;
|
|
int m_idealthreads;
|
|
QMutex dl_mutex;
|
|
#endif
|
|
|
|
//! \brief Sends day object to be distributed to all Graphs Layers objects
|
|
void setDay(Day *day);
|
|
|
|
//! \brief pops a graph off the list for multithreaded drawing code
|
|
gGraph *popGraph(); // exposed for multithreaded drawing
|
|
|
|
//! \brief Hides the splitter, used in report printing code
|
|
void hideSplitter() { m_showsplitter = false; }
|
|
|
|
//! \brief Re-enabled the in-between graph splitters.
|
|
void showSplitter() { m_showsplitter = true; }
|
|
|
|
//! \brief Trash all graph objects listed (without destroying Graph contents)
|
|
void trashGraphs(bool destroy);
|
|
|
|
//! \brief Enable or disable the Text Pixmap Caching system preference overide
|
|
void setUsePixmapCache(bool b) { use_pixmap_cache = b; }
|
|
|
|
//! \brief Graph drawing routines, returns true if there weren't any graphs to draw
|
|
bool renderGraphs(QPainter &painter);
|
|
|
|
//! \brief Used internally by graph mousehandler to set modifier state
|
|
void setMetaSelect(bool b) { m_metaselect = b; }
|
|
|
|
//! \brief The current time the mouse pointer is hovering over
|
|
inline double currentTime() { return m_currenttime; }
|
|
|
|
//! \brief Returns a context formatted text string with the currently selected time range in days
|
|
QString getRangeInDaysString();
|
|
|
|
//! \brief Returns a context formatted text string with the currently selected time range
|
|
QString getRangeString();
|
|
|
|
Layer * findLayer(gGraph * graph, LayerType type);
|
|
|
|
void populateMenu(gGraph *);
|
|
QMenu * limits_menu;
|
|
QMenu * lines_menu;
|
|
QMenu * plots_menu;
|
|
|
|
QMenu * oximeter_menu;
|
|
QMenu * cpap_menu;
|
|
|
|
|
|
inline void setCurrentTime(double time) {
|
|
m_currenttime = time;
|
|
}
|
|
|
|
inline QPoint currentMousePos() const { return m_mouse; }
|
|
|
|
void dumpInfo();
|
|
void resetMouse() { m_mouse = QPoint(0,0); }
|
|
|
|
void getSelectionTimes(qint64 & start, qint64 & end);
|
|
|
|
//! \brief Whether to show a little authorship message down the bottom of empty graphs.
|
|
void setShowAuthorMessage(bool b) { m_showAuthorMessage = b; }
|
|
|
|
// for profiling purposes, a count of lines drawn in a single frame
|
|
int lines_drawn_this_frame;
|
|
int quads_drawn_this_frame;
|
|
int strings_drawn_this_frame;
|
|
int strings_cached_this_frame;
|
|
|
|
QVector<SelectionHistoryItem> history;
|
|
|
|
static MyDockWindow * dock;
|
|
protected:
|
|
|
|
bool event(QEvent * event) Q_DECL_OVERRIDE;
|
|
|
|
bool gestureEvent(QGestureEvent * event);
|
|
bool pinchTriggered(QPinchGesture * gesture);
|
|
|
|
|
|
void leaveEvent (QEvent * event) override;
|
|
|
|
//! \brief The heart of the drawing code
|
|
#ifdef BROKEN_OPENGL_BUILD
|
|
void paintEvent(QPaintEvent *) override;
|
|
#else
|
|
void paintGL() override;
|
|
#endif
|
|
//! \brief Calculates the sum of all graph heights
|
|
float totalHeight();
|
|
|
|
//! \brief Calculates the sum of all graph heights, taking scaling into consideration
|
|
float scaleHeight();
|
|
|
|
//! \brief Update the OpenGL area when the screen is resized
|
|
void resizeEvent(QResizeEvent *) override;
|
|
|
|
//! \brief Set the Vertical offset (used in scrolling)
|
|
void setOffsetY(int offsetY);
|
|
|
|
//! \brief Set the Horizontal offset (not used yet)
|
|
void setOffsetX(int offsetX);
|
|
|
|
//! \brief Mouse Moved somewhere in main gGraphArea, propagates to the individual graphs
|
|
void mouseMoveEvent(QMouseEvent *event) override;
|
|
//! \brief Mouse Button Press Event somewhere in main gGraphArea, propagates to the individual graphs
|
|
void mousePressEvent(QMouseEvent *event) override;
|
|
//! \brief Mouse Button Release Event somewhere in main gGraphArea, propagates to the individual graphs
|
|
void mouseReleaseEvent(QMouseEvent *event) override;
|
|
//! \brief Mouse Button Double Click Event somewhere in main gGraphArea, propagates to the individual graphs
|
|
void mouseDoubleClickEvent(QMouseEvent *event) override;
|
|
//! \brief Mouse Wheel Event somewhere in main gGraphArea, propagates to the individual graphs
|
|
void wheelEvent(QWheelEvent *event) override;
|
|
//! \brief Keyboard event while main gGraphArea has focus.
|
|
void keyPressEvent(QKeyEvent *event) override;
|
|
//! \brief Keyboard event while main gGraphArea has focus.
|
|
void keyReleaseEvent(QKeyEvent *event) override;
|
|
|
|
//! \brief Add Graph to drawing queue, mainly for the benefit of multithreaded drawing code
|
|
void queGraph(gGraph *, int originX, int originY, int width, int height);
|
|
|
|
|
|
Day *m_day;
|
|
|
|
//! \brief the list of graphs to draw this frame
|
|
QList<gGraph *> m_drawlist;
|
|
|
|
//! \brief Linked graph object containing shared GL Context (in this app, daily view's gGraphView)
|
|
gGraphView *m_shared;
|
|
|
|
//! \brief List of all graphs contained in this area
|
|
QList<gGraph *> m_graphs;
|
|
|
|
//! \brief List of all graphs contained, indexed by title
|
|
QHash<QString, gGraph *> m_graphsbyname;
|
|
|
|
//! \brief List of initial settings of all graphs contained in this area
|
|
QList<gGraph *> m_default_graphs;
|
|
|
|
//! \variable Vertical scroll offset (adjusted when scrollbar gets moved)
|
|
int m_offsetY;
|
|
//! \variable Horizontal scroll offset (unused, but can be made to work if necessary)
|
|
int m_offsetX;
|
|
//! \variable Scale used to enlarge graphs when less graphs than can fit on screen.
|
|
float m_scaleY;
|
|
float m_dpr;
|
|
|
|
bool m_sizer_dragging;
|
|
int m_sizer_index;
|
|
|
|
bool m_button_down;
|
|
QPoint m_point_clicked;
|
|
QPoint m_point_released;
|
|
bool m_metaselect;
|
|
|
|
QPoint m_sizer_point;
|
|
int m_horiz_travel;
|
|
|
|
MyScrollBar *m_scrollbar;
|
|
QTimer *redrawtimer;
|
|
|
|
bool m_graph_dragging;
|
|
int m_graph_index;
|
|
|
|
qint64 pinch_min, pinch_max;
|
|
|
|
//! \brief List of all queue text to draw.. not sure why I didn't use a vector here.. Might of been a leak issue
|
|
QVector<TextQue> m_textque;
|
|
|
|
//! \brief ANother text que with rect alignment capabilities...
|
|
QVector<TextQueRect> m_textqueRect;
|
|
|
|
int m_lastxpos, m_lastypos;
|
|
|
|
QString m_emptytext;
|
|
QPixmap m_emptyimage;
|
|
|
|
bool m_showsplitter;
|
|
|
|
// msec in epoch of first day and last day of range
|
|
qint64 m_minx, m_maxx;
|
|
|
|
QVector<SelectionHistoryItem> fwd_history;
|
|
float print_scaleX, print_scaleY;
|
|
|
|
QPixmap previous_day_snapshot;
|
|
QPixmap current_day_snapshot;
|
|
bool m_fadingOut;
|
|
bool m_fadingIn;
|
|
bool m_limbo;
|
|
bool m_fadedir;
|
|
bool m_inAnimation;
|
|
bool m_blockUpdates;
|
|
|
|
QPoint m_mouse;
|
|
double m_currenttime;
|
|
|
|
QTime m_animationStarted;
|
|
|
|
bool use_pixmap_cache;
|
|
|
|
QPixmapCache pixmapcache;
|
|
|
|
QElapsedTimer horizScrollTime, vertScrollTime;
|
|
QMenu * context_menu;
|
|
QAction * pin_action;
|
|
QAction * popout_action;
|
|
QPixmap pin_icon;
|
|
gGraph *pin_graph;
|
|
gGraph *popout_graph;
|
|
|
|
QAction * snap_action;
|
|
|
|
QAction * zoom100_action;
|
|
QWidget * caller;
|
|
|
|
bool m_showAuthorMessage;
|
|
|
|
signals:
|
|
void updateCurrentTime(double);
|
|
void updateRange(double,double);
|
|
void GraphsChanged();
|
|
void XBoundsChanged(qint64 ,qint64);
|
|
|
|
public slots:
|
|
//! \brief Callback from the ScrollBar, to change scroll position
|
|
void scrollbarValueChanged(int val);
|
|
|
|
//! \brief Simply refreshes the GL view, called when timeout expires.
|
|
void refreshTimeout();
|
|
|
|
//! \brief Call UpdateGL unless animation is in progress
|
|
void redraw();
|
|
|
|
//! \brief Resets all contained graphs to have a uniform height.
|
|
void resetLayout();
|
|
|
|
void resetZoom();
|
|
|
|
void dataChanged();
|
|
|
|
|
|
bool hasSnapshots();
|
|
|
|
void popoutGraph();
|
|
void togglePin();
|
|
protected slots:
|
|
void onLinesClicked(QAction *);
|
|
void onPlotsClicked(QAction *);
|
|
void onOverlaysClicked(QAction *);
|
|
void onSnapshotGraphToggle();
|
|
};
|
|
|
|
#endif // GGRAPHVIEW_H
|