5d3fb1e1d8901b8ee620c4236ae8a2ab80bb37c3
[platform/core/csapi/tizenfx.git] / src / Tizen.NUI.Wearable / src / public / Title.cs
1 /*
2  * Copyright(c) 2020 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 using System;
18 using System.ComponentModel;
19 using System.Runtime.InteropServices;
20 using Tizen.NUI.BaseComponents;
21 using Tizen.NUI.Binding;
22
23 namespace Tizen.NUI.Components
24 {
25     /// <summary>
26     /// Use it to set the title. this has a fadeout effect.
27     /// You can also set the color of the fadeout.
28     /// </summary>
29     /// <since_tizen> 8 </since_tizen>
30     /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
31     [EditorBrowsable(EditorBrowsableState.Never)]
32     public class Title : TextLabel
33     {
34         private const string VERTEX_SHADER =
35                         "attribute mediump vec2 aPosition;\n" +
36                         "varying mediump vec2 vTexCoord;\n" +
37                         "uniform highp mat4 uMvpMatrix;\n" +
38                         "uniform mediump vec3 uSize;\n" +
39                         "varying mediump vec2 sTexCoordRect;\n" +
40                         "void main()\n" +
41                         "{\n" +
42                         "   gl_Position = uMvpMatrix * vec4(aPosition * uSize.xy, 0.0, 1.0);\n" +
43                         "   vTexCoord = aPosition + vec2(0.5);\n" +
44                         "}\n";
45
46         private const string FRAGMENT_SHADER =
47                         "uniform lowp vec4 uColor;\n" +
48                         "varying mediump vec2 vTexCoord;\n" +
49                         "uniform sampler2D sTexture;\n" +
50                         "void main()\n" +
51                         "{\n" +
52                         "   gl_FragColor = texture2D(sTexture, vTexCoord) * uColor;\n" +
53                         "}\n";
54
55         private ImageView leftImage = null;
56         private ImageView rightImage = null;
57         private Geometry geometry = null;
58         private Shader shader = null;
59         private Renderer leftRenderer = null;
60         private Renderer rightRenderer = null;
61         private Color fadeOutColor;
62         private bool isFadeOutColorSet = false;
63         private int fadeOutWidth = 32; // default size
64
65         /// <summary>
66         /// </summary>
67         /// <since_tizen> 8 </since_tizen>
68         static Title() { }
69
70         /// <summary>
71         /// Construct Title with null.
72         /// </summary>
73         /// <since_tizen> 8 </since_tizen>
74         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
75         [EditorBrowsable(EditorBrowsableState.Never)]
76         public Title() : base()
77         {
78             Initialize();
79         }
80
81         /// <summary>
82         /// The constructor of the Title class with specific Style.
83         /// </summary>
84         /// <param name="textLabelStyle">Construct Style</param>
85         /// <since_tizen> 8 </since_tizen>
86         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
87         [EditorBrowsable(EditorBrowsableState.Never)]
88         public Title(TextLabelStyle textLabelStyle) : base(textLabelStyle)
89         {
90             Initialize();
91         }
92
93         /// <summary>
94         /// Constructor of the Title class with special style.
95         /// </summary>
96         /// <param name="style"> style name </param>
97         /// <since_tizen> 8 </since_tizen>
98         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
99         [EditorBrowsable(EditorBrowsableState.Never)]
100         public Title(string style) : base(style)
101         {
102             Initialize();
103         }
104
105         /// <summary>
106         /// Sets the start and end color of the fadeout.
107         /// </summary>
108         /// <since_tizen> 8 </since_tizen>
109         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
110         [EditorBrowsable(EditorBrowsableState.Never)]
111         public Color FadeOutColor
112         {
113             get
114             {
115                 return fadeOutColor;
116             }
117             set
118             {
119                 fadeOutColor = value;
120                 isFadeOutColorSet = true;
121                 UpdateImage();
122             }
123         }
124
125         /// <summary>
126         /// Gets or Sets the width of the fadeout effect.
127         /// </summary>
128         /// <since_tizen> 8 </since_tizen>
129         /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
130         [EditorBrowsable(EditorBrowsableState.Never)]
131         public int FadeOutWidth
132         {
133             get
134             {
135                 return fadeOutWidth;
136             }
137             set
138             {
139                 fadeOutWidth = value;
140                 UpdateImage();
141             }
142         }
143
144         /// <summary>
145         /// Dispose Title.
146         /// </summary>
147         /// <param name="type">dispose types.</param>
148         /// <since_tizen> 8 </since_tizen>
149         protected override void Dispose(DisposeTypes type)
150         {
151             if (disposed)
152             {
153                 return;
154             }
155
156             if (type == DisposeTypes.Explicit)
157             {
158                 if (null != leftImage)
159                 {
160                     leftImage.Unparent();
161                     leftImage.Dispose();
162                     leftImage = null;
163                 }
164                 if (null != rightImage)
165                 {
166                     rightImage.Unparent();
167                     rightImage.Dispose();
168                     rightImage = null;
169                 }
170             }
171             base.Dispose(type);
172         }
173
174         private void UpdateImage()
175         {
176             leftImage.SizeWidth = fadeOutWidth;
177             rightImage.SizeWidth = fadeOutWidth;
178
179             if (fadeOutWidth > 0)
180             {
181                 Color startColor = new Color(fadeOutColor.R, fadeOutColor.G, fadeOutColor.B, 0.6F);
182                 Color endColor = new Color(fadeOutColor.R, fadeOutColor.G, fadeOutColor.B, 0.0F);
183
184                 TextureSet leftTextureSet = CreateTexture(startColor, endColor);
185                 TextureSet rightTextureSet = CreateTexture(endColor, startColor);
186
187                 leftImage.RemoveRenderer(leftRenderer);
188                 rightImage.RemoveRenderer(rightRenderer);
189
190                 if (this.EnableAutoScroll)
191                 {
192                     leftRenderer.SetTextures(leftTextureSet);
193                     rightRenderer.SetTextures(rightTextureSet);
194
195                     leftImage.AddRenderer(leftRenderer);
196                     rightImage.AddRenderer(rightRenderer);
197                 }
198                 else if (this.TextDirection == TextDirection.LeftToRight)
199                 {
200                     rightRenderer.SetTextures(rightTextureSet);
201                     rightImage.AddRenderer(rightRenderer);
202                 }
203                 else
204                 {
205                     leftRenderer.SetTextures(leftTextureSet);
206                     leftImage.AddRenderer(leftRenderer);
207                 }
208             }
209
210             this.Ellipsis = false;
211             this.HorizontalAlignment = HorizontalAlignment.Center;
212             this.VerticalAlignment = VerticalAlignment.Center;
213         }
214
215         private void Initialize()
216         {
217             leftImage = new ImageView();
218             leftImage.PositionUsesPivotPoint = true;
219             leftImage.ParentOrigin = Tizen.NUI.ParentOrigin.TopLeft;
220             leftImage.PivotPoint = Tizen.NUI.PivotPoint.TopLeft;
221             leftImage.WidthResizePolicy = ResizePolicyType.FillToParent;
222             leftImage.HeightResizePolicy = ResizePolicyType.FillToParent;
223             this.Add(leftImage);
224
225             rightImage = new ImageView();
226             rightImage.PositionUsesPivotPoint = true;
227             rightImage.ParentOrigin = Tizen.NUI.ParentOrigin.TopRight;
228             rightImage.PivotPoint = Tizen.NUI.PivotPoint.TopRight;
229             rightImage.WidthResizePolicy = ResizePolicyType.FillToParent;
230             rightImage.HeightResizePolicy = ResizePolicyType.FillToParent;
231             this.Add(rightImage);
232
233             geometry = CreateQuadGeometry();
234
235             shader = new Shader(VERTEX_SHADER, FRAGMENT_SHADER);
236
237             leftRenderer = new Renderer(geometry, shader);
238
239             rightRenderer = new Renderer(geometry, shader);
240
241             fadeOutColor = this.BackgroundColor;
242
243             PropertyChanged += TitlePropertyChanged;
244
245             UpdateImage();
246         }
247
248         private void TitlePropertyChanged(object sender, PropertyChangedEventArgs e)
249         {
250             if (isFadeOutColorSet == false  && e.PropertyName.Equals("BackgroundColor") )
251             {
252                 fadeOutColor = this.BackgroundColor;
253                 UpdateImage();
254             }
255         }
256
257         private TextureSet CreateTexture(Vector4 color1, Vector4 color2)
258         {
259             TextureSet textureSet = new TextureSet();
260             const int width = 2;
261             const int height = 1;
262             uint size = width * height * 4;
263             byte[] pixelBuffer = new byte[size];
264             pixelBuffer[0] = (byte)(0xFF * color1.X);
265             pixelBuffer[1] = (byte)(0xFF * color1.Y);
266             pixelBuffer[2] = (byte)(0xFF * color1.Z);
267             pixelBuffer[3] = (byte)(0xFF * color1.W);
268             pixelBuffer[4] = (byte)(0xFF * color2.X);
269             pixelBuffer[5] = (byte)(0xFF * color2.Y);
270             pixelBuffer[6] = (byte)(0xFF * color2.Z);
271             pixelBuffer[7] = (byte)(0xFF * color2.W);
272
273             PixelData pixelData = new PixelData(pixelBuffer, size, width, height, PixelFormat.RGBA8888);
274             Texture texture = new Texture(TextureType.TEXTURE_2D, PixelFormat.RGBA8888, width, height);
275             texture.Upload(pixelData);
276
277             textureSet.SetTexture(0u, texture);
278             return textureSet;
279         }
280
281         private PropertyBuffer CreatePropertyBuffer()
282         {
283             PropertyMap vertexFormat = new PropertyMap();
284             vertexFormat.Add("aPosition", new PropertyValue((int)PropertyType.Vector2));
285             PropertyBuffer vertexBuffer = new PropertyBuffer(vertexFormat);
286             return vertexBuffer;
287         }
288
289         private struct Vec2
290         {
291             float x;
292             float y;
293             public Vec2(float xIn, float yIn)
294             {
295                 x = xIn;
296                 y = yIn;
297             }
298         }
299
300         private struct TexturedQuadVertex
301         {
302             public Vec2 position;
303         };
304
305         private byte[] Struct2Bytes(TexturedQuadVertex[] obj)
306         {
307             int size = Marshal.SizeOf(obj);
308             byte[] bytes = new byte[size];
309             IntPtr ptr = Marshal.AllocHGlobal(size);
310             Marshal.StructureToPtr(obj, ptr, false);
311             Marshal.Copy(ptr, bytes, 0, size);
312             Marshal.FreeHGlobal(ptr);
313             return bytes;
314         }
315
316         private Geometry CreateQuadGeometry()
317         {
318             PropertyBuffer vertexData = CreatePropertyBuffer();
319
320             TexturedQuadVertex vertex1 = new TexturedQuadVertex();
321             TexturedQuadVertex vertex2 = new TexturedQuadVertex();
322             TexturedQuadVertex vertex3 = new TexturedQuadVertex();
323             TexturedQuadVertex vertex4 = new TexturedQuadVertex();
324             vertex1.position = new Vec2(-0.5f, -0.5f);
325             vertex2.position = new Vec2(-0.5f, 0.5f);
326             vertex3.position = new Vec2(0.5f, -0.5f);
327             vertex4.position = new Vec2(0.5f, 0.5f);
328
329
330             TexturedQuadVertex[] texturedQuadVertexData = new TexturedQuadVertex[4] { vertex1, vertex2, vertex3, vertex4 };
331
332             int lenght = Marshal.SizeOf(vertex1);
333             IntPtr pA = Marshal.AllocHGlobal(lenght * 4);
334
335             for (int i = 0; i < 4; i++)
336             {
337                 Marshal.StructureToPtr(texturedQuadVertexData[i], pA + i * lenght, true);
338             }
339             vertexData.SetData(pA, 4);
340
341             Geometry geometry = new Geometry();
342             geometry.AddVertexBuffer(vertexData);
343             geometry.SetType(Geometry.Type.TRIANGLE_STRIP);
344             return geometry;
345         }
346
347     }
348 }