mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 11:11:49 +02:00
fix(image_roi): coordinates are emitted correctly when handles are inverted; closes #672
This commit is contained in:
@ -437,6 +437,23 @@ class RectangularROI(BaseROI, pg.RectROI):
|
|||||||
self.hoverPen = fn.mkPen(color=(255, 0, 0), width=3, style=QtCore.Qt.DashLine)
|
self.hoverPen = fn.mkPen(color=(255, 0, 0), width=3, style=QtCore.Qt.DashLine)
|
||||||
self.handleHoverPen = fn.mkPen("lime", width=4)
|
self.handleHoverPen = fn.mkPen("lime", width=4)
|
||||||
|
|
||||||
|
def _normalized_edges(self) -> tuple[float, float, float, float]:
|
||||||
|
"""
|
||||||
|
Return rectangle edges as (left, bottom, right, top) with consistent
|
||||||
|
ordering even when the ROI has been inverted by its scale handles.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
tuple: A tuple containing the left, bottom, right, and top edges
|
||||||
|
of the ROI rectangle in normalized coordinates.
|
||||||
|
"""
|
||||||
|
x0, y0 = self.pos().x(), self.pos().y()
|
||||||
|
w, h = self.state["size"]
|
||||||
|
x_left = min(x0, x0 + w)
|
||||||
|
x_right = max(x0, x0 + w)
|
||||||
|
y_bottom = min(y0, y0 + h)
|
||||||
|
y_top = max(y0, y0 + h)
|
||||||
|
return x_left, y_bottom, x_right, y_top
|
||||||
|
|
||||||
def add_scale_handle(self):
|
def add_scale_handle(self):
|
||||||
"""
|
"""
|
||||||
Add scale handles at every corner and edge of the ROI.
|
Add scale handles at every corner and edge of the ROI.
|
||||||
@ -465,17 +482,15 @@ class RectangularROI(BaseROI, pg.RectROI):
|
|||||||
|
|
||||||
def _on_region_changed(self):
|
def _on_region_changed(self):
|
||||||
"""
|
"""
|
||||||
Handles ROI region change events.
|
Handles changes to the ROI's region.
|
||||||
|
|
||||||
This method is called whenever the ROI's position or size changes.
|
This method is called whenever the ROI's position or size changes.
|
||||||
It calculates the new corner coordinates and emits the edgesChanged signal
|
It calculates the new corner coordinates and emits the edgesChanged signal
|
||||||
with the updated coordinates.
|
with the updated coordinates.
|
||||||
"""
|
"""
|
||||||
x0, y0 = self.pos().x(), self.pos().y()
|
x_left, y_bottom, x_right, y_top = self._normalized_edges()
|
||||||
w, h = self.state["size"]
|
self.edgesChanged.emit(x_left, y_bottom, x_right, y_top)
|
||||||
self.edgesChanged.emit(x0, y0, x0 + w, y0 + h)
|
self.parent_plot_item.vb.update()
|
||||||
viewBox = self.parent_plot_item.vb
|
|
||||||
viewBox.update()
|
|
||||||
|
|
||||||
def mouseDragEvent(self, ev):
|
def mouseDragEvent(self, ev):
|
||||||
"""
|
"""
|
||||||
@ -489,9 +504,8 @@ class RectangularROI(BaseROI, pg.RectROI):
|
|||||||
"""
|
"""
|
||||||
super().mouseDragEvent(ev)
|
super().mouseDragEvent(ev)
|
||||||
if ev.isFinish():
|
if ev.isFinish():
|
||||||
x0, y0 = self.pos().x(), self.pos().y()
|
x_left, y_bottom, x_right, y_top = self._normalized_edges()
|
||||||
w, h = self.state["size"]
|
self.edgesReleased.emit(x_left, y_bottom, x_right, y_top)
|
||||||
self.edgesReleased.emit(x0, y0, x0 + w, y0 + h)
|
|
||||||
|
|
||||||
def get_coordinates(self, typed: bool | None = None) -> dict | tuple:
|
def get_coordinates(self, typed: bool | None = None) -> dict | tuple:
|
||||||
"""
|
"""
|
||||||
@ -510,17 +524,16 @@ class RectangularROI(BaseROI, pg.RectROI):
|
|||||||
if typed is None:
|
if typed is None:
|
||||||
typed = self.description
|
typed = self.description
|
||||||
|
|
||||||
x0, y0 = self.pos().x(), self.pos().y()
|
x_left, y_bottom, x_right, y_top = self._normalized_edges()
|
||||||
w, h = self.state["size"]
|
|
||||||
x1, y1 = x0 + w, y0 + h
|
|
||||||
if typed:
|
if typed:
|
||||||
return {
|
return {
|
||||||
"bottom_left": (x0, y0),
|
"bottom_left": (x_left, y_bottom),
|
||||||
"bottom_right": (x1, y0),
|
"bottom_right": (x_right, y_bottom),
|
||||||
"top_left": (x0, y1),
|
"top_left": (x_left, y_top),
|
||||||
"top_right": (x1, y1),
|
"top_right": (x_right, y_top),
|
||||||
}
|
}
|
||||||
return ((x0, y0), (x1, y0), (x0, y1), (x1, y1))
|
return (x_left, y_bottom), (x_right, y_bottom), (x_left, y_top), (x_right, y_top)
|
||||||
|
|
||||||
def _lookup_scene_image(self):
|
def _lookup_scene_image(self):
|
||||||
"""
|
"""
|
||||||
@ -654,7 +667,7 @@ class CircularROI(BaseROI, pg.CircleROI):
|
|||||||
if typed is None:
|
if typed is None:
|
||||||
typed = self.description
|
typed = self.description
|
||||||
|
|
||||||
d = self.state["size"][0]
|
d = abs(self.state["size"][0])
|
||||||
cx = self.pos().x() + d / 2
|
cx = self.pos().x() + d / 2
|
||||||
cy = self.pos().y() + d / 2
|
cy = self.pos().y() + d / 2
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user