--- /dev/null
+namespace MusicPlayer.Common
+{
+ class AppConstants
+ {
+ // LogTag
+ public const string LogTag = "MUSIC_PLAYER";
+ // KeyCodes
+ public const string BackKeyCode = "XF86Back";
+ public const string EscapeKeyCode = "Escape";
+ }
+}
--- /dev/null
+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,
+ }
+}
--- /dev/null
+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/";
+ }
+ }
+}
--- /dev/null
+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);
+
+ }
+}
Album info = dataReader.Current;\r
albumList.Add(info.Id, info);\r
}\r
- Tizen.Log.Debug(Constants.LogTag, "Total album retrived from database: " + albumList.Count);\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Total album retrived from database: " + albumList.Count);\r
dataReader.Dispose();\r
return albumList;\r
}\r
string info = (string)dataReader.Current;\r
artistList.Add(info);\r
}\r
- Tizen.Log.Debug(Constants.LogTag, "Total artists retrived from database: " + artistList.Count);\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Total artists retrived from database: " + artistList.Count);\r
dataReader.Dispose();\r
return artistList;\r
}\r
}\r
catch (ObjectDisposedException ex)\r
{\r
- Tizen.Log.Error(Constants.LogTag, "ObjectDisposedException: " + ex.Message);\r
+ Tizen.Log.Error(AppConstants.LogTag, "ObjectDisposedException: " + ex.Message);\r
}\r
catch (InvalidOperationException ex)\r
{\r
- Tizen.Log.Error(Constants.LogTag, "InvalidOperationException: " + ex.Message);\r
+ Tizen.Log.Error(AppConstants.LogTag, "InvalidOperationException: " + ex.Message);\r
}\r
catch (MediaDatabaseException ex)\r
{\r
- Tizen.Log.Error(Constants.LogTag, "MediaDatabaseException: " + ex.Message);\r
+ Tizen.Log.Error(AppConstants.LogTag, "MediaDatabaseException: " + ex.Message);\r
}\r
catch (Exception ex)\r
{\r
- Tizen.Log.Error(Constants.LogTag, "Unknown Exception: " + ex.Message);\r
+ Tizen.Log.Error(AppConstants.LogTag, "Unknown Exception: " + ex.Message);\r
}\r
\r
return count;\r
Playlist playlist = dataReader.Current;\r
playlists.Add(playlist);\r
}\r
- Tizen.Log.Debug(Constants.LogTag, "PlayLists Count : " + playlists.Count);\r
+ Tizen.Log.Debug(AppConstants.LogTag, "PlayLists Count : " + playlists.Count);\r
return playlists;\r
}\r
\r
MediaInfo info = dataReader.Current;\r
mediaList.Add(info.Id, info);\r
}\r
- Tizen.Log.Debug(Constants.LogTag, "Total track retrived from database: " + mediaList.Count);\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Total track retrived from database: " + mediaList.Count);\r
dataReader.Dispose();\r
return mediaList;\r
}\r
--- /dev/null
+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; }
+ }
+ }
+}
public string Id\r
{\r
get => id;\r
- set\r
- {\r
- id = value;\r
- }\r
+ set { id = value; }\r
}\r
// TODO create new property of duration in string\r
public int Duration\r
{\r
get => duration;\r
- set\r
- {\r
- duration = value;\r
- }\r
+ set { duration = value; }\r
}\r
public string ThumbnailPath\r
{\r
public string FilePath\r
{\r
get => filePath;\r
- set\r
- {\r
- filePath = value;\r
- }\r
+ set { filePath = value; }\r
}\r
}\r
}\r
{
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();
}
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");
}
}
}
--- /dev/null
+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";
+ }
+ }
+ }
+}
--- /dev/null
+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<T>(this IList<T> 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<int> shuffleList;
+ private int currentIndex;
+ private RepeatMode repeatMode;
+ private ShuffleMode shuffleMode;
+ public event EventHandler<EventArgs> ItemsSourceChanged;
+ private string shuffleButtonUrl;
+ private string repeatButtonUrl;
+
+ public PlayingListViewModel()
+ {
+ shuffleList = new List<int>();
+ 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;
+ }
+ }
+}
{\r
Add(new Track((AudioInfo)item.Value));\r
}\r
- Tizen.Log.Debug(Constants.LogTag, "Observable list item count: " + this.Count);\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Observable list item count: " + this.Count);\r
}\r
}\r
}\r
public string TrackCount\r
{\r
get => trackCount;\r
- set => SetProperty(ref trackCount, value);\r
+ set => SetProperty(ref trackCount, value + " tracks");\r
}\r
}\r
}\r
ItemTemplate = new DataTemplate(() =>\r
{\r
TrackLayout layout = new TrackLayout();\r
- layout.Thumbnail.SetBinding(ImageView.ResourceUrlProperty, "ThumbnailPath");\r
- layout.TitleText.SetBinding(TextLabel.TextProperty, "TrackTitle");\r
- layout.SubtitletText.SetBinding(TextLabel.TextProperty, "ArtistName");\r
+ layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "ThumbnailPath");\r
+ layout.TitleLabel.SetBinding(TextLabel.TextProperty, "TrackTitle");\r
+ layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName");\r
return layout;\r
}),\r
ScrollingDirection = ScrollableBase.Direction.Vertical,\r
Text = "Music",\r
PixelSize = 40,\r
FontFamily = "BreezeSans",\r
- TextColor = new Color(0.0f, 0.0078f, 0.0353f, 1.0f),\r
+ TextColor = UIColors.HEX000209,\r
HorizontalAlignment = HorizontalAlignment.Begin,\r
Margin = new Extents(0, 0, 6, 6),\r
Ellipsis = true,\r
\r
public Tab Tabs\r
{\r
- get\r
- {\r
- return tabs;\r
- }\r
+ get => tabs;\r
}\r
\r
public string Title\r
{\r
- set\r
- {\r
- titleLabel.Text = value;\r
- }\r
- get\r
- {\r
- return titleLabel.Text;\r
- }\r
+ get => titleLabel.Text;\r
+ set { titleLabel.Text = value;}\r
}\r
\r
public bool BackButton\r
--- /dev/null
+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<string>
+ {
+ All = Resources.GetImagePath() + "empty_track.png",
+ },
+ },
+ Progress = new ImageViewStyle
+ {
+ ResourceUrl = new Selector<string>
+ {
+ 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<string>
+ {
+ All = Resources.GetImagePath() + "empty_track.png",
+ },
+ },
+ Progress = new ImageViewStyle
+ {
+ ResourceUrl = new Selector<string>
+ {
+ 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);
+ }
+ }
+}
--- /dev/null
+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;
+ }
+ }
+}
using Tizen.NUI.Components;\r
using Tizen.NUI.BaseComponents;\r
using Tizen.NUI;\r
+using MusicPlayer.Common;\r
\r
namespace MusicPlayer.Views\r
{\r
{\r
private View itemSeperator;\r
private TextLabel titleLabel;\r
- private TextLabel artistAndTimeLabel;\r
+ private TextLabel subtitleLabel;\r
private ImageView icon;\r
\r
private static int WIDTH = 1792;\r
HeightSpecification = SEPERATOR_HEIGHT,\r
ExcludeLayouting = true,\r
Position2D = new Position2D(X, HEIGHT - SEPERATOR_HEIGHT),\r
- BackgroundColor = new Color(0.75f, 0.79f, 0.82f, 1.0f)\r
+ BackgroundColor = UIColors.ItemSeperator,\r
};\r
base.Add(itemSeperator);\r
\r
};\r
base.Add(titleLabel);\r
\r
- artistAndTimeLabel = new TextLabel()\r
+ subtitleLabel = new TextLabel()\r
{\r
WidthSpecification = (WIDTH - (2 * LEFT_PADDING) - ICON_SIZE - PADDING),\r
HeightSpecification = 36,\r
IsCreateByXaml = true,\r
Position2D = new Position2D((X + ICON_SIZE + PADDING), MARGIN + 40)\r
};\r
- base.Add(artistAndTimeLabel);\r
+ base.Add(subtitleLabel);\r
IsCreateByXaml = true;\r
}\r
- public ImageView Thumbnail\r
+ public ImageView Icon\r
{\r
- get\r
- {\r
- return icon;\r
- }\r
+ get => icon;\r
}\r
- public TextLabel TitleText\r
+ public TextLabel TitleLabel\r
{\r
- get\r
- {\r
- return titleLabel;\r
- }\r
+ get => titleLabel;\r
}\r
- public TextLabel SubtitletText\r
+ public TextLabel SubtitleLabel\r
{\r
- get\r
- {\r
- return artistAndTimeLabel;\r
- }\r
+ get => subtitleLabel;\r
}\r
\r
protected override void Dispose(DisposeTypes type)\r
titleLabel?.Dispose();\r
titleLabel = null;\r
\r
- base.Remove(artistAndTimeLabel);\r
- artistAndTimeLabel?.Dispose();\r
- artistAndTimeLabel = null;\r
+ base.Remove(subtitleLabel);\r
+ subtitleLabel?.Dispose();\r
+ subtitleLabel = null;\r
}\r
\r
base.Dispose(type);\r
using Tizen.NUI.BaseComponents;\r
using Tizen.NUI;\r
using Tizen.NUI.Binding;\r
+using MusicPlayer.Common;\r
\r
namespace MusicPlayer.Views\r
{\r
public TrackView(TrackViewModel viewModel)\r
{\r
this.viewModel = viewModel;\r
+ BindingContext = viewModel;\r
collectionView.ItemsSource = viewModel.ListViewModel;\r
collectionView.ScrollingDirection = ScrollableBase.Direction.Vertical;\r
collectionView.WidthSpecification = LayoutParamPolicies.WrapContent;\r
{\r
PixelSize = 28,\r
Text = "TRACK COUNT",\r
- TextColor = new Color(0.0f, 0.0784f, 0.2754f, 1.0f),\r
+ TextColor = UIColors.HEX001447,\r
VerticalAlignment = VerticalAlignment.Center,\r
FontFamily = "BreezeSans",\r
IsCreateByXaml = true,\r