Beispiel #1
0
    def _changeFrame(self, frame):
        """Internal helper for setFrame() / animatedTransition();
        change self._frame and returns the differences between the
        current items and the new ones as (newGeometry, addItems,
        removeItems) tuple."""
        
        self._resetAnimation()
        self._frame = frame
        newGeometry = QtCore.QRectF(p(self.pos), frame.sizeF())

        addItems = {}
        removeItems = dict(self._items)

        for key, (layer, item) in self._frameItems(frame).iteritems():
            try:
                del removeItems[key]
            except KeyError:
                parentItem = self._contentItem(layer)
                item.setParentItem(parentItem)
                addItems[key] = (layer, item)

        return newGeometry, addItems, removeItems
Beispiel #2
0
    def _resetAnimation(self):
        if not self._animation:
            return

        self._animation.stop()

        self._removeItems(self._pendingRemove)

        # reset parent of all animated contents:
        for i in range(self._animation.animationCount()):
            anim = self._animation.animationAt(i)
            for item in p(anim.targetObject).childItems():
                parentItem = self._staticParents[item]
                # custom items are special, because they're just
                # moved/reparented/hidden, but not created on the fly:
                origParent = self._originalCustomItemState.get(item)
                if origParent:
                    item.setParentItem(origParent)
                else:
                    item.setParentItem(parentItem)

        self._animation = None
        self._staticParents = {}
Beispiel #3
0
    def animatedTransition(self, sourceFrame, targetFrame):
        """Set up child items for an animated transition from
        sourceFrame to targetFrame.  Set rendered frame() to the
        targetFrame.  Return animation (QAnimation instance)."""
        
        self.setFrame(sourceFrame)
        if targetFrame is sourceFrame:
            return None # raise?

        # sliding transition (left/right) if Slide changes:
        slide = cmp(targetFrame.slide().slideIndex(),
                    sourceFrame.slide().slideIndex())

        oldGeometry = QtCore.QRectF(p(self.pos), self._frame.sizeF())
        newGeometry, addItems, removeItems = self._changeFrame(targetFrame)
        if oldGeometry != newGeometry:
            self._geometryAnimation = QtCore.QPropertyAnimation(self, 'geometry', self)
            self._geometryAnimation.setEndValue(newGeometry)
            self._geometryAnimation.setDuration(100)

        self._animation = QtCore.QParallelAnimationGroup()
        self._animation.finished.connect(self._resetAnimation)

        fadeOut = {}
        fadeIn = {}
        slideOut = {}
        slideIn = {}

        # decide which items to slide and which to fade out/in:
        if not slide:
            # within-Slide animation, no sliding here:
            fadeOut = dict(removeItems)
            fadeIn = addItems
        else:
            for oldKey, (oldLayer, oldItem) in removeItems.iteritems():
                # always slide custom items:
                if oldKey is oldItem:
                    slideOut[oldKey] = (oldLayer, oldItem)
                    continue

                # always fade non-Patches (e.g. backgrounds, movies, ...)
                if not isinstance(oldKey, presentation.Patch):
                    fadeOut[oldKey] = (oldLayer, oldItem)
                    continue

                # always fade header & footer:
                if (isinstance(oldKey, presentation.Patch) and
                    oldKey.flag(presentation.Patch.FLAG_HEADER | presentation.Patch.FLAG_FOOTER)):
                    fadeOut[oldKey] = (oldLayer, oldItem)
                    continue

                slideOut[oldKey] = (oldLayer, oldItem)

            for newKey, (newLayer, newItem) in addItems.iteritems():
                # always slide custom items:
                if newKey is newItem:
                    slideIn[newKey] = (newLayer, newItem)
                    continue

                # always fade non-Patches (e.g. backgrounds, movies, ...)
                if not isinstance(newKey, presentation.Patch):
                    fadeIn[newKey] = (newLayer, newItem)
                    continue

                # always fade header & footer:
                if (isinstance(newKey, presentation.Patch) and
                    newKey.flag(presentation.Patch.FLAG_HEADER | presentation.Patch.FLAG_FOOTER)):
                    fadeIn[newKey] = (newLayer, newItem)
                    continue

                # look for pairs (oldItem, newItem) of Patches where
                # newKey.isSuccessorOf(oldKey) => fade out/in
                changed = False
                for oldKey, (oldLayer, oldItem) in removeItems.iteritems():
                    if not isinstance(oldKey, presentation.Patch):
                        continue
                    if newKey.isSuccessorOf(oldKey):
                        changed = True
                        if oldKey in slideOut:
                            del slideOut[oldKey]
                        else:
                            print "not found in slideOut (fadeOut: %s): %s" % (oldKey in fadeOut, oldKey)
                        fadeOut[oldKey] = (oldLayer, oldItem)
                        fadeIn[newKey] = (newLayer, newItem)
                        break
                if not changed:
                    slideIn[newKey] = (newLayer, newItem)

        # don't fade out items that are completely covered by items that fade in:
        for newKey, (newLayer, newItem) in fadeIn.iteritems():
            coveredRect = _frameBoundingRect(newItem)
            for oldKey, (oldLayer, oldItem) in fadeOut.items():
                if coveredRect.contains(_frameBoundingRect(oldItem)):
                    del fadeOut[oldKey]

        offset = self._frame.sizeF().width() * slide

        # set up property animations for sliding/fading in/out:
        for items, contentName, duration, propName, startValue, endValue in (
                (slideOut, 'slideOut', SLIDE_DURATION,
                 'pos', QtCore.QPoint(0, 0), QtCore.QPoint(-offset, 0)),
                (slideIn, 'slideIn', SLIDE_DURATION,
                 'pos', QtCore.QPoint(offset, 0), QtCore.QPoint(0, 0)),
                (fadeOut, 'fadeOut', FADE_DURATION,
                 'opacity', 1.0, 0.0),
                (fadeIn, 'fadeIn', FADE_DURATION,
                 'opacity', 0.0, 1.0),
            ):
            if items:
                parentItems = set()

                for key, (layer, item) in items.iteritems():
                    parentItem = self._contentItem("%s-%s" % (layer, contentName))
                    self._staticParents[item] = item.parentItem()
                    item.setParentItem(parentItem)
                    parentItems.add(parentItem)

                for parentItem in parentItems:
                    anim = QtCore.QPropertyAnimation(parentItem, propName, self._animation)
                    anim.setDuration(duration)
                    anim.setStartValue(startValue)
                    anim.setEndValue(endValue)

        self._items.update(addItems)
        self._pendingRemove = removeItems

        self._animation.start()
        return self._animation