gaphas.tool.placement - Gaphas

Hide navigation sidebar
Hide table of contents sidebar
Skip to content
Back to top
Toggle table of contents sidebar

# Source code for gaphas.tool.placement

    from __future__ import annotations

    from collections.abc import Callable

    from gi.repository import Gtk

    from gaphas.handlemove import HandleMove
    from gaphas.item import Item
    from gaphas.move import MoveType

    FactoryType = Callable[[], Item]

    def placement_tool(factory: FactoryType, handle_index: int) -> Gtk.GestureDrag:
        """Place a new item on the model."""
        gesture = Gtk.GestureDrag.new()
        placement_state = PlacementState(factory, handle_index)
        gesture.connect("drag-begin", on_drag_begin, placement_state)
        gesture.connect("drag-update", on_drag_update, placement_state)
        gesture.connect("drag-end", on_drag_end, placement_state)
        return gesture

    class PlacementState:
        def __init__(self, factory: FactoryType, handle_index: int):
            self.factory = factory
            self.handle_index = handle_index
            self.moving: MoveType | None = None

    def on_drag_begin(gesture, start_x, start_y, placement_state):
        view = gesture.get_widget()
        item = placement_state.factory()
        x, y = view.get_matrix_v2i(item).transform_point(start_x, start_y)
        item.matrix.translate(x, y)
        view.selection.unselect_all()
        view.selection.focused_item = item

        gesture.set_state(Gtk.EventSequenceState.CLAIMED)

        handle = item.handles()[placement_state.handle_index]
        if handle.movable:
            placement_state.moving = HandleMove(item, handle, view)
            placement_state.moving.start_move((start_x, start_y))

    def on_drag_update(gesture, offset_x, offset_y, placement_state):
        if placement_state.moving:
            _, x, y = gesture.get_start_point()
            placement_state.moving.move((x + offset_x, y + offset_y))

    def on_drag_end(gesture, offset_x, offset_y, placement_state):
        if placement_state.moving:
            _, x, y = gesture.get_start_point()
            placement_state.moving.stop_move((x + offset_x, y + offset_y))