You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmPlot/nmObjRect.cpp

381 lines
10 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <QPainter>
#include "ZxSerializer.h"
#include "IxPtyPano.h"
#include "ZxSubAxisX.h"
#include "ZxSubAxisY.h"
#include "nmObjRectTool.h"
#include "nmObjRect.h"
#include "nmDataAnalyzeManager.h"
ZX_DEFINE_DYNAMIC(nObjRect, nmObjRect)
nmObjRect::nmObjRect() {
m_sObjTag = "nObjRect";
nmObjRect::init("", NULL, NULL);
}
nmObjRect::nmObjRect(const QString& sName, \
ZxSubAxisX* pAxisX, \
ZxSubAxisY* pAxisY) {
m_sObjTag = "nObjRect";
nmObjRect::init(sName, pAxisX, pAxisY);
}
nmObjRect::~nmObjRect() {
}
// 初始化矩形对象对应的笔和填充颜色
void nmObjRect::init(const QString& sName, \
ZxSubAxisX* pAxisX, \
ZxSubAxisY* pAxisY) {
nmObjBase::init(sName, pAxisX, pAxisY);
// 初始为未选中状态
//this->setSelected(false);
// 初始化击中位置及索引
m_oHitPos = RBP_Unknown;
m_nRectHitIndex = -1;
nmObjRect::initFlags();
m_oPen = QPen(QBrush(QColor(0, 0, 0)), \
0.5f, Qt::SolidLine);
m_clrBackgrd = QColor(255, 170, 255, 100);
loadTempl();
}
void nmObjRect::initTools() {
m_pTool = new nmObjRectTool();
nmObjBase::initTools();
}
void nmObjRect::initFlags() {
setLockPos(false);
setLockSize(false);
setReadOnly(false);
}
bool nmObjRect::hitTest(const QPointF& pt) {
return nmObjBase::hitTest(pt);
}
bool nmObjRect::_runHitTest(const QPointF& pt, int& nOption, int& nSubIndex) {
if(!nmObjBase::_runHitTest(pt, nOption, nSubIndex)) {
return false;
}
// RectBoundPos m_oHitPos;
/*
// 非选中状态,不需要执行下列语句
if (!isSelected()) {
return false;
}
*/
QPointF ptPos = pt;
// 不使用传入的参数
nOption = -1;
nSubIndex = -1;
if(NULL == m_pAxisX || NULL == m_pAxisY) {
return false;
}
QVector<QPointF> pts = getPosOf(m_vecPoints);
// 点
double r = 1.f;
QPointF pt1, pt2; //pt1:击中的点pt2:对角线上的点
bool isInitialized = false;
for(int i = 0; i < pts.count(); i++) {
QPointF ptTopLeft = QPointF(pts[i].x() - r,
pts[i].y() - r);
QSizeF sz = QSizeF(r * 2.f, r * 2.f);
QRectF rt = QRectF(ptTopLeft, sz);
bool isContain = rt.contains(ptPos);
if (isContain) {
// 击中了这个点,记录该点的位置
pt1 = pts[i];
pt2 = pts[(i + 2) % 4];
m_nRectHitIndex = i;
isInitialized = true;
break;
}
}
// 判断该点所在的位置
if (isInitialized) {
if(pt1.x() < pt2.x() && pt1.y() < pt2.y()) {
// nOption = RBP_LeftTop;
m_oHitPos = RBP_LeftTop;
//m_nRectHitIndex = 0;
// nSubIndex = 0;
} else if(pt1.x() > pt2.x() && pt1.y() < pt2.y()) {
// nOption = RBP_RightTop;
m_oHitPos = RBP_RightTop;
//m_nRectHitIndex = 1;
// nSubIndex = 1;
} else if(pt1.x() > pt2.x() && pt1.y() > pt2.y()) {
// nOption = RBP_RightBottom;
m_oHitPos = RBP_RightBottom;
//m_nRectHitIndex = 2;
// nSubIndex = 2;
} else if(pt1.x() < pt2.x() && pt1.y() > pt2.y()) {
// nOption = RBP_LeftBottom;
m_oHitPos = RBP_LeftBottom;
//m_nRectHitIndex = 3;
// nSubIndex = 3;
}
return true;
}
// 线
for(int i = 0; i < pts.count()/* - 1*/; i++) {
int n1 = i;
int n2 = (i == pts.count() - 1 ? 0 : i + 1);
if(_isNearLine(ptPos, pts[n1], pts[n2], 1.f * 2)) {
m_nRectHitIndex = i;
// 判断是哪一条线
if(pts[n1].x() < pts[n2].x() && pts[n1].y() == pts[n2].y()) {
// nOption = RBP_Top;
m_oHitPos = RBP_Top;
//m_nRectHitIndex = 0;
//nSubIndex = 0;
} else if(pts[n1].x() == pts[n2].x() && pts[n1].y() < pts[n2].y()) {
// nOption = RBP_Right;
m_oHitPos = RBP_Right;
//m_nRectHitIndex = 1;
// nSubIndex = 1;
} else if(pts[n1].x() > pts[n2].x() && pts[n1].y() == pts[n2].y()) {
// nOption = RBP_Bottom;
m_oHitPos = RBP_Bottom;
//m_nRectHitIndex = 2;
// nSubIndex = 2;
} else if(pts[n1].x() == pts[n2].x() && pts[n1].y() > pts[n2].y()) {
// nOption = RBP_Left;
m_oHitPos = RBP_Left;
//m_nRectHitIndex = 3;
// nSubIndex = 3;
}
return true;
}
}
// 内部
QPainterPath oPath;
oPath.moveTo(pts[0]);
for(int i = 1; i < pts.count(); i++) {
oPath.lineTo(pts[i]);
}
oPath.closeSubpath();
// 只有为选中状态才能触发RBP_Inner
if(oPath.contains(pt) && isSelected()) {
// nOption = RBP_Inner;
m_oHitPos = RBP_Inner;
m_nRectHitIndex = 4;
// nSubIndex = 4;
return true;
}
// 击中外部
m_oHitPos = RBP_Outer;
m_nRectHitIndex = -1;
return false;
}
bool nmObjRect::runMove(const QPointF& pt1,
const QPointF& pt2) {
if(isLockPos()) {
return false;
}
if(NULL == m_pAxisX || NULL == m_pAxisY) {
return false;
}
int nCount = m_vecPoints.count();
QVector<QPointF> vecPts = getPosOf(m_vecPoints); // 屏幕值
if((m_oHitPos == RBP_LeftTop || m_oHitPos == RBP_RightBottom) && m_nRectHitIndex >= 0) { // 击中左上角或右下角
// 左下角y不变右上角x不变
QPointF p1 = pt2, p2 = pt2;
p1.setY(pt1.y());
p2.setX(pt1.x());
vecPts[m_nRectHitIndex] = offsetPoint(vecPts[m_nRectHitIndex], pt1, pt2);
vecPts[(m_nRectHitIndex + 3) % 4] = offsetPoint(vecPts[(m_nRectHitIndex + 3) % 4], pt1, p1);
vecPts[(m_nRectHitIndex + 1) % 4] = offsetPoint(vecPts[(m_nRectHitIndex + 1) % 4], pt1, p2);
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
return moveToPos(vecPts);
} else if((m_oHitPos == RBP_RightTop || m_oHitPos == RBP_LeftBottom) && m_nRectHitIndex >= 0) { // 击中左下角或右上角
// 左上角y不变右下角x不变
QPointF p1 = pt2, p2 = pt2;
p1.setY(pt1.y());
p2.setX(pt1.x());
vecPts[m_nRectHitIndex] = offsetPoint(vecPts[m_nRectHitIndex], pt1, pt2);
vecPts[(m_nRectHitIndex + 3) % 4] = offsetPoint(vecPts[(m_nRectHitIndex + 3) % 4], pt1, p2);
vecPts[(m_nRectHitIndex + 1) % 4] = offsetPoint(vecPts[(m_nRectHitIndex + 1) % 4], pt1, p1);
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
return moveToPos(vecPts);
} else if((m_oHitPos == RBP_Top || m_oHitPos == RBP_Bottom) && m_nRectHitIndex >= 0) { // 上下边
// x不变
QPointF p1 = pt2;
p1.setX(pt1.x());
vecPts[m_nRectHitIndex] = offsetPoint(vecPts[m_nRectHitIndex], pt1, p1);
vecPts[(m_nRectHitIndex + 1) % 4] = offsetPoint(vecPts[(m_nRectHitIndex + 1) % 4], pt1, p1);
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
return moveToPos(vecPts);
} else if((m_oHitPos == RBP_Left || m_oHitPos == RBP_Right) && m_nRectHitIndex >= 0) { // 左右边
// y不变
QPointF p1(pt2.x(), pt1.y());
vecPts[m_nRectHitIndex] = offsetPoint(vecPts[m_nRectHitIndex], pt1, p1);
vecPts[(m_nRectHitIndex + 1) % 4] = offsetPoint(vecPts[(m_nRectHitIndex + 1) % 4], pt1, p1);
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
return moveToPos(vecPts);
} else if(m_oHitPos == RBP_Inner) { // 内部
for(int i = 0; i < nCount; i++) {
vecPts[i] = offsetPoint(vecPts[i], pt1, pt2);
}
m_dOffsetX = pt2.x() - pt1.x();
m_dOffsetY = pt2.y() - pt1.y();
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
return moveToPos(vecPts);
} else {
return false;
}
return true;
}
void nmObjRect::fillPtyPano(IxPtyPano* sheet) {
nmObjBase::fillPtyPano(sheet);
ZX_PROP("ObjRect.Pen", getPen, setPen);
ZX_PROP("ObjRect.BackgrdColor", getBackgrdColor, setBackgrdColor);
ZX_PROP("ObjRect.BackgrdColorAlpha", getBackgrdAlpha, setBackgrdAlpha);
}
void nmObjRect::onSerialize(ZxSerializer* ser) {
nmObjBase::onSerialize(ser);
ser->write("BackgrdColor", m_clrBackgrd);
}
void nmObjRect::onDeserialize(ZxSerializer* ser) {
nmObjBase::onDeserialize(ser);
ser->read("BackgrdColor", m_clrBackgrd);
}
void nmObjRect::onLoadTempl(ZxSerializer* ser) {
nmObjBase::onLoadTempl(ser);
ser->read("BackgrdColor", m_clrBackgrd);
}
void nmObjRect::onSaveTempl(ZxSerializer* ser) {
nmObjBase::onSaveTempl(ser);
ser->write("BackgrdColor", m_clrBackgrd);
}
void nmObjRect::paintBack(QPainter* painter, const ZxPaintParam& param) {
// 判断当前坐标轴是否有效
if(NULL == m_pAxisX || NULL == m_pAxisY || \
m_pAxisX->getRangeMin() == m_pAxisX->getRangeMax() || \
m_pAxisY->getRangeMin() == m_pAxisY->getRangeMax()) {
return;
}
painter->save();
QVector<QPointF> pts = getPosOf(m_vecPoints); // 获取矩形四个点的坐标
QRectF bound = getBounds(); // 获取图元基础边框(位置)
if(!pts.empty()) { //矩形的四个点存在
// 填充矩形路径
QPainterPath oPath;
oPath.moveTo(pts[0]);
for(int i = 1; i < pts.count(); i++) {
oPath.lineTo(pts[i]);
}
oPath.closeSubpath();
painter->fillPath(oPath, QBrush(m_clrBackgrd));
// 边界
QPen pen = m_oPen;
painter->setPen(pen);
painter->drawPolygon(&pts[0], pts.count());
// 绘制名称文字
QFont ft = qApp->font();
ft.setPointSize(8);
painter->setFont(ft);
painter->setPen(Qt::black);
ZxDrawHelper::drawText(painter,
bound,
Qt::AlignCenter | Qt::AlignVCenter,
m_sName);
}
bool sss = this->isSelected();
if(sss) { // 选中状态下
QPen pen(QBrush(Qt::black), 0.0f, Qt::DotLine);
painter->setPen(pen);
painter->drawPolygon(&pts[0], pts.count());
for(int i = 0; i < pts.count(); i++) {
double w = 2.2f;
QPointF pt = pts[i];
QRectF rect(pt.x() - w * 0.5f, pt.y() - w * 0.5f, w, w); // 选中状态下四个点对应的矩形边框
// 击中四个角
if((m_oHitPos == RBP_LeftTop || m_oHitPos == RBP_RightTop || m_oHitPos == RBP_RightBottom || m_oHitPos == RBP_LeftBottom ) && m_nRectHitIndex == i) {
QBrush br(Qt::red);
painter->fillRect(rect, br);
} else {
painter->setPen(QColor(0, 0, 128));
painter->drawRect(rect);
}
}
}
painter->restore();
}
QColor nmObjRect::getBackgrdColor() const {
return m_clrBackgrd;
}
void nmObjRect::setBackgrdColor(QColor clr) {
m_clrBackgrd.setRed(clr.red());
m_clrBackgrd.setGreen(clr.green());
m_clrBackgrd.setBlue(clr.blue());
update();
}
int nmObjRect::getBackgrdAlpha() const {
return m_clrBackgrd.alpha();
}
void nmObjRect::setBackgrdAlpha(int nAlpha) {
m_clrBackgrd.setAlpha(nAlpha);
update();
}