ソースを参照

Added a test program that uses GTK with Cairo to draw widgets and tests event propagation.

Taddeus Kroes 13 年 前
コミット
d78ee60af0
1 ファイル変更148 行追加0 行削除
  1. 148 0
      tests/cairotest.py

+ 148 - 0
tests/cairotest.py

@@ -0,0 +1,148 @@
+#!/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()