Merge "fix ellipsis not working issue when the given width is too narrow" into devel...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / controls / page-turn-view / page-turn-effect.cpp
1 /*
2  * Copyright (c) 2017 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 // EXTERNAL INCLUDES
19 #include <string.h>
20 #include <dali/public-api/animation/constraint.h>
21 #include <dali/public-api/actors/actor.h>
22 #include <dali/public-api/object/property-map.h>
23
24 // INTERNAL INCLUDES
25 #include <dali-toolkit/public-api/visuals/visual-properties.h>
26 #include <dali-toolkit/internal/controls/page-turn-view/page-turn-effect.h>
27 #include <dali-toolkit/internal/graphics/builtin-shader-extern-gen.h>
28
29 using namespace Dali;
30 using namespace Dali::Toolkit;
31
32 namespace
33 {
34 const char * const PROPERTY_COMMON_PARAMETERS( "uCommonParameters" );
35 const char * const PROPERTY_ORIGINAL_CENTER( "originalCenter" );
36 const char * const PROPERTY_CURRENT_CENTER( "currentCenter" );
37 }
38
39 /**
40  * This constraint updates the common parameter values used by every vertex.
41  * By using constraint, they are calculate once in CPU then pass into the vertex shader as uniforms
42  */
43 struct CommonParametersConstraint
44 {
45   CommonParametersConstraint( float pageHeight )
46   : mPageHeight( pageHeight )
47   {}
48
49   void operator()( Dali::Matrix& current, const PropertyInputContainer& inputs )
50   {
51     const Vector2& originalCenter = inputs[0]->GetVector2();
52     Vector2 currentCenter = inputs[1]->GetVector2();
53
54     // calculate the curve direction and the vanishing point
55     // here, the vanishing point is the intersection of spine with the line passing through original center and vertical to curve direction
56     Vector2 curveDirection( currentCenter - originalCenter );
57     curveDirection.Normalize();
58     if( fabs(curveDirection.y) < 0.01f) // eliminate the possibility of division by zero in the next step
59     {
60       curveDirection.y = 0.01f;
61     }
62     float vanishingPointY = originalCenter.y + curveDirection.x * originalCenter.x / curveDirection.y;
63
64     float curveEndY, cosTheta ,sinTheta ,translateX, translateY;
65     // when the vanishing point is very far away, make it infinitely, in this case, the page bent horizontally
66     const float THRESHOLD(20.0);
67     if( fabs(vanishingPointY-mPageHeight*0.5f) >= mPageHeight*THRESHOLD )
68     {
69       curveDirection = Vector2(-1.f,0.f);
70       currentCenter.y = originalCenter.y;
71
72       curveEndY = originalCenter.y;
73       cosTheta = 1.f;
74       sinTheta = 0.f;
75       translateX = currentCenter.x - originalCenter.x;
76       translateY = vanishingPointY;
77     }
78     else
79     {
80       curveEndY = currentCenter.y - curveDirection.y * (currentCenter.x/curveDirection.x) ;
81       Vector2 v1( currentCenter.x, currentCenter.y - vanishingPointY );
82       v1.Normalize();
83       Vector2 v2( originalCenter.x, originalCenter.y - vanishingPointY );
84       v2.Normalize();
85       cosTheta = v1.x*v2.x + v1.y*v2.y;
86       sinTheta = ( vanishingPointY > mPageHeight*0.5f ) ? sqrt(1.0-cosTheta*cosTheta) : -sqrt(1.0-cosTheta*cosTheta);
87       translateX = currentCenter.x - cosTheta*originalCenter.x - sinTheta*( originalCenter.y-vanishingPointY );
88       translateY = currentCenter.y + sinTheta*originalCenter.x - cosTheta*( originalCenter.y-vanishingPointY );
89     }
90
91     float originalLength = fabs(originalCenter.x/curveDirection.x);
92     float currentLength = fabs(currentCenter.x/curveDirection.x);
93     float curveHeight = 0.45f*sqrt(originalLength*originalLength - currentLength*currentLength);
94
95     float* parameterArray = current.AsFloat();
96     parameterArray[0] = cosTheta;
97     parameterArray[1] = -sinTheta;
98     parameterArray[2] = originalCenter.x;
99     parameterArray[3] = originalCenter.y;
100     parameterArray[4] = sinTheta;
101     parameterArray[5] = cosTheta;
102     parameterArray[6] = currentCenter.x;
103     parameterArray[7] = currentCenter.y;
104     parameterArray[8] = translateX;
105     parameterArray[9] = translateY;
106     parameterArray[10] = vanishingPointY;
107     parameterArray[11] = curveEndY;
108     parameterArray[12] = curveDirection.x;
109     parameterArray[13] = curveDirection.y;
110     parameterArray[14] = curveHeight;
111     parameterArray[15] = currentLength;
112   }
113
114   float mPageHeight;
115 };
116
117 void Dali::Toolkit::Internal::PageTurnApplyInternalConstraint( Actor& actor, float pageHeight )
118 {
119   Constraint constraint = Constraint::New<Dali::Matrix>( actor, actor.GetPropertyIndex( PROPERTY_COMMON_PARAMETERS ) , CommonParametersConstraint( pageHeight ) );
120   constraint.AddSource( LocalSource( actor.GetPropertyIndex( PROPERTY_ORIGINAL_CENTER ) ) );
121   constraint.AddSource( LocalSource( actor.GetPropertyIndex( PROPERTY_CURRENT_CENTER ) ) );
122   constraint.Apply();
123 }
124
125 Property::Map Dali::Toolkit::Internal::CreatePageTurnEffect()
126 {
127   Property::Map map;
128
129   Property::Map customShader;
130
131   customShader[ Toolkit::Visual::Shader::Property::VERTEX_SHADER ] = SHADER_PAGE_TURN_EFFECT_VERT.data();
132   customShader[ Toolkit::Visual::Shader::Property::FRAGMENT_SHADER ] = SHADER_PAGE_TURN_EFFECT_FRAG.data();
133   customShader[ Toolkit::Visual::Shader::Property::SUBDIVIDE_GRID_X ] = 20;
134   customShader[ Toolkit::Visual::Shader::Property::SUBDIVIDE_GRID_Y ] = 20;
135
136   map[ Toolkit::Visual::Property::SHADER ] = customShader;
137   return map;
138
139 }