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

304 lines
8.3 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 "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);
// 矩形依赖拖拽成形,起点和终点过近时取消本次创建,避免双击或误点生成零尺寸图元。
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<nmObjRect*>(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<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; // 鼠标
}