diff --git a/tk_annotation_gui.py b/tk_annotation_gui.py index f9227067..f59331bb 100644 --- a/tk_annotation_gui.py +++ b/tk_annotation_gui.py @@ -673,6 +673,37 @@ class TkAnnotationApp: self.drag_start = (event_x, event_y) self._redraw_boxes() + def _apply_move_drag(self, event_x: float, event_y: float) -> None: + if ( + not self.dragging + or self.drag_mode != "move" + or self.selected_box_index is None + or self.drag_start is None + or self.current_image_path is None + ): + return + + boxes = self.annotations.get(self.current_image_path.name, []) or [] + if self.selected_box_index >= len(boxes): + return + + bbox = boxes[self.selected_box_index]["bbox"] + x1, y1, x2, y2 = bbox + # Convert to display coords, move, convert back + dx1, dy1 = self._img_to_disp(x1, y1) + dx2, dy2 = self._img_to_disp(x2, y2) + dx = event_x - self.drag_start[0] + dy = event_y - self.drag_start[1] + dx1 += dx + dy1 += dy + dx2 += dx + dy2 += dy + ix1, iy1 = self._disp_to_img(dx1, dy1) + ix2, iy2 = self._disp_to_img(dx2, dy2) + boxes[self.selected_box_index]["bbox"] = [ix1, iy1, ix2, iy2] + self.drag_start = (event_x, event_y) + self._redraw_boxes() + # ------------------------- Mouse interactions ------------------------- def _on_mouse_down(self, event: tk.Event) -> None: @@ -700,18 +731,6 @@ class TkAnnotationApp: # Check if Ctrl is held for moving or resizing boxes if event.state & 0x4: # Ctrl key - # First, check if clicking on a corner of the selected box for resizing - if self.selected_box_index is not None: - corner = self._find_resize_corner(event.x, event.y, self.selected_box_index) - if corner: - self.dragging = True - self.drag_mode = 'resize' - self.resize_corner = corner - self.drag_start = (event.x, event.y) - self._refresh_box_list() - self._redraw_boxes() - return - # Otherwise, select and move a box if box_index is not None: self.selected_box_index = box_index @@ -722,12 +741,20 @@ class TkAnnotationApp: self._redraw_boxes() return - # Normal mode: check if clicking inside a box to potentially select it + # Normal mode: check if clicking inside a box if box_index is not None: - self._potential_select = box_index - self._is_selecting = True - self._mouse_moved = False - return + if box_index == self.selected_box_index: + # If clicking on the already selected box, start moving it + self.dragging = True + self.drag_mode = 'move' + self.drag_start = (event.x, event.y) + return + else: + # Otherwise, potentially select it + self._potential_select = box_index + self._is_selecting = True + self._mouse_moved = False + return # Otherwise, start drawing self._draw_start = (event.x, event.y) @@ -741,34 +768,8 @@ class TkAnnotationApp: self._apply_resize_drag(event.x, event.y) return - if self.dragging and self.drag_mode == 'move' and self.drag_start and self.selected_box_index is not None: - # Move the box - dx = event.x - self.drag_start[0] - dy = event.y - self.drag_start[1] - if self.current_image_path is None: - return - boxes = self.annotations.get(self.current_image_path.name, []) or [] - if self.selected_box_index >= len(boxes): - return - bbox = boxes[self.selected_box_index]["bbox"] - x1, y1, x2, y2 = bbox - # Convert to display coords, move, convert back - dx1, dy1 = self._img_to_disp(x1, y1) - dx2, dy2 = self._img_to_disp(x2, y2) - dx1 += dx - dy1 += dy - dx2 += dx - dy2 += dy - ix1, iy1 = self._disp_to_img(dx1, dy1) - ix2, iy2 = self._disp_to_img(dx2, dy2) - boxes[self.selected_box_index]["bbox"] = [ix1, iy1, ix2, iy2] - self.drag_start = (event.x, event.y) - self._redraw_boxes() - return - - if self._is_selecting: - self._mouse_moved = True - return + if self.dragging and self.drag_mode == "move": + self._apply_move_drag(event.x, event.y) if self._draw_start is None or self.current_image is None or self.transform is None: return