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/nmObjPolygonTool.cpp

271 lines
6.5 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 "ZxBaseUtil.h"
#include "nmObjPolygon.h"
#include "nmObjPolygonTool.h"
nmObjPolygonTool::nmObjPolygonTool() : nmObjToolBase()
{
setText(tr("nObjPolygonTool"));
m_oNot = NMOT_Polygon;
}
bool nmObjPolygonTool::onLeftDown(const QPointF& pt)
{
if (nullptr == m_pObj) //绘图对象尚未创建(鼠标选点ing
{
m_bTracking = true;
m_ptStart = pt;
changeCursor(Qt::CrossCursor);
// 对于持续性选点的工具,需要设置
getView()->setCursorKeeping(true);
if (m_vecPoints.count() > 2) //如果与第一个点非常接近,自动封闭处理
{
double nDistance = 3.0f;
if ((qAbs(m_vecPoints[0].x() - pt.x()) < nDistance) && \
(qAbs(m_vecPoints[0].y() - pt.y()) < nDistance))
{
getView()->setCursorKeeping(false);
changeCursor(Qt::ArrowCursor);
emit sigPtsFinished(m_vecPoints); //注该句正确执行之后会把本工具nmObjPolygonTool
//与View之间detach
m_vecPoints.clear();
m_bTracking = false;
return true;
}
}
m_vecPoints.push_back(pt);
return true;
}
else //业已绑定绘图对象
{
return nmObjToolBase::onLeftDown(pt);
}
}
bool nmObjPolygonTool::onMouseMove(const QPointF& pt)
{
if (nullptr == m_pObj) //绘图对象尚未创建(鼠标选点ing
{
m_ptMove = pt;
if (m_bTracking)
{
updateLastMoveArea(true);
}
return true;
}
else //业已绑定绘图对象
{
return nmObjToolBase::onMouseMove(pt);
}
}
bool nmObjPolygonTool::onLeftUp(const QPointF& pt)
{
if (nullptr == m_pObj) //绘图对象尚未创建(鼠标选点ing
{
// if (m_bTracking)
// {
// m_bTracking = false;
// }
if (!m_vecPoints.isEmpty()) //避免本工具被Detach之后无法update
{
updateLastMoveArea(true);
}
return true;
}
else //业已绑定绘图对象
{
return nmObjToolBase::onLeftUp(pt);
}
}
bool nmObjPolygonTool::onLeftDoubleClick(const QPointF& pt)
{
if (nullptr == m_pObj) //绘图对象尚未创建(鼠标选点ing
{
// 多边形至少需要 3 个点才能闭合成有效面,点数不足时吞掉双击。
if (m_vecPoints.count() < 3) {
return true;
}
changeCursor(Qt::ArrowCursor);
emit sigPtsFinished(m_vecPoints); //注该句正确执行之后会把本工具nmObjPolygonTool
//与View之间detach
m_vecPoints.clear();
if (m_bTracking)
{
m_bTracking = false;
}
return true;
}
else //业已绑定绘图对象
{
// 双击内部,取消选中状态
if (m_pObj->m_oHitOption == OHO_Inner) {
m_pObj->setSelected(false);
return true;
}
return nmObjToolBase::onLeftDoubleClick(pt);
}
}
bool nmObjPolygonTool::onMouseWheel(const QPointF& pt, int delta)
{
return nmObjToolBase::onMouseWheel(pt, delta);
}
void nmObjPolygonTool::onPaint(QPainter* painter, const ZxPaintParam& param)
{
nmObjPolygon* pObj = dynamic_cast<nmObjPolygon*>(m_pObj);
if (pObj == nullptr) //绘图对象尚未创建(鼠标选点ing
{
Qt::CursorShape o = Qt::CrossCursor;
changeCursor(o);
paintTrackingVirtualObj(painter, param);
}
else //业已绑定绘图对象
{
paintTrackingRealObj(painter, param);
}
}
void nmObjPolygonTool::paintTrackingVirtualObj(QPainter* painter, const ZxPaintParam& param)
{
painter->save();
// 已经选的点
{
QPen pen(Qt::SolidLine);
painter->setPen(pen);
for (int i = 0; i < m_vecPoints.count() - 1; i++)
{
painter->drawLine(m_vecPoints[i], m_vecPoints[i + 1]);
}
}
// 当前正在进行的点
if (m_bTracking || !m_vecPoints.isEmpty())
{
QPen pen(Qt::DashLine);
painter->setPen(pen);
painter->drawLine(m_ptStart, m_ptMove);
if (m_vecPoints.count() >= 2)
{
painter->drawLine(m_vecPoints[0], m_ptMove);
}
}
painter->restore();
}
void nmObjPolygonTool::paintTrackingRealObj(QPainter* painter, const ZxPaintParam& param)
{
if (!m_bTracking)
{
return;
}
nmObjPolygon* pObj = dynamic_cast<nmObjPolygon*>(m_pObj);
Q_ASSERT (nullptr != pObj);
if (nullptr == pObj)
{
return; // 如果pObj为nullptr直接返回
}
int nIndex = pObj->m_nHitIndex;
Qt::CursorShape o = getCursorBy((int)m_oHitOption, nIndex);
QVector<QPointF> vec = pObj->getAllPos();
QPointF ptOld = m_ptStart;
QPointF ptNew = getCurrentPos();
if (m_oHitOption == OHO_Point)
{
if (nIndex >= 0 && nIndex < vec.count())
{
vec[nIndex] = getCurrentPos();
}
}
else if (m_oHitOption == OHO_Bound)
{
if (nIndex >= 0 && nIndex < vec.count())
{
int nNext = (nIndex == vec.count() - 1) ? 0 : (nIndex + 1);
vec[nIndex] = pObj->offsetPoint(vec[nIndex], ptOld, ptNew);
vec[nNext] = pObj->offsetPoint(vec[nNext], ptOld, ptNew);
}
}
else if (m_oHitOption == OHO_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 nmObjPolygonTool::getCursorBy(const int& nOption,
const int& nSubIndex)
{
if (nOption < 0)
{
return Qt::ArrowCursor;
}
// 选择状态下起作用
if (!m_pObj->isSelected()) {
return Qt::ArrowCursor;
}
ObjHitOption oHitOption = (ObjHitOption)nOption;
if (oHitOption == OHO_Point)
{
return (Qt::CrossCursor);
}
else if (oHitOption == OHO_Bound)
{
return (Qt::CrossCursor);
}
else if (oHitOption == OHO_Inner)
{
return (Qt::PointingHandCursor);
}
return Qt::ArrowCursor;
}