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

436 lines
11 KiB
C++

#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"
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();
}
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);
}
}
// 通过 Binder 查询关联的数据对象(供 nmObjRegion 使用)