Adds and modifies comment of TV MediaHub
[profile/tv/apps/dotnet/mediahub.git] / TVMediaHub / TVMediaHub.Tizen / Views / VideoItem.xaml.cs
1 /*
2  * Copyright (c) 2017 Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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 Tizen.Content.MediaContent;
20 using TVMediaHub.Tizen.Utils;
21 using Xamarin.Forms;
22
23 namespace TVMediaHub.Tizen.Views
24 {
25     /// <summary>
26     /// A custom view for displaying video item
27     /// </summary>
28     public partial class VideoItem : RelativeLayout
29     {
30         /// <summary>
31         /// A flag that whether the item is loaded or not
32         /// </summary>
33         private bool IsLoaded = false;
34
35         /// <summary>
36         /// An enumeration for ItemStatus
37         /// </summary>
38         public enum ItemStatus
39         {
40             NORMAL = 0,
41             SELECTED,
42         };
43
44         /// <summary>
45         /// A value of current ItemStatus
46         /// </summary>
47         private ItemStatus CurStatus;
48
49         private Rectangle NormalShadowBounds;
50         private Rectangle FocusedShadowBounds;
51         private Rectangle FocusedBounds;
52         private Rectangle NormalBounds;
53
54         private Rectangle NormalContentImageBounds;
55         private Rectangle FocusedContentImageBounds;
56
57         private Rectangle PlayIconBounds;
58
59         private Rectangle TitleContainerBounds;
60
61         /// <summary>
62         /// An EventHandler for focus event of item
63         /// </summary>
64         public EventHandler OnFocusedEventHandler;
65         /// <summary>
66         /// An EventHandler for unfocus event of item
67         /// </summary>
68         public EventHandler OnUnfocusedEventHandler;
69         /// <summary>
70         /// A delegate will be executed when the item is clicked
71         /// </summary>
72         /// <param name="info">A clicked item's MediaInformation</param>
73         public delegate void ClickEventHandler(MediaInformation info);
74         /// <summary>
75         /// A ClickEventHandler for click event of the item
76         /// </summary>
77         public ClickEventHandler OnItemClickedHandler;
78
79         /// <summary>
80         /// Identifies the IsDeleteMode bindable property
81         /// </summary>
82         public static readonly BindableProperty IsDeleteModeProperty = BindableProperty.Create("IsDeleteMode", typeof(bool), typeof(VideoItem), false);
83
84         /// <summary>
85         /// Gets or sets the value whether item is delete mode or not
86         /// </summary>
87         public bool IsDeleteMode
88         {
89             set
90             {
91                 SetValue(IsDeleteModeProperty, value);
92             }
93
94             get
95             {
96                 return (bool)GetValue(IsDeleteModeProperty);
97             }
98         }
99
100         /// <summary>
101         /// Identifies the VideoInfo bindable property
102         /// </summary>
103         public static readonly BindableProperty VideoInfoProperty = BindableProperty.Create("VideoInfo", typeof(MediaInformation), typeof(VideoItem), null);
104
105         /// <summary>
106         /// Gets or sets the VideoInfo of current video
107         /// </summary>
108         public MediaInformation VideoInfo
109         {
110             set
111             {
112                 SetValue(VideoInfoProperty, value);
113             }
114
115             get
116             {
117                 return (MediaInformation)GetValue(VideoInfoProperty);
118             }
119         }
120
121         /// <summary>
122         /// A constructor
123         /// Initializes the size of the items that are used in this class
124         /// </summary>
125         public VideoItem()
126         {
127             InitializeComponent();
128             InitializeSize();
129             PropertyChanged += VideoTabPropertyChanged;
130         }
131
132         /// <summary>
133         /// A method for initializing size of the items that are used in this class
134         /// </summary>
135         private void InitializeSize()
136         {
137             int w0 = SizeUtils.GetWidthSize(0);
138             int h0 = SizeUtils.GetHeightSize(0);
139             int w12 = SizeUtils.GetWidthSize(12);
140             int h12 = SizeUtils.GetHeightSize(12);
141             int w344 = SizeUtils.GetWidthSize(344);
142             int h204 = SizeUtils.GetHeightSize(204);
143
144             int h5 = SizeUtils.GetHeightSize(5);
145             int w5 = SizeUtils.GetWidthSize(5);
146
147             NormalShadowBounds = new Rectangle(w12, h12, SizeUtils.GetWidthSize(448), SizeUtils.GetHeightSize(308));
148             FocusedShadowBounds = new Rectangle(w0, h0, SizeUtils.GetWidthSize(472), SizeUtils.GetHeightSize(332));
149             FocusedBounds = new Rectangle(SizeUtils.GetWidthSize(64), SizeUtils.GetHeightSize(64), w344, h204);
150             NormalBounds = new Rectangle(SizeUtils.GetWidthSize(76), SizeUtils.GetHeightSize(76), SizeUtils.GetWidthSize(320), SizeUtils.GetHeightSize(180));
151
152             NormalContentImageBounds = new Rectangle(-w12, -h12, w344, h204);
153             FocusedContentImageBounds = new Rectangle(w0, h0, w344, h204);
154
155             PlayIconBounds = new Rectangle(SizeUtils.GetWidthSize(208), SizeUtils.GetHeightSize(126), SizeUtils.GetWidthSize(80), SizeUtils.GetHeightSize(80));
156
157             TitleContainerBounds = new Rectangle(SizeUtils.GetWidthSize(94), SizeUtils.GetHeightSize(214), SizeUtils.GetWidthSize(284), SizeUtils.GetHeightSize(30) * 1.3);
158
159             WidthRequest = SizeUtils.GetWidthSize(472);
160             HeightRequest = SizeUtils.GetHeightSize(332);
161
162             BgDimImage.BorderTop = SizeUtils.GetHeightSize(124);
163             BgDimImage.BorderBottom = SizeUtils.GetHeightSize(124);
164             BgDimImage.BorderLeft = SizeUtils.GetWidthSize(124);
165             BgDimImage.BorderRight = SizeUtils.GetWidthSize(124);
166             BgDimImage.Opacity = 0;
167
168             DimImage.BorderTop = SizeUtils.GetHeightSize(20);
169             DimImage.BorderBottom = SizeUtils.GetHeightSize(20);
170             DimImage.BorderLeft = SizeUtils.GetWidthSize(20);
171             DimImage.BorderRight = SizeUtils.GetWidthSize(20);
172
173             CheckDimImage.BorderTop = h5;
174             CheckDimImage.BorderBottom = h5;
175             CheckDimImage.BorderLeft = w5;
176             CheckDimImage.BorderRight = w5;
177
178             CheckImage.BorderTop = h5;
179             CheckImage.BorderBottom = h5;
180             CheckImage.BorderLeft = w5;
181             CheckImage.BorderRight = w5;
182
183             FocusArea.HeightRequest = SizeUtils.GetHeightSize(50);
184             FocusArea.WidthRequest = SizeUtils.GetWidthSize(50);
185
186             ContentTitle.FontSize = SizeUtils.GetFontSize(26);
187
188             CheckImage.ImageColor = ElmSharp.Color.White;
189         }
190
191         /// <summary>
192         /// Positions and sizes the children of a Layout.
193         /// </summary>
194         /// <param name="x">A value representing the x coordinate of the child region bounding box.</param>
195         /// <param name="y">A value representing the y coordinate of the child region bounding box.</param>
196         /// <param name="width">A value representing the width of the child region bounding box.</param>
197         /// <param name="height">A value representing the height of the child region bounding box.</param>
198         protected override void LayoutChildren(double x, double y, double width, double height)
199         {
200             if (IsLoaded == false)
201             {
202                 FocusArea.Layout(NormalBounds);
203                 BgDimImage.Layout(NormalShadowBounds);
204                 ImageArea.Layout(NormalBounds);
205                 ContentImage.Layout(NormalContentImageBounds);
206                 DimImage.Layout(NormalBounds);
207                 TitleContainer.Layout(TitleContainerBounds);
208                 PlayImage.Layout(PlayIconBounds);
209                 CheckDimImage.Layout(NormalBounds);
210                 CheckImage.Layout(NormalBounds);
211                 IsLoaded = true;
212             }
213         }
214
215         /// <summary>
216         /// A method for getting item's button object
217         /// </summary>
218         /// <returns>A button object</returns>
219         public Button GetFocusArea()
220         {
221             return FocusArea;
222         }
223
224         /// <summary>
225         /// This method is called when item is unfocused
226         /// </summary>
227         /// <param name="sender">The source of the event</param>
228         /// <param name="e">A Focus event's argument</param>
229         public void OnUnfocused(object sender, FocusEventArgs e)
230         {
231             Easing easing = new Easing(EasingFunction.EasyIn2);
232             this.AbortAnimation("TextSliding");
233             this.AbortAnimation("FocusAnimation");
234
235             BgDimImage.Opacity = 0;
236             ContentImage.ScaleTo(1.0, 167, easing);
237             DimImage.LayoutTo(NormalBounds, 167, easing);
238             ContentImage.LayoutTo(NormalContentImageBounds, 167, easing);
239             BgDimImage.LayoutTo(NormalShadowBounds, 167, easing);
240             PlayImage.FadeTo(0.0, 167);
241             if (IsDeleteMode)
242             {
243                 CheckDimImage.LayoutTo(NormalBounds, 167, easing);
244                 CheckImage.LayoutTo(NormalBounds, 167, easing);
245             }
246
247             ImageArea.LayoutTo(NormalBounds, 167, easing);
248         }
249
250         /// <summary>
251         /// This method is called when item is focused
252         /// </summary>
253         /// <param name="sender">The source of the event</param>
254         /// <param name="e">A Focus event's argument</param>
255         public void OnFocused(object sender, FocusEventArgs e)
256         {
257             Easing easing = new Easing(EasingFunction.EasyIn1);
258             this.Animate("TextSliding",
259                 (v) => { },
260                 length: 2000,
261                 finished: (v, IsCanceled) =>
262                 {
263                     if (!IsCanceled)
264                     {
265                         uint animationLength = (uint)(ContentTitle.Width * 12000 / 480);
266                         this.Animate("TextSliding",
267                             (v2) =>
268                             {
269                                 ContentTitle.TranslationX = -ContentTitle.Width * v2;
270                             },
271                             length: animationLength,
272                             finished: (v2, c2) =>
273                              {
274                                  ContentTitle.TranslationX = 0;
275                              });
276                     }
277                 });
278
279             this.Animate("FocusAnimation",
280                 (v) => { },
281                 length: 167,
282                 finished: (v, IsCanceled) =>
283                 {
284                     if (!IsCanceled)
285                     {
286                         BgDimImage.Opacity = 0.99;
287                         OnFocusedEventHandler?.Invoke(sender, e);
288 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
289                         ContentImage.ScaleTo(1.3, 167, easing);
290                         DimImage.LayoutTo(FocusedBounds, 500, easing);
291                         ContentImage.LayoutTo(FocusedContentImageBounds, 500, easing);
292                         BgDimImage.LayoutTo(FocusedShadowBounds, 500, easing);
293                         PlayImage.FadeTo(0.99, 167);
294                         if (IsDeleteMode)
295                         {
296                             CheckDimImage.LayoutTo(FocusedBounds, 167, easing);
297                             CheckImage.LayoutTo(FocusedBounds, 167, easing);
298                         }
299 #pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
300                         ImageArea.LayoutTo(FocusedBounds, 500, easing);
301                     }
302                 });
303         }
304
305         /// <summary>
306         /// This method is called when item is focused
307         /// </summary>
308         /// <param name="sender">The source of the event</param>
309         /// <param name="e">A Focus event's argument</param>
310         private async void OnItemClicked(object sender, EventArgs e)
311         {
312             if (DimImage.AnimationIsRunning("LayoutTo"))
313             {
314                 return;
315             }
316 #pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
317             DimImage.LayoutTo(NormalBounds, 167);
318             ContentImage.LayoutTo(NormalContentImageBounds, 167);
319             BgDimImage.LayoutTo(NormalShadowBounds, 167);
320             CheckDimImage.LayoutTo(NormalBounds, 167);
321             CheckImage.LayoutTo(NormalBounds, 167);
322             await ImageArea.LayoutTo(NormalBounds, 167);
323
324             DimImage.LayoutTo(FocusedBounds, 167);
325             ContentImage.LayoutTo(FocusedContentImageBounds, 167);
326             BgDimImage.LayoutTo(FocusedShadowBounds, 167);
327             CheckDimImage.LayoutTo(FocusedBounds, 167);
328             CheckImage.LayoutTo(FocusedBounds, 167);
329             ImageArea.LayoutTo(FocusedBounds, 167);
330             OnItemClickedHandler?.Invoke(VideoInfo);
331             if (IsDeleteMode)
332             {
333                 if (CurStatus == ItemStatus.NORMAL)
334                 {
335                     CurStatus = ItemStatus.SELECTED;
336                     PlayImage.FadeTo(0, 167);
337                 }
338                 else
339                 {
340                     CurStatus = ItemStatus.NORMAL;
341                     PlayImage.FadeTo(0.99, 167);
342                 }
343 #pragma warning restore CS4014
344                 UpdateView();
345             }
346             else
347             {
348                 PushNavigationPage();
349             }
350         }
351
352         /// <summary>
353         /// A method for updating view according to current status
354         /// </summary>
355         private void UpdateView()
356         {
357             switch (CurStatus)
358             {
359                 case ItemStatus.NORMAL:
360                     CheckDimImage.FadeTo(0.0, 167);
361                     CheckImage.FadeTo(0.0, 167);
362                     break;
363                 case ItemStatus.SELECTED:
364                     CheckDimImage.FadeTo(0.75, 167);
365                     CheckImage.FadeTo(0.99, 167);
366                     break;
367             }
368         }
369
370         /// <summary>
371         /// A method for pushing VideoPlayer page at MainPage of TV MediaHub
372         /// </summary>
373         private void PushNavigationPage()
374         {
375             Program.TransitionTo(new VideoPlayer());
376         }
377
378         /// <summary>
379         /// This method is called when the properties is changed
380         /// </summary>
381         /// <param name="sender">The source of the event</param>
382         /// <param name="e">A propertyChanged event argument</param>
383         private void VideoTabPropertyChanged(object sender, PropertyChangedEventArgs e)
384         {
385             if (e.PropertyName.CompareTo("IsDeleteMode") == 0)
386             {
387                 if (!IsDeleteMode)
388                 {
389                     CurStatus = ItemStatus.NORMAL;
390                     UpdateView();
391                 }
392             }
393         }
394     }
395 }