Support new features of Tizen.CircularUI (#188)
[platform/core/csapi/xsf.git] / src / XSF / Xamarin.Forms.Platform.Tizen / Native / EmbeddingControls.cs
1 using System;
2 using System.Globalization;
3 using Xamarin.Forms.PlatformConfiguration.TizenSpecific;
4
5 using XLabel = Xamarin.Forms.Label;
6 using XTextAlignment = Xamarin.Forms.TextAlignment;
7 using PlayerState = Xamarin.Forms.PlatformConfiguration.TizenSpecific.PlaybackState;
8
9 namespace Xamarin.Forms.Platform.Tizen.Native
10 {
11         public class EmbeddingControls : ContentView
12         {
13                 static readonly string PlayImagePath = "XSF.Resources.img_button_play.png";
14                 static readonly string PauseImagePath = "XSF.Resources.img_button_pause.png";
15
16                 public ImageButton PlayImage { get; private set; }
17                 public ImageButton PauseImage { get; private set; }
18
19                 public EmbeddingControls()
20                 {
21                         PlayImage = new ImageButton
22                         {
23                                 Source = ImageSource.FromResource(PlayImagePath, typeof(EmbeddingControls).Assembly),
24                                 IsVisible = false
25                         };
26                         PlayImage.Clicked += OnImageButtonClicked;
27                         AbsoluteLayout.SetLayoutFlags(PlayImage, AbsoluteLayoutFlags.All);
28                         AbsoluteLayout.SetLayoutBounds(PlayImage, new Rectangle(0.5, 0.5, 0.25, 0.25));
29
30                         PauseImage = new ImageButton
31                         {
32                                 Source = ImageSource.FromResource(PauseImagePath, typeof(EmbeddingControls).Assembly),
33                                 IsVisible = false
34                         };
35                         PauseImage.Clicked += OnImageButtonClicked;
36                         AbsoluteLayout.SetLayoutFlags(PauseImage, AbsoluteLayoutFlags.All);
37                         AbsoluteLayout.SetLayoutBounds(PauseImage, new Rectangle(0.5, 0.5, 0.25, 0.25));
38
39                         var bufferingLabel = new XLabel
40                         {
41                                 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label), false),
42                                 HorizontalTextAlignment = XTextAlignment.Center,
43                                 TextColor = Color.FromHex("#eeeeeeee")
44                         };
45                         bufferingLabel.SetBinding(XLabel.TextProperty, new Binding
46                         {
47                                 Path = "BufferingProgress",
48                                 StringFormat = "{0:0%}"
49                         });
50                         bufferingLabel.SetBinding(IsVisibleProperty, new Binding
51                         {
52                                 Path = "IsBuffering",
53                         });
54                         AbsoluteLayout.SetLayoutFlags(bufferingLabel, AbsoluteLayoutFlags.All);
55                         AbsoluteLayout.SetLayoutBounds(bufferingLabel, new Rectangle(0.5, 0.5, 0.25, 0.25));
56
57                         var progressBoxView = new BoxView
58                         {
59                                 Color = Color.FromHex($"#4286f4")
60                         };
61                         progressBoxView.SetBinding(AbsoluteLayout.LayoutBoundsProperty, new Binding
62                         {
63                                 Path = "Progress",
64                                 Converter = new ProgressToBoundTextConverter()
65                         });
66                         AbsoluteLayout.SetLayoutFlags(progressBoxView, AbsoluteLayoutFlags.All);
67
68                         var posLabel = new XLabel
69                         {
70                                 Margin = new Thickness(10, 0, 0, 0),
71                                 FontSize = Device.GetNamedSize(NamedSize.Micro, typeof(XLabel)),
72                                 HorizontalTextAlignment = XTextAlignment.Start
73                         };
74                         posLabel.SetBinding(XLabel.TextProperty, new Binding
75                         {
76                                 Path = "Position",
77                                 Converter = new MillisecondToTextConverter()
78                         });
79                         AbsoluteLayout.SetLayoutFlags(posLabel, AbsoluteLayoutFlags.All);
80                         AbsoluteLayout.SetLayoutBounds(posLabel, new Rectangle(0,0,1,1));
81
82                         var durationLabel = new XLabel
83                         {
84                                 Margin = new Thickness(0, 0, 10, 0),
85                                 FontSize = Device.GetNamedSize(NamedSize.Micro, typeof(XLabel)),
86                                 HorizontalTextAlignment = XTextAlignment.End
87                         };
88                         durationLabel.SetBinding(XLabel.TextProperty, new Binding
89                         {
90                                 Path = "Duration",
91                                 Converter = new MillisecondToTextConverter()
92                         });
93                         AbsoluteLayout.SetLayoutFlags(durationLabel, AbsoluteLayoutFlags.All);
94                         AbsoluteLayout.SetLayoutBounds(durationLabel, new Rectangle(0, 0, 1, 1));
95
96                         var progressInnerLayout = new AbsoluteLayout
97                         {
98                                 HorizontalOptions = LayoutOptions.FillAndExpand,
99                                 HeightRequest = 23,
100                                 BackgroundColor = Color.FromHex("#80000000"),
101                                 Children =
102                                 {
103                                         progressBoxView,
104                                         posLabel,
105                                         durationLabel
106                                 }
107                         };
108
109                         var progressLayout = new StackLayout
110                         {
111                                 Children =
112                                 {
113                                         new StackLayout { VerticalOptions = LayoutOptions.FillAndExpand },
114                                         new StackLayout
115                                         {
116                                                 Margin =  Device.Idiom == TargetIdiom.Watch ? new Thickness(80, 0, 80, 0) : 20,
117                                                 VerticalOptions = LayoutOptions.End,
118                                                 HorizontalOptions = LayoutOptions.FillAndExpand,
119                                                 BackgroundColor = Color.FromHex("#50000000"),
120                                                 Children = { progressInnerLayout }
121                                         }
122                                 }
123                         };
124                         AbsoluteLayout.SetLayoutFlags(progressLayout, AbsoluteLayoutFlags.All);
125                         AbsoluteLayout.SetLayoutBounds(progressLayout, new Rectangle(0, 0, 1, 1));
126
127                         Content = new AbsoluteLayout
128                         {
129                                 HorizontalOptions = LayoutOptions.FillAndExpand,
130                                 VerticalOptions = LayoutOptions.FillAndExpand,
131                                 Children = {
132                                         progressLayout,
133                                         PlayImage,
134                                         PauseImage,
135                                         bufferingLabel
136                                 }
137                         };
138                 }
139
140                 protected override void OnBindingContextChanged()
141                 {
142                         base.OnBindingContextChanged();
143                         if (BindingContext is IMediaPlayer player)
144                         {
145                                 player.PlaybackPaused += OnPlaybackStateChanged;
146                                 player.PlaybackStarted += OnPlaybackStateChanged;
147                                 player.PlaybackStopped += OnPlaybackStateChanged;
148                         }
149                 }
150
151                 async void OnPlaybackStateChanged(object sender, EventArgs e)
152                 {
153                         if (BindingContext is IMediaPlayer player)
154                         {
155                                 if (player.State == PlayerState.Playing)
156                                 {
157                                         var unused = PlayImage.FadeTo(0, 100);
158                                         await PlayImage.ScaleTo(3.0, 300);
159                                         PlayImage.IsVisible = false;
160                                         PlayImage.Scale = 1.0;
161
162                                         PauseImage.IsVisible = true;
163                                         unused = PauseImage.FadeTo(1, 50);
164                                 }
165                                 else
166                                 {
167                                         var unused = PauseImage.FadeTo(0, 100);
168                                         await PauseImage.ScaleTo(3.0, 300);
169                                         PauseImage.IsVisible = false;
170                                         PauseImage.Scale = 1.0;
171
172                                         PlayImage.IsVisible = true;
173                                         unused = PlayImage.FadeTo(1, 50);
174                                 }
175                         }
176                 }
177
178                 async void OnImageButtonClicked(object sender, EventArgs e)
179                 {
180                         if (BindingContext is MediaPlayer player)
181                         {
182                                 if (player.State == PlayerState.Playing)
183                                 {
184                                         player.Pause();
185                                 }
186                                 else
187                                 {
188                                         await player.Start();
189                                 }
190                         }
191                 }
192         }
193
194         public class ProgressToBoundTextConverter : IValueConverter
195         {
196                 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
197                 {
198                         double progress = (double)value;
199                         if (Double.IsNaN(progress))
200                         {
201                                 progress = 0d;
202                         }
203                         return new Rectangle(0, 0, progress, 1);
204                 }
205
206                 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
207                 {
208                         Rectangle rect = (Rectangle)value;
209                         return rect.Width;
210                 }
211         }
212
213         public class MillisecondToTextConverter : IValueConverter
214         {
215                 public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
216                 {
217                         int millisecond = (int)value;
218                         int second = (millisecond / 1000) % 60;
219                         int min = (millisecond / 1000 / 60) % 60;
220                         int hour = (millisecond / 1000 / 60 / 60);
221                         if (hour > 0)
222                         {
223                                 return string.Format("{0:d2}:{1:d2}:{2:d2}", hour, min, second);
224                         }
225                         else
226                         {
227                                 return string.Format("{0:d2}:{1:d2}", min, second);
228                         }
229                 }
230
231                 public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
232                 {
233                         throw new NotImplementedException();
234                 }
235         }
236 }