jfjoch_viewer: mouse events are handled by JFJochImage, but this is not working properly for neither of the modes (TBD)

This commit is contained in:
2025-11-07 16:11:34 +01:00
parent 1f37bb3fd6
commit bb58849543
6 changed files with 187 additions and 252 deletions
+16 -147
View File
@@ -48,122 +48,24 @@ void JFJochSimpleImage::Redraw() {
}
}
void JFJochSimpleImage::mousePressEvent(QMouseEvent* event) {
if (!scene() || !has_image_) return;
if (event->button() == Qt::LeftButton) {
const QPointF scenePos = mapToScene(event->pos());
// With Shift -> ROI interactions (draw/resize/move); without -> pan
if (event->modifiers() & Qt::Modifier::SHIFT) {
// Determine if we are over an existing ROI handle
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;
setCursor(Qt::CrossCursor);
}
} else {
mouse_event_type = MouseEventType::Panning;
setCursor(Qt::ClosedHandCursor);
lastMousePos = event->pos();
}
}
QGraphicsView::mousePressEvent(event);
}
void JFJochSimpleImage::mouseMoveEvent(QMouseEvent* event) {
if (!scene() || !has_image_) return;
void JFJochSimpleImage::mouseHover(QMouseEvent *event) {
const QPointF scenePos = mapToScene(event->pos());
switch (mouse_event_type) {
case MouseEventType::Panning: {
const QPointF delta = mapToScene(event->pos()) - mapToScene(lastMousePos);
lastMousePos = event->pos();
translate(delta.x(), delta.y());
updateOverlay();
break;
// Hover feedback / status bar display
if ((scenePos.x() >= 0)
&& (scenePos.x() < image_->image.GetWidth())
&& (scenePos.y() >= 0)
&& (scenePos.y() < image_->image.GetHeight())) {
const auto ix = int(scenePos.x());
const auto iy = int(scenePos.y());
const auto idx = iy * int(image_->image.GetWidth()) + ix;
if (idx >= 0 && idx < int(image_values_.size()))
emit writeStatusBar(QString("x=%1 y=%2 I=%3")
.arg(scenePos.x(), 0, 'f', 1)
.arg(scenePos.y(), 0, 'f', 1)
.arg(image_values_[size_t(idx)]), 3000);
} else {
emit writeStatusBar("", 1000);
}
case MouseEventType::DrawingROI: {
roiEndPos = RoundPoint(scenePos);
updateROI();
break;
}
case MouseEventType::MovingROI: {
const QPointF delta = mapToScene(event->pos()) - mapToScene(lastMousePos);
lastMousePos = event->pos();
roiBox.translate(delta);
updateROI();
break;
}
case MouseEventType::ResizingROI: {
// Modify the corresponding edges based on active_handle_
QRectF r = roiBox;
switch (active_handle_) {
case ResizeHandle::Left: r.setLeft(scenePos.x()); break;
case ResizeHandle::Right: r.setRight(scenePos.x()); break;
case ResizeHandle::Top: r.setTop(scenePos.y()); break;
case ResizeHandle::Bottom: r.setBottom(scenePos.y()); break;
case ResizeHandle::TopLeft: r.setTop(scenePos.y()); r.setLeft(scenePos.x()); break;
case ResizeHandle::TopRight: r.setTop(scenePos.y()); r.setRight(scenePos.x()); break;
case ResizeHandle::BottomLeft: r.setBottom(scenePos.y()); r.setLeft(scenePos.x()); break;
case ResizeHandle::BottomRight:r.setBottom(scenePos.y()); r.setRight(scenePos.x()); break;
default: break;
}
roiBox = r.normalized();
updateROI();
break;
}
case MouseEventType::None: {
// Hover feedback / status bar display
if ((scenePos.x() >= 0)
&& (scenePos.x() < image_->image.GetWidth())
&& (scenePos.y() >= 0)
&& (scenePos.y() < image_->image.GetHeight())) {
const auto ix = int(scenePos.x());
const auto iy = int(scenePos.y());
const auto idx = iy * int(image_->image.GetWidth()) + ix;
if (idx >= 0 && idx < int(image_values_.size()))
emit writeStatusBar(QString("x=%1 y=%2 I=%3")
.arg(scenePos.x(), 0, 'f', 1)
.arg(scenePos.y(), 0, 'f', 1)
.arg(image_values_[size_t(idx)]), 3000);
} else {
emit writeStatusBar("", 1000);
}
break;
}
}
QGraphicsView::mouseMoveEvent(event);
}
void JFJochSimpleImage::mouseReleaseEvent(QMouseEvent* event) {
if (!scene() || !has_image_) return;
if (event->button() == Qt::LeftButton) {
if (mouse_event_type == MouseEventType::DrawingROI) {
roiEndPos = RoundPoint(mapToScene(event->pos()));
updateROI();
}
mouse_event_type = MouseEventType::None;
active_handle_ = ResizeHandle::None;
setCursor(Qt::ArrowCursor);
}
QGraphicsView::mouseReleaseEvent(event);
}
void JFJochSimpleImage::renderImage() {
@@ -334,39 +236,6 @@ void JFJochSimpleImage::renderImage(QImage &qimg, const uint8_t *input) {
}
}
JFJochSimpleImage::ResizeHandle
JFJochSimpleImage::hitTestROIHandle(const QPointF& scenePos, qreal tol) const {
if (roiBox.isNull() || roiBox.width() <= 0 || roiBox.height() <= 0)
return ResizeHandle::None;
const QRectF r = roiBox;
const QPointF tl = r.topLeft();
const QPointF tr = r.topRight();
const QPointF bl = r.bottomLeft();
const QPointF br = r.bottomRight();
auto nearPt = [&](const QPointF& a, const QPointF& b, qreal t) {
return std::abs(a.x() - b.x()) <= t && std::abs(a.y() - b.y()) <= t;
};
if (nearPt(scenePos, tl, tol)) return ResizeHandle::TopLeft;
if (nearPt(scenePos, tr, tol)) return ResizeHandle::TopRight;
if (nearPt(scenePos, bl, tol)) return ResizeHandle::BottomLeft;
if (nearPt(scenePos, br, tol)) return ResizeHandle::BottomRight;
// Edges
if (std::abs(scenePos.x() - r.left()) <= tol && scenePos.y() >= r.top() - tol && scenePos.y() <= r.bottom() + tol)
return ResizeHandle::Left;
if (std::abs(scenePos.x() - r.right()) <= tol && scenePos.y() >= r.top() - tol && scenePos.y() <= r.bottom() + tol)
return ResizeHandle::Right;
if (std::abs(scenePos.y() - r.top()) <= tol && scenePos.x() >= r.left() - tol && scenePos.x() <= r.right() + tol)
return ResizeHandle::Top;
if (std::abs(scenePos.y() - r.bottom()) <= tol && scenePos.x() >= r.left() - tol && scenePos.x() <= r.right() + tol)
return ResizeHandle::Bottom;
if (r.contains(scenePos)) return ResizeHandle::Inside;
return ResizeHandle::None;
}
void JFJochSimpleImage::updateROI() {
// Normalize box if drawing