|
|
#include <QPainter>
|
|
|
|
|
|
#include "ZxSerializer.h"
|
|
|
#include "IxPtyPano.h"
|
|
|
|
|
|
#include "ZxSubAxisX.h"
|
|
|
#include "ZxSubAxisY.h"
|
|
|
|
|
|
#include "nmObjRoundTool.h"
|
|
|
#include "nmObjRound.h"
|
|
|
#include "nmDataAnalyzeManager.h"
|
|
|
|
|
|
ZX_DEFINE_DYNAMIC(nObjRound, nmObjRound)
|
|
|
|
|
|
nmObjRound::nmObjRound() {
|
|
|
m_sObjTag = "nObjRound";
|
|
|
nmObjRound::init("", NULL, NULL);
|
|
|
}
|
|
|
|
|
|
nmObjRound::nmObjRound(const QString& sName, \
|
|
|
ZxSubAxisX* pAxisX, \
|
|
|
ZxSubAxisY* pAxisY) {
|
|
|
m_sObjTag = "nObjRound";
|
|
|
nmObjRound::init(sName, pAxisX, pAxisY);
|
|
|
}
|
|
|
|
|
|
nmObjRound::~nmObjRound() {
|
|
|
}
|
|
|
|
|
|
// 初始化矩形对象对应的笔和填充颜色
|
|
|
void nmObjRound::init(const QString& sName, \
|
|
|
ZxSubAxisX* pAxisX, \
|
|
|
ZxSubAxisY* pAxisY) {
|
|
|
nmObjBase::init(sName, pAxisX, pAxisY);
|
|
|
|
|
|
nmObjRound::initFlags();
|
|
|
|
|
|
m_oPen = QPen(QBrush(QColor(0, 0, 0)), \
|
|
|
0.5f, Qt::SolidLine);
|
|
|
m_clrBackgrd = QColor(255, 170, 255, 100);
|
|
|
|
|
|
loadTempl();
|
|
|
}
|
|
|
|
|
|
// 初始化绘制圆形的工具
|
|
|
void nmObjRound::initTools() {
|
|
|
m_pTool = new nmObjRoundTool();
|
|
|
|
|
|
nmObjBase::initTools();
|
|
|
}
|
|
|
|
|
|
void nmObjRound::initFlags() {
|
|
|
setLockPos(false);
|
|
|
setLockSize(false);
|
|
|
setReadOnly(false);
|
|
|
}
|
|
|
|
|
|
QColor nmObjRound::getBackgrdColor() const {
|
|
|
//if (m_nLineIndex)
|
|
|
//return m_vecPresType[m_nLineIndex]
|
|
|
return m_clrBackgrd;
|
|
|
}
|
|
|
|
|
|
void nmObjRound::setBackgrdColor(QColor color) {
|
|
|
if (m_clrBackgrd != color) {
|
|
|
//m_vecPresType[m_nLineIndex] =
|
|
|
m_clrBackgrd = color;
|
|
|
update();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
bool nmObjRound::hitTest(const QPointF& pt) {
|
|
|
return nmObjBase::hitTest(pt);
|
|
|
}
|
|
|
|
|
|
bool nmObjRound::_runHitTest(const QPointF& pt, int& nOption, int& nSubIndex) {
|
|
|
if (!nmObjBase::_runHitTest(pt, nOption, nSubIndex)) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
nOption = -1;
|
|
|
nSubIndex = 0;
|
|
|
|
|
|
if (NULL == m_pAxisX || NULL == m_pAxisY) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
QVector<QPointF> pts = getPosOf(m_vecPoints);
|
|
|
|
|
|
// 判断半径是否相同,不相同先修改半径相同
|
|
|
if (pts[1].x() != pts[1].y())
|
|
|
{
|
|
|
double radius = qAbs(pts[0].y() - pts[2].y());
|
|
|
pts[1] = QPointF(radius, radius);
|
|
|
|
|
|
// 重新计算圆上的四个点
|
|
|
QPointF center = pts[0]; // 圆心
|
|
|
|
|
|
// 上点 (x, y - radius)
|
|
|
pts[2] = QPointF(center.x(), center.y() - radius);
|
|
|
|
|
|
// 右点 (x + radius, y)
|
|
|
pts[3] = QPointF(center.x() + radius, center.y());
|
|
|
|
|
|
// 下点 (x, y + radius)
|
|
|
pts[4] = QPointF(center.x(), center.y() + radius);
|
|
|
|
|
|
// 左点 (x - radius, y)
|
|
|
pts[5] = QPointF(center.x() - radius, center.y());
|
|
|
}
|
|
|
|
|
|
// 点
|
|
|
double r = 1.f;
|
|
|
QPointF p1;//p1:击中的点;p2:圆心
|
|
|
bool isInitialized = false;
|
|
|
for (int i = 2; i < pts.count(); i++) { //下标从2开始
|
|
|
QPointF ptTopLeft = QPointF(pts[i].x() - r,
|
|
|
pts[i].y() - r);
|
|
|
QSizeF sz = QSizeF(r * 2.f, r * 2.f);
|
|
|
|
|
|
QRectF rt = QRectF(ptTopLeft, sz);
|
|
|
bool b = rt.contains(pt);
|
|
|
if (b) {
|
|
|
// 击中了这个点,记录该点的位置
|
|
|
p1 = pts[i];
|
|
|
nSubIndex = i;
|
|
|
isInitialized = true;
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
QPointF p2 = pts[0];
|
|
|
|
|
|
//判断该点所在的位置,与圆心作比较
|
|
|
if (isInitialized) {
|
|
|
if(p1.x() == p2.x() && p1.y() < p2.y()) { //上
|
|
|
nOption = (int)OHO_Point;
|
|
|
} else if (p1.x() > p2.x() && p1.y() == p2.y()) { //右
|
|
|
nOption = (int)OHO_Point;
|
|
|
} else if (p1.x() == p2.x () && p1.y() > p2.y()) { //下
|
|
|
nOption = (int)OHO_Point;
|
|
|
} else if(p1.x() < p2.x() && p1.y() == p2.y()) {
|
|
|
nOption = (int)OHO_Point;//左
|
|
|
}
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
// 判断线所在的位置
|
|
|
qreal distance = QLineF(pts[0], pt).length();
|
|
|
qreal radius = pts[1].x();
|
|
|
|
|
|
// 允许误差范围
|
|
|
qreal epsilon = 2.0;
|
|
|
|
|
|
// 判断鼠标是否位于圆的边界(即圆的线)上
|
|
|
if (fabs(distance - radius) <= epsilon) {
|
|
|
nOption = (int)OHO_Bound;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
// 内部
|
|
|
QPainterPath oPath;
|
|
|
// 添加圆形路径
|
|
|
oPath.addEllipse(pts[0], pts[1].x(), pts[1].y());
|
|
|
if (oPath.contains(pt) && isSelected()) {
|
|
|
nOption = (int)OHO_Inner;
|
|
|
nSubIndex = 0;
|
|
|
return true;
|
|
|
} else {
|
|
|
nOption = (int)OHO_None;
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
bool nmObjRound::runMove(const QPointF& pt1,
|
|
|
const QPointF& pt2) {
|
|
|
if (isLockPos()) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
if (NULL == m_pAxisX || NULL == m_pAxisY) {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
int nCount = m_vecPoints.count();
|
|
|
QVector<QPointF> vecPts = getPosOf(m_vecPoints); //屏幕值
|
|
|
|
|
|
// 判断半径是否相同,不相同先修改半径相同
|
|
|
if (vecPts[1].x() != vecPts[1].y())
|
|
|
{
|
|
|
double radius = qAbs(vecPts[0].y() - vecPts[2].y());
|
|
|
vecPts[1] = QPointF(radius, radius);
|
|
|
|
|
|
// 重新计算圆上的四个点
|
|
|
QPointF center = vecPts[0]; // 圆心
|
|
|
|
|
|
// 上点 (x, y - radius)
|
|
|
vecPts[2] = QPointF(center.x(), center.y() - radius);
|
|
|
|
|
|
// 右点 (x + radius, y)
|
|
|
vecPts[3] = QPointF(center.x() + radius, center.y());
|
|
|
|
|
|
// 下点 (x, y + radius)
|
|
|
vecPts[4] = QPointF(center.x(), center.y() + radius);
|
|
|
|
|
|
// 左点 (x - radius, y)
|
|
|
vecPts[5] = QPointF(center.x() - radius, center.y());
|
|
|
}
|
|
|
|
|
|
if (m_oHitOption == OHO_Point) { //击中上下边
|
|
|
// x不变
|
|
|
QPointF p1 = pt2;
|
|
|
p1.setX(pt1.x());
|
|
|
|
|
|
//计算偏移量
|
|
|
qreal offset = pt1.y() - pt2.y();
|
|
|
|
|
|
// 判断是上边还是下边
|
|
|
if (m_nHitIndex == 2) { // 上边
|
|
|
// 更新半径
|
|
|
vecPts[1].setX(vecPts[1].x() + offset);
|
|
|
vecPts[1].setY(vecPts[1].y() + offset);
|
|
|
|
|
|
// 更新四个点
|
|
|
vecPts[2].setY(vecPts[2].y() - offset);
|
|
|
vecPts[4].setY(vecPts[4].y() + offset);
|
|
|
|
|
|
vecPts[5].setX(vecPts[5].x() - offset); //左
|
|
|
vecPts[3].setX(vecPts[3].x() + offset); //右
|
|
|
} else if (m_nHitIndex == 4) { // 下边
|
|
|
|
|
|
offset = pt2.y() - pt1.y();
|
|
|
|
|
|
// 更新半径
|
|
|
vecPts[1].setX(vecPts[1].x() + offset);
|
|
|
vecPts[1].setY(vecPts[1].y() + offset);
|
|
|
|
|
|
// 下边
|
|
|
vecPts[4].setY(vecPts[4].y() + offset);
|
|
|
vecPts[2].setY(vecPts[2].y() - offset);
|
|
|
|
|
|
vecPts[3].setX(vecPts[3].x() + offset);
|
|
|
vecPts[5].setX(vecPts[5].x() - offset);
|
|
|
}else if (m_nHitIndex == 3) { // 右边
|
|
|
offset = pt2.x() - pt1.x();
|
|
|
|
|
|
// 更新半径
|
|
|
vecPts[1].setX(vecPts[1].x() + offset);
|
|
|
vecPts[1].setY(vecPts[1].y() + offset);
|
|
|
|
|
|
// 右边
|
|
|
vecPts[3].setX(vecPts[3].x() + offset);
|
|
|
vecPts[5].setX(vecPts[5].x() - offset);
|
|
|
|
|
|
vecPts[2].setY(vecPts[2].y() - offset); // 上
|
|
|
vecPts[4].setY(vecPts[4].y() + offset); // 下
|
|
|
} else if (m_nHitIndex == 5) { // 左边
|
|
|
offset = pt1.x() - pt2.x();
|
|
|
|
|
|
// 更新半径
|
|
|
vecPts[1].setX(vecPts[1].x() + offset);
|
|
|
vecPts[1].setY(vecPts[1].y() + offset);
|
|
|
|
|
|
// 左边
|
|
|
vecPts[5].setX(vecPts[5].x() - offset);
|
|
|
vecPts[3].setX(vecPts[3].x() + offset);
|
|
|
|
|
|
vecPts[2].setY(vecPts[2].y() - offset); // 上
|
|
|
vecPts[4].setY(vecPts[4].y() + offset); // 下
|
|
|
}
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
|
|
|
return moveToPos(vecPts);
|
|
|
} else if (m_oHitOption == OHO_Bound) { //左右两边
|
|
|
// y不变
|
|
|
QPointF p1 = pt2;
|
|
|
p1.setY(pt1.y());
|
|
|
|
|
|
//计算偏移量
|
|
|
qreal offset = pt2.x() - pt1.x();
|
|
|
|
|
|
// 判断是上边还是下边
|
|
|
if (m_nHitIndex == 3) { // 右边
|
|
|
// 更新半径
|
|
|
vecPts[1].setX(vecPts[1].x() + offset);
|
|
|
vecPts[1].setY(vecPts[1].y() + offset);
|
|
|
|
|
|
// 更新四个点
|
|
|
vecPts[3].setX(vecPts[3].x() + offset); //右
|
|
|
vecPts[5].setX(vecPts[5].x() - offset); //左
|
|
|
|
|
|
vecPts[2].setY(vecPts[2].y() - offset); // 上
|
|
|
vecPts[4].setY(vecPts[4].y() + offset); //下
|
|
|
} else if (m_nHitIndex == 5) { // 左边
|
|
|
|
|
|
offset = pt1.x() - pt2.x();
|
|
|
|
|
|
// 更新半径
|
|
|
vecPts[1].setX(vecPts[1].x() + offset);
|
|
|
vecPts[1].setY(vecPts[1].y() + offset);
|
|
|
|
|
|
// 更新四个点
|
|
|
vecPts[3].setX(vecPts[3].x() + offset); //右
|
|
|
vecPts[5].setX(vecPts[5].x() - offset); //左
|
|
|
|
|
|
vecPts[2].setY(vecPts[2].y() - offset); // 上
|
|
|
vecPts[4].setY(vecPts[4].y() + offset); //下
|
|
|
}
|
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
|
|
|
return moveToPos(vecPts);
|
|
|
}
|
|
|
|
|
|
if (m_oHitOption == OHO_Inner) {
|
|
|
// 更新圆点
|
|
|
vecPts[0] = offsetPoint(vecPts[0], pt1, pt2);
|
|
|
m_dOffsetX = pt2.x() - pt1.x();
|
|
|
m_dOffsetY = pt2.y() - pt1.y();
|
|
|
|
|
|
// 更新上下左右四个点
|
|
|
for (int i = 2; i < vecPts.count(); i++) {
|
|
|
vecPts[i] = offsetPoint(vecPts[i], pt1, pt2);
|
|
|
}
|
|
|
|
|
|
nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged();
|
|
|
return moveToPos(vecPts);
|
|
|
} else {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
|
|
|
void nmObjRound::fillPtyPano(IxPtyPano* sheet) {
|
|
|
nmObjBase::fillPtyPano(sheet);
|
|
|
|
|
|
ZX_PROP("ObjPolygon.Pen", getPen, setPen);
|
|
|
ZX_PROP("ObjPolygon.BackgrdColor", getBackgrdColor, setBackgrdColor);
|
|
|
}
|
|
|
|
|
|
void nmObjRound::paintBack(QPainter* painter, const ZxPaintParam& param) {
|
|
|
// 判断当前坐标轴是否有效
|
|
|
if (NULL == m_pAxisX || NULL == m_pAxisY || \
|
|
|
m_pAxisX->getRangeMin() == m_pAxisX->getRangeMax() || \
|
|
|
m_pAxisY->getRangeMin() == m_pAxisY->getRangeMax()) {
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
painter->save();
|
|
|
|
|
|
//QVector<QPointF> pts = getPosOf(m_vecPoints); //获取当前对象的原点的坐标
|
|
|
//QRectF bound = getBounds(); //获取图元基础边框(位置)
|
|
|
|
|
|
// 判断半径是否相同,不相同先修改半径相同
|
|
|
if (m_vecPoints[1].x() != m_vecPoints[1].y())
|
|
|
{
|
|
|
// 重新计算半径
|
|
|
// 计算半径(绝对值)
|
|
|
double radius = qAbs(m_vecPoints[0].y() - m_vecPoints[2].y());
|
|
|
|
|
|
// 更新 vecConvertPoints[1] 为 (radius, radius)
|
|
|
m_vecPoints[1] = QPointF(radius, radius);
|
|
|
}
|
|
|
|
|
|
QVector<QPointF> pts = getPosOf(m_vecPoints);
|
|
|
|
|
|
// 判断半径是否相同,不相同先修改半径相同,重新计算上下左右四个点的坐标
|
|
|
if (pts[1].x() != pts[1].y())
|
|
|
{
|
|
|
double radius = qAbs(pts[0].y() - pts[2].y());
|
|
|
pts[1] = QPointF(radius, radius);
|
|
|
|
|
|
// 重新计算圆上的四个点
|
|
|
QPointF center = pts[0]; // 圆心
|
|
|
|
|
|
// 上点 (x, y - radius)
|
|
|
pts[2] = QPointF(center.x(), center.y() - radius);
|
|
|
|
|
|
// 右点 (x + radius, y)
|
|
|
pts[3] = QPointF(center.x() + radius, center.y());
|
|
|
|
|
|
// 下点 (x, y + radius)
|
|
|
pts[4] = QPointF(center.x(), center.y() + radius);
|
|
|
|
|
|
// 左点 (x - radius, y)
|
|
|
pts[5] = QPointF(center.x() - radius, center.y());
|
|
|
}
|
|
|
|
|
|
if (!pts.empty()) { //圆存在
|
|
|
// 填充
|
|
|
QPainterPath oPath;
|
|
|
|
|
|
// 添加圆形路径
|
|
|
oPath.addEllipse(pts[0], pts[1].x(), pts[1].y());
|
|
|
|
|
|
// m_clrBackgrd.setAlpha(100);
|
|
|
painter->fillPath(oPath, QBrush(m_clrBackgrd));
|
|
|
|
|
|
// 边界
|
|
|
QPen pen = m_oPen;
|
|
|
painter->setPen(pen);
|
|
|
painter->drawEllipse(pts[0], pts[1].x(), pts[1].y());
|
|
|
|
|
|
// 获取圆心和半径
|
|
|
QPointF center = pts[0];
|
|
|
qreal radius = pts[1].x();
|
|
|
|
|
|
// 计算边界框的左上角和右下角坐标
|
|
|
QPointF topLeft = center - QPointF(radius, radius);
|
|
|
QPointF bottomRight = center + QPointF(radius, radius);
|
|
|
|
|
|
// 创建QRectF对象
|
|
|
QRectF bound(topLeft, bottomRight);
|
|
|
|
|
|
// 绘制名称文字
|
|
|
painter->setFont(QFont("Arial", 8, QFont::Normal));
|
|
|
painter->setPen(Qt::black);
|
|
|
ZxDrawHelper::drawText(painter,
|
|
|
bound,
|
|
|
Qt::AlignCenter | Qt::AlignVCenter,
|
|
|
m_sName);
|
|
|
}
|
|
|
|
|
|
//选中状态下的圆形形状
|
|
|
if (isSelected()) {
|
|
|
QPen pen(QBrush(Qt::black), 0.0f, Qt::DotLine);
|
|
|
painter->setPen(pen);
|
|
|
painter->drawEllipse(pts[0], pts[1].x(), pts[1].y());
|
|
|
for (int i = 2; i < pts.count(); i++) {
|
|
|
double w = 2.2f;
|
|
|
QPointF pt = pts[i];
|
|
|
QRectF rect(pt.x() - w * 0.5f, pt.y() - w * 0.5f, w, w); //每个点周围画小矩形边框
|
|
|
|
|
|
// 击中四个点
|
|
|
if (m_nHitIndex == i && (m_oHitOption == OHO_Point || m_oHitOption == OHO_Bound)) {
|
|
|
QBrush br(Qt::red);
|
|
|
painter->fillRect(rect, br);
|
|
|
} else {
|
|
|
painter->setPen(QColor(0, 0, 128));
|
|
|
painter->drawRect(rect);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
painter->restore();
|
|
|
}
|