Create property map from ControlRenderer and make SetOffStage API public
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / renderers / border / border-renderer.cpp
1 /*
2  * Copyright (c) 2015 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 "border-renderer.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 //INTERNAL INCLUDES
25 #include <dali-toolkit/internal/controls/renderers/renderer-factory-impl.h>
26 #include <dali-toolkit/internal/controls/renderers/renderer-factory-cache.h>
27 #include <dali-toolkit/internal/controls/renderers/control-renderer-data-impl.h>
28
29 namespace Dali
30 {
31
32 namespace Toolkit
33 {
34
35 namespace Internal
36 {
37
38 namespace
39 {
40 const char * const RENDERER_TYPE("renderer-type");
41 const char * const RENDERER_TYPE_VALUE("border-renderer");
42
43 const char * const COLOR_NAME("border-color");
44 const char * const COLOR_UNIFORM_NAME("uBorderColor");
45 const char * const SIZE_NAME("border-size");
46 const char * const SIZE_UNIFORM_NAME("uBorderSize");
47
48 const char * const POSITION_ATTRIBUTE_NAME("aPosition");
49 const char * const DRIFT_ATTRIBUTE_NAME("aDrift");
50 const char * const INDEX_NAME("indices");
51
52
53 const char* VERTEX_SHADER = DALI_COMPOSE_SHADER(
54   attribute mediump vec2 aPosition;\n
55   attribute mediump vec2 aDrift;\n
56   uniform mediump mat4 uMvpMatrix;\n
57   uniform mediump vec3 uSize;\n
58   uniform mediump float uBorderSize;\n
59   \n
60   void main()\n
61   {\n
62     vec2 position = aPosition*uSize.xy + aDrift*uBorderSize;\n
63     gl_Position = uMvpMatrix * vec4(position, 0.0, 1.0);\n
64   }\n
65 );
66
67 const char* FRAGMENT_SHADER = DALI_COMPOSE_SHADER(
68   uniform lowp vec4 uColor;\n
69   uniform lowp vec4 uBorderColor;\n
70   \n
71   void main()\n
72   {\n
73     gl_FragColor = uBorderColor*uColor;\n
74   }\n
75 );
76 }
77
78 BorderRenderer::BorderRenderer()
79 : ControlRenderer(),
80   mBorderColor( Color::TRANSPARENT ),
81   mBorderSize( 0.f ),
82   mBorderColorIndex( Property::INVALID_INDEX ),
83   mBorderSizeIndex( Property::INVALID_INDEX )
84 {
85 }
86
87 BorderRenderer::~BorderRenderer()
88 {
89 }
90
91 void BorderRenderer::Initialize( RendererFactoryCache& factoryCache, const Property::Map& propertyMap )
92 {
93   Initialize( factoryCache );
94
95   Property::Value* color = propertyMap.Find( COLOR_NAME );
96   if( !( color && color->Get(mBorderColor) ) )
97   {
98     DALI_LOG_ERROR( "Fail to provide a border color to the BorderRenderer object" );
99   }
100
101   Property::Value* size = propertyMap.Find( SIZE_NAME );
102   if( !( size && size->Get(mBorderSize) ) )
103   {
104     DALI_LOG_ERROR( "Fail to provide a border size to the BorderRenderer object" );
105   }
106 }
107
108 void BorderRenderer::SetClipRect( const Rect<int>& clipRect )
109 {
110   ControlRenderer::SetClipRect( clipRect );
111
112   //ToDo: renderer responds to the clipRect change
113 }
114
115 void BorderRenderer::DoSetOnStage( Actor& actor )
116 {
117   mBorderColorIndex = (mImpl->mRenderer).RegisterProperty( COLOR_UNIFORM_NAME, mBorderColor );
118   if( mBorderColor.a < 1.f )
119   {
120     (mImpl->mRenderer).GetMaterial().SetBlendMode( BlendingMode::ON );
121   }
122   mBorderSizeIndex = (mImpl->mRenderer).RegisterProperty( SIZE_UNIFORM_NAME, mBorderSize );
123 }
124
125 void BorderRenderer::CreatePropertyMap( Property::Map& map ) const
126 {
127   map.Clear();
128   map.Insert( RENDERER_TYPE, RENDERER_TYPE_VALUE );
129   map.Insert( COLOR_NAME, mBorderColor );
130   map.Insert( SIZE_NAME, mBorderSize );
131 }
132
133 void BorderRenderer::Initialize( RendererFactoryCache& factoryCache)
134 {
135   mImpl->mGeometry = factoryCache.GetGeometry( RendererFactoryCache::BORDER_GEOMETRY );
136   if( !(mImpl->mGeometry) )
137   {
138     mImpl->mGeometry =  CreateBorderGeometry();
139     factoryCache.SaveGeometry( RendererFactoryCache::QUAD_GEOMETRY, mImpl->mGeometry );
140   }
141
142   mImpl->mShader = factoryCache.GetShader( RendererFactoryCache::BORDER_SHADER );
143   if( !(mImpl->mShader) )
144   {
145     mImpl->mShader = Shader::New( VERTEX_SHADER, FRAGMENT_SHADER );
146     factoryCache.SaveShader( RendererFactoryCache::COLOR_SHADER, mImpl->mShader );
147   }
148 }
149
150 void BorderRenderer::SetBorderColor(const Vector4& color)
151 {
152   mBorderColor = color;
153
154   if( mImpl->mIsOnStage )
155   {
156     (mImpl->mRenderer).SetProperty( mBorderColorIndex, color );
157     if( color.a < 1.f &&  (mImpl->mRenderer).GetMaterial().GetBlendMode() != BlendingMode::ON)
158     {
159       (mImpl->mRenderer).GetMaterial().SetBlendMode( BlendingMode::ON );
160     }
161   }
162 }
163
164 void BorderRenderer::SetBorderSize( float size )
165 {
166   mBorderSize = size;
167
168   if( mImpl->mIsOnStage )
169   {
170     (mImpl->mRenderer).SetProperty( mBorderSizeIndex, size );
171   }
172 }
173
174 /**
175  * Vertices and triangles of the border geometry:
176  *
177  * vertex position = aPosition*uSize.xy + aDrift*uBorderSize;
178  *
179  * 0--1--2--3
180  * | /| /| /|
181  * |/ |/ |/ |
182  * 4--5--6--7
183  * | /|  | /|
184  * |/ |  |/ |
185  * 8--9--10-11
186  * | /| /| /|
187  * |/ |/ |/ |
188  * 12-13-14-15
189  */
190 Geometry BorderRenderer::CreateBorderGeometry()
191 {
192   const float halfWidth = 0.5f;
193   const float halfHeight = 0.5f;
194   struct BorderVertex { Vector2 position; Vector2 drift;};
195   BorderVertex borderVertexData[16] =
196   {
197       { Vector2(-halfWidth, -halfHeight), Vector2(0.f, 0.f) },
198       { Vector2(-halfWidth, -halfHeight), Vector2(1.f, 0.f) },
199       { Vector2(halfWidth, -halfHeight),  Vector2(-1.f, 0.f) },
200       { Vector2(halfWidth, -halfHeight),  Vector2(0.f, 0.f) },
201
202       { Vector2(-halfWidth, -halfHeight), Vector2(0.f, 1.f) },
203       { Vector2(-halfWidth, -halfHeight), Vector2(1.f, 1.f) },
204       { Vector2(halfWidth, -halfHeight),  Vector2(-1.f, 1.f) },
205       { Vector2(halfWidth, -halfHeight),  Vector2(0.f, 1.f) },
206
207       { Vector2(-halfWidth, halfHeight), Vector2(0.f, -1.f) },
208       { Vector2(-halfWidth, halfHeight), Vector2(1.f, -1.f) },
209       { Vector2(halfWidth, halfHeight),  Vector2(-1.f, -1.f) },
210       { Vector2(halfWidth, halfHeight),  Vector2(0.f, -1.f) },
211
212       { Vector2(-halfWidth, halfHeight), Vector2(0.f, 0.f) },
213       { Vector2(-halfWidth, halfHeight), Vector2(1.f, 0.f) },
214       { Vector2(halfWidth, halfHeight),  Vector2(-1.f, 0.f) },
215       { Vector2(halfWidth, halfHeight),  Vector2(0.f, 0.f) },
216   };
217
218   Property::Map borderVertexFormat;
219   borderVertexFormat[POSITION_ATTRIBUTE_NAME] = Property::VECTOR2;
220   borderVertexFormat[DRIFT_ATTRIBUTE_NAME] = Property::VECTOR2;
221   PropertyBuffer borderVertices = PropertyBuffer::New( borderVertexFormat, 16 );
222   borderVertices.SetData(borderVertexData);
223
224   // Create indices
225   unsigned int indexData[48] = { 0, 4, 1, 1, 4, 5, 1, 5, 2, 2, 5, 6, 2, 6,3, 3, 6, 7,
226                                  4, 8, 5, 5, 8, 9, 6, 10, 7, 7, 10, 11,
227                                  8, 12, 9, 9, 12, 13, 9, 13, 10, 10, 13, 14, 10, 11, 14, 11, 14, 15};
228
229   Property::Map indexFormat;
230   indexFormat[INDEX_NAME] = Property::INTEGER;
231   PropertyBuffer indices = PropertyBuffer::New( indexFormat, 48 );
232   indices.SetData(indexData);
233
234   // Create the geometry object
235   Geometry geometry = Geometry::New();
236   geometry.AddVertexBuffer( borderVertices );
237   geometry.SetIndexBuffer( indices );
238
239   return geometry;
240 }
241
242 } // namespace Internal
243
244 } // namespace Toolkit
245
246 } // namespace Dali