Files
Renderive/YSGraphic_Core/base/MutiSelectRect_p.h
T
2026-07-23 11:10:17 +08:00

147 lines
5.9 KiB
C++

#pragma once
#include <QApplication>
#include "MutiSelectRect.h"
#include "Plot.h"
#include "../Axis/AbsAxis.h"
namespace YSG {
struct MutiSelectRectRenderState : YSG::RenderState {
QVector<QRectF> 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<QRectF> &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<QRectF> &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<QRectF> &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<QRectF> 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();
}
};
}