Commit a7a2067c authored by Taddeus Kroes's avatar Taddeus Kroes

Fixed offset positioning of events/areas.

parent 53c4d2ba
...@@ -8,9 +8,9 @@ from abc import ABCMeta, abstractmethod ...@@ -8,9 +8,9 @@ from abc import ABCMeta, abstractmethod
class Area(Positionable, Logger): class Area(Positionable, Logger):
""" """
Abstract class for area implementations. A area represents a 2D object Abstract class for area implementations. A area represents a 2D object on
on the screen in which gestures can occur. Handlers for a specific gesture the screen in which gestures can occur. Handlers for specific gesture types
type can be bound to a area. can be bound to a area.
""" """
__metaclass__ = ABCMeta __metaclass__ = ABCMeta
...@@ -36,34 +36,32 @@ class Area(Positionable, Logger): ...@@ -36,34 +36,32 @@ class Area(Positionable, Logger):
return self return self
def get_screen_offset(self): def get_screen_position(self):
""" """
Get the position relative to the screen. Get the position relative to the screen.
""" """
root = self.get_root_area() if not self.parent:
return root + self.get_offset(root) return self.get_position()
return self.get_position() + self.parent.get_screen_position()
def get_offset(self, offset_parent=None): def get_root_position(self):
""" """
Get the position relative to an offset parent. If no offset parent is Get the position relative to the root area.
specified, the position relative to the root area is returned. The
position of the root area itself is (0, 0).
""" """
if not offset_parent:
offset_parent = self.get_root_area()
if not self.parent: if not self.parent:
if offset_parent is self: return Positionable(0, 0)
return 0, 0
ox, oy = offset_paret return self.get_position() + self.parent.get_root_position()
x = y = 0
else:
ox, oy = offset_parent
x = self.x
y = self.y
return x - ox, y - oy def get_offset(self, offset_area):
"""
Get the position relative to an ancestor area.
"""
if self.parent == offset_area:
return self.get_position()
return self.get_position() + self.parent.get_offset(offset_area)
def add_area(self, area): def add_area(self, area):
""" """
...@@ -180,7 +178,7 @@ class Area(Positionable, Logger): ...@@ -180,7 +178,7 @@ class Area(Positionable, Logger):
child_found = False child_found = False
if self.children: if self.children:
event.set_offset(self.get_offset()) event.set_area(self)
# Delegate to children in reverse order because areas that are # Delegate to children in reverse order because areas that are
# added later, should be placed over previously added siblings # added later, should be placed over previously added siblings
...@@ -196,11 +194,18 @@ class Area(Positionable, Logger): ...@@ -196,11 +194,18 @@ class Area(Positionable, Logger):
self.propagate_event(event) self.propagate_event(event)
def propagate_event(self, event): def propagate_event(self, event):
"""
Delagate an event to all gesture trackers (immediate propagation), then
propagate it to the parent area (if any). Propagation can be stopped by
a tracker.
"""
event.set_area(self)
for tracker in self.trackers: for tracker in self.trackers:
tracker.handle_event(event) tracker.handle_event(event)
if event.is_immediate_propagation_stopped(): if event.is_immediate_propagation_stopped():
break return
if self.parent and not event.is_propagation_stopped(): if self.parent and not event.is_propagation_stopped():
self.parent.propagate_event(event) self.parent.propagate_event(event)
......
...@@ -22,7 +22,7 @@ class EventDriver(Logger): ...@@ -22,7 +22,7 @@ class EventDriver(Logger):
area tree. area tree.
""" """
if self.root_area.contains_event(event): if self.root_area.contains_event(event):
event.set_root_area(self.root_area) event.set_area(self.root_area)
self.root_area.delegate_event(event) self.root_area.delegate_event(event)
def start(self): def start(self):
......
...@@ -16,7 +16,7 @@ class Event(Positionable): ...@@ -16,7 +16,7 @@ class Event(Positionable):
super(Event, self).__init__(*touch_object) super(Event, self).__init__(*touch_object)
self.touch_object = touch_object self.touch_object = touch_object
self.stopped = self.stopped_immidiate = False self.stopped = self.stopped_immidiate = False
self.offset = Positionable(0, 0) self.area = None
def __getattr__(self, name): def __getattr__(self, name):
if name in OBJECT_NAMES \ if name in OBJECT_NAMES \
...@@ -26,16 +26,21 @@ class Event(Positionable): ...@@ -26,16 +26,21 @@ class Event(Positionable):
raise AttributeError("'%s' object has no attribute '%s'" raise AttributeError("'%s' object has no attribute '%s'"
% (self.__class__.__name__, name)) % (self.__class__.__name__, name))
def get_offset(self): def set_area(self, area):
return self - self.offset self.area = area
def set_offset(self, offset): def get_area(self):
self.offset.set_position(*offset) return self.area
def set_root_area(self, area): def get_root_position(self):
x, y = area return self.get_offset(self.area.get_root_area())
self.x -= x
self.y -= y def get_position(self):
return self.get_offset(self.area)
def get_offset(self, area):
ox, oy = area.get_screen_position()
return Positionable(self.x - ox, self.y - oy)
def get_type(self): def get_type(self):
return self._type return self._type
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment