Repository URL to install this package:
Version:
5.2.1 ▾
|
# (C) Copyright 2005-2021 Enthought, Inc., Austin, TX
# All rights reserved.
#
# This software is provided without warranty under the terms of the BSD
# license included in LICENSE.txt and may be redistributed only under
# the conditions described in the aforementioned license. The license
# is also available online at http://www.enthought.com/licenses/BSD.txt
#
# Thanks for using Enthought open source!
# Standard library imports
import copy
import unittest
# Enthought library imports
from traits.api import Any, Tuple
# Enable imports
from enable.api import (
AbstractWindow, BasicEvent, Canvas, Component, Container, Viewport
)
class EnableUnitTest(unittest.TestCase):
def assert_dims(self, obj, **dims):
"""
checks that each of the named dimensions of the object are a
certain value. e.g. assert_dims(component, x=5.0, y=7.0).
"""
for dim, val in dims.items():
self.assertTrue(getattr(obj, dim) == val)
class TestComponent(Component):
""" A component used for testing event handling. Most notably, it
saves a copy of the last event it received.
"""
# Make some nice default bounds
bounds = [10, 10]
last_event = Any
def _dispatch_stateful_event(self, event, suffix):
super()._dispatch_stateful_event(event, suffix)
self.last_event = copy.copy(event)
class TestContainer(Container):
last_event = Any
def _dispatch_stateful_event(self, event, suffix):
super()._dispatch_stateful_event(event, suffix)
self.last_event = copy.copy(event)
class TestCanvas(Canvas):
last_event = Any
def _dispatch_stateful_event(self, event, suffix):
super()._dispatch_stateful_event(event, suffix)
self.last_event = copy.copy(event)
class DummyWindow(AbstractWindow):
""" A stubbed-out subclass of AbstractWindow that passes on most virtual
methods instead of raising an exception.
"""
def _capture_mouse(self):
pass
def _release_mouse(self):
pass
def _create_mouse_event(self, event):
return event
def _redraw(self, *args, **kw):
pass
def _get_control_size(self):
return self._size
def _create_gc(self, *args, **kw):
pass
def _window_paint(self, event):
pass
def set_pointer(self, pointer):
pass
def _set_timer_interval(self, component, interval):
pass
def _set_focus(self):
pass
def screen_to_window(self, x, y):
return (x, y)
class EventTransformTestCase(EnableUnitTest):
def test_simple_container(self):
""" Tests event handling of nested containers """
comp = TestComponent(position=[50, 50])
inner_container = TestContainer(
bounds=[100.0, 100.0], position=[50, 50]
)
inner_container.add(comp)
outer_container = TestContainer(bounds=[200, 200])
outer_container.add(inner_container)
event = BasicEvent(x=105, y=105)
outer_container.dispatch(event, "left_down")
self.assertTrue(comp.last_event.x == 55)
self.assertTrue(comp.last_event.y == 55)
self.assertTrue(inner_container.last_event.x == 105)
self.assertTrue(inner_container.last_event.y == 105)
def test_viewport_container(self):
""" Tests event handling of viewports (scaling and translation) """
comp = TestComponent(position=[20, 20])
container = TestContainer(bounds=[100, 100], position=[50, 50])
container.add(comp)
viewport = Viewport(
component=container, bounds=[400, 400], position=[30, 30]
)
# Test unscaled event
event = BasicEvent(x=105, y=105)
viewport.dispatch(event, "left_down")
self.assertTrue(container.last_event.x == 75)
self.assertTrue(container.last_event.y == 75)
self.assertTrue(comp.last_event.x == 25)
self.assertTrue(comp.last_event.y == 25)
# Translate the viewport's view_position
container.last_event = None
comp.last_event = None
viewport.view_position = [-10, -10]
event = BasicEvent(x=115, y=115)
viewport.dispatch(event, "left_down")
self.assertTrue(container.last_event.x == 75)
self.assertTrue(container.last_event.y == 75)
self.assertTrue(comp.last_event.x == 25)
self.assertTrue(comp.last_event.y == 25)
# Do a zoom
container.last_event = None
comp.last_event = None
# Zoom in by a factor of 2, so view an area that is 200x200.
viewport.zoom = 2.0
viewport.enable_zoom = True
viewport.view_position = [-50, -50]
viewport.view_bounds = [200, 200]
event = BasicEvent(x=280, y=280)
viewport.dispatch(event, "left_down")
self.assertTrue(container.last_event.x == 75)
self.assertTrue(container.last_event.y == 75)
self.assertTrue(comp.last_event.x == 25)
self.assertTrue(comp.last_event.y == 25)
def test_mouse_capture(self):
""" Tests saving the event's net_transform as well as the dispatch
history when capturing a mouse and dispatching subsequent events.
"""
class MouseCapturingComponent(TestComponent):
captured_event_pos = Tuple
def normal_left_down(self, event):
self.captured_event_pos = (event.x, event.y)
event.window.set_mouse_owner(self, event.net_transform())
comp = MouseCapturingComponent(position=[20, 20])
container = TestContainer(bounds=[100, 100], position=[50, 50])
container.add(comp)
viewport = Viewport(
component=container,
bounds=[400, 400],
position=[30, 30],
fit_window=False,
resizable="",
)
window = DummyWindow(_size=(500, 500))
window.component = viewport
# Create the first event (to trigger the mouse capture)
event = BasicEvent(x=105, y=105, window=window)
window._handle_mouse_event("left_down", event)
self.assertTrue(window.mouse_owner == comp)
# Create the second event
event = BasicEvent(x=107, y=107, window=window)
old_pos = comp.captured_event_pos
window._handle_mouse_event("left_down", event)
new_pos = comp.captured_event_pos
self.assertTrue(new_pos[0] == old_pos[0] + 2)
self.assertTrue(new_pos[1] == old_pos[1] + 2)