Implement basic animation

master
Marco Pesenti Gritti 18 years ago
parent a292b642e1
commit 1e3af85c40

@ -1,4 +1,5 @@
#!/usr/bin/python #!/usr/bin/python
import math
import pygtk import pygtk
pygtk.require('2.0') pygtk.require('2.0')
@ -8,10 +9,24 @@ from sugar.scene.Stage import Stage
from sugar.scene.Group import Group from sugar.scene.Group import Group
from sugar.scene.PixbufActor import PixbufActor from sugar.scene.PixbufActor import PixbufActor
from sugar.scene.CircleLayout import CircleLayout from sugar.scene.CircleLayout import CircleLayout
from sugar.scene.Timeline import Timeline
def drawing_area_expose_cb(widget, event, stage): def __drawing_area_expose_cb(widget, event, stage):
stage.render(widget.window) stage.render(widget.window)
def __next_frame_cb(timeline, frame_num, group):
angle = math.pi * 2 / timeline.get_n_frames() * frame_num
group.get_layout().set_angle(angle)
group.do_layout()
drawing_area.window.invalidate_rect(None, False)
def __completed_cb(timeline, group):
group.get_layout().set_angle(0)
group.do_layout()
drawing_area.window.invalidate_rect(None, False)
stage = Stage() stage = Stage()
pixbuf = gtk.gdk.pixbuf_new_from_file('background.png') pixbuf = gtk.gdk.pixbuf_new_from_file('background.png')
@ -26,7 +41,7 @@ while i <= 5:
i += 1 i += 1
layout = CircleLayout(100) layout = CircleLayout(100)
icons_group.set_layout_manager(layout) icons_group.set_layout(layout)
stage.add(icons_group) stage.add(icons_group)
@ -34,10 +49,15 @@ window = gtk.Window()
window.set_default_size(640, 480) window.set_default_size(640, 480)
drawing_area = gtk.DrawingArea() drawing_area = gtk.DrawingArea()
drawing_area.connect('expose_event', drawing_area_expose_cb, stage) drawing_area.connect('expose_event', __drawing_area_expose_cb, stage)
window.add(drawing_area) window.add(drawing_area)
drawing_area.show() drawing_area.show()
window.show() window.show()
timeline = Timeline(stage, 100)
timeline.connect('next-frame', __next_frame_cb, icons_group)
timeline.connect('completed', __completed_cb, icons_group)
timeline.start()
gtk.main() gtk.main()

@ -7,13 +7,17 @@ class CircleLayout(LayoutManager):
LayoutManager.__init__(self) LayoutManager.__init__(self)
self._radium = radium self._radium = radium
self._angle = 0
def set_angle(self, angle):
self._angle = angle
def layout_group(self, group): def layout_group(self, group):
step = 2 * math.pi / len(group.get_actors()) step = 2 * math.pi / len(group.get_actors())
angle = 2 * math.pi angle = self._angle
for actor in group.get_actors(): for actor in group.get_actors():
self._update_position(actor, angle) self._update_position(actor, angle)
angle -= step angle += step
def _update_position(self, actor, angle): def _update_position(self, actor, angle):
x = math.cos(angle) * self._radium + self._radium x = math.cos(angle) * self._radium + self._radium

@ -3,24 +3,29 @@ from sugar.scene.Actor import Actor
class Group(Actor): class Group(Actor):
def __init__(self): def __init__(self):
self._actors = [] self._actors = []
self._layout_manager = None self._layout = None
def add(self, actor): def add(self, actor):
self._actors.append(actor) self._actors.append(actor)
if self._layout_manager: self.do_layout()
self._layout_manager.layout_group(slef)
def remove(self, actor): def remove(self, actor):
self._actors.remove(actor) self._actors.remove(actor)
if self._layout_manager: self.do_layout()
self._layout_manager.layout_group(self)
def get_actors(self): def get_actors(self):
return self._actors return self._actors
def set_layout_manager(self, layout_manager): def set_layout(self, layout):
self._layout_manager = layout_manager self._layout = layout
self._layout_manager.layout_group(self) self.do_layout()
def get_layout(self):
return self._layout
def do_layout(self):
if self._layout:
self._layout.layout_group(self)
def render(self, drawable): def render(self, drawable):
for actor in self._actors: for actor in self._actors:

@ -3,3 +3,7 @@ from sugar.scene.Group import Group
class Stage(Group): class Stage(Group):
def __init__(self): def __init__(self):
Group.__init__(self) Group.__init__(self)
self._fps = 50
def get_fps(self):
return self._fps

@ -0,0 +1,33 @@
import gobject
class Timeline(gobject.GObject):
__gsignals__ = {
'next-frame': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([int])),
'completed': (gobject.SIGNAL_RUN_FIRST, gobject.TYPE_NONE, ([]))
}
def __init__(self, stage, n_frames):
gobject.GObject.__init__(self)
self._stage = stage
self._fps = stage.get_fps()
self._n_frames = n_frames
self._current_frame = 0
def start(self):
gobject.timeout_add(1000 / self._fps, self.__timeout_cb)
def get_n_frames(self):
return self._n_frames
def __timeout_cb(self):
self.emit('next-frame', self._current_frame)
# FIXME skip frames if necessary
self._current_frame += 1
if self._current_frame < self._n_frames:
return True
else:
self.emit('completed')
return False
Loading…
Cancel
Save