VisualizationSelectionZoneItem.cpp
272 lines
| 9.0 KiB
| text/x-c
|
CppLexer
r1084 | #include "Visualization/VisualizationSelectionZoneItem.h" | |||
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; | ||||
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); | ||||
r1087 | auto distance = zoneItem->selectTest(pos, false); | |||
r1084 | ||||
if (distanceRight <= distance) { | ||||
return VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight; | ||||
} | ||||
else if (distanceLeft <= distance) { | ||||
return VisualizationSelectionZoneItemPrivate::EditionMode::ResizeLeft; | ||||
} | ||||
return VisualizationSelectionZoneItemPrivate::EditionMode::Move; | ||||
} | ||||
}; | ||||
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); | ||||
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); | ||||
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_RightLine->setSelectable(false); | ||||
impl->m_LeftLine->setSelectable(false); | ||||
// connect(this, &VisualizationSelectionZoneItem::selectionChanged, impl->m_RightLine, | ||||
// &QCPItemStraightLine::setSelected); | ||||
// connect(this, &VisualizationSelectionZoneItem::selectionChanged, impl->m_LeftLine, | ||||
// &QCPItemStraightLine::setSelected); | ||||
setColor(QColor("#E79D41")); | ||||
} | ||||
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; | ||||
brushColor.setAlpha(40); | ||||
setBrush(QBrush(brushColor)); | ||||
setPen(QPen(Qt::NoPen)); | ||||
auto selectedBrushColor = brushColor; | ||||
selectedBrushColor.setAlpha(65); | ||||
setSelectedBrush(QBrush(selectedBrushColor)); | ||||
setSelectedPen(QPen(Qt::NoPen)); | ||||
auto linePen = QPen(color); | ||||
linePen.setStyle(Qt::SolidLine); | ||||
linePen.setWidth(2); | ||||
auto selectedLinePen = linePen; | ||||
selectedLinePen.setColor(color.darker(30)); | ||||
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); | ||||
r1087 | impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition; | |||
r1084 | } | |||
} | ||||
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); | ||||
} | ||||
} | ||||
void VisualizationSelectionZoneItem::mousePressEvent(QMouseEvent *event, const QVariant &details) | ||||
{ | ||||
if (isEditionEnabled()) { | ||||
impl->m_CurrentEditionMode = impl->getEditionMode(event->pos(), this); | ||||
impl->m_MovedOrinalT1 = impl->m_T1; | ||||
impl->m_MovedOrinalT2 = impl->m_T2; | ||||
} | ||||
else { | ||||
event->ignore(); | ||||
} | ||||
} | ||||
void VisualizationSelectionZoneItem::mouseMoveEvent(QMouseEvent *event, const QPointF &startPos) | ||||
{ | ||||
if (isEditionEnabled()) { | ||||
auto axis = impl->m_Plot->axisRect()->axis(QCPAxis::atBottom); | ||||
auto diff = axis->pixelToCoord(event->pos().x()) - axis->pixelToCoord(startPos.x()); | ||||
switch (impl->m_CurrentEditionMode) { | ||||
case VisualizationSelectionZoneItemPrivate::EditionMode::Move: | ||||
setRange(impl->m_MovedOrinalT1 + diff, impl->m_MovedOrinalT2 + diff); | ||||
break; | ||||
case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeLeft: | ||||
setStart(impl->m_MovedOrinalT1 + diff); | ||||
break; | ||||
case VisualizationSelectionZoneItemPrivate::EditionMode::ResizeRight: | ||||
setEnd(impl->m_MovedOrinalT2 + diff); | ||||
break; | ||||
// default: | ||||
// unknown edition mode | ||||
} | ||||
} | ||||
else { | ||||
event->ignore(); | ||||
} | ||||
} | ||||
void VisualizationSelectionZoneItem::mouseReleaseEvent(QMouseEvent *event, const QPointF &startPos) | ||||
{ | ||||
if (isEditionEnabled()) { | ||||
impl->m_CurrentEditionMode = VisualizationSelectionZoneItemPrivate::EditionMode::NoEdition; | ||||
} | ||||
else { | ||||
event->ignore(); | ||||
} | ||||
} | ||||