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

452 lines
11 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 "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<QVariant> 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<QPointF> 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<QPointF> 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<ZxPlot*>(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<QPointF> pts = obj->getAllPos();
if(_isSame("nObjRegion", obj->getTagName())) {
// 获取区域的多边形点
QPolygonF regionPolygon(pts);
nmObjRegion* region = static_cast<nmObjRegion*>(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<nmObjRegionMark*>(this));
}
return nullptr;
}