Implement the music player for the music tab
authorGeunsun, Lee <gs86.lee@samsung.com>
Wed, 7 Jun 2017 10:26:16 +0000 (19:26 +0900)
committerGeunSun Lee <gs86.lee@samsung.com>
Fri, 9 Jun 2017 00:00:55 +0000 (09:00 +0900)
Change-Id: I89095aac77e014ae8ba0ad5a73c237468b7f18d3

21 files changed:
TVMediaHub/TVMediaHub.Tizen/Models/ContentProvider.cs
TVMediaHub/TVMediaHub.Tizen/Models/MediaHubImpl.cs
TVMediaHub/TVMediaHub.Tizen/Models/MusicPlayerModel.cs [new file with mode: 0644]
TVMediaHub/TVMediaHub.Tizen/Models/MusicProvider.cs
TVMediaHub/TVMediaHub.Tizen/TVMediaHub.Tizen.csproj
TVMediaHub/TVMediaHub.Tizen/Utils/EasingFunction.cs
TVMediaHub/TVMediaHub.Tizen/ViewModels/ImageTabViewModel.cs
TVMediaHub/TVMediaHub.Tizen/ViewModels/MusicPlayerViewModel.cs [new file with mode: 0644]
TVMediaHub/TVMediaHub.Tizen/ViewModels/MusicPlayerViewModelLocator.cs [new file with mode: 0644]
TVMediaHub/TVMediaHub.Tizen/ViewModels/MusicTabViewModel.cs
TVMediaHub/TVMediaHub.Tizen/ViewModels/MusicTabViewModelLocator.cs
TVMediaHub/TVMediaHub.Tizen/ViewModels/VideoTabViewModelLocator.cs
TVMediaHub/TVMediaHub.Tizen/Views/ImageItem.xaml.cs
TVMediaHub/TVMediaHub.Tizen/Views/ImageViewer.xaml.cs
TVMediaHub/TVMediaHub.Tizen/Views/MusicGroup.xaml.cs
TVMediaHub/TVMediaHub.Tizen/Views/MusicItem.xaml
TVMediaHub/TVMediaHub.Tizen/Views/MusicItem.xaml.cs
TVMediaHub/TVMediaHub.Tizen/Views/MusicPlayer.xaml [new file with mode: 0644]
TVMediaHub/TVMediaHub.Tizen/Views/MusicPlayer.xaml.cs [new file with mode: 0644]
TVMediaHub/TVMediaHub.Tizen/Views/MusicTab.xaml
TVMediaHub/TVMediaHub.Tizen/Views/MusicTab.xaml.cs

index 3d21b0b..3ffb646 100755 (executable)
@@ -162,6 +162,7 @@ namespace TVMediaHub.Tizen.Models
                         newGroupFlag = true;
                         newTitle = mediaInformationEx.MediaContentInformation.MediaType.ToString();
                     }
+
                     break;
                 case SortOption.Album:
                     if (lastGroupItem == null || lastGroupItem.Title != (mediaInformationEx.MediaContentInformation as AudioInformation).Album)
@@ -169,6 +170,7 @@ namespace TVMediaHub.Tizen.Models
                         newGroupFlag = true;
                         newTitle = (mediaInformationEx.MediaContentInformation as AudioInformation).Album.ToString();
                     }
+
                     break;
                 case SortOption.Artist:
                     if (lastGroupItem == null || lastGroupItem.Title != (mediaInformationEx.MediaContentInformation as AudioInformation).Artist)
index 4e89dcc..4d4a51d 100755 (executable)
@@ -26,6 +26,7 @@ namespace TVMediaHub.Tizen.Models
         /// An instance of the MediaHubImpl
         /// </summary>
         private static readonly MediaHubImpl instance = new MediaHubImpl();
+
         /// <summary>
         /// Gets an instance of the MediaHubImpl
         /// </summary>
@@ -56,6 +57,7 @@ namespace TVMediaHub.Tizen.Models
         /// An instance of the MusicProvider
         /// </summary>
         private static readonly MusicProvider musicProviderInstance = new MusicProvider();
+
         /// <summary>
         /// Gets an instance of the MusicProvider
         /// </summary>
@@ -71,6 +73,7 @@ namespace TVMediaHub.Tizen.Models
         /// An instance of the MusicProvider
         /// </summary>
         private static readonly VideoProvider videoProviderInstance = new VideoProvider();
+
         /// <summary>
         /// Gets an instance of the MusicProvider
         /// </summary>
@@ -86,6 +89,7 @@ namespace TVMediaHub.Tizen.Models
         /// An instance of the StorageProvider
         /// </summary>
         private static readonly StorageProvider storageProviderInstance = new StorageProvider();
+
         /// <summary>
         /// Gets an instance of the StorageProvider
         /// </summary>
diff --git a/TVMediaHub/TVMediaHub.Tizen/Models/MusicPlayerModel.cs b/TVMediaHub/TVMediaHub.Tizen/Models/MusicPlayerModel.cs
new file mode 100644 (file)
index 0000000..74c1294
--- /dev/null
@@ -0,0 +1,260 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using Tizen.Content.MediaContent;
+using Tizen.Multimedia;
+using TVMediaHub.Tizen.DataModels;
+using TVMediaHub.Tizen.Utils;
+
+namespace TVMediaHub.Tizen.Models
+{
+    /// <summary>
+    /// A custom EventArgs with string fields
+    /// </summary>
+    public class MusicPlayerInfoEventArgs : EventArgs
+    {
+        public string Title;
+        public string Artist;
+        public string AlbumCover;
+    }
+
+    /// <summary>
+    /// A custom EventArgs with double field
+    /// </summary>
+    public class MusicPlayerProgressEventArgs : EventArgs
+    {
+        public double Progress;
+    }
+
+    /// <summary>
+    /// An instance of the MusicPlayerModel
+    /// </summary>
+    public class MusicPlayerModel
+    {
+        /// <summary>
+        /// A main instance class of the music player model instance
+        /// </summary>
+        private static readonly MusicPlayerModel instance = new MusicPlayerModel();
+
+        /// <summary>
+        /// An instance of the player
+        /// </summary>
+        private Player playerInstance;
+
+        /// <summary>
+        /// An timer for the progressbar
+        /// </summary>
+        private Timer progressbarTimer;
+
+        /// <summary>
+        /// The period of the timer
+        /// </summary>
+        private int timerPeriod = 1000;
+
+        /// <summary>
+        /// An event handler for handling the current music information
+        /// </summary>
+        private EventHandler<MusicPlayerInfoEventArgs> MusicPlayerInfoListener;
+
+        /// <summary>
+        /// An event handler for handling the percentage of the progressbar
+        /// </summary>
+        private EventHandler<MusicPlayerProgressEventArgs> MusicPlayerProgressListener;
+
+        /// <summary>
+        /// The information of the current music
+        /// </summary>
+        public MediaInformationEx currentMusic;
+
+        /// <summary>
+        /// Gets or sets the current music
+        /// </summary>
+        public MediaInformationEx CurrentMusic
+        {
+            get
+            {
+                return currentMusic;
+            }
+
+            set
+            {
+                if (currentMusic != value)
+                {
+                    currentMusic = value;
+
+                    /// 1. Stop the player
+                    if (playerInstance.State == PlayerState.Playing)
+                    {
+                        StopPlayer();
+                    }
+
+                    /// 2. Play the current music
+                    StartPlayerAsync((currentMusic.MediaContentInformation as AudioInformation).FilePath);
+
+                    /// 3. Update the information of the current music
+                    MusicPlayerInfoListener?.Invoke(this, new MusicPlayerInfoEventArgs()
+                    {
+                        Title = (currentMusic.MediaContentInformation as AudioInformation).Title,
+                        Artist = (currentMusic.MediaContentInformation as AudioInformation).Artist,
+                        AlbumCover = ((currentMusic.MediaContentInformation as AudioInformation).ThumbnailPath.Length != 0) ? (currentMusic.MediaContentInformation as AudioInformation).ThumbnailPath : "img_media_no_contents.png",
+                    });
+
+                    /// 4. Update the progressbar of the current music
+                    MusicPlayerProgressListener?.Invoke(this, new MusicPlayerProgressEventArgs()
+                    {
+                        Progress = (playerInstance.State == PlayerState.Idle || playerInstance.State == PlayerState.Preparing) ? 0 : Convert.ToDouble(playerInstance.GetPlayPosition()) / (currentMusic.MediaContentInformation as AudioInformation).Duration,
+                    });
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets an instance of the music player model
+        /// </summary>
+        public static MusicPlayerModel Instance
+        {
+            get
+            {
+                return instance;
+            }
+        }
+
+        /// <summary>
+        /// A constructor
+        /// </summary>
+        public MusicPlayerModel()
+        {
+            InitializePlayer();
+            InitializeProgressbarTimer();
+        }
+
+        /// <summary>
+        /// Initialize the player instance
+        /// Register event handler for the player
+        /// </summary>
+        private void InitializePlayer()
+        {
+            playerInstance = new Player();
+
+            playerInstance.PlaybackCompleted += ((s, e) =>
+            {
+                StopPlayer();
+            });
+
+            playerInstance.PlaybackInterrupted += ((s, e) =>
+            {
+                DbgPort.E("Error : " + Enum.GetName(typeof(PlayerError), e.Reason));
+
+                StopPlayer();
+            });
+
+            playerInstance.ErrorOccurred += ((s, e) =>
+            {
+                DbgPort.E("Error : " + Enum.GetName(typeof(PlayerError), e.Error));
+
+                StopPlayer();
+            });
+        }
+
+        /// <summary>
+        /// Initialize the timer for the progressbar
+        /// </summary>
+        private void InitializeProgressbarTimer()
+        {
+            progressbarTimer = new Timer((object o) =>
+            {
+                MusicPlayerProgressListener?.Invoke(this, new MusicPlayerProgressEventArgs()
+                {
+                    Progress = (playerInstance.State == PlayerState.Idle || playerInstance.State == PlayerState.Preparing) ? 0 : Convert.ToDouble(playerInstance.GetPlayPosition()) / (currentMusic.MediaContentInformation as AudioInformation).Duration,
+                });
+            }, null, Timeout.Infinite, Timeout.Infinite);
+        }
+
+        /// <summary>
+        /// Starts the timer for the progressbar
+        /// </summary>
+        private void StartProgressbarTimer()
+        {
+            progressbarTimer.Change(0, timerPeriod);
+        }
+
+        /// <summary>
+        /// Stops the timer for the porgressbar
+        /// </summary>
+        private void StopProgressbarTimer()
+        {
+            progressbarTimer.Change(Timeout.Infinite, Timeout.Infinite);
+        }
+
+        /// <summary>
+        /// Plays the current music
+        /// </summary>
+        /// <param name="filePath">The file path of the media source</param>
+        public void StartPlayerAsync(string filePath)
+        {
+            MediaSource source = new MediaUriSource(filePath);
+            playerInstance.SetSource(source);
+
+            Task.Run(async () =>
+            {
+                await playerInstance.PrepareAsync();
+
+                playerInstance.Start();
+
+                StartProgressbarTimer();
+            });
+        }
+
+        /// <summary>
+        /// Stops the current music
+        /// </summary>
+        public void StopPlayer()
+        {
+            StopProgressbarTimer();
+
+            try
+            {
+                playerInstance.Stop();
+                playerInstance.Unprepare();
+            }
+            catch (Exception e)
+            {
+                DbgPort.E("Error : " + e.Message);
+            }
+        }
+
+        /// <summary>
+        /// A method adds EventHandler to SetCurrentMusicInfoListener
+        /// </summary>
+        /// <param name="listener">The EventHandler for adding</param>
+        public void SetCurrentMusicInfoListener(EventHandler<MusicPlayerInfoEventArgs> listener)
+        {
+            MusicPlayerInfoListener += listener;
+        }
+
+        /// <summary>
+        /// A method adds EventHandler to SetCurrentMusicProgressListener
+        /// </summary>
+        /// <param name="listener">The EventHandler for adding</param>
+        public void SetCurrentMusicProgressListener(EventHandler<MusicPlayerProgressEventArgs> listener)
+        {
+            MusicPlayerProgressListener += listener;
+        }
+    }
+}
index 381a321..95a5540 100755 (executable)
@@ -15,7 +15,6 @@
  */
 
 using System;
-using Tizen.Content.MediaContent;
 using TVMediaHub.Tizen.DataModels;
 
 namespace TVMediaHub.Tizen.Models
index 6b66f2b..0666f86 100755 (executable)
@@ -65,6 +65,7 @@
     <Compile Include="Models\GroupItem.cs" />
     <Compile Include="Models\ImageProvider.cs" />
     <Compile Include="Models\MediaHubImpl.cs" />
+    <Compile Include="Models\MusicPlayerModel.cs" />
     <Compile Include="Models\MusicProvider.cs" />
     <Compile Include="Models\StorageProvider.cs" />
     <Compile Include="Models\MediaShortcutInfo.cs" />
@@ -85,7 +86,9 @@
     <Compile Include="ViewModels\ImageTabViewModel.cs" />
     <Compile Include="ViewModels\ImageTabViewModelLocator.cs" />
     <Compile Include="ViewModels\MediaHubMainPageViewModel.cs" />
+    <Compile Include="ViewModels\MusicPlayerViewModel.cs" />
     <Compile Include="ViewModels\MusicTabViewModel.cs" />
+    <Compile Include="ViewModels\MusicPlayerViewModelLocator.cs" />
     <Compile Include="ViewModels\MusicTabViewModelLocator.cs" />
     <Compile Include="ViewModels\VideoPlayerViewModel.cs" />
     <Compile Include="ViewModels\VideoTabViewModel.cs" />
     <Compile Include="Views\VideoItem.xaml.cs">
       <DependentUpon>VideoItem.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Views\MusicPlayer.xaml.cs">
+      <DependentUpon>MusicPlayer.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Views\VideoPlayer.xaml.cs">
       <DependentUpon>VideoPlayer.xaml</DependentUpon>
     </Compile>
       <SubType>Designer</SubType>
     </EmbeddedResource>
   </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Views\MusicPlayer.xaml">
+      <Generator>MSBuild:UpdateDesignTimeXaml</Generator>
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
                Other similar extension points exist, see Microsoft.Common.targets.
index b5afebc..c8cae1a 100755 (executable)
@@ -62,6 +62,10 @@ namespace TVMediaHub.Tizen.Utils
         /// <summary>
         /// Calculate Cubic Bezier curves
         /// </summary>
+        /// <param name="a"></param>
+        /// <param name="x1"></param>
+        /// <param name="x2"></param>
+        /// <returns></returns>
         private static double CubicBezierTGet(double a, double x1, double x2)
         {
             int limit = 100;
@@ -89,9 +93,14 @@ namespace TVMediaHub.Tizen.Utils
 
             return guessT;
         }
+
         /// <summary>
         /// Calculate Cubic Bezier curves
         /// </summary>
+        /// <param name="t"></param>
+        /// <param name="a1"></param>
+        /// <param name="a2"></param>
+        /// <returns></returns>
         private static double CubicBezierSlopeGet(double t, double a1, double a2)
         {
             return 3.0 * CubicBezierA(a1, a2) * t * t + 2.0 * CubicBezierB(a1, a2) * t + CubicBezierC(a1);
@@ -100,6 +109,10 @@ namespace TVMediaHub.Tizen.Utils
         /// <summary>
         /// Calculate Cubic Bezier curves
         /// </summary>
+        /// <param name="t"></param>
+        /// <param name="a1"></param>
+        /// <param name="a2"></param>
+        /// <returns></returns>
         private static double CubicBezierCalc(double t, double a1, double a2)
         {
             return ((CubicBezierA(a1, a2) * t + CubicBezierB(a1, a2)) * t + CubicBezierC(a1)) * t;
@@ -108,6 +121,9 @@ namespace TVMediaHub.Tizen.Utils
         /// <summary>
         /// Calculate Cubic Bezier curves
         /// </summary>
+        /// <param name="a1"></param>
+        /// <param name="a2"></param>
+        /// <returns></returns>
         private static double CubicBezierA(double a1, double a2)
         {
             return 1.0 - 3.0 * a2 + 3.0 * a1;
@@ -116,6 +132,9 @@ namespace TVMediaHub.Tizen.Utils
         /// <summary>
         /// Calculate Cubic Bezier curves
         /// </summary>
+        /// <param name="a1"></param>
+        /// <param name="a2"></param>
+        /// <returns></returns>
         private static double CubicBezierB(double a1, double a2)
         {
             return 3.0 * a2 - 6.0 * a1;
@@ -124,6 +143,8 @@ namespace TVMediaHub.Tizen.Utils
         /// <summary>
         /// Calculate Cubic Bezier curves
         /// </summary>
+        /// <param name="a1"></param>
+        /// <returns></returns>
         private static double CubicBezierC(double a1)
         {
             return 3.0 * a1;
index fff156c..4e8371f 100755 (executable)
@@ -562,10 +562,11 @@ namespace TVMediaHub.Tizen.ViewModels
         /// A method for reading image contents through ImageProvider and updating ImageList
         /// </summary>
         /// <param name="option">A current sort option</param>
-        private async void ReadImageList(SortOption option, string storageId = null)
+        /// <param name="storageID">The given storage ID</param>
+        private async void ReadImageList(SortOption option, string storageID = null)
         {
             ImageList.Clear();
-            IEnumerable<GroupItem> tempList = await MediaHubImpl.GetInstance.ImageProviderInstance.ReadAsync(option, storageId);
+            IEnumerable<GroupItem> tempList = await MediaHubImpl.GetInstance.ImageProviderInstance.ReadAsync(option, storageID);
             foreach (var group in tempList)
             {
                 await MediaHubImpl.GetInstance.ImageProviderInstance.CheckThumbnail(group.Contents);
diff --git a/TVMediaHub/TVMediaHub.Tizen/ViewModels/MusicPlayerViewModel.cs b/TVMediaHub/TVMediaHub.Tizen/ViewModels/MusicPlayerViewModel.cs
new file mode 100644 (file)
index 0000000..b4d39d9
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.ComponentModel;
+using TVMediaHub.Tizen.Models;
+
+namespace TVMediaHub.Tizen.ViewModels
+{
+    /// <summary>
+    /// A class for ViewModel of the music player
+    /// </summary>
+    public class MusicPlayerViewModel : INotifyPropertyChanged
+    {
+        /// <summary>
+        /// The percentage of the progressbar to be shown
+        /// </summary>
+        public double ProgressBarPercentage { get; private set; }
+
+        /// <summary>
+        /// The album title to be shown
+        /// </summary>
+        public string AlbumTitle { get; private set; }
+
+        /// <summary>
+        /// The artist to be shown
+        /// </summary>
+        public string AlbumArtist { get; private set; }
+
+        /// <summary>
+        /// The album cover to be shown
+        /// </summary>
+        public string AlbumCover { get; private set; }
+
+        /// <summary>
+        /// An event that is occurred when property of ViewModel is changed
+        /// </summary>
+        public event PropertyChangedEventHandler PropertyChanged;
+
+        /// <summary>
+        /// A method for invoking PropertyChanged event
+        /// </summary>
+        /// <param name="name">The name of property</param>
+        public void OnPropertyChanged(string name)
+        {
+            PropertyChangedEventHandler handler = PropertyChanged;
+            if (handler != null)
+            {
+                handler(this, new PropertyChangedEventArgs(name));
+            }
+        }
+
+        /// <summary>
+        /// A constructor
+        /// </summary>
+        public MusicPlayerViewModel()
+        {
+            ProgressBarPercentage = 0.0;
+            AlbumTitle = "Title";
+            AlbumArtist = "Artist";
+            AlbumCover = "img_media_no_contents.png";
+
+            MusicPlayerModel.Instance.SetCurrentMusicInfoListener((e, args) =>
+            {
+                if (args == null)
+                {
+                    return;
+                }
+
+                AlbumTitle = args.Title;
+                OnPropertyChanged("AlbumTitle");
+
+                AlbumArtist = args.Artist;
+                OnPropertyChanged("AlbumArtist");
+
+                AlbumCover = args.AlbumCover;
+                OnPropertyChanged("AlbumCover");
+            });
+
+            MusicPlayerModel.Instance.SetCurrentMusicProgressListener((e, arg) =>
+            {
+                if (arg == null)
+                {
+                    return;
+                }
+
+                ProgressBarPercentage = arg.Progress;
+
+                OnPropertyChanged("ProgressBarPercentage");
+            });
+        }
+    }
+}
diff --git a/TVMediaHub/TVMediaHub.Tizen/ViewModels/MusicPlayerViewModelLocator.cs b/TVMediaHub/TVMediaHub.Tizen/ViewModels/MusicPlayerViewModelLocator.cs
new file mode 100644 (file)
index 0000000..bc63141
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2017 Samsung Electronics Co., Ltd
+ *
+ * Licensed under the Flora License, Version 1.1 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://floralicense.org/license/
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace TVMediaHub.Tizen.ViewModels
+{
+    /// <summary>
+    /// A class to have static instance of MusicPlayerViewModel
+    /// </summary>
+    public static class MusicPlayerViewModelLocator
+    {
+        /// <summary>
+        /// An instance of the MusicPlayerViewModel
+        /// </summary>
+        private static MusicPlayerViewModel _viewModel = new MusicPlayerViewModel();
+
+        /// <summary>
+        /// Gets the instance of the MusicPlayerViewModel
+        /// </summary>
+        public static MusicPlayerViewModel ViewModel
+        {
+            get
+            {
+                return _viewModel;
+            }
+        }
+    }
+}
\ No newline at end of file
index f05af0c..29298a4 100755 (executable)
@@ -19,6 +19,7 @@ using System.Collections.ObjectModel;
 using System.ComponentModel;
 using System.Threading;
 using System.Windows.Input;
+using TVMediaHub.Tizen.DataModels;
 using TVMediaHub.Tizen.Models;
 using TVMediaHub.Tizen.Utils;
 using Xamarin.Forms;
@@ -55,14 +56,22 @@ namespace TVMediaHub.Tizen.ViewModels
         /// </summary>
         public ICommand ChangeSortOptionCommand { get; set; }
 
-        private SortOption option = SortOption.Title;
-
         /// <summary>
         /// A command for executing to get informations
         /// </summary>
         public ICommand GetInformationsCommand { get; set; }
 
         /// <summary>
+        /// The information of the current music
+        /// </summary>
+        public MediaInformationEx CurrentMusic { get; set; }
+
+        /// <summary>
+        /// The sort option to display items of the music tab
+        /// </summary>
+        private SortOption option = SortOption.Title;
+
+        /// <summary>
         /// An event that is occurred when property of ViewModel is changed
         /// </summary>
         public event PropertyChangedEventHandler PropertyChanged;
@@ -127,6 +136,7 @@ namespace TVMediaHub.Tizen.ViewModels
                 "ARTIST",
                 "GENRE",
             };
+
             SortOptions = list;
             OnPropertyChanged("SortOptions");
 
@@ -135,6 +145,7 @@ namespace TVMediaHub.Tizen.ViewModels
                 "DETAIL INFO",
                 "DELETE"
             };
+
             OptionList = list;
             OnPropertyChanged("OptionList");
         }
@@ -175,7 +186,18 @@ namespace TVMediaHub.Tizen.ViewModels
                     ReadMusicList(option);
                 }, "");
             });
+
             OnPropertyChanged("ChangeSortOptionCommand");
         }
+
+        /// <summary>
+        /// Sets the current music
+        /// </summary>
+        /// <param name="musicContent">The given content to be set</param>
+        public void SetCurrentMusic(MediaInformationEx musicContent)
+        {
+            CurrentMusic = MusicPlayerModel.Instance.CurrentMusic = musicContent;
+            OnPropertyChanged("CurrentMusic");
+        }
     }
 }
index 319961b..9bab807 100644 (file)
@@ -25,6 +25,7 @@ namespace TVMediaHub.Tizen.ViewModels
         /// An instance of the MusicTabViewModel
         /// </summary>
         private static MusicTabViewModel _viewModel = new MusicTabViewModel();
+
         /// <summary>
         /// Gets the instance of the MusicTabViewModel
         /// </summary>
index fab84cd..838702f 100755 (executable)
@@ -25,6 +25,7 @@ namespace TVMediaHub.Tizen.ViewModels
         /// An instance of the VideoTabViewModel
         /// </summary>
         private static VideoTabViewModel _viewModel = null;
+
         /// <summary>
         /// Gets the instance of the VideoTabViewModel
         /// </summary>
index 08eb93e..6a9fa7a 100755 (executable)
@@ -470,6 +470,7 @@ namespace TVMediaHub.Tizen.Views
                     ContextPopupItemSelectedHandler?.Invoke(SelectedImage, ImageContextPopupItem.Delete);
                     break;
             }
+
             ctxPopup.Dismiss();
         }
 
index b858412..f1ed435 100755 (executable)
@@ -915,9 +915,10 @@ namespace TVMediaHub.Tizen.Views
             UngrabRemoteKeys();
         }
 
-        /// <summary>e
+        /// <summary>
         /// A method for hiding control area when timer is over
         /// </summary>
+        /// <param name="state">The state to be changed</param>
         private void HideControlAreaHandler(object state)
         {
             SetControlAreaState(ControlAreaState.HIDE);
index 6aab07b..34a465f 100644 (file)
@@ -81,10 +81,10 @@ namespace TVMediaHub.Tizen.Views
         /// <param name="e">A propertyChanged event argument</param>
         private void MusicGroupPropertyChanged(object sender, PropertyChangedEventArgs e)
         {
-            if(e.PropertyName.Equals("ItemsSource"))
+            if (e.PropertyName.Equals("ItemsSource"))
             {
                 var index = 0;
-                foreach(var item in ItemsSource)
+                foreach (var item in ItemsSource)
                 {
                     var itemView = new MusicItem();
                     itemView.BindingContext = item;
index 9404527..c74e79f 100644 (file)
@@ -5,11 +5,6 @@
                 xmlns:Utils="clr-namespace:TVMediaHub.Tizen.Utils"
                 xmlns:Views="clr-namespace:TVMediaHub.Tizen.Views"
                 MusicInfo="{Binding Information}">
-    <Button x:Name="FocusArea"
-            Opacity="0"
-            Clicked="OnItemClicked"
-            Focused="OnItemFocused"
-            Unfocused="OnItemUnfocused"/>
     <Grid>
         <Grid.RowDefinitions>
             <RowDefinition Height="3*" />
         <Image x:Name="AlbumCover"
                Grid.Row="0"
                Grid.RowSpan="3"
-               Grid.Column="0"
-               Source="{Binding ThumbnailPath}"/>
+               Grid.Column="0"/>
         <Label x:Name="SongTitle"
                Grid.Row="0"
                Grid.Column="1"
-               LineBreakMode="TailTruncation"
-               Text="{Binding ContentName}"/>
+               LineBreakMode="TailTruncation"/>
         <Label x:Name="Artist"
                Grid.Row="1"
                Grid.Column="1"
                Grid.Column="1"
                LineBreakMode="TailTruncation"/>
     </Grid>
+    <Button x:Name="FocusArea"
+            RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=1}"
+            RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}"
+            RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0}"
+            RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0}"
+            Opacity="0"
+            Clicked="OnItemClicked"
+            Focused="OnItemFocused"
+            Unfocused="OnItemUnfocused"/>
 </RelativeLayout>
\ No newline at end of file
index 840f471..0285c9e 100644 (file)
@@ -19,6 +19,7 @@ using System.ComponentModel;
 using Tizen.Content.MediaContent;
 using TVMediaHub.Tizen.DataModels;
 using TVMediaHub.Tizen.Utils;
+using TVMediaHub.Tizen.ViewModels;
 using Xamarin.Forms;
 using Xamarin.Forms.Xaml;
 
@@ -87,7 +88,9 @@ namespace TVMediaHub.Tizen.Views
         /// <param name="e">A Focus event's argument</param>
         private void OnItemClicked(object sender, EventArgs e)
         {
+            DbgPort.D("MusicItem is clicked : " + (MusicInfo.MediaContentInformation as AudioInformation).Title);
 
+            MusicTabViewModelLocator.ViewModel.SetCurrentMusic(MusicInfo);
         }
 
         /// <summary>
@@ -97,7 +100,7 @@ namespace TVMediaHub.Tizen.Views
         /// <param name="e">A Focus event's argument</param>
         private void OnItemFocused(object sender, FocusEventArgs e)
         {
-
+            DbgPort.D("MusicItem is focused : " + (MusicInfo.MediaContentInformation as AudioInformation).Title);
         }
 
         /// <summary>
@@ -107,7 +110,7 @@ namespace TVMediaHub.Tizen.Views
         /// <param name="e">A Focus event's argument</param>
         private void OnItemUnfocused(object sender, FocusEventArgs e)
         {
-
+            DbgPort.D("MusicItem is unfocused : " + (MusicInfo.MediaContentInformation as AudioInformation).Title);
         }
 
         /// <summary>
@@ -120,6 +123,7 @@ namespace TVMediaHub.Tizen.Views
             if (e.PropertyName.Equals("MusicInfo"))
             {
                 AudioInformation info = MusicInfo.MediaContentInformation as AudioInformation;
+                AlbumCover.Source = (info.ThumbnailPath.Length != 0) ? info.ThumbnailPath : "img_media_no_contents.png";
                 SongTitle.Text = info.Title;
                 Artist.Text = info.Artist;
                 AlbumTitle.Text = info.Album;
diff --git a/TVMediaHub/TVMediaHub.Tizen/Views/MusicPlayer.xaml b/TVMediaHub/TVMediaHub.Tizen/Views/MusicPlayer.xaml
new file mode 100644 (file)
index 0000000..3667788
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<StackLayout xmlns="http://xamarin.com/schemas/2014/forms"
+                  xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+                  x:Class="TVMediaHub.Tizen.Views.MusicPlayer">
+    <Image x:Name="MusicPlayerAlbumArt"
+           Source="{Binding AlbumCover}"
+           WidthRequest="300"
+           HeightRequest="300"
+           HorizontalOptions="Center"/>
+    <Label x:Name="MusicPlayerTitle"
+           Text="{Binding AlbumTitle}"
+           HorizontalOptions="Center"/>
+    <Label x:Name="MusicPlayerArtist"
+           Text="{Binding AlbumArtist}"
+           HorizontalOptions="Center"/>
+    <ProgressBar x:Name="MusicPlayerProgressbar"
+                 Progress="{Binding ProgressBarPercentage}"/>
+</StackLayout>
\ No newline at end of file
diff --git a/TVMediaHub/TVMediaHub.Tizen/Views/MusicPlayer.xaml.cs b/TVMediaHub/TVMediaHub.Tizen/Views/MusicPlayer.xaml.cs
new file mode 100644 (file)
index 0000000..008a402
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+* Copyright (c) 2017 Samsung Electronics Co., Ltd
+*
+* Licensed under the Flora License, Version 1.1 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*     http://floralicense.org/license/
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+using TVMediaHub.Tizen.ViewModels;
+using Xamarin.Forms;
+
+namespace TVMediaHub.Tizen.Views
+{
+    /// <summary>
+    /// A custom ContentPage for displaying the music player
+    /// </summary>
+    public partial class MusicPlayer : StackLayout
+    {
+        /// <summary>
+        /// A constructor
+        /// </summary>
+        public MusicPlayer()
+        {
+            BindingContext = MusicPlayerViewModelLocator.ViewModel;
+
+            InitializeComponent();
+        }
+    }
+}
index 78f5d61..7a13d16 100755 (executable)
                                       SortOptions="{Binding SortOptions}"
                                       OptionList="{Binding OptionList}"/>
         </RelativeLayout>
+        <Views:MusicPlayer x:Name="MusicPlayer"
+                           RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.855}"
+                           RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.3}"
+                           RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.0}">
+        </Views:MusicPlayer>
         <ScrollView x:Name="MusicTabScrollView"
                     RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=0.855}"
-                    RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}"
+                    RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.7}"
+                    RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=0.3}"
                     Orientation="Horizontal" IsVisible="False">
             <StackLayout x:Name="MusicContentView"
                          Orientation="Horizontal"
index 69ff533..918b62e 100755 (executable)
@@ -180,6 +180,7 @@ namespace TVMediaHub.Tizen.Views
                     MusicNoContents.IsVisible = false;
                     MusicTabScrollView.IsVisible = true;
                 }
+
                 MusicGroup groupView = new MusicGroup();
 
                 var groupItem = e.NewItems[0];