Tools no longer have a view argument
This commit is contained in:
parent
1bfcd6be93
commit
c55f260385
@ -19,7 +19,7 @@ Guides consist of a couple of elements: aspects that hook into the item-drag cyc
|
||||
... .append(HandlePainter(view))
|
||||
... .append(GuidePainter(view))
|
||||
... )
|
||||
>>> view.add_controller(item_tool(view))
|
||||
>>> view.add_controller(zoom_tool(view))
|
||||
>>> view.add_controller(item_tool())
|
||||
>>> view.add_controller(zoom_tool())
|
||||
|
||||
You need to hook up the ``GuidePainter``. The aspect are loaded as soon as the module is loaded.
|
||||
|
@ -21,5 +21,5 @@ to actually use it, the ``segment`` module needs to be imported.
|
||||
... .append(HandlePainter(view))
|
||||
... .append(LineSegmentPainter(view.selection))
|
||||
... )
|
||||
>>> view.add_controller(item_tool(view))
|
||||
>>> view.add_controller(zoom_tool(view))
|
||||
>>> view.add_controller(item_tool())
|
||||
>>> view.add_controller(zoom_tool())
|
||||
|
@ -137,6 +137,7 @@ def text_underline(cr, x, y, text, offset=1.5):
|
||||
cr.rel_line_to(x_adv, 0)
|
||||
cr.stroke()
|
||||
|
||||
|
||||
def rubberband_state(view):
|
||||
try:
|
||||
return view.rubberband_state
|
||||
@ -147,14 +148,14 @@ def rubberband_state(view):
|
||||
|
||||
def apply_default_tool_set(view):
|
||||
view.remove_all_controllers()
|
||||
view.add_controller(item_tool(view))
|
||||
for tool in zoom_tools(view):
|
||||
view.add_controller(item_tool())
|
||||
for tool in zoom_tools():
|
||||
view.add_controller(tool)
|
||||
view.add_controller(pan_tool(view))
|
||||
view.add_controller(view_focus_tool(view))
|
||||
view.add_controller(pan_tool())
|
||||
view.add_controller(view_focus_tool())
|
||||
|
||||
view.add_controller(rubberband_tool(view, rubberband_state(view)))
|
||||
view.add_controller(hover_tool(view))
|
||||
view.add_controller(rubberband_tool(rubberband_state(view)))
|
||||
view.add_controller(hover_tool())
|
||||
return rubberband_state
|
||||
|
||||
|
||||
@ -163,12 +164,12 @@ def apply_placement_tool_set(view, item_type, handle_index):
|
||||
apply_default_tool_set(view)
|
||||
|
||||
view.remove_all_controllers()
|
||||
tool = placement_tool(view, factory(view, item_type), handle_index)
|
||||
tool = placement_tool(factory(view, item_type), handle_index)
|
||||
tool.connect("drag-end", unset_placement_tool)
|
||||
for tool in zoom_tools(view):
|
||||
view.add_controller(tool)
|
||||
view.add_controller(view_focus_tool(view))
|
||||
view.add_controller(tool)
|
||||
for tool in zoom_tools():
|
||||
view.add_controller(tool)
|
||||
view.add_controller(view_focus_tool())
|
||||
|
||||
|
||||
def apply_painters(view):
|
||||
@ -283,9 +284,7 @@ def create_window(canvas, title, zoom=1.0): # noqa too complex
|
||||
assert view.model
|
||||
painter = ItemPainter()
|
||||
|
||||
bounding_box = calculate_bounding_box(
|
||||
painter, canvas.get_all_items()
|
||||
)
|
||||
bounding_box = calculate_bounding_box(painter, canvas.get_all_items())
|
||||
|
||||
surface = cairo.ImageSurface(
|
||||
cairo.FORMAT_ARGB32, int(bounding_box.width), int(bounding_box.height)
|
||||
@ -422,8 +421,6 @@ def main():
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
|
||||
if "-p" in sys.argv:
|
||||
print("Profiling...")
|
||||
import hotshot
|
||||
|
@ -143,6 +143,7 @@ def text_multiline(cr, x, y, text):
|
||||
cr.move_to(x, y)
|
||||
cr.show_text(line)
|
||||
|
||||
|
||||
def path_ellipse(cr, x, y, width, height, angle=0):
|
||||
"""Draw an ellipse.
|
||||
|
||||
|
@ -16,10 +16,10 @@ from examples.exampleitems import Box
|
||||
|
||||
def apply_default_tool_set(view):
|
||||
view.remove_all_controllers()
|
||||
view.add_controller(item_tool(view))
|
||||
view.add_controller(zoom_tool(view))
|
||||
view.add_controller(view_focus_tool(view))
|
||||
view.add_controller(hover_tool(view))
|
||||
view.add_controller(item_tool())
|
||||
view.add_controller(zoom_tool())
|
||||
view.add_controller(view_focus_tool())
|
||||
view.add_controller(hover_tool())
|
||||
|
||||
|
||||
def create_canvas(canvas, title):
|
||||
|
@ -2,10 +2,9 @@ from gi.repository import Gdk, Gtk
|
||||
|
||||
from gaphas.cursor import cursor
|
||||
from gaphas.tool.itemtool import find_item_and_handle_at_point
|
||||
from gaphas.view import GtkView
|
||||
|
||||
|
||||
def hover_tool(view: GtkView) -> Gtk.EventController:
|
||||
def hover_tool() -> Gtk.EventController:
|
||||
"""Highlight the currently hovered item."""
|
||||
ctrl = Gtk.EventControllerMotion.new()
|
||||
ctrl.connect("motion", on_motion)
|
||||
|
@ -16,7 +16,7 @@ from gaphas.view import GtkView
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def item_tool(view: GtkView) -> Gtk.GestureDrag:
|
||||
def item_tool() -> Gtk.GestureDrag:
|
||||
"""Handle item movement and movement of handles."""
|
||||
gesture = Gtk.GestureDrag.new()
|
||||
drag_state = DragState()
|
||||
|
@ -5,14 +5,11 @@ from gi.repository import Gtk
|
||||
from gaphas.handlemove import HandleMove
|
||||
from gaphas.item import Item
|
||||
from gaphas.move import MoveType
|
||||
from gaphas.view import GtkView
|
||||
|
||||
FactoryType = Callable[[], Item]
|
||||
|
||||
|
||||
def placement_tool(
|
||||
view: GtkView, factory: FactoryType, handle_index: int
|
||||
) -> Gtk.GestureDrag:
|
||||
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)
|
||||
|
@ -38,7 +38,7 @@ class RubberbandPainter:
|
||||
cairo.stroke()
|
||||
|
||||
|
||||
def rubberband_tool(view, rubberband_state):
|
||||
def rubberband_tool(rubberband_state):
|
||||
"""Rubberband selection tool.
|
||||
|
||||
Should be used in conjunction with ``RubberbandPainter``.
|
||||
|
@ -2,14 +2,13 @@ from gi.repository import Gdk, Gtk
|
||||
|
||||
from gaphas.tool.zoom import Zoom
|
||||
from gaphas.tool.hover import set_cursor
|
||||
from gaphas.view import GtkView
|
||||
|
||||
|
||||
def scroll_tools(view: GtkView, speed: int = 10) -> Gtk.EventControllerScroll:
|
||||
return scroll_tool(view, speed), pan_tool(view)
|
||||
def scroll_tools(speed: int = 10) -> Gtk.EventControllerScroll:
|
||||
return scroll_tool(speed), pan_tool()
|
||||
|
||||
|
||||
def scroll_tool(view: GtkView, speed: int = 10) -> Gtk.EventControllerScroll:
|
||||
def scroll_tool(speed: int = 10) -> Gtk.EventControllerScroll:
|
||||
"""Scroll tool recognized 2 finger scroll gestures."""
|
||||
ctrl = Gtk.EventControllerScroll.new(Gtk.EventControllerScrollFlags.BOTH_AXES)
|
||||
ctrl.connect("scroll", on_scroll, speed)
|
||||
@ -26,8 +25,8 @@ def on_scroll(controller, dx, dy, speed):
|
||||
view = controller.get_widget()
|
||||
x = view.get_width() / 2
|
||||
y = view.get_height() / 2
|
||||
zoom = Zoom(view.matrix)
|
||||
zoom.begin(x, y)
|
||||
zoom = Zoom()
|
||||
zoom.begin(view.matrix, x, y)
|
||||
|
||||
zoom_factor = 0.1
|
||||
d = 1 - dy * zoom_factor
|
||||
@ -49,7 +48,7 @@ class PanState:
|
||||
self.v = 0
|
||||
|
||||
|
||||
def pan_tool(view: GtkView) -> Gtk.GestureDrag:
|
||||
def pan_tool() -> Gtk.GestureDrag:
|
||||
gesture = Gtk.GestureDrag.new()
|
||||
gesture.set_button(Gdk.BUTTON_MIDDLE)
|
||||
pan_state = PanState()
|
||||
|
@ -1,7 +1,7 @@
|
||||
from gi.repository import Gtk
|
||||
|
||||
|
||||
def view_focus_tool(view):
|
||||
def view_focus_tool():
|
||||
"""This little tool ensures the view grabs focus when a mouse press or
|
||||
touch event happens."""
|
||||
gesture = Gtk.GestureSingle()
|
||||
|
@ -2,24 +2,24 @@ from __future__ import annotations
|
||||
|
||||
from gi.repository import Gdk, Gtk
|
||||
|
||||
from gaphas.view import GtkView
|
||||
|
||||
|
||||
class Zoom:
|
||||
def __init__(self, matrix):
|
||||
self.matrix = matrix
|
||||
def __init__(self):
|
||||
self.matrix = None
|
||||
self.x0 = 0
|
||||
self.y0 = 0
|
||||
self.sx = 1.0
|
||||
self.sy = 1.0
|
||||
|
||||
def begin(self, x0, y0):
|
||||
def begin(self, matrix, x0, y0):
|
||||
self.matrix = matrix
|
||||
self.x0 = x0
|
||||
self.y0 = y0
|
||||
self.sx = self.matrix[0]
|
||||
self.sy = self.matrix[3]
|
||||
self.sx = matrix[0]
|
||||
self.sy = matrix[3]
|
||||
|
||||
def update(self, scale):
|
||||
assert self.matrix
|
||||
if self.sx * scale < 0.2:
|
||||
scale = 0.2 / self.sx
|
||||
elif self.sx * scale > 20.0:
|
||||
@ -37,18 +37,18 @@ class Zoom:
|
||||
m.translate(+ox, +oy)
|
||||
|
||||
|
||||
def zoom_tools(
|
||||
view: GtkView,
|
||||
) -> tuple[Gtk.GestureZoom] | tuple[Gtk.GestureZoom, Gtk.EventControllerScroll]:
|
||||
return (zoom_tool(view), scroll_zoom_tool(view))
|
||||
def zoom_tools() -> (
|
||||
tuple[Gtk.GestureZoom] | tuple[Gtk.GestureZoom, Gtk.EventControllerScroll]
|
||||
):
|
||||
return zoom_tool(), scroll_zoom_tool()
|
||||
|
||||
|
||||
def zoom_tool(view: GtkView) -> Gtk.GestureZoom:
|
||||
def zoom_tool() -> Gtk.GestureZoom:
|
||||
"""Create a zoom tool as a Gtk.Gesture.
|
||||
|
||||
Note: we need to keep a reference to this gesture, or else it will be destroyed.
|
||||
"""
|
||||
zoom = Zoom(view.matrix)
|
||||
zoom = Zoom()
|
||||
gesture = Gtk.GestureZoom.new()
|
||||
gesture.set_propagation_phase(Gtk.PropagationPhase.CAPTURE)
|
||||
gesture.connect("begin", on_begin, zoom)
|
||||
@ -61,15 +61,16 @@ def on_begin(
|
||||
sequence: None,
|
||||
zoom: Zoom,
|
||||
) -> None:
|
||||
view = gesture.get_widget()
|
||||
_, x0, y0 = gesture.get_point(sequence)
|
||||
zoom.begin(x0, y0)
|
||||
zoom.begin(view.matrix, x0, y0)
|
||||
|
||||
|
||||
def on_scale_changed(gesture: Gtk.GestureZoom, scale: float, zoom: Zoom) -> None:
|
||||
def on_scale_changed(_gesture: Gtk.GestureZoom, scale: float, zoom: Zoom) -> None:
|
||||
zoom.update(scale)
|
||||
|
||||
|
||||
def scroll_zoom_tool(view: GtkView) -> Gtk.EventControllerScroll:
|
||||
def scroll_zoom_tool() -> Gtk.EventControllerScroll:
|
||||
"""Ctrl-scroll wheel zoom.
|
||||
|
||||
GTK4 only.
|
||||
@ -91,8 +92,8 @@ def on_scroll(controller, _dx, dy):
|
||||
view = controller.get_widget()
|
||||
x = view.get_width() / 2
|
||||
y = view.get_height() / 2
|
||||
zoom = Zoom(view.matrix)
|
||||
zoom.begin(x, y)
|
||||
zoom = Zoom()
|
||||
zoom.begin(view.matrix, x, y)
|
||||
|
||||
zoom_factor = 0.1
|
||||
d = 1 - dy * zoom_factor
|
||||
|
@ -416,7 +416,6 @@ class GtkView(Gtk.DrawingArea, Gtk.Scrollable):
|
||||
else:
|
||||
self._back_buffer = None
|
||||
|
||||
|
||||
def update_back_buffer(self) -> None:
|
||||
self.queue_draw()
|
||||
|
||||
|
@ -1,5 +1,4 @@
|
||||
# ruff: noqa: F402, E402
|
||||
import os
|
||||
|
||||
import gi
|
||||
|
||||
|
@ -1,35 +1,19 @@
|
||||
import pytest
|
||||
from gi.repository import Gdk, Gtk
|
||||
|
||||
from gaphas.tool.hover import hover_tool
|
||||
|
||||
GTK4 = Gtk._version == "4.0"
|
||||
from gaphas.tool.hover import hover_tool, on_motion
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def motion_event():
|
||||
event = Gdk.Event()
|
||||
event.type = Gdk.EventType.MOTION_NOTIFY
|
||||
return event
|
||||
def test_hovers_item(view, box):
|
||||
tool = hover_tool()
|
||||
view.add_controller(tool)
|
||||
|
||||
|
||||
@pytest.mark.skipif(GTK4, reason="test does work on GTK 3 only")
|
||||
def test_hovers_item(view, box, motion_event):
|
||||
tool = hover_tool(view)
|
||||
motion_event.x = 5
|
||||
motion_event.y = 5
|
||||
|
||||
tool.handle_event(motion_event)
|
||||
on_motion(tool, 5, 5)
|
||||
|
||||
assert view.selection.hovered_item is box
|
||||
|
||||
|
||||
@pytest.mark.skipif(GTK4, reason="test does work on GTK 3 only")
|
||||
def test_handles_event(view, box, motion_event):
|
||||
tool = hover_tool(view)
|
||||
motion_event.x = 100
|
||||
motion_event.y = 100
|
||||
def test_handles_event(view, box):
|
||||
tool = hover_tool()
|
||||
view.add_controller(tool)
|
||||
|
||||
tool.handle_event(motion_event)
|
||||
on_motion(tool, 100, 100)
|
||||
|
||||
assert view.selection.hovered_item is None
|
||||
|
@ -41,8 +41,8 @@ class MockGesture:
|
||||
pass
|
||||
|
||||
|
||||
def test_should_create_a_gesture(view):
|
||||
tool = item_tool(view)
|
||||
def test_should_create_a_gesture():
|
||||
tool = item_tool()
|
||||
|
||||
assert isinstance(tool, Gtk.Gesture)
|
||||
|
||||
|
@ -13,15 +13,15 @@ def tool_factory(connections):
|
||||
return tool_factory
|
||||
|
||||
|
||||
def test_can_create_placement_tool(view, tool_factory):
|
||||
tool = placement_tool(view, tool_factory, 2)
|
||||
def test_can_create_placement_tool(tool_factory):
|
||||
tool = placement_tool(tool_factory, 2)
|
||||
|
||||
assert isinstance(tool, Gtk.Gesture)
|
||||
|
||||
|
||||
def test_create_new_element(view, tool_factory, window):
|
||||
state = PlacementState(tool_factory, 2)
|
||||
tool = placement_tool(view, tool_factory, 2)
|
||||
tool = placement_tool(tool_factory, 2)
|
||||
view.add_controller(tool)
|
||||
|
||||
on_drag_begin(tool, 0, 0, state)
|
||||
|
@ -6,16 +6,17 @@ from gaphas.tool.zoom import Zoom, on_begin, on_scale_changed, zoom_tool
|
||||
|
||||
@pytest.fixture
|
||||
def zoom_data(view):
|
||||
zoom_data = Zoom(view.matrix)
|
||||
zoom_data = Zoom()
|
||||
zoom_data.x0 = 0
|
||||
zoom_data.y0 = 0
|
||||
zoom_data.sx = 1
|
||||
zoom_data.sy = 1
|
||||
zoom_data.begin(view.matrix, 0, 0)
|
||||
return zoom_data
|
||||
|
||||
|
||||
def test_can_create_zoom_tool(view):
|
||||
tool = zoom_tool(view)
|
||||
tool = zoom_tool()
|
||||
view.add_controller(tool)
|
||||
|
||||
assert isinstance(tool, Gtk.Gesture)
|
||||
@ -41,7 +42,7 @@ def test_begin_state(zoom_data, view):
|
||||
|
||||
|
||||
def test_scaling(zoom_data, view):
|
||||
tool = zoom_tool(view)
|
||||
tool = zoom_tool()
|
||||
view.add_controller(tool)
|
||||
|
||||
on_scale_changed(tool, 1.2, zoom_data)
|
||||
@ -51,7 +52,7 @@ def test_scaling(zoom_data, view):
|
||||
|
||||
|
||||
def test_multiple_scaling_events(zoom_data, view):
|
||||
tool = zoom_tool(view)
|
||||
tool = zoom_tool()
|
||||
view.add_controller(tool)
|
||||
|
||||
on_scale_changed(tool, 1.1, zoom_data)
|
||||
@ -62,7 +63,7 @@ def test_multiple_scaling_events(zoom_data, view):
|
||||
|
||||
|
||||
def test_scaling_with_unequal_scaling_factor(zoom_data, view):
|
||||
tool = zoom_tool(view)
|
||||
tool = zoom_tool()
|
||||
view.add_controller(tool)
|
||||
|
||||
zoom_data.sx = 2
|
||||
@ -74,7 +75,7 @@ def test_scaling_with_unequal_scaling_factor(zoom_data, view):
|
||||
|
||||
|
||||
def test_zoom_should_center_around_mouse_cursor(zoom_data, view):
|
||||
tool = zoom_tool(view)
|
||||
tool = zoom_tool()
|
||||
view.add_controller(tool)
|
||||
zoom_data.x0 = 100
|
||||
zoom_data.y0 = 50
|
||||
@ -86,8 +87,9 @@ def test_zoom_should_center_around_mouse_cursor(zoom_data, view):
|
||||
|
||||
|
||||
def test_zoom_out_should_be_limited_to_20_percent(zoom_data, view):
|
||||
tool = zoom_tool(view)
|
||||
tool = zoom_tool()
|
||||
view.add_controller(tool)
|
||||
|
||||
on_scale_changed(tool, 0.0, zoom_data)
|
||||
|
||||
assert view.matrix[0] == pytest.approx(0.2)
|
||||
@ -95,7 +97,7 @@ def test_zoom_out_should_be_limited_to_20_percent(zoom_data, view):
|
||||
|
||||
|
||||
def test_zoom_in_should_be_limited_to_20_times(zoom_data, view):
|
||||
tool = zoom_tool(view)
|
||||
tool = zoom_tool()
|
||||
view.add_controller(tool)
|
||||
|
||||
on_scale_changed(tool, 100.0, zoom_data)
|
||||
|
Loading…
x
Reference in New Issue
Block a user