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

842 lines
25 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 "nmPlotGraphicBinder.h"
#include "nmObjLineFault.h"
#include "nmDataFault.h"
#include "nmObjLineCrack.h"
#include "nmDataFracture.h"
#include "nmObjRoundOutline.h"
#include "nmObjRectOutline.h"
#include "nmObjPolygonOutline.h"
#include "nmDataOutline.h"
#include "nmObjLineMeasure.h"
#include "nmDataMeasure.h"
#include "nmObjBase.h"
#include "nmDataAnalyzeManager.h"
#include <QMetaObject>
nmPlotGraphicBinder::nmPlotGraphicBinder(nmDataAnalyzeManager* pDataMgr, QObject* parent)
: QObject(parent)
, m_pDataMgr(pDataMgr)
{
}
// 用户画完断层后:创建数据对象并建立绑定
void nmPlotGraphicBinder::createFaultForGraphic(nmObjLineFault* pGraphic)
{
if (!pGraphic || !m_pDataMgr) {
return;
}
// 创建数据对象
nmDataFault* pData = m_pDataMgr->createFault();
// 将图元值推入数据
pData->setFaultName(pGraphic->getName());
pData->setFaultPoints(pGraphic->getAllValues());
// 建立信号连接
_connectFault(pGraphic, pData);
m_pDataMgr->notifyDataChanged();
}
// 从文件加载:绑定已有数据到已有图元
void nmPlotGraphicBinder::bindFaultToGraphic(nmObjLineFault* pGraphic, nmDataFault* pData)
{
if (!pGraphic || !pData) {
return;
}
// 将数据值推到图元
_pushFaultDataToGraphic(pGraphic, pData);
// 建立信号连接
_connectFault(pGraphic, pData);
}
// 删除图元:断开连接并移除数据
void nmPlotGraphicBinder::removeFaultBinding(nmObjLineFault* pGraphic)
{
if (!pGraphic) {
return;
}
// 断开信号
_disconnectFault(pGraphic);
// 从数据中心移除
if (m_mapFaultData.contains(pGraphic)) {
nmDataFault* pData = m_mapFaultData.value(pGraphic);
if (pData && m_pDataMgr) {
m_pDataMgr->removeFaultData(pData);
}
m_mapFaultData.remove(pGraphic);
}
}
nmDataFault* nmPlotGraphicBinder::getFaultDataFor(nmObjLineFault* pGraphic)
{
return m_mapFaultData.value(pGraphic, nullptr);
}
// 名称同步:检测图元名称与数据名称是否一致,不一致则同步
void nmPlotGraphicBinder::syncFaultName(nmObjLineFault* pGraphic)
{
if (!pGraphic) return;
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (pData && pData->getFaultName() != pGraphic->getName()) {
pData->setFaultName(pGraphic->getName());
}
}
// 切换分析时更新绑定的 DataManager
// 旧图元已由 deleteAllPlotObjs 清除,清理残留映射避免悬空指针
void nmPlotGraphicBinder::updateDataMgr(nmDataAnalyzeManager* pDataMgr)
{
m_mapFaultData.clear();
m_setBoundGraphics.clear();
m_mapCrackData.clear();
m_setBoundCrackGraphics.clear();
m_mapOutlineData.clear();
m_setBoundOutlineGraphics.clear();
m_mapMeasureData.clear();
m_pDataMgr = pDataMgr;
}
// 将数据值推到图元本地副本
void nmPlotGraphicBinder::_pushFaultDataToGraphic(nmObjLineFault* pGraphic, nmDataFault* pData)
{
// 阻断信号,防止推送中触发反向同步
pGraphic->blockSignals(true);
pGraphic->setName(pData->getFaultName());
int flowModel = (pData->getFaultFlowModel().getValue() == tr("Leaky")) ? 0 : 1;
pGraphic->setFaultFlowModel(flowModel);
pGraphic->setFaultLeakage(pData->getFaultLeakage().getValue().toDouble());
pGraphic->blockSignals(false);
}
// 建立图元与数据的双向信号连接
void nmPlotGraphicBinder::_connectFault(nmObjLineFault* pGraphic, nmDataFault* pData)
{
QObject::connect(pGraphic, SIGNAL(sigFlowModelChanged(int)),
this, SLOT(onGraphicFlowModelChanged(int)));
QObject::connect(pGraphic, SIGNAL(sigLeakageChanged(double)),
this, SLOT(onGraphicLeakageChanged(double)));
QObject::connect(pGraphic, SIGNAL(sigPointsChanged()),
this, SLOT(onGraphicPointsChanged()));
QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicVisibleChanged(bool)));
m_mapFaultData[pGraphic] = pData;
m_setBoundGraphics.insert(pGraphic);
pGraphic->setGraphicBinder(this);
}
// 断开图元与本 Binder 的所有信号连接
void nmPlotGraphicBinder::_disconnectFault(nmObjLineFault* pGraphic)
{
QObject::disconnect(pGraphic, SIGNAL(sigFlowModelChanged(int)),
this, SLOT(onGraphicFlowModelChanged(int)));
QObject::disconnect(pGraphic, SIGNAL(sigLeakageChanged(double)),
this, SLOT(onGraphicLeakageChanged(double)));
QObject::disconnect(pGraphic, SIGNAL(sigPointsChanged()),
this, SLOT(onGraphicPointsChanged()));
QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicVisibleChanged(bool)));
m_setBoundGraphics.remove(pGraphic);
}
// 图元属性变更 → 同步到数据
// 流动模型变更
void nmPlotGraphicBinder::onGraphicFlowModelChanged(int model)
{
nmObjLineFault* pGraphic = qobject_cast<nmObjLineFault*>(sender());
if (!pGraphic) return;
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFaultFlowModel();
attr.setValue(model == 0 ? tr("Leaky") : tr("Composite Limit"));
pData->setFaultFlowModel(attr);
}
// 渗漏率变更
void nmPlotGraphicBinder::onGraphicLeakageChanged(double leakage)
{
nmObjLineFault* pGraphic = qobject_cast<nmObjLineFault*>(sender());
if (!pGraphic) return;
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFaultLeakage();
attr.setValue(leakage);
pData->setFaultLeakage(attr);
}
// 点坐标变更
void nmPlotGraphicBinder::onGraphicPointsChanged()
{
nmObjLineFault* pGraphic = qobject_cast<nmObjLineFault*>(sender());
if (!pGraphic) return;
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (!pData) return;
pData->setFaultPoints(pGraphic->getAllValues());
pData->setFaultName(pGraphic->getName());
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 可见性变更
void nmPlotGraphicBinder::onGraphicVisibleChanged(bool bVisible)
{
nmObjLineFault* pGraphic = qobject_cast<nmObjLineFault*>(sender());
if (!pGraphic) return;
nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr);
if (!pData) return;
pData->setPlotVisible(bVisible);
}
// 数据变更(预留)
void nmPlotGraphicBinder::onDataChanged()
{
}
// ============ 裂缝绑定 ============
// 用户画完裂缝后:创建数据对象并建立绑定
void nmPlotGraphicBinder::createCrackForGraphic(nmObjLineCrack* pGraphic)
{
if (!pGraphic || !m_pDataMgr) {
return;
}
// 创建数据对象
nmDataFracture* pData = m_pDataMgr->createFracture();
// 将图元值推入数据
pData->setFractureName(pGraphic->getName());
pData->setFracturePoints(pGraphic->getAllValues());
// 建立信号连接
_connectCrack(pGraphic, pData);
m_pDataMgr->notifyDataChanged();
}
// 从文件加载:绑定已有裂缝数据到已有图元
void nmPlotGraphicBinder::bindCrackToGraphic(nmObjLineCrack* pGraphic, nmDataFracture* pData)
{
if (!pGraphic || !pData) {
return;
}
// 将数据值推到图元
_pushCrackDataToGraphic(pGraphic, pData);
// 建立信号连接
_connectCrack(pGraphic, pData);
}
// 删除裂缝图元:断开连接并移除数据
void nmPlotGraphicBinder::removeCrackBinding(nmObjLineCrack* pGraphic)
{
if (!pGraphic) {
return;
}
// 断开信号
_disconnectCrack(pGraphic);
// 从数据中心移除
if (m_mapCrackData.contains(pGraphic)) {
nmDataFracture* pData = m_mapCrackData.value(pGraphic);
if (pData && m_pDataMgr) {
m_pDataMgr->removeFractureData(pData);
}
m_mapCrackData.remove(pGraphic);
}
}
nmDataFracture* nmPlotGraphicBinder::getCrackDataFor(nmObjLineCrack* pGraphic)
{
return m_mapCrackData.value(pGraphic, nullptr);
}
// 名称同步:检测图元名称与数据名称是否一致,不一致则同步
void nmPlotGraphicBinder::syncCrackName(nmObjLineCrack* pGraphic)
{
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (pData && pData->getFractureName() != pGraphic->getName()) {
pData->setFractureName(pGraphic->getName());
}
}
// 将裂缝数据值推到图元本地副本
void nmPlotGraphicBinder::_pushCrackDataToGraphic(nmObjLineCrack* pGraphic, nmDataFracture* pData)
{
// 阻断信号,防止推送中触发反向同步
pGraphic->blockSignals(true);
pGraphic->setName(pData->getFractureName());
int flowModel = (pData->getFractureFlowModel().getValue() == tr("Infinite Conductivity")) ? 0 : 1;
pGraphic->setCrackFlowModel(flowModel);
pGraphic->setCrackDfc(pData->getFractureDfc().getValue().toDouble());
pGraphic->setCrackDw(pData->getFractureDw().getValue().toDouble());
pGraphic->blockSignals(false);
}
// 建立裂缝图元与数据的双向信号连接
void nmPlotGraphicBinder::_connectCrack(nmObjLineCrack* pGraphic, nmDataFracture* pData)
{
QObject::connect(pGraphic, SIGNAL(sigFlowModelChanged(int)),
this, SLOT(onGraphicCrackFlowModelChanged(int)));
QObject::connect(pGraphic, SIGNAL(sigDfcChanged(double)),
this, SLOT(onGraphicCrackDfcChanged(double)));
QObject::connect(pGraphic, SIGNAL(sigDwChanged(double)),
this, SLOT(onGraphicCrackDwChanged(double)));
QObject::connect(pGraphic, SIGNAL(sigPointsChanged()),
this, SLOT(onGraphicCrackPointsChanged()));
QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicCrackVisibleChanged(bool)));
m_mapCrackData[pGraphic] = pData;
m_setBoundCrackGraphics.insert(pGraphic);
pGraphic->setGraphicBinder(this);
}
// 断开裂缝图元与本 Binder 的所有信号连接
void nmPlotGraphicBinder::_disconnectCrack(nmObjLineCrack* pGraphic)
{
QObject::disconnect(pGraphic, SIGNAL(sigFlowModelChanged(int)),
this, SLOT(onGraphicCrackFlowModelChanged(int)));
QObject::disconnect(pGraphic, SIGNAL(sigDfcChanged(double)),
this, SLOT(onGraphicCrackDfcChanged(double)));
QObject::disconnect(pGraphic, SIGNAL(sigDwChanged(double)),
this, SLOT(onGraphicCrackDwChanged(double)));
QObject::disconnect(pGraphic, SIGNAL(sigPointsChanged()),
this, SLOT(onGraphicCrackPointsChanged()));
QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicCrackVisibleChanged(bool)));
m_setBoundCrackGraphics.remove(pGraphic);
}
// 裂缝流动模型变更
void nmPlotGraphicBinder::onGraphicCrackFlowModelChanged(int model)
{
nmObjLineCrack* pGraphic = qobject_cast<nmObjLineCrack*>(sender());
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFractureFlowModel();
attr.setValue(model == 0 ? tr("Infinite Conductivity") : tr("Finite Conductivity"));
pData->setFractureFlowModel(attr);
}
// 裂缝导流能力变更
void nmPlotGraphicBinder::onGraphicCrackDfcChanged(double dfc)
{
nmObjLineCrack* pGraphic = qobject_cast<nmObjLineCrack*>(sender());
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFractureDfc();
attr.setValue(dfc);
pData->setFractureDfc(attr);
}
// 裂缝储能比变更
void nmPlotGraphicBinder::onGraphicCrackDwChanged(double dw)
{
nmObjLineCrack* pGraphic = qobject_cast<nmObjLineCrack*>(sender());
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
nmDataAttribute attr = pData->getFractureDw();
attr.setValue(dw);
pData->setFractureDw(attr);
}
// 裂缝点坐标变更
void nmPlotGraphicBinder::onGraphicCrackPointsChanged()
{
nmObjLineCrack* pGraphic = qobject_cast<nmObjLineCrack*>(sender());
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
pData->setFracturePoints(pGraphic->getAllValues());
pData->setFractureName(pGraphic->getName());
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 裂缝可见性变更
void nmPlotGraphicBinder::onGraphicCrackVisibleChanged(bool bVisible)
{
nmObjLineCrack* pGraphic = qobject_cast<nmObjLineCrack*>(sender());
if (!pGraphic) return;
nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr);
if (!pData) return;
pData->setPlotVisible(bVisible);
}
// ==================== 边界图元绑定 ====================
// 圆形边界:用户画完后创建数据并绑定
void nmPlotGraphicBinder::createOutlineForGraphic(nmObjRoundOutline* pGraphic)
{
if (!pGraphic || !m_pDataMgr) return;
// 清理旧边界图元的绑定(数据中心同一时间只持有一个边界数据)
QList<nmObjBase*> oldGraphics = m_mapOutlineData.keys();
foreach (nmObjBase* pOld, oldGraphics) {
if (pOld != pGraphic) {
_disconnectOutline(pOld);
m_mapOutlineData.remove(pOld);
}
}
nmDataOutline* pData = m_pDataMgr->createOutline();
pData->setName(pGraphic->getName());
pData->setOutlinePoints(pGraphic->getAllValues());
pData->setFlowTypeList(pGraphic->m_vFlowTypeList);
pData->setOutlineType(NM_Data_Outline_Type::NM_Round_Outline_Type);
// 视觉属性同步到数据
pData->setPenWidth(pGraphic->getPen().widthF());
QColor roundClr = pGraphic->getBackgrdColor();
pData->setBackgrdColor(roundClr);
pData->setBackgrdAlpha(roundClr.alpha());
pData->setVisualPropsValid(true);
double qradius = pGraphic->getAllValues()[2].y() - pGraphic->getAllValues()[0].y();
pData->setRadius(qradius);
pData->setCenter(pGraphic->getAllValues()[0]);
m_mapOutlineData[pGraphic] = pData;
m_setBoundOutlineGraphics.insert(pGraphic);
_connectOutline(pGraphic, pData);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 矩形边界:用户画完后创建数据并绑定
void nmPlotGraphicBinder::createOutlineForGraphic(nmObjRectOutline* pGraphic)
{
if (!pGraphic || !m_pDataMgr) return;
// 清理旧边界图元的绑定(数据中心同一时间只持有一个边界数据)
QList<nmObjBase*> oldGraphics = m_mapOutlineData.keys();
foreach (nmObjBase* pOld, oldGraphics) {
if (pOld != pGraphic) {
_disconnectOutline(pOld);
m_mapOutlineData.remove(pOld);
}
}
nmDataOutline* pData = m_pDataMgr->createOutline();
pData->setName(pGraphic->getName());
pData->setOutlinePoints(pGraphic->getAllValues());
pData->setFlowTypeList(pGraphic->m_vFlowTypeList);
pData->setOutlineType(NM_Data_Outline_Type::NM_Rect_Outline_Type);
pData->setPenWidth(pGraphic->getPen().widthF());
pData->setBackgrdColor(pGraphic->getBackgrdColor());
pData->setBackgrdAlpha(pGraphic->getBackgrdAlpha());
pData->setVisualPropsValid(true);
m_mapOutlineData[pGraphic] = pData;
m_setBoundOutlineGraphics.insert(pGraphic);
_connectOutline(pGraphic, pData);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 多边形边界:用户画完后创建数据并绑定
void nmPlotGraphicBinder::createOutlineForGraphic(nmObjPolygonOutline* pGraphic)
{
if (!pGraphic || !m_pDataMgr) return;
// 清理旧边界图元的绑定(数据中心同一时间只持有一个边界数据)
QList<nmObjBase*> oldGraphics = m_mapOutlineData.keys();
foreach (nmObjBase* pOld, oldGraphics) {
if (pOld != pGraphic) {
_disconnectOutline(pOld);
m_mapOutlineData.remove(pOld);
}
}
nmDataOutline* pData = m_pDataMgr->createOutline();
pData->setName(pGraphic->getName());
pData->setOutlinePoints(pGraphic->getAllValues());
pData->setFlowTypeList(pGraphic->m_vFlowTypeList);
pData->setOutlineType(NM_Data_Outline_Type::NM_Polygon_Outline_Type);
pData->setPenWidth(pGraphic->getPen().widthF());
pData->setBackgrdColor(pGraphic->getBackgrdColor());
pData->setBackgrdAlpha(pGraphic->getBackgrdAlpha());
pData->setVisualPropsValid(true);
m_mapOutlineData[pGraphic] = pData;
m_setBoundOutlineGraphics.insert(pGraphic);
_connectOutline(pGraphic, pData);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 从文件加载,绑定已有边界数据到已有图元
void nmPlotGraphicBinder::bindOutlineToGraphic(nmObjBase* pGraphic, nmDataOutline* pData)
{
if (!pGraphic || !pData) return;
m_mapOutlineData[pGraphic] = pData;
m_setBoundOutlineGraphics.insert(pGraphic);
_pushOutlineDataToGraphic(pGraphic, pData);
_connectOutline(pGraphic, pData);
}
// 删除边界图元前,断开绑定并从数据中心移除
void nmPlotGraphicBinder::removeOutlineBinding(nmObjBase* pGraphic)
{
if (!pGraphic) return;
_disconnectOutline(pGraphic);
m_mapOutlineData.remove(pGraphic);
if (m_pDataMgr) {
m_pDataMgr->removeOutlineData();
m_pDataMgr->notifyDataChanged();
}
}
// 查找边界图元对应的数据指针
nmDataOutline* nmPlotGraphicBinder::getOutlineDataFor(nmObjBase* pGraphic)
{
return m_mapOutlineData.value(pGraphic, nullptr);
}
// 名称同步setName 不发信号,由图元在 paintBack 中调用
void nmPlotGraphicBinder::syncOutlineName(nmObjBase* pGraphic)
{
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (pData && pData->getName() != pGraphic->getName()) {
pData->setName(pGraphic->getName());
}
}
// 视觉属性兜底同步paintBack 中调用,确保画笔宽度、填充色、透明度始终同步到数据中心
void nmPlotGraphicBinder::syncOutlineVisual(nmObjBase* pGraphic)
{
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (!pData) return;
// 画笔宽度
QPen pen = pGraphic->getPen();
double penWidth = pen.widthF();
if (pData->getPenWidth() != penWidth) {
pData->setPenWidth(penWidth);
}
// 填充背景色和透明度
QColor backgrdColor;
int backgrdAlpha = 0;
if (nmObjRectOutline* pRect = dynamic_cast<nmObjRectOutline*>(pGraphic)) {
backgrdColor = pRect->getBackgrdColor();
backgrdAlpha = pRect->getBackgrdAlpha();
} else if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
backgrdColor = pRound->getBackgrdColor();
backgrdAlpha = backgrdColor.alpha(); // 圆形透明度嵌入在 QColor 中
} else if (nmObjPolygonOutline* pPolygon = dynamic_cast<nmObjPolygonOutline*>(pGraphic)) {
backgrdColor = pPolygon->getBackgrdColor();
backgrdAlpha = pPolygon->getBackgrdAlpha();
}
if (pData->getBackgrdColor().rgb() != backgrdColor.rgb()) {
pData->setBackgrdColor(backgrdColor);
}
if (pData->getBackgrdAlpha() != backgrdAlpha) {
pData->setBackgrdAlpha(backgrdAlpha);
}
pData->setVisualPropsValid(true);
}
// 建立边界图元与数据的信号连接(三条信号)
void nmPlotGraphicBinder::_connectOutline(nmObjBase* pGraphic, nmDataOutline* pData)
{
QObject::connect(pGraphic, SIGNAL(sigOutlinePointsChanged()),
this, SLOT(onGraphicOutlinePointsChanged()));
QObject::connect(pGraphic, SIGNAL(sigOutlineFlowTypeChanged()),
this, SLOT(onGraphicOutlineFlowTypeChanged()));
QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicOutlineVisibleChanged(bool)));
m_setBoundOutlineGraphics.insert(pGraphic);
// 注入 Binder 指针到图元
if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
pRound->setGraphicBinder(this);
} else if (nmObjRectOutline* pRect = dynamic_cast<nmObjRectOutline*>(pGraphic)) {
pRect->setGraphicBinder(this);
} else if (nmObjPolygonOutline* pPolygon = dynamic_cast<nmObjPolygonOutline*>(pGraphic)) {
pPolygon->setGraphicBinder(this);
}
}
// 断开边界图元与本 Binder 的信号连接
void nmPlotGraphicBinder::_disconnectOutline(nmObjBase* pGraphic)
{
QObject::disconnect(pGraphic, SIGNAL(sigOutlinePointsChanged()),
this, SLOT(onGraphicOutlinePointsChanged()));
QObject::disconnect(pGraphic, SIGNAL(sigOutlineFlowTypeChanged()),
this, SLOT(onGraphicOutlineFlowTypeChanged()));
QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)),
this, SLOT(onGraphicOutlineVisibleChanged(bool)));
m_setBoundOutlineGraphics.remove(pGraphic);
}
// 从边界数据对象读取值,写入图元本地副本(加载时用)
void nmPlotGraphicBinder::_pushOutlineDataToGraphic(nmObjBase* pGraphic, nmDataOutline* pData)
{
pGraphic->blockSignals(true);
pGraphic->setName(pData->getName());
QVector<int> flowTypes = pData->getFlowTypeList();
bool bPushVisual = pData->hasVisualProps();
if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
pRound->m_vFlowTypeList = flowTypes;
if (bPushVisual) {
QPen pen = pRound->getPen();
pen.setWidthF(pData->getPenWidth());
pRound->setPen(pen);
QColor clr = pData->getBackgrdColor();
clr.setAlpha(pData->getBackgrdAlpha());
pRound->setBackgrdColor(clr);
}
} else if (nmObjRectOutline* pRect = dynamic_cast<nmObjRectOutline*>(pGraphic)) {
pRect->m_vFlowTypeList = flowTypes;
if (bPushVisual) {
QPen pen = pRect->getPen();
pen.setWidthF(pData->getPenWidth());
pRect->setPen(pen);
pRect->setBackgrdColor(pData->getBackgrdColor());
pRect->setBackgrdAlpha(pData->getBackgrdAlpha());
}
} else if (nmObjPolygonOutline* pPolygon = dynamic_cast<nmObjPolygonOutline*>(pGraphic)) {
pPolygon->m_vFlowTypeList = flowTypes;
if (bPushVisual) {
QPen pen = pPolygon->getPen();
pen.setWidthF(pData->getPenWidth());
pPolygon->setPen(pen);
pPolygon->setBackgrdColor(pData->getBackgrdColor());
pPolygon->setBackgrdAlpha(pData->getBackgrdAlpha());
}
}
pGraphic->blockSignals(false);
}
// ==================== 边界图元信号 → 数据同步 ====================
// 边界点坐标变更
void nmPlotGraphicBinder::onGraphicOutlinePointsChanged()
{
nmObjBase* pGraphic = qobject_cast<nmObjBase*>(sender());
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (!pData) return;
pData->setOutlinePoints(pGraphic->getAllValues());
// 圆形边界额外同步 radius 和 center
if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
QVector<QPointF> pts = pRound->getAllValues();
if (pts.count() >= 3) {
double radius = pts[2].y() - pts[0].y();
pData->setRadius(radius);
pData->setCenter(pts[0]);
}
}
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 边界流动类型变更
void nmPlotGraphicBinder::onGraphicOutlineFlowTypeChanged()
{
nmObjBase* pGraphic = qobject_cast<nmObjBase*>(sender());
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (!pData) return;
QVector<int> flowTypes;
if (nmObjRoundOutline* pRound = dynamic_cast<nmObjRoundOutline*>(pGraphic)) {
flowTypes = pRound->m_vFlowTypeList;
} else if (nmObjRectOutline* pRect = dynamic_cast<nmObjRectOutline*>(pGraphic)) {
flowTypes = pRect->m_vFlowTypeList;
} else if (nmObjPolygonOutline* pPolygon = dynamic_cast<nmObjPolygonOutline*>(pGraphic)) {
flowTypes = pPolygon->m_vFlowTypeList;
}
pData->setFlowTypeList(flowTypes);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 边界可见性变更
void nmPlotGraphicBinder::onGraphicOutlineVisibleChanged(bool bVisible)
{
nmObjBase* pGraphic = qobject_cast<nmObjBase*>(sender());
if (!pGraphic) return;
nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr);
if (!pData) return;
pData->setPlotVisible(bVisible);
if (m_pDataMgr) {
m_pDataMgr->notifyDataChanged();
}
}
// 用户画完测量线后:获取数据对象并建立绑定
void nmPlotGraphicBinder::createMeasureForGraphic(nmObjLineMeasure* pGraphic)
{
if (!pGraphic || !m_pDataMgr) {
return;
}
// 获取测量数据单例
nmDataMeasure* pData = m_pDataMgr->getMeasureData();
// 将图元坐标推入数据
QVector<QPointF> pts = pGraphic->getAllValues();
if (pts.count() >= 2) {
QPointF pStart = pts[0];
QPointF pEnd = pts[1];
double dLength = QLineF(pStart, pEnd).length();
if (pEnd != pStart) {
pData->setStartPoint(pStart);
pData->setEndPoint(pEnd);
} else {
pData->setCurrentPoint(pStart);
}
nmDataAttribute lenAttr = pData->getLength();
lenAttr.setValue(dLength);
pData->setLength(lenAttr);
}
// 建立映射
m_mapMeasureData[pGraphic] = pData;
pGraphic->setGraphicBinder(this);
m_pDataMgr->notifyDataChanged();
}
// 删除测量线图元:移除映射(不删除数据对象,由 DataManager 管理)
void nmPlotGraphicBinder::removeMeasureBinding(nmObjLineMeasure* pGraphic)
{
if (!pGraphic) {
return;
}
m_mapMeasureData.remove(pGraphic);
}
// 坐标同步:从数据对象读取起点终点,写回图元(拟合功能修改数据后由 paintBack 调用)
void nmPlotGraphicBinder::syncMeasurePoints(nmObjLineMeasure* pGraphic)
{
if (!pGraphic || !m_pDataMgr) return;
nmDataMeasure* pData = m_mapMeasureData.value(pGraphic, nullptr);
if (!pData) return;
QPointF startPt = pData->getStartPoint();
QPointF endPt = pData->getEndPoint();
// 仅在坐标确实变化时才更新,避免每次绘制都无谓写入
QVector<QPointF> currentPts = pGraphic->getAllValues();
if (currentPts.count() >= 2 &&
currentPts[0] == startPt && currentPts[1] == endPt) {
return;
}
pGraphic->blockSignals(true);
QVector<QPointF> pts;
pts << startPt << endPt;
pGraphic->setAllValues(pts);
pGraphic->blockSignals(false);
}