/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
void EffectRewinder::initialize()
{ // Add some event handlers so that we are informed when // a) an animation is started (we then check whether that belongs to a // main sequence effect and if so, increase the respective counter), // b,c) a slide was started or ended (in which case the effect counter // is reset.
// Check if the current slide has advance time setting or not
uno::Reference< beans::XPropertySet > xPropSet( mxCurrentSlide, uno::UNO_QUERY );
sal_Int32 nChange(0);
// Do not allow nested rewinds. if (mpAsynchronousRewindEvent)
{
OSL_ASSERT( ! mpAsynchronousRewindEvent); returnfalse;
}
// Abort (and skip over the rest of) any currently active animation.
mrUserEventQueue.callSkipEffectEventHandler();
if (!mbHasAdvancedTimeSetting)
mrEventQueue.forceEmpty();
constint nSkipCount (mnMainSequenceEffectCount - 1); if (nSkipCount < 0)
{ if ( ! rPreviousSlideFunctor)
{
OSL_ASSERT(rPreviousSlideFunctor); returnfalse;
}
// No main sequence effects to rewind on the current slide. // Go back to the previous slide.
mpAsynchronousRewindEvent = makeEvent(
::std::bind(
&EffectRewinder::asynchronousRewindToPreviousSlide, this,
rPreviousSlideFunctor),
u"EffectRewinder::asynchronousRewindToPreviousSlide"_ustr);
} else
{ // The actual rewinding is done asynchronously so that we can safely // call other methods.
mpAsynchronousRewindEvent = makeEvent(
::std::bind(
&EffectRewinder::asynchronousRewind, this,
nSkipCount, true,
rSlideRewindFunctor),
u"EffectRewinder::asynchronousRewind"_ustr);
}
if (mpAsynchronousRewindEvent)
mrEventQueue.addEvent(mpAsynchronousRewindEvent);
returnbool(mpAsynchronousRewindEvent);
}
void EffectRewinder::skipAllMainSequenceEffects()
{ // Do not allow nested rewinds. if (mpAsynchronousRewindEvent)
{
OSL_ASSERT(!mpAsynchronousRewindEvent); return;
}
// Does the current node belong to the main sequence? if (xNode.is())
{
animations::Event aEvent; if (xNode->getBegin() >>= aEvent) if (aEvent.Trigger == animations::EventTrigger::ON_NEXT)
++nMainSequenceNodeCount;
}
// If the current node is a container then prepare its children for investigation.
uno::Reference<container::XEnumerationAccess> xEnumerationAccess (xNode, uno::UNO_QUERY); if (xEnumerationAccess.is())
{
uno::Reference<container::XEnumeration> xEnumeration (
xEnumerationAccess->createEnumeration()); if (xEnumeration.is()) while (xEnumeration->hasMoreElements())
{
aNodeQueue.push(
uno::Reference<animations::XAnimationNode>(
xEnumeration->nextElement(), uno::UNO_QUERY));
}
}
}
return nMainSequenceNodeCount;
}
void EffectRewinder::skipSingleMainSequenceEffects()
{ // This basically just starts the next effect and then skips over its // animation.
mrEventMultiplexer.notifyNextEffect();
mrEventQueue.forceEmpty();
mrUserEventQueue.callSkipEffectEventHandler();
mrEventQueue.forceEmpty();
}
bool EffectRewinder::notifyAnimationStart (const AnimationNodeSharedPtr& rpNode)
{ // This notification is only relevant for us when the rpNode belongs to // the main sequence.
BaseNodeSharedPtr pBaseNode (::std::dynamic_pointer_cast<BaseNode>(rpNode)); if ( ! pBaseNode) returnfalse;
BaseContainerNodeSharedPtr pParent (pBaseNode->getParentNode()); if ( ! (pParent && pParent->isMainSequenceRootNode())) returnfalse;
// This notification is only relevant for us when the effect is user // triggered. bool bIsUserTriggered (false);
Reference<animations::XAnimationNode> xNode (rpNode->getXAnimationNode()); if (xNode.is())
{
animations::Event aEvent; if (xNode->getBegin() >>= aEvent)
bIsUserTriggered = (aEvent.Trigger == animations::EventTrigger::ON_NEXT);
}
if (bIsUserTriggered)
++mnMainSequenceEffectCount; else
mbNonUserTriggeredMainSequenceEffectSeen = true;
if (bRedisplayCurrentSlide)
{
mpPaintLock->Activate(); // Re-display the current slide. if (rSlideRewindFunctor)
rSlideRewindFunctor();
mpAsynchronousRewindEvent = makeEvent(
::std::bind(
&EffectRewinder::asynchronousRewind, this,
nEffectCount, false,
rSlideRewindFunctor),
u"EffectRewinder::asynchronousRewind"_ustr);
mrEventQueue.addEvent(mpAsynchronousRewindEvent);
} else
{ // Process initial events and skip any animations that are started // when the slide is shown.
mbNonUserTriggeredMainSequenceEffectSeen = false;
if (!mbHasAdvancedTimeSetting)
mrEventQueue.forceEmpty();
if (mbNonUserTriggeredMainSequenceEffectSeen)
{
mrUserEventQueue.callSkipEffectEventHandler();
mrEventQueue.forceEmpty();
}
while (--nEffectCount >= 0)
skipSingleMainSequenceEffects();
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.