#include #include "nmObjRegionMark.h" #include "nmObjRegionMarkTool.h" #include "nmObjRegion.h" #include "ZxSerializer.h" #include "IxPtyPano.h" #include "ZxSubAxisX.h" #include "ZxSubAxisY.h" #include "nmObjRegion.h" #include "nmObjRegionTool.h" #include "ZxBaseUtil.h" #include "ZxPlot.h" #include "nmPlotGraphicBinder.h" #include "nmDataRegionMark.h" ZX_DEFINE_DYNAMIC(nObjRegionMark, nmObjRegionMark) nmObjRegionMark::nmObjRegionMark() : m_bSelectRegion(false) , m_iColorIndex(0) , m_reservoirType(0) , m_comKr(1.0) , m_comW(1.0) , m_netToGross(1.0) , m_pGraphicBinder(nullptr) { m_sObjTag = "nObjRegionMark"; nmObjRegionMark::init("", NULL, NULL); } nmObjRegionMark::nmObjRegionMark(const QString& sName, \ ZxSubAxisX* pAxisX, \ ZxSubAxisY* pAxisY, \ int RegionMarkCount) : m_bSelectRegion(false) , m_iColorIndex(RegionMarkCount) , m_reservoirType(0) , m_comKr(1.0) , m_comW(1.0) , m_netToGross(1.0) , m_pGraphicBinder(nullptr) { m_sObjTag = "nObjRegionMark"; nmObjRegionMark::init(sName, pAxisX, pAxisY); this->m_iColorIndex = RegionMarkCount; m_clrBackgrd = generateColor(m_iColorIndex); } nmObjRegionMark::~nmObjRegionMark() { } QColor nmObjRegionMark::generateColor(int index) { int hue = (index % 6) * 60; // 色相,每6个标记循环一次,每次加60度 int saturation = 255; // 饱和度,最大值 int value = 255; // 亮度,最大值 int alpha = 128; // 透明度,半透明,可根据需要调整 return QColor::fromHsv(hue, saturation, value, alpha); // 返回带透明度的颜色 } void nmObjRegionMark::init(const QString& sName, \ ZxSubAxisX* pAxisX, \ ZxSubAxisY* pAxisY) { nmObjBase::init(sName, pAxisX, pAxisY); nmObjRegionMark::initFlags(); m_bSelectRegion = false; m_pGraphicBinder = nullptr; m_icon = QPixmap(ZxBaseUtil::getDirOf(s_Dir_Res, "Icon") + "Anchor.png"); loadTempl(); // 连接图元可见性信号和槽 connect(this, SIGNAL(sigObjVisibleChanged(bool)), this, SLOT(onObjVisibleChanged(bool))); } void nmObjRegionMark::initTools() { m_pTool = new nmObjRegionMarkTool(); nmObjBase::initTools(); } void nmObjRegionMark::setResevoirType(int newResevoirType) { if (m_reservoirType != newResevoirType) { m_reservoirType = newResevoirType; emit sigResevoirTypeChanged(newResevoirType); } } int nmObjRegionMark::getResevoirType() { return m_reservoirType; } void nmObjRegionMark::setComKr(double newComkr) { if (m_comKr != newComkr) { m_comKr = newComkr; emit sigComKrChanged(newComkr); } } double nmObjRegionMark::getComKr() { return m_comKr; } void nmObjRegionMark::setComW(double newComW) { if (m_comW != newComW) { m_comW = newComW; emit sigComWChanged(newComW); } } double nmObjRegionMark::getComW() { return m_comW; } void nmObjRegionMark::setNetToGross(double newNetToGross) { if (m_netToGross != newNetToGross) { m_netToGross = newNetToGross; emit sigNetToGrossChanged(newNetToGross); } } double nmObjRegionMark::getNetToGross() { return m_netToGross; } void nmObjRegionMark::onSerialize(ZxSerializer* ser) { nmObjBase::onSerialize(ser); ser->write("ResevoirType", m_reservoirType); ser->write("dComKr", m_comKr); ser->write("dComW", m_comW); ser->write("NetToGross", m_netToGross); } void nmObjRegionMark::onDeserialize(ZxSerializer* ser) { nmObjBase::onDeserialize(ser); int resevoirType; double comKr; double comW; double netToGross; ser->read("ResevoirType", resevoirType); ser->read("dComKr", comKr); ser->read("dComW", comW); ser->read("NetToGross", netToGross); m_reservoirType = resevoirType; m_comKr = comKr; m_comW = comW; m_netToGross = netToGross; } void nmObjRegionMark::onSaveTempl(ZxSerializer* ser) { nmObjBase::onSaveTempl(ser); ser->write("ResevoirType", m_reservoirType); ser->write("dComKr", m_comKr); ser->write("dComW", m_comW); ser->write("NetToGross", m_netToGross); } void nmObjRegionMark::onLoadTempl(ZxSerializer* ser) { nmObjBase::onLoadTempl(ser); int resevoirType; double comKr; double comW; double netToGross; ser->read("ResevoirType", resevoirType); ser->read("dComKr", comKr); ser->read("dComW", comW); ser->read("NetToGross", netToGross); m_reservoirType = resevoirType; m_comKr = comKr; m_comW = comW; m_netToGross = netToGross; } void nmObjRegionMark::fillPtyPano(IxPtyPano* sheet) { nmObjBase::fillPtyPano(sheet); IxPtyItem* pProp = ZX_PROP("ObjRegionMark.ResevoirType", getResevoirType, setResevoirType); if(NULL != pProp) { QStringList listTags; listTags << tr("Homogeneous") << tr("Dual porosity pseudo steady state"); QList listIndexes; listIndexes << 0 << 1; pProp->getPtyPano(); pProp->setOptions(listTags, listIndexes); } ZX_PROP("ObjRegionMark.dComKr", getComKr, setComKr); ZX_PROP("ObjRegionMark.dComW", getComW, setComW); ZX_PROP("ObjRegionMark.NetToGross", getNetToGross, setNetToGross); } void nmObjRegionMark::initFlags() { setLockPos(false); setLockSize(false); setReadOnly(false); } bool nmObjRegionMark::hitTest(const QPointF& pt) { return nmObjBase::hitTest(pt); } bool nmObjRegionMark::_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 pts = getPosOf(m_vecPoints); // 点 double r = 3.f; for(int i = 0; i < pts.count(); i++) { 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) { nOption = (int)OHO_Point; nSubIndex = i; return true; } } nOption = (int)OHO_None; nSubIndex = -1; return false; } bool nmObjRegionMark::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 vecPts = getPosOf(m_vecPoints); if(m_oHitOption == OHO_Point && m_nHitIndex >= 0) { // 如果是点,不用计算偏移量,直接将该点移动到鼠标抬起的位置即可 vecPts[m_nHitIndex] = pt2; return moveToPos(vecPts); } else { return false; } return true; } void nmObjRegionMark::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; } QPointF ptPos = getPosOf(m_vecPoints[0]); painter->save(); ZxPlot* m_pCurPlot = dynamic_cast(this->getParent()); if (m_pCurPlot == nullptr) { painter->restore(); return; } // 获取当前图表的对象数 int objCount = m_pCurPlot->getObjCount(); for(int i = 0; i < objCount; i++) { ZxObjBase* obj = m_pCurPlot->getObjByIndex(i); if (obj == nullptr) { continue; } QVector pts = obj->getAllPos(); if(_isSame("nObjRegion", obj->getTagName())) { // 获取区域的多边形点 QPolygonF regionPolygon(pts); nmObjRegion* region = static_cast(obj); // 判断 RegionMark 是否在该区域内 if(regionPolygon.containsPoint(ptPos, Qt::OddEvenFill)) { // 判断该区域是否已经被标记 if(region->getRegionMark() == nullptr) { // 仅在 Binder 已绑定时才关联(避免加载数据前 paintBack 误设) if (m_pGraphicBinder) { region->setRegionMark(this); region->setBackgrdColor(this->m_clrBackgrd); this->setSelectRegion(true); } } else { // 如果区域已被标记 int index = region->getRegionMark()->getColorIndex(); // 判断大小 if(this->m_iColorIndex < index) { region->setRegionMark(this); region->setBackgrdColor(this->m_clrBackgrd); this->setSelectRegion(true); } } } } } // 通过 Binder 同步名称、位置、颜色、选中状态到数据(paintBack 兜底同步) if (m_pGraphicBinder) { m_pGraphicBinder->syncRegionMarkData(this); } // 设置字体 QFont ft = qApp->font(); ft.setPointSize(8); painter->setFont(ft); painter->setPen(Qt::black); // 定义图标和文本的绘制参数 int iconSize = 6; // 图标大小 int spacing = 0; // 图标和文本之间的间距 int textWidth = 100; // 文本区域的固定宽度 // 计算图标的矩形区域,居中于ptPos QRectF iconRect(ptPos.x() - iconSize / 2, ptPos.y() - iconSize / 2, iconSize, iconSize); painter->drawPixmap(iconRect, m_icon, m_icon.rect()); // 计算文本的矩形区域,位于图标上方 QRectF textRect( ptPos.x() - textWidth / 2, // 文本水平居中于图标 ptPos.y() - iconSize / 2 - spacing - iconSize, // 在图标上方 textWidth, iconSize // 使用与图标相同的高度 ); ZxDrawHelper::drawText(painter, textRect, Qt::AlignCenter, m_sName); // 使用居中对齐 painter->restore(); } void nmObjRegionMark::setColorIndex(int newIndex) { m_iColorIndex = newIndex; } int nmObjRegionMark::getColorIndex() const { return m_iColorIndex; } void nmObjRegionMark::setSelectRegion(bool select) { m_bSelectRegion = select; } bool nmObjRegionMark::getSelectRegion() const { return m_bSelectRegion; } QColor nmObjRegionMark::getBackgrdColor() const { return m_clrBackgrd; } void nmObjRegionMark::setBackgrdColor(QColor color) { if(m_clrBackgrd != color) { m_clrBackgrd = color; update(); } } void nmObjRegionMark::afterCreated() { if (m_pGraphicBinder) { m_pGraphicBinder->createRegionMarkForGraphic(this); } } void nmObjRegionMark::removeData() { if (m_pGraphicBinder) { m_pGraphicBinder->removeRegionMarkBinding(this); } } void nmObjRegionMark::onObjVisibleChanged(bool bIsVisible) { emit sigRegionMarkVisibleChanged(bIsVisible); } // 通过 Binder 查询关联的数据对象(供 nmObjRegion 使用) nmDataRegionMark* nmObjRegionMark::getRegionMarkData() const { if (m_pGraphicBinder) { return m_pGraphicBinder->getRegionMarkDataFor(const_cast(this)); } return nullptr; }