Create Renderer when the Visual is created
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / arc / arc-visual.cpp
1 /*
2  * Copyright (c) 2021 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 <dali-toolkit/internal/visuals/arc/arc-visual.h>
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 //INTERNAL INCLUDES
25 #include <dali-toolkit/devel-api/visuals/visual-properties-devel.h>
26 #include <dali-toolkit/devel-api/visuals/arc-visual-actions-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/graphics/builtin-shader-extern-gen.h>
32
33 namespace Dali
34 {
35
36 namespace Toolkit
37 {
38
39 namespace Internal
40 {
41
42 namespace
43 {
44
45 // cap
46 DALI_ENUM_TO_STRING_TABLE_BEGIN( CAP )
47 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelArcVisual::Cap, BUTT )
48 DALI_ENUM_TO_STRING_WITH_SCOPE( DevelArcVisual::Cap, ROUND )
49 DALI_ENUM_TO_STRING_TABLE_END( CAP )
50
51 }
52
53 ArcVisualPtr ArcVisual::New( VisualFactoryCache& factoryCache, const Property::Map& properties )
54 {
55   ArcVisualPtr arcVisualPtr( new ArcVisual( factoryCache ) );
56   arcVisualPtr->SetProperties( properties );
57   arcVisualPtr->Initialize();
58   return arcVisualPtr;
59 }
60
61 ArcVisual::ArcVisual( VisualFactoryCache& factoryCache )
62 : Visual::Base( factoryCache, Visual::FittingMode::FILL, static_cast<Toolkit::Visual::Type>( Toolkit::DevelVisual::ARC ) ),
63   mThickness( 0.0f ),
64   mRadius( 0.0f ),
65   mStartAngle( 0.0f ),
66   mSweepAngle( 360.0f ),
67   mRadiusIndex( Property::INVALID_INDEX ),
68   mThicknessIndex( Property::INVALID_INDEX ),
69   mStartAngleIndex( Property::INVALID_INDEX ),
70   mSweepAngleIndex( Property::INVALID_INDEX ),
71   mCapType( DevelArcVisual::Cap::BUTT )
72 {
73 }
74
75 ArcVisual::~ArcVisual()
76 {
77 }
78
79 void ArcVisual::DoSetProperties( const Property::Map& propertyMap )
80 {
81   Property::Value* thicknessValue = propertyMap.Find( Toolkit::DevelArcVisual::Property::THICKNESS, THICKNESS_NAME );
82   if( thicknessValue )
83   {
84     if( !thicknessValue->Get( mThickness ) )
85     {
86       DALI_LOG_ERROR( "ArcVisual:DoSetProperties:: THICKNESS property has incorrect type: %d\n", thicknessValue->GetType() );
87     }
88     else
89     {
90       if( mImpl->mRenderer )
91       {
92         mImpl->mRenderer.SetProperty( mThicknessIndex, mThickness );
93
94         // Need to calculate radius again
95         OnSetTransform();
96       }
97     }
98   }
99
100   Property::Value* startAngleValue = propertyMap.Find( Toolkit::DevelArcVisual::Property::START_ANGLE, START_ANGLE_NAME );
101   if( startAngleValue )
102   {
103     if( !startAngleValue->Get( mStartAngle ) )
104     {
105       DALI_LOG_ERROR( "ArcVisual:DoSetProperties:: START_ANGLE property has incorrect type: %d\n", startAngleValue->GetType() );
106     }
107     else
108     {
109       if( mImpl->mRenderer )
110       {
111         mImpl->mRenderer.SetProperty( mStartAngleIndex, mStartAngle );
112       }
113     }
114   }
115
116   Property::Value* sweepAngleValue = propertyMap.Find( Toolkit::DevelArcVisual::Property::SWEEP_ANGLE, SWEEP_ANGLE_NAME );
117   if( sweepAngleValue )
118   {
119     if( !sweepAngleValue->Get( mSweepAngle ) )
120     {
121       DALI_LOG_ERROR( "ArcVisual:DoSetProperties:: SWEEP_ANGLE property has incorrect type: %d\n", sweepAngleValue->GetType() );
122     }
123     else
124     {
125       if( mImpl->mRenderer )
126       {
127         mImpl->mRenderer.SetProperty( mSweepAngleIndex, mSweepAngle );
128       }
129     }
130   }
131
132   Property::Value* capValue = propertyMap.Find( Toolkit::DevelArcVisual::Property::CAP, CAP_NAME );
133   if( capValue )
134   {
135     int capType = 0;
136     Scripting::GetEnumerationProperty( *capValue, CAP_TABLE, CAP_TABLE_COUNT, capType );
137     mCapType = Toolkit::DevelArcVisual::Cap::Type( capType );
138   }
139 }
140
141 void ArcVisual::DoSetOnScene( Actor& actor )
142 {
143   actor.AddRenderer( mImpl->mRenderer );
144
145   // Arc Visual generated and ready to display
146   ResourceReady( Toolkit::Visual::ResourceStatus::READY );
147 }
148
149 void ArcVisual::DoSetOffScene(Actor& actor)
150 {
151   actor.RemoveRenderer(mImpl->mRenderer);
152 }
153
154 void ArcVisual::DoCreatePropertyMap( Property::Map& map ) const
155 {
156   float thickness, startAngle, sweepAngle;
157   if(mImpl->mRenderer)
158   {
159     // Update values from Renderer
160     thickness  = mImpl->mRenderer.GetProperty<float>(mThicknessIndex);
161     startAngle = mImpl->mRenderer.GetProperty<float>(mStartAngleIndex);
162     sweepAngle = mImpl->mRenderer.GetProperty<float>(mSweepAngleIndex);
163   }
164   else
165   {
166     thickness  = mThickness;
167     startAngle = mStartAngle;
168     sweepAngle = mSweepAngle;
169   }
170
171   map.Clear();
172   map.Insert( Toolkit::Visual::Property::TYPE, Toolkit::DevelVisual::ARC );
173   map.Insert(Toolkit::DevelArcVisual::Property::THICKNESS, thickness);
174   map.Insert(Toolkit::DevelArcVisual::Property::START_ANGLE, startAngle);
175   map.Insert(Toolkit::DevelArcVisual::Property::SWEEP_ANGLE, sweepAngle);
176   map.Insert( Toolkit::DevelArcVisual::Property::CAP, mCapType );
177 }
178
179 void ArcVisual::DoCreateInstancePropertyMap( Property::Map& map ) const
180 {
181   // Do nothing
182 }
183
184 void ArcVisual::OnSetTransform()
185 {
186   Vector2 visualSize = mImpl->mTransform.GetVisualSize( mImpl->mControlSize );
187   mRadius = ( std::min( visualSize.width, visualSize.height ) - mThickness ) / 2.0f;
188
189   if( mImpl->mRenderer )
190   {
191     mImpl->mRenderer.SetProperty( mRadiusIndex, mRadius );
192   }
193 }
194
195 void ArcVisual::OnDoAction( const Property::Index actionId, const Property::Value& attributes )
196 {
197   // Check if action is valid for this visual type and perform action if possible
198   switch( actionId )
199   {
200     case DevelArcVisual::Action::UPDATE_PROPERTY:
201     {
202       const Property::Map* map = attributes.GetMap();
203       if( map )
204       {
205         DoSetProperties( *map );
206       }
207       break;
208     }
209   }
210 }
211
212 void ArcVisual::OnInitialize()
213 {
214   Geometry geometry = mFactoryCache.GetGeometry( VisualFactoryCache::QUAD_GEOMETRY );
215
216   Shader shader;
217   if( mCapType == DevelArcVisual::Cap::BUTT )
218   {
219     shader = mFactoryCache.GetShader( VisualFactoryCache::ARC_BUTT_CAP_SHADER );
220     if( !shader )
221     {
222       shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + SHADER_ARC_VISUAL_SHADER_VERT.data(), Dali::Shader::GetFragmentShaderPrefix() + SHADER_ARC_VISUAL_BUTT_CAP_SHADER_FRAG.data() );
223       mFactoryCache.SaveShader( VisualFactoryCache::ARC_BUTT_CAP_SHADER, shader );
224     }
225   }
226   else
227   {
228     shader = mFactoryCache.GetShader( VisualFactoryCache::ARC_ROUND_CAP_SHADER );
229     if( !shader )
230     {
231       shader = Shader::New( Dali::Shader::GetVertexShaderPrefix() + SHADER_ARC_VISUAL_SHADER_VERT.data(), Dali::Shader::GetFragmentShaderPrefix() + SHADER_ARC_VISUAL_ROUND_CAP_SHADER_FRAG.data() );
232       mFactoryCache.SaveShader( VisualFactoryCache::ARC_ROUND_CAP_SHADER, shader );
233     }
234   }
235
236   mImpl->mRenderer = Renderer::New( geometry, shader );
237
238   mThicknessIndex  = mImpl->mRenderer.RegisterProperty(DevelArcVisual::Property::THICKNESS, THICKNESS_NAME, mThickness);
239   mStartAngleIndex = mImpl->mRenderer.RegisterProperty(DevelArcVisual::Property::START_ANGLE, START_ANGLE_NAME, mStartAngle);
240   mSweepAngleIndex = mImpl->mRenderer.RegisterProperty(DevelArcVisual::Property::SWEEP_ANGLE, SWEEP_ANGLE_NAME, mSweepAngle);
241
242   mRadiusIndex = mImpl->mRenderer.RegisterProperty( RADIUS_NAME, mRadius );
243
244   mImpl->mRenderer.SetProperty( Renderer::Property::BLEND_MODE, BlendMode::ON );
245
246   // Register transform properties
247   mImpl->mTransform.RegisterUniforms( mImpl->mRenderer, Direction::LEFT_TO_RIGHT );
248 }
249
250 } // namespace Internal
251
252 } // namespace Toolkit
253
254 } // namespace Dali