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 "cube-transition-effect-impl.h"
22 #include <dali/integration-api/debug.h>
23 #include <dali/public-api/object/type-registry-helper.h>
24 #include <dali/public-api/object/type-registry.h>
25 #include <cstring> // for strcmp
28 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
29 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
30 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
40 // Setup properties, signals and actions using the type-registry.
41 DALI_TYPE_REGISTRATION_BEGIN(Toolkit::CubeTransitionEffect, Dali::BaseHandle, NULL);
43 DALI_SIGNAL_REGISTRATION(Toolkit, CubeTransitionEffect, "transitionCompleted", SIGNAL_TRANSITION_COMPLETED)
45 DALI_TYPE_REGISTRATION_END()
47 Actor CreateTile(const Vector4& samplerRect)
49 Actor tile = Actor::New();
50 tile.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
51 tile.RegisterProperty("uTextureRect", samplerRect);
57 const Vector4 CubeTransitionEffect::FULL_BRIGHTNESS(1.0f, 1.0f, 1.0f, 1.0f);
58 const Vector4 CubeTransitionEffect::HALF_BRIGHTNESS(0.5f, 0.5f, 0.5f, 1.0f);
60 CubeTransitionEffect::CubeTransitionEffect(unsigned int rows, unsigned int columns)
61 : Control(ControlBehaviour(DISABLE_STYLE_CHANGE_SIGNALS)),
66 mAnimationDuration(1.f),
67 mCubeDisplacement(0.f)
71 CubeTransitionEffect::~CubeTransitionEffect()
75 void CubeTransitionEffect::SetTargetRight(unsigned int idx)
77 mBoxType[idx] = RIGHT;
79 mBoxes[idx].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f);
81 mTargetTiles[idx].SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(1.f, 0.5f, 0.5f));
82 mTargetTiles[idx].SetProperty(Actor::Property::ORIENTATION, Quaternion(Degree(90.f), Vector3::YAXIS));
85 void CubeTransitionEffect::SetTargetLeft(unsigned int idx)
89 mBoxes[idx].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f);
91 mTargetTiles[idx].SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.f, 0.5f, 0.5f));
92 mTargetTiles[idx].SetProperty(Actor::Property::ORIENTATION, Quaternion(Degree(-90.f), Vector3::YAXIS));
95 void CubeTransitionEffect::SetTargetBottom(unsigned int idx)
97 mBoxType[idx] = BOTTOM;
99 mBoxes[idx].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f);
101 mTargetTiles[idx].SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.5f, 0.f, 0.5f));
102 mTargetTiles[idx].SetProperty(Actor::Property::ORIENTATION, Quaternion(Degree(90.f), Vector3::XAXIS));
105 void CubeTransitionEffect::SetTargetTop(unsigned int idx)
109 mBoxes[idx].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f);
111 mTargetTiles[idx].SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.5f, 1.f, 0.5f));
112 mTargetTiles[idx].SetProperty(Actor::Property::ORIENTATION, Quaternion(Degree(-90.f), Vector3::XAXIS));
115 void CubeTransitionEffect::OnRelayout(const Vector2& size, RelayoutContainer& container)
117 mTileSize = Vector2(size.x / mColumns, size.y / mRows);
119 mBoxRoot.SetProperty(Actor::Property::SIZE_WIDTH, size.x);
120 mBoxRoot.SetProperty(Actor::Property::SIZE_HEIGHT, size.y);
121 mBoxRoot.SetProperty(Actor::Property::SIZE_DEPTH, 1.0f);
123 for(size_t i = 0; i < mBoxes.size(); ++i)
125 mBoxes[i].SetProperty(Actor::Property::SIZE_WIDTH, mTileSize.x);
126 mBoxes[i].SetProperty(Actor::Property::SIZE_HEIGHT, mTileSize.y);
133 mBoxes[i].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.x * 0.5f);
134 mBoxes[i].SetProperty(Actor::Property::SIZE_DEPTH, mTileSize.x);
140 mBoxes[i].SetProperty(Actor::Property::PARENT_ORIGIN_Z, 1.0f - mTileSize.y * 0.5f);
141 mBoxes[i].SetProperty(Actor::Property::SIZE_DEPTH, mTileSize.y);
147 for(ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it)
149 it->SetProperty(Actor::Property::SIZE_WIDTH, mTileSize.x);
150 it->SetProperty(Actor::Property::SIZE_HEIGHT, mTileSize.y);
152 for(ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it)
154 it->SetProperty(Actor::Property::SIZE_WIDTH, mTileSize.x);
155 it->SetProperty(Actor::Property::SIZE_HEIGHT, mTileSize.y);
159 void CubeTransitionEffect::Initialize()
161 Self().RegisterProperty("uTextureRect", Vector4(0.0f, 0.0f, 1.0f, 1.0f));
163 mBoxType.Resize(mColumns * mRows);
165 //create the box parents
166 mBoxRoot = Actor::New();
167 mBoxRoot.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
168 mBoxRoot.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
170 mCurrentTiles.clear();
171 mTargetTiles.clear();
173 mCurrentTiles.reserve(mColumns * mRows);
174 mTargetTiles.reserve(mColumns * mRows);
176 Vector2 gridSizeInv(1.0f / mColumns, 1.0f / mRows);
177 Vector3 offset(0.5f * gridSizeInv.x, 0.5f * gridSizeInv.y, 0.0f);
180 for(unsigned int y = 0; y < mRows; ++y, anchor.y += 1.0f / mRows)
183 for(unsigned int x = 0; x < mColumns; ++x, anchor.x += 1.0f / mColumns)
185 Vector4 textureRect(anchor.x, anchor.y, anchor.x + gridSizeInv.x, anchor.y + gridSizeInv.y);
187 Actor currentTile = CreateTile(textureRect);
188 currentTile.SetProperty(Actor::Property::COLOR, FULL_BRIGHTNESS);
189 currentTile.SetProperty(Actor::Property::PARENT_ORIGIN, ParentOrigin::CENTER);
190 mCurrentTiles.push_back(currentTile);
192 Actor targetTile = CreateTile(textureRect);
193 targetTile.SetProperty(Actor::Property::COLOR, HALF_BRIGHTNESS);
194 mTargetTiles.push_back(targetTile);
196 Actor box = Actor::New();
197 box.SetProperty(Actor::Property::PARENT_ORIGIN, anchor + offset);
198 box.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::CENTER);
200 box.Add(currentTile);
205 mBoxes.push_back(box);
212 void CubeTransitionEffect::OnSceneConnection(int depth)
214 Geometry geometry = VisualFactoryCache::CreateQuadGeometry();
215 Shader shader = Shader::New(SHADER_CUBE_TRANSITION_EFFECT_VERT, SHADER_CUBE_TRANSITION_EFFECT_FRAG);
217 TextureSet textureSet = TextureSet::New();
221 textureSet.SetTexture(0u, mCurrentTexture);
223 mCurrentRenderer = Renderer::New(geometry, shader);
224 mCurrentRenderer.SetTextures(textureSet);
226 mCurrentRenderer.SetProperty(Renderer::Property::DEPTH_INDEX, depth);
227 Self().AddRenderer(mCurrentRenderer);
229 Control::OnSceneConnection(depth);
232 void CubeTransitionEffect::OnSceneDisconnection()
236 Self().RemoveRenderer(mCurrentRenderer);
238 for(ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it)
240 it->RemoveRenderer(mCurrentRenderer);
242 mCurrentRenderer.Reset();
247 for(ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it)
249 it->RemoveRenderer(mTargetRenderer);
251 mTargetRenderer.Reset();
254 Control::OnSceneDisconnection();
257 void CubeTransitionEffect::SetTransitionDuration(float duration)
259 mAnimationDuration = duration;
262 float CubeTransitionEffect::GetTransitionDuration() const
264 return mAnimationDuration;
267 void CubeTransitionEffect::SetCubeDisplacement(float displacement)
269 mCubeDisplacement = displacement;
272 float CubeTransitionEffect::GetCubeDisplacement() const
274 return mCubeDisplacement;
277 bool CubeTransitionEffect::IsTransitioning()
282 void CubeTransitionEffect::SetCurrentTexture(Texture texture)
284 mCurrentTexture = texture;
288 TextureSet textureSet = mCurrentRenderer.GetTextures();
289 textureSet.SetTexture(0u, mCurrentTexture);
293 void CubeTransitionEffect::SetTargetTexture(Texture texture)
295 mTargetTexture = texture;
299 TextureSet textureSet = mTargetRenderer.GetTextures();
300 textureSet.SetTexture(0u, mTargetTexture);
304 void CubeTransitionEffect::StartTransition(bool toNextImage)
306 Vector3 size = Self().GetCurrentProperty<Vector3>(Actor::Property::SIZE);
309 StartTransition(Vector2(size.x * 0.5f, size.y * 0.5f), Vector2(-10.f, 0.f));
313 StartTransition(Vector2(size.x * 0.5f, size.y * 0.5f), Vector2(10.f, 0.f));
317 void CubeTransitionEffect::StartTransition(Vector2 panPosition, Vector2 panDisplacement)
319 if(!mCurrentRenderer)
321 DALI_LOG_ERROR("Trying to transition a cube transition without an image set\n");
325 //create the target renderer
326 TextureSet textureSet = TextureSet::New();
329 textureSet.SetTexture(0u, mTargetTexture);
331 Geometry geometry = mCurrentRenderer.GetGeometry();
332 Shader shader(mCurrentRenderer.GetShader());
333 mTargetRenderer = Renderer::New(geometry, shader);
334 mTargetRenderer.SetTextures(textureSet);
336 int depthIndex = mCurrentRenderer.GetProperty<int>(Renderer::Property::DEPTH_INDEX);
337 mTargetRenderer.SetProperty(Dali::Renderer::Property::DEPTH_INDEX, depthIndex);
339 for(size_t i = 0; i < mBoxes.size(); ++i)
341 mBoxes[i].SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(0.0f), Vector3::XAXIS));
344 for(ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it)
346 it->SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.5f, 0.5f, 1.0f));
347 it->SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(0.0f), Vector3::XAXIS));
348 it->AddRenderer(mCurrentRenderer);
350 for(ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it)
352 it->AddRenderer(mTargetRenderer);
355 Self().RemoveRenderer(mCurrentRenderer);
356 Self().Add(mBoxRoot);
364 mAnimation = Animation::New(mAnimationDuration);
365 mAnimation.FinishedSignal().Connect(this, &CubeTransitionEffect::OnTransitionFinished);
367 OnStartTransition(panPosition, panDisplacement);
370 void CubeTransitionEffect::PauseTransition()
372 if(mIsAnimating && !mIsPaused)
379 void CubeTransitionEffect::ResumeTransition()
381 if(mIsAnimating && mIsPaused)
388 void CubeTransitionEffect::StopTransition()
390 ResetToInitialState();
393 void CubeTransitionEffect::ResetToInitialState()
397 mIsAnimating = false;
399 Self().Remove(mBoxRoot);
401 for(size_t i = 0; i < mBoxes.size(); ++i)
403 mBoxes[i].SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(0.0f), Vector3::XAXIS));
406 for(ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it)
408 it->SetProperty(Actor::Property::PARENT_ORIGIN, Vector3(0.5f, 0.5f, 1.0f));
409 it->SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(0.0f), Vector3::XAXIS));
410 it->SetProperty(Actor::Property::COLOR, FULL_BRIGHTNESS);
414 for(ActorArray::iterator it = mCurrentTiles.begin(); it != mCurrentTiles.end(); ++it)
416 it->RemoveRenderer(mCurrentRenderer);
418 Self().AddRenderer(mCurrentRenderer);
421 for(ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it)
423 it->SetProperty(Actor::Property::COLOR, HALF_BRIGHTNESS);
427 for(ActorArray::iterator it = mTargetTiles.begin(); it != mTargetTiles.end(); ++it)
429 it->RemoveRenderer(mTargetRenderer);
434 void CubeTransitionEffect::OnTransitionFinished(Animation& source)
436 std::swap(mCurrentTiles, mTargetTiles);
437 std::swap(mCurrentRenderer, mTargetRenderer);
438 std::swap(mCurrentTexture, mTargetTexture);
440 ResetToInitialState();
443 Toolkit::CubeTransitionEffect handle(GetOwner());
444 mTransitionCompletedSignal.Emit(handle, mCurrentTexture);
447 Toolkit::CubeTransitionEffect::TransitionCompletedSignalType& CubeTransitionEffect::TransitionCompletedSignal()
449 return mTransitionCompletedSignal;
452 bool CubeTransitionEffect::DoConnectSignal(BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor)
454 Dali::BaseHandle handle(object);
456 bool connected(true);
457 Toolkit::CubeTransitionEffect cubeTransitionEffect = Toolkit::CubeTransitionEffect::DownCast(handle);
459 if(0 == strcmp(signalName.c_str(), SIGNAL_TRANSITION_COMPLETED))
461 cubeTransitionEffect.TransitionCompletedSignal().Connect(tracker, functor);
465 // signalName does not match any signal
472 } // namespace Internal
474 } // namespace Toolkit