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