diff --git a/viewer/widgets/JFJochImage.cpp b/viewer/widgets/JFJochImage.cpp index a2a82fc7..2268c411 100644 --- a/viewer/widgets/JFJochImage.cpp +++ b/viewer/widgets/JFJochImage.cpp @@ -115,29 +115,27 @@ void JFJochImage::SetROICircle(double x, double y, double radius) { } void JFJochImage::mousePressEvent(QMouseEvent *event) { - if (!scene()) return; + if (!scene()) return; if (event->button() == Qt::LeftButton) { const QPointF scenePos = mapToScene(event->pos()); + active_handle_ = hitTestROIHandle(scenePos, 4.0 / std::sqrt(std::max(1e-4, scale_factor))); - if (event->modifiers() & Qt::Modifier::SHIFT) { - active_handle_ = hitTestROIHandle(scenePos, 4.0 / std::sqrt(std::max(1e-4, scale_factor))); - if (active_handle_ != ResizeHandle::None && active_handle_ != ResizeHandle::Inside) { - mouse_event_type = MouseEventType::ResizingROI; - roiStartPos = roiBox.topLeft(); - roiEndPos = roiBox.bottomRight(); - setCursor(Qt::SizeAllCursor); - } else if (roiBox.contains(scenePos)) { - mouse_event_type = MouseEventType::MovingROI; - lastMousePos = event->pos(); - setCursor(Qt::ClosedHandCursor); - } else { - mouse_event_type = MouseEventType::DrawingROI; - roiStartPos = RoundPoint(scenePos); - roiEndPos = roiStartPos; - roi_type = (event->modifiers() & Qt::Modifier::CTRL) ? RoiType::RoiCircle : RoiType::RoiBox; - setCursor(Qt::CrossCursor); - } + if (active_handle_ != ResizeHandle::None && active_handle_ != ResizeHandle::Inside) { + mouse_event_type = MouseEventType::ResizingROI; + roiStartPos = roiBox.topLeft(); + roiEndPos = roiBox.bottomRight(); + setCursor(Qt::SizeAllCursor); + } else if (roiBox.contains(scenePos)) { + mouse_event_type = MouseEventType::MovingROI; + lastMousePos = event->pos(); + setCursor(Qt::ClosedHandCursor); + } else if (event->modifiers() & Qt::Modifier::SHIFT) { + mouse_event_type = MouseEventType::DrawingROI; + roiStartPos = RoundPoint(scenePos); + roiEndPos = roiStartPos; + roi_type = (event->modifiers() & Qt::Modifier::CTRL) ? RoiType::RoiCircle : RoiType::RoiBox; + setCursor(Qt::CrossCursor); } else { mouse_event_type = MouseEventType::Panning; setCursor(Qt::ClosedHandCursor); @@ -146,9 +144,7 @@ void JFJochImage::mousePressEvent(QMouseEvent *event) { } QGraphicsView::mousePressEvent(event); - } - void JFJochImage::mouseMoveEvent(QMouseEvent *event) { if (!scene()) return; @@ -208,6 +204,11 @@ void JFJochImage::mouseMoveEvent(QMouseEvent *event) { case MouseEventType::None: { const qreal tol = 4.0 / std::sqrt(std::max(1e-4, scale_factor)); ResizeHandle h = hitTestROIHandle(scenePos, tol); + // Update hover state so overlay can draw arrows/handles accordingly + if (h != hover_handle_) { + hover_handle_ = h; + updateOverlay(); + } // Set an informative cursor switch (h) { case ResizeHandle::Left: @@ -308,15 +309,32 @@ JFJochImage::hitTestROIHandle(const QPointF& scenePos, qreal tol) const { void JFJochImage::updateROI() { if (roi_type == RoiType::RoiBox) { - QRect roiBox_int = QRectF(RoundPoint(roiStartPos), RoundPoint(roiEndPos)).normalized().toRect(); - roiBox= roiBox_int; - emit roiBoxUpdated(roiBox_int); + if (mouse_event_type == MouseEventType::DrawingROI) { + // While drawing: construct box from start/end + QRectF rect = QRectF(RoundPoint(roiStartPos), RoundPoint(roiEndPos)).normalized(); + roiBox = rect; + } else { + // While moving/resizing: keep roiBox as modified, just sync corners + roiStartPos = roiBox.topLeft(); + roiEndPos = roiBox.bottomRight(); + } + emit roiBoxUpdated(roiBox.toRect()); } else { - QPointF delta = roiStartPos - roiEndPos; - double radius = std::sqrt(delta.x() * delta.x() + delta.y() * delta.y()); - roiBox= QRectF(roiStartPos.x() - radius, roiStartPos.y() - radius, - 2 * radius, 2 * radius).normalized(); - emit roiCircleUpdated(roiStartPos.x(), roiStartPos.y(), radius); + if (mouse_event_type == MouseEventType::DrawingROI) { + // Center at roiStartPos, radius from start->end + QPointF delta = roiStartPos - roiEndPos; + double radius = std::sqrt(delta.x() * delta.x() + delta.y() * delta.y()); + roiBox = QRectF(roiStartPos.x() - radius, roiStartPos.y() - radius, + 2 * radius, 2 * radius).normalized(); + emit roiCircleUpdated(roiStartPos.x(), roiStartPos.y(), radius); + } else { + // Moving/resizing: infer center/radius from roiBox + const QPointF c = roiBox.center(); + const double radius = 0.5 * std::min(roiBox.width(), roiBox.height()); + roiStartPos = c; // treat start as center for consistency + roiEndPos = QPointF(c.x() + radius, c.y()); // arbitrary point on radius + emit roiCircleUpdated(c.x(), c.y(), radius); + } } updateOverlay(); }