| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148 |
- #!/usr/bin/env python
- from __future__ import division
- import gtk
- import cairo
- from math import radians
- from threading import Thread
- import src as mt
- def quit(*args):
- gtk.main_quit()
- class Rectangle(mt.RectangularWidget):
- def __init__(self, x, y, width, height, color=(1, 0, 0)):
- super(Rectangle, self).__init__(x, y, width, height)
- self.angle = 0
- self.scale = 1
- self.color = color
- def scale(self, angle):
- self.scale *= scale
- def rotate(self, angle):
- self.angle += angle
- def get_transformation_matrix(self):
- t = cairo.Matrix()
- t.translate(*self.get_position())
- t.rotate(self.angle)
- t.scale(self.scale, self.scale)
- return t
- def draw(self, cr):
- cr.transform(self.get_transformation_matrix())
- w, h = self.get_size()
- cr.rectangle(-w / 2, -h / 2, w, h)
- cr.set_source_rgb(*self.color)
- cr.fill()
- fullscreen = False
- W, H = mt.screen.screen_size
- def create_context_window(w, h, callback):
- def create_context(area, event):
- """Add Cairo context to GTK window and draw initial state."""
- global cr
- #if cr:
- # return
- cr = area.window.cairo_create()
- draw()
- def move_window(win, event):
- """Synchronize root multi-touch widget with GTK window."""
- root.set_position(*event.get_coords())
- root.set_size(event.width, event.height)
- draw()
- def handle_key(win, event):
- """Handle key event. 'f' toggles fullscreen, 'q' exits the program."""
- if event.keyval >= 256:
- return
- key = chr(event.keyval)
- if key == 'f':
- global fullscreen
- (win.unfullscreen if fullscreen else win.fullscreen)()
- fullscreen = not fullscreen
- elif key == 'q':
- quit()
- # Root widget (will be synchronized with GTK window)
- global root
- root = mt.RectangularWidget(0, 0, w, h)
- # GTK window
- win = gtk.Window()
- win.set_title('Cairo test')
- win.connect('destroy', quit)
- win.connect('key-press-event', handle_key)
- win.connect('configure-event', move_window)
- win.connect('show', callback)
- # Drawing area, needed by cairo context for drawing
- area = gtk.DrawingArea()
- area.set_size_request(w, h)
- area.connect('expose-event', create_context)
- win.add(area)
- area.show()
- win.show()
- def draw():
- # Background
- cr.rectangle(0, 0, *root.get_size())
- cr.set_source_rgb(0, 1, 0)
- cr.fill()
- # Drawable objects (use save and restore to allow transformations)
- for obj in draw_objects:
- #cr.save()
- obj.draw(cr)
- #cr.restore()
- # Initialization
- cr = root = None
- draw_objects = []
- def on_show(window):
- def root_dtap(g): print 'double tapped on root'
- root.on_double_tap(root_dtap)
- # Create blue rectangle
- rect = Rectangle(300, 200, 250, 150, color=(0, 0, 1))
- draw_objects.append(rect)
- root.add_widget(rect)
- def rect_tap(g): print 'tapped on rectangle'
- rect.on_tap(rect_tap, propagate_up_event=False)
- if __name__ == '__main__':
- # Parse arguments
- 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
- # syncronized with it
- create_context_window(640, 460, on_show)
- # Run multi-touch gesture server in separate thread
- server = mt.EventServer(root)
- mt_thread = Thread(target=server.start)
- mt_thread.daemon = True
- mt_thread.start()
- # Initialize threads in GTK so that the thread started above will work
- gtk.gdk.threads_init()
- # Start main loop in current thread
- gtk.main()
|