#include #include "ZxBaseUtil.h" #include "nmObjRect.h" #include "nmObjRectTool.h" #include nmObjRectTool::nmObjRectTool() : nmObjToolBase() { setText(tr("nObjRectTool")); m_oNot = NMOT_Rect; } bool nmObjRectTool::onLeftDown(const QPointF& pt) { nmObjRect* pObj = dynamic_cast(m_pObj); if(NULL == pObj) { //绘图对象尚未创建(鼠标选点ing) m_bTracking = true; m_ptStart = pt; changeCursor(Qt::CrossCursor); // 对于持续性选点的工具,需要设置 getView()->setCursorKeeping(true); m_vecPoints.push_back(pt); return true; } else { // 已绑定绘图对象 return nmObjToolBase::onLeftDown(pt); /* // 判断是否为选中状态 if (pObj->isSelected()) { // 调用基类方法 return nmObjToolBase::onLeftDown(pt); } // 击中了点或线 if (pObj->m_oHitPos != RBP_Unknown && pObj->m_oHitPos != RBP_Inner) { pObj->setSelected(true); return true; } // 未击中 //pObj->setSelected(false); return false; */ } } bool nmObjRectTool::onMouseMove(const QPointF& pt) { nmObjRect* pObj = dynamic_cast(m_pObj); if(NULL == pObj) { // 绘图对象尚未创建(鼠标选点ing) m_ptMove = pt; if(m_bTracking) { // 调用渲染函数 updateLastMoveArea(true); } return true; } else { //业已绑定绘图对象 /* // 如果不是选中状态,不需要调用父类的方法 if (pObj->isSelected()) return nmObjToolBase::onMouseMove(pt); else return false; */ return nmObjToolBase::onMouseMove(pt); } } bool nmObjRectTool::onLeftUp(const QPointF& pt) { nmObjRect* pObj = dynamic_cast(m_pObj); if(NULL == pObj) { // 绘图对象尚未创建(鼠标选点ing) getView()->setCursorKeeping(false); changeCursor(Qt::ArrowCursor); // 矩形依赖拖拽成形,起点和终点过近时取消本次创建,避免双击或误点生成零尺寸图元。 double dDistance = 2.2f; if ((qAbs(m_ptStart.x() - pt.x()) < dDistance) && (qAbs(m_ptStart.y() - pt.y()) < dDistance)) { m_vecPoints.clear(); m_bTracking = false; return true; } // 保存其余三个点的坐标 m_ptMove = pt; QPointF m_ptOne(m_ptMove.x(), m_ptStart.y()), m_ptTwo(m_ptStart.x(), m_ptMove.y()); m_vecPoints.push_back(m_ptOne); m_vecPoints.push_back(m_ptMove); m_vecPoints.push_back(m_ptTwo); emit sigPtsFinished(m_vecPoints); // 矩形边界绘制完成 m_vecPoints.clear(); m_bTracking = false; return true; } else { // 已绑定绘图对象 return nmObjToolBase::onLeftUp(pt); /* // 选中状态,调用基类方法 if (pObj->isSelected()) { return nmObjToolBase::onLeftUp(pt); } return false; */ /* if (pObj->m_oHitPos == RBP_Top) { return true; } else { if (pObj->m_oHitPos == RBP_Top) { pObj->setSelected(true); return true; } else return false; //return nmObjRectTool::onLeftUp(pt); } */ } } bool nmObjRectTool::onLeftDoubleClick(const QPointF& pt) { nmObjRect* pObj = dynamic_cast(m_pObj); if(NULL == pObj) { // 绘图对象尚未创建(鼠标选点ing) // 矩形创建不依赖双击收尾,创建态直接吞掉双击事件。 return true; } else { // 已绑定绘图对象 // 双击内部,取消选中状态 if (pObj->m_oHitPos == RBP_Inner) { pObj->setSelected(false); //pObj->update(); return true; } return nmObjToolBase::onLeftDoubleClick(pt); } } void nmObjRectTool::onPaint(QPainter* painter, const ZxPaintParam& param) { nmObjRect* pObj = dynamic_cast(m_pObj); if(pObj == NULL) { // 绘图对象尚未创建(鼠标选点ing) Qt::CursorShape o = Qt::CrossCursor; changeCursor(o); paintTrackingVirtualObj(painter, param); } else { // 已绑定绘图对象 /* if (pObj->isSelected()){ paintTrackingRealObj(painter, param); } */ paintTrackingRealObj(painter, param); } } void nmObjRectTool::paintTrackingVirtualObj(QPainter* painter, const ZxPaintParam& param) { painter->save(); // 当前正在进行的点 if(m_bTracking || !m_vecPoints.isEmpty()) { QPen pen(Qt::DashLine); painter->setPen(pen); // 绘制矩形边界(虚线) QPointF m_ptOne(m_ptMove.x(), m_ptStart.y()), m_ptTwo(m_ptStart.x(), m_ptMove.y()); painter->drawLine(m_ptStart, m_ptOne); painter->drawLine(m_ptOne, m_ptMove); painter->drawLine(m_ptMove, m_ptTwo); painter->drawLine(m_ptTwo, m_ptStart); } painter->restore(); } void nmObjRectTool::paintTrackingRealObj(QPainter* painter, const ZxPaintParam& param) { if(!m_bTracking) { return; } nmObjRect* pObj = dynamic_cast(m_pObj); Q_ASSERT(NULL != pObj); if (nullptr == pObj) { return; // 如果pObj为nullptr,直接返回 } int nIndex = pObj->m_nRectHitIndex; RectBoundPos eHitPos = pObj->m_oHitPos; Qt::CursorShape o = getCursorBy((int)eHitPos, nIndex); QVector vec = pObj->getAllPos(); QPointF ptOld = m_ptStart; // 第一次击中的点 QPointF ptNew = getCurrentPos(); // 鼠标当前的位置 if(eHitPos == RBP_LeftTop || eHitPos == RBP_RightBottom) { // 击中左上角或右下角 if(nIndex >= 0 && nIndex < vec.count()) { //更新相邻的三个点的位置 vec[nIndex] = getCurrentPos(); vec[(nIndex + 3) % 4].setX(vec[nIndex].x()); vec[(nIndex + 1) % 4].setY(vec[nIndex].y()); } } else if(eHitPos == RBP_RightTop || eHitPos == RBP_LeftBottom) { // 击中右上角或左下角 if(nIndex >= 0 && nIndex < vec.count()) { vec[nIndex] = getCurrentPos(); vec[(nIndex + 3) % 4].setY(vec[nIndex].y()); vec[(nIndex + 1) % 4].setX(vec[nIndex].x()); } } else if(eHitPos == RBP_Top || eHitPos == RBP_Bottom) { // 击中上边或下边,只能纵向移动 if(nIndex >= 0 && nIndex < vec.count()) { QPointF p1 = ptNew; p1.setX(ptOld.x()); vec[nIndex] = pObj->offsetPoint(vec[nIndex], ptOld, p1); vec[(nIndex + 1) % 4] = pObj->offsetPoint(vec[(nIndex + 1) % 4], ptOld, p1); } } else if(eHitPos == RBP_Left || eHitPos == RBP_Right) { // 击中左边或右边,只能横向移动 if(nIndex >= 0 && nIndex < vec.count()) { ptNew.setY(ptOld.y()); vec[nIndex] = pObj->offsetPoint(vec[nIndex], ptOld, ptNew); vec[(nIndex + 1) % 4] = pObj->offsetPoint(vec[(nIndex + 1) % 4], ptOld, ptNew); } } else if(eHitPos == RBP_Inner) { // 击中内部,整体移动 for(int i = 0; i < vec.count(); i++) { vec[i] = pObj->offsetPoint(vec[i], ptOld, ptNew); } } else { return; } painter->save(); QPen pen(Qt::DashLine); painter->setPen(pen); // 绘制矩形路径 QPainterPath oPath; oPath.moveTo(vec[0]); for(int i = 1; i < vec.count(); i++) { oPath.lineTo(vec[i]); } oPath.closeSubpath(); // 填充路径背景 QColor clr = pObj->getBackgrdColor(); clr.setAlpha(128); painter->fillPath(oPath, QBrush(clr)); changeCursor(o); painter->restore(); } Qt::CursorShape nmObjRectTool::getCursorBy(const int& nOption, const int& nSubIndex) { nmObjRect* pObj = dynamic_cast(m_pObj); Q_ASSERT(NULL != pObj); if (nullptr == pObj) { return Qt::ArrowCursor; // 如果pObj为nullptr,直接返回 } RectBoundPos eHitPos = pObj->m_oHitPos; // 选择状态下起作用 if (!pObj->isSelected()) { return Qt::ArrowCursor; } if(eHitPos == RBP_LeftTop || eHitPos == RBP_RightBottom) { return (Qt::SizeFDiagCursor); } else if(eHitPos == RBP_RightTop || eHitPos == RBP_LeftBottom) { return (Qt::SizeBDiagCursor); } else if(eHitPos == RBP_Top || eHitPos == RBP_Bottom) { return (Qt::SizeVerCursor); } else if(eHitPos == RBP_Left || eHitPos == RBP_Right) { return (Qt::SizeHorCursor); } else if(eHitPos == RBP_Inner) { return (Qt::PointingHandCursor); // 手 } return Qt::ArrowCursor; // 鼠标 }