185 lines
4.4 KiB
C++
185 lines
4.4 KiB
C++
#include <QTimer>
|
|
#include "graphic_ranges.h"
|
|
|
|
|
|
GraphicRanges::GraphicRanges(QWidget * parent): Graphic(parent) {
|
|
connect(this, SIGNAL(graphicPaintEvent(QPainter *)), this, SLOT(onPaintEvent(QPainter *)));
|
|
connect(this, SIGNAL(graphicMousePressEvent(QPointF, int)), this, SLOT(onMousePressEvent(QPointF, int)));
|
|
connect(this, SIGNAL(graphicMouseMoveEvent(QPointF, int)), this, SLOT(onMouseMoveEvent(QPointF, int)));
|
|
connect(this, SIGNAL(graphicMouseReleaseEvent(QPointF, int)), this, SLOT(onMouseReleaseEvent(QPointF, int)));
|
|
//setOpenGL(true);
|
|
range_start = range_end = 0.;
|
|
range_sel = request = false;
|
|
color_ = QColor(64, 192, 64, 128);
|
|
color_cur = QColor(64, 64, 192, 128);
|
|
}
|
|
|
|
|
|
GraphicRanges::~GraphicRanges() {
|
|
}
|
|
|
|
|
|
int GraphicRanges::addRange(double start, double end, QString name, QColor color) {
|
|
ranges_ << Range(start, end, name, color);
|
|
update();
|
|
return ranges_.size() - 1;
|
|
}
|
|
|
|
|
|
void GraphicRanges::replaceRange(int index, double start, double end) {
|
|
if (index < 0 || index >= ranges_.size()) return;
|
|
ranges_[index].start = start;
|
|
ranges_[index].end = end;
|
|
update();
|
|
}
|
|
|
|
|
|
GraphicRanges::Range GraphicRanges::removeRange(int index) {
|
|
if (index < 0 || index >= ranges_.size()) return Range();
|
|
Range ret = ranges_.takeAt(index);
|
|
update();
|
|
return ret;
|
|
}
|
|
|
|
|
|
void GraphicRanges::clearRanges() {
|
|
ranges_.clear();
|
|
update();
|
|
}
|
|
|
|
|
|
void GraphicRanges::clearRangesByColor(QColor c) {
|
|
for (int i = 0; i < ranges_.size(); ++i) {
|
|
if (ranges_[i].color == c) {
|
|
ranges_.removeAt(i);
|
|
--i;
|
|
}
|
|
}
|
|
update();
|
|
}
|
|
|
|
|
|
GraphicRanges::Range GraphicRanges::rangeAll() const {
|
|
Range ret;
|
|
for (int g = 0; g < graphicsCount(); ++g) {
|
|
const QPolygonF & gd(graphics[g].polyline);
|
|
if (!gd.isEmpty()) {
|
|
if (ret.isEmpty()) {
|
|
ret.start = gd.front().x();
|
|
ret.end = gd.back ().x();
|
|
} else {
|
|
ret.start = qMin(ret.start, gd.front().x());
|
|
ret.end = qMax(ret.end , gd.back ().x());
|
|
}
|
|
}
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
|
|
GraphicRanges::Range GraphicRanges::rangeVisible() const {
|
|
Range ret;
|
|
ret.start = visualRect().left ();
|
|
ret.end = visualRect().right();
|
|
return ret;
|
|
}
|
|
|
|
|
|
void GraphicRanges::setCurrentRange(double start, double end) {
|
|
range_start = start;
|
|
range_end = end;
|
|
update();
|
|
}
|
|
|
|
|
|
void GraphicRanges::clearCurrentRange() {
|
|
range_start = range_end = 0.;
|
|
update();
|
|
}
|
|
|
|
|
|
GraphicRanges::Range GraphicRanges::currentRange() const {
|
|
return Range(range_start, range_end);
|
|
}
|
|
|
|
|
|
void GraphicRanges::clear() {
|
|
ranges_.clear();
|
|
Graphic::clear();
|
|
}
|
|
|
|
|
|
void GraphicRanges::drawRange(QPainter * p, const GraphicRanges::Range & r, QColor color) {
|
|
if (r.isEmpty()) return;
|
|
double cx[2] = {real2canvasX(r.start),
|
|
real2canvasX(r.end)};
|
|
p->fillRect(QRectF(cx[0], 0, cx[1] - cx[0], height()), color);
|
|
p->setPen(QPen(QColor(color.rgb()), 2, Qt::DotLine));
|
|
p->drawLine(cx[0], 0, cx[0], height());
|
|
p->drawLine(cx[1], 0, cx[1], height());
|
|
if (!r.name.isEmpty()) {
|
|
p->setPen(QPen(QColor(color.rgb()).darker(), 1, Qt::SolidLine));
|
|
p->drawText(QRectF(cx[0], 10, cx[1] - cx[0], height() - 10), Qt::AlignHCenter | Qt::AlignTop | Qt::TextDontClip, r.name);
|
|
}
|
|
|
|
}
|
|
|
|
|
|
void GraphicRanges::onPaintEvent(QPainter * p) {
|
|
p->save();
|
|
//QPen pen = p->pen();
|
|
for (const auto & r: ranges_) {
|
|
drawRange(p, r, r.hasColor() ? r.color : color_);
|
|
}
|
|
drawRange(p, Range(range_start, range_end), color_cur);
|
|
p->restore();
|
|
}
|
|
|
|
|
|
void GraphicRanges::onMousePressEvent(QPointF p, int b) {
|
|
if (b == Qt::RightButton) return;// request = false;
|
|
if (b != Qt::LeftButton || !request) return;
|
|
update();
|
|
range_sel = true;
|
|
range_start = range_end = p.x();
|
|
setNavigationEnabled(false);
|
|
}
|
|
|
|
|
|
void GraphicRanges::onMouseMoveEvent(QPointF p, int b) {
|
|
if (!range_sel) return;
|
|
range_end = p.x();
|
|
update();
|
|
}
|
|
|
|
|
|
void GraphicRanges::onMouseReleaseEvent(QPointF p, int b) {
|
|
if (b == Qt::RightButton && range_sel)
|
|
canvas->setCursor(Qt::SplitHCursor);
|
|
if (b != Qt::LeftButton) return;
|
|
if (range_sel) {
|
|
range_sel = request = false;
|
|
range_end = p.x();
|
|
if (range_start > range_end)
|
|
std::swap(range_start, range_end);
|
|
rangeSelected(range_start, range_end);
|
|
canvas->setCursor(Qt::ArrowCursor);
|
|
range_start = range_end = 0.;
|
|
}
|
|
QTimer::singleShot(10, [this](){setNavigationEnabled(true); update();});
|
|
}
|
|
|
|
|
|
void GraphicRanges::rangeRequest() {
|
|
request = true;
|
|
canvas->setCursor(Qt::SplitHCursor);
|
|
}
|
|
|
|
|
|
void GraphicRanges::cancelRangeRequest(bool with_nav) {
|
|
request = false;
|
|
canvas->setCursor(Qt::ArrowCursor);
|
|
if (with_nav)
|
|
QTimer::singleShot(10, [this](){setNavigationEnabled(true); update();});
|
|
}
|