#pragma once #include #include "MutiSelectRect.h" #include "Plot.h" #include "../Axis/AbsAxis.h" namespace YSG { struct MutiSelectRectRenderState : YSG::RenderState { QVector mRects; QFont mFont; QPen mBorderPen, mFontPen = QPen(Qt::white); QBrush mRectBrush = QColor(0, 0, 255, 50); AbsAxis *mHorizontalAxis{}, *mVerticalAxis{}; MutiSelectRectRenderState() { // NoPen, // SolidLine, // DashLine, // DotLine, // DashDotLine, // DashDotDotLine, // CustomDashLine mBorderPen.setStyle(Qt::DashLine); mBorderPen.setColor(Qt::white); } }; struct MutiSelectRectTempData : YSG::TempData { }; struct MutiSelectRectPrivate : YSG::RenderData { D_Ptr(MutiSelectRect) bool mActive = false; protected: bool selectTest(const QPointF& pos) override { return true; } // event->button():返回引发该事件的单个鼠标按钮。通常在 mousePressEvent 和 mouseReleaseEvent 中使用。 // event->buttons():返回一个标志,指示当前按下的所有鼠标按钮。可以在任何鼠标事件中使用,特别是 mouseMoveEvent 中。 void mousePressEvent(QMouseEvent* event) override { if (event->button() != Qt::LeftButton) return; MutiSelectRectRenderState* sc = editState(); SpinLockGuard _guard(&mBufferLock); RenderEditGuard _editGuard(this); QVector &rectList = sc->mRects; if (!(QApplication::keyboardModifiers() & Qt::ControlModifier)) { rectList.clear(); } else { int n = rectList.size(); for (int i = n - 1; i >= 0; i--) { auto &rect = rectList[i]; if (qFuzzyCompare(rect.width(), 0.0) || qFuzzyCompare(rect.height(), 0.0)) { rectList.removeAt(i); } } } double x = sc->mHorizontalAxis->pixelToCoord(event->pos().x(), SRC::Render); double y = sc->mVerticalAxis->pixelToCoord(event->pos().y(), SRC::Render); rectList.append(QRectF(QPointF(x, y), QPointF(x, y))); mActive = true; } void mouseMoveEvent(QMouseEvent* event) override { if(!(event->buttons() & Qt::LeftButton)) return; MutiSelectRectRenderState* sc = editState(); SpinLockGuard _guard(&mBufferLock); RenderEditGuard _editGuard(this); QVector &rectList = sc->mRects; if (rectList.empty()) return; rectList.last().setBottomRight(event->pos()); QRectF &r = rectList.last(); r.setRight(sc->mHorizontalAxis->pixelToCoord(r.right(), SRC::Render)); r.setBottom(sc->mVerticalAxis->pixelToCoord(r.bottom(), SRC::Render)); } void mouseReleaseEvent(QMouseEvent* event) override {} void keyPressEvent(QKeyEvent* event) override { if (event->key() != Qt::Key_Escape || !mActive) return; MutiSelectRectRenderState* sc = editState(); SpinLockGuard _guard(&mBufferLock); RenderEditGuard _editGuard(this); mActive = false; QVector &rectList = sc->mRects; if (rectList.empty()) return; rectList.removeLast(); } void keyReleaseEvent(QKeyEvent* event) override { MutiSelectRectRenderState* sc = editState(); MutiSelectRectTempData* td = editTempData(); SpinLockGuard _guard(&mBufferLock); } void draw(QPainter* painter) override { if(!mActive) return; MutiSelectRectRenderState* s = renderState(); QList drawRectList; for (QRectF r: s->mRects) { if (qFuzzyCompare(r.width(), 0.0) || qFuzzyCompare(r.height(), 0.0)) continue; r.setX(s->mHorizontalAxis->coordToPixel(r.x(), SRC::Render)); r.setY(s->mVerticalAxis->coordToPixel(r.y(), SRC::Render)); r.setRight(s->mHorizontalAxis->coordToPixel(r.right(), SRC::Render)); r.setBottom(s->mVerticalAxis->coordToPixel(r.bottom(), SRC::Render)); drawRectList.append(r); } painter->save(); QFontMetrics xfm(s->mHorizontalAxis->unitTextFont()); QFontMetrics yfm(s->mVerticalAxis->unitTextFont()); painter->setPen(s->mBorderPen); painter->setBrush(s->mRectBrush); for (auto &rect: drawRectList) { painter->drawRect(rect); } painter->setPen(s->mFontPen); painter->setFont(s->mFont); int n = drawRectList.size(); for (int i = 0; i < n; ++i) { QRectF &rect = drawRectList[i]; QRectF &coordRect = s->mRects[i]; double OffsetX = coordRect.right() - coordRect.left(); double OffsetY = coordRect.bottom() - coordRect.top(); QString text1 = "OffsetX == " + QString::number(OffsetX) + s->mHorizontalAxis->unitText(); QString text2 = "OffsetY == " + QString::number(OffsetY) + s->mVerticalAxis->unitText(); double width1 = xfm.horizontalAdvance(text1) + 32; double width2 = yfm.horizontalAdvance(text2) + 32; double rect1X = rect.x() + rect.width() / 2 - width1 / 2; double rect2X = rect.x() + rect.width() / 2 - width2 / 2; QRectF rect1 = QRectF(rect1X, rect.y(), width1, xfm.lineSpacing()); QRectF rect2 = QRectF(rect2X, rect1.bottom(), width2, yfm.lineSpacing()); painter->drawText(rect1, Qt::AlignCenter, text1); painter->drawText(rect2, Qt::AlignCenter, text2); } painter->restore(); } }; }