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