Update of /cvsroot/freevo/freevo/src/animation
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1556/animation

Added Files:
        .cvsignore __init__.py base.py marquee.py render.py 
        screensaver.py transition.py 
Log Message:
Added support for animations. Most of the code is from Viggo Fredriksen


--- NEW FILE: .cvsignore ---
*.pyc *.pyo

--- NEW FILE: transition.py ---
#if 0 /*
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------
# transition.py - A transition animation, intended use: imageviewer
# Author: Viggo Fredriksen <[EMAIL PROTECTED]>
# -----------------------------------------------------------------------
# $Id: transition.py,v 1.1 2004/04/25 11:23:58 dischi Exp $
#
# Notes:
# Todo:        
#
# -----------------------------------------------------------------------
# $Log: transition.py,v $
# Revision 1.1  2004/04/25 11:23:58  dischi
# Added support for animations. Most of the code is from Viggo Fredriksen
#
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002 Krister Lagerstrom, et al. 
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# 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 2 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 MER-
# CHANTABILITY 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, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ----------------------------------------------------------------------- */
#endif

from base import BaseAnimation

import pygame, random

class Transition(BaseAnimation):
    """
    This class blends two surfaces.

    Targeted to be finished within 1 second
    """
    image        = None
    finished     = False  # flag for finished animation

    surf_blend1  = None
    surf_blend2  = None


    def __init__(self, surf1, surf2, mode=-1, direction='vertical', fps=25):
        """
        @surf1: Surface to blend with
        @surf2: New surface
        @mode: effect to use
        @direction: vertical/horizontal
        """

        BaseAnimation.__init__(self, surf1.get_rect(), fps, bg_update=False)

        self.steps     = fps
        self.mode      = mode
        self.direction = direction

        self.drawfuncs = { 0: self.draw_blend_alpha,
                           1: self.draw_wipe,
                           2: self.draw_wipe_alpha }

        self.surf_blend1 = surf1.convert()
        self.surf_blend2 = surf2.convert()

        self.prepare()


    def prepare(self):

        # random effect
        if self.mode == -1:
            start = self.drawfuncs.keys()[0]
            stop  = self.drawfuncs.keys()[(len(self.drawfuncs.keys())-1)]
            self.mode = random.randrange(start, stop, 1)

            self.direction = random.choice( ['vertical', 'horizontal'] )
            self.prepare()

        # blend alpha effect
        elif self.mode == 0:
            step_size = 255.0 / self.steps
            self.index_alpha  = 0
            self.blend_alphas = [int(x*step_size) for x in range(1, self.steps+1)]
            self.blend_alphas.append(255) # The last step must be 255

        # plain wipe effect
        elif self.mode == 1:
            self.offset_x = 0
            self.offset_y = 0

            self.surface.blit(self.surf_blend1, (0, 0))

            if self.direction == 'vertical':
                step = self.rect.height / self.steps
                self.step_x = 0
                self.step_y = step
            else:
                step = self.rect.width / self.steps
                self.step_x = step
                self.step_y = 0

        # alpha wipe effect
        elif self.mode == 2:
            self.line = 0
            self.size = self.surf_blend1.get_size()
            self.surf_blend2 = self.surf_blend2.convert_alpha()
            self.fade_rows = 10
            self.fade_factor = int(256/self.fade_rows)


    def draw(self):
        if self.finished:
            return

        self.drawfuncs[self.mode]()


    def draw_wipe(self):
        """
        Plain wipe
        """
        if self.offset_x > self.rect.width:
            self.offset_x = self.rect.width
            self.finished = True

        if self.offset_y > self.rect.height:
            self.offset_y = self.rect.height
            self.finished = True


        x = self.offset_x
        y = self.offset_y
        w = self.step_x
        h = self.step_y

        if w == 0:  w = self.rect.width
        if h == 0:  h = self.rect.height

        self.surface.blit(self.surf_blend2, (x, y), (x, y, w, h))

        self.offset_x += self.step_x
        self.offset_y += self.step_y


    def draw_wipe_alpha(self):
        """
        Alpha transition wipe

        This is _very_ slow atm.

        XXX not working!
        """

        if self.line > self.size[0] - 1:
            self.finished = True

        for i in range(0, (self.line + self.fade_rows)):
            # array with alphavals
            arr = pygame.surfarray.pixels_alpha(self.surf_blend2)

            #if (arr[i] <= self.fade_factor):
            #    arr[i] = 0
            #else:
            #arr[i] -= self.fade_factor

            #for j in range(0, (self.size[0]-1)):
            #    if (arr[j][i] <= self.fade_factor):
            #        arr[j][i] = 0
            #    else:
            #        arr[j][i] -= self.fade_factor
            """
            for i in range(0, self.fade_rows):

                # Bounds check...
                if((offset - i) < 0):
                    break
                if((offset - i) > self.size[1] - 1):
                    continue
                else:
                    for j in range(0, (self.size[0]-1)):
                        if (arr[j][offset-i] <= self.fade_factor):
                            arr[j][offset-i]=0
                        else:
                            arr[j][offset-i] -= self.fade_factor
            """
        del arr

        self.line += self.fade_rows

        self.surface.blit(self.surf_blend1, (0, 0))
        self.surface.blit(self.surf_blend2, (0, 0))


    def draw_blend_alpha(self):

        alpha = self.blend_alphas[self.index_alpha]

        self.surf_blend2.set_alpha(alpha)
        self.surface.blit(self.surf_blend1, (0, 0))
        self.surface.blit(self.surf_blend2, (0, 0))

        self.index_alpha += 1

        if self.index_alpha > len(self.blend_alphas) - 1:
            self.finished = True


--- NEW FILE: render.py ---
#if 0 /*
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------
# render.py - The render part of Freevo animation extensions
# Author: Viggo Fredriksen <[EMAIL PROTECTED]>
# -----------------------------------------------------------------------
# $Id: render.py,v 1.1 2004/04/25 11:23:58 dischi Exp $
#
# Notes:
# Todo:        
#  - Proper pausing of animations (should it still be drawn to screen?)
#  - What to do when an app like imageviewer takes the whole screen. Ex. the
#    detachbar needs to stop it's animation when this happens
#  - Update animations to support combinations of animation,
#    ex. slide the detachbar in and out of view
#  - Better handling of fps
#
# -----------------------------------------------------------------------
# $Log: render.py,v $
# Revision 1.1  2004/04/25 11:23:58  dischi
# Added support for animations. Most of the code is from Viggo Fredriksen
#
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002 Krister Lagerstrom, et al. 
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# 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 2 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 MER-
# CHANTABILITY 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, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ----------------------------------------------------------------------- */
#endif


# freevo modules
import osd, config, util

# pygame modules
import pygame.time

# python modules
from time      import sleep, time


_singleton = None

def get_singleton():
    global _singleton

    # don't start render for helper
    if config.HELPER:
        return

    # One-time init
    if _singleton == None:
        _singleton = util.SynchronizedObject(Render())

    return _singleton



class Render:
    """
    This class/interface handles updating animation sprites

    Problems:
      How to do everything correctly so we don't end up with garbled screens.
      Currently there's probably tons of problems with this.

    Notes:
      Perhaps we should utilize spritegroups for this, as it is supposed
      to be optimized for this kind of stuff - pluss we get alot of code
      for free. (ex. RenderUpdates). All animations objects would need to
      extend the pygame.sprite.Sprite object.
    """

    animations   = []    # all animations
    suspended    = []    # suspended animations
    osd          = None
    realtime     = False # update as fast as possible

    def __init__(self):
        # set the update handler to wait for osd
        self.update = self.update_wait


    def set_realtime(self, realtime=False):
        self.realtime = realtime


    def update_wait(self, timer=0):
        """
        This is used while starting freevo
        """
        if osd._singleton == None:
            return

        if self.osd == None:
            self.osd    = osd.get_singleton()
            self.update = self.update_enabled


    def update_enabled(self, timer=0):
        """
        This is the draw method for animations
        """
        render  = []
        add     = render.append
        remove  = self.animations.remove
        i = 0

        for a in self.animations:

            # XXX something should be done to clean up the mess
            if a.delete:
                self.animations.remove(a)
                continue

            if a.active:
                r = a.poll(timer)
                if r:
                    i += 1
                    add(r)
            # XXX something might be done to handle stopped animations
            else:
                pass

        # only invoke osd singleton if there are updates
        # since this is a potential time hog
        if len(render) > 0:
            rects = []
            for (rect, surf) in render:
                self.osd.putsurface(surf, rect.left, rect.top)
                rects.append(rect)

            if len(rects)>0:
                self.osd.update(rects)


    def damage(self, rects=[]):
        """
        This method invokes damages on animations.
        """
        for a in self.animations:
            if a.bg_redraw or a.bg_update:
                a.damage(rects)


    def kill(self, anim_object):
        """
        Kill an animation
        """

        try:
            i = self.animations.index(anim_object)
            self.animations[i].remove()
        except:
            pass


    def killall(self):
        """
        Kills all animations
        """
        for a in self.animations:
            a.remove()
        

    def suspendall(self):
        """
        Suspends all animations
        """
        for a in self.animations:
            if a.active:
                a.active = False
                self.suspended.append(a)


    def restartall(self):
        """
        Restarts all suspended animations
        """
        for a in self.suspended:
            a.active = True

        self.suspended = []


    def add_animation(self, anim_object):
        """
        Add an animation to our list
        """
        self.animations.append(anim_object)


--- NEW FILE: screensaver.py ---
#if 0 /*
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------
# screensaver.py - A screensaver animation
# Author: Viggo Fredriksen <[EMAIL PROTECTED]>
# -----------------------------------------------------------------------
# $Id: screensaver.py,v 1.1 2004/04/25 11:23:58 dischi Exp $
#
# Notes:
# Todo:        
#
# -----------------------------------------------------------------------
# $Log: screensaver.py,v $
# Revision 1.1  2004/04/25 11:23:58  dischi
# Added support for animations. Most of the code is from Viggo Fredriksen
#
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002 Krister Lagerstrom, et al. 
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# 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 2 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 MER-
# CHANTABILITY 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, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ----------------------------------------------------------------------- */
#endif

# freevo modules
from animation import BaseAnimation

class Screensaver(BaseAnimation):
    """
    This is _very_ simplistic. Feel free to add what you want
    """
    def __init__(self):
        BaseAnimation.__init__(self, self.get_osd().screen.get_rect(),
                               fps=5, bg_update=True, bg_redraw=True)

        self.overlay = self.get_surface(self.rect.width,
                                        self.rect.height).convert_alpha()
        self.overlay.fill(0x66000000)

    def draw(self):
        self.surface.blit(self.overlay, (0,0))


--- NEW FILE: marquee.py ---
#if 0 /*
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------
# marquee.py - A marquee animation, intended use: selected text
# Author: Viggo Fredriksen <[EMAIL PROTECTED]>
# -----------------------------------------------------------------------
# $Id: marquee.py,v 1.1 2004/04/25 11:23:58 dischi Exp $
#
# Notes:
# Todo:        
#
# -----------------------------------------------------------------------
# $Log: marquee.py,v $
# Revision 1.1  2004/04/25 11:23:58  dischi
# Added support for animations. Most of the code is from Viggo Fredriksen
#
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002 Krister Lagerstrom, et al. 
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# 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 2 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 MER-
# CHANTABILITY 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, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ----------------------------------------------------------------------- */
#endif


from base   import BaseAnimation
from pygame import Rect

class Marquee(BaseAnimation):
    """
    This class animates a surface like a marquee.

    Nothing fancy, just scrolls it back and forth, takes a pause
    when returning to ground zero. This is just intended as a demo
    for testing the rendering.
    """
    smoothfactor = 0.1
    image        = None


    def __init__(self, rectstyle, surface, step_x=1, fps=25, init_sleep=-1,
                 bg_update=True, bg_wait=False, bg_redraw=False):

        BaseAnimation.__init__(self, rectstyle, fps, bg_update, bg_wait, bg_redraw)

        self.image  = surface
        self.step_x = step_x

        self.w, self.h = surface.get_size()
        self.animrect  = Rect( (0, 0, self.rect.width, self.rect.height) )


    def draw(self):
        if self.w < self.rect.width:
            self.surface.blit(self.image, (0,0))
            return

        ### move and blit
        self.animrect.move_ip(int(self.step_x * self.smoothfactor), 0)
        self.surface.blit(self.image, (0,0), self.animrect)

        ### recalculate for next pass
        if self.smoothfactor < float(1):
            self.smoothfactor *= 1.1
            if self.smoothfactor > float(1):
                self.smoothfactor = 1


        # at bounds, change direction
        if self.animrect.right > self.w or self.animrect.left < 0:
            self.smoothfactor = 0.08
            if self.step_x < 0:
                self.animrect.left  = 0
                self.sleep = True
            else:
                self.animrect.right = self.w

            self.step_x = - self.step_x

--- NEW FILE: __init__.py ---
#if 0 /*
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------
# __init__.py - Animation support
# Author: Viggo Fredriksen <[EMAIL PROTECTED]>
# -----------------------------------------------------------------------
# $Id: __init__.py,v 1.1 2004/04/25 11:23:58 dischi Exp $
#
# Notes:
# Todo:        
#
# -----------------------------------------------------------------------
# $Log: __init__.py,v $
# Revision 1.1  2004/04/25 11:23:58  dischi
# Added support for animations. Most of the code is from Viggo Fredriksen
#
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002 Krister Lagerstrom, et al. 
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# 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 2 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 MER-
# CHANTABILITY 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, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ----------------------------------------------------------------------- */
#endif


from render     import *
from base       import *
from marquee    import *
from transition import *

--- NEW FILE: base.py ---
#if 0 /*
# -*- coding: iso-8859-1 -*-
# -----------------------------------------------------------------------
# base.py - The basic animation class for freevo
# Author: Viggo Fredriksen <[EMAIL PROTECTED]>
# -----------------------------------------------------------------------
# $Id: base.py,v 1.1 2004/04/25 11:23:58 dischi Exp $
#
# Notes:
# Todo:        
#
# -----------------------------------------------------------------------
# $Log: base.py,v $
# Revision 1.1  2004/04/25 11:23:58  dischi
# Added support for animations. Most of the code is from Viggo Fredriksen
#
#
# -----------------------------------------------------------------------
# Freevo - A Home Theater PC framework
# Copyright (C) 2002 Krister Lagerstrom, et al. 
# Please see the file freevo/Docs/CREDITS for a complete list of authors.
#
# 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 2 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 MER-
# CHANTABILITY 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, write to the Free Software Foundation, Inc.,
# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# ----------------------------------------------------------------------- */
#endif

from pygame import Rect, Surface, constants

import pygame.time
import osd, render

class BaseAnimation:
    """
    Base class for animations, this should perhaps be changed to use sprites
    in the future (if one decides to go with a RenderGroup model)

     @rectstyle  : the rectangle defining the position on the screen (pygame)
     @fps        : Desired fps
     @bg_update  : update the animation with background from screen
     @bg_wait    : initially wait for updated background before activating
     @bg_redraw  : set background to original screen bg when finished
    """

    background   = None   # Surface Background (screen)
    surface      = None   # The Surface obj. to work with
    active       = False  # Should it be updated in the poll
    delete       = False  # Delete from list on next poll
    updates      = []     # list of updates from screen
    next_update  = 0      # timestamp for next update


    def __init__(self, rectstyle, fps=20, bg_update=True,
                 bg_wait=False, bg_redraw=False):

        self.rect      = Rect(rectstyle)
        self.bg_update = bg_update
        self.bg_wait   = bg_wait
        self.bg_redraw = bg_redraw

        self.surface = Surface( (self.rect.width,
                                 self.rect.height)).convert()

        self.set_fps(fps)


    def get_surface(self, width, height):
        """
        Helper for creating surfaces
        """
        return Surface( (width, height), 0, 32)


    def get_osd(self):
        """
        Helper for getting osd singleton
        """
        return osd.get_singleton()


    def set_fps(self, fps):
        """
        Sets the desired fps
        """
        self.interval  = int(1000.0/float(fps))


    def set_screen_background(self):
        """
        Update the background
        """
        if not self.background:
            self.background = osd.get_singleton().getsurface(rect=self.rect)
            self.updates = []

        else:
            # check for damages done on osd.screen
            while len(self.updates) > 0:

                update = self.updates.pop()
                x      = update[0] - self.rect.left
                y      = update[1] - self.rect.top
                bg_tmp = osd.get_singleton().getsurface(rect=update)

                self.background.blit(bg_tmp, (x, y))

        self.surface.blit(self.background, (0,0))


    def get_rect(self):
        return self.rect


    def start(self):
        """
        Starts the animation
        """
        render.get_singleton().add_animation(self)
        if not self.bg_wait:
            self.active = True


    def stop(self):
        """
        Stops the animation from being polled
        """
        self.active = False


    def remove(self):
        """
        Flags the animation to be removed from the animation list
        """
        self.active = False

        # set the org. bg if we use this
        if self.bg_update:
            osd.get_singleton().putsurface(self.background,
                                           self.rect.left,
                                           self.rect.top)
            osd.get_singleton().update( [self.rect] )

        self.delete = True


    def damage(self, rectstyles=[]):
        """
        Checks if the screen background has been damaged

        Note:
            If the rect passed damages our rect, but no actual blit is done
            on osd.screen, we'll end up with a copy of our animation in our
            bg. This is BAD.
        """

        if not (self.bg_redraw or self.bg_update) or rectstyles == None:
            return

        for rect in rectstyles:
            if rect == None:
                continue

            if self.rect.colliderect(rect):
                if self.bg_wait:
                    self.active = True

                self.updates.append(self.rect.clip(rect))
                _debug_('Damaged, updating background')


    def poll(self, current_time):

        if self.next_update < current_time:
            self.next_update = current_time + self.interval

            if self.bg_update:
                self.set_screen_background()

            self.draw()
            return self.rect, self.surface


    def draw(self):
        """
        Overload to do stuff with the surface
        """
        pass





-------------------------------------------------------
This SF.net email is sponsored by: The Robotic Monkeys at ThinkGeek
For a limited time only, get FREE Ground shipping on all orders of $35
or more. Hurry up and shop folks, this offer expires April 30th!
http://www.thinkgeek.com/freeshipping/?cpg=12297
_______________________________________________
Freevo-cvslog mailing list
[EMAIL PROTECTED]
https://lists.sourceforge.net/lists/listinfo/freevo-cvslog

Reply via email to