##// END OF EJS Templates
Reads variable's metadata to retrieve the type of data series (scalar, vector, spectrogram)
Reads variable's metadata to retrieve the type of data series (scalar, vector, spectrogram)

File last commit:

r1191:4c27015bd9c6
r1304:23206e07bbc2
Show More
VisualizationSelectionZoneItem.cpp
440 lines | 15.2 KiB | text/x-c | CppLexer
/ gui / src / Visualization / VisualizationSelectionZoneItem.cpp
Display of selection zones on a graph
r1084 #include "Visualization/VisualizationSelectionZoneItem.h"
Action "Remove Selected Zones"
r1114 #include "Visualization/VisualizationGraphWidget.h"
Multi selection improvements
r1119 #include "Visualization/VisualizationSelectionZoneManager.h"
#include "Visualization/VisualizationWidget.h"
Display of selection zones on a graph
r1084
multi selection of zones
r1089 const QString &DEFAULT_COLOR = QStringLiteral("#E79D41");
Display of selection zones on a graph
r1084 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
r1090 QVector<VisualizationSelectionZoneItem *> m_AssociatedEditedZones;
Display of selection zones on a graph
r1084 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
r1087 auto distance = zoneItem->selectTest(pos, false);
Display of selection zones on a graph
r1084
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
r1090
double pixelSizeToAxisXSize(double pixels)
{
auto axis = m_Plot->axisRect()->axis(QCPAxis::atBottom);
return axis->pixelToCoord(pixels) - axis->pixelToCoord(0);
}
Alignment actions for zone selections
r1116
bool alignZones(VisualizationSelectionZoneItem *referenceZone,
const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool alignOnLeft,
bool allowResize, bool vertically)
{
auto result = false;
auto referenceTime
= alignOnLeft ? referenceZone->range().m_TStart : referenceZone->range().m_TEnd;
auto referenceBottomAxis = m_Plot->axisRect()->axis(QCPAxis::atBottom);
auto referenceVerticalPosition = referenceBottomAxis->coordToPixel(referenceTime);
for (auto otherZone : zonesToAlign) {
auto otherZoneRange = otherZone->range();
auto newZoneStart = otherZoneRange.m_TStart;
auto newZoneEnd = otherZoneRange.m_TEnd;
auto alignedTime = referenceTime;
if (vertically) {
auto otherZoneAxis = otherZone->parentPlot()->axisRect()->axis(QCPAxis::atBottom);
alignedTime = otherZoneAxis->pixelToCoord(referenceVerticalPosition);
}
if (alignOnLeft) {
newZoneStart = alignedTime;
if (!allowResize) {
newZoneEnd = alignedTime + (otherZoneRange.m_TEnd - otherZoneRange.m_TStart);
}
}
else { // align on right
newZoneEnd = alignedTime;
if (!allowResize) {
newZoneStart = alignedTime - (otherZoneRange.m_TEnd - otherZoneRange.m_TStart);
}
}
if (newZoneStart < newZoneEnd) {
result = true;
otherZone->setRange(newZoneStart, newZoneEnd);
otherZone->parentPlot()->replot();
}
}
return result;
}
Display of selection zones on a graph
r1084 };
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
r1089 setSelectable(false);
Display of selection zones on a graph
r1084
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
r1089 impl->m_RightLine->setSelectable(false);
Display of selection zones on a graph
r1084
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
r1091 connect(this, &VisualizationSelectionZoneItem::selectionChanged, impl->m_RightLine,
&QCPItemStraightLine::setSelected);
connect(this, &VisualizationSelectionZoneItem::selectionChanged, impl->m_LeftLine,
&QCPItemStraightLine::setSelected);
multi selection of zones
r1089 setColor(QColor(DEFAULT_COLOR));
Display of selection zones on a graph
r1084 }
Add Catalogue methods
r1191 VisualizationSelectionZoneItem::~VisualizationSelectionZoneItem()
{
}
Display of selection zones on a graph
r1084
Action "Remove Selected Zones"
r1114 VisualizationGraphWidget *VisualizationSelectionZoneItem::parentGraphWidget() const noexcept
{
auto parent = impl->m_Plot->parentWidget();
while (parent != nullptr && !qobject_cast<VisualizationGraphWidget *>(parent)) {
parent = parent->parentWidget();
}
return qobject_cast<VisualizationGraphWidget *>(parent);
}
Display of selection zones on a graph
r1084 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
r1091 brushColor.setAlpha(80);
Display of selection zones on a graph
r1084 setBrush(QBrush(brushColor));
setPen(QPen(Qt::NoPen));
auto selectedBrushColor = brushColor;
Improves display of selected zones
r1091 selectedBrushColor.setAlpha(150);
Display of selection zones on a graph
r1084 setSelectedBrush(QBrush(selectedBrushColor));
setSelectedPen(QPen(Qt::NoPen));
auto linePen = QPen(color);
linePen.setStyle(Qt::SolidLine);
Improves display of selected zones
r1091 linePen.setWidth(4);
Display of selection zones on a graph
r1084
auto selectedLinePen = linePen;
Improves display of selected zones
r1091 selectedLinePen.setColor(color.darker(120));
selectedLinePen.setWidth(4);
Display of selection zones on a graph
r1084
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
r1087 impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition;
Display of selection zones on a graph
r1084 }
}
bool VisualizationSelectionZoneItem::isEditionEnabled() const
{
return impl->m_IsEditionEnabled;
}
Selection of stacked zone via a dialog box
r1120 void VisualizationSelectionZoneItem::moveToTop()
{
moveToLayer(layer(), false);
}
Display of selection zones on a graph
r1084 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
r1090 void VisualizationSelectionZoneItem::setAssociatedEditedZones(
const QVector<VisualizationSelectionZoneItem *> &associatedZones)
{
impl->m_AssociatedEditedZones = associatedZones;
impl->m_AssociatedEditedZones.removeAll(this);
}
Alignment actions for zone selections
r1116 bool VisualizationSelectionZoneItem::alignZonesVerticallyOnLeft(
const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize)
{
return impl->alignZones(this, zonesToAlign, true, allowResize, true);
}
bool VisualizationSelectionZoneItem::alignZonesVerticallyOnRight(
const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize)
{
return impl->alignZones(this, zonesToAlign, false, allowResize, true);
}
bool VisualizationSelectionZoneItem::alignZonesTemporallyOnLeft(
const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize)
{
return impl->alignZones(this, zonesToAlign, true, allowResize, false);
}
bool VisualizationSelectionZoneItem::alignZonesTemporallyOnRight(
const QVector<VisualizationSelectionZoneItem *> &zonesToAlign, bool allowResize)
{
return impl->alignZones(this, zonesToAlign, false, allowResize, false);
}
Display of selection zones on a graph
r1084 void VisualizationSelectionZoneItem::mousePressEvent(QMouseEvent *event, const QVariant &details)
{
Selection of stacked zone via a dialog box
r1120 Q_UNUSED(details);
multi selection of zones
r1089 if (isEditionEnabled() && event->button() == Qt::LeftButton) {
Display of selection zones on a graph
r1084 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
r1090 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
r1084 }
else {
multi selection of zones
r1089 impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition;
Display of selection zones on a graph
r1084 event->ignore();
}
}
void VisualizationSelectionZoneItem::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos)
{
if (isEditionEnabled()) {
Multi selection improvements
r1119 if (!selected()) {
// Force the item to be selected during the edition
parentGraphWidget()->parentVisualizationWidget()->selectionZoneManager().setSelected(
this, true);
}
Display of selection zones on a graph
r1084 auto axis = impl->m_Plot->axisRect()->axis(QCPAxis::atBottom);
Resize and move of multiple zones together
r1090 auto pixelDiff = event->pos().x() - startPos.x();
auto diff = impl->pixelSizeToAxisXSize(pixelDiff);
Display of selection zones on a graph
r1084
switch (impl->m_CurrentEditionMode) {
case VisualizationSelectionZoneItemPrivate::EditionMode::Move:
setRange(impl->m_MovedOrinalT1 + diff, impl->m_MovedOrinalT2 + diff);
Resize and move of multiple zones together
r1090 for (auto associatedZone : impl->m_AssociatedEditedZones) {
associatedZone->move(pixelDiff);
}
Display of selection zones on a graph
r1084 break;
case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeLeft:
setStart(impl->m_MovedOrinalT1 + diff);
Resize and move of multiple zones together
r1090 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
r1084 break;
case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight:
setEnd(impl->m_MovedOrinalT2 + diff);
Resize and move of multiple zones together
r1090 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
r1084 break;
multi selection of zones
r1089 default:
break;
Display of selection zones on a graph
r1084 }
Resize and move of multiple zones together
r1090
for (auto associatedZone : impl->m_AssociatedEditedZones) {
associatedZone->parentPlot()->replot();
}
Display of selection zones on a graph
r1084 }
else {
event->ignore();
}
}
void VisualizationSelectionZoneItem::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos)
{
Selection of stacked zone via a dialog box
r1120 Q_UNUSED(startPos);
Display of selection zones on a graph
r1084 if (isEditionEnabled()) {
impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition;
}
else {
event->ignore();
}
Resize and move of multiple zones together
r1090
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
r1084 }