2
# Standard library imports
6
# Enthought library imports
7
from enthought.traits.api import Any, Tuple
10
from enthought.enable2.api import BasicEvent, Canvas, Component, Container, \
11
Viewport, AbstractWindow
14
class EnableUnitTest(unittest.TestCase):
16
def assert_dims(self, obj, **dims):
18
checks that each of the named dimensions of the object are a
19
certain value. e.g. assert_dims(component, x=5.0, y=7.0).
21
for dim, val in dims.items():
22
self.assert_( getattr(obj, dim) == val )
25
class TestComponent(Component):
26
""" A component used for testing event handling. Most notably, it
27
saves a copy of the last event it received.
30
# Make some nice default bounds
35
def _dispatch_stateful_event(self, event, suffix):
36
super(TestComponent, self)._dispatch_stateful_event(event, suffix)
37
self.last_event = copy.copy(event)
39
class TestContainer(Container):
43
def _dispatch_stateful_event(self, event, suffix):
44
super(TestContainer, self)._dispatch_stateful_event(event, suffix)
45
self.last_event = copy.copy(event)
47
class TestCanvas(Canvas):
51
def _dispatch_stateful_event(self, event, suffix):
52
super(TestCanvas, self)._dispatch_stateful_event(event, suffix)
53
self.last_event = copy.copy(event)
56
class DummyWindow(AbstractWindow):
57
""" A stubbed-out subclass of AbstractWindow that passes on most virtual
58
methods instead of raising an exception.
60
def _capture_mouse(self):
62
def _release_mouse(self):
64
def _create_mouse_event(self, event):
66
def _redraw(self, *args, **kw):
68
def _get_control_size(self):
70
def _create_gc(self, *args, **kw):
72
def _window_paint(self, event):
74
def set_pointer(self, pointer):
76
def _set_timer_interval(self, component, interval):
80
def screen_to_window(self, x, y):
84
class EventTransformTestCase(EnableUnitTest):
86
def test_simple_container(self):
87
""" Tests event handling of nested containers """
88
comp = TestComponent(position=[50,50])
89
inner_container = TestContainer(bounds=[100.0, 100.0],
91
inner_container.add(comp)
92
outer_container = TestContainer(bounds=[200,200])
93
outer_container.add(inner_container)
95
event = BasicEvent(x=105, y=105)
96
outer_container.dispatch(event, "left_down")
98
self.assert_(comp.last_event.x == 55)
99
self.assert_(comp.last_event.y == 55)
100
self.assert_(inner_container.last_event.x == 105)
101
self.assert_(inner_container.last_event.y == 105)
104
def test_viewport_container(self):
105
""" Tests event handling of viewports (scaling and translation) """
106
comp = TestComponent(position=[20,20])
108
container = TestContainer(bounds=[100,100], position=[50,50])
111
viewport = Viewport(component=container, bounds=[400,400],
114
# Test unscaled event
115
event = BasicEvent(x=105, y=105)
116
viewport.dispatch(event, "left_down")
118
self.assert_(container.last_event.x == 75)
119
self.assert_(container.last_event.y == 75)
120
self.assert_(comp.last_event.x == 25)
121
self.assert_(comp.last_event.y == 25)
123
# Translate the viewport's view_position
124
container.last_event = None
125
comp.last_event = None
126
viewport.view_position = [-10,-10]
127
event = BasicEvent(x=115, y=115)
128
viewport.dispatch(event, "left_down")
130
self.assert_(container.last_event.x == 75)
131
self.assert_(container.last_event.y == 75)
132
self.assert_(comp.last_event.x == 25)
133
self.assert_(comp.last_event.y == 25)
136
container.last_event = None
137
comp.last_event = None
138
# Zoom in by a factor of 2, so view an area that is 200x200.
140
viewport.enable_zoom = True
141
viewport.view_position = [-50, -50]
142
viewport.view_bounds = [200, 200]
143
event = BasicEvent(x=280, y=280)
144
viewport.dispatch(event, "left_down")
146
self.assert_(container.last_event.x == 75)
147
self.assert_(container.last_event.y == 75)
148
self.assert_(comp.last_event.x == 25)
149
self.assert_(comp.last_event.y == 25)
152
def test_mouse_capture(self):
153
""" Tests saving the event's net_transform as well as the dispatch
154
history when capturing a mouse and dispatching subsequent events.
156
class MouseCapturingComponent(TestComponent):
157
captured_event_pos = Tuple
158
def normal_left_down(self, event):
159
self.captured_event_pos = (event.x, event.y)
160
event.window.set_mouse_owner(self, event.net_transform())
162
comp = MouseCapturingComponent(position=[20,20])
164
container = TestContainer(bounds=[100,100], position=[50,50])
167
viewport = Viewport(component=container, bounds=[400,400],
172
window = DummyWindow(_size=(500,500))
173
window.component = viewport
175
# Create the first event (to trigger the mouse capture)
176
event = BasicEvent(x=105, y=105, window=window)
177
window._handle_mouse_event("left_down", event)
179
self.assert_(window.mouse_owner == comp)
181
# Create the second event
182
event = BasicEvent(x=107, y=107, window=window)
183
old_pos = comp.captured_event_pos
184
window._handle_mouse_event("left_down", event)
185
new_pos = comp.captured_event_pos
186
self.assert_(new_pos[0] == old_pos[0] + 2)
187
self.assert_(new_pos[1] == old_pos[1] + 2)
192
if __name__ == "__main__":