#include "stdafx.h" #include #include #include #include #include "ImageViewer.h" #include "RasterLayer.h" #include "MapTool.h" #define VIEW_CENTER viewport()->rect().center() #define VIEW_WIDTH viewport()->rect().width() #define VIEW_HEIGHT viewport()->rect().height() Mapcavas::Mapcavas(QWidget* pParent) :QGraphicsView(pParent) { setRenderHint(QPainter::Antialiasing); setRenderHint(QPainter::SmoothPixmapTransform); setDragMode(QGraphicsView::ScrollHandDrag); // 使用 Qt 默认 anchor 行为以外的配置 setTransformationAnchor(QGraphicsView::NoAnchor); setResizeAnchor(QGraphicsView::NoAnchor); m_qtGraphicsScene = new QGraphicsScene(this); this->setScene(m_qtGraphicsScene); m_qtGraphicsScene->setSceneRect(-1e6, -1e6, 2e6, 2e6); m_framNumberLabel = new QLabel(this); m_framNumberLabel->setAlignment(Qt::AlignHCenter); m_framNumberLabel->setAlignment(Qt::AlignVCenter); QFont ft; ft.setPointSize(14); m_framNumberLabel->setFont(ft); m_framNumberLabel->setText("0"); m_GraphicsPixmapItemHandle = nullptr; m_scale = 1.0; m_zoomDelta = 0.1; m_translateSpeed = 1.0; m_bMouseTranslate = false; setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); setFrameShape(QFrame::NoFrame); } Mapcavas::~Mapcavas() { } void Mapcavas::DisplayFrameNumber(int frameNumber) { m_framNumberLabel->setText(QString::number(frameNumber)); m_framNumberLabel->adjustSize(); } void Mapcavas::SetImage(QPixmap *image) { if (!HasImage()) { m_GraphicsPixmapItemHandle = m_qtGraphicsScene->addPixmap(*image); } else { m_GraphicsPixmapItemHandle->setPixmap(*image); } ensureSceneVisible(); } void Mapcavas::ensureSceneVisible() { resetTransform(); auto view_rect = viewport()->rect(); auto scene_rect = this->scene()->itemsBoundingRect(); double x_ratio = view_rect.width() / scene_rect.width(); double y_ratio = view_rect.height() / scene_rect.height(); double scale_factor = std::min(x_ratio, y_ratio) * 0.9; scale(scale_factor, scale_factor); m_scale *= scale_factor; centerOn(scene_rect.center()); } bool Mapcavas::HasImage() { if (m_GraphicsPixmapItemHandle == nullptr) { return false; } else { return true; } } void Mapcavas::updateCrosshair(double sceneX, double sceneY) { QPen pen(Qt::red, 2.0); pen.setCosmetic(true); // constant screen-width regardless of zoom if (!m_hLine) { m_hLine = m_qtGraphicsScene->addLine(0, 0, 0, 0, pen); m_hLine->setZValue(1e9); } if (!m_vLine) { m_vLine = m_qtGraphicsScene->addLine(0, 0, 0, 0, pen); m_vLine->setZValue(1e9); } m_hLine->setPen(pen); m_vLine->setPen(pen); m_hLine->setLine(sceneX - m_CrosshairHalfLen, sceneY, sceneX + m_CrosshairHalfLen, sceneY); m_vLine->setLine(sceneX, sceneY - m_CrosshairHalfLen, sceneX, sceneY + m_CrosshairHalfLen); } void Mapcavas::removeCrosshair() { if (m_hLine) { if (m_hLine->scene()) m_hLine->scene()->removeItem(m_hLine); delete m_hLine; m_hLine = nullptr; } if (m_vLine) { if (m_vLine->scene()) m_vLine->scene()->removeItem(m_vLine); delete m_vLine; m_vLine = nullptr; } } void Mapcavas::wheelEvent(QWheelEvent *event) { // Always let the tool have a chance first if (m_mapTool) { m_mapTool->canvasWheelEvent(event); } if (HasImage()) { QPointF oldPos = mapToScene(event->pos()); QPoint scrollAmount = event->angleDelta(); scrollAmount.y() > 0 ? zoomIn() : zoomOut(); QPointF newPos = mapToScene(event->pos()); QPointF delta = newPos - oldPos; translate(delta.x(), delta.y()); } } void Mapcavas::scaling(qreal scaleFactor) { scale(scaleFactor, scaleFactor); } void Mapcavas::mousePressEvent(QMouseEvent *event) { if (m_mapTool) { m_mapTool->canvasMousePressEvent(event); QGraphicsView::mousePressEvent(event); return; } QGraphicsView::mousePressEvent(event); } void Mapcavas::mouseMoveEvent(QMouseEvent *event) { if (m_mapTool) { m_mapTool->canvasMouseMoveEvent(event); QGraphicsView::mousePressEvent(event); return; } QGraphicsView::mousePressEvent(event); } void Mapcavas::mouseReleaseEvent(QMouseEvent *event) { if (m_mapTool) { m_mapTool->canvasMouseReleaseEvent(event); QGraphicsView::mouseReleaseEvent(event); return; } QGraphicsView::mouseReleaseEvent(event); } void Mapcavas::mouseDoubleClickEvent(QMouseEvent *event) { if (m_mapTool) { m_mapTool->canvasMouseDoubleClickEvent(event); return; } QGraphicsView::mouseDoubleClickEvent(event); } void Mapcavas::zoomIn() { zoom(1 + m_zoomDelta); } void Mapcavas::zoomOut() { zoom(1 - m_zoomDelta); } void Mapcavas::zoom(float scaleFactor) { qreal factor = transform().scale(scaleFactor, scaleFactor).mapRect(QRectF(0, 0, 1, 1)).width(); if (factor < 0.07 || factor > 100) return; scale(scaleFactor, scaleFactor); m_scale *= scaleFactor; } void Mapcavas::setTranslateSpeed(qreal speed) { Q_ASSERT_X(speed >= 0.0 && speed <= 2.0, "InteractiveView::setTranslateSpeed", "Speed should be in range [0.0, 2.0]."); m_translateSpeed = speed; } qreal Mapcavas::translateSpeed() const { return m_translateSpeed; } void Mapcavas::setZoomDelta(qreal delta) { Q_ASSERT_X(delta >= 0.0 && delta <= 1.0, "InteractiveView::setZoomDelta", "Delta should be in range [0.0, 1.0]."); m_zoomDelta = delta; } qreal Mapcavas::zoomDelta() const { return m_zoomDelta; } // new: set associated raster layer void Mapcavas::setLayers(RasterLayer* layer) { m_rasterLayer = layer; } RasterLayer* Mapcavas::rasterLayer() const { return m_rasterLayer; } // new: refresh the map by rendering using the RasterLayer's render method void Mapcavas::freshmap() { if (!m_rasterLayer) return; RasterLayer::RenderParams params = m_rasterLayer->currentRenderParams(); QImage img = m_rasterLayer->render(params); if (img.isNull()) return; QPixmap pm = QPixmap::fromImage(img); SetImage(&pm); } void Mapcavas::freshmap(const RasterLayer::RenderParams& params) { if (!m_rasterLayer) return; QImage img = m_rasterLayer->render(params); if (img.isNull()) return; QPixmap pm = QPixmap::fromImage(img); SetImage(&pm); } // MapTool management void Mapcavas::setMapTool(MapTool* tool) { if (m_mapTool) { m_mapTool->deactivate(); } m_mapTool = tool; if (m_mapTool) { // Disable built-in drag mode so the tool controls everything setDragMode(QGraphicsView::NoDrag); m_mapTool->activate(); } else { // Restore legacy drag mode when no tool setDragMode(QGraphicsView::ScrollHandDrag); } } void Mapcavas::unsetMapTool(MapTool* tool) { if (m_mapTool && m_mapTool == tool) { m_mapTool->deactivate(); m_mapTool = nullptr; setDragMode(QGraphicsView::ScrollHandDrag); } } MapTool* Mapcavas::mapTool() const { return m_mapTool; }