|
|
#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; // 鼠标
|
|
|
}
|