Skip to content

Commit

Permalink
Data tracer with custom tooltip WIP
Browse files Browse the repository at this point in the history
Signed-off-by: Alexis Jeandet <[email protected]>
  • Loading branch information
jeandet committed Jul 16, 2024
1 parent a9b40eb commit 03f4b90
Show file tree
Hide file tree
Showing 11 changed files with 538 additions and 24 deletions.
4 changes: 4 additions & 0 deletions SciQLopPlots/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ moc_headers = [
project_source_root + '/include/SciQLopPlots/SciQLopGraphResampler.hpp',
project_source_root + '/include/SciQLopPlots/SciQLopCurveResampler.hpp',
project_source_root + '/include/SciQLopPlots/SciQLopColorMapResampler.hpp',
project_source_root + '/include/SciQLopPlots/SciQLopTracer.hpp',
project_source_root + '/include/SciQLopPlots/QCPItemRichText.hpp',
project_source_root + '/qcustomplot-source/qcustomplot.h'
]

Expand Down Expand Up @@ -88,6 +90,8 @@ sources = moc_files \
'../src/SciQLopColorMap.cpp',
'../src/SciQLopColorMapResampler.cpp',
'../src/BufferProtocol.cpp',
'../src/SciQLopTracer.cpp',
'../src/QCPItemRichText.cpp',
'../qcustomplot-source/qcustomplot.cpp'
]

Expand Down
41 changes: 41 additions & 0 deletions include/SciQLopPlots/QCPItemRichText.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*------------------------------------------------------------------------------
-- This file is a part of the SciQLop Software
-- Copyright (C) 2024, Plasma Physics Laboratory - CNRS
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-------------------------------------------------------------------------------*/
/*-- Author : Alexis Jeandet
-- Mail : [email protected]
----------------------------------------------------------------------------*/
#pragma once

#include <QTextDocument>
#include <qcustomplot.h>

class QCPItemRichText : public QCPItemText
{
Q_OBJECT
QTextDocument m_textDocument;
QRect _boundingRect;

public:
QCPItemRichText(QCustomPlot* parentPlot);
virtual ~QCPItemRichText() { }
void setHtml(const QString& html);

protected:
virtual void draw(QCPPainter* painter) Q_DECL_OVERRIDE;
virtual QPointF anchorPixelPosition(int anchorId) const Q_DECL_OVERRIDE;
};
26 changes: 13 additions & 13 deletions include/SciQLopPlots/SciQLopPlot.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <SciQLopPlots/SciQLopCurve.hpp>
#include <SciQLopPlots/SciQLopGraph.hpp>
#include <SciQLopPlots/SciQLopPlotItem.hpp>
#include <SciQLopPlots/SciQLopTracer.hpp>
#include <optional>
#include <qcustomplot.h>

Expand All @@ -36,25 +37,15 @@ class SciQLopPlot : public QCustomPlot
Q_OBJECT

double m_scroll_factor = 1.;
TracerWithToolTip* m_tracer = nullptr;

public:
#ifndef BINDINGS_H
Q_SIGNAL void scroll_factor_changed(double factor);
#endif
explicit SciQLopPlot(QWidget* parent = nullptr) : QCustomPlot { parent }
{
using namespace Constants;
this->addLayer(LayersNames::Spans, this->layer(LayersNames::Main), QCustomPlot::limAbove);
this->layer(LayersNames::Spans)->setMode(QCPLayer::lmBuffered);
this->layer(LayersNames::Spans)->setVisible(true);
this->addLayer(
LayersNames::SpansBorders, this->layer(LayersNames::Spans), QCustomPlot::limAbove);
this->layer(LayersNames::SpansBorders)->setMode(QCPLayer::lmBuffered);
this->layer(LayersNames::SpansBorders)->setVisible(true);
this->setFocusPolicy(Qt::StrongFocus);
}
explicit SciQLopPlot(QWidget* parent = nullptr);

virtual ~SciQLopPlot() Q_DECL_OVERRIDE { }
virtual ~SciQLopPlot() Q_DECL_OVERRIDE;
inline QCPColorMap* addColorMap(QCPAxis* x, QCPAxis* y)
{
auto cm = new QCPColorMap(x, y);
Expand Down Expand Up @@ -99,6 +90,8 @@ class SciQLopPlot : public QCustomPlot
void set_scroll_factor(double factor) noexcept;
inline double scroll_factor() const noexcept { return m_scroll_factor; }

void enable_cursor(bool enable = true) noexcept;

protected:
virtual void mousePressEvent(QMouseEvent* event) override;
virtual void mouseMoveEvent(QMouseEvent* event) override;
Expand All @@ -109,6 +102,13 @@ class SciQLopPlot : public QCustomPlot

virtual bool event(QEvent* event) override;

void _update_tracer(const QPointF& pos);

bool _handle_tool_tip(QEvent* event);
QCPGraph* _nearest_graph(const QPointF& pos);
std::optional<std::tuple<double, double>> _nearest_data_point(
const QPointF& pos, QCPGraph* graph);

private:
void _wheel_pan(QCPAxis* axis, const double wheelSteps, const QPointF& pos);
void _wheel_zoom(QCPAxis* axis, const double wheelSteps, const QPointF& pos);
Expand Down
66 changes: 66 additions & 0 deletions include/SciQLopPlots/SciQLopTracer.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
/*------------------------------------------------------------------------------
-- This file is a part of the SciQLop Software
-- Copyright (C) 2024, Plasma Physics Laboratory - CNRS
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-------------------------------------------------------------------------------*/
/*-- Author : Alexis Jeandet
-- Mail : [email protected]
----------------------------------------------------------------------------*/
#pragma once
#include <SciQLopPlots/QCPItemRichText.hpp>
#include <qcustomplot.h>

class TracerWithToolTip
{
QCPItemRichText* m_tooltip = nullptr;
QCPItemTracer* m_tracer = nullptr;
double m_x = 0;
double m_y = 0;

public:
TracerWithToolTip(QCustomPlot* parent = nullptr);

virtual ~TracerWithToolTip();

void update_position(const QPointF& pos, bool replot = true);

inline void set_visible(bool visible)
{
m_tracer->setVisible(visible);
m_tooltip->setVisible(visible);
}

inline bool visible() const noexcept { return m_tracer->visible(); }
inline void replot() { m_tracer->layer()->replot(); }

inline void set_graph(QCPGraph* graph)
{
if (graph == nullptr && m_tracer->graph() != nullptr)
{
m_tracer->setGraph(nullptr);
set_visible(false);
replot();
}
else
{
if (m_tracer->graph() != graph)
{
m_tracer->setGraph(graph);
m_tracer->setPen(graph->pen());
}
}
}
};
112 changes: 112 additions & 0 deletions src/QCPItemRichText.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
/*------------------------------------------------------------------------------
-- This file is a part of the SciQLop Software
-- Copyright (C) 2024, Plasma Physics Laboratory - CNRS
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program; if not, write to the Free Software
-- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
-------------------------------------------------------------------------------*/
/*-- Author : Alexis Jeandet
-- Mail : [email protected]
----------------------------------------------------------------------------*/
#include "SciQLopPlots/QCPItemRichText.hpp"

QCPItemRichText::QCPItemRichText(QCustomPlot* parentPlot) : QCPItemText(parentPlot)
{
m_textDocument.setDefaultFont(mainFont());
m_textDocument.setDocumentMargin(0);
m_textDocument.setTextWidth(QWIDGETSIZE_MAX);
m_textDocument.setUndoRedoEnabled(false);
m_textDocument.setUseDesignMetrics(true);
}

void QCPItemRichText::setHtml(const QString& html)
{
m_textDocument.setHtml(html);
_boundingRect = QRect(0, 0, m_textDocument.idealWidth(), m_textDocument.size().height());
}

void QCPItemRichText::draw(QCPPainter* painter)
{
QPointF pos(position->pixelPosition());
QTransform transform = painter->transform();
transform.translate(pos.x(), pos.y());
if (!qFuzzyIsNull(mRotation))
transform.rotate(mRotation);
painter->setFont(mainFont());
auto textRect = _boundingRect;
QRect textBoxRect
= textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom());
QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect,
mPositionAlignment); // 0, 0 because the transform does the translation
textRect.moveTopLeft(textPos.toPoint() + QPoint(mPadding.left(), mPadding.top()));
textBoxRect.moveTopLeft(textPos.toPoint());
int clipPad = qCeil(mainPen().widthF());
QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad);

if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(clipRect())))
{
painter->setTransform(transform);
if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0)
|| (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0))
{
painter->setPen(mainPen());
painter->setBrush(mainBrush());
painter->drawRect(textBoxRect);
}
painter->setBrush(Qt::NoBrush);
painter->setPen(QPen(mainColor()));
painter->translate(getTextDrawPoint(QPointF(0, 0), textRect, mPositionAlignment));
m_textDocument.drawContents(painter);
}
}

QPointF QCPItemRichText::anchorPixelPosition(int anchorId) const
{
// get actual rect points (pretty much copied from draw function):
QPointF pos(position->pixelPosition());
QTransform transform;
transform.translate(pos.x(), pos.y());
if (!qFuzzyIsNull(mRotation))
transform.rotate(mRotation);
QRect textRect = _boundingRect;
QRectF textBoxRect
= textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom());
QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect,
mPositionAlignment); // 0, 0 because the transform does the translation
textBoxRect.moveTopLeft(textPos.toPoint());
QPolygonF rectPoly = transform.map(QPolygonF(textBoxRect));

switch (anchorId)
{
case aiTopLeft:
return rectPoly.at(0);
case aiTop:
return (rectPoly.at(0) + rectPoly.at(1)) * 0.5;
case aiTopRight:
return rectPoly.at(1);
case aiRight:
return (rectPoly.at(1) + rectPoly.at(2)) * 0.5;
case aiBottomRight:
return rectPoly.at(2);
case aiBottom:
return (rectPoly.at(2) + rectPoly.at(3)) * 0.5;
case aiBottomLeft:
return rectPoly.at(3);
case aiLeft:
return (rectPoly.at(3) + rectPoly.at(0)) * 0.5;
}

qDebug() << Q_FUNC_INFO << "invalid anchorId" << anchorId;
return {};
}
Loading

0 comments on commit 03f4b90

Please sign in to comment.