自定义标绘之五 - 鼠标操作

137 篇文章 44 订阅

当用户选中了需要绘制的要素时,需要通过鼠标的操作把要素绘制出来,而且同时要保证之前已经绘制完成的不在受到任何的干扰。所以在显示层面就分为两层:最下面的一层就是已经绘制好的图形数据,上面一层则是当前正在绘制的图形。

这两层的管理通过一个类来管理:

//用户自定义图形的绘制
/*
这个用来显示用户自定义绘制的图形,分为两部分
1.用户当前正在绘制的图形
2.已经绘制完成图形
*/

#define DrawGeoMapInst() (GeoDrawMap::getInstance())

class CurrentGeoDraw;

class USERDEFINEDRAW_EXPORT GeoDrawMap
	:public IDisplay
	, public IMouseEvent {
private:
	GeoDrawMap();
	static GeoDrawMap* _instance;
public:
	~GeoDrawMap();
	static GeoDrawMap* getInstance();

	//用户当前绘制类型
	void setCurrentUserDrawType(USER_DRAW_TYPE currentDrawType);
	USER_DRAW_TYPE getCurrentUserDrawType() {
		return _currentDrawType;
	}

	virtual void draw(QPainter* p)override;

	virtual void mousePress(QMouseEvent * event)override;
	virtual void mouseRelease(QMouseEvent *event)override;
	virtual void mouseMove(QMouseEvent * event)override;

private:
	CurrentGeoDraw* _currentGeoDraw = nullptr;//控制当前绘制的内容
	USER_DRAW_TYPE _currentDrawType = USER_DRAW_NULL;//当前绘制用户类型
};

GeoDrawMap* GeoDrawMap::_instance = nullptr;

GeoDrawMap::GeoDrawMap() {
	MouseMgr()->addMouseEvent(this);
	DisplayMgr()->addRender(this);
	MutualMouse()->addMutualMouseEvent(this);//鼠标操作互斥

	//保存当前绘制
	_currentGeoDraw = new CurrentGeoDraw;
	ResumeDrawMgr()->saveCurrnenGeoDraw(_currentGeoDraw);
}

GeoDrawMap::~GeoDrawMap() {
	DisplayMgr()->removeRender(this);
	MutualMouse()->removeMutualMouseEvent(this);
	MouseMgr()->removeMouseEvent(this);
}

GeoDrawMap* GeoDrawMap::getInstance() {
	if (_instance == nullptr){
		_instance = new GeoDrawMap;
	}
	return _instance;
}

void GeoDrawMap::setCurrentUserDrawType(USER_DRAW_TYPE currentDrawType) {
	_currentDrawType = currentDrawType;
	_currentGeoDraw->setDrawGeoType(_currentDrawType);
}

void GeoDrawMap::draw(QPainter* p) {
	//已经保存的绘制内容
	QVector<BaseGeo*>&geoList = UserDefineDataMgr()->getUseGeoList();
	int num = geoList.size();
	for (int i = 0; i < num;i++) {
		geoList.at(i)->draw(p);
		geoList.at(i)->drawNameText(p);
	}
	//当前绘制的内容
	_currentGeoDraw->draw(p);
}

void GeoDrawMap::mousePress(QMouseEvent * event) {
	_currentGeoDraw->mousePress(event);
}

void GeoDrawMap::mouseRelease(QMouseEvent *event) {
	_currentGeoDraw->mouseRelease(event);
}

void GeoDrawMap::mouseMove(QMouseEvent * event) {
	_currentGeoDraw->mouseMove(event);
}

当前绘制的基类:

//当前正在绘制的几何图形的基类

class DrawGeoBase :public IDisplay
	, public IMouseEvent {
public:
	DrawGeoBase();
	~DrawGeoBase();

	virtual void draw(QPainter* p)override;

	virtual void mousePress(QMouseEvent * event)override;
	virtual void mouseRelease(QMouseEvent *event)override;
	virtual void mouseMove(QMouseEvent * event)override;
};

DrawGeoBase::DrawGeoBase() {
}

DrawGeoBase::~DrawGeoBase() {
}

void DrawGeoBase::draw(QPainter* p) {

}

void DrawGeoBase::mousePress(QMouseEvent * event) {

}

void DrawGeoBase::mouseRelease(QMouseEvent *event) {

}

点绘制:

//当前正在绘制的点
class DrawGeoPoint :public DrawGeoBase {
public:
	DrawGeoPoint();
	~DrawGeoPoint();

	virtual void draw(QPainter* p)override;

	virtual void mousePress(QMouseEvent * event)override;
	virtual void mouseRelease(QMouseEvent *event)override;
	virtual void mouseMove(QMouseEvent * event)override;

private:
	bool _leftDown = false;//鼠标左键按下
	QPoint _pt;
	QPoint _mousePressPt;
};

DrawGeoPoint::DrawGeoPoint() {
}

DrawGeoPoint::~DrawGeoPoint() {
}

void DrawGeoPoint::draw(QPainter* p) {
	GeoPointProp*pointProp = dynamic_cast<GeoPointProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_POINT));
	if (pointProp != nullptr&&_pt.x() != -999 && _pt.y() != -999) {
		p->setPen(QPen(pointProp->getOuterColor(), pointProp->getOuterWidth(), Qt::SolidLine));
		p->setBrush(pointProp->getFillColor());

		p->drawEllipse(_pt.x() - pointProp->getRadius()
			, _pt.y() - pointProp->getRadius()
			, pointProp->getRadius() * 2
			, pointProp->getRadius() * 2);
	}
}

void DrawGeoPoint::mousePress(QMouseEvent * event) {
	if (event->button() == Qt::LeftButton){
		_leftDown = true;
		_pt = event->pos();
		_mousePressPt = _pt;
	}
}

void DrawGeoPoint::mouseRelease(QMouseEvent *event) {
	if (event->button() == Qt::LeftButton) {

		GeoPointProp*pointProp = dynamic_cast<GeoPointProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_POINT));
		PointGeo* point = new StoragePointGeo;
		point->setGeoID(QDateTime::currentMSecsSinceEpoch());//设置ID
		point->setGeoName(QStringLiteral("点"));//设置名称
		point->setPointProp(pointProp);//保存点属性
		double lon = 0.0, lat = 0.0;
		CoordInst()->screen2LonLat(_pt, lon, lat);
		point->setLon(lon);
		point->setLat(lat);
		point->setAlt(0.0);

		UserDefineDataMgr()->addUseGeo(point);
		_leftDown = false;
		_pt = QPoint(-999, -999);
	} else if (event->button() == Qt::RightButton) {
		CurrentDrawFinishMgr()->currentFinish(USER_DRAW_POINT);
	} else if (event->button() == Qt::MidButton) {//删除点
		QVector<BaseGeo*>&geoList = UserDefineDataMgr()->getUseGeoList();
		int num = geoList.size();
		for (int i = num - 1; i >= 0;i--) {
			BaseGeo* geo = geoList.at(i);
			if (geo->getUserDrawDataType() == USER_DRAW_POINT){
				UserDefineDataMgr()->removeUseGeo(geo);
				break;
			} else {
				break;
			}
		}
	}
}

void DrawGeoPoint::mouseMove(QMouseEvent * event) {
	GlobalUseInst()->load2DMapUpdate()->setCursor(Qt::CrossCursor);
	if (_leftDown){
		_pt -= (_mousePressPt - event->pos());
		_mousePressPt = event->pos();
	}
}

线绘制:

DrawGeoPoint::DrawGeoPoint() {
}

DrawGeoPoint::~DrawGeoPoint() {
}

void DrawGeoPoint::draw(QPainter* p) {
	GeoPointProp*pointProp = dynamic_cast<GeoPointProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_POINT));
	if (pointProp != nullptr&&_pt.x() != -999 && _pt.y() != -999) {
		p->setPen(QPen(pointProp->getOuterColor(), pointProp->getOuterWidth(), Qt::SolidLine));
		p->setBrush(pointProp->getFillColor());

		p->drawEllipse(_pt.x() - pointProp->getRadius()
			, _pt.y() - pointProp->getRadius()
			, pointProp->getRadius() * 2
			, pointProp->getRadius() * 2);
	}
}

void DrawGeoPoint::mousePress(QMouseEvent * event) {
	if (event->button() == Qt::LeftButton){
		_leftDown = true;
		_pt = event->pos();
		_mousePressPt = _pt;
	}
}

void DrawGeoPoint::mouseRelease(QMouseEvent *event) {
	if (event->button() == Qt::LeftButton) {

		GeoPointProp*pointProp = dynamic_cast<GeoPointProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_POINT));
		PointGeo* point = new StoragePointGeo;
		point->setGeoID(QDateTime::currentMSecsSinceEpoch());//设置ID
		point->setGeoName(QStringLiteral("点"));//设置名称
		point->setPointProp(pointProp);//保存点属性
		double lon = 0.0, lat = 0.0;
		CoordInst()->screen2LonLat(_pt, lon, lat);
		point->setLon(lon);
		point->setLat(lat);
		point->setAlt(0.0);

		UserDefineDataMgr()->addUseGeo(point);
		_leftDown = false;
		_pt = QPoint(-999, -999);
	} else if (event->button() == Qt::RightButton) {
		CurrentDrawFinishMgr()->currentFinish(USER_DRAW_POINT);
	} else if (event->button() == Qt::MidButton) {//删除点
		QVector<BaseGeo*>&geoList = UserDefineDataMgr()->getUseGeoList();
		int num = geoList.size();
		for (int i = num - 1; i >= 0;i--) {
			BaseGeo* geo = geoList.at(i);
			if (geo->getUserDrawDataType() == USER_DRAW_POINT){
				UserDefineDataMgr()->removeUseGeo(geo);
				break;
			} else {
				break;
			}
		}
	}
}

void DrawGeoPoint::mouseMove(QMouseEvent * event) {
	GlobalUseInst()->load2DMapUpdate()->setCursor(Qt::CrossCursor);
	if (_leftDown){
		_pt -= (_mousePressPt - event->pos());
		_mousePressPt = event->pos();
	}
}

DrawGeoLine::DrawGeoLine() {
}

DrawGeoLine::~DrawGeoLine() {
}

void DrawGeoLine::draw(QPainter* p) {
	p->setRenderHint(QPainter::Antialiasing, true);
	GeoLineProp*lineProp = dynamic_cast<GeoLineProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_LINE));
	if (lineProp != nullptr) {
		QPen pen;
		pen.setColor(lineProp->getLineColor());
		pen.setWidth(lineProp->getLineWidth());
		pen.setStyle((Qt::PenStyle)lineProp->getLineType());
		p->setPen(pen);
	}
	if (_useElastic) {
		p->drawLine(_elasticStart, _elasticEnd);
	}
	QPointF ptSrc;
	QPoint ptDes;
	QVector<QPoint> ptList;
	int num = _ptList.size();
	for (int i = 0; i < num; i++) {
		ptSrc = _ptList.at(i);
		CoordInst()->lonlat2Screen(ptSrc.x(), ptSrc.y(), ptDes);
		ptList.push_back(ptDes);
	}

	p->drawPolyline(ptList);
}

void DrawGeoLine::mousePress(QMouseEvent * event) {
	if (event->button() == Qt::LeftButton) {
		_leftDown = true;
		_useElastic = true;

		_elasticStart = event->pos();
		_elasticEnd = event->pos();

		double lon = 0.0, lat = 0.0;
		CoordInst()->screen2LonLat(_elasticStart.x(), _elasticStart.y(), lon, lat);
		_ptList.push_back(QPointF(lon, lat));
	}
}

void DrawGeoLine::mouseRelease(QMouseEvent *event) {
	if (event->button() == Qt::LeftButton) {
		_leftDown = false;
	} else if (event->button() == Qt::RightButton) {
		if (_useElastic) {
#if 0
			//当前移动的点不绘制
			double lon = 0.0, lat = 0.0;
			CoordInst()->screen2LonLat(event->pos().x(), event->pos().y(), lon, lat);
			_ptList.push_back(QPointF(lon, lat));
#endif
			_useElastic = false;

			GeoLineProp*lineProp = dynamic_cast<GeoLineProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_LINE));
			LineGeo* line = new StorageLineGeo;
			line->setGeoID(QDateTime::currentMSecsSinceEpoch());//设置ID
			line->setGeoName(QStringLiteral("线"));//设置名称
			line->setLineProp(lineProp);//保存线属性

			int num = _ptList.size();
			for (int i = 0; i < num; i++) {
				QPointF pt = _ptList.at(i);
				line->addLinePoint(UserGeoPoint(pt.x(), pt.y(), 0.0));
			}

			UserDefineDataMgr()->addUseGeo(line);

			_ptList.clear();
			GlobalUseInst()->load2DMapUpdate()->update2DMap();
		} else {
			CurrentDrawFinishMgr()->currentFinish(USER_DRAW_LINE);
		}
	} else if (event->button() == Qt::MidButton) {//删除
		if (_ptList.size() == 0){
			_elasticStart = QPointF(-100.0, -100.0);
			_elasticEnd = QPointF(-100.0, -100.0);
			return;
		}
		_ptList.pop_back();
		if (_ptList.size() == 0){
			_useElastic = false;
		}
		QPointF ptLast = _ptList.at(_ptList.size() - 1);
		CoordInst()->lonlat2Screen(ptLast.x(), ptLast.y(), _elasticStart);
	}
}

void DrawGeoLine::mouseMove(QMouseEvent * event) {
	GlobalUseInst()->load2DMapUpdate()->setCursor(Qt::CrossCursor);
	_elasticEnd = event->pos();
}

当前正在绘制的内容:

DrawGeoLine::DrawGeoLine() {
}

DrawGeoLine::~DrawGeoLine() {
}

void DrawGeoLine::draw(QPainter* p) {
	p->setRenderHint(QPainter::Antialiasing, true);
	GeoLineProp*lineProp = dynamic_cast<GeoLineProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_LINE));
	if (lineProp != nullptr) {
		QPen pen;
		pen.setColor(lineProp->getLineColor());
		pen.setWidth(lineProp->getLineWidth());
		pen.setStyle((Qt::PenStyle)lineProp->getLineType());
		p->setPen(pen);
	}
	if (_useElastic) {
		p->drawLine(_elasticStart, _elasticEnd);
	}
	QPointF ptSrc;
	QPoint ptDes;
	QVector<QPoint> ptList;
	int num = _ptList.size();
	for (int i = 0; i < num; i++) {
		ptSrc = _ptList.at(i);
		CoordInst()->lonlat2Screen(ptSrc.x(), ptSrc.y(), ptDes);
		ptList.push_back(ptDes);
	}

	p->drawPolyline(ptList);
}

void DrawGeoLine::mousePress(QMouseEvent * event) {
	if (event->button() == Qt::LeftButton) {
		_leftDown = true;
		_useElastic = true;

		_elasticStart = event->pos();
		_elasticEnd = event->pos();

		double lon = 0.0, lat = 0.0;
		CoordInst()->screen2LonLat(_elasticStart.x(), _elasticStart.y(), lon, lat);
		_ptList.push_back(QPointF(lon, lat));
	}
}

void DrawGeoLine::mouseRelease(QMouseEvent *event) {
	if (event->button() == Qt::LeftButton) {
		_leftDown = false;
	} else if (event->button() == Qt::RightButton) {
		if (_useElastic) {
#if 0
			//当前移动的点不绘制
			double lon = 0.0, lat = 0.0;
			CoordInst()->screen2LonLat(event->pos().x(), event->pos().y(), lon, lat);
			_ptList.push_back(QPointF(lon, lat));
#endif
			_useElastic = false;

			GeoLineProp*lineProp = dynamic_cast<GeoLineProp*>(UserGeoCfgMgr()->getGeoProp(USER_DRAW_LINE));
			LineGeo* line = new StorageLineGeo;
			line->setGeoID(QDateTime::currentMSecsSinceEpoch());//设置ID
			line->setGeoName(QStringLiteral("线"));//设置名称
			line->setLineProp(lineProp);//保存线属性

			int num = _ptList.size();
			for (int i = 0; i < num; i++) {
				QPointF pt = _ptList.at(i);
				line->addLinePoint(UserGeoPoint(pt.x(), pt.y(), 0.0));
			}

			UserDefineDataMgr()->addUseGeo(line);

			_ptList.clear();
			GlobalUseInst()->load2DMapUpdate()->update2DMap();
		} else {
			CurrentDrawFinishMgr()->currentFinish(USER_DRAW_LINE);
		}
	} else if (event->button() == Qt::MidButton) {//删除
		if (_ptList.size() == 0){
			_elasticStart = QPointF(-100.0, -100.0);
			_elasticEnd = QPointF(-100.0, -100.0);
			return;
		}
		_ptList.pop_back();
		if (_ptList.size() == 0){
			_useElastic = false;
		}
		QPointF ptLast = _ptList.at(_ptList.size() - 1);
		CoordInst()->lonlat2Screen(ptLast.x(), ptLast.y(), _elasticStart);
	}
}

void DrawGeoLine::mouseMove(QMouseEvent * event) {
	GlobalUseInst()->load2DMapUpdate()->setCursor(Qt::CrossCursor);
	_elasticEnd = event->pos();
}

CurrentGeoDraw::CurrentGeoDraw() {
	_currentGeoDrawFactory = new CurrentGeoDrawFactory;
}

CurrentGeoDraw::~CurrentGeoDraw() {
}

void CurrentGeoDraw::setDrawGeoType(USER_DRAW_TYPE drawType) {
	_drawType = drawType;
	_currentDraw = _currentGeoDrawFactory->getCurrentDraw(_drawType);
}

void CurrentGeoDraw::draw(QPainter* p) {
	if (_currentDraw!=nullptr) {
		_currentDraw->draw(p);
	}
}

void CurrentGeoDraw::mousePress(QMouseEvent * event) {
	if (_currentDraw != nullptr) {
		_currentDraw->mousePress(event);
	}
}

void CurrentGeoDraw::mouseRelease(QMouseEvent *event) {
	if (_currentDraw != nullptr) {
		_currentDraw->mouseRelease(event);
	}
}

void CurrentGeoDraw::mouseMove(QMouseEvent * event) {
	if (_currentDraw != nullptr) {
		_currentDraw->mouseMove(event);
	}
}

绘制工厂,通过工厂选择不同的绘制类型:

//当前绘制的创建工厂

class CurrentGeoDrawFactory {
public:
	CurrentGeoDrawFactory();
	~CurrentGeoDrawFactory();

	DrawGeoBase* getCurrentDraw(USER_DRAW_TYPE drawType);

private:
	DrawGeoBase* _drawGeo = nullptr;

	DrawGeoPoint* _drawGeoPoint = nullptr;
	ResumeDrawLine* _drawGeoLine = nullptr;
	ResumeDrawPath* _drawGeoPath = nullptr;
	DrawGeoRect* _drawGeoRect = nullptr;
	ResumeDrawPolygon* _drawGeoPolygon = nullptr;
	DrawGeoCircle* _drawGeoCircle = nullptr;
	DrawGeoPie* _drawGeoPie = nullptr;
	DrawGeoCircleArc* _drawGeoCircleArc = nullptr;
	DrawGeoText* _drawGeoText = nullptr;
};

CurrentGeoDrawFactory::CurrentGeoDrawFactory() {
}

CurrentGeoDrawFactory::~CurrentGeoDrawFactory() {
}

DrawGeoBase* CurrentGeoDrawFactory::getCurrentDraw(USER_DRAW_TYPE drawType) {
	switch (drawType) {
		case USER_DRAW_NULL:
		_drawGeo = nullptr;
		break;
		case USER_DRAW_POINT:
		if (_drawGeoPoint == nullptr) {
			_drawGeoPoint = new DrawGeoPoint;
		}
		_drawGeo = _drawGeoPoint;
		break;
		case USER_DRAW_LINE:
		if (_drawGeoLine == nullptr) {
			_drawGeoLine = new ResumeDrawLine;
			ResumeDrawMgr()->addResumeDraw(_drawGeoLine);
		}
		_drawGeo = _drawGeoLine;
		break;
		case USER_DRAW_PATH:
		if (_drawGeoPath == nullptr){
			_drawGeoPath = new ResumeDrawPath;
			ResumeDrawMgr()->addResumeDraw(_drawGeoPath);
		}
		_drawGeo = _drawGeoPath;
		break;
		case USER_DRAW_RECT:
		if (_drawGeoRect == nullptr) {
			_drawGeoRect = new DrawGeoRect;
		}
		_drawGeo = _drawGeoRect;
		break;
		case USER_DRAW_POLYGON:
		if (_drawGeoPolygon == nullptr) {
			_drawGeoPolygon = new ResumeDrawPolygon;
			ResumeDrawMgr()->addResumeDraw(_drawGeoPolygon);
		}
		_drawGeo = _drawGeoPolygon;
		break;
		case USER_DRAW_CIRCLE:
		if (_drawGeoCircle == nullptr) {
			_drawGeoCircle = new DrawGeoCircle;
		}
		_drawGeo = _drawGeoCircle;
		break;
		case USER_DRAW_PIE:
		if (_drawGeoPie == nullptr) {
			_drawGeoPie = new DrawGeoPie;
		}
		_drawGeo = _drawGeoPie;
		break;
		case USER_DRAW_CIRCLE_ARC:
		if (_drawGeoCircleArc == nullptr) {
			_drawGeoCircleArc = new DrawGeoCircleArc;
		}
		_drawGeo = _drawGeoCircleArc;

		break;
		case USER_DRAW_TEXT:
		if (_drawGeoText == nullptr) {
			_drawGeoText = new QtDrawTextCursor(nullptr);
		}
		_drawGeo = _drawGeoText;

		break;
		default:
		_drawGeo = nullptr;
		break;
	}
	return _drawGeo;
} 

aaa

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wb175208

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值