--- /dev/null
+#!/usr/bin/env python
+
+# An example of an animation done with cairo and Gtk+
+#
+# Copyright (C) 2013 Antonio Ospite <ospite@studenti.unina.it>
+#
+# This program is free software: you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+# References:
+# http://wiki.laptop.org/go/PyGTK/Smooth_Animation_with_PyGTK
+
+import gi
+
+gi.require_version('Gtk', '3.0')
+from gi.repository import Gtk, GObject, Gio
+
+import math
+import colorsys
+
+
+class AnimatedCanvas(Gtk.DrawingArea):
+ def __init__(self, width, height, *args, **kwargs):
+ super(AnimatedCanvas, self).__init__(*args, **kwargs)
+
+ self.width = width
+ self.height = height
+
+ self.x_offset = 2
+ self.y_offset = 3
+ self.radius = 10
+ self.border = 4
+
+ self.x = self.radius + self.border
+ self.y = self.radius + self.border
+
+ self.set_size_request(width, height)
+ self.connect('draw', self.do_draw_cb)
+ self.connect('configure-event', self.do_configure_event_cb)
+
+ fps = 30
+ GObject.timeout_add(1000 / fps, self.update)
+
+ def update(self):
+ if self.x - self.radius - self.border < 0 or \
+ self.x + self.radius + self.border > self.width:
+ self.x_offset *= -1
+
+ if self.y - self.radius - self.border < 0 or \
+ self.y + self.radius + self.border > self.height:
+ self.y_offset *= -1
+
+ self.x += self.x_offset
+ self.y += self.y_offset
+
+ self.queue_draw()
+ return True
+
+ def do_configure_event_cb(self, widget, event):
+ self.width = event.width
+ self.height = event.height
+
+ def do_draw_cb(self, widget, cr):
+
+ cr.rectangle(0, 0, self.width, self.height)
+ cr.set_source_rgb(1.0, 0.5, 0.5)
+ cr.fill()
+
+ cr.arc(self.x, self.y, self.radius, 0, 2 * math.pi)
+
+ cr.set_line_width(self.border)
+
+ _h = self.x / float(self.width)
+ _l = 0.5
+ _s = self.y / float(self.height)
+ _r, _g, _b = colorsys.hls_to_rgb(_h, _l, _s)
+ cr.set_source_rgb(_r, _g, _b)
+ cr.fill_preserve()
+
+ cr.set_source_rgb(0, 0, 0)
+ cr.stroke()
+
+
+class AnimatedApp(Gtk.Application):
+ def __init__(self, title, width, height, *args, **kwargs):
+ super(AnimatedApp, self).__init__(*args, **kwargs)
+ self.connect("activate", self.on_activate)
+ self.title = title
+ self.width = width
+ self.height = height
+
+ def on_activate(self, data=None):
+ window = Gtk.Window(type=Gtk.WindowType.TOPLEVEL)
+ window.set_title(self.title)
+
+ canvas = AnimatedCanvas(self.width, self.height)
+ window.add(canvas)
+ window.show_all()
+ self.add_window(window)
+
+
+if __name__ == "__main__":
+ app = AnimatedApp("AnimatedApp", 640, 480,
+ application_id="apps.test.animatedapp",
+ flags=Gio.ApplicationFlags.FLAGS_NONE)
+ app.run(None)