Implement basic animation

This commit is contained in:
Marco Pesenti Gritti 2006-07-22 13:48:47 +02:00
parent a292b642e1
commit 1e3af85c40
5 changed files with 79 additions and 13 deletions

View File

@ -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()

View File

@ -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

View File

@ -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:

View File

@ -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

33
sugar/scene/Timeline.py Normal file
View File

@ -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