Merge "Prevent Image visuals creating a renderer and putting it on stage even if...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / color / color-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 "color-visual.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 //INTERNAL INCLUDES
25 #include <dali-toolkit/public-api/visuals/color-visual-properties.h>
26 #include <dali-toolkit/devel-api/visual-factory/devel-visual-properties.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
32 namespace Dali
33 {
34
35 namespace Toolkit
36 {
37
38 namespace Internal
39 {
40
41 namespace
42 {
43 const char * const COLOR_NAME("mixColor");
44
45 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
46   attribute mediump vec2 aPosition;\n
47   uniform mediump mat4 uMvpMatrix;\n
48   uniform mediump vec3 uSize;\n
49   \n
50
51   //Visual size and offset
52   uniform mediump vec2 offset;\n
53   uniform mediump vec2 size;\n
54   uniform mediump vec4 offsetSizeMode;\n
55   uniform mediump vec2 origin;\n
56   uniform mediump vec2 anchorPoint;\n
57
58   vec4 ComputeVertexPosition()\n
59   {\n
60     vec2 visualSize = mix(uSize.xy*size, size, offsetSizeMode.zw );\n
61     vec2 visualOffset = mix( offset, offset/uSize.xy, offsetSizeMode.xy);\n
62     return vec4( (aPosition + anchorPoint)*visualSize + (visualOffset + origin)*uSize.xy, 0.0, 1.0 );\n
63   }\n
64
65   void main()\n
66   {\n
67     gl_Position = uMvpMatrix * ComputeVertexPosition();\n
68   }\n
69 );
70
71 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
72   uniform lowp vec4 uColor;\n
73   uniform lowp vec4 mixColor;\n
74   \n
75   void main()\n
76   {\n
77     gl_FragColor = mixColor*uColor;\n
78   }\n
79 );
80 }
81
82 ColorVisualPtr ColorVisual::New( VisualFactoryCache& factoryCache )
83 {
84   return new ColorVisual( factoryCache );
85 }
86
87 ColorVisual::ColorVisual( VisualFactoryCache& factoryCache )
88 : Visual::Base( factoryCache ),
89   mMixColorIndex( Property::INVALID_INDEX )
90 {
91 }
92
93 ColorVisual::~ColorVisual()
94 {
95 }
96
97 void ColorVisual::DoSetProperties( const Property::Map& propertyMap )
98 {
99   Property::Value* color = propertyMap.Find( Toolkit::ColorVisual::Property::MIX_COLOR, COLOR_NAME );
100   if( !( color && color->Get(mMixColor) ) )
101   {
102     DALI_LOG_ERROR( "Fail to provide a color to the ColorVisual object\n" );
103   }
104 }
105
106 void ColorVisual::SetSize( const Vector2& size )
107 {
108   Visual::Base::SetSize( size );
109
110   // ToDo: renderer responds to the size change
111 }
112
113 void ColorVisual::DoSetOnStage( Actor& actor )
114 {
115   InitializeRenderer();
116
117   actor.AddRenderer( mImpl->mRenderer );
118 }
119
120 void ColorVisual::DoCreatePropertyMap( Property::Map& map ) const
121 {
122   map.Clear();
123   map.Insert( Toolkit::VisualProperty::TYPE, Toolkit::Visual::COLOR );
124   map.Insert( Toolkit::ColorVisual::Property::MIX_COLOR, mMixColor );
125 }
126
127 void ColorVisual::DoSetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue )
128 {
129   // TODO
130   /* David Steele comented :
131
132      Some things to bear in mind:
133
134      We currently keep a copy of the mix color in the ColorVisual object, which is then used to instantiate the registered property on the renderer.
135
136      The user can get the renderer and animate the mixColor property (it's registered, so is automatically a scene-graph property).
137
138      The GetProperty method will have to read from the renderer, or from the cached value in the Visual, and the SetProperty will have to write to cache and to the renderer if present.
139   */
140 }
141
142 Dali::Property::Value ColorVisual::DoGetProperty( Dali::Property::Index index )
143 {
144   // TODO
145   return Dali::Property::Value();
146 }
147
148 void ColorVisual::OnSetTransform()
149 {
150   if( mImpl->mRenderer )
151   {
152     mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
153   }
154 }
155
156 void ColorVisual::InitializeRenderer()
157 {
158   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
159   if( !geometry )
160   {
161     geometry =  VisualFactoryCache::CreateQuadGeometry();
162     mFactoryCache.SaveGeometry( VisualFactoryCache::QUAD_GEOMETRY, geometry );
163   }
164
165   Shader shader = mFactoryCache.GetShader( VisualFactoryCache::COLOR_SHADER );
166   if( !shader )
167   {
168     shader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
169     mFactoryCache.SaveShader( VisualFactoryCache::COLOR_SHADER, shader );
170   }
171
172   mImpl->mRenderer = Renderer::New( geometry, shader );
173
174   mMixColorIndex = mImpl->mRenderer.RegisterProperty( Toolkit::ColorVisual::Property::MIX_COLOR, COLOR_NAME, mMixColor );
175   if( mMixColor.a < 1.f )
176   {
177     mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
178   }
179
180   //Register transform properties
181   mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
182 }
183
184 void ColorVisual::SetColor(const Vector4& color)
185 {
186   mMixColor = color;
187
188   if( mImpl->mRenderer )
189   {
190     (mImpl->mRenderer).SetProperty( mMixColorIndex, color );
191     if( color.a < 1.f )
192     {
193       mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
194     }
195   }
196 }
197
198 } // namespace Internal
199
200 } // namespace Toolkit
201
202 } // namespace Dali