tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / slideshow / source / engine / animationnodes / basecontainernode.cxx
blob02e97261bbc7ae7bc3851e481fcc8e8f2b46b083
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <basecontainernode.hxx>
22 #include <com/sun/star/animations/AnimationRestart.hpp>
23 #include <com/sun/star/animations/AnimationFill.hpp>
24 #include <eventqueue.hxx>
25 #include "nodetools.hxx"
26 #include <delayevent.hxx>
27 #include <o3tl/safeint.hxx>
28 #include <sal/log.hxx>
30 #include <functional>
31 #include <algorithm>
33 using namespace com::sun::star;
35 namespace slideshow::internal {
36 namespace {
37 bool isRepeatIndefinite(const uno::Reference<animations::XAnimationNode>& xNode)
39 return xNode->getRepeatCount().hasValue() && isIndefiniteTiming(xNode->getRepeatCount());
42 bool isRestart(const uno::Reference<animations::XAnimationNode>& xNode)
44 sal_Int16 nRestart = xNode->getRestart();
45 return nRestart == animations::AnimationRestart::WHEN_NOT_ACTIVE ||
46 nRestart == animations::AnimationRestart::ALWAYS;
50 BaseContainerNode::BaseContainerNode(
51 const uno::Reference< animations::XAnimationNode >& xNode,
52 const BaseContainerNodeSharedPtr& rParent,
53 const NodeContext& rContext )
54 : BaseNode( xNode, rParent, rContext ),
55 maChildren(),
56 mnFinishedChildren(0),
57 mnLeftIterations(0),
58 mbRepeatIndefinite(isRepeatIndefinite(xNode)),
59 mbRestart(isRestart(xNode)),
60 mbDurationIndefinite( isIndefiniteTiming( xNode->getEnd() ) &&
61 isIndefiniteTiming( xNode->getDuration() ) )
65 void BaseContainerNode::dispose()
67 forEachChildNode( std::mem_fn(&Disposable::dispose), -1 );
68 maChildren.clear();
69 BaseNode::dispose();
72 bool BaseContainerNode::init_st()
74 if( !(getXAnimationNode()->getRepeatCount() >>= mnLeftIterations) )
75 mnLeftIterations = 1.0;
76 return init_children();
79 bool BaseContainerNode::init_children()
81 mnFinishedChildren = 0;
83 // initialize all children
84 return (o3tl::make_unsigned(std::count_if(
85 maChildren.begin(), maChildren.end(),
86 std::mem_fn(&AnimationNode::init) )) ==
87 maChildren.size());
90 void BaseContainerNode::deactivate_st( NodeState eDestState )
92 mnLeftIterations = 0; // in order to make skip effect work correctly
93 if (eDestState == FROZEN) {
94 // deactivate all children that are not FROZEN or ENDED:
95 forEachChildNode( std::mem_fn(&AnimationNode::deactivate),
96 ~(FROZEN | ENDED) );
98 else {
99 // end all children that are not ENDED:
100 forEachChildNode( std::mem_fn(&AnimationNode::end), ~ENDED );
104 bool BaseContainerNode::hasPendingAnimation() const
106 // does any of our children returns "true" on
107 // AnimationNode::hasPendingAnimation()?
108 // If yes, we, too, return true
109 return std::any_of(
110 maChildren.begin(), maChildren.end(),
111 std::mem_fn(&AnimationNode::hasPendingAnimation) );
114 void BaseContainerNode::appendChildNode( AnimationNodeSharedPtr const& pNode )
116 if (! checkValidNode())
117 return;
119 // register derived classes as end listeners at all children.
120 // this is necessary to control the children animation
121 // sequence, and to determine our own end event
122 if (pNode->registerDeactivatingListener( getSelf() )) {
123 maChildren.push_back( pNode );
127 bool BaseContainerNode::isChildNode( AnimationNodeSharedPtr const& pNode ) const
129 // find given notifier in child vector
130 VectorOfNodes::const_iterator const iEnd( maChildren.end() );
131 VectorOfNodes::const_iterator const iFind(
132 std::find( maChildren.begin(), iEnd, pNode ) );
133 return (iFind != iEnd);
136 bool BaseContainerNode::notifyDeactivatedChild(
137 AnimationNodeSharedPtr const& pChildNode )
139 OSL_ASSERT( pChildNode->getState() == FROZEN ||
140 pChildNode->getState() == ENDED );
141 // early exit on invalid nodes
142 OSL_ASSERT( getState() != INVALID );
143 if( getState() == INVALID )
144 return false;
146 if (! isChildNode(pChildNode)) {
147 OSL_FAIL( "unknown notifier!" );
148 return false;
151 std::size_t const nSize = maChildren.size();
152 OSL_ASSERT( mnFinishedChildren < nSize );
153 ++mnFinishedChildren;
154 bool bFinished = (mnFinishedChildren >= nSize);
156 // Handle repetition here.
157 if (bFinished) {
158 if(!mbRepeatIndefinite && mnLeftIterations >= 1.0)
160 mnLeftIterations -= 1.0;
162 if(mnLeftIterations >= 1.0 || mbRestart)
164 // SMIL spec said that "Accumulate" controls whether or not the animation
165 // is cumulative, but XTimeContainer do not have this attribute, so always
166 // remove the effect before next repeat.
167 forEachChildNode(std::mem_fn(&AnimationNode::removeEffect), -1);
169 if (mnLeftIterations >= 1.0)
170 bFinished = false;
172 EventSharedPtr aRepetitionEvent =
173 makeDelay( [this] () { this->repeat(); },
174 0.0,
175 u"BaseContainerNode::repeat"_ustr);
176 getContext().mrEventQueue.addEvent( aRepetitionEvent );
178 else if (isDurationIndefinite())
180 if (getFillMode() == animations::AnimationFill::REMOVE)
181 forEachChildNode(std::mem_fn(&AnimationNode::removeEffect), -1);
182 deactivate();
186 return bFinished;
189 void BaseContainerNode::repeat()
191 // Prevent repeat event scheduled before deactivation.
192 if (getState() == FROZEN || getState() == ENDED)
193 return;
195 forEachChildNode( std::mem_fn(&AnimationNode::end), ~ENDED );
196 bool bState = init_children();
197 if( bState )
198 activate_st();
201 #if defined(DBG_UTIL)
202 void BaseContainerNode::showState() const
204 for(const auto & i : maChildren)
206 BaseNodeSharedPtr pNode =
207 std::dynamic_pointer_cast<BaseNode>(i);
208 SAL_INFO("slideshow.verbose",
209 "Node connection: n" <<
210 debugGetNodeName(this) <<
211 " -> n" <<
212 debugGetNodeName(pNode.get()));
213 pNode->showState();
216 BaseNode::showState();
218 #endif
220 } // namespace slideshow::internal
222 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */