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

294 lines
7.9 KiB
C++

#include <QPainter>
#include "ZxBaseUtil.h"
#include "nmObjRect.h"
#include "nmObjRectTool.h"
#include <vector>
nmObjRectTool::nmObjRectTool() : nmObjToolBase()
{
setText(tr("nObjRectTool"));
m_oNot = NMOT_Rect;
}
bool nmObjRectTool::onLeftDown(const QPointF& pt)
{
nmObjRect* pObj = dynamic_cast<nmObjRect*>(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<nmObjRect*>(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<nmObjRect*>(m_pObj);
if(NULL == pObj) { // 绘图对象尚未创建(鼠标选点ing
getView()->setCursorKeeping(false);
changeCursor(Qt::ArrowCursor);
// 保存其余三个点的坐标
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<nmObjRect*>(m_pObj);
if(NULL == pObj) { // 绘图对象尚未创建(鼠标选点ing
return false;
} 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<nmObjRect*>(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<nmObjRect*>(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<QPointF> 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<nmObjRect*>(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; // 鼠标
}