Updated visuals to separate alpha channel from mixColor
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / visuals / visual-base-impl.h
1 #ifndef DALI_TOOLKIT_INTERNAL_VISUAL_H
2 #define DALI_TOOLKIT_INTERNAL_VISUAL_H
3
4 /*
5  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/animation/animation.h>
23 #include <dali/public-api/common/intrusive-ptr.h>
24 #include <dali/public-api/images/image-operations.h>
25 #include <dali/public-api/object/base-object.h>
26 #include <dali/public-api/rendering/renderer.h>
27 #include <dali/public-api/rendering/shader.h>
28
29 // INTERNAL INCLUDES
30 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
31 #include <dali-toolkit/devel-api/visual-factory/visual-base.h>
32 #include <dali-toolkit/internal/visuals/transition-data-impl.h>
33 #include <dali-toolkit/internal/visuals/visual-factory-cache.h>
34
35 namespace Dali
36 {
37
38 namespace Toolkit
39 {
40
41 namespace Internal
42 {
43
44 namespace Visual
45 {
46
47 /**
48  * Base class for all Control rendering logic. A control may have multiple visuals.
49  *
50  * Note: The visual responds to the the Actor::COLOR by blending it with the 'Multiply' operator.
51  *
52  * The following properties are optional
53  *
54  * | %Property Name          | Type             |
55  * |-------------------------|------------------|
56  * | customShader            | MAP              |
57  *
58  * where custom-shader is a map with the following properties:
59  * | %Property Name          | Type             |
60  * |-------------------------|------------------|
61  * | vertexShader            | STRING           |
62  * | fragmentShader          | STRING           |
63  * | subdivideGridX          | INT              |
64  * | subdivideGridY          | INT              |
65  * | shaderHints             | INT              |
66  */
67 class Base : public BaseObject
68 {
69 public:
70
71   /**
72    * Setting the properties of the visual, this API should only called by the VisualFactory
73    * @param[in] propertyMap The properties for the requested Visual object.
74    */
75   void SetProperties( const Property::Map& propertyMap );
76
77   /**
78    * @copydoc Toolkit::Visual::Base::SetName
79    */
80   void SetName( const std::string& name );
81
82   /**
83    * @copydoc Toolkit::Visual::Base::GetName
84    */
85   const std::string& GetName();
86
87   /**
88    * @copydoc Toolkit::Visual::Base::SetSize
89    */
90   void SetTransformAndSize( const Property::Map& transform, Size controlSize );
91
92   /**
93    * @copydoc Toolkit::Visual::Base::GetHeightForWidth
94    */
95   virtual float GetHeightForWidth( float width );
96
97   /**
98    * @copydoc Toolkit::Visual::Base::GetWidthForHeight
99    */
100   virtual float GetWidthForHeight( float height );
101
102   /**
103    * @copydoc Toolkit::Visual::Base::GetNaturalSize
104    */
105   virtual void GetNaturalSize( Vector2& naturalSize );
106
107   /**
108    * @copydoc Toolkit::Visual::Base::SetDepthIndex
109    */
110   void SetDepthIndex( float index );
111
112   /**
113    * @copydoc Toolkit::Visual::Base::GetDepthIndex
114    */
115   float GetDepthIndex() const;
116
117   /**
118    * @copydoc Toolkit::Visual::Base::SetOnStage
119    * @pre Impl->mGeometry must be created before this method is called
120    */
121   void SetOnStage( Actor& actor );
122
123   /**
124    * @copydoc Toolkit::Visual::Base::SetOffStage
125    */
126   void SetOffStage( Actor& actor );
127
128   /**
129    * @copydoc Toolkit::Visual::Base::CreatePropertyMap
130    */
131   void CreatePropertyMap( Property::Map& map ) const;
132
133   /**
134    * @brief Set whether the Pre-multiplied Alpha Blending is required
135    *
136    * @param[in] preMultipled whether alpha is pre-multiplied.
137    */
138   void EnablePreMultipliedAlpha( bool preMultipled );
139
140   /**
141    * @brief Query whether alpha is pre-multiplied.
142    *
143    * @return True is alpha is pre-multiplied, false otherwise.
144    */
145   bool IsPreMultipliedAlphaEnabled() const;
146
147   /**
148    * @brief Sets properties of custom shader
149    * @param[in] propertyMap Property map containing the custom shader data
150    */
151   void SetCustomShader( const Property::Map& propertyMap );
152
153   /**
154    * @copydoc Toolkit::Visual::Base::SetProperty
155    */
156   void SetProperty( Dali::Property::Index index, const Dali::Property::Value& propertyValue );
157
158   /**
159    * @copydoc Toolkit::Visual::Base::GetProperty
160    */
161   Dali::Property::Value GetProperty( Dali::Property::Index index );
162
163   /**
164    * Gets currently staged renderer, or an empty handle if not staged
165    */
166   Renderer GetRenderer();
167
168   /**
169    * Sets the mix color ( including opacity )  of the visual.
170    * @param[in] mixColor The new mix color
171    */
172   void SetMixColor( const Vector4& color );
173
174   /**
175    * Sets the mix color of the visual.
176    * @param[in] mixColor The new mix color
177    */
178   void SetMixColor( const Vector3& color );
179
180   /**
181    * Gets the mix color of the visual.
182    * @return The mix color
183    */
184   const Vector4& GetMixColor() const;
185
186   /**
187    * Animate the property if it exists in the visual or renderer.
188    *
189    * If it's a visual property such as mix color or a transform property,
190    * saves the target value to the local data.
191    *
192    * If the visual isn't staged (i.e. it doesn't have a renderer),
193    * then this will not add an animation.
194    *
195    * @param[in] transition The animation to create or attach to
196    * @param[in] animator The animation parameters of the property.
197    */
198   void AnimateProperty( Dali::Animation& transition,
199                         Internal::TransitionData::Animator& animator );
200
201 protected:
202
203   /**
204    * @brief Constructor.
205    *
206    * @param[in] factoryCache A pointer pointing to the VisualFactoryCache object
207    */
208   Base( VisualFactoryCache& factoryCache );
209
210   /**
211    * @brief A reference counted object may only be deleted by calling Unreference().
212    */
213   virtual ~Base();
214
215 protected:
216
217   /**
218    * @brief Called by CreatePropertyMap() allowing sub classes to respond to the CreatePropertyMap event
219    *
220    * @param[out] map The visual property map.
221    */
222   virtual void DoCreatePropertyMap( Property::Map& map ) const = 0;
223
224   /**
225    * @brief Called by SetProperties() allowing sub classes to set their properties
226    *
227    * @param[in] propertyMap The properties for the requested Visual object.
228    */
229   virtual void DoSetProperties( const Property::Map& propertyMap ) = 0;
230
231   /**
232    * @brief Called when transform or control size changes
233    * ( Of use to SVG and Text visuals )
234    */
235   virtual void OnSetTransform() = 0;
236
237   /**
238    * @brief Called by SetOnStage() allowing sub classes to respond to the SetOnStage event
239    *
240    * @note The derived class is required to create the renderer, and add it to the actor when all the resources are in place.
241    *
242    * @param[in] actor The actor applying this visual.
243    */
244   virtual void DoSetOnStage( Actor& actor )=0;
245
246   /**
247    * @brief Called by SetOffStage() allowing sub classes to respond to the SetOffStage event
248    *
249    * @param[in] actor The actor applying this visual.
250    */
251   virtual void DoSetOffStage( Actor& actor );
252
253 protected:
254
255   /**
256    * @brief Gets the on stage state for this Visual
257    *
258    * @return Returns true if this Visual is on stage, false if it is off the stage
259    */
260   bool IsOnStage() const;
261
262   /**
263    * @brief Gets whether the Dali::Renderer is from a shared cache (and therefore any modifications will affect other users of that renderer)
264    *
265    * @return Returns true if the renderer is from shared cache, false otherwise
266    */
267   bool IsFromCache() const;
268
269 private:
270
271   /**
272    * Register the mix color uniform on the Renderer and store the property index.
273    * Note, this is not used by Color or Primitive Visuals, which will use their
274    * own property index.
275    */
276   void RegisterMixColor();
277
278   /**
279    * Find the matching property on the renderer or shader. If it's a shader
280    * property, register it on the renderer in order to animate it for this
281    * visual independently.
282    * @param[in] key The key to match.
283    * @return the matching index, or INVALID_INDEX if it's not found
284    */
285   Property::Index GetPropertyIndex( Property::Key key );
286
287   /**
288    * Set up the transition. If no animation is required, then
289    * transition will be untouched.
290    *
291    * @param[in] transition The transition to use or set up.
292    * @param[in] animator The animation data to use
293    * @param[in] index The property index on the renderer to animate
294    * @param[in] initialValue The optional initial value
295    * @param[in] targetValue The target value to use
296    */
297   void SetupTransition( Dali::Animation& transition,
298                         Internal::TransitionData::Animator& animator,
299                         Property::Index index,
300                         Property::Value& initialValue,
301                         Property::Value& targetValue );
302
303   /**
304    * Animate the opacity property - Special handling to
305    * ensure that the blend mode is set to ON whilst animating,
306    * and set back to AUTO if it's opaque at the end of the
307    * animation.
308    *
309    * @param[in] transition The transition to use or set up.
310    * @param[in] animator The animation data to use
311    */
312   void AnimateOpacityProperty( Dali::Animation& transition,
313                                Internal::TransitionData::Animator& animator );
314
315   /**
316    * Animate the renderer property - no special handling
317    *
318    * @param[in] transition The transition to use or set up.
319    * @param[in] animator The animation data to use
320    */
321   void AnimateRendererProperty( Dali::Animation& transition,
322                                 Internal::TransitionData::Animator& animator );
323
324   /**
325    * Animate the mix color property.
326    *
327    * If the animator is a vec3, then it only animates the color
328    * channels without animating the opacity.  If it's a vec4, then it
329    * runs 2 animators, one for the the vec3 mixColor, and one for the
330    * opacity. (They are separate uniforms in the shader )
331    *
332    * @param[in] transition The transition to use or set up.
333    * @param[in] animator The animation data to use
334    */
335   void AnimateMixColorProperty( Dali::Animation& transition,
336                                 Internal::TransitionData::Animator& animator );
337
338   /**
339    * Set up the right blend mode if the opacity is being animated.
340    * Also ensure that when the animation finishes, the blend mode is
341    * set to the appropriate value. It also uses the target value as
342    * set into mMixColor.
343    *
344    * @param[in] transition The transition to listen to
345    * @param[in] isInitialOpaque Whether the initial value is opaque
346    * @param[in] animating If the transition animates the value.
347    */
348   void SetupBlendMode( Dali::Animation& transition,
349                        bool isInitialOpaque, bool animating );
350
351   /**
352    * When a mix color animation has finished, ensure the blend mode is set back
353    * to the right value for the target opacity.
354    */
355   void OnMixColorFinished( Animation& animation );
356
357   // Undefined
358   Base( const Visual::Base& visual );
359
360   // Undefined
361   Base& operator=( const Visual::Base& visual );
362
363 protected:
364   struct Impl;
365   Impl* mImpl;
366   VisualFactoryCache& mFactoryCache;
367 };
368
369 typedef IntrusivePtr<Base> BasePtr;
370
371 } // namspace Visual
372
373 } // namespace Internal
374
375 inline const Internal::Visual::Base& GetImplementation(const Toolkit::Visual::Base& visualBase )
376 {
377   DALI_ASSERT_ALWAYS( visualBase && "visual base handle is empty" );
378
379   const BaseObject& handle = visualBase.GetBaseObject();
380
381   return static_cast<const Internal::Visual::Base&>(handle);
382 }
383
384 inline Internal::Visual::Base& GetImplementation(Toolkit::Visual::Base& visualBase)
385 {
386   DALI_ASSERT_ALWAYS( visualBase && "visual base handle is empty" );
387
388   BaseObject& handle = visualBase.GetBaseObject();
389
390   return static_cast<Internal::Visual::Base&>(handle);
391 }
392
393 } // namespace Toolkit
394
395 } // namespace Dali
396
397 #endif // DALI_TOOLKIT_INTERNAL_VISUAL_H