##// END OF EJS Templates
Fix the close button on the graphs and multi selection in the same graph
Fix the close button on the graphs and multi selection in the same graph

File last commit:

r1051:ea6e09e4a905
r1054:f391b1d9fb19
Show More
VisualizationSelectionZoneItem.cpp
343 lines | 11.7 KiB | text/x-c | CppLexer
/ gui / src / Visualization / VisualizationSelectionZoneItem.cpp
Display of selection zones on a graph
r1044 #include "Visualization/VisualizationSelectionZoneItem.h"
multi selection of zones
r1049 const QString &DEFAULT_COLOR = QStringLiteral("#E79D41");
Display of selection zones on a graph
r1044 struct VisualizationSelectionZoneItem::VisualizationSelectionZoneItemPrivate {
QCustomPlot *m_Plot;
double m_T1 = 0;
double m_T2 = 0;
QColor m_Color;
bool m_IsEditionEnabled = true;
double m_MovedOrinalT1 = 0;
double m_MovedOrinalT2 = 0;
QCPItemStraightLine *m_LeftLine;
QCPItemStraightLine *m_RightLine;
QCPItemText *m_NameLabelItem = nullptr;
enum class EditionMode { NoEdition, ResizeLeft, ResizeRight, Move };
EditionMode m_CurrentEditionMode;
Resize and move of multiple zones together
r1050 QVector<VisualizationSelectionZoneItem *> m_AssociatedEditedZones;
Display of selection zones on a graph
r1044 VisualizationSelectionZoneItemPrivate(QCustomPlot *plot)
: m_Plot(plot), m_Color(Qt::blue), m_CurrentEditionMode(EditionMode::NoEdition)
{
}
void updatePosition(VisualizationSelectionZoneItem *item)
{
item->topLeft->setCoords(m_T1, 0);
item->bottomRight->setCoords(m_T2, 1);
}
EditionMode getEditionMode(const QPoint &pos, const VisualizationSelectionZoneItem *zoneItem)
{
auto distanceLeft = m_LeftLine->selectTest(pos, false);
auto distanceRight = m_RightLine->selectTest(pos, false);
drag of selection zones
r1047 auto distance = zoneItem->selectTest(pos, false);
Display of selection zones on a graph
r1044
if (distanceRight <= distance) {
return VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight;
}
else if (distanceLeft <= distance) {
return VisualizationSelectionZoneItemPrivate::EditionMode::ResizeLeft;
}
return VisualizationSelectionZoneItemPrivate::EditionMode::Move;
}
Resize and move of multiple zones together
r1050
double pixelSizeToAxisXSize(double pixels)
{
auto axis = m_Plot->axisRect()->axis(QCPAxis::atBottom);
return axis->pixelToCoord(pixels) - axis->pixelToCoord(0);
}
Display of selection zones on a graph
r1044 };
VisualizationSelectionZoneItem::VisualizationSelectionZoneItem(QCustomPlot *plot)
: QCPItemRect(plot),
impl{spimpl::make_unique_impl<VisualizationSelectionZoneItemPrivate>(plot)}
{
topLeft->setTypeX(QCPItemPosition::ptPlotCoords);
topLeft->setTypeY(QCPItemPosition::ptAxisRectRatio);
bottomRight->setTypeX(QCPItemPosition::ptPlotCoords);
bottomRight->setTypeY(QCPItemPosition::ptAxisRectRatio);
multi selection of zones
r1049 setSelectable(false);
Display of selection zones on a graph
r1044
impl->m_RightLine = new QCPItemStraightLine(plot);
impl->m_RightLine->point1->setParentAnchor(topRight);
impl->m_RightLine->point2->setParentAnchor(bottomRight);
impl->m_RightLine->point1->setTypeX(QCPItemPosition::ptAbsolute);
impl->m_RightLine->point1->setTypeY(QCPItemPosition::ptAbsolute);
impl->m_RightLine->point2->setTypeX(QCPItemPosition::ptAbsolute);
impl->m_RightLine->point2->setTypeY(QCPItemPosition::ptAbsolute);
multi selection of zones
r1049 impl->m_RightLine->setSelectable(false);
Display of selection zones on a graph
r1044
impl->m_LeftLine = new QCPItemStraightLine(plot);
impl->m_LeftLine->point1->setParentAnchor(topLeft);
impl->m_LeftLine->point2->setParentAnchor(bottomLeft);
impl->m_LeftLine->point1->setTypeX(QCPItemPosition::ptAbsolute);
impl->m_LeftLine->point1->setTypeY(QCPItemPosition::ptAbsolute);
impl->m_LeftLine->point2->setTypeX(QCPItemPosition::ptAbsolute);
impl->m_LeftLine->point2->setTypeY(QCPItemPosition::ptAbsolute);
impl->m_LeftLine->setSelectable(false);
Improves display of selected zones
r1051 connect(this, &VisualizationSelectionZoneItem::selectionChanged, impl->m_RightLine,
&QCPItemStraightLine::setSelected);
connect(this, &VisualizationSelectionZoneItem::selectionChanged, impl->m_LeftLine,
&QCPItemStraightLine::setSelected);
multi selection of zones
r1049 setColor(QColor(DEFAULT_COLOR));
Display of selection zones on a graph
r1044 }
VisualizationSelectionZoneItem::~VisualizationSelectionZoneItem()
{
impl->m_Plot->removeItem(impl->m_RightLine);
impl->m_Plot->removeItem(impl->m_LeftLine);
}
void VisualizationSelectionZoneItem::setName(const QString &name)
{
if (name.isEmpty() && impl->m_NameLabelItem) {
impl->m_Plot->removeItem(impl->m_NameLabelItem);
impl->m_NameLabelItem = nullptr;
}
else if (!impl->m_NameLabelItem) {
impl->m_NameLabelItem = new QCPItemText(impl->m_Plot);
impl->m_NameLabelItem->setText(name);
impl->m_NameLabelItem->setPositionAlignment(Qt::AlignHCenter | Qt::AlignTop);
impl->m_NameLabelItem->setColor(impl->m_Color);
impl->m_NameLabelItem->position->setParentAnchor(top);
}
}
QString VisualizationSelectionZoneItem::name() const
{
if (!impl->m_NameLabelItem) {
return QString();
}
return impl->m_NameLabelItem->text();
}
SqpRange VisualizationSelectionZoneItem::range() const
{
SqpRange range;
range.m_TStart = impl->m_T1 <= impl->m_T2 ? impl->m_T1 : impl->m_T2;
range.m_TEnd = impl->m_T1 > impl->m_T2 ? impl->m_T1 : impl->m_T2;
return range;
}
void VisualizationSelectionZoneItem::setRange(double tstart, double tend)
{
impl->m_T1 = tstart;
impl->m_T2 = tend;
impl->updatePosition(this);
}
void VisualizationSelectionZoneItem::setStart(double tstart)
{
impl->m_T1 = tstart;
impl->updatePosition(this);
}
void VisualizationSelectionZoneItem::setEnd(double tend)
{
impl->m_T2 = tend;
impl->updatePosition(this);
}
void VisualizationSelectionZoneItem::setColor(const QColor &color)
{
impl->m_Color = color;
auto brushColor = color;
Improves display of selected zones
r1051 brushColor.setAlpha(80);
Display of selection zones on a graph
r1044 setBrush(QBrush(brushColor));
setPen(QPen(Qt::NoPen));
auto selectedBrushColor = brushColor;
Improves display of selected zones
r1051 selectedBrushColor.setAlpha(150);
Display of selection zones on a graph
r1044 setSelectedBrush(QBrush(selectedBrushColor));
setSelectedPen(QPen(Qt::NoPen));
auto linePen = QPen(color);
linePen.setStyle(Qt::SolidLine);
Improves display of selected zones
r1051 linePen.setWidth(4);
Display of selection zones on a graph
r1044
auto selectedLinePen = linePen;
Improves display of selected zones
r1051 selectedLinePen.setColor(color.darker(120));
selectedLinePen.setWidth(4);
Display of selection zones on a graph
r1044
impl->m_LeftLine->setPen(linePen);
impl->m_RightLine->setPen(linePen);
impl->m_LeftLine->setSelectedPen(selectedLinePen);
impl->m_RightLine->setSelectedPen(selectedLinePen);
}
void VisualizationSelectionZoneItem::setEditionEnabled(bool value)
{
impl->m_IsEditionEnabled = value;
setSelectable(value);
if (!value) {
setSelected(false);
drag of selection zones
r1047 impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition;
Display of selection zones on a graph
r1044 }
}
bool VisualizationSelectionZoneItem::isEditionEnabled() const
{
return impl->m_IsEditionEnabled;
}
Qt::CursorShape
VisualizationSelectionZoneItem::curshorShapeForPosition(const QPoint &position) const
{
auto mode = impl->m_CurrentEditionMode
== VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition
? impl->getEditionMode(position, this)
: impl->m_CurrentEditionMode;
switch (mode) {
case VisualizationSelectionZoneItemPrivate::EditionMode::Move:
return Qt::SizeAllCursor;
case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeLeft:
case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight: // fallthrough
return Qt::SizeHorCursor;
default:
return Qt::ArrowCursor;
}
}
void VisualizationSelectionZoneItem::setHovered(bool value)
{
if (value) {
auto linePen = impl->m_LeftLine->pen();
linePen.setStyle(Qt::DotLine);
linePen.setWidth(3);
auto selectedLinePen = impl->m_LeftLine->selectedPen();
;
selectedLinePen.setStyle(Qt::DotLine);
selectedLinePen.setWidth(3);
impl->m_LeftLine->setPen(linePen);
impl->m_RightLine->setPen(linePen);
impl->m_LeftLine->setSelectedPen(selectedLinePen);
impl->m_RightLine->setSelectedPen(selectedLinePen);
}
else {
setColor(impl->m_Color);
}
}
Resize and move of multiple zones together
r1050 void VisualizationSelectionZoneItem::setAssociatedEditedZones(
const QVector<VisualizationSelectionZoneItem *> &associatedZones)
{
impl->m_AssociatedEditedZones = associatedZones;
impl->m_AssociatedEditedZones.removeAll(this);
}
Display of selection zones on a graph
r1044 void VisualizationSelectionZoneItem::mousePressEvent(QMouseEvent *event, const QVariant &details)
{
multi selection of zones
r1049 if (isEditionEnabled() && event->button() == Qt::LeftButton) {
Display of selection zones on a graph
r1044 impl->m_CurrentEditionMode = impl->getEditionMode(event->pos(), this);
impl->m_MovedOrinalT1 = impl->m_T1;
impl->m_MovedOrinalT2 = impl->m_T2;
Resize and move of multiple zones together
r1050 for (auto associatedZone : impl->m_AssociatedEditedZones) {
associatedZone->impl->m_MovedOrinalT1 = associatedZone->impl->m_T1;
associatedZone->impl->m_MovedOrinalT2 = associatedZone->impl->m_T2;
}
Display of selection zones on a graph
r1044 }
else {
multi selection of zones
r1049 impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition;
Display of selection zones on a graph
r1044 event->ignore();
}
}
void VisualizationSelectionZoneItem::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
{
if (isEditionEnabled()) {
auto axis = impl->m_Plot->axisRect()->axis(QCPAxis::atBottom);
Resize and move of multiple zones together
r1050 auto pixelDiff = event->pos().x() - startPos.x();
auto diff = impl->pixelSizeToAxisXSize(pixelDiff);
Display of selection zones on a graph
r1044
switch (impl->m_CurrentEditionMode) {
case VisualizationSelectionZoneItemPrivate::EditionMode::Move:
setRange(impl->m_MovedOrinalT1 + diff, impl->m_MovedOrinalT2 + diff);
Resize and move of multiple zones together
r1050 for (auto associatedZone : impl->m_AssociatedEditedZones) {
associatedZone->move(pixelDiff);
}
Display of selection zones on a graph
r1044 break;
case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeLeft:
setStart(impl->m_MovedOrinalT1 + diff);
Resize and move of multiple zones together
r1050 for (auto associatedZone : impl->m_AssociatedEditedZones) {
impl->m_MovedOrinalT1 < impl->m_MovedOrinalT2
? associatedZone->resizeLeft(pixelDiff)
: associatedZone->resizeRight(pixelDiff);
}
Display of selection zones on a graph
r1044 break;
case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight:
setEnd(impl->m_MovedOrinalT2 + diff);
Resize and move of multiple zones together
r1050 for (auto associatedZone : impl->m_AssociatedEditedZones) {
impl->m_MovedOrinalT1 < impl->m_MovedOrinalT2
? associatedZone->resizeRight(pixelDiff)
: associatedZone->resizeLeft(pixelDiff);
}
Display of selection zones on a graph
r1044 break;
multi selection of zones
r1049 default:
break;
Display of selection zones on a graph
r1044 }
Resize and move of multiple zones together
r1050
for (auto associatedZone : impl->m_AssociatedEditedZones) {
associatedZone->parentPlot()->replot();
}
Display of selection zones on a graph
r1044 }
else {
event->ignore();
}
}
void VisualizationSelectionZoneItem::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
{
if (isEditionEnabled()) {
impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition;
}
else {
event->ignore();
}
Resize and move of multiple zones together
r1050
impl->m_AssociatedEditedZones.clear();
}
void VisualizationSelectionZoneItem::resizeLeft(double pixelDiff)
{
auto diff = impl->pixelSizeToAxisXSize(pixelDiff);
if (impl->m_MovedOrinalT1 <= impl->m_MovedOrinalT2) {
setStart(impl->m_MovedOrinalT1 + diff);
}
else {
setEnd(impl->m_MovedOrinalT2 + diff);
}
}
void VisualizationSelectionZoneItem::resizeRight(double pixelDiff)
{
auto diff = impl->pixelSizeToAxisXSize(pixelDiff);
if (impl->m_MovedOrinalT1 > impl->m_MovedOrinalT2) {
setStart(impl->m_MovedOrinalT1 + diff);
}
else {
setEnd(impl->m_MovedOrinalT2 + diff);
}
}
void VisualizationSelectionZoneItem::move(double pixelDiff)
{
auto diff = impl->pixelSizeToAxisXSize(pixelDiff);
setRange(impl->m_MovedOrinalT1 + diff, impl->m_MovedOrinalT2 + diff);
Display of selection zones on a graph
r1044 }