Files
qad/libs/graphic/graphic_ranges.cpp
peri4 d98e8c1f30 version 2.18.0
add GraphicRanges to graphic library
new graphic_analysis library
2023-07-31 20:17:34 +03:00

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();});
}