Merge "Fix SVACE error in KeyboardFocusManager" into devel/master
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / animated-image / animated-image-visual.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  *
16  */
17
18 // CLASS HEADER
19 #include "animated-image-visual.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/devel-api/adaptor-framework/gif-loading.h>
23
24 // INTERNAL INCLUDES
25 #include <dali-toolkit/public-api/visuals/image-visual-properties.h>
26 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
27 #include <dali-toolkit/internal/visuals/visual-factory-impl.h>
28 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
29 #include <dali-toolkit/internal/visuals/visual-string-constants.h>
30 #include <dali-toolkit/internal/visuals/visual-base-data-impl.h>
31 #include <dali-toolkit/internal/visuals/image/image-visual.h>
32 #include <dali-toolkit/devel-api/image-loader/image-atlas.h>
33
34 namespace Dali
35 {
36
37 namespace Toolkit
38 {
39
40 namespace Internal
41 {
42
43 AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl, const Property::Map& properties )
44 {
45   AnimatedImageVisual* visual = new AnimatedImageVisual( factoryCache );
46   visual->mImageUrl = imageUrl;
47   visual->SetProperties( properties );
48
49   return visual;
50 }
51
52 AnimatedImageVisualPtr AnimatedImageVisual::New( VisualFactoryCache& factoryCache, const std::string& imageUrl )
53 {
54   AnimatedImageVisual* visual = new AnimatedImageVisual( factoryCache );
55   visual->mImageUrl = imageUrl;
56
57   return visual;
58 }
59
60 AnimatedImageVisual::AnimatedImageVisual( VisualFactoryCache& factoryCache )
61 : Visual::Base( factoryCache ),
62   mFrameDelayTimer(),
63   mImageUrl(),
64   mImageSize(),
65   mCurrentFrameIndex( 0 )
66 {}
67
68 AnimatedImageVisual::~AnimatedImageVisual()
69 {
70 }
71
72 void AnimatedImageVisual::GetNaturalSize( Vector2& naturalSize )
73 {
74   if( mImageSize.GetWidth() == 0 &&  mImageSize.GetHeight() == 0)
75   {
76     mImageSize = Dali::GetGifImageSize( mImageUrl );
77   }
78
79   naturalSize.width = mImageSize.GetWidth();
80   naturalSize.height = mImageSize.GetHeight();
81 }
82
83 void AnimatedImageVisual::DoCreatePropertyMap( Property::Map& map ) const
84 {
85   map.Clear();
86   map.Insert( Toolkit::DevelVisual::Property::TYPE, Toolkit::Visual::IMAGE );
87   if( !mImageUrl.empty() )
88   {
89     map.Insert( Toolkit::ImageVisual::Property::URL, mImageUrl );
90   }
91 }
92
93 void AnimatedImageVisual::DoSetProperties( const Property::Map& propertyMap )
94 {
95   // url already passed in from constructor
96 }
97
98 void AnimatedImageVisual::DoSetOnStage( Actor& actor )
99 {
100   Texture texture = PrepareAnimatedImage();
101   if( texture ) // if the image loading is successful
102   {
103     Shader shader = ImageVisual::GetImageShader( mFactoryCache, true, true );
104     Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
105     TextureSet textureSet = TextureSet::New();
106     mImpl->mRenderer = Renderer::New( geometry, shader );
107     mImpl->mRenderer.SetTextures( textureSet );
108     textureSet.SetTexture( 0u, PrepareAnimatedImage() );
109     mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, mTextureRectContainer[0] );
110
111     // Register transform properties
112     mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
113
114     mCurrentFrameIndex = 0;
115     if( mFrameDelayContainer.Count() > 1 )
116     {
117       mFrameDelayTimer = Timer::New( mFrameDelayContainer[0] );
118       mFrameDelayTimer.TickSignal().Connect( this, &AnimatedImageVisual::DisplayNextFrame );
119       mFrameDelayTimer.Start();
120     }
121
122     actor.AddRenderer( mImpl->mRenderer );
123   }
124 }
125
126 void AnimatedImageVisual::DoSetOffStage( Actor& actor )
127 {
128   if( !mImpl->mRenderer )
129   {
130     return;
131   }
132
133   if( mFrameDelayTimer )
134   {
135     mFrameDelayTimer.Stop();
136     mFrameDelayTimer.Reset();
137   }
138
139   mTextureRectContainer.Clear();
140   mFrameDelayContainer.Clear();
141
142   actor.RemoveRenderer( mImpl->mRenderer );
143   mImpl->mRenderer.Reset();
144 }
145
146 void AnimatedImageVisual::OnSetTransform()
147 {
148   if( mImpl->mRenderer )
149   {
150     mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
151   }
152 }
153
154 Texture AnimatedImageVisual::PrepareAnimatedImage()
155 {
156   // load from image file
157   std::vector<Dali::PixelData> pixelDataList;
158   if( Dali::LoadAnimatedGifFromFile( mImageUrl.c_str() , pixelDataList, mFrameDelayContainer ) )
159   {
160     mImageSize.SetWidth( pixelDataList[0].GetWidth() );
161     mImageSize.SetHeight( pixelDataList[0].GetHeight() );
162
163     return Toolkit::ImageAtlas::PackToAtlas( pixelDataList, mTextureRectContainer );
164   }
165
166   return Texture();
167 }
168
169 bool AnimatedImageVisual::DisplayNextFrame()
170 {
171   mCurrentFrameIndex = (mCurrentFrameIndex+1) % mFrameDelayContainer.Count();
172   mImpl->mRenderer.RegisterProperty( ATLAS_RECT_UNIFORM_NAME, mTextureRectContainer[mCurrentFrameIndex] );
173   if( mFrameDelayTimer.GetInterval() != mFrameDelayContainer[mCurrentFrameIndex] )
174   {
175     mFrameDelayTimer.SetInterval( mFrameDelayContainer[mCurrentFrameIndex] );
176   }
177
178   return true;
179 }
180
181
182 } // namespace Internal
183
184 } // namespace Toolkit
185
186 } // namespace Dali