From: aman.jeph Date: Fri, 11 Jun 2021 11:57:12 +0000 (+0530) Subject: Adding playerview and related class X-Git-Tag: submit/tizen/20210915.141722~11 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=52475dba0f5788f90f25c40aafc3826b4733ec2d;p=profile%2Fiot%2Fapps%2Fdotnet%2Fmusic-player.git Adding playerview and related class Change-Id: I0890702f0dca7ae9e8aaf607c562b2800cdf3b69 Signed-off-by: aman.jeph --- diff --git a/Common/AppConstants.cs b/Common/AppConstants.cs new file mode 100755 index 0000000..98cfef0 --- /dev/null +++ b/Common/AppConstants.cs @@ -0,0 +1,11 @@ +namespace MusicPlayer.Common +{ + class AppConstants + { + // LogTag + public const string LogTag = "MUSIC_PLAYER"; + // KeyCodes + public const string BackKeyCode = "XF86Back"; + public const string EscapeKeyCode = "Escape"; + } +} diff --git a/Common/PlayerCommon.cs b/Common/PlayerCommon.cs new file mode 100755 index 0000000..a2703c7 --- /dev/null +++ b/Common/PlayerCommon.cs @@ -0,0 +1,27 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MusicPlayer.Common +{ + public enum RepeatMode + { + Off, + RepeatOne, + RepeatAll, + } + + public enum PlayingStatus + { + None, + Playing, + Paused, + Stopped, + } + + public enum ShuffleMode + { + On, + Off, + } +} diff --git a/Common/Resources.cs b/Common/Resources.cs new file mode 100644 index 0000000..865883c --- /dev/null +++ b/Common/Resources.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace MusicPlayer.Common +{ + public class Resources + { + public static string GetImagePath() + { + return Tizen.Applications.Application.Current.DirectoryInfo.Resource + "images/"; + } + } +} diff --git a/Common/UIColors.cs b/Common/UIColors.cs new file mode 100755 index 0000000..dd3026a --- /dev/null +++ b/Common/UIColors.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Tizen.NUI; + +namespace MusicPlayer.Common +{ + class UIColors + { + public static readonly Color HEX000209 = new Color(0.0f, 0.0078f, 0.0353f, 1.0f); + public static readonly Color HEX001447 = new Color(0.0f, 0.0784f, 0.2784f, 1.0f); + public static readonly Color HEXEEEFF1 = new Color(0.9333f, 0.9373f, 0.9450f, 1.0f); + + public static readonly Color LyricsBackground = new Color(0.0f, 0.0f, 0.0f, 0.85f); + public static readonly Color ItemSeperator = new Color(0.75f, 0.79f, 0.82f, 1.0f); + + } +} diff --git a/MediaContent/AlbumContents.cs b/MediaContent/AlbumContents.cs index 312cf28..2c32f06 100755 --- a/MediaContent/AlbumContents.cs +++ b/MediaContent/AlbumContents.cs @@ -19,7 +19,7 @@ namespace MusicPlayer.Media Album info = dataReader.Current; albumList.Add(info.Id, info); } - Tizen.Log.Debug(Constants.LogTag, "Total album retrived from database: " + albumList.Count); + Tizen.Log.Debug(AppConstants.LogTag, "Total album retrived from database: " + albumList.Count); dataReader.Dispose(); return albumList; } diff --git a/MediaContent/ArtistContents.cs b/MediaContent/ArtistContents.cs index b0bc7be..e9e2b66 100755 --- a/MediaContent/ArtistContents.cs +++ b/MediaContent/ArtistContents.cs @@ -21,7 +21,7 @@ namespace MusicPlayer.Media string info = (string)dataReader.Current; artistList.Add(info); } - Tizen.Log.Debug(Constants.LogTag, "Total artists retrived from database: " + artistList.Count); + Tizen.Log.Debug(AppConstants.LogTag, "Total artists retrived from database: " + artistList.Count); dataReader.Dispose(); return artistList; } @@ -53,19 +53,19 @@ namespace MusicPlayer.Media } catch (ObjectDisposedException ex) { - Tizen.Log.Error(Constants.LogTag, "ObjectDisposedException: " + ex.Message); + Tizen.Log.Error(AppConstants.LogTag, "ObjectDisposedException: " + ex.Message); } catch (InvalidOperationException ex) { - Tizen.Log.Error(Constants.LogTag, "InvalidOperationException: " + ex.Message); + Tizen.Log.Error(AppConstants.LogTag, "InvalidOperationException: " + ex.Message); } catch (MediaDatabaseException ex) { - Tizen.Log.Error(Constants.LogTag, "MediaDatabaseException: " + ex.Message); + Tizen.Log.Error(AppConstants.LogTag, "MediaDatabaseException: " + ex.Message); } catch (Exception ex) { - Tizen.Log.Error(Constants.LogTag, "Unknown Exception: " + ex.Message); + Tizen.Log.Error(AppConstants.LogTag, "Unknown Exception: " + ex.Message); } return count; diff --git a/MediaContent/PlaylistContents.cs b/MediaContent/PlaylistContents.cs index d7f9f34..d3e69ff 100755 --- a/MediaContent/PlaylistContents.cs +++ b/MediaContent/PlaylistContents.cs @@ -17,7 +17,7 @@ namespace MusicPlayer.Media Playlist playlist = dataReader.Current; playlists.Add(playlist); } - Tizen.Log.Debug(Constants.LogTag, "PlayLists Count : " + playlists.Count); + Tizen.Log.Debug(AppConstants.LogTag, "PlayLists Count : " + playlists.Count); return playlists; } diff --git a/MediaContent/TrackContents.cs b/MediaContent/TrackContents.cs index 1ce5290..551a80c 100755 --- a/MediaContent/TrackContents.cs +++ b/MediaContent/TrackContents.cs @@ -18,7 +18,7 @@ namespace MusicPlayer.Media MediaInfo info = dataReader.Current; mediaList.Add(info.Id, info); } - Tizen.Log.Debug(Constants.LogTag, "Total track retrived from database: " + mediaList.Count); + Tizen.Log.Debug(AppConstants.LogTag, "Total track retrived from database: " + mediaList.Count); dataReader.Dispose(); return mediaList; } diff --git a/Models/PlayerModel.cs b/Models/PlayerModel.cs new file mode 100755 index 0000000..1d37e93 --- /dev/null +++ b/Models/PlayerModel.cs @@ -0,0 +1,70 @@ +using MusicPlayer.Common; + +namespace MusicPlayer.Models +{ + class PlayerModel : PropertyNotifier + { + private Track currentTrack; + private string trackName; + private string trackArtist; + private int trackLength; + private int trackPlayingTime; //TODO need to use with mmplayer + private string thumbnailPath; + private PlayingStatus playingStatus; + + public PlayerModel() + { + } + public PlayerModel(Track track) + { + CurrentTrack = track; + } + + public Track CurrentTrack + { + set + { + currentTrack = value; + TrackName = currentTrack.TrackTitle; + TrackArtist = currentTrack.ArtistName; + TrackLength = currentTrack.Duration; + ThumbnailPath = currentTrack.ThumbnailPath; + PlayingStatus = PlayingStatus.None; + } + get + { + return currentTrack; + } + } + + public string TrackName + { + get => trackName; + set => SetProperty(ref trackName, value); + } + + public string TrackArtist + { + get => trackArtist; + set => SetProperty(ref trackArtist, value); + } + + public int TrackLength + { + get => trackLength; + set => SetProperty(ref trackLength, value); + } + + public string ThumbnailPath + { + get => thumbnailPath; + set => SetProperty(ref thumbnailPath, value); + } + + public PlayingStatus PlayingStatus + { + get => playingStatus; + set { playingStatus = value; } + } + } +} diff --git a/Models/Track.cs b/Models/Track.cs index c92dcae..de4d2ff 100755 --- a/Models/Track.cs +++ b/Models/Track.cs @@ -50,19 +50,13 @@ namespace MusicPlayer.Models public string Id { get => id; - set - { - id = value; - } + set { id = value; } } // TODO create new property of duration in string public int Duration { get => duration; - set - { - duration = value; - } + set { duration = value; } } public string ThumbnailPath { @@ -77,10 +71,7 @@ namespace MusicPlayer.Models public string FilePath { get => filePath; - set - { - filePath = value; - } + set { filePath = value; } } } } diff --git a/MusicPlayer.cs b/MusicPlayer.cs index 4ea8ee9..1a0a01e 100755 --- a/MusicPlayer.cs +++ b/MusicPlayer.cs @@ -9,20 +9,20 @@ namespace MusicPlayer { protected override void OnCreate() { - Tizen.Log.Info(Constants.LogTag, "OnCreate statrted"); + Tizen.Log.Info(AppConstants.LogTag, "OnCreate statrted"); base.OnCreate(); Window window = Window.Instance; window.BackgroundColor = Color.White; window.KeyEvent += OnKeyEvent; Size2D size = window.Size; - Tizen.Log.Info(Constants.LogTag, "Window Size: " + size.Width + "x" + size.Height); + Tizen.Log.Info(AppConstants.LogTag, "Window Size: " + size.Width + "x" + size.Height); ViewManager manager = new ViewManager(Window.Instance); } public void OnKeyEvent(object sender, Window.KeyEventArgs e) { - if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == Constants.BackKeyCode || e.Key.KeyPressedName == Constants.EscapeKeyCode)) + if (e.Key.State == Key.StateType.Down && (e.Key.KeyPressedName == AppConstants.BackKeyCode || e.Key.KeyPressedName == AppConstants.EscapeKeyCode)) { Exit(); } @@ -30,10 +30,10 @@ namespace MusicPlayer static void Main(string[] args) { - Tizen.Log.Info(Constants.LogTag, "Main statrted"); + Tizen.Log.Info(AppConstants.LogTag, "Main statrted"); var app = new Application(); app.Run(args); - Tizen.Log.Info(Constants.LogTag, "Main finished"); + Tizen.Log.Info(AppConstants.LogTag, "Main finished"); } } } diff --git a/ViewModels/PlayerViewModel.cs b/ViewModels/PlayerViewModel.cs new file mode 100755 index 0000000..5c2b290 --- /dev/null +++ b/ViewModels/PlayerViewModel.cs @@ -0,0 +1,89 @@ +using System; +using System.Collections.Generic; +using System.Text; +using MusicPlayer.Models; +using MusicPlayer.Common; + +namespace MusicPlayer.ViewModels +{ + class PlayerViewModel : PropertyNotifier + { + internal PlayerModel playerModel; + internal PlayingListViewModel playingListViewModel; + internal LyricsViewModel lyricsViewModel; + private string playPauseUrl; + + public PlayerViewModel() + { + lyricsViewModel = new LyricsViewModel(); + playingListViewModel = new PlayingListViewModel(); + playerModel = new PlayerModel(); + PlayPauseUrl = Resources.GetImagePath() + "play.png"; + } + + public PlayingListViewModel CurrentPlayingListViewModel + { + get => playingListViewModel; + } + + public void SetCurrentTrack(Track track) + { + playerModel.CurrentTrack = track; + lyricsViewModel.CurrentTrack = track; + } + + public void SetPlayingList(TrackListViewModel trackListVM) + { + playingListViewModel.SetTrackListViewModel(trackListVM); + } + + public void ShuffleChanged() + { + ShuffleMode currentMode = playingListViewModel.ShuffleMode; + playingListViewModel.ShuffleMode = ((currentMode == ShuffleMode.Off) ? ShuffleMode.On : ShuffleMode.Off); + } + + public void RepeatChanged() + { + var values = Enum.GetValues(typeof(RepeatMode)); + int i = 0; + foreach (RepeatMode mode in values) + { + if (playingListViewModel.RepeatMode == mode) + break; + i++; + } + RepeatMode new_mode = RepeatMode.Off; + RepeatMode [] repeatArr = (RepeatMode [])values; + if(i+1 >= values.Length) + { + new_mode = repeatArr[0]; + } + else + { + new_mode = repeatArr[i + 1]; + } + playingListViewModel.RepeatMode = new_mode; + } + + public string PlayPauseUrl + { + get => playPauseUrl; + set => SetProperty(ref playPauseUrl, value); + } + + public void PlayingStatusChanged() + { + if(playerModel.PlayingStatus == PlayingStatus.Playing) + { + playerModel.PlayingStatus = PlayingStatus.Paused; + PlayPauseUrl = Resources.GetImagePath() + "play.png"; + } + else + { + playerModel.PlayingStatus = PlayingStatus.Playing; + PlayPauseUrl = Resources.GetImagePath() + "pause.png"; + } + } + } +} diff --git a/ViewModels/PlayingListViewModel.cs b/ViewModels/PlayingListViewModel.cs new file mode 100755 index 0000000..c058bfe --- /dev/null +++ b/ViewModels/PlayingListViewModel.cs @@ -0,0 +1,262 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using MusicPlayer.ViewModels; +using System.Threading; +using MusicPlayer.Common; + +namespace MusicPlayer.ViewModels +{ + public static class ThreadSafeRandom + { + [ThreadStatic] private static Random Local; + + public static Random ThisThreadsRandom + { + get { return Local ??= new Random(unchecked(Environment.TickCount * 31 + Thread.CurrentThread.ManagedThreadId)); } + } + } + + static class ShuffleExtension + { + public static void Shuffle(this IList list) + { + int n = list.Count; + while (n > 1) + { + n--; + int k = ThreadSafeRandom.ThisThreadsRandom.Next(n + 1); + T value = list[k]; + list[k] = list[n]; + list[n] = value; + } + } + } + + class PlayingListViewModel : PropertyNotifier + { + private TrackListViewModel tracklistViewModel; + private List shuffleList; + private int currentIndex; + private RepeatMode repeatMode; + private ShuffleMode shuffleMode; + public event EventHandler ItemsSourceChanged; + private string shuffleButtonUrl; + private string repeatButtonUrl; + + public PlayingListViewModel() + { + shuffleList = new List(); + currentIndex = -1; + tracklistViewModel = null; + RepeatMode = RepeatMode.Off; + ShuffleMode = ShuffleMode.Off; + } + + private void UpdateShuffleList(int count) + { + shuffleList.Clear(); + shuffleList.AddRange(Enumerable.Range(0, count - 1)); + } + + private void OnItemsSourceChanged(EventArgs eventArgs) + { + ItemsSourceChanged?.Invoke(this, eventArgs); + } + + public void SetTrackListViewModel(TrackListViewModel trackListVM) + { + // Need to check for same VM and in case same VM just update the playing track + Tizen.Log.Info(AppConstants.LogTag, "Setting Current Playing list"); + tracklistViewModel = trackListVM; + currentIndex = 0; + RepeatMode = RepeatMode.Off; + ShuffleMode = ShuffleMode.Off; + OnItemsSourceChanged(new EventArgs()); + } + + public TrackListViewModel TrackListVM + { + get => tracklistViewModel; + } + + public string ShuffleUrl + { + get => shuffleButtonUrl; + set => SetProperty(ref shuffleButtonUrl, value); + } + + public ShuffleMode ShuffleMode + { + get => shuffleMode; + set + { + shuffleMode = value; + if(value == ShuffleMode.On) + { + shuffleList.Shuffle(); + } + else + { + if (tracklistViewModel != null) + { + UpdateShuffleList(tracklistViewModel.Count); + } + } + if (shuffleMode == ShuffleMode.On) + ShuffleUrl = Resources.GetImagePath() + "shuffle_on.png"; + else + ShuffleUrl = Resources.GetImagePath() + "shuffle_off.png"; + } + } + + public string RepeatUrl + { + get => repeatButtonUrl; + set => SetProperty(ref repeatButtonUrl, value); + } + + public RepeatMode RepeatMode + { + get => repeatMode; + set + { + repeatMode = value; + if (repeatMode == RepeatMode.Off) + RepeatUrl = Resources.GetImagePath() + "repeat_off.png"; + else if (repeatMode == RepeatMode.RepeatOne) + RepeatUrl = Resources.GetImagePath() + "repeat_one.png"; + else + RepeatUrl = Resources.GetImagePath() + "repeat_all.png"; + } + } + + public string Next() + { + if(currentIndex < 0 ) + { + Tizen.Log.Error(AppConstants.LogTag,"Invalid track index"); + return null; + } + if(RepeatMode == RepeatMode.RepeatOne) + { + return tracklistViewModel[shuffleList[currentIndex]].FilePath; + } + else if(RepeatMode == RepeatMode.Off) + { + if (currentIndex + 1 >= shuffleList.Count) + { + return null; + } + else + { + currentIndex += 1; + return tracklistViewModel[shuffleList[currentIndex]].FilePath; + } + } + else + { + if (currentIndex + 1 >= shuffleList.Count) + { + currentIndex = 0; + return tracklistViewModel[shuffleList[currentIndex]].FilePath; + } + else + { + currentIndex += 1; + return tracklistViewModel[shuffleList[currentIndex]].FilePath; + } + } + } + + public string Prev() + { + if (currentIndex < 0) + { + Tizen.Log.Error(AppConstants.LogTag, "Invalid track index"); + return null; + } + if (RepeatMode == RepeatMode.RepeatOne) + { + return tracklistViewModel[shuffleList[currentIndex]].FilePath; + } + else if (RepeatMode == RepeatMode.Off) + { + if (currentIndex - 1 < 0) + { + return null; + } + else + { + currentIndex -= 1; + return tracklistViewModel[shuffleList[currentIndex]].FilePath; + } + } + else + { + if (currentIndex - 1 < 0) + { + currentIndex = shuffleList.Count-1; + return tracklistViewModel[shuffleList[currentIndex]].FilePath; + } + else + { + currentIndex -= 1; + return tracklistViewModel[shuffleList[currentIndex]].FilePath; + } + } + } + + public bool HasNext() + { + if (currentIndex < 0 && currentIndex > shuffleList.Count) + return false; + if(RepeatMode == RepeatMode.RepeatOne || RepeatMode == RepeatMode.RepeatAll) + { + return true; + } + else + { + return currentIndex + 1 < shuffleList.Count ? true : false; + } + } + + public bool HasPrev() + { + if (currentIndex < 0 && currentIndex > shuffleList.Count) + return false; + if (RepeatMode == RepeatMode.RepeatOne || RepeatMode == RepeatMode.RepeatAll) + { + return true; + } + else + { + return currentIndex - 1 >= 0 ? true : false; + } + } + + public string Current() + { + if (currentIndex < 0 && currentIndex > shuffleList.Count) + return null; + else + return tracklistViewModel[shuffleList[currentIndex]].FilePath; + } + + public void SetPlayingTrack(string mediaId) + { + int count = 0; + for(count = 0; count< tracklistViewModel.Count; ++count) + { + if (mediaId == tracklistViewModel[0].Id) + { + currentIndex = count; + return; + } + } + currentIndex = -1; + } + } +} diff --git a/ViewModels/TrackListViewModel.cs b/ViewModels/TrackListViewModel.cs index 5b40008..8670d35 100755 --- a/ViewModels/TrackListViewModel.cs +++ b/ViewModels/TrackListViewModel.cs @@ -19,7 +19,7 @@ namespace MusicPlayer.ViewModels { Add(new Track((AudioInfo)item.Value)); } - Tizen.Log.Debug(Constants.LogTag, "Observable list item count: " + this.Count); + Tizen.Log.Debug(AppConstants.LogTag, "Observable list item count: " + this.Count); } } } diff --git a/ViewModels/TrackViewModel.cs b/ViewModels/TrackViewModel.cs index 38ed6cb..4fcf53c 100755 --- a/ViewModels/TrackViewModel.cs +++ b/ViewModels/TrackViewModel.cs @@ -31,7 +31,7 @@ namespace MusicPlayer.ViewModels public string TrackCount { get => trackCount; - set => SetProperty(ref trackCount, value); + set => SetProperty(ref trackCount, value + " tracks"); } } } diff --git a/Views/BaseContentView.cs b/Views/BaseContentView.cs index 3514758..d62b178 100755 --- a/Views/BaseContentView.cs +++ b/Views/BaseContentView.cs @@ -42,9 +42,9 @@ namespace MusicPlayer.Views ItemTemplate = new DataTemplate(() => { TrackLayout layout = new TrackLayout(); - layout.Thumbnail.SetBinding(ImageView.ResourceUrlProperty, "ThumbnailPath"); - layout.TitleText.SetBinding(TextLabel.TextProperty, "TrackTitle"); - layout.SubtitletText.SetBinding(TextLabel.TextProperty, "ArtistName"); + layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "ThumbnailPath"); + layout.TitleLabel.SetBinding(TextLabel.TextProperty, "TrackTitle"); + layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName"); return layout; }), ScrollingDirection = ScrollableBase.Direction.Vertical, diff --git a/Views/BaseView.cs b/Views/BaseView.cs index 6ed379e..e78f0f6 100755 --- a/Views/BaseView.cs +++ b/Views/BaseView.cs @@ -53,7 +53,7 @@ namespace MusicPlayer.Views Text = "Music", PixelSize = 40, FontFamily = "BreezeSans", - TextColor = new Color(0.0f, 0.0078f, 0.0353f, 1.0f), + TextColor = UIColors.HEX000209, HorizontalAlignment = HorizontalAlignment.Begin, Margin = new Extents(0, 0, 6, 6), Ellipsis = true, @@ -105,22 +105,13 @@ namespace MusicPlayer.Views public Tab Tabs { - get - { - return tabs; - } + get => tabs; } public string Title { - set - { - titleLabel.Text = value; - } - get - { - return titleLabel.Text; - } + get => titleLabel.Text; + set { titleLabel.Text = value;} } public bool BackButton diff --git a/Views/PlayerView.cs b/Views/PlayerView.cs new file mode 100755 index 0000000..3202405 --- /dev/null +++ b/Views/PlayerView.cs @@ -0,0 +1,385 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Tizen.NUI.BaseComponents; +using Tizen.NUI; +using Tizen.NUI.Components; +using MusicPlayer.Common; +using Tizen.NUI.Binding; +using MusicPlayer.ViewModels; + +namespace MusicPlayer.Views +{ + class PlayerView : View + { + private const int LAYOUT_PADDING = 64; + private const int ICON_SIZE = 48; + private const int TOPBAR_SIZE = 120; + private const int CONTROL_VIEW_WIDTH = 640; + private const int CONTROL_VIEW_HEIGHT = 384; + private const int CONTROL_VIEW_MARGIN = 315; + + private View leftView; + private View rightView; + private Button backButton; + private Button moreButton; + + private View controlsView; + private Button playButton; + private Button prevButton; + private Button nextButton; + private Button shuffleButton; + private Button repeatButton; + private Slider volumeSlider; + private Slider playbackSlider; + private TextLabel titleLabel; + private TextLabel artistLabel; + private TextLabel currentTime; + private TextLabel totalTime; + + private ImageView leftVolumeIcon; + private ImageView rightVolumeIcon; + private ImageView thumb; + private Button listButton; + private Button playlistButton; + private Button favouriteButton; + private PlayingListView currentListView; + private LyricsView lyricsView; + + private PlayerViewModel viewModel; + + public PlayerView(PlayerViewModel viewModel) : base() + { + this.viewModel = viewModel; + BindingContext = viewModel.playerModel; + BackgroundColor = Color.White; + WidthResizePolicy = ResizePolicyType.FillToParent; + HeightResizePolicy = ResizePolicyType.FillToParent; + + leftView = CreateLeftView(); + rightView = CreateRightView(); + + AddTopButtons(); + AddControlView(); + AddControlElements(); + AddPlaybackSlider(); + AddListActionButtons(); + AddThumbnail(); + //AddPlayingListView(); + AddLyricsView(); + } + + private Button CreatButton(string url, int x, int y) + { + ButtonStyle buttonStyle = new ButtonStyle() + { + Icon = new ImageViewStyle() + { + ResourceUrl = url, + }, + IsSelectable = false, + IsEnabled = true, + }; + + Button button = new Button(buttonStyle) + { + Size2D = new Size2D(ICON_SIZE, ICON_SIZE), + Position2D = new Position2D(x, y), + }; + return button; + } + + private View CreateLeftView() + { + View leftView = new View() + { + BackgroundColor = Color.Transparent, + HeightResizePolicy = ResizePolicyType.FillToParent, + SizeWidth = Window.Instance.WindowSize.Width / 2, + Position2D = new Position2D(0, 0), + }; + base.Add(leftView); + return leftView; + } + + private View CreateRightView() + { + View rightView = new View() + { + BackgroundColor = Color.Green, + HeightResizePolicy = ResizePolicyType.FillToParent, + SizeWidth = Window.Instance.WindowSize.Width / 2, + Position2D = new Position2D(Window.Instance.WindowSize.Width / 2, 0), + }; + base.Add(rightView); + return rightView; + } + + private void AddTopButtons() + { + backButton = CreatButton(Resources.GetImagePath() + "back_button.png", LAYOUT_PADDING, (TOPBAR_SIZE / 2 - ICON_SIZE / 2)); + leftView.Add(backButton); + + moreButton = CreatButton(Resources.GetImagePath() + "more_button.png", Window.Instance.WindowSize.Width / 2 - LAYOUT_PADDING - ICON_SIZE, (TOPBAR_SIZE / 2 - ICON_SIZE / 2)); + rightView.Add(moreButton); + } + + private void AddControlView() + { + controlsView = new View() + { + BackgroundColor = Color.Transparent, + Size2D = new Size2D(640, 384), + Position2D = new Position2D((Window.Instance.WindowSize.Width / 4 - CONTROL_VIEW_WIDTH / 2), TOPBAR_SIZE + CONTROL_VIEW_MARGIN), + }; + rightView.Add(controlsView); + } + + private void AddTextControlElements() + { + titleLabel = new TextLabel() + { + Size2D = new Size2D(640, 48), + Position2D = new Position2D(0, 0), + PixelSize = 36, + FontFamily = "BreezeSans", + TextColor = UIColors.HEX001447, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + Ellipsis = true, + }; + titleLabel.SetBinding(TextLabel.TextProperty, "TrackName"); + controlsView.Add(titleLabel); + + artistLabel = new TextLabel() + { + Size2D = new Size2D(640, 36), + Position2D = new Position2D(0, 62), + PixelSize = 28, + FontFamily = "BreezeSans", + TextColor = UIColors.HEX001447, + HorizontalAlignment = HorizontalAlignment.Center, + VerticalAlignment = VerticalAlignment.Center, + Ellipsis = true, + }; + artistLabel.SetBinding(TextLabel.TextProperty, "TrackArtist"); + controlsView.Add(artistLabel); + } + + private void AddButtonControlElements() + { + shuffleButton = CreatButton(Resources.GetImagePath() + "shuffle.png", 0, 196); + shuffleButton.Icon.BindingContext = viewModel.playingListViewModel; + shuffleButton.Icon.SetBinding(ImageView.ResourceUrlProperty, "ShuffleUrl"); + shuffleButton.Clicked += (object sender, ClickedEventArgs e) => + { + viewModel.ShuffleChanged(); + }; + controlsView.Add(shuffleButton); + + prevButton = CreatButton(Resources.GetImagePath() + "prev.png", 168, 196); + controlsView.Add(prevButton); + + playButton = CreatButton(Resources.GetImagePath() + "play.png", 296, 196); + playButton.Icon.BindingContext = viewModel; + playButton.Icon.SetBinding(ImageView.ResourceUrlProperty, "PlayPauseUrl"); + controlsView.Add(playButton); + playButton.Clicked += (object sender, ClickedEventArgs e) => + { + viewModel.PlayingStatusChanged(); + }; + + nextButton = CreatButton(Resources.GetImagePath() + "next.png", 424, 196); + controlsView.Add(nextButton); + + repeatButton = CreatButton(Resources.GetImagePath() + "repeat.png", 592, 196); + repeatButton.Icon.BindingContext = viewModel.playingListViewModel; + repeatButton.Icon.SetBinding(ImageView.ResourceUrlProperty, "RepeatUrl"); + controlsView.Add(repeatButton); + repeatButton.Clicked += (object sender, ClickedEventArgs e) => + { + viewModel.RepeatChanged(); + }; + } + + private void AddVolumeSliderElements() + { + leftVolumeIcon = new ImageView(Resources.GetImagePath() + "left_sound_icon.png") + { + Size2D = new Size2D(ICON_SIZE, ICON_SIZE), + Position2D = new Position2D(0, 336), + }; + controlsView.Add(leftVolumeIcon); + + rightVolumeIcon = new ImageView(Resources.GetImagePath() + "right_sound_icon.png") + { + Size2D = new Size2D(ICON_SIZE, ICON_SIZE), + Position2D = new Position2D(592, 336), + }; + controlsView.Add(rightVolumeIcon); + + SliderStyle volumeSliderStyle = new SliderStyle() + { + IndicatorType = Slider.IndicatorType.Image, + TrackThickness = 4, + Track = new ImageViewStyle + { + ResourceUrl = new Selector + { + All = Resources.GetImagePath() + "empty_track.png", + }, + }, + Progress = new ImageViewStyle + { + ResourceUrl = new Selector + { + All = Resources.GetImagePath() + "progress_track.png", + }, + }, + }; + + volumeSlider = new Slider(volumeSliderStyle); + volumeSlider.Indicator = Slider.IndicatorType.Text; + volumeSlider.TrackThickness = 4; + volumeSlider.ThumbImageURLSelector = new StringSelector + { + Normal = Resources.GetImagePath() + "nomal_slider_handler.png", + Pressed = Resources.GetImagePath() + "nomal_slider_handler.png" + }; + volumeSlider.Size2D = new Size2D(496, 48); + volumeSlider.Position2D = new Position2D(72, 336); + volumeSlider.ThumbSize = new Size(36, 36); + volumeSlider.Direction = Slider.DirectionType.Horizontal; + volumeSlider.MinValue = 0; + volumeSlider.MaxValue = 100; + volumeSlider.CurrentValue = 10; + controlsView.Add(volumeSlider); + } + + private void AddControlElements() + { + AddTextControlElements(); + AddButtonControlElements(); + AddVolumeSliderElements(); + } + + private void AddPlaybackSlider() + { + View sliderView = new View() + { + Size2D = new Size2D(1792, 80), + Position2D = new Position2D(64, 950), + BackgroundColor = Color.Transparent, + }; + SliderStyle playbackSliderStyle = new SliderStyle() + { + IndicatorType = Slider.IndicatorType.Image, + TrackThickness = 4, + Track = new ImageViewStyle + { + ResourceUrl = new Selector + { + All = Resources.GetImagePath() + "empty_track.png", + }, + }, + Progress = new ImageViewStyle + { + ResourceUrl = new Selector + { + All = Resources.GetImagePath() + "progress_track.png", + }, + }, + }; + playbackSlider = new Slider(playbackSliderStyle) + { + ThumbImageURLSelector = new StringSelector + { + Normal = Resources.GetImagePath() + "nomal_slider_handler.png", + Pressed = Resources.GetImagePath() + "nomal_slider_handler.png" + }, + MinValue = 0.0f, + MaxValue = 1.0f, + WidthResizePolicy = ResizePolicyType.FillToParent, + SizeHeight = 44, + ThumbSize = new Size(36, 36), + Direction = Slider.DirectionType.Horizontal, + }; + sliderView.Add(playbackSlider); + currentTime = new TextLabel() + { + Size2D = new Size2D(400, 32), + Position2D = new Position2D(0, 48), + TextColor = UIColors.HEX001447, + PixelSize = 24, + FontFamily = "BreezeSans", + Text = "00::00:00", + HorizontalAlignment = HorizontalAlignment.Begin, + }; + sliderView.Add(currentTime); + totalTime = new TextLabel() + { + Size2D = new Size2D(400, 32), + Position2D = new Position2D(1792-400, 48), + TextColor = UIColors.HEX001447, + PixelSize = 24, + FontFamily = "BreezeSans", + HorizontalAlignment = HorizontalAlignment.End, + Text = "59:59:59", + }; + sliderView.Add(totalTime); + this.Add(sliderView); + } + + private void AddListActionButtons() + { + View actionButtonView = new View() + { + Size2D = new Size2D(224, 48), + Position2D = new Position2D((Window.Instance.WindowSize.Width / 2 - 224 - LAYOUT_PADDING), 120), + BackgroundColor = Color.Transparent, + }; + rightView.Add(actionButtonView); + + listButton = CreatButton(Resources.GetImagePath() + "playing_queue.png", 0, 0); + actionButtonView.Add(listButton); + + playlistButton = CreatButton(Resources.GetImagePath() + "addtoplaylist.png", 88, 0); + actionButtonView.Add(playlistButton); + + favouriteButton = CreatButton(Resources.GetImagePath() + "favourite_off.png", 176, 0); + actionButtonView.Add(favouriteButton); + } + + private void AddThumbnail() + { + thumb = new ImageView() + { + BackgroundColor = Color.Cyan, + Size2D = new Size2D(200, 200), + Position2D = new Position2D(380, 120), + }; + thumb.SetBinding(ImageView.ResourceUrlProperty, "ThumbnailPath"); + rightView.Add(thumb); + } + + private void AddPlayingListView() + { + if (currentListView == null) + currentListView = new PlayingListView(viewModel.CurrentPlayingListViewModel); + + currentListView.Size2D = new Size2D(832, 900); + currentListView.Position2D = new Position2D(64, 108); + leftView.Add(currentListView); + } + + private void AddLyricsView() + { + if (lyricsView == null) + lyricsView = new LyricsView(viewModel.lyricsViewModel); + + lyricsView.Size2D = new Size2D(784, 784); + lyricsView.Position2D = new Position2D(88, 120); + leftView.Add(lyricsView); + } + } +} diff --git a/Views/PlayingListView.cs b/Views/PlayingListView.cs new file mode 100755 index 0000000..893b67c --- /dev/null +++ b/Views/PlayingListView.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Tizen.NUI.BaseComponents; +using Tizen.NUI.Components; +using Tizen.NUI; +using MusicPlayer.ViewModels; +using MusicPlayer.Common; +using Tizen.NUI.Binding; + +namespace MusicPlayer.Views +{ + class PlayingListView : View + { + private CollectionView collectionView; + private PlayingListViewModel viewModel; + + public PlayingListView(PlayingListViewModel viewModel) : base() + { + this.viewModel = viewModel; + collectionView = new CollectionView() + { + BackgroundImage = Resources.GetImagePath() + "playing_list_bg.png", + ItemsSource = this.viewModel.TrackListVM, + ItemsLayouter = new LinearLayouter(), + ItemTemplate = new DataTemplate(() => + { + TrackLayout layout = new TrackLayout(832, 108); + layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "ThumbnailPath"); + layout.TitleLabel.SetBinding(TextLabel.TextProperty, "TrackTitle"); + layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName"); + return layout; + }), + ScrollingDirection = ScrollableBase.Direction.Vertical, + SelectionMode = ItemSelectionMode.Single, + WidthResizePolicy = ResizePolicyType.FillToParent, + HeightResizePolicy = ResizePolicyType.FillToParent, + }; + base.Add(collectionView); + viewModel.ItemsSourceChanged += ItemSourceChanged; + } + + private void ItemSourceChanged(object sender, EventArgs e) + { + collectionView.ItemsSource = viewModel.TrackListVM; + } + } +} diff --git a/Views/TrackLayout.cs b/Views/TrackLayout.cs index a84b827..d9908ab 100755 --- a/Views/TrackLayout.cs +++ b/Views/TrackLayout.cs @@ -1,6 +1,7 @@ using Tizen.NUI.Components; using Tizen.NUI.BaseComponents; using Tizen.NUI; +using MusicPlayer.Common; namespace MusicPlayer.Views { @@ -8,7 +9,7 @@ namespace MusicPlayer.Views { private View itemSeperator; private TextLabel titleLabel; - private TextLabel artistAndTimeLabel; + private TextLabel subtitleLabel; private ImageView icon; private static int WIDTH = 1792; @@ -48,7 +49,7 @@ namespace MusicPlayer.Views HeightSpecification = SEPERATOR_HEIGHT, ExcludeLayouting = true, Position2D = new Position2D(X, HEIGHT - SEPERATOR_HEIGHT), - BackgroundColor = new Color(0.75f, 0.79f, 0.82f, 1.0f) + BackgroundColor = UIColors.ItemSeperator, }; base.Add(itemSeperator); @@ -65,7 +66,7 @@ namespace MusicPlayer.Views }; base.Add(titleLabel); - artistAndTimeLabel = new TextLabel() + subtitleLabel = new TextLabel() { WidthSpecification = (WIDTH - (2 * LEFT_PADDING) - ICON_SIZE - PADDING), HeightSpecification = 36, @@ -76,29 +77,20 @@ namespace MusicPlayer.Views IsCreateByXaml = true, Position2D = new Position2D((X + ICON_SIZE + PADDING), MARGIN + 40) }; - base.Add(artistAndTimeLabel); + base.Add(subtitleLabel); IsCreateByXaml = true; } - public ImageView Thumbnail + public ImageView Icon { - get - { - return icon; - } + get => icon; } - public TextLabel TitleText + public TextLabel TitleLabel { - get - { - return titleLabel; - } + get => titleLabel; } - public TextLabel SubtitletText + public TextLabel SubtitleLabel { - get - { - return artistAndTimeLabel; - } + get => subtitleLabel; } protected override void Dispose(DisposeTypes type) @@ -121,9 +113,9 @@ namespace MusicPlayer.Views titleLabel?.Dispose(); titleLabel = null; - base.Remove(artistAndTimeLabel); - artistAndTimeLabel?.Dispose(); - artistAndTimeLabel = null; + base.Remove(subtitleLabel); + subtitleLabel?.Dispose(); + subtitleLabel = null; } base.Dispose(type); diff --git a/Views/TrackView.cs b/Views/TrackView.cs index 7fa3141..a6aa3f1 100755 --- a/Views/TrackView.cs +++ b/Views/TrackView.cs @@ -3,6 +3,7 @@ using Tizen.NUI.Components; using Tizen.NUI.BaseComponents; using Tizen.NUI; using Tizen.NUI.Binding; +using MusicPlayer.Common; namespace MusicPlayer.Views { @@ -15,6 +16,7 @@ namespace MusicPlayer.Views public TrackView(TrackViewModel viewModel) { this.viewModel = viewModel; + BindingContext = viewModel; collectionView.ItemsSource = viewModel.ListViewModel; collectionView.ScrollingDirection = ScrollableBase.Direction.Vertical; collectionView.WidthSpecification = LayoutParamPolicies.WrapContent; @@ -25,7 +27,7 @@ namespace MusicPlayer.Views { PixelSize = 28, Text = "TRACK COUNT", - TextColor = new Color(0.0f, 0.0784f, 0.2754f, 1.0f), + TextColor = UIColors.HEX001447, VerticalAlignment = VerticalAlignment.Center, FontFamily = "BreezeSans", IsCreateByXaml = true,