Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
M
multitouch
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Taddeüs Kroes
multitouch
Commits
1fb84754
Commit
1fb84754
authored
Jun 16, 2012
by
UVA Multi-touch
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Changed occurences of 'widget' to 'area' in code.
parent
c476b2ba
Changes
14
Hide whitespace changes
Inline
Side-by-side
Showing
14 changed files
with
100 additions
and
100 deletions
+100
-100
src/__init__.py
src/__init__.py
+1
-1
src/area.py
src/area.py
+31
-31
src/areas.py
src/areas.py
+13
-13
src/event.py
src/event.py
+3
-3
src/event_driver.py
src/event_driver.py
+1
-1
src/event_server.py
src/event_server.py
+15
-15
src/tracker.py
src/tracker.py
+4
-4
src/trackers/tap.py
src/trackers/tap.py
+4
-4
src/trackers/transform.py
src/trackers/transform.py
+3
-3
tests/basic.py
tests/basic.py
+3
-3
tests/cairotest.py
tests/cairotest.py
+6
-6
tests/draw.py
tests/draw.py
+10
-10
tests/tap.py
tests/tap.py
+3
-3
tests/transform.py
tests/transform.py
+3
-3
No files found.
src/__init__.py
View file @
1fb84754
from
logger
import
Logger
from
tracker
import
GestureTracker
,
Gesture
from
event_server
import
EventServer
from
widget
s
import
*
from
area
s
import
*
src/
widget
.py
→
src/
area
.py
View file @
1fb84754
...
...
@@ -6,11 +6,11 @@ from trackers import create_tracker
from
abc
import
ABCMeta
,
abstractmethod
class
Widget
(
Positionable
,
Logger
):
class
Area
(
Positionable
,
Logger
):
"""
Abstract class for
widget implementations. A widget
represents a 2D object
Abstract class for
area implementations. A area
represents a 2D object
on the screen in which gestures can occur. Handlers for a specific gesture
type can be bound to a
widget
.
type can be bound to a
area
.
"""
__metaclass__
=
ABCMeta
...
...
@@ -23,16 +23,16 @@ class Widget(Positionable, Logger):
# Map of gesture types to a list of handlers for that type
self
.
handlers
=
{}
#
Widget
tree references
#
Area
tree references
self
.
parent
=
None
self
.
children
=
[]
def
get_root_
widget
(
self
):
def
get_root_
area
(
self
):
"""
Traverse up in the
widget tree to find the root widget
.
Traverse up in the
area tree to find the root area
.
"""
if
self
.
parent
:
return
self
.
parent
.
get_root_
widget
()
return
self
.
parent
.
get_root_
area
()
return
self
...
...
@@ -40,17 +40,17 @@ class Widget(Positionable, Logger):
"""
Get the position relative to the screen.
"""
root
=
self
.
get_root_
widget
()
root
=
self
.
get_root_
area
()
return
root
+
self
.
get_offset
(
root
)
def
get_offset
(
self
,
offset_parent
=
None
):
"""
Get the position relative to an offset parent. If no offset parent is
specified, the position relative to the root
widget
is returned. The
position of the root
widget
itself is (0, 0).
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_
widget
()
offset_parent
=
self
.
get_root_
area
()
if
not
self
.
parent
:
if
offset_parent
is
self
:
...
...
@@ -65,29 +65,29 @@ class Widget(Positionable, Logger):
return
x
-
ox
,
y
-
oy
def
add_
widget
(
self
,
widget
):
def
add_
area
(
self
,
area
):
"""
Add a new child
widget
.
Add a new child
area
.
"""
self
.
children
.
append
(
widget
)
widget
.
set_parent
(
self
)
self
.
children
.
append
(
area
)
area
.
set_parent
(
self
)
def
remove_
widget
(
self
,
widget
):
def
remove_
area
(
self
,
area
):
"""
Remove a child
widget
.
Remove a child
area
.
"""
self
.
children
.
remove
(
widget
)
widget
.
set_parent
(
None
)
self
.
children
.
remove
(
area
)
area
.
set_parent
(
None
)
def
set_parent
(
self
,
widget
):
def
set_parent
(
self
,
area
):
"""
Set a new parent
widget. If a parent widget
has already been assigned,
remove the
widget
from that parent first.
Set a new parent
area. If a parent area
has already been assigned,
remove the
area
from that parent first.
"""
if
widget
and
self
.
parent
:
self
.
parent
.
remove_
widget
(
self
)
if
area
and
self
.
parent
:
self
.
parent
.
remove_
area
(
self
)
self
.
parent
=
widget
self
.
parent
=
area
def
unbind
(
self
,
gesture_type
,
handler
=
None
):
"""
...
...
@@ -154,9 +154,9 @@ class Widget(Positionable, Logger):
def
__getattr__
(
self
,
name
):
"""
Allow calls like:
widget
.on_gesture(...)
area
.on_gesture(...)
instead of:
widget
.bind('gesture', ...)
area
.bind('gesture', ...)
"""
if
len
(
name
)
<
4
or
name
[:
3
]
!=
'on_'
:
raise
AttributeError
(
"'%s' has no attribute '%s'"
...
...
@@ -167,14 +167,14 @@ class Widget(Positionable, Logger):
@
abstractmethod
def
contains_event
(
self
,
event
):
"""
Check if the coordinates of an event are contained within this
widget
.
Check if the coordinates of an event are contained within this
area
.
"""
raise
NotImplementedError
def
delegate_event
(
self
,
event
):
"""
Delegate a triggered event to all child
widget
s. If a child stops
propagation, return so that its siblings and the parent
widget
will not
Delegate a triggered event to all child
area
s. If a child stops
propagation, return so that its siblings and the parent
area
will not
delegate the event to their trackers.
"""
child_found
=
False
...
...
@@ -182,7 +182,7 @@ class Widget(Positionable, Logger):
if
self
.
children
:
event
.
set_offset
(
self
.
get_offset
())
# Delegate to children in reverse order because
widget
s that are
# Delegate to children in reverse order because
area
s that are
# added later, should be placed over previously added siblings
for
child
in
reversed
(
self
.
children
):
if
child
.
contains_event
(
event
):
...
...
src/
widget
s.py
→
src/
area
s.py
View file @
1fb84754
from
widget
import
Widget
from
area
import
Area
from
screen
import
screen_size
__all__
=
[
'Rectangular
Widget'
,
'CircularWidget'
,
'FullscreenWidget
'
]
__all__
=
[
'Rectangular
Area'
,
'CircularArea'
,
'FullscreenArea
'
]
class
Rectangular
Widget
(
Widget
):
class
Rectangular
Area
(
Area
):
"""
Rectangular
widget
, has a position and a size.
Rectangular
area
, has a position and a size.
"""
def
__init__
(
self
,
x
,
y
,
width
,
height
):
super
(
Rectangular
Widget
,
self
).
__init__
(
x
,
y
)
super
(
Rectangular
Area
,
self
).
__init__
(
x
,
y
)
self
.
set_size
(
width
,
height
)
def
__str__
(
self
):
...
...
@@ -31,12 +31,12 @@ class RectangularWidget(Widget):
and
self
.
y
<=
y
<=
self
.
y
+
self
.
height
class
Circular
Widget
(
Widget
):
class
Circular
Area
(
Area
):
"""
Circular
widget
, has a position and a radius.
Circular
area
, has a position and a radius.
"""
def
__init__
(
self
,
x
,
y
,
radius
):
super
(
Circular
Widget
,
self
).
__init__
(
x
,
y
)
super
(
Circular
Area
,
self
).
__init__
(
x
,
y
)
self
.
set_radius
(
radius
)
def
__str__
(
self
):
...
...
@@ -54,16 +54,16 @@ class CircularWidget(Widget):
return
event
.
distance_to
(
self
)
<=
self
.
radius
class
Fullscreen
Widget
(
RectangularWidget
):
class
Fullscreen
Area
(
RectangularArea
):
"""
Widget
representation for the entire screen. This class provides an easy
way to create a single rectangular
widget
that catches all gestures.
Area
representation for the entire screen. This class provides an easy
way to create a single rectangular
area
that catches all gestures.
"""
def
__init__
(
self
):
super
(
Fullscreen
Widget
,
self
).
__init__
(
0
,
0
,
*
screen_size
)
super
(
Fullscreen
Area
,
self
).
__init__
(
0
,
0
,
*
screen_size
)
def
__str__
(
self
):
return
'<Fullscreen
Widget
size=(%d, %d)>'
%
self
.
get_size
()
return
'<Fullscreen
Area
size=(%d, %d)>'
%
self
.
get_size
()
def
contains_event
(
self
,
event
):
return
True
src/event.py
View file @
1fb84754
...
...
@@ -6,7 +6,7 @@ class Event(Positionable):
"""
Abstract base class for events triggered by an event driver. These events
are delegated to gesture trackers, to be translated to gestures. To be able
to check whether an event is located within a
widget
, a position is
to check whether an event is located within a
area
, a position is
required. Therefore, the touch object that triggers the event is is linked
to the event object.
"""
...
...
@@ -32,8 +32,8 @@ class Event(Positionable):
def
set_offset
(
self
,
offset
):
self
.
offset
.
set_position
(
*
offset
)
def
set_root_
widget
(
self
,
widget
):
x
,
y
=
widget
def
set_root_
area
(
self
,
area
):
x
,
y
=
area
self
.
x
-=
x
self
.
y
-=
y
...
...
src/event_driver.py
View file @
1fb84754
...
...
@@ -7,7 +7,7 @@ class EventDriver(Logger):
messages to a common set of events. The minimal set is {point_down,
point_move, point_up}. A driver implementation should define the methods
'start' and 'stop', which starts/stops some event loop that triggers the
'delegate_event' method of a
widget
.
'delegate_event' method of a
area
.
"""
def
__init__
(
self
,
event_server
):
self
.
event_server
=
event_server
...
...
src/event_server.py
View file @
1fb84754
...
...
@@ -5,37 +5,37 @@ from drivers import select_driver
class
EventServer
(
Logger
):
"""
The event server uses an event driver to receive events, which are
delegated to a
widget
tree (and eventually to gesture trackers).
delegated to a
area
tree (and eventually to gesture trackers).
"""
def
__init__
(
self
,
root_
widget
=
None
):
# Root
widget
to which events are delegated
self
.
root_
widget
=
root_widget
def
__init__
(
self
,
root_
area
=
None
):
# Root
area
to which events are delegated
self
.
root_
area
=
root_area
# Driver implementation that will be serving events
self
.
event_driver
=
select_driver
(
self
)
def
get_root_
widget
(
self
):
return
self
.
root_
widget
def
get_root_
area
(
self
):
return
self
.
root_
area
def
set_root_
widget
(
self
,
widget
):
self
.
root_
widget
=
widget
def
set_root_
area
(
self
,
area
):
self
.
root_
area
=
area
def
delegate_event
(
self
,
event
):
"""
Delegate an event that has been triggered by the event driver to the
widget
tree.
area
tree.
"""
if
self
.
root_
widget
.
contains_event
(
event
):
event
.
set_root_
widget
(
self
.
root_widget
)
self
.
root_
widget
.
delegate_event
(
event
)
if
self
.
root_
area
.
contains_event
(
event
):
event
.
set_root_
area
(
self
.
root_area
)
self
.
root_
area
.
delegate_event
(
event
)
def
start
(
self
):
"""
Start the event loop. A root
widget
is needed to be able to delegate
Start the event loop. A root
area
is needed to be able to delegate
events, so check if it exists first.
"""
if
not
self
.
root_
widget
:
raise
ValueError
(
'Cannot start event server without root
widget
.'
)
if
not
self
.
root_
area
:
raise
ValueError
(
'Cannot start event server without root
area
.'
)
self
.
event_driver
.
start
()
...
...
src/tracker.py
View file @
1fb84754
...
...
@@ -15,12 +15,12 @@ class GestureTracker(Logger):
# Configurable properties (see configure() method)
configurable
=
[]
def
__init__
(
self
,
widget
):
self
.
widget
=
widget
def
__init__
(
self
,
area
):
self
.
area
=
area
def
handle_event
(
self
,
event
):
"""
Handle an event that was delegated by a
widget
. The tracker
Handle an event that was delegated by a
area
. The tracker
implementation should define a handler function for the event.
Otherwise, the event will be ignored.
"""
...
...
@@ -32,7 +32,7 @@ class GestureTracker(Logger):
def
trigger
(
self
,
gesture
):
gesture
.
set_tracker
(
self
)
self
.
info
(
'Triggered %s.'
%
gesture
)
self
.
widget
.
handle_gesture
(
gesture
)
self
.
area
.
handle_gesture
(
gesture
)
def
configure
(
self
,
**
kwargs
):
for
name
,
value
in
kwargs
.
iteritems
():
...
...
src/trackers/tap.py
View file @
1fb84754
...
...
@@ -36,8 +36,8 @@ class TapTracker(GestureTracker):
configurable
=
[
'tap_distance'
,
'tap_time'
,
'double_tap_time'
,
'double_tap_distance'
,
'update_rate'
,
'propagate_up_event'
]
def
__init__
(
self
,
widget
):
super
(
TapTracker
,
self
).
__init__
(
widget
)
def
__init__
(
self
,
area
):
super
(
TapTracker
,
self
).
__init__
(
area
)
# Map of touch object id to tuple (timestamp, position) of point down
self
.
reg
=
{}
...
...
@@ -57,8 +57,8 @@ class TapTracker(GestureTracker):
# Times per second to detect single taps
self
.
update_rate
=
30
# Whether to stop propagation of the 'point_up' event to parent
widget
s
# If False, this reserves tap events to child
widget
s
# Whether to stop propagation of the 'point_up' event to parent
area
s
# If False, this reserves tap events to child
area
s
self
.
propagate_up_event
=
True
self
.
reset_last_tap
()
...
...
src/trackers/transform.py
View file @
1fb84754
...
...
@@ -73,8 +73,8 @@ class TransformationTracker(GestureTracker):
"""
supported_gestures
=
[
RotationGesture
,
PinchGesture
,
DragGesture
]
def
__init__
(
self
,
widget
):
super
(
TransformationTracker
,
self
).
__init__
(
widget
)
def
__init__
(
self
,
area
):
super
(
TransformationTracker
,
self
).
__init__
(
area
)
# All touch points performing the transformation
self
.
points
=
[]
...
...
@@ -102,7 +102,7 @@ class TransformationTracker(GestureTracker):
else
:
self
.
centroid
=
MovingPositionable
(
x
,
y
)
#wx, wy = self.
widget
.get_screen_offset()
#wx, wy = self.
area
.get_screen_offset()
#self.centroid.translate(-wx, -wy)
def
on_point_down
(
self
,
event
):
...
...
tests/basic.py
View file @
1fb84754
from
src.event_server
import
EventServer
from
src.
widgets
import
FullscreenWidget
from
src.
areas
import
FullscreenArea
from
tests.parse_arguments
import
create_parser
,
parse_args
parse_args
(
create_parser
())
# Create server and fullscreen
widget
screen
=
Fullscreen
Widget
()
# Create server and fullscreen
area
screen
=
Fullscreen
Area
()
server
=
EventServer
(
screen
)
# Bind handlers
...
...
tests/cairotest.py
View file @
1fb84754
...
...
@@ -12,7 +12,7 @@ def quit(*args):
gtk
.
main_quit
()
class
Rectangle
(
mt
.
Rectangular
Widget
):
class
Rectangle
(
mt
.
Rectangular
Area
):
def
__init__
(
self
,
x
,
y
,
width
,
height
,
color
=
(
1
,
0
,
0
)):
super
(
Rectangle
,
self
).
__init__
(
x
,
y
,
width
,
height
)
self
.
angle
=
1.0
...
...
@@ -72,7 +72,7 @@ def create_context_window(w, h, callback):
draw
()
def
move_window
(
win
,
event
):
"""Synchronize root multi-touch
widget
with GTK window."""
"""Synchronize root multi-touch
area
with GTK window."""
root
.
set_position
(
*
event
.
get_coords
())
root
.
set_size
(
event
.
width
,
event
.
height
)
draw
()
...
...
@@ -91,9 +91,9 @@ def create_context_window(w, h, callback):
elif
key
==
'q'
:
quit
()
# Root
widget
(will be synchronized with GTK window)
# Root
area
(will be synchronized with GTK window)
global
root
root
=
mt
.
Rectangular
Widget
(
0
,
0
,
w
,
h
)
root
=
mt
.
Rectangular
Area
(
0
,
0
,
w
,
h
)
# GTK window
global
window
...
...
@@ -146,7 +146,7 @@ def on_show(window):
# Create blue rectangle
rect
=
Rectangle
(
300
,
200
,
250
,
150
,
color
=
(
0
,
0
,
1
))
draw_objects
.
append
(
rect
)
root
.
add_
widget
(
rect
)
root
.
add_
area
(
rect
)
def
rect_tap
(
g
):
print
'tapped on rectangle'
rect
.
on_tap
(
rect_tap
,
propagate_up_event
=
False
)
...
...
@@ -157,7 +157,7 @@ if __name__ == '__main__':
from
tests.parse_arguments
import
create_parser
,
parse_args
parse_args
(
create_parser
())
# Create a window with a Cairo context in it and a multi-touch
widget
# Create a window with a Cairo context in it and a multi-touch
area
# syncronized with it
create_context_window
(
640
,
460
,
on_show
)
...
...
tests/draw.py
View file @
1fb84754
...
...
@@ -5,7 +5,7 @@ from threading import Thread
from
math
import
degrees
from
src.event_server
import
EventServer
from
src.
widgets
import
FullscreenWidget
from
src.
areas
import
FullscreenArea
from
tests.parse_arguments
import
create_parser
,
parse_args
from
src.screen
import
screen_size
...
...
@@ -146,17 +146,17 @@ def pinch(gesture):
save_tracker
(
gesture
)
widget
=
FullscreenWidget
()
server
=
EventServer
(
widget
)
widget
.
on_rotate
(
rotate
)
widget
.
on_pinch
(
pinch
)
area
=
FullscreenArea
()
server
=
EventServer
(
area
)
area
.
on_rotate
(
rotate
)
area
.
on_pinch
(
pinch
)
widget
.
on_tap
(
lambda
g
:
taps
.
append
([
coord
(
*
g
),
FINGER_RADIUS
]))
widget
.
on_single_tap
(
lambda
g
:
dtaps
.
append
(
list
(
coord
(
*
g
))
+
[
1
]))
widget
.
on_double_tap
(
lambda
g
:
dtaps
.
append
(
list
(
coord
(
*
g
))
+
[
0
]))
area
.
on_tap
(
lambda
g
:
taps
.
append
([
coord
(
*
g
),
FINGER_RADIUS
]))
area
.
on_single_tap
(
lambda
g
:
dtaps
.
append
(
list
(
coord
(
*
g
))
+
[
1
]))
area
.
on_double_tap
(
lambda
g
:
dtaps
.
append
(
list
(
coord
(
*
g
))
+
[
0
]))
widget
.
on_point_down
(
lambda
g
:
points
.
append
(
g
.
get_event
().
point
))
widget
.
on_point_up
(
lambda
g
:
points
.
remove
(
g
.
get_event
().
point
))
area
.
on_point_down
(
lambda
g
:
points
.
append
(
g
.
get_event
().
point
))
area
.
on_point_up
(
lambda
g
:
points
.
remove
(
g
.
get_event
().
point
))
try
:
...
...
tests/tap.py
View file @
1fb84754
from
src.event_server
import
EventServer
from
src.
widgets
import
FullscreenWidget
from
src.
areas
import
FullscreenArea
from
tests.parse_arguments
import
create_parser
,
parse_args
parse_args
(
create_parser
())
# Create server and fullscreen
widget
screen
=
Fullscreen
Widget
()
# Create server and fullscreen
area
screen
=
Fullscreen
Area
()
server
=
EventServer
(
screen
)
# Bind handlers
...
...
tests/transform.py
View file @
1fb84754
from
src.event_server
import
EventServer
from
src.
widgets
import
FullscreenWidget
from
src.
areas
import
FullscreenArea
from
tests.parse_arguments
import
create_parser
,
parse_args
parse_args
(
create_parser
())
# Create server and fullscreen
widget
screen
=
Fullscreen
Widget
()
# Create server and fullscreen
area
screen
=
Fullscreen
Area
()
server
=
EventServer
(
screen
)
# Bind handlers
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment