2 * Copyright (c) 2021 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali-toolkit/internal/transition/transition-set-impl.h>
22 #include <dali/integration-api/adaptor-framework/adaptor.h>
23 #include <dali/integration-api/debug.h>
24 #include <dali/public-api/object/type-registry.h>
27 #include <dali-toolkit/internal/transition/transition-lifecycle-controller.h>
38 static constexpr std::string_view SIGNAL_FINISHED = "finished";
40 static constexpr float OPACITY_TRANSPARENT = 0.0f;
42 float CustomAlphaFunction(float progress)
44 return (progress >= 1.0f) ? 1.0f : 0.0f;
49 return Dali::Toolkit::TransitionSet::New();
52 TypeRegistration mType(typeid(Dali::Toolkit::TransitionSet), typeid(Dali::BaseHandle), Create);
54 SignalConnectorType signalConnector1(mType, std::string(SIGNAL_FINISHED), &TransitionSet::DoConnectSignal);
56 } // anonymous namespace
58 TransitionSetPtr TransitionSet::New()
60 TransitionSetPtr transitionSet = new TransitionSet();
65 TransitionSet::TransitionSet()
69 TransitionSet::~TransitionSet()
74 void TransitionSet::AddTransition(TransitionBasePtr transition)
76 mTransitions.push_back(transition);
79 TransitionBase* TransitionSet::GetTransitionAt(uint32_t index) const
81 TransitionBase* result(nullptr);
82 if(index < GetTransitionCount())
84 result = mTransitions[index].Get();
88 DALI_LOG_ERROR("Error: Invalid index to TransitionSet::GetTransitionAt\n");
94 uint32_t TransitionSet::GetTransitionCount() const
96 return mTransitions.size();
99 void TransitionSet::Play()
101 Adaptor::Get().RegisterProcessor(*this, true);
102 Adaptor::Get().RegisterProcessor(*this, false);
103 TransitionLifecycleController::GetInstance().AddTransitions(Dali::Toolkit::TransitionSet(this));
106 void TransitionSet::TransitionPreProcess()
108 float lastDuration = 0.0f;
109 for(auto&& transition : mTransitions)
111 TimePeriod timePeriod = transition->GetTimePeriod();
112 if(lastDuration <= timePeriod.durationSeconds + timePeriod.delaySeconds)
114 lastDuration = timePeriod.durationSeconds + timePeriod.delaySeconds;
117 mAnimation = Dali::Animation::New(lastDuration);
119 for(auto&& transition : mTransitions)
121 transition->PreProcess(mAnimation);
125 void TransitionSet::TransitionStart()
127 std::vector<std::pair<Dali::Actor, float>> minimumDelays;
128 for(auto&& transition : mTransitions)
132 // If target Control has appearing transition, the target will not be rendered during delay.
133 // And if the Control has multiple transitions, the target will not be rendered during minimum delay of the transitions.
134 // Here we can find minimum delay of each target.
135 if(!transition->IsPairTransition() && transition->IsAppearingTransition())
138 for(uint32_t index = 0; index < minimumDelays.size(); ++index)
140 if(minimumDelays[index].first == transition->GetTarget())
142 minimumDelays[index].second = std::min(minimumDelays[index].second, transition->GetTimePeriod().delaySeconds);
149 minimumDelays.push_back(std::pair<Dali::Actor, float>(transition->GetTarget(), transition->GetTimePeriod().delaySeconds));
154 // If the target has delay that is larger than 0, hide the target during minimum delay.
155 // The custom alpha function make the target hide just during delay.
156 for(auto&& delay : minimumDelays)
158 if(delay.second > Dali::Math::MACHINE_EPSILON_10)
160 Dali::KeyFrames initialKeyframes = Dali::KeyFrames::New();
161 initialKeyframes.Add(0.0f, OPACITY_TRANSPARENT);
162 initialKeyframes.Add(1.0f, delay.first.GetProperty<float>(Dali::Actor::Property::OPACITY));
164 AlphaFunction alpha(&CustomAlphaFunction);
165 mAnimation.AnimateBetween(Property(delay.first, Dali::Actor::Property::OPACITY), initialKeyframes, alpha, TimePeriod(delay.second));
169 mAnimation.FinishedSignal().Connect(this, &TransitionSet::TransitionFinished);
173 void TransitionSet::TransitionFinished(Dali::Animation& source)
175 // Call TransitionFinished() in reverse order.
176 // This let the first copied original properties will be return again at the final.
177 std::vector<TransitionBasePtr>::reverse_iterator riter;
178 for(riter = mTransitions.rbegin(); riter != mTransitions.rend(); riter++)
180 (*riter)->TransitionFinished();
183 EmitFinishedSignal();
186 Dali::Toolkit::TransitionSet::TransitionSetSignalType& TransitionSet::FinishedSignal()
188 return mFinishedSignal;
191 void TransitionSet::EmitFinishedSignal()
193 if(!mFinishedSignal.Empty())
195 Dali::Toolkit::TransitionSet handle(this);
196 mFinishedSignal.Emit(handle);
200 bool TransitionSet::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
202 bool connected(false);
203 TransitionSet* transitionSet = static_cast<TransitionSet*>(object); // TypeRegistry guarantees that this is the correct type.
205 if(SIGNAL_FINISHED == signalName)
207 transitionSet->FinishedSignal().Connect(tracker, functor);
214 void TransitionSet::Process(bool postProcessor)
218 TransitionPreProcess();
224 Adaptor::Get().UnregisterProcessor(*this, postProcessor);
227 } // namespace Internal
229 } // namespace Toolkit