##// END OF EJS Templates
Adds "number of operations" and "number of variables" properties for the tests
Adds "number of operations" and "number of variables" properties for the tests

File last commit:

r1159:4c27015bd9c6
r1170:3da18e6983d5
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
r1044 #include "Visualization/VisualizationSelectionZoneItem.h"
Action "Remove Selected Zones"
r1079 #include "Visualization/VisualizationGraphWidget.h"
Multi selection improvements
r1084 #include "Visualization/VisualizationSelectionZoneManager.h"
#include "Visualization/VisualizationWidget.h"
Display of selection zones on a graph
r1044
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);
}
Alignment actions for zone selections
r1081
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
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 }
Add Catalogue methods
r1159 VisualizationSelectionZoneItem::~VisualizationSelectionZoneItem()
{
}
Display of selection zones on a graph
r1044
Action "Remove Selected Zones"
r1079 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
r1044 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;
}
Selection of stacked zone via a dialog box
r1085 void VisualizationSelectionZoneItem::moveToTop()
{
moveToLayer(layer(), false);
}
Display of selection zones on a graph
r1044 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);
}
Alignment actions for zone selections
r1081 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
r1044 void VisualizationSelectionZoneItem::mousePressEvent(QMouseEvent *event, const QVariant &details)
{
Selection of stacked zone via a dialog box
r1085 Q_UNUSED(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()) {
Multi selection improvements
r1084 if (!selected()) {
// Force the item to be selected during the edition
parentGraphWidget()->parentVisualizationWidget()->selectionZoneManager().setSelected(
this, true);
}
Display of selection zones on a graph
r1044 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)
{
Selection of stacked zone via a dialog box
r1085 Q_UNUSED(startPos);
Display of selection zones on a graph
r1044 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 }