+++ /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";
-
- // string literals
- public const string TimeFormat = @"mm\:ss";
- public const string LightPlatformThemeId = "org.tizen.default-light-theme";
- public const string DarkPlatformThemeId = "org.tizen.default-dark-theme";
- }
-}
+++ /dev/null
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-namespace MusicPlayer.Common
-{
- public enum ThemeType
- {
- Light,
- Dark
- };
- public enum RepeatMode
- {
- Off,
- RepeatOne,
- RepeatAll,
- }
-
- public enum PlayingStatus
- {
- None,
- Playing,
- Paused,
- Stopped,
- }
-
- public enum ShuffleMode
- {
- On,
- Off,
- }
-
- public enum Favourite
- {
- On,
- Off,
- }
-
- public enum EventType
- {
- Error,
- PlaybackCompleted,
- }
-
- public class PlayerEventArgs : EventArgs
- {
- private readonly EventType type;
- private readonly string description;
-
- internal PlayerEventArgs(EventType eventType, string desc)
- {
- type = eventType;
- description = desc;
- }
-
- public EventType Type
- {
- get => type;
- }
- public string Description
- {
- get => description;
- }
- }
-}
+++ /dev/null
-using System;\r
-using System.Collections.Generic;\r
-using System.Text;\r
-using System.ComponentModel;\r
-using System.Runtime.CompilerServices;\r
-\r
-namespace MusicPlayer.Common\r
-{\r
- class PropertyNotifier : INotifyPropertyChanged\r
- {\r
- public event PropertyChangedEventHandler PropertyChanged;\r
-\r
- protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)\r
- {\r
- if (Equals(storage, value))\r
- {\r
- return false;\r
- }\r
-\r
- storage = value;\r
- OnPropertyChanged(propertyName);\r
- return true;\r
- }\r
-\r
- protected void OnPropertyChanged([CallerMemberName] string propertyName = null)\r
- {\r
- PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));\r
- }\r
- }\r
-}\r
+++ /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/";
- }
-
- public static string GetThemePath()
- {
- return Tizen.Applications.Application.Current.DirectoryInfo.Resource + "themes/";
- }
- }
-}
+++ /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);
-
- }
-}
+++ /dev/null
-using System.Threading;
-using System.Threading.Tasks;
-using Tizen.NUI;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.Core
-{
- static class ColorExtractor
- {
- public static async Task<Palette> GetPaletteAsync(string imagePath)
- {
- Tizen.Log.Debug(AppConstants.LogTag, "Main Thread Id: " + Thread.CurrentThread.ManagedThreadId);
- return await Task.Run(() => GeneratePalette(imagePath));
- }
-
- private static Palette GeneratePalette(string imagePath)
- {
- PixelBuffer pixelBuffer = ImageLoading.LoadImageFromFile(imagePath);
- if(pixelBuffer == null)
- {
- Tizen.Log.Error(AppConstants.LogTag, "Pixel buffer is null");
- return null;
- }
-
- Palette palette = null;
-
- try
- {
- palette = Palette.Generate(pixelBuffer);
- }
- catch(System.ArgumentNullException e)
- {
- Tizen.Log.Error(AppConstants.LogTag, "ArgumentNullException: " + e.Message);
- }
-
- return palette;
- }
- }
-}
+++ /dev/null
-using System;
-using System.Threading.Tasks;
-using Tizen.Multimedia;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.Core
-{
- public class MusicPlayer
- {
- private readonly Player player = new Player();
-
- public MusicPlayer()
- {
- player.ErrorOccurred += OnErrorOccurred;
- player.PlaybackCompleted += OnPlayBackCompleted;
- }
-
- public event EventHandler<PlayerEventArgs> PlayerEvent;
-
- private enum PlayerValidationState
- {
- Start,
- Stop,
- Pause,
- Resume,
- Position,
- }
-
- public PlayerState State
- {
- get => player.State;
- }
-
- public void SetSource(string uri)
- {
- if(State != PlayerState.Idle)
- {
- Tizen.Log.Error(AppConstants.LogTag, "Player is not in idle state, can't set source");
- return;
- }
- try
- {
- Tizen.Log.Error(AppConstants.LogTag, "setting uri: " + uri);
- player.SetSource(new MediaUriSource(uri));
- }
- catch (UnauthorizedAccessException ex)
- {
- Tizen.Log.Error(AppConstants.LogTag, "UnauthorizedAccessException: " + ex.Message);
- }
- catch (ObjectDisposedException ex)
- {
- Tizen.Log.Error(AppConstants.LogTag, "ObjectDisposed: " + ex.Message);
- }
- catch (InvalidOperationException ex)
- {
- Tizen.Log.Error(AppConstants.LogTag, "InvalidOperationException: " + ex.Message);
- }
- }
-
- public async Task PreparePlayer()
- {
- try
- {
- await player.PrepareAsync();
- }
- catch (ObjectDisposedException ex)
- {
- Tizen.Log.Error("MusicPlayer", "ObjectDisposedException: "+ex.Message);
- }
- catch (InvalidOperationException ex)
- {
- Tizen.Log.Error("MusicPlayer", "InvalidOperationException: "+ex.Message);
- }
- finally // TODO do we really need this
- {
- //DisposePlayer();
- }
- }
-
- public void Play()
- {
- if (ValidatePlayerState(PlayerValidationState.Start))
- {
- player.Start();
- }
- else
- {
- Tizen.Log.Error(AppConstants.LogTag, "Invalid player state for playing: " + player.State.ToString());
- }
- }
-
- public void Pause()
- {
- if(ValidatePlayerState(PlayerValidationState.Pause))
- {
- player.Pause();
- }
- }
-
- public void Resume()
- {
- if (ValidatePlayerState(PlayerValidationState.Resume))
- {
- player.Start();
- }
- }
-
- public void Stop()
- {
- if(ValidatePlayerState(PlayerValidationState.Stop))
- {
- player.Stop();
- }
- }
-
- public int GetPosition()
- {
- if (ValidatePlayerState(PlayerValidationState.Position))
- {
- return player.GetPlayPosition();
- }
- else
- {
- return 0;
- }
- }
-
- public void Unprepare()
- {
- player.Unprepare();
- }
-
- public void DisposePlayer()
- {
- player.Dispose();
- }
-
- public async Task SetPosition(int pos)
- {
- await player.SetPlayPositionAsync(pos, false);
- }
-
- private bool ValidatePlayerState(PlayerValidationState state)
- {
- if(state == PlayerValidationState.Start || state == PlayerValidationState.Position)
- {
- return (State == PlayerState.Ready || State == PlayerState.Playing || State == PlayerState.Paused);
- }
- else if(state == PlayerValidationState.Pause)
- {
- return (State == PlayerState.Playing);
- }
- else if(state == PlayerValidationState.Resume)
- {
- return (State == PlayerState.Paused);
- }
- else if(state == PlayerValidationState.Stop)
- {
- return (State == PlayerState.Paused || State == PlayerState.Playing);
- }
- else
- {
- return false;
- }
- }
-
- private void OnPlayBackCompleted(object sender, EventArgs e)
- {
- PlayerEvent?.Invoke(this, new PlayerEventArgs(EventType.PlaybackCompleted, "Playback Completed"));
- Tizen.Log.Error(AppConstants.LogTag, "Playback completed");
- }
-
- // TODO this event is called on a differnt thread..need to handle it
- private void OnErrorOccurred(object sender, PlayerErrorOccurredEventArgs e)
- {
- PlayerEvent.Invoke(this, new PlayerEventArgs(EventType.Error, e.Error.ToString()));
- Tizen.Log.Error(AppConstants.LogTag, "Error Occurred: " + e.Error.ToString());
- }
- }
-}
+++ /dev/null
-using System;
-using Tizen.Multimedia;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.Core
-{
- class PlayerController
- {
- private readonly MusicPlayer musicPlayer;
- private static PlayerController instance = instance ??= new PlayerController();
-
- private PlayerController()
- {
- musicPlayer = new MusicPlayer();
- musicPlayer.PlayerEvent += OnPlayerEvent;
- }
-
- public event EventHandler<PlayerEventArgs> PlayerEventOccurred;
-
- public static PlayerController Instance
- {
- get => instance;
- }
-
- private string uri;
-
- public string Uri
- {
- get => uri;
- set => uri = value;
- }
-
- public async void Play()
- {
- if(Uri == null)
- {
- Tizen.Log.Error(AppConstants.LogTag, "Please set the uri to play");
- return;
- }
- Tizen.Log.Error(AppConstants.LogTag, "Current player state: "+musicPlayer.State.ToString());
- if (musicPlayer.State == PlayerState.Paused || musicPlayer.State == PlayerState.Playing)
- {
- musicPlayer.Stop();
- }
- if(musicPlayer.State == PlayerState.Ready)
- {
- musicPlayer.Unprepare();
- }
- musicPlayer.SetSource(Uri);
- if(musicPlayer.State == PlayerState.Idle)
- {
- await musicPlayer.PreparePlayer();
- }
- musicPlayer.Play();
- }
-
- public void Destroy()
- {
- musicPlayer?.DisposePlayer();
- }
-
- public void SetSource()
- {
- musicPlayer.SetSource(Uri);
- }
-
- public void Pause()
- {
- musicPlayer.Pause();
- }
-
- public void Resume()
- {
- if (musicPlayer.State == PlayerState.Paused)
- {
- musicPlayer.Resume();
- }
- else
- {
- Play();
- }
- }
-
- public void Stop()
- {
- musicPlayer.Stop();
- }
-
- public int GetPosition()
- {
- return musicPlayer.GetPosition();
- }
-
- public async void SetPosition(int pos)
- {
- await musicPlayer.SetPosition(pos);
- }
-
- private void OnPlayerEvent(object sender, PlayerEventArgs e)
- {
- PlayerEventOccurred?.Invoke(this, e);
- }
- }
-}
--- /dev/null
+Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd. All rights reserved.
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ 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.
+
+++ /dev/null
-using System;\r
-using System.Collections.Specialized;\r
-using Tizen.Content.MediaContent;\r
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.Media\r
-{\r
- public static partial class Contents\r
- {\r
- public static OrderedDictionary GetAlbumList()\r
- {\r
- OrderedDictionary albumList = new OrderedDictionary();\r
-\r
- SelectArguments albumSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, AlbumColumns.Name + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<Album> dataReader = albumInfo.Select(albumSelectArguments);\r
-\r
- while (dataReader.Read())\r
- {\r
- Album info = dataReader.Current;\r
- SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<MediaInfo> albumDataReader = albumInfo.SelectMember(info.Id, audioSelectArguments);\r
- if (albumDataReader.Read())\r
- albumList.Add(info.Id, info);\r
- }\r
- Tizen.Log.Debug(AppConstants.LogTag, "Total album retrived from database: " + albumList.Count);\r
- dataReader.Dispose();\r
- return albumList;\r
- }\r
-\r
- public static int GetAlbumMemberCount(int albumId)\r
- {\r
- return albumInfo.CountMember(albumId);\r
- }\r
-\r
- public static OrderedDictionary GetAlbumMemberList(int albumId)\r
- {\r
- OrderedDictionary mediaList = new OrderedDictionary();\r
- SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<MediaInfo> dataReader = albumInfo.SelectMember(albumId, audioSelectArguments);\r
-\r
- while (dataReader.Read())\r
- {\r
- MediaInfo info = dataReader.Current;\r
- mediaList.Add(info.Id, info);\r
- }\r
- Tizen.Log.Debug(AppConstants.LogTag, "Total track retrived from currentAlbum: " + mediaList.Count);\r
- dataReader.Dispose();\r
- return mediaList;\r
- }\r
-\r
- public static string GetAlbumArtPath(int albumId)\r
- {\r
- string path = "";\r
- SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<MediaInfo> dataReader = albumInfo.SelectMember(albumId, audioSelectArguments);\r
- while (dataReader.Read())\r
- {\r
- MediaInfo info = dataReader.Current;\r
- if (!string.IsNullOrEmpty(info.ThumbnailPath))\r
- path = info.ThumbnailPath;\r
- }\r
- dataReader.Dispose();\r
- return path;\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System.Collections.Specialized;\r
-using System.Collections.Generic;\r
-using Tizen.Content.MediaContent;\r
-using System;\r
-using MusicPlayer.Common;\r
-\r
-\r
-namespace MusicPlayer.Media\r
-{\r
- public static partial class Contents\r
- {\r
- public static List<string> GetArtistList()\r
- {\r
- List<string> artistList = new List<string>();\r
-\r
- SelectArguments artistSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Artist + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<string> dataReader = mediaInfo.SelectGroupBy(MediaInfoColumnKey.Artist, artistSelectArguments);\r
-\r
- while (dataReader.Read())\r
- {\r
- string info = (string)dataReader.Current;\r
- artistList.Add(info);\r
- }\r
- Tizen.Log.Debug(AppConstants.LogTag, "Total artists retrived from database: " + artistList.Count);\r
- dataReader.Dispose();\r
- return artistList;\r
- }\r
-\r
- public static OrderedDictionary GetAlbumListForArtist(string artistName)\r
- {\r
- OrderedDictionary albumList = new OrderedDictionary();\r
- string expression = MEDIA_STORAGE_TYPE_QUERY + "AND " + AlbumColumns.Artist + "=\"" + artistName + "\"";\r
- SelectArguments albumSelectArguments = CreateSelectArgument(expression, AlbumColumns.Name + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<Album> dataReader = albumInfo.Select(albumSelectArguments);\r
-\r
- while (dataReader.Read())\r
- {\r
- Album info = dataReader.Current;\r
- SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<MediaInfo> albumDataReader = albumInfo.SelectMember(info.Id, audioSelectArguments);\r
- if(albumDataReader.Read())\r
- albumList.Add(info.Id, info);\r
- }\r
- dataReader.Dispose();\r
- Tizen.Log.Debug(AppConstants.LogTag, "Total Albums retrived from Artist: " + albumList.Count);\r
- return albumList;\r
- }\r
-\r
- public static OrderedDictionary GetTrackListForArtist(string artistName)\r
- {\r
- OrderedDictionary mediaList = new OrderedDictionary();\r
- string expression = MEDIA_STORAGE_TYPE_QUERY + "AND " + AlbumColumns.Artist + "=\"" + artistName + "\"";\r
- SelectArguments albumSelectArguments = CreateSelectArgument(expression, AlbumColumns.Name + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<Album> dataReader = albumInfo.Select(albumSelectArguments);\r
-\r
- while (dataReader.Read())\r
- {\r
- Album info = dataReader.Current;\r
- SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<MediaInfo> albumDataReader = albumInfo.SelectMember(info.Id, audioSelectArguments);\r
-\r
- while (albumDataReader.Read())\r
- {\r
- MediaInfo mediaInfo = albumDataReader.Current;\r
- mediaList.Add(mediaInfo.Id, mediaInfo);\r
- }\r
- albumDataReader.Dispose();\r
- }\r
- dataReader.Dispose();\r
- Tizen.Log.Debug(AppConstants.LogTag, "Total track retrived from Artist: " + mediaList.Count);\r
- return mediaList;\r
- }\r
-\r
- public static string GetAlbumArtPathForArtist(string artistName)\r
- {\r
- string expression = MEDIA_STORAGE_TYPE_QUERY + "AND " + AlbumColumns.Artist + "=\"" + artistName + "\"";\r
- SelectArguments albumSelectArguments = CreateSelectArgument(expression, AlbumColumns.Name + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<Album> dataReader = albumInfo.Select(albumSelectArguments);\r
- string albumArtPath = "";\r
-\r
- while (dataReader.Read())\r
- {\r
- Album info = dataReader.Current;\r
- string path = "";\r
- if (!string.IsNullOrEmpty(info.AlbumArtPath))\r
- path = info.AlbumArtPath;\r
- else\r
- path = GetAlbumArtPath(info.Id);\r
- if (!string.IsNullOrEmpty(path))\r
- albumArtPath = path;\r
- }\r
- dataReader.Dispose();\r
- return albumArtPath;\r
- }\r
-\r
- public static int GetAlbumCountForArtist(string artistName)\r
- {\r
- string expression = MEDIA_STORAGE_TYPE_QUERY + "AND " + AlbumColumns.Artist + "=\"" + artistName+"\"";\r
- int count = 0;\r
-\r
- SelectArguments albumSelectArguments = CreateSelectArgument(expression, AlbumColumns.Name + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<Album> dataReader = albumInfo.Select(albumSelectArguments);\r
-\r
- while (dataReader.Read())\r
- {\r
- Album info = dataReader.Current;\r
- SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<MediaInfo> albumDataReader = albumInfo.SelectMember(info.Id, audioSelectArguments);\r
- if (albumDataReader.Read())\r
- count++;\r
- }\r
- dataReader.Dispose();\r
- return count;\r
- }\r
-\r
- public static int GetMediaCountForArtist(string artistName)\r
- {\r
- string expression = MEDIA_STORAGE_TYPE_QUERY + "AND " + MediaInfoColumns.Artist + "=\"" + artistName+"\"";\r
- CountArguments audioCountArguments = CreateCountArgument(expression);\r
- int count = 0;\r
- try\r
- {\r
- count = mediaInfo.CountMedia(audioCountArguments);\r
- }\r
- catch (ObjectDisposedException ex)\r
- {\r
- Tizen.Log.Error(AppConstants.LogTag, "ObjectDisposedException: " + ex.Message);\r
- }\r
- catch (InvalidOperationException ex)\r
- {\r
- Tizen.Log.Error(AppConstants.LogTag, "InvalidOperationException: " + ex.Message);\r
- }\r
- catch (MediaDatabaseException ex)\r
- {\r
- Tizen.Log.Error(AppConstants.LogTag, "MediaDatabaseException: " + ex.Message);\r
- }\r
- catch (Exception ex)\r
- {\r
- Tizen.Log.Error(AppConstants.LogTag, "Unknown Exception: " + ex.Message);\r
- }\r
-\r
- return count;\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System;\r
-using Tizen.Content.MediaContent;\r
-\r
-namespace MusicPlayer.Media\r
-{\r
- public class MusicItemUpdateEventArgs : EventArgs\r
- {\r
- internal MusicItemUpdateEventArgs(int pid,\r
- OperationType operationType, MediaType mediaType, string id, string path, string mimeType)\r
- {\r
- ProcessId = pid;\r
- OperationType = operationType;\r
- Id = id;\r
- Path = path;\r
- MediaType = mediaType;\r
- MimeType = mimeType;\r
- }\r
- public int ProcessId { get; }\r
-\r
- public OperationType OperationType { get; }\r
-\r
- public string Id { get; }\r
-\r
- public string Path { get; }\r
-\r
- public MediaType MediaType { get; }\r
-\r
- public string MimeType { get; }\r
- }\r
-\r
- public class MusicDBUpdateEventArgs : EventArgs\r
- {\r
- internal MusicDBUpdateEventArgs(OperationType operationType, string id, string path)\r
- {\r
- OperationType = operationType;\r
- Id = id;\r
- Path = path;\r
- }\r
-\r
- public OperationType OperationType { get; }\r
-\r
- public string Id { get; }\r
-\r
- public string Path { get; }\r
- }\r
-\r
- public static partial class Contents\r
- {\r
- private static Database database;\r
- private static MediaInfoCommand mediaInfo;\r
- private static AlbumCommand albumInfo;\r
- private static PlaylistCommand playlistInfo;\r
- private const string MEDIA_STORAGE_TYPE_QUERY = " (( MEDIA_STORAGE_TYPE IS NOT 101 ) AND (MEDIA_TYPE = 3)) ";\r
- private const string MEDIA_SORT_ORDER_ASC = " COLLATE NOCASE ASC ";\r
-\r
- public static event EventHandler<MusicItemUpdateEventArgs> MusicItemUpdate;\r
- public static event EventHandler<MusicDBUpdateEventArgs> MusicDBUpdate;\r
-\r
- static Contents()\r
- {\r
- database = new Database();\r
- mediaInfo = new MediaInfoCommand(database.MediaDatabase);\r
- albumInfo = new AlbumCommand(database.MediaDatabase);\r
- playlistInfo = new PlaylistCommand(database.MediaDatabase);\r
- MediaDatabase.MediaInfoUpdated += OnMediaDatabaseItemUpdate;\r
- MediaDatabase.FolderUpdated += OnMediaDatabaseFolderUpdate;\r
- }\r
-\r
- private static void OnMediaDatabaseItemUpdate(object sender, MediaInfoUpdatedEventArgs e)\r
- {\r
- if(e.MediaType == MediaType.Music)\r
- {\r
- MusicItemUpdateEventArgs item = new MusicItemUpdateEventArgs(e.ProcessId, e.OperationType, e.MediaType,\r
- e.Id, e.Path, e.MimeType);\r
- MusicItemUpdate?.Invoke(null, item);\r
- }\r
- }\r
-\r
- private static void OnMediaDatabaseFolderUpdate(object sender, FolderUpdatedEventArgs e)\r
- {\r
- MusicDBUpdateEventArgs item = new MusicDBUpdateEventArgs(e.OperationType, e.Id, e.Path);\r
- MusicDBUpdate?.Invoke(null, item);\r
- }\r
-\r
- private static SelectArguments CreateSelectArgument(string filterExpression, string sortOrder)\r
- {\r
- SelectArguments arguments = new SelectArguments();\r
- arguments.FilterExpression = filterExpression;\r
- arguments.SortOrder = sortOrder;\r
- return arguments;\r
- }\r
-\r
- private static CountArguments CreateCountArgument(string filterExpression)\r
- {\r
- CountArguments arguments = new CountArguments();\r
- arguments.FilterExpression = filterExpression;\r
- return arguments;\r
- }\r
-\r
- public static void Dispose()\r
- {\r
- database.Dispose();\r
- }\r
- }\r
-\r
-}
\ No newline at end of file
+++ /dev/null
-using System;\r
-using Tizen.Content.MediaContent;\r
-\r
-namespace MusicPlayer.Media\r
-{\r
- class Database : IDisposable\r
- {\r
- private MediaDatabase mediaDatabase;\r
-\r
- public Database()\r
- {\r
- mediaDatabase = new MediaDatabase();\r
- mediaDatabase.Connect();\r
- }\r
-\r
- private void TerminateDatabase()\r
- {\r
- mediaDatabase.Disconnect();\r
- mediaDatabase.Dispose();\r
- }\r
-\r
- ~Database()\r
- {\r
- TerminateDatabase();\r
- }\r
-\r
- public void Dispose()\r
- {\r
- TerminateDatabase();\r
- // This will informed gc to not call the finalize method as resources are already released.\r
- GC.SuppressFinalize(this);\r
- }\r
-\r
- public MediaDatabase MediaDatabase\r
- {\r
- get { return mediaDatabase; }\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System.Collections.Generic;\r
-using Tizen.Content.MediaContent;\r
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.Media\r
-{\r
- public static partial class Contents\r
- {\r
- public static List<Playlist> GetPlaylists()\r
- {\r
- List<Playlist> playlists = new List<Playlist>();\r
- SelectArguments arguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, PlaylistColumns.Name + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<Playlist> dataReader = playlistInfo.Select(arguments);\r
-\r
- while(dataReader.Read())\r
- {\r
- Playlist playlist = dataReader.Current;\r
- playlists.Add(playlist);\r
- }\r
- Tizen.Log.Debug(AppConstants.LogTag, "PlayLists Count : " + playlists.Count);\r
- return playlists;\r
- }\r
-\r
- public static Playlist GetPlaylistByName(string name)\r
- {\r
- string filterExpression = MEDIA_STORAGE_TYPE_QUERY + " AND " + PlaylistColumns.Name + "=\"" + name + "\"";\r
- SelectArguments arguments = CreateSelectArgument(filterExpression, PlaylistColumns.Name + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<Playlist> dataReader = playlistInfo.Select(arguments);\r
-\r
- Playlist list = null;\r
- while (dataReader.Read())\r
- {\r
- list = dataReader.Current;\r
- }\r
- return list;\r
- }\r
-\r
- public static Playlist GetPlaylistById(int playlistId)\r
- {\r
- Playlist list = null;\r
- list = playlistInfo.Select(playlistId);\r
- return list;\r
- }\r
-\r
- }\r
-}\r
+++ /dev/null
-using System.Collections.Specialized;\r
-using Tizen.Content.MediaContent;\r
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.Media\r
-{\r
- public static partial class Contents\r
- {\r
- public static OrderedDictionary GetTrackList()\r
- {\r
- OrderedDictionary mediaList = new OrderedDictionary();\r
-\r
- SelectArguments argument = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
- MediaDataReader<MediaInfo> dataReader = mediaInfo.SelectMedia(argument);\r
-\r
- while (dataReader.Read())\r
- {\r
- MediaInfo info = dataReader.Current;\r
- mediaList.Add(info.Id, info);\r
- }\r
- Tizen.Log.Debug(AppConstants.LogTag, "Total track retrived from database: " + mediaList.Count);\r
- dataReader.Dispose();\r
- return mediaList;\r
- }\r
- }\r
-}\r
+++ /dev/null
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.Models\r
-{\r
- class MusicAlbum : PropertyNotifier\r
- {\r
- public MusicAlbum()\r
- {\r
- //this is required for Activator.CreateInstance in ListViewModel\r
- }\r
-\r
- public MusicAlbum(Tizen.Content.MediaContent.Album album)\r
- {\r
- AlbumName = album.Name;\r
- ArtistName = album.Artist;\r
- Id = album.Id;\r
- string text = album.AlbumArtPath;\r
- if (string.IsNullOrEmpty(album.AlbumArtPath))\r
- {\r
- text = AlbumDataProvider.GetAlbumArtFromTracks(album.Id);\r
- }\r
- AlbumArtPath = text;\r
- }\r
-\r
- private string albumName;\r
-\r
- public string AlbumName\r
- {\r
- get => albumName;\r
- set\r
- {\r
- string text = string.IsNullOrEmpty(value) ? "Unknown" : value;\r
- SetProperty(ref albumName, text);\r
- }\r
- }\r
-\r
- private string artistName;\r
-\r
- public string ArtistName\r
- {\r
- get => artistName;\r
- set\r
- {\r
- string text = string.IsNullOrEmpty(value) ? "Unknown" : value;\r
- SetProperty(ref artistName, text);\r
- }\r
- }\r
-\r
- private int id;\r
-\r
- public int Id\r
- {\r
- get => id;\r
- set => id = value;\r
- }\r
-\r
- private string albumArtPath;\r
-\r
- public string AlbumArtPath\r
- {\r
- get => albumArtPath;\r
- set\r
- {\r
- string thumb = string.IsNullOrEmpty(value) ? Resources.GetImagePath() + "thumbnail.png" : value;\r
- SetProperty(ref albumArtPath, thumb);\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System.Collections.Specialized;\r
-using MusicPlayer.Media;\r
-\r
-namespace MusicPlayer.Models\r
-{\r
- public static class AlbumDataProvider\r
- {\r
- private static OrderedDictionary albumsList;\r
-\r
- static AlbumDataProvider()\r
- {\r
- albumsList = Contents.GetAlbumList();\r
- Contents.MusicItemUpdate += OnMusicItemUpdate;\r
- Contents.MusicDBUpdate += OnMusicDatabaseUpdate;\r
- }\r
-\r
- private static void OnMusicDatabaseUpdate(object sender, MusicDBUpdateEventArgs e)\r
- {\r
- albumsList = Contents.GetAlbumList();\r
- // TODO implement database update event handler\r
- return;\r
- }\r
-\r
- private static void OnMusicItemUpdate(object sender, MusicItemUpdateEventArgs e)\r
- {\r
- // TODO implement database item update event handler\r
- return;\r
- }\r
-\r
- public static OrderedDictionary CurrentAlbumList()\r
- {\r
- return albumsList;\r
- }\r
-\r
- public static OrderedDictionary GetAlbumTrackList(int albumId)\r
- {\r
- return Contents.GetAlbumMemberList(albumId);\r
- }\r
-\r
- public static string GetAlbumArtFromTracks(int albumId)\r
- {\r
- return Contents.GetAlbumArtPath(albumId);\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.Models
-{
- class Artist : PropertyNotifier
- {
- public Artist()
- {
- //this is required for Activator.CreateInstance in ListViewModel
- }
-
- public Artist(string artistName)
- {
- ArtistName = artistName;
- AlbumCount = ArtistDataProvider.GetArtistAlbumCount(artistName).ToString();
- TrackCount = ArtistDataProvider.GetArtistTrackCount(artistName).ToString();
- TotalCount = AlbumCount + " / " + TrackCount;
- AlbumArtPath = ArtistDataProvider.GetArtistAlbumArtPath(artistName);
- }
-
- private string artistName;
-
- public string ArtistName
- {
- get => artistName;
- set
- {
- string text = string.IsNullOrEmpty(value) ? "Unknown" : value;
- SetProperty(ref artistName, text);
- }
- }
-
- private string albumCount;
-
- public string AlbumCount
- {
- get => albumCount;
- set
- {
- string text = string.Equals(value, "1") ? " album" : " albums";
- SetProperty(ref albumCount, value + text);
- }
- }
-
- private string trackCount;
-
- public string TrackCount
- {
- get => trackCount;
- set
- {
- string text = string.Equals(value, "1") ? " track" : " tracks";
- SetProperty(ref trackCount, value + text);
- }
- }
-
- private string totalCount;
-
- public string TotalCount
- {
- get => totalCount;
- set => SetProperty(ref totalCount, value);
- }
-
- private string albumArtPath;
-
- public string AlbumArtPath
- {
- get => albumArtPath;
- set
- {
- string thumb = string.IsNullOrEmpty(value) ? Resources.GetImagePath() + "thumbnail.png" : value;
- SetProperty(ref albumArtPath, thumb);
- }
- }
- }
-}
+++ /dev/null
-using System.Collections.Specialized;
-using System.Collections.Generic;
-using MusicPlayer.Media;
-
-namespace MusicPlayer.Models
-{
- public static class ArtistDataProvider
- {
- private static List<string> artistsList;
-
- static ArtistDataProvider()
- {
- artistsList = Contents.GetArtistList();
- Contents.MusicItemUpdate += OnMusicItemUpdate;
- Contents.MusicDBUpdate += OnMusicDatabaseUpdate;
- }
-
- private static void OnMusicDatabaseUpdate(object sender, MusicDBUpdateEventArgs e)
- {
- artistsList = Contents.GetArtistList();
- // TODO implement database update event handler
- return;
- }
-
- private static void OnMusicItemUpdate(object sender, MusicItemUpdateEventArgs e)
- {
- // TODO implement database item update event handler
- return;
- }
-
- public static List<string> CurrentArtistList()
- {
- return artistsList;
- }
-
- public static int GetArtistTrackCount(string artistName)
- {
- return Contents.GetMediaCountForArtist(artistName);
- }
-
- public static int GetArtistAlbumCount(string artistName)
- {
- return Contents.GetAlbumCountForArtist(artistName);
- }
-
- public static string GetArtistAlbumArtPath(string artistName)
- {
- return Contents.GetAlbumArtPathForArtist(artistName);
- }
-
- public static OrderedDictionary GetArtistAlbumList(string artistName)
- {
- return Contents.GetAlbumListForArtist(artistName);
- }
-
- public static OrderedDictionary GetArtistTrackList(string artistName)
- {
- return Contents.GetTrackListForArtist(artistName);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using System;
-using System.Collections.Generic;
-using System.Text;
-using MusicPlayer.Common;
-using System.Collections.ObjectModel;
-
-namespace MusicPlayer.Models
-{
- class ArtistDetailAlbum: ObservableCollection <Track>
- {
- public ArtistDetailAlbum()
- {
- //this is required for Activator.CreateInstance in ListViewModel
- }
-
- public ArtistDetailAlbum(MusicAlbum album)
- {
- AlbumArtPath = album.AlbumArtPath;
- AlbumName = album.AlbumName;
- }
-
- public string AlbumName { get; set; }
-
- public string AlbumArtPath { get; set; }
- }
-}
+++ /dev/null
-using Tizen.Multimedia;
-using System.ComponentModel;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.Models
-{
- class LyricsModel: PropertyNotifier
- {
- public LyricsModel()
- {
- }
-
- public LyricsModel(string thumbPath, string lyrics)
- {
- ThumbPath = thumbPath;
- Lyrics = lyrics;
- }
-
- private string thumbPath;
-
- public string ThumbPath
- {
- get => thumbPath;
- set => SetProperty(ref thumbPath, value);
- }
-
- private string lyrics;
-
- public string Lyrics
- {
- get => lyrics;
- set => SetProperty(ref lyrics, value);
- }
- }
-}
+++ /dev/null
-using MusicPlayer.Common;
-using System;
-
-namespace MusicPlayer.Models
-{
- class PlayerModel : PropertyNotifier
- {
- public PlayerModel()
- {
- }
-
- private Track currentTrack;
-
- public Track CurrentTrack
- {
- get => currentTrack;
- set
- {
- currentTrack = value;
- TrackName = currentTrack.TrackTitle;
- TrackArtist = currentTrack.ArtistName;
- TrackLength = currentTrack.Duration;
- PlayingTime = TimeSpan.FromMilliseconds(0).ToString(AppConstants.TimeFormat);
- ThumbnailPath = currentTrack.ThumbnailPath;
- }
- }
-
- private string trackName;
-
- public string TrackName
- {
- get => trackName;
- set => SetProperty(ref trackName, value);
- }
-
- private string trackArtist;
-
- public string TrackArtist
- {
- get => trackArtist;
- set => SetProperty(ref trackArtist, value);
- }
-
- private string trackLength;
-
- public string TrackLength
- {
- get => trackLength;
- set => SetProperty(ref trackLength, value);
- }
-
- private string thumbnailPath;
-
- public string ThumbnailPath
- {
- get => thumbnailPath;
- set => SetProperty(ref thumbnailPath, value);
- }
-
- private string playingTime;
-
- public string PlayingTime
- {
- get => playingTime;
- set => SetProperty(ref playingTime, value);
- }
-
- private float elapsedTime;
-
- public float ElapsedTime
- {
- get => elapsedTime;
- set => SetProperty(ref elapsedTime, value);
- }
- }
-}
+++ /dev/null
-using System;\r
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.Models\r
-{\r
- class Track : PropertyNotifier\r
- {\r
- public Track()\r
- {\r
- //this is required for Activator.CreateInstance in ListViewModel\r
- }\r
-\r
- public Track(Tizen.Content.MediaContent.AudioInfo audioInfo)\r
- {\r
- TrackTitle = audioInfo.Title;\r
- AlbumName = audioInfo.Album;\r
- Id = audioInfo.Id;\r
- ArtistName = audioInfo.Artist;\r
- DurationInMS = audioInfo.Duration;\r
- Duration = TimeSpan.FromMilliseconds(audioInfo.Duration).ToString(AppConstants.TimeFormat);\r
- ThumbnailPath = audioInfo.ThumbnailPath;\r
- FilePath = audioInfo.Path;\r
- }\r
-\r
- private string trackTitle;\r
-\r
- public string TrackTitle\r
- {\r
- get => trackTitle;\r
- set => SetProperty(ref trackTitle, value);\r
- }\r
-\r
- private string albumName;\r
-\r
- public string AlbumName\r
- {\r
- get => albumName;\r
- set\r
- {\r
- string name = string.IsNullOrEmpty(value) ? "Unknown" : value;\r
- SetProperty(ref albumName, name);\r
- }\r
- }\r
-\r
- private string artistName;\r
-\r
- public string ArtistName\r
- {\r
- get => artistName;\r
- set\r
- {\r
- string name = string.IsNullOrEmpty(value) ? "Unknown" : value;\r
- SetProperty(ref artistName, name);\r
- }\r
- }\r
-\r
- private string id;\r
-\r
- public string Id\r
- {\r
- get => id;\r
- set => id = value;\r
- }\r
-\r
- private string duration;\r
-\r
- public string Duration\r
- {\r
- get => duration;\r
- set => SetProperty(ref duration, value);\r
- }\r
-\r
- private int durationInMS;\r
-\r
- public int DurationInMS\r
- {\r
- get => durationInMS;\r
- set => SetProperty(ref durationInMS, value);\r
- }\r
-\r
- private string thumbnailPath;\r
-\r
- public string ThumbnailPath\r
- {\r
- get => thumbnailPath;\r
- set\r
- {\r
- string thumb = string.IsNullOrEmpty(value) ? Resources.GetImagePath() + "thumbnail.png" : value;\r
- SetProperty(ref thumbnailPath, thumb);\r
- }\r
- }\r
-\r
- private string filePath;\r
-\r
- public string FilePath\r
- {\r
- get => filePath;\r
- set { filePath = value; }\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System.Collections.Specialized;\r
-using MusicPlayer.Media;\r
-\r
-namespace MusicPlayer.Models\r
-{\r
- public static class TrackDataProvider\r
- {\r
- private static OrderedDictionary tracksList;\r
-\r
- static TrackDataProvider()\r
- {\r
- tracksList = Contents.GetTrackList();\r
- Contents.MusicItemUpdate += OnMusicItemUpdate;\r
- Contents.MusicDBUpdate += OnMusicDatabaseUpdate;\r
- }\r
-\r
- private static void OnMusicDatabaseUpdate(object sender, MusicDBUpdateEventArgs e)\r
- {\r
- tracksList = Contents.GetTrackList();\r
- // TODO implement database update event handler\r
- return;\r
- }\r
-\r
- private static void OnMusicItemUpdate(object sender, MusicItemUpdateEventArgs e)\r
- {\r
- // TODO implement database item update event handler\r
- return;\r
- }\r
-\r
- public static OrderedDictionary CurrentTrackList()\r
- {\r
- return tracksList;\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System;
-using Tizen.NUI;
-using MusicPlayer.Views;
-using MusicPlayer.Common;
-
-namespace MusicPlayer
-{
- public class Application : NUIApplication
- {
- public Application() : base(ThemeOptions.PlatformThemeEnabled)
- {
-
- }
- protected override void OnCreate()
- {
- 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(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 == AppConstants.BackKeyCode || e.Key.KeyPressedName == AppConstants.EscapeKeyCode))
- {
- Exit();
- }
- }
-
- static void Main(string[] args)
- {
- Tizen.Log.Info(AppConstants.LogTag, "Main statrted");
- var app = new Application();
- app.Run(args);
- Tizen.Log.Info(AppConstants.LogTag, "Main finished");
- }
- }
-}
+++ /dev/null
-\r
-Microsoft Visual Studio Solution File, Format Version 12.00\r
-# Visual Studio Version 16\r
-VisualStudioVersion = 16.0.30804.86\r
-MinimumVisualStudioVersion = 10.0.40219.1\r
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "music-player", "music-player.csproj", "{18A58E69-495D-4F9C-BA77-C969BE9D8104}"\r
-EndProject\r
-Global\r
- GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
- Debug|Any CPU = Debug|Any CPU\r
- Release|Any CPU = Release|Any CPU\r
- EndGlobalSection\r
- GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
- {18A58E69-495D-4F9C-BA77-C969BE9D8104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
- {18A58E69-495D-4F9C-BA77-C969BE9D8104}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
- {18A58E69-495D-4F9C-BA77-C969BE9D8104}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
- {18A58E69-495D-4F9C-BA77-C969BE9D8104}.Release|Any CPU.Build.0 = Release|Any CPU\r
- EndGlobalSection\r
- GlobalSection(SolutionProperties) = preSolution\r
- HideSolutionNode = FALSE\r
- EndGlobalSection\r
- GlobalSection(ExtensibilityGlobals) = postSolution\r
- SolutionGuid = {7072B878-F218-47CE-84F8-FC9AC39798C6}\r
- EndGlobalSection\r
-EndGlobal\r
+++ /dev/null
-using System.Collections.Specialized;\r
-using MusicPlayer.Models;\r
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.ViewModels\r
-{\r
- using AudioInfo = Tizen.Content.MediaContent.AudioInfo;\r
- class AlbumDetailViewModel : PropertyNotifier\r
- {\r
- public AlbumDetailViewModel(MusicAlbum album)\r
- {\r
- Id = album.Id;\r
- AlbumName = album.AlbumName;\r
- ArtistName = album.ArtistName;\r
- AlbumArtPath = album.AlbumArtPath;\r
- OrderedDictionary trackList = AlbumDataProvider.GetAlbumTrackList(album.Id);\r
- listViewModel = new ListViewModel<Track>();\r
- listViewModel.CreateData<AudioInfo>(trackList);\r
- listViewModel.CollectionChanged += OnAlbumDetailListChanges;\r
- TotalTracks = listViewModel.Count.ToString();\r
- }\r
-\r
- private void OnAlbumDetailListChanges(object sender, NotifyCollectionChangedEventArgs e)\r
- {\r
- //TODO\r
- TotalTracks = listViewModel.Count.ToString();\r
- }\r
-\r
- private int id;\r
-\r
- public int Id\r
- {\r
- get => id;\r
- set => id = value;\r
- }\r
-\r
- private string albumName;\r
-\r
- public string AlbumName\r
- {\r
- get => albumName;\r
- set\r
- {\r
- string text = string.Equals(value,"Unknown") ? null : value;\r
- SetProperty(ref albumName, text);\r
- }\r
- }\r
-\r
- private string artistName;\r
-\r
- public string ArtistName\r
- {\r
- get => artistName;\r
- set\r
- {\r
- string text = string.Equals(value, "Unknown") ? null : value;\r
- SetProperty(ref artistName, text);\r
- }\r
- }\r
-\r
- private string albumArtPath;\r
-\r
- public string AlbumArtPath\r
- {\r
- get => albumArtPath;\r
- set => SetProperty(ref albumArtPath, value);\r
- }\r
-\r
- private ListViewModel<Track> listViewModel;\r
-\r
- public ListViewModel<Track> ListViewModel\r
- {\r
- get => listViewModel;\r
- }\r
-\r
- private string totalTracks;\r
-\r
- public string TotalTracks\r
- {\r
- get => totalTracks;\r
- set\r
- {\r
- string text = string.Equals(value, "1") ? " Track" : " Tracks";\r
- SetProperty(ref totalTracks, value + text);\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System.Collections.Specialized;\r
-using MusicPlayer.Models;\r
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.ViewModels\r
-{\r
- using Album = Tizen.Content.MediaContent.Album;\r
- class AlbumViewModel : PropertyNotifier\r
- {\r
- private AlbumDetailViewModel albumDetailViewModel;\r
-\r
- public AlbumViewModel()\r
- {\r
- OrderedDictionary albumList = AlbumDataProvider.CurrentAlbumList();\r
- listViewModel = new ListViewModel<MusicAlbum>();\r
- listViewModel.CreateData<Album>(albumList);\r
- listViewModel.CollectionChanged += OnAlbumListChanges;\r
- AlbumCount = listViewModel.Count.ToString();\r
- }\r
-\r
- private void OnAlbumListChanges(object sender, NotifyCollectionChangedEventArgs e)\r
- {\r
- AlbumCount = listViewModel.Count.ToString();\r
- }\r
-\r
- public AlbumDetailViewModel getDetailViewModel(MusicAlbum musicAlbum)\r
- {\r
- if(albumDetailViewModel == null)\r
- albumDetailViewModel = new AlbumDetailViewModel(musicAlbum);\r
- else if (albumDetailViewModel.Id != musicAlbum.Id)\r
- albumDetailViewModel = new AlbumDetailViewModel(musicAlbum);\r
- return albumDetailViewModel;\r
- }\r
-\r
- private ListViewModel<MusicAlbum> listViewModel;\r
-\r
- public ListViewModel<MusicAlbum> ListViewModel\r
- {\r
- get => listViewModel;\r
- }\r
-\r
- private string albumCount;\r
-\r
- public string AlbumCount\r
- {\r
- get => albumCount;\r
- set\r
- {\r
- string text = string.Equals(value, "1") ? " album" : " albums";\r
- SetProperty(ref albumCount, value + text);\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System.Collections.Specialized;
-using MusicPlayer.Models;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.ViewModels
-{
- using Album = Tizen.Content.MediaContent.Album;
- using AudioInfo = Tizen.Content.MediaContent.AudioInfo;
- class ArtistDetailViewModel : PropertyNotifier
- {
-
- public ArtistDetailViewModel(Artist artist)
- {
- ArtistName = artist.ArtistName;
- TotalCount = artist.TotalCount;
- string text = string.Equals(ArtistName, "Unknown") ? "" : ArtistName;
-
- OrderedDictionary albumList = ArtistDataProvider.GetArtistAlbumList(text);
- albumListViewModel = new ListViewModel<MusicAlbum>();
- albumListViewModel.CreateData<Album>(albumList);
-
- OrderedDictionary trackList = ArtistDataProvider.GetArtistTrackList(text);
- trackListViewModel = new ListViewModel<Track>();
- trackListViewModel.CreateData<AudioInfo>(trackList);
-
- groupListViewModel = new ListViewModel<ArtistDetailAlbum>();
-
- foreach(MusicAlbum album in albumListViewModel)
- {
- ArtistDetailAlbum artistAlbum = new ArtistDetailAlbum(album);
- OrderedDictionary albumTrackList = AlbumDataProvider.GetAlbumTrackList(album.Id);
- ListViewModel<Track> albumTrackListViewModel = new ListViewModel<Track>();
- albumTrackListViewModel.CreateData<AudioInfo>(albumTrackList);
- foreach (Track track in albumTrackListViewModel)
- artistAlbum.Add(track);
- groupListViewModel.Add(artistAlbum);
- }
- }
-
- private string artistName;
-
- public string ArtistName
- {
- get => artistName;
- set => SetProperty(ref artistName, value);
- }
-
- private string totalCount;
-
- public string TotalCount
- {
- get => totalCount;
- set => SetProperty(ref totalCount, value);
- }
-
- private readonly ListViewModel<ArtistDetailAlbum> groupListViewModel;
- public ListViewModel<ArtistDetailAlbum> GroupListViewModel => groupListViewModel;
-
- private readonly ListViewModel<MusicAlbum> albumListViewModel;
- public ListViewModel<MusicAlbum> AlbumListViewModel => albumListViewModel;
-
- private readonly ListViewModel<Track> trackListViewModel;
- public ListViewModel<Track> TrackListViewModel => trackListViewModel;
- }
-}
+++ /dev/null
-using System.Collections.Specialized;
-using System.Collections.Generic;
-using MusicPlayer.Models;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.ViewModels
-{
- class ArtistViewModel : PropertyNotifier
- {
- private ArtistDetailViewModel artistDetailViewModel;
-
- public ArtistViewModel()
- {
- List<string> artistList = ArtistDataProvider.CurrentArtistList();
- listViewModel = new ListViewModel<Artist>();
- listViewModel.CreateData<string>(artistList);
- listViewModel.CollectionChanged += OnArtistListChanges;
- ArtistCount = listViewModel.Count.ToString();
- }
-
- private void OnArtistListChanges(object sender, NotifyCollectionChangedEventArgs e)
- {
- artistCount = listViewModel.Count.ToString();
- }
-
- public ArtistDetailViewModel getDetailViewModel(Artist artist)
- {
- if (artistDetailViewModel == null)
- artistDetailViewModel = new ArtistDetailViewModel(artist);
- else if (artistDetailViewModel.ArtistName != artist.ArtistName)
- artistDetailViewModel = new ArtistDetailViewModel(artist);
- return artistDetailViewModel;
- }
-
- private ListViewModel<Artist> listViewModel;
-
- public ListViewModel<Artist> ListViewModel
- {
- get => listViewModel;
- }
-
- private string artistCount;
-
- public string ArtistCount
- {
- get => artistCount;
- set
- {
- string text = string.Equals(value, "1") ? " artist" : " artists";
- SetProperty(ref artistCount, value + text);
- }
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using System.Collections;\r
-using System.Collections.Specialized;\r
-using System.Collections.ObjectModel;\r
-using MusicPlayer.Models;\r
-using Tizen.Content.MediaContent;\r
-using MusicPlayer.Common;\r
-using System;\r
-using System.Collections.Generic;\r
-\r
-namespace MusicPlayer.ViewModels\r
-{\r
- class ListViewModel<T> : ObservableCollection<T> where T : new()\r
- {\r
- public ListViewModel()\r
- {\r
- }\r
-\r
- public void CreateData<U>(OrderedDictionary dict)\r
- {\r
- foreach (DictionaryEntry item in dict)\r
- {\r
- Add((T)Activator.CreateInstance(typeof(T), new object[] { (U)item.Value }));\r
- }\r
- Tizen.Log.Debug(AppConstants.LogTag, "Observable list item count: " + this.Count);\r
- }\r
-\r
- public void CreateData<U>(List<U> list)\r
- {\r
- foreach (var item in list)\r
- {\r
- Add((T)Activator.CreateInstance(typeof(T), new object[] { (U)item }));\r
- }\r
- Tizen.Log.Debug(AppConstants.LogTag, "Observable list item count: " + this.Count);\r
- }\r
-\r
-\r
- }\r
-}\r
+++ /dev/null
-using Tizen.Multimedia;
-using MusicPlayer.Models;
-using MusicPlayer.Common;
-using Tizen.NUI;
-
-namespace MusicPlayer.ViewModels
-{
- class LyricsViewModel : PropertyNotifier
- {
- internal LyricsModel lyricsModel;
-
- public LyricsViewModel()
- {
- lyricsModel = new LyricsModel();
- }
-
- public LyricsViewModel(Track currentTrack)
- {
- FilePath = currentTrack.FilePath;
- lyricsModel = new LyricsModel(currentTrack.ThumbnailPath, GetLyrics(FilePath));
- }
-
- public string FilePath { get; set; }
-
- private Track currentTrack;
-
- public Track CurrentTrack
- {
- get => currentTrack;
- set
- {
- currentTrack = value;
- FilePath = currentTrack.FilePath;
- lyricsModel.ThumbPath = currentTrack.ThumbnailPath;
- lyricsModel.Lyrics = GetLyrics(FilePath);
- }
- }
-
- private Color lyricsBackgroundColor;
-
- public Color LyricsBackgroundColor
- {
- get => lyricsBackgroundColor;
- set => SetProperty(ref lyricsBackgroundColor, value);
- }
-
- private string GetLyrics(string path)
- {
- var metadataExtractor = new MetadataExtractor(path);
- Metadata metadata = metadataExtractor.GetMetadata();
- string lyrics = metadata.UnsyncLyrics;
- if(string.IsNullOrEmpty(lyrics))
- {
- LyricsBackgroundColor = Color.Transparent;
- return string.Empty;
- }
- else
- {
- LyricsBackgroundColor = UIColors.LyricsBackground;
- return lyrics;
- }
- }
- }
-}
+++ /dev/null
-using System;
-using System.Collections.Generic;
-using System.Text;
-using MusicPlayer.Models;
-using MusicPlayer.Common;
-using MusicPlayer.Core;
-using Tizen.NUI;
-using Tizen.Multimedia;
-using System.Threading.Tasks;
-
-namespace MusicPlayer.ViewModels
-{
- class PlayerViewModel : PropertyNotifier
- {
- public const string PlayState = "Play";
- public const string PauseState = "Pause";
- private const int PlaybackTimerDuration = 1000;
- private const int MinPaletteColorCount = 2;
-
- internal PlayerModel playerModel;
- internal LyricsViewModel lyricsViewModel;
- private Timer playbackTimer;
- private bool isVolumeChanging;
-
- public PlayerViewModel()
- {
- lyricsViewModel = new LyricsViewModel();
- playingListViewModel = new PlayingListViewModel();
- playerModel = new PlayerModel();
- playerModel.ElapsedTime = 0.0f;
- PlayingStatus = PlayingStatus.None;
- PlayerController.Instance.PlayerEventOccurred += OnPlayerEventOccurred;
- playbackTimer = new Timer(PlaybackTimerDuration);
- playbackTimer.Tick += OnPlaybackTimerTick;
- isVolumeChanging = false;
- VolumeLevel = AudioManager.VolumeController.Level[AudioVolumeType.Media];
- AudioManager.VolumeController.Changed += OnVolumeLevelChanged;
- HasPreviousTrack = playingListViewModel.HasPrev();
- HasNextTrack = playingListViewModel.HasNext();
- }
-
- internal PlayingListViewModel playingListViewModel;
-
- public PlayingListViewModel CurrentPlayingListViewModel
- {
- get => playingListViewModel;
- }
-
- private string playButtonState;
-
- public string PlayButtonState
- {
- get => playButtonState;
- set => SetProperty(ref playButtonState, value);
- }
-
- private float volumeLevel;
-
- public float VolumeLevel
- {
- get => volumeLevel;
- set => SetProperty(ref volumeLevel, value);
- }
-
- private bool hasPreviousTrack;
-
- public bool HasPreviousTrack
- {
- get => hasPreviousTrack;
- set => SetProperty(ref hasPreviousTrack, value);
- }
-
- private bool hasNextTrack;
-
- public bool HasNextTrack
- {
- get => hasNextTrack;
- set => SetProperty(ref hasNextTrack, value);
- }
-
- private PropertyMap playerBackground;
-
- public PropertyMap PlayerBackground
- {
- get => playerBackground;
- set => SetProperty(ref playerBackground, value);
- }
-
- private PlayingStatus playingStatus;
-
- public PlayingStatus PlayingStatus
- {
- get => playingStatus;
- set => UpdatePlayingStatus(value);
- }
-
- public void SetPlayingList(ListViewModel<Track> trackListVM)
- {
- playingListViewModel.SetTrackListViewModel(trackListVM);
- }
-
- public void SetCurrentTrack(Track track)
- {
- Tizen.Log.Info(AppConstants.LogTag, "Setting Current track");
- playerModel.CurrentTrack = track;
- lyricsViewModel.CurrentTrack = track;
- //TO DO need to set index properly
- Track current = playingListViewModel.Current();
- if (current == null)
- {
- Tizen.Log.Error(AppConstants.LogTag, "Current track is null so setting new track");
- playingListViewModel.SetPlayingTrack(track);
- }
- // updating prev/next button state
- HasPreviousTrack = playingListViewModel.HasPrev();
- HasNextTrack = playingListViewModel.HasNext();
-
- // SetBackground
- SetExtractedBackground(track.ThumbnailPath);
-
- PlayerController.Instance.Uri = track.FilePath;
- StartPlayback();
- }
-
- public void NextButtonClicked()
- {
- Track nextTrack = playingListViewModel.Next();
- if (nextTrack == null)
- {
- Tizen.Log.Error(AppConstants.LogTag, "nextTrack is null");
- StopPlayback();
- return;
- }
- Tizen.Log.Debug(AppConstants.LogTag, "Next track is: " + nextTrack.TrackTitle);
- SetCurrentTrack(nextTrack);
- }
-
- public void PrevButtonClicked()
- {
- Track previousTrack = playingListViewModel.Prev();
- if (previousTrack == null)
- {
- Tizen.Log.Error(AppConstants.LogTag, "previousTrack is null");
- StopPlayback();
- return;
- }
- Tizen.Log.Debug(AppConstants.LogTag, "Prev track is: " + previousTrack.TrackTitle);
- SetCurrentTrack(previousTrack);
- }
-
- 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[] repeatArr = (RepeatMode[])values;
- RepeatMode new_mode;
- if (i + 1 >= values.Length)
- {
- new_mode = repeatArr[0];
- }
- else
- {
- new_mode = repeatArr[i + 1];
- }
- playingListViewModel.RepeatMode = new_mode;
- }
-
- public void PlayingStatusChanged()
- {
- if (PlayingStatus == PlayingStatus.Playing)
- {
- PlayingStatus = PlayingStatus.Paused;
- Pause();
- playbackTimer.Stop();
- }
- else
- {
- PlayingStatus = PlayingStatus.Playing;
- Resume();
- playbackTimer.Start();
- }
- }
-
- public void UpdatePlayerPosition(float value)
- {
- int currentPosition = (int)(playerModel.CurrentTrack.DurationInMS * value);
- PlayerController.Instance.SetPosition(currentPosition);
- playerModel.PlayingTime = TimeSpan.FromMilliseconds(currentPosition).ToString(AppConstants.TimeFormat);
- playbackTimer.Start();
- }
-
- public void StopPlaybackTimer()
- {
- playbackTimer.Stop();
- }
-
- public void SetElapsedTime(float value)
- {
- int currentPosition = (int)(playerModel.CurrentTrack.DurationInMS * value);
- playerModel.PlayingTime = TimeSpan.FromMilliseconds(currentPosition).ToString(AppConstants.TimeFormat);
- }
-
- public void VolumeChangeStarted()
- {
- isVolumeChanging = true;
- }
-
- public void VolumeChangeFinished(int value)
- {
- VolumeLevelChanged(value);
- isVolumeChanging = false;
- }
- public void VolumeLevelChanged(int value)
- {
- AudioManager.VolumeController.Level[AudioVolumeType.Media] = value;
- }
-
- private void UpdatePlayingStatus(PlayingStatus status)
- {
- playingStatus = status;
- switch (status)
- {
- case PlayingStatus.Playing:
- PlayButtonState = PauseState;
- break;
- case PlayingStatus.Paused: // Fall Through
- case PlayingStatus.Stopped: // Fall Through
- case PlayingStatus.None:
- PlayButtonState = PlayState;
- break;
- }
- }
-
- private bool OnPlaybackTimerTick(object source, Timer.TickEventArgs e)
- {
- UpdatePlayingTime();
- return true;
- }
-
- private void OnPlayerEventOccurred(object sender, PlayerEventArgs e)
- {
- Tizen.Log.Error(AppConstants.LogTag, "Player Event Occurred:");
- Tizen.Log.Error(AppConstants.LogTag, "\t"+e.Type.ToString());
- Tizen.Log.Error(AppConstants.LogTag, "\t:"+e.Description);
- if(e.Type == EventType.PlaybackCompleted)
- {
- PlayNext();
- }
- }
-
- private void PlayNext()
- {
- if(playingListViewModel.RepeatMode == RepeatMode.Off)
- {
- Tizen.Log.Debug(AppConstants.LogTag, "Repeat is off, can't play next");
- StopPlayback();
- UpdatePlayingTime();
- return;
- }
- NextButtonClicked();
- }
-
- private void UpdatePlayingTime()
- {
- int position = PlayerController.Instance.GetPosition();
- playerModel.ElapsedTime = position / (float)playerModel.CurrentTrack.DurationInMS;
- playerModel.PlayingTime = TimeSpan.FromMilliseconds(position).ToString(AppConstants.TimeFormat);
- }
-
- private void StartPlayback()
- {
- PlayingStatus = PlayingStatus.Playing;
- Play();
- playbackTimer.Start();
- }
-
- private void StopPlayback()
- {
- PlayingStatus = PlayingStatus.Stopped;
- Stop();
- playbackTimer.Stop();
- }
-
- private void Play()
- {
- PlayerController.Instance.Play();
- }
- private void Pause()
- {
- PlayerController.Instance.Pause();
- }
- private void Resume()
- {
- PlayerController.Instance.Resume();
- }
- private void Stop()
- {
- PlayerController.Instance.Stop();
- }
-
- private void OnVolumeLevelChanged(object sender, VolumeChangedEventArgs e)
- {
- if(e.Type == AudioVolumeType.Media && isVolumeChanging == false)
- {
- VolumeLevel = e.Level;
- }
- }
-
- private ImageVisual CreateImageVisual()
- {
- ImageVisual visual = new ImageVisual()
- {
- URL = Resources.GetImagePath() + "gradient_music_light.png",
- };
- return visual;
- }
-
- private GradientVisual CreateGradientVisual(PropertyArray stopColor)
- {
- GradientVisual gradientVisual = new GradientVisual()
- {
- StartPosition = new Vector2(0.0f, -1.0f),
- EndPosition = new Vector2(0.0f, 1.0f),
- StopColor = stopColor,
- SpreadMethod = GradientVisualSpreadMethodType.Pad,
- };
- return gradientVisual;
- }
-
- private PropertyArray GetGradientStopColors(Palette palette)
- {
- PropertyArray propertyArray = new PropertyArray();
- if(palette == null)
- {
- Tizen.Log.Error(AppConstants.LogTag, "Color palatte from background is null");
- return propertyArray;
- }
-
- Palette.Swatch lightMutedSwatch = palette.GetLightMutedSwatch();
- Palette.Swatch darkMutedSwatch = palette.GetDarkMutedSwatch();
- if(lightMutedSwatch != null && darkMutedSwatch != null)
- {
- propertyArray.PushBack(new PropertyValue(lightMutedSwatch.GetRgb()));
- propertyArray.PushBack(new PropertyValue(darkMutedSwatch.GetRgb()));
- return propertyArray;
- }
-
- Palette.Swatch lightVibrantSwatch = palette.GetLightVibrantSwatch();
- Palette.Swatch darkVibrantSwatch = palette.GetDarkVibrantSwatch();
- if(lightVibrantSwatch != null && darkVibrantSwatch != null)
- {
- propertyArray.PushBack(new PropertyValue(lightVibrantSwatch.GetRgb()));
- propertyArray.PushBack(new PropertyValue(darkVibrantSwatch.GetRgb()));
- return propertyArray;
- }
-
- Palette.Swatch mutedSwatch = palette.GetMutedSwatch();
- Palette.Swatch vibrantSwatch = palette.GetVibrantSwatch();
- if(mutedSwatch != null && vibrantSwatch != null)
- {
- propertyArray.PushBack(new PropertyValue(mutedSwatch.GetRgb()));
- propertyArray.PushBack(new PropertyValue(vibrantSwatch.GetRgb()));
- return propertyArray;
- }
-
- IReadOnlyCollection<Palette.Swatch> swatches = palette.GetSwatches();
- foreach(Palette.Swatch swatch in swatches)
- {
- if(propertyArray.Count() >= MinPaletteColorCount)
- {
- return propertyArray;
- }
- if(swatch != null)
- {
- propertyArray.PushBack(new PropertyValue(swatch.GetRgb()));
- }
- }
- return propertyArray;
- }
-
- private async void SetExtractedBackground(string path)
- {
- Tizen.Log.Debug(AppConstants.LogTag, "Path for the color image thumbnail" + path);
- Palette palette = await ColorExtractor.GetPaletteAsync(path);
- PropertyArray stopColor = GetGradientStopColors(palette);
- if (stopColor.Count() < MinPaletteColorCount)
- {
- Tizen.Log.Info(AppConstants.LogTag, "Palette or palatte values not valid, adding default gradient");
- ImageVisual imageVisual = CreateImageVisual();
- PlayerBackground = imageVisual.OutputVisualMap;
- return;
- }
- else
- {
- Tizen.Log.Info(AppConstants.LogTag, "setting palette color");
- GradientVisual gradientVisual = CreateGradientVisual(stopColor);
- PlayerBackground = gradientVisual.OutputVisualMap;
- }
- }
- }
-}
+++ /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;
-using MusicPlayer.Models;
-
-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 ListViewModel<Track> 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(ListViewModel<Track> 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 = -1;
- RepeatMode = RepeatMode.Off;
- ShuffleMode = ShuffleMode.Off;
- OnItemsSourceChanged(new EventArgs());
- }
-
- public ListViewModel<Track> TrackListVM
- {
- get => tracklistViewModel;
- }
-
- public string ShuffleButtonState
- {
- 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);
- }
- }
- ShuffleButtonState = shuffleMode.ToString();
- }
- }
-
- public string RepeatButtonState
- {
- get => repeatButtonUrl;
- set => SetProperty(ref repeatButtonUrl, value);
- }
-
- public RepeatMode RepeatMode
- {
- get => repeatMode;
- set
- {
- repeatMode = value;
- RepeatButtonState = repeatMode.ToString();
- }
- }
-
- public Track Next()
- {
- if(currentIndex < 0 )
- {
- Tizen.Log.Error(AppConstants.LogTag,"Invalid track index");
- return null;
- }
- if(RepeatMode == RepeatMode.RepeatOne)
- {
- return tracklistViewModel[shuffleList[currentIndex]];
- }
- else if(RepeatMode == RepeatMode.Off)
- {
- if (currentIndex + 1 >= shuffleList.Count)
- {
- return null;
- }
- else
- {
- currentIndex += 1;
- return tracklistViewModel[shuffleList[currentIndex]];
- }
- }
- else
- {
- if (currentIndex + 1 >= shuffleList.Count)
- {
- currentIndex = 0;
- return tracklistViewModel[shuffleList[currentIndex]];
- }
- else
- {
- currentIndex += 1;
- return tracklistViewModel[shuffleList[currentIndex]];
- }
- }
- }
-
- public Track Prev()
- {
- if (currentIndex < 0)
- {
- Tizen.Log.Error(AppConstants.LogTag, "Invalid track index");
- return null;
- }
- if (RepeatMode == RepeatMode.RepeatOne)
- {
- return tracklistViewModel[shuffleList[currentIndex]];
- }
- else if (RepeatMode == RepeatMode.Off)
- {
- if (currentIndex - 1 < 0)
- {
- return null;
- }
- else
- {
- currentIndex -= 1;
- return tracklistViewModel[shuffleList[currentIndex]];
- }
- }
- else
- {
- if (currentIndex - 1 < 0)
- {
- currentIndex = shuffleList.Count-1;
- return tracklistViewModel[shuffleList[currentIndex]];
- }
- else
- {
- currentIndex -= 1;
- return tracklistViewModel[shuffleList[currentIndex]];
- }
- }
- }
-
- public bool HasNext()
- {
- if (IsTrackIndexInvalid())
- {
- return false;
- }
- if(RepeatMode == RepeatMode.RepeatOne || RepeatMode == RepeatMode.RepeatAll)
- {
- return true;
- }
- else
- {
- return currentIndex + 1 < shuffleList.Count ? true : false;
- }
- }
-
- public bool HasPrev()
- {
- if (IsTrackIndexInvalid())
- {
- return false;
- }
- if (RepeatMode == RepeatMode.RepeatOne || RepeatMode == RepeatMode.RepeatAll)
- {
- return true;
- }
- else
- {
- return currentIndex - 1 >= 0 ? true : false;
- }
- }
-
- public Track Current()
- {
- if (IsTrackIndexInvalid())
- {
- return null;
- }
- else
- {
- return tracklistViewModel[shuffleList[currentIndex]];
- }
- }
-
- public void SetPlayingTrack(string mediaId)
- {
- int count;
- for (count = 0; count< tracklistViewModel.Count; ++count)
- {
- if (mediaId == tracklistViewModel[count].Id)
- {
- currentIndex = count;
- return;
- }
- }
- currentIndex = -1;
- }
-
- public void SetPlayingTrack(Track track)
- {
- int count;
- for (count = 0; count < tracklistViewModel.Count; ++count)
- {
- if (track == tracklistViewModel[count])
- {
- Tizen.Log.Debug(AppConstants.LogTag, "Current track index is " + count);
- currentIndex = count;
- return;
- }
- }
- currentIndex = -1;
- }
-
- private bool IsTrackIndexInvalid()
- {
- if(currentIndex < 0 || currentIndex > shuffleList.Count)
- {
- return true;
- }
- return false;
- }
- }
-}
+++ /dev/null
-using System.Collections.Specialized;\r
-using MusicPlayer.Models;\r
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.ViewModels\r
-{\r
- using AudioInfo = Tizen.Content.MediaContent.AudioInfo;\r
- class TrackViewModel : PropertyNotifier\r
- {\r
- public TrackViewModel()\r
- {\r
- OrderedDictionary trackList = TrackDataProvider.CurrentTrackList();\r
- listViewModel = new ListViewModel<Track>();\r
- listViewModel.CreateData<AudioInfo>(trackList);\r
- listViewModel.CollectionChanged += OnTrackListChanges;\r
- TrackCount = listViewModel.Count.ToString();\r
- }\r
-\r
- private void OnTrackListChanges(object sender, NotifyCollectionChangedEventArgs e)\r
- {\r
- TrackCount = listViewModel.Count.ToString();\r
- }\r
-\r
- private ListViewModel<Track> listViewModel;\r
-\r
- public ListViewModel<Track> ListViewModel\r
- {\r
- get => listViewModel;\r
- }\r
-\r
- private string trackCount;\r
-\r
- public string TrackCount\r
- {\r
- get => trackCount;\r
- set\r
- {\r
- string text = string.Equals(value, "1") ? " track" : " tracks";\r
- SetProperty(ref trackCount, value + text);\r
- }\r
- }\r
- }\r
-}\r
+++ /dev/null
-using Tizen.NUI.Components;\r
-using Tizen.NUI.BaseComponents;\r
-using Tizen.NUI;\r
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.Views\r
-{\r
- class AlbumDetailLayout : RecyclerViewItem\r
- {\r
- private View itemSeperator;\r
- private TextLabel titleLabel;\r
- private TextLabel subtitleLabel;\r
- private TextLabel additionalLabel;\r
-\r
- private const int LayoutMargin = 16;\r
- private const int LayoutPadding = 32;\r
- private const int SeperatorHeight = 1;\r
- private const int LeftPadding = 64;\r
- private const int X = 0;\r
-\r
- public AlbumDetailLayout(int width = 832, int height = 108) : base()\r
- {\r
- base.OnInitialize();\r
- base.IsCreateByXaml = true;\r
- WidthSpecification = width;\r
- HeightSpecification = height;\r
-\r
- // to show the rounded rect of the bg\r
- BackgroundColor = Color.Transparent;\r
-\r
- titleLabel = CreateTitleLabel();\r
- subtitleLabel = CreateSubTitleLabel();\r
- additionalLabel = CreateAdditionalLabel(width);\r
- itemSeperator = CreateItemSeparator(width, height);\r
- IsCreateByXaml = true;\r
- }\r
-\r
- private TextLabel CreateTitleLabel()\r
- {\r
- TextLabel titleLabel = new TextLabel()\r
- {\r
- Size2D = new Size2D(596, 40),\r
- TextColor = UIColors.HEX001447,\r
- PixelSize = 32,\r
- FontFamily = "BreezeSans",\r
- VerticalAlignment = VerticalAlignment.Center,\r
- Padding=new Extents(LayoutPadding,0,0,0),\r
- IsCreateByXaml = true,\r
- Position2D = new Position2D(X , LayoutMargin),\r
- };\r
- base.Add(titleLabel);\r
- return titleLabel;\r
- }\r
-\r
- private TextLabel CreateSubTitleLabel()\r
- {\r
- TextLabel subtitleLabel = new TextLabel()\r
- {\r
- Size2D= new Size2D(596,36),\r
- TextColor = UIColors.HEX001447,\r
- PixelSize = 28,\r
- FontFamily = "BreezeSans",\r
- VerticalAlignment = VerticalAlignment.Center,\r
- Padding = new Extents(LayoutPadding, 0, 0, 0),\r
- IsCreateByXaml = true,\r
- Position2D = new Position2D(X , LayoutMargin + 40)\r
- };\r
- base.Add(subtitleLabel);\r
- return subtitleLabel;\r
- }\r
-\r
- private TextLabel CreateAdditionalLabel(int width)\r
- {\r
- TextLabel additionalLabel = new TextLabel()\r
- {\r
- Size2D= new Size2D(108,36),\r
- TextColor = UIColors.HEX001447,\r
- PixelSize = 28,\r
- FontFamily = "BreezeSans",\r
- VerticalAlignment = VerticalAlignment.Center,\r
- HorizontalAlignment =HorizontalAlignment.End,\r
- IsCreateByXaml = true,\r
- Position2D = new Position2D(width-LayoutPadding-LeftPadding-108, 36)\r
- };\r
- base.Add(additionalLabel);\r
- return additionalLabel;\r
- }\r
-\r
- private View CreateItemSeparator(int width, int height)\r
- {\r
- View itemSeperator = new View()\r
- {\r
- Size2D = new Size2D(width, SeperatorHeight),\r
- ExcludeLayouting = true,\r
- Position2D = new Position2D(X , height - SeperatorHeight),\r
- BackgroundColor = UIColors.ItemSeperator,\r
- };\r
- base.Add(itemSeperator);\r
- return itemSeperator;\r
- }\r
-\r
- public TextLabel TitleLabel\r
- {\r
- get => titleLabel;\r
- }\r
- public TextLabel SubtitleLabel\r
- {\r
- get => subtitleLabel;\r
- }\r
- public TextLabel AdditionalLabel\r
- {\r
- get => additionalLabel;\r
- }\r
-\r
- protected override void Dispose(DisposeTypes type)\r
- {\r
- if (Disposed)\r
- {\r
- return;\r
- }\r
- if (type == DisposeTypes.Explicit)\r
- {\r
- base.Remove(itemSeperator);\r
- itemSeperator?.Dispose();\r
- itemSeperator = null;\r
-\r
- base.Remove(titleLabel);\r
- titleLabel?.Dispose();\r
- titleLabel = null;\r
-\r
- base.Remove(subtitleLabel);\r
- subtitleLabel?.Dispose();\r
- subtitleLabel = null;\r
-\r
- base.Remove(additionalLabel);\r
- additionalLabel?.Dispose();\r
- additionalLabel = null;\r
- }\r
- base.Dispose(type);\r
- }\r
- }\r
-}\r
+++ /dev/null
-using MusicPlayer.ViewModels;\r
-using Tizen.NUI.Components;\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
- class AlbumDetailView : View\r
- {\r
- private const int LayoutPadding = 64;\r
- private const int IconSize = 48;\r
- private const int AlbumArtSize = 520;\r
- private const int ControlViewWidth = 960;\r
- private const int ControlViewHeight = 60;\r
- private const int ControlViewMargin = 6;\r
-\r
- private BaseView baseView;\r
- private View contentView;\r
- private View leftView;\r
- private View rightView;\r
- private ImageView albumArtIcon;\r
- private TextLabel albumNameLabel;\r
- private TextLabel albumArtistLabel;\r
- private View controlsView;\r
- private TextLabel trackCountLabel;\r
- private Button playAllIcon; // TODO need to implement playall feature\r
- private Button shuffleAndPlayAllIcon; // TODO need to implement playlist manager\r
- private CollectionView collectionView;\r
-\r
- private AlbumDetailViewModel viewModel;\r
- public AlbumDetailView(AlbumDetailViewModel viewModel) : base()\r
- {\r
- this.viewModel = viewModel;\r
- BindingContext = viewModel;\r
- BackgroundColor = UIColors.HEXEEEFF1;\r
- WidthResizePolicy = ResizePolicyType.FillToParent;\r
- HeightResizePolicy = ResizePolicyType.FillToParent;\r
-\r
- //TODO need to change this part after implementation of Command Interface\r
- baseView = new BaseView()\r
- {\r
- Title = viewModel.AlbumName,\r
- BackButton = true,\r
- MoreButton = true,\r
- SearchButton = true,\r
- BackgroundColor = UIColors.HEXEEEFF1,\r
- };\r
- base.Add(baseView);\r
- contentView = new View()\r
- {\r
- WidthSpecification = LayoutParamPolicies.MatchParent,\r
- HeightSpecification = 876,\r
- Layout = new FlexLayout()\r
- {\r
- Direction = FlexLayout.FlexDirection.Row,\r
- ItemsAlignment = FlexLayout.AlignmentType.FlexStart,\r
- Justification = FlexLayout.FlexJustification.FlexStart,\r
- },\r
- };\r
- baseView.SetContent = contentView;\r
-\r
- leftView = CreateLeftView();\r
- rightView = CreateRightView();\r
- controlsView = AddControlView();\r
- AddControlElements();\r
- collectionView = AddCollectionView();\r
- AddAlbumArt();\r
- AddAlbumInfo();\r
- }\r
-\r
- private void OnTrackSelection(object sender, SelectionChangedEventArgs e)\r
- {\r
-\r
- }\r
-\r
- private Button CreateButton(string url, int x, int y)\r
- {\r
- ButtonStyle buttonStyle = new ButtonStyle()\r
- {\r
- Icon = new ImageViewStyle()\r
- {\r
- ResourceUrl = url,\r
- },\r
- IsSelectable = false,\r
- IsEnabled = true,\r
- };\r
-\r
- Button button = new Button(buttonStyle)\r
- {\r
- Size2D = new Size2D(IconSize, IconSize),\r
- Position2D = new Position2D(x, y),\r
- };\r
- return button;\r
- }\r
-\r
- private View CreateLeftView()\r
- {\r
- View leftView = new View()\r
- {\r
- BackgroundColor = UIColors.HEXEEEFF1,\r
- Size2D = new Size2D(Window.Instance.WindowSize.Width / 2, 752),\r
- Position2D = new Position2D(0, 0),\r
- Layout = new FlexLayout\r
- {\r
- Direction = FlexLayout.FlexDirection.Column,\r
- ItemsAlignment = FlexLayout.AlignmentType.Center,\r
- Justification = FlexLayout.FlexJustification.FlexStart,\r
- },\r
- Padding = new Extents(0, 0, ControlViewHeight, 42),\r
- };\r
- contentView.Add(leftView);\r
- return leftView;\r
- }\r
-\r
- private View CreateRightView()\r
- {\r
- View rightView = new View()\r
- {\r
- BackgroundColor = UIColors.HEXEEEFF1,\r
- Size2D = new Size2D(Window.Instance.WindowSize.Width / 2, 752),\r
- Position2D = new Position2D(Window.Instance.WindowSize.Width / 2, 0),\r
- Layout = new FlexLayout\r
- {\r
- Direction = FlexLayout.FlexDirection.Column,\r
- ItemsAlignment = FlexLayout.AlignmentType.Center,\r
- Justification = FlexLayout.FlexJustification.FlexStart,\r
- },\r
- };\r
- contentView.Add(rightView);\r
- return rightView;\r
- }\r
-\r
- private void AddAlbumArt()\r
- {\r
- albumArtIcon = new ImageView()\r
- {\r
- BackgroundColor = UIColors.HEXEEEFF1,\r
- Size2D = new Size2D(AlbumArtSize, AlbumArtSize),\r
- };\r
- albumArtIcon.SetBinding(ImageView.ResourceUrlProperty, "AlbumArtPath");\r
- leftView.Add(albumArtIcon);\r
- }\r
- private void AddAlbumInfo()\r
- {\r
- albumNameLabel = new TextLabel()\r
- {\r
- Text = "ALBUM NAME",\r
- Size2D = new Size2D(640, 48),\r
- PixelSize = 36,\r
- Margin = new Extents(0, 0, 32, 0),\r
- FontFamily = "BreezeSans",\r
- TextColor = UIColors.HEX001447,\r
- HorizontalAlignment = HorizontalAlignment.Center,\r
- VerticalAlignment = VerticalAlignment.Center,\r
- Ellipsis = true,\r
- };\r
- albumNameLabel.SetBinding(TextLabel.TextProperty, "AlbumName");\r
- leftView.Add(albumNameLabel);\r
- albumArtistLabel = new TextLabel()\r
- {\r
- Text = "ARTIST NAME",\r
- Size2D = new Size2D(640, 36),\r
- PixelSize = 28,\r
- Margin = new Extents(0, 0, 14, 0),\r
- FontFamily = "BreezeSans",\r
- TextColor = UIColors.HEX000209,\r
- HorizontalAlignment = HorizontalAlignment.Center,\r
- VerticalAlignment = VerticalAlignment.Center,\r
- Ellipsis = true,\r
- };\r
- albumArtistLabel.SetBinding(TextLabel.TextProperty, "ArtistName");\r
- leftView.Add(albumArtistLabel);\r
-\r
- }\r
- private View AddControlView()\r
- {\r
- View controlsView = new View()\r
- {\r
- BackgroundColor = UIColors.HEXEEEFF1,\r
- Size2D = new Size2D(ControlViewWidth, ControlViewHeight),\r
- Padding = new Extents(LayoutPadding, LayoutPadding, ControlViewMargin, ControlViewMargin),\r
- };\r
- rightView.Add(controlsView);\r
- return controlsView;\r
- }\r
-\r
- private void AddControlElements()\r
- {\r
- trackCountLabel = new TextLabel()\r
- {\r
- Text = "TRACK COUNT",\r
- Size2D = new Size2D(664, 36),\r
- Position2D = new Position2D(LayoutPadding, 12),\r
- PixelSize = 28,\r
- Margin = new Extents(0, 0, ControlViewMargin, ControlViewMargin),\r
- FontFamily = "BreezeSans",\r
- TextColor = UIColors.HEX001447,\r
- HorizontalAlignment = HorizontalAlignment.Begin,\r
- VerticalAlignment = VerticalAlignment.Center,\r
- };\r
- trackCountLabel.SetBinding(TextLabel.TextProperty, "TotalTracks");\r
- controlsView.Add(trackCountLabel);\r
-\r
- playAllIcon = CreateButton(Resources.GetImagePath() + "playlist_active.png.png", Window.Instance.WindowSize.Width / 2 - LayoutPadding - IconSize, ControlViewMargin);\r
- playAllIcon.Margin = new Extents(40, 0, 0, 0);\r
- controlsView.Add(playAllIcon);\r
-\r
- shuffleAndPlayAllIcon = CreateButton(Resources.GetImagePath() + "shuffle_on.png", Window.Instance.WindowSize.Width / 2 - LayoutPadding - 2 * IconSize - 40, ControlViewMargin);\r
- playAllIcon.Margin = new Extents(32, 0, 0, 0);\r
- controlsView.Add(shuffleAndPlayAllIcon);\r
-\r
- }\r
-\r
- private CollectionView AddCollectionView()\r
- {\r
- CollectionView collectionView = new CollectionView()\r
- {\r
- Size2D = new Size2D(832, 108),\r
- BackgroundImage = Resources.GetImagePath() + "list_view_bg.png",\r
- ItemsLayouter = new LinearLayouter(),\r
- ItemTemplate = new DataTemplate(() =>\r
- {\r
- AlbumDetailLayout layout = new AlbumDetailLayout();\r
- layout.TitleLabel.SetBinding(TextLabel.TextProperty, "TrackTitle");\r
- layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName");\r
- layout.AdditionalLabel.SetBinding(TextLabel.TextProperty, "Duration");\r
- return layout;\r
- }),\r
- ScrollingDirection = ScrollableBase.Direction.Vertical,\r
- HeightSpecification = LayoutParamPolicies.WrapContent,\r
- SelectionMode = ItemSelectionMode.Single,\r
- };\r
- rightView.Add(collectionView);\r
- FlexLayout.SetFlexGrow(collectionView, 1);\r
- FlexLayout.SetFlexShrink(collectionView, 1);\r
- collectionView.ItemsSource = viewModel.ListViewModel;\r
- collectionView.SelectionChanged += OnTrackSelection;\r
- return collectionView;\r
- }\r
- }\r
-}\r
+++ /dev/null
-using MusicPlayer.ViewModels;\r
-using Tizen.NUI.Components;\r
-using Tizen.NUI.BaseComponents;\r
-using Tizen.NUI;\r
-using Tizen.NUI.Binding;\r
-using MusicPlayer.Common;\r
-using MusicPlayer.Models;\r
-\r
-namespace MusicPlayer.Views\r
-{\r
- class AlbumView : BaseContentView\r
- {\r
- private AlbumViewModel viewModel;\r
- private TextLabel albumCountLabel;\r
-\r
- public AlbumView(AlbumViewModel viewModel)\r
- {\r
- this.viewModel = viewModel;\r
- BindingContext = viewModel;\r
- collectionView.ItemsSource = viewModel.ListViewModel;\r
- collectionView.ItemTemplate = new DataTemplate(() =>\r
- {\r
- ListItemLayout layout = new ListItemLayout();\r
- layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "AlbumArtPath");\r
- layout.TitleLabel.SetBinding(TextLabel.TextProperty, "AlbumName");\r
- layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName");\r
- return layout;\r
- });\r
- collectionView.ScrollingDirection = ScrollableBase.Direction.Vertical;\r
- collectionView.WidthSpecification = LayoutParamPolicies.WrapContent;\r
- collectionView.SelectionMode = ItemSelectionMode.Single;\r
- collectionView.SelectionChanged += OnAlbumSelection;\r
-\r
- albumCountLabel = new TextLabel()\r
- {\r
- PixelSize = 28,\r
- Text = "ALBUM COUNT",\r
- TextColor = UIColors.HEX001447,\r
- VerticalAlignment = VerticalAlignment.Center,\r
- FontFamily = "BreezeSans",\r
- IsCreateByXaml = true,\r
- };\r
- titleView.Add(albumCountLabel);\r
- albumCountLabel.SetBinding(TextLabel.TextProperty, "AlbumCount");\r
- RelativeLayout.SetLeftTarget(albumCountLabel, titleView);\r
- RelativeLayout.SetLeftRelativeOffset(albumCountLabel, 1.0f);\r
- RelativeLayout.SetRightRelativeOffset(albumCountLabel, 0.0f);\r
- RelativeLayout.SetFillHorizontal(albumCountLabel, true);\r
- }\r
- private void OnAlbumSelection(object sender, SelectionChangedEventArgs e)\r
- {\r
- MusicAlbum currentAlbum= (MusicAlbum)collectionView.SelectedItem;\r
- // viewModel.getDetailViewModel(currentAlbum) => need to replace direct function call on viewModel class with command interface\r
- AlbumDetailView view = new AlbumDetailView(viewModel.getDetailViewModel(currentAlbum));\r
- Window.Instance.Add(view);\r
- }\r
- protected override void Dispose(DisposeTypes type)\r
- {\r
- if (Disposed)\r
- {\r
- return;\r
- }\r
- if (type == DisposeTypes.Explicit)\r
- {\r
- titleView.Remove(albumCountLabel);\r
- albumCountLabel.Dispose();\r
- albumCountLabel = null;\r
- }\r
- base.Dispose(type);\r
- }\r
- }\r
-}\r
+++ /dev/null
-using Tizen.NUI.Components;
-using Tizen.NUI.BaseComponents;
-using Tizen.NUI;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.Views
-{
- class ArtistDetailGroupLayout : RecyclerViewItem
- {
- private static int Width = 1792;
- private static int Height = 108;
-
- private const int IconSize = 64;
- private const int LayoutPadding = 32;
- private const int SeperatorHeight = 1;
- private const int LeftPadding = 64;
- private const int x = 0;
-
- private View itemSeperator;
- private TextLabel titleLabel;
- private ImageView icon;
-
- public ArtistDetailGroupLayout(int width = 1792, int height = 108) : base()
- {
- base.OnInitialize();
- base.IsCreateByXaml = true;
- Width = width;
- Height = height;
- WidthSpecification = Width;
- HeightSpecification = Height;
-
- // to show the rounded rect of the bg
- BackgroundColor = Color.Transparent;
-
- icon = CreateIcon();
- titleLabel = CreateTitleLabel();
- itemSeperator = CreateItemSeparator();
- IsCreateByXaml = true;
- }
-
- private ImageView CreateIcon()
- {
- ImageView icon = new ImageView()
- {
- WidthSpecification = IconSize,
- HeightSpecification = IconSize,
- IsCreateByXaml = true,
- Position2D = new Position2D(x, (Height / 2) - (IconSize / 2)),
- };
- base.Add(icon);
- return icon;
- }
-
- private View CreateItemSeparator()
- {
- View itemSeperator = new View()
- {
- WidthSpecification = (Width - (2 * LeftPadding)),
- HeightSpecification = SeperatorHeight,
- ExcludeLayouting = true,
- Position2D = new Position2D(x, Height - SeperatorHeight),
- BackgroundColor = UIColors.ItemSeperator,
- };
- base.Add(itemSeperator);
- return itemSeperator;
- }
-
- private TextLabel CreateTitleLabel()
- {
- TextLabel titleLabel = new TextLabel()
- {
- WidthSpecification = (Width - (2 * LeftPadding) - IconSize - LayoutPadding),
- HeightSpecification = 40,
- TextColor = UIColors.HEX001447,
- PixelSize = 32,
- FontFamily = "BreezeSans",
- VerticalAlignment = VerticalAlignment.Center,
- IsCreateByXaml = true,
- Position2D = new Position2D(x + IconSize + LayoutPadding, 34),
- };
- base.Add(titleLabel);
- return titleLabel;
- }
-
- public ImageView Icon
- {
- get => icon;
- }
-
- public TextLabel TitleLabel
- {
- get => titleLabel;
- }
-
- protected override void Dispose(DisposeTypes type)
- {
- if (Disposed)
- {
- return;
- }
- if (type == DisposeTypes.Explicit)
- {
- base.Remove(itemSeperator);
- itemSeperator?.Dispose();
- itemSeperator = null;
-
- base.Remove(icon);
- icon?.Dispose();
- icon = null;
-
- base.Remove(titleLabel);
- titleLabel?.Dispose();
- titleLabel = null;
- }
- base.Dispose(type);
- }
- }
-}
+++ /dev/null
-using Tizen.NUI.Components;
-using Tizen.NUI.BaseComponents;
-using Tizen.NUI;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.Views
-{
- class ArtistDetailItemLayout : RecyclerViewItem
- {
- private static int Width = 1792;
- private static int Height = 108;
-
- private const int LayoutPadding = 32;
- private const int SeperatorHeight = 1;
- private const int LeftPadding = 64;
- private const int x = 0;
-
- private View itemSeperator;
- private TextLabel titleLabel;
- private TextLabel extraLabel;
-
- public ArtistDetailItemLayout(int width = 1792, int height = 108) : base()
- {
- base.OnInitialize();
- base.IsCreateByXaml = true;
- Width = width;
- Height = height;
- WidthSpecification = Width;
- HeightSpecification = Height;
-
- // to show the rounded rect of the bg
- BackgroundColor = Color.Transparent;
-
- titleLabel = CreateTitleLabel();
- extraLabel = CreateExtraLabel();
- itemSeperator = CreateItemSeparator();
- IsCreateByXaml = true;
- }
-
- private View CreateItemSeparator()
- {
- View itemSeperator = new View()
- {
- WidthSpecification = (Width - (2 * LeftPadding)),
- HeightSpecification = SeperatorHeight,
- ExcludeLayouting = true,
- Position2D = new Position2D(x, Height - SeperatorHeight),
- BackgroundColor = UIColors.ItemSeperator,
- };
- base.Add(itemSeperator);
- return itemSeperator;
- }
-
- private TextLabel CreateTitleLabel()
- {
- TextLabel titleLabel = new TextLabel()
- {
- WidthSpecification = 1272,
- HeightSpecification = 40,
- TextColor = UIColors.HEX001447,
- PixelSize = 32,
- FontFamily = "BreezeSans",
- VerticalAlignment = VerticalAlignment.Center,
- IsCreateByXaml = true,
- Position2D = new Position2D(x, 34),
- };
- base.Add(titleLabel);
- return titleLabel;
- }
-
- private TextLabel CreateExtraLabel()
- {
- TextLabel extraLabel = new TextLabel()
- {
- WidthSpecification = 360,
- HeightSpecification = 36,
- TextColor = UIColors.HEX001447,
- PixelSize = 28,
- FontFamily = "BreezeSans",
- VerticalAlignment = VerticalAlignment.Center,
- HorizontalAlignment = HorizontalAlignment.End,
- IsCreateByXaml = true,
- Position2D = new Position2D((x + 1272 + LayoutPadding), 36)
- };
- base.Add(extraLabel);
- return extraLabel;
- }
-
- public TextLabel TitleLabel
- {
- get => titleLabel;
- }
-
- public TextLabel ExtraLabel
- {
- get => extraLabel;
- }
-
- protected override void Dispose(DisposeTypes type)
- {
- if (Disposed)
- {
- return;
- }
- if (type == DisposeTypes.Explicit)
- {
- base.Remove(itemSeperator);
- itemSeperator?.Dispose();
- itemSeperator = null;
-
- base.Remove(titleLabel);
- titleLabel?.Dispose();
- titleLabel = null;
-
- base.Remove(extraLabel);
- extraLabel?.Dispose();
- extraLabel = null;
- }
- base.Dispose(type);
- }
- }
-}
+++ /dev/null
-using MusicPlayer.ViewModels;
-using Tizen.NUI.Components;
-using Tizen.NUI.BaseComponents;
-using Tizen.NUI;
-using Tizen.NUI.Binding;
-using MusicPlayer.Common;
-using MusicPlayer.Models;
-
-namespace MusicPlayer.Views
-{
- class ArtistDetailView : View //BaseContentView
- {
- private const int LayoutPadding = 64;
- private const int IconSize = 48;
-
- private BaseView baseView;
- private View contentView;
- private View topView;
- private TextLabel totalCountLabel;
- private Button playAllIcon; // TODO need to implement playall feature
- private Button shuffleAndPlayAllIcon; // TODO need to implement playlist manager
- private CollectionView collectionView;
-
- private ArtistDetailViewModel viewModel;
-
- public ArtistDetailView(ArtistDetailViewModel viewModel) : base()
- {
- this.viewModel = viewModel;
- BindingContext = viewModel;
- BackgroundColor = UIColors.HEXEEEFF1;
- WidthResizePolicy = ResizePolicyType.FillToParent;
- HeightResizePolicy = ResizePolicyType.FillToParent;
-
- //TODO need to change this part after implementation of Command Interface
- baseView = new BaseView()
- {
- Title = viewModel.ArtistName,
- BackButton = true,
- MoreButton = true,
- SearchButton = true,
- BackgroundColor = UIColors.HEXEEEFF1,
- };
- base.Add(baseView);
- contentView = new View()
- {
- WidthSpecification = LayoutParamPolicies.MatchParent,
- HeightSpecification = 876,
- Layout = new FlexLayout()
- {
- Direction = FlexLayout.FlexDirection.Column,
- Padding = new Extents(LayoutPadding, LayoutPadding, 0, 0),
- },
- };
- baseView.SetContent = contentView;
-
- topView = CreateTopView();
- AddTitle();
- AddButtons();
- collectionView = AddCollectionView();
- }
-
- private void OnTrackSelection(object sender, SelectionChangedEventArgs e)
- {
-
- }
-
- private Button CreateButton(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(IconSize, IconSize),
- Position2D = new Position2D(x, y),
- };
- return button;
- }
-
- private View CreateTopView()
- {
- View topView = new View()
- {
- BackgroundColor = UIColors.HEXEEEFF1,
- Size2D = new Size2D(Window.Instance.WindowSize.Width - 2 * LayoutPadding, 60),
- };
- contentView.Add(topView);
- return topView;
- }
-
- private void AddTitle()
- {
- totalCountLabel = new TextLabel()
- {
- Size2D = new Size2D(1624, 36),
- Position2D = new Position2D(0, 12),
- PixelSize = 28,
- Text = "TOTAL COUNT",
- TextColor = UIColors.HEX001447,
- VerticalAlignment = VerticalAlignment.Center,
- FontFamily = "BreezeSans",
- IsCreateByXaml = true,
- };
- topView.Add(totalCountLabel);
- totalCountLabel.SetBinding(TextLabel.TextProperty, "TotalCount");
- }
-
- private void AddButtons()
- {
- playAllIcon = CreateButton(Resources.GetImagePath() + "playlist_active.png", Window.Instance.WindowSize.Width - 2 * LayoutPadding - IconSize, 6);
- playAllIcon.Margin = new Extents(40, 0, 0, 0);
- topView.Add(playAllIcon);
-
- shuffleAndPlayAllIcon = CreateButton(Resources.GetImagePath() + "shuffle_on.png", Window.Instance.WindowSize.Width - 2 * LayoutPadding - 2 * IconSize - 40, 6);
- playAllIcon.Margin = new Extents(32, 0, 0, 0);
- topView.Add(shuffleAndPlayAllIcon);
- }
-
- private CollectionView AddCollectionView()
- {
- CollectionView collectionView = new CollectionView()
- {
- Size2D = new Size2D(1792, 108),
- BackgroundImage = Resources.GetImagePath() + "list_view_bg.png",
- ItemsLayouter = new LinearLayouter(),
- ItemTemplate = new DataTemplate(() =>
- {
- ArtistDetailItemLayout layout = new ArtistDetailItemLayout();
- layout.TitleLabel.SetBinding(TextLabel.TextProperty, "TrackTitle");
- layout.ExtraLabel.SetBinding(TextLabel.TextProperty, "Duration");
- return layout;
- }),
- GroupHeaderTemplate = new DataTemplate(() =>
- {
- ArtistDetailGroupLayout group = new ArtistDetailGroupLayout();
- group.Icon.SetBinding(ImageView.ResourceUrlProperty, "AlbumArtPath");
- group.TitleLabel.SetBinding(TextLabel.TextProperty, "AlbumName");
- return group;
- }),
- IsGrouped = true,
- ScrollingDirection = ScrollableBase.Direction.Vertical,
- HeightSpecification = LayoutParamPolicies.WrapContent,
- SelectionMode = ItemSelectionMode.Single,
- };
- contentView.Add(collectionView);
- FlexLayout.SetFlexGrow(collectionView, 1);
- FlexLayout.SetFlexShrink(collectionView, 1);
- collectionView.ItemsSource = viewModel.GroupListViewModel;
- collectionView.SelectionChanged += OnTrackSelection;
- return collectionView;
- }
- }
-}
+++ /dev/null
-using MusicPlayer.ViewModels;
-using Tizen.NUI.Components;
-using Tizen.NUI.BaseComponents;
-using Tizen.NUI;
-using Tizen.NUI.Binding;
-using MusicPlayer.Common;
-using MusicPlayer.Models;
-
-namespace MusicPlayer.Views
-{
- class ArtistView : BaseContentView
- {
- private ArtistViewModel viewModel;
- private TextLabel artistCountLabel;
-
- public ArtistView(ArtistViewModel viewModel)
- {
- this.viewModel = viewModel;
- BindingContext = viewModel;
- collectionView.ItemsSource = viewModel.ListViewModel;
- collectionView.ItemTemplate = new DataTemplate(() =>
- {
- ListItemLayout layout = new ListItemLayout();
- layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "AlbumArtPath");
- layout.TitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName");
- layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "TotalCount");
- return layout;
- });
- collectionView.ScrollingDirection = ScrollableBase.Direction.Vertical;
- collectionView.WidthSpecification = LayoutParamPolicies.WrapContent;
- collectionView.SelectionMode = ItemSelectionMode.Single;
- collectionView.SelectionChanged += OnArtistSelection;
-
- artistCountLabel = new TextLabel()
- {
- PixelSize = 28,
- Text = "ARTIST COUNT",
- TextColor = UIColors.HEX001447,
- VerticalAlignment = VerticalAlignment.Center,
- FontFamily = "BreezeSans",
- IsCreateByXaml = true,
- };
- titleView.Add(artistCountLabel);
- artistCountLabel.SetBinding(TextLabel.TextProperty, "ArtistCount");
- RelativeLayout.SetLeftTarget(artistCountLabel, titleView);
- RelativeLayout.SetLeftRelativeOffset(artistCountLabel, 1.0f);
- RelativeLayout.SetRightRelativeOffset(artistCountLabel, 0.0f);
- RelativeLayout.SetFillHorizontal(artistCountLabel, true);
- }
- private void OnArtistSelection(object sender, SelectionChangedEventArgs e)
- {
- Artist currentArtist = (Artist)collectionView.SelectedItem;
- ArtistDetailView view = new ArtistDetailView(viewModel.getDetailViewModel(currentArtist));
- Window.Instance.Add(view);
- }
- protected override void Dispose(DisposeTypes type)
- {
- if (Disposed)
- {
- return;
- }
- if (type == DisposeTypes.Explicit)
- {
- titleView.Remove(artistCountLabel);
- artistCountLabel.Dispose();
- artistCountLabel = null;
- }
- base.Dispose(type);
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-using MusicPlayer.Common;\r
-using Tizen.NUI;\r
-using Tizen.NUI.BaseComponents;\r
-using Tizen.NUI.Components;\r
-\r
-namespace MusicPlayer.Views\r
-{\r
- class BaseContentView : View\r
- {\r
- protected View titleView;\r
- protected CollectionView collectionView;\r
- public BaseContentView() : base()\r
- {\r
- ThemeChangeSensitive = true;\r
- WidthResizePolicy = ResizePolicyType.FillToParent;\r
- HeightResizePolicy = ResizePolicyType.FillToParent;\r
- Layout = new FlexLayout()\r
- {\r
- Direction = FlexLayout.FlexDirection.Column,\r
- Padding = new Extents(64, 64, 0, 0),\r
- };\r
- titleView = new View()\r
- {\r
- ThemeChangeSensitive = true,\r
- WidthSpecification = LayoutParamPolicies.MatchParent,\r
- HeightSpecification = 60,\r
- Layout = new RelativeLayout()\r
- {\r
- Padding = new Extents(0, 0, 13, 13),\r
- },\r
- };\r
- base.Add(titleView);\r
- FlexLayout.SetFlexGrow(titleView, 0);\r
- FlexLayout.SetFlexShrink(titleView, 0);\r
-\r
- collectionView = new CollectionView()\r
- {\r
- ThemeChangeSensitive = true,\r
- Size2D = new Size2D(1792, 108),\r
- Margin = new Extents(0, 0, 0, 2),\r
- BackgroundImage = GetBackgroundImagePath(ThemeManager.PlatformThemeId),\r
- ItemsLayouter = new LinearLayouter(),\r
- ScrollingDirection = ScrollableBase.Direction.Vertical,\r
- WidthSpecification = LayoutParamPolicies.MatchParent,\r
- HeightSpecification = LayoutParamPolicies.WrapContent,\r
- SelectionMode = ItemSelectionMode.Single,\r
- };\r
- base.Add(collectionView);\r
- FlexLayout.SetFlexGrow(collectionView, 1);\r
- FlexLayout.SetFlexShrink(collectionView, 1);\r
- }\r
-\r
- private string GetBackgroundImagePath(string platformThemeId)\r
- {\r
- if(platformThemeId.Equals(AppConstants.DarkPlatformThemeId))\r
- {\r
- return Resources.GetImagePath() + "dark/list_view_bg.png";\r
- }\r
- else\r
- {\r
- return Resources.GetImagePath() + "light/list_view_bg.png";\r
- }\r
- }\r
-\r
- protected override void OnThemeChanged(object sender, ThemeChangedEventArgs e)\r
- {\r
- base.OnThemeChanged(sender, e);\r
- if(e.IsPlatformThemeChanged)\r
- {\r
- collectionView.BackgroundImage = GetBackgroundImagePath(e.PlatformThemeId);\r
- }\r
- }\r
-\r
- protected override void Dispose(DisposeTypes type)\r
- {\r
- if (type == DisposeTypes.Explicit)\r
- {\r
- base.Remove(titleView);\r
- titleView.Dispose();\r
- titleView = null;\r
-\r
- base.Remove(collectionView);\r
- collectionView.Dispose();\r
- collectionView = null;\r
- }\r
- base.Dispose(type);\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System.Collections.Generic;\r
-using Tizen.NUI;\r
-using Tizen.NUI.BaseComponents;\r
-using Tizen.NUI.Components;\r
-using Tizen.NUI.Binding;\r
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.Views\r
-{\r
- class BaseView : View\r
- {\r
- private View topView;\r
- private View bottomView; // TODO Used this for MiniController UI\r
- private View contentView;\r
- private TextLabel titleLabel;\r
- private Button backButton;\r
- private Button moreButton;\r
- private Button searchButton;\r
- private Tab tabs;\r
-\r
- // TODO these name strings are temporary...once the po files are added\r
- // need to use Translatable names.\r
- private static string[] TabNames = new string[]\r
- {\r
- "Playlists",\r
- "Tracks",\r
- "Albums",\r
- "Artists",\r
- };\r
- public BaseView() : base()\r
- {\r
- ThemeChangeSensitive = true;\r
- WidthSpecification = LayoutParamPolicies.MatchParent;\r
- HeightSpecification = LayoutParamPolicies.MatchParent;\r
- Layout = new FlexLayout()\r
- {\r
- Direction = FlexLayout.FlexDirection.Column,\r
- ItemsAlignment = FlexLayout.AlignmentType.FlexStart,\r
- Justification = FlexLayout.FlexJustification.FlexStart,\r
- };\r
- topView = new View()\r
- {\r
- ThemeChangeSensitive = true,\r
- WidthSpecification = LayoutParamPolicies.MatchParent,\r
- HeightSpecification = 120,\r
- Layout = new RelativeLayout()\r
- {\r
- Padding = new Extents(64, 64, 30, 30),\r
- },\r
- };\r
- base.Add(topView);\r
- FlexLayout.SetFlexGrow(topView, 0);\r
- FlexLayout.SetFlexShrink(topView, 0);\r
- titleLabel = new TextLabel()\r
- {\r
- ThemeChangeSensitive = true,\r
- Text = "Music",\r
- PixelSize = 40,\r
- FontFamily = "BreezeSans",\r
- TextColor = UIColors.HEX000209,\r
- HorizontalAlignment = HorizontalAlignment.Begin,\r
- Margin = new Extents(0, 0, 6, 6),\r
- Ellipsis = true,\r
- };\r
- topView.Add(titleLabel);\r
- titleLabel.SetBinding(TextLabel.TextProperty, "Title");\r
- RelativeLayout.SetLeftTarget(titleLabel, topView);\r
- RelativeLayout.SetLeftRelativeOffset(titleLabel, 0.0f);\r
- RelativeLayout.SetRightTarget(titleLabel, topView);\r
- RelativeLayout.SetRightRelativeOffset(titleLabel, 1.0f);\r
- RelativeLayout.SetFillHorizontal(titleLabel, true);\r
-\r
- contentView = new View()\r
- {\r
- ThemeChangeSensitive = true,\r
- WidthSpecification = LayoutParamPolicies.MatchParent,\r
- HeightSpecification = 876,\r
- };\r
- base.Add(contentView);\r
- FlexLayout.SetFlexGrow(contentView, 1);\r
- FlexLayout.SetFlexShrink(contentView, 1);\r
-\r
- tabs = new Tab()\r
- {\r
- ThemeChangeSensitive = true,\r
- Size2D = new Size2D(Window.Instance.Size.Width, 84),\r
- WidthSpecification = LayoutParamPolicies.MatchParent,\r
- HeightSpecification = 84,\r
- UnderLineBackgroundColor = Color.Blue,\r
- UnderLineSize = new Size2D(1, 3),\r
- PointSize = 25,\r
- BackgroundColor = Color.White,\r
- };\r
- tabs.TextColorSelector = new ColorSelector\r
- {\r
- Normal = Color.Black,\r
- Selected = Color.Magenta,\r
- };\r
- base.Add(tabs);\r
- for(int i = 0; i<4; ++i)\r
- {\r
- Tab.TabItemData item = new Tab.TabItemData();\r
- item.Text = TabNames[i];\r
- tabs.AddItem(item);\r
- }\r
- tabs.SelectedItemIndex = 1;\r
-\r
- backButton = null;\r
- moreButton = null;\r
- searchButton = null;\r
- }\r
-\r
- public Tab Tabs\r
- {\r
- get => tabs;\r
- }\r
-\r
- public string Title\r
- {\r
- get => titleLabel.Text;\r
- set { titleLabel.Text = value;}\r
- }\r
-\r
- public bool BackButton\r
- {\r
- set\r
- {\r
- if (value)\r
- {\r
- ButtonStyle buttonStyle = new ButtonStyle()\r
- {\r
- Icon = new ImageViewStyle()\r
- {\r
- ResourceUrl = Resources.GetImagePath() + "back_button.png",\r
- },\r
- IsSelectable = false,\r
- IsEnabled = true,\r
- };\r
-\r
- backButton = new Button(buttonStyle)\r
- {\r
- ThemeChangeSensitive = true,\r
- Size2D = new Size2D(48, 48),\r
- Margin = new Extents(0, 24, 6, 6),\r
- };\r
- topView.Add(backButton);\r
-\r
- RelativeLayout.SetLeftRelativeOffset(backButton, 0.0f);\r
- RelativeLayout.SetRightRelativeOffset(backButton, 0.0f);\r
- RelativeLayout.SetHorizontalAlignment(backButton, RelativeLayout.Alignment.Start);\r
-\r
- RelativeLayout.SetLeftTarget(titleLabel, backButton);\r
- RelativeLayout.SetLeftRelativeOffset(titleLabel, 1.0f);\r
- }\r
- }\r
- }\r
-\r
- public bool MoreButton\r
- {\r
- set\r
- {\r
- if (value)\r
- {\r
- ButtonStyle buttonStyle = new ButtonStyle()\r
- {\r
- Icon = new ImageViewStyle()\r
- {\r
- ResourceUrl = Resources.GetImagePath() + "more.png",\r
- },\r
- IsSelectable = false,\r
- IsEnabled = true,\r
- };\r
- moreButton = new Button(buttonStyle)\r
- {\r
- ThemeChangeSensitive = true,\r
- Size2D = new Size2D(48, 48),\r
- Margin = new Extents(32, 0, 6, 6),\r
- };\r
- topView.Add(moreButton);\r
- RelativeLayout.SetLeftRelativeOffset(moreButton, 1.0f);\r
- RelativeLayout.SetRightRelativeOffset(moreButton, 1.0f);\r
- RelativeLayout.SetHorizontalAlignment(moreButton, RelativeLayout.Alignment.End);\r
-\r
- RelativeLayout.SetRightTarget(titleLabel, moreButton);\r
- RelativeLayout.SetRightRelativeOffset(titleLabel, 0.0f);\r
- }\r
- }\r
- }\r
-\r
- public bool SearchButton\r
- {\r
- set\r
- {\r
- if (value)\r
- {\r
- ButtonStyle buttonStyle = new ButtonStyle()\r
- {\r
- Icon = new ImageViewStyle()\r
- {\r
- ResourceUrl = Resources.GetImagePath() + "search_icon.png",\r
- },\r
- IsSelectable = false,\r
- IsEnabled = true,\r
- };\r
- searchButton = new Button(buttonStyle)\r
- {\r
- ThemeChangeSensitive = true,\r
- Size2D = new Size2D(96, 60),\r
- BackgroundImage = Resources.GetImagePath() + "search_button_bg.png",\r
- Margin = new Extents(24, 0, 0, 0),\r
- };\r
- topView.Add(searchButton);\r
- RelativeLayout.SetRightTarget(searchButton, moreButton);\r
- RelativeLayout.SetRightRelativeOffset(searchButton, 0.0f);\r
- RelativeLayout.SetHorizontalAlignment(searchButton, RelativeLayout.Alignment.End);\r
-\r
- RelativeLayout.SetLeftTarget(titleLabel, RelativeLayout.GetLeftTarget(titleLabel));\r
- RelativeLayout.SetLeftRelativeOffset(titleLabel, RelativeLayout.GetLeftRelativeOffset(titleLabel));\r
- RelativeLayout.SetRightTarget(titleLabel, searchButton);\r
- RelativeLayout.SetRightRelativeOffset(titleLabel, 0.0f);\r
- }\r
- }\r
- }\r
-\r
- public View SetContent\r
- {\r
- set\r
- {\r
- contentView.Add(value);\r
- }\r
- }\r
-\r
- protected override void Dispose(DisposeTypes type)\r
- {\r
- if (Disposed)\r
- {\r
- return;\r
- }\r
- if (type == DisposeTypes.Explicit)\r
- {\r
- List<View> children = topView?.Children;\r
- foreach (View child in children)\r
- {\r
- topView.Remove(child);\r
- child?.Dispose();\r
- }\r
- base.Remove(topView);\r
- topView?.Dispose();\r
- topView = null;\r
-\r
- // Do not delete the children of contentview as they are not owned by BaseView\r
- base.Remove(contentView);\r
- contentView?.Dispose();\r
- contentView = null;\r
-\r
- base.Remove(tabs);\r
- tabs?.Dispose();\r
- tabs = null;\r
-\r
- base.Remove(bottomView);\r
- bottomView?.Dispose();\r
- bottomView = null;\r
- }\r
-\r
- base.Dispose(type);\r
- }\r
- }\r
-}
\ No newline at end of file
+++ /dev/null
-using Tizen.NUI.Components;\r
-using Tizen.NUI.BaseComponents;\r
-using Tizen.NUI;\r
-using MusicPlayer.Common;\r
-\r
-namespace MusicPlayer.Views\r
-{\r
- class ListItemLayout : RecyclerViewItem\r
- {\r
- private static int Width = 1792;\r
- private static int Height = 108;\r
-\r
- private const int IconSize = 64;\r
- private const int LayoutMargin = 16;\r
- private const int LayoutPadding = 32;\r
- private const int SeperatorHeight = 1;\r
- private const int LeftPadding = 64;\r
- private const int x = 0;\r
-\r
- private View itemSeperator;\r
- private TextLabel titleLabel;\r
- private TextLabel subtitleLabel;\r
- private ImageView icon;\r
-\r
- public ListItemLayout(int width = 1792, int height = 108) : base()\r
- {\r
- base.OnInitialize();\r
- base.IsCreateByXaml = true;\r
- Width = width;\r
- Height = height;\r
- WidthSpecification = Width;\r
- HeightSpecification = Height;\r
-\r
- // to show the rounded rect of the bg\r
- BackgroundColor = Color.Transparent;\r
-\r
- icon = new ImageView()\r
- {\r
- WidthSpecification = IconSize,\r
- HeightSpecification = IconSize,\r
- IsCreateByXaml = true,\r
- Position2D = new Position2D(x, ((Height / 2) - (IconSize / 2))),\r
- };\r
- base.Add(icon);\r
-\r
- itemSeperator = new View()\r
- {\r
- WidthSpecification = (Width - (2 * LeftPadding)),\r
- HeightSpecification = SeperatorHeight,\r
- ExcludeLayouting = true,\r
- Position2D = new Position2D(x, Height - SeperatorHeight),\r
- BackgroundColor = UIColors.ItemSeperator,\r
- };\r
- base.Add(itemSeperator);\r
-\r
- titleLabel = new TextLabel("ItemLabel")\r
- {\r
- ThemeChangeSensitive = true,\r
- WidthSpecification = (Width - (2 * LeftPadding) - IconSize - LayoutPadding),\r
- HeightSpecification = 40,\r
- PixelSize = 32,\r
- FontFamily = "BreezeSans",\r
- VerticalAlignment = VerticalAlignment.Center,\r
- IsCreateByXaml = true,\r
- Position2D = new Position2D((x + IconSize + LayoutPadding), LayoutMargin),\r
- };\r
- // ToDo need to make this a readonly const\r
- PropertyMap titleFontStyle = new PropertyMap();\r
- titleFontStyle.Add("width", new PropertyValue("normal"));\r
- titleFontStyle.Add("weight", new PropertyValue("light"));\r
- titleLabel.FontStyle = titleFontStyle;\r
- base.Add(titleLabel);\r
-\r
- subtitleLabel = new TextLabel("ItemLabel")\r
- {\r
- ThemeChangeSensitive = true,\r
- WidthSpecification = (Width - (2 * LeftPadding) - IconSize - LayoutPadding),\r
- HeightSpecification = 36,\r
- PixelSize = 28,\r
- FontFamily = "BreezeSans",\r
- VerticalAlignment = VerticalAlignment.Center,\r
- IsCreateByXaml = true,\r
- Position2D = new Position2D((x + IconSize + LayoutPadding), LayoutMargin + 40)\r
- };\r
- // ToDo need to make this a readonly const\r
- PropertyMap subtitleFontStyle = new PropertyMap();\r
- subtitleFontStyle.Add("width", new PropertyValue("normal"));\r
- subtitleFontStyle.Add("weight", new PropertyValue("normal"));\r
- subtitleFontStyle.Add("slant", new PropertyValue("normal"));\r
- subtitleLabel.FontStyle = subtitleFontStyle;\r
- base.Add(subtitleLabel);\r
- IsCreateByXaml = true;\r
- }\r
- public ImageView Icon\r
- {\r
- get => icon;\r
- }\r
- public TextLabel TitleLabel\r
- {\r
- get => titleLabel;\r
- }\r
- public TextLabel SubtitleLabel\r
- {\r
- get => subtitleLabel;\r
- }\r
-\r
- protected override void Dispose(DisposeTypes type)\r
- {\r
- if(Disposed)\r
- {\r
- return;\r
- }\r
- if (type == DisposeTypes.Explicit)\r
- {\r
- base.Remove(itemSeperator);\r
- itemSeperator?.Dispose();\r
- itemSeperator = null;\r
-\r
- base.Remove(icon);\r
- icon?.Dispose();\r
- icon = null;\r
-\r
- base.Remove(titleLabel);\r
- titleLabel?.Dispose();\r
- titleLabel = null;\r
-\r
- base.Remove(subtitleLabel);\r
- subtitleLabel?.Dispose();\r
- subtitleLabel = null;\r
- }\r
-\r
- base.Dispose(type);\r
- }\r
- }\r
-}\r
+++ /dev/null
-using Tizen.NUI;
-using Tizen.NUI.Binding;
-using Tizen.NUI.BaseComponents;
-using Tizen.NUI.Components;
-using MusicPlayer.ViewModels;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.Views
-{
- class LyricsView : View
- {
- private const int ViewSize = 784;
- private const int LyricsViewMargin = 40;
- private const int LyricsViewSize = 704;
-
- private readonly LyricsViewModel lyricsViewModel;
-
- private ImageView thumbView;
- private ScrollableBase scrollView;
- private TextLabel lyricsLabel;
-
- public LyricsView(LyricsViewModel lyricsViewModel) : base()
- {
- this.lyricsViewModel = lyricsViewModel;
- BindingContext = lyricsViewModel.lyricsModel;
- Size2D = new Size2D(ViewSize, ViewSize);
-
- AddThumbnail();
- AddLyricsView();
- }
-
- private void AddThumbnail()
- {
- thumbView = new ImageView()
- {
- HeightResizePolicy = ResizePolicyType.FillToParent,
- WidthResizePolicy = ResizePolicyType.FillToParent,
- };
- thumbView.SetBinding(ImageView.ResourceUrlProperty, "ThumbPath");
- base.Add(thumbView);
- }
-
- private void AddLyricsView()
- {
- scrollView = new ScrollableBase()
- {
- Position2D = new Position2D(LyricsViewMargin, LyricsViewMargin),
- Size2D = new Size2D(LyricsViewSize, LyricsViewSize),
- ScrollingDirection = ScrollableBase.Direction.Vertical,
- BackgroundColor = Color.Transparent,
- };
- scrollView.BindingContext = lyricsViewModel;
- scrollView.SetBinding(View.BackgroundColorProperty, "LyricsBackgroundColor");
- base.Add(scrollView);
-
- lyricsLabel = new TextLabel()
- {
- WidthResizePolicy = ResizePolicyType.FillToParent,
- TextColor = Color.White,
- MultiLine = true,
- LineWrapMode = LineWrapMode.Word,
- PointSize = 25.0f,
- HorizontalAlignment = HorizontalAlignment.Center,
- };
- lyricsLabel.BindingContext = lyricsViewModel.lyricsModel;
- lyricsLabel.SetBinding(TextLabel.TextProperty, "Lyrics");
- scrollView.Add(lyricsLabel);
- }
- }
-}
+++ /dev/null
-using Tizen.NUI;
-using Tizen.Multimedia;
-using Tizen.NUI.Components;
-using Tizen.NUI.BaseComponents;
-using Tizen.NUI.Binding;
-using MusicPlayer.Common;
-using MusicPlayer.ViewModels;
-using MusicPlayer.Views.Utils;
-using System.Collections.Generic;
-
-namespace MusicPlayer.Views
-{
- class PlayerView : View
- {
- private enum PlayerViewState
- {
- AlbumArt,
- TrackList,
- }
- private const int LayoutPadding = 64;
- private const int IconSize = 48;
- private const int TopBarSize = 120;
- private const int ControlViewWidth = 640;
- private const int ControlViewHeight = 384;
- private const int ControlViewMargin = 315;
- private const int TitleLabelHeight = 48;
- private const int ArtistLabelHeight = 36;
- private const int TopBarButtonsY = (TopBarSize / 2 - IconSize / 2);
-
- private View playerBackgroundView;
- private View leftView;
- private View rightView;
- private View rightViewBackground;
- private Button backButton;
- private Button moreButton;
-
- private View controlsView;
- private View sliderView;
- private MultiStateButton playButton;
- private Button prevButton;
- private Button nextButton;
- private MultiStateButton shuffleButton;
- private MultiStateButton 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 MultiStateButton favouriteButton;
- private PlayingListView currentListView;
- private LyricsView lyricsView;
-
- private PlayerViewModel viewModel;
-
- private PlayerViewState viewState;
-
- public PlayerView(PlayerViewModel viewModel) : base()
- {
- this.viewModel = viewModel;
- BindingContext = viewModel.playerModel;
- StyleName = "AppBackground";
- WidthResizePolicy = ResizePolicyType.FillToParent;
- HeightResizePolicy = ResizePolicyType.FillToParent;
-
- AddPlayerBackground();
-
- viewState = PlayerViewState.AlbumArt;
-
- leftView = CreateLeftView();
- rightView = CreateRightView();
- AddRightViewBackground();
-
- AddTopButtons();
- AddControlView();
- AddControlElements();
- AddPlaybackSlider();
- AddListActionButtons();
- AddThumbnail();
- AddLyricsView();
- }
-
- private void AddPlayerBackground()
- {
- playerBackgroundView = new View();
- playerBackgroundView.Size2D = new Size2D(Window.Instance.WindowSize.Width, Window.Instance.WindowSize.Height);
- WidthResizePolicy = ResizePolicyType.FillToParent;
- HeightResizePolicy = ResizePolicyType.FillToParent;
- base.Add(playerBackgroundView);
- playerBackgroundView.BackgroundColor = Color.Transparent;
- playerBackgroundView.BindingContext = viewModel;
- playerBackgroundView.SetBinding(BackgroundProperty, "PlayerBackground");
- }
-
- 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.Transparent,
- 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 AddRightViewBackground()
- {
- rightViewBackground = new View();
- rightViewBackground.BackgroundColor = Color.Transparent;
- rightViewBackground.SizeWidth = Window.Instance.WindowSize.Width / 2;
- rightViewBackground.SizeHeight = Window.Instance.WindowSize.Height;
- rightViewBackground.WidthResizePolicy = ResizePolicyType.FillToParent;
- rightViewBackground.HeightResizePolicy = ResizePolicyType.FillToParent;
- rightView.Add(rightViewBackground);
- rightViewBackground.BindingContext = viewModel;
- rightViewBackground.SetBinding(BackgroundProperty, "PlayerBackground");
- rightViewBackground.Hide();
- }
-
- private void UpdatePlayerViewBackground(PlayerViewState state)
- {
- if (state == PlayerViewState.AlbumArt)
- {
- rightViewBackground.Hide();
- playerBackgroundView.Show();
- }
- else
- {
- playerBackgroundView.Hide();
- rightViewBackground.Show();
- }
- }
-
- private void AddTopButtons()
- {
- backButton = new Button("BackButton");
- backButton.ThemeChangeSensitive = true;
- backButton.Position2D = new Position2D(LayoutPadding, TopBarButtonsY);
- leftView.Add(backButton);
-
- moreButton = new Button("MoreButton");
- moreButton.ThemeChangeSensitive = true;
- moreButton.Position2D = new Position2D(Window.Instance.WindowSize.Width / 2 - LayoutPadding - IconSize, TopBarButtonsY);
- rightView.Add(moreButton);
- }
-
- private void AddControlView()
- {
- controlsView = new View()
- {
- BackgroundColor = Color.Transparent,
- Size2D = new Size2D(ControlViewWidth, ControlViewHeight),
- Position2D = new Position2D((Window.Instance.WindowSize.Width / 4 - ControlViewWidth / 2), TopBarSize + ControlViewMargin),
- };
- rightView.Add(controlsView);
- }
-
- private void AddTitleLabel()
- {
- titleLabel = new TextLabel("LabelText")
- {
- ThemeChangeSensitive = true,
- Size2D = new Size2D(ControlViewWidth, TitleLabelHeight),
- Position2D = new Position2D(0, 0),
- PixelSize = 36,
- FontFamily = "BreezeSans",
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center,
- Ellipsis = true,
- };
- titleLabel.SetBinding(TextLabel.TextProperty, "TrackName");
- controlsView.Add(titleLabel);
- }
-
- private void AddArtistLabel()
- {
- artistLabel = new TextLabel("LabelText")
- {
- ThemeChangeSensitive = true,
- Size2D = new Size2D(ControlViewWidth, ArtistLabelHeight),
- Position2D = new Position2D(0, 62),
- PixelSize = 28,
- FontFamily = "BreezeSans",
- HorizontalAlignment = HorizontalAlignment.Center,
- VerticalAlignment = VerticalAlignment.Center,
- Ellipsis = true,
- };
- artistLabel.SetBinding(TextLabel.TextProperty, "TrackArtist");
- controlsView.Add(artistLabel);
- }
-
- private void AddTextControlElements()
- {
- AddTitleLabel();
- AddArtistLabel();
- }
-
- private void AddShuffleButton()
- {
- shuffleButton = new MultiStateButton()
- {
- Size2D = new Size2D(IconSize, IconSize),
- Position2D = new Position2D(0, 196),
- IconResources = new Dictionary<ThemeType, Dictionary<string, StringSelector>>()
- {
- {
- ThemeType.Light,
- new Dictionary<string, StringSelector>()
- {
- {
- ShuffleMode.Off.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "light/shuffle_off.png",
- }
- },
- {
- ShuffleMode.On.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "light/shuffle_on.png",
- }
- },
- }
- },
- {
- ThemeType.Dark,
- new Dictionary<string, StringSelector>()
- {
- {
- ShuffleMode.Off.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "dark/shuffle_off.png",
- }
- },
- {
- ShuffleMode.On.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "dark/shuffle_on.png",
- }
- },
- }
- }
- },
- };
- shuffleButton.BindingContext = viewModel.playingListViewModel;
- shuffleButton.SetBinding(MultiStateButton.CustomStateProperty, "ShuffleButtonState");
- // TODO need to implement command instead
- shuffleButton.Clicked += (object sender, ClickedEventArgs e) =>
- {
- viewModel.ShuffleChanged();
- };
- controlsView.Add(shuffleButton);
- }
-
- private void AddPreviousButton()
- {
- prevButton = new Button("PrevButton");
- prevButton.ThemeChangeSensitive = true;
- // TODO need to implement command instead
- prevButton.Clicked += (object sender, ClickedEventArgs e) =>
- {
- viewModel.PrevButtonClicked();
- };
- prevButton.BindingContext = viewModel;
- prevButton.SetBinding(Button.IsEnabledProperty, "HasPreviousTrack");
- controlsView.Add(prevButton);
- }
-
- private void AddPlayButton()
- {
- playButton = new MultiStateButton()
- {
- Size2D = new Size2D(IconSize, IconSize),
- Position2D = new Position2D(296, 196),
- BackgroundColor = Color.Transparent,
- IconResources = new Dictionary<ThemeType, Dictionary<string, StringSelector>>()
- {
- {
- ThemeType.Light,
- new Dictionary<string, StringSelector>()
- {
- {
- "Play",
- new StringSelector()
- {
- Normal = Resources.GetImagePath() + "light/play.png",
- Pressed = Resources.GetImagePath() + "play_pressed.png",
- Disabled = Resources.GetImagePath() + "play_disabled.png",
- }
- },
- {
- "Pause",
- new StringSelector()
- {
- Normal = Resources.GetImagePath() + "light/pause.png",
- Pressed = Resources.GetImagePath() + "pause_pressed.png",
- Disabled = Resources.GetImagePath() + "pause_disabled.png",
- }
- },
- }
- },
- {
- ThemeType.Dark,
- new Dictionary<string, StringSelector>()
- {
- {
- "Play",
- new StringSelector()
- {
- Normal = Resources.GetImagePath() + "dark/play.png",
- Pressed = Resources.GetImagePath() + "play_pressed.png",
- Disabled = Resources.GetImagePath() + "play_disabled.png",
- }
- },
- {
- "Pause",
- new StringSelector()
- {
- Normal = Resources.GetImagePath() + "dark/pause.png",
- Pressed = Resources.GetImagePath() + "pause_pressed.png",
- Disabled = Resources.GetImagePath() + "pause_disabled.png",
- }
- },
- }
- }
- },
- };
- playButton.BindingContext = viewModel;
- playButton.SetBinding(MultiStateButton.CustomStateProperty, "PlayButtonState");
- controlsView.Add(playButton);
- // TODO need to implement command instead
- playButton.Clicked += (object sender, ClickedEventArgs e) =>
- {
- viewModel.PlayingStatusChanged();
- };
- }
-
- private void AddNextButton()
- {
- nextButton = new Button("NextButton");
- nextButton.ThemeChangeSensitive = true;
- // TODO need to implement command instead
- nextButton.Clicked += (object sender, ClickedEventArgs e) =>
- {
- viewModel.NextButtonClicked();
- };
- nextButton.BindingContext = viewModel;
- nextButton.SetBinding(Button.IsEnabledProperty, "HasNextTrack");
- controlsView.Add(nextButton);
- }
-
- private void AddRepeatButton()
- {
- repeatButton = new MultiStateButton()
- {
- Size2D = new Size2D(IconSize, IconSize),
- Position2D = new Position2D(592, 196),
- IconResources = new Dictionary<ThemeType, Dictionary<string, StringSelector>>()
- {
- {
- ThemeType.Light,
- new Dictionary<string, StringSelector>()
- {
- {
- RepeatMode.Off.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "light/repeat_off.png",
- }
- },
- {
- RepeatMode.RepeatOne.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "light/repeat_one.png",
- }
- },
- {
- RepeatMode.RepeatAll.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "light/repeat_all.png",
- }
- },
- }
- },
- {
- ThemeType.Dark,
- new Dictionary<string, StringSelector>()
- {
- {
- RepeatMode.Off.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "dark/repeat_off.png",
- }
- },
- {
- RepeatMode.RepeatOne.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "dark/repeat_one.png",
- }
- },
- {
- RepeatMode.RepeatAll.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "dark/repeat_all.png",
- }
- },
- }
- }
- },
- };
- repeatButton.BindingContext = viewModel.playingListViewModel;
- repeatButton.SetBinding(MultiStateButton.CustomStateProperty, "RepeatButtonState");
- controlsView.Add(repeatButton);
- // TODO need to implement command instead
- repeatButton.Clicked += (object sender, ClickedEventArgs e) =>
- {
- viewModel.RepeatChanged();
- };
- }
-
- private void AddButtonControlElements()
- {
- AddShuffleButton();
- AddPreviousButton();
- AddPlayButton();
- AddNextButton();
- AddRepeatButton();
- }
-
- private void AddLeftVolumeIcon()
- {
- leftVolumeIcon = new ImageView()
- {
- ThemeChangeSensitive = true,
- StyleName = "LeftVolume",
- };
- controlsView.Add(leftVolumeIcon);
- }
-
- private void AddRightVolumeIcon()
- {
- rightVolumeIcon = new ImageView()
- {
- ThemeChangeSensitive = true,
- StyleName = "RightVolume",
- };
- controlsView.Add(rightVolumeIcon);
- }
-
- private void AddVolumeSliderEventHandlers()
- {
- volumeSlider.SlidingStarted += (object sender, SliderSlidingStartedEventArgs e) =>
- {
- viewModel.VolumeChangeStarted();
- };
- volumeSlider.ValueChanged += (object sender, SliderValueChangedEventArgs e) =>
- {
- viewModel.VolumeLevelChanged((int)e.CurrentValue);
- };
- volumeSlider.SlidingFinished += (object sender, SliderSlidingFinishedEventArgs e) =>
- {
- viewModel.VolumeChangeFinished((int)e.CurrentValue);
- };
- }
-
- private void AddVolumeSlider()
- {
- volumeSlider = new Slider("Slider");
- volumeSlider.ThemeChangeSensitive = true;
- volumeSlider.Size2D = new Size2D(496, 48);
- volumeSlider.Position2D = new Position2D(72, 336);
- volumeSlider.ThumbSize = new Tizen.NUI.Size(36, 36);
- volumeSlider.Direction = Slider.DirectionType.Horizontal;
- volumeSlider.MinValue = 0;
- volumeSlider.MaxValue = AudioManager.VolumeController.MaxLevel[AudioVolumeType.Media];
- volumeSlider.CurrentValue = AudioManager.VolumeController.Level[AudioVolumeType.Media];
- controlsView.Add(volumeSlider);
- volumeSlider.BindingContext = viewModel;
- volumeSlider.SetBinding(Slider.CurrentValueProperty, "VolumeLevel");
- AddVolumeSliderEventHandlers();
- }
-
- private void AddVolumeSliderElements()
- {
- AddLeftVolumeIcon();
- AddRightVolumeIcon();
- AddVolumeSlider();
- }
-
- private void AddControlElements()
- {
- AddTextControlElements();
- AddButtonControlElements();
- AddVolumeSliderElements();
- }
-
- private void AddPlaybackSliderEventHandler()
- {
- playbackSlider.SlidingStarted += (object sender, SliderSlidingStartedEventArgs e) =>
- {
- viewModel.StopPlaybackTimer();
- };
- playbackSlider.ValueChanged += (object sender, SliderValueChangedEventArgs e) =>
- {
- viewModel.SetElapsedTime(e.CurrentValue);
- };
- playbackSlider.SlidingFinished += (object sender, SliderSlidingFinishedEventArgs e) =>
- {
- viewModel.UpdatePlayerPosition(e.CurrentValue);
- };
- }
-
- private void AddPlaybackSlider(View sliderView)
- {
- playbackSlider = new Slider("Slider")
- {
- ThemeChangeSensitive = true,
- MinValue = 0.0f,
- MaxValue = 1.0f,
- WidthResizePolicy = ResizePolicyType.FillToParent,
- SizeHeight = 44,
- ThumbSize = new Tizen.NUI.Size(36, 36),
- Direction = Slider.DirectionType.Horizontal,
- };
- playbackSlider.SetBinding(Slider.CurrentValueProperty, "ElapsedTime");
- sliderView.Add(playbackSlider);
- AddPlaybackSliderEventHandler();
- }
-
- private void AddCurrentTimeLabel(View sliderView)
- {
- currentTime = new TextLabel("LabelText")
- {
- ThemeChangeSensitive = true,
- Size2D = new Size2D(400, 32),
- Position2D = new Position2D(0, 48),
- PixelSize = 24,
- FontFamily = "BreezeSans",
- Text = "00::00:00",
- HorizontalAlignment = HorizontalAlignment.Begin,
- };
- currentTime.SetBinding(TextLabel.TextProperty, "PlayingTime");
- sliderView.Add(currentTime);
- }
-
- private void AddTotalTimeLabel(View sliderView)
- {
- totalTime = new TextLabel("LabelText")
- {
- ThemeChangeSensitive = true,
- Size2D = new Size2D(400, 32),
- Position2D = new Position2D(1792 - 400, 48),
- PixelSize = 24,
- FontFamily = "BreezeSans",
- HorizontalAlignment = HorizontalAlignment.End,
- Text = "59:59:59",
- };
- totalTime.SetBinding(TextLabel.TextProperty, "TrackLength");
- sliderView.Add(totalTime);
- }
-
- private void AddPlaybackSlider()
- {
- sliderView = new View()
- {
- Size2D = new Size2D(1792, 80),
- Position2D = new Position2D(64, 950),
- BackgroundColor = Color.Transparent,
- };
- Add(sliderView);
-
- AddPlaybackSlider(sliderView);
- AddCurrentTimeLabel(sliderView);
- AddTotalTimeLabel(sliderView);
- UpdatePlaybackSliderPosition(viewState);
- }
-
- private void UpdatePlaybackSliderPosition(PlayerViewState state)
- {
- if(state == PlayerViewState.AlbumArt)
- {
- sliderView.Size2D = new Size2D(1792, 80);
- sliderView.Position2D = new Position2D(64, 950);
- currentTime.Size2D = new Size2D(400, 32);
- currentTime.Position2D = new Position2D(0, 48);
- totalTime.Size2D = new Size2D(400, 32);
- totalTime.Position2D = new Position2D(1392, 48);
- }
- else
- {
- sliderView.Size2D = new Size2D(640, 80);
- sliderView.Position2D = new Position2D(1056, 950);
- currentTime.Size2D = new Size2D(180, 32);
- currentTime.Position2D = new Position2D(0, 48);
- totalTime.Size2D = new Size2D(180, 32);
- totalTime.Position2D = new Position2D(460, 48);
- }
- }
-
- private void AddListActionButtons()
- {
- View actionButtonView = new View()
- {
- Size2D = new Size2D(224, 48),
- Position2D = new Position2D((Window.Instance.WindowSize.Width / 2 - 224 - LayoutPadding), 120),
- BackgroundColor = Color.Transparent,
- };
- rightView.Add(actionButtonView);
-
- listButton = new Button("ListButton")
- {
- ThemeChangeSensitive = true,
- };
- listButton.Clicked += (object sender, ClickedEventArgs e) =>
- {
- if(viewState == PlayerViewState.AlbumArt)
- {
- Tizen.Log.Debug(AppConstants.LogTag, "Adding Playing list view");
- viewState = PlayerViewState.TrackList;
- RemoveLyricsView();
- AddPlayingListView();
- thumb.Show();
- }
- else
- {
- Tizen.Log.Debug(AppConstants.LogTag, "Adding album art view");
- viewState = PlayerViewState.AlbumArt;
- RemovePlayingListView();
- AddLyricsView();
- thumb.Hide();
- }
- UpdatePlaybackSliderPosition(viewState);
- UpdatePlayerViewBackground(viewState);
- };
- actionButtonView.Add(listButton);
-
- playlistButton = new Button("PlaylistButton")
- {
- ThemeChangeSensitive = true,
- };
- actionButtonView.Add(playlistButton);
-
- favouriteButton = new MultiStateButton()
- {
- Size2D = new Size2D(IconSize, IconSize),
- Position2D = new Position2D(176, 0),
- IconResources = new Dictionary<ThemeType, Dictionary<string, StringSelector>>()
- {
- {
- ThemeType.Light,
- new Dictionary<string, StringSelector>()
- {
- {
- Favourite.Off.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "light/favourite_off.png",
- }
- },
- {
- Favourite.On.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "light/favourite_on.png",
- }
- },
- }
- },
- {
- ThemeType.Dark,
- new Dictionary<string, StringSelector>()
- {
- {
- Favourite.Off.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "dark/favourite_off.png",
- }
- },
- {
- Favourite.On.ToString(),
- new StringSelector()
- {
- All = Resources.GetImagePath() + "dark/favourite_on.png",
- }
- },
- }
- }
- },
- };
- favouriteButton.CusotmState = Favourite.Off.ToString();
- 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);
- thumb.Hide();
- }
-
- 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);
- currentListView.Show();
- }
-
- private void RemovePlayingListView()
- {
- if(currentListView == null)
- {
- Tizen.Log.Error(AppConstants.LogTag, "current listview is null, can't remove it");
- return;
- }
- leftView.Remove(currentListView);
- currentListView.Hide();
- }
-
- 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);
- lyricsView.Show();
- }
-
- private void RemoveLyricsView()
- {
- if(lyricsView == null)
- {
- Tizen.Log.Error(AppConstants.LogTag, "lyricsview is null, can't remove it");
- return;
- }
- leftView.Remove(lyricsView);
- lyricsView.Hide();
- }
- }
-}
+++ /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(() =>
- {
- ListItemLayout layout = new ListItemLayout(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;
- }
- }
-}
+++ /dev/null
-using MusicPlayer.ViewModels;\r
-using Tizen.NUI.Components;\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
- class TrackView : BaseContentView\r
- {\r
- private TrackViewModel viewModel;\r
- private TextLabel trackCountLabel;\r
- private Button playAllIcon; // TODO need to implement playall feature\r
- private Button addToPlaylistIcon; // TODO need to implement playlist manager\r
- public TrackView(TrackViewModel viewModel)\r
- {\r
- this.viewModel = viewModel;\r
- collectionView.ItemsSource = viewModel.ListViewModel;\r
- collectionView.ItemTemplate = new DataTemplate(() =>\r
- {\r
- ListItemLayout layout = new ListItemLayout();\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
- collectionView.ScrollingDirection = ScrollableBase.Direction.Vertical;\r
- collectionView.WidthSpecification = LayoutParamPolicies.WrapContent;\r
- collectionView.SelectionMode = ItemSelectionMode.Single;\r
- collectionView.SelectionChanged += OnTrackSelection;\r
-\r
- trackCountLabel = new TextLabel("LabelText")\r
- {\r
- ThemeChangeSensitive = true,\r
- PixelSize = 28,\r
- Text = "TRACK COUNT",\r
- VerticalAlignment = VerticalAlignment.Center,\r
- FontFamily = "BreezeSans",\r
- };\r
- trackCountLabel.BindingContext = viewModel;\r
- titleView.Add(trackCountLabel);\r
- trackCountLabel.SetBinding(TextLabel.TextProperty, "TrackCount");\r
- RelativeLayout.SetLeftTarget(trackCountLabel, titleView);\r
- RelativeLayout.SetLeftRelativeOffset(trackCountLabel, 1.0f);\r
- RelativeLayout.SetRightRelativeOffset(trackCountLabel, 0.0f);\r
- RelativeLayout.SetFillHorizontal(trackCountLabel, true);\r
-\r
- playAllIcon = new Button("PlayAll")\r
- {\r
- ThemeChangeSensitive = true,\r
- };\r
- titleView.Add(playAllIcon);\r
- RelativeLayout.SetLeftRelativeOffset(playAllIcon, 1.0f);\r
- RelativeLayout.SetRightRelativeOffset(playAllIcon, 1.0f);\r
- RelativeLayout.SetHorizontalAlignment(playAllIcon, RelativeLayout.Alignment.End);\r
-\r
- addToPlaylistIcon = new Button("PlaylistAdd")\r
- {\r
- ThemeChangeSensitive = true,\r
- Margin = new Extents(32, 40, 0, 0),\r
- };\r
- titleView.Add(addToPlaylistIcon);\r
- RelativeLayout.SetRightTarget(addToPlaylistIcon, playAllIcon);\r
- RelativeLayout.SetRightRelativeOffset(addToPlaylistIcon, 0.0f);\r
- RelativeLayout.SetHorizontalAlignment(addToPlaylistIcon, RelativeLayout.Alignment.End);\r
- }\r
-\r
- private void OnTrackSelection(object sender, SelectionChangedEventArgs e)\r
- {\r
- //TODO\r
- }\r
-\r
- protected override void OnThemeChanged(object sender, ThemeChangedEventArgs e)\r
- {\r
- base.OnThemeChanged(sender, e);\r
- }\r
- protected override void Dispose(DisposeTypes type)\r
- {\r
- if(Disposed)\r
- {\r
- return;\r
- }\r
- if(type == DisposeTypes.Explicit)\r
- {\r
- titleView.Remove(trackCountLabel);\r
- trackCountLabel.Dispose();\r
- trackCountLabel = null;\r
-\r
- // TODO Uncomment after implementation is completed\r
- titleView.Remove(playAllIcon);\r
- playAllIcon.Dispose();\r
- playAllIcon = null;\r
-\r
- //titleView.Remove(addToPlaylistIcon);\r
- addToPlaylistIcon.Dispose();\r
- addToPlaylistIcon = null;\r
- }\r
- base.Dispose(type);\r
- }\r
- }\r
-}\r
+++ /dev/null
-using System.Collections.Generic;
-using Tizen.NUI;
-using Tizen.NUI.Binding;
-using Tizen.NUI.Components;
-using MusicPlayer.Common;
-
-namespace MusicPlayer.Views.Utils
-{
- class MultiStateButton: Button
- {
- public static readonly BindableProperty CustomStateProperty = BindableProperty.Create(nameof(CusotmState), typeof(string), typeof(MultiStateButton), null, propertyChanged: (bindable, oldValue, newValue) =>
- {
- var instance = (MultiStateButton)bindable;
- if (newValue != null)
- {
- string newCustomState = (string)newValue;
- instance.UpdateCustomState(newCustomState);
- }
- },
- defaultValueCreator: (bindable) =>
- {
- var instance = (MultiStateButton)bindable;
- return instance.customState;
- });
-
- public MultiStateButton() : base()
- {
- ThemeChangeSensitive = true;
- EnableControlState = true;
- BackgroundColor = Color.Transparent;
- }
-
- private Dictionary<ThemeType, Dictionary<string, StringSelector>> iconResources;
-
- public Dictionary<ThemeType, Dictionary<string, StringSelector>> IconResources
- {
- get => iconResources;
- set => iconResources = value;
- }
-
- private string customState;
- public string CusotmState
- {
- get => (string)GetValue(CustomStateProperty);
- set => SetValue(CustomStateProperty, value);
- }
-
- private void UpdateCustomState(string customStatevalue)
- {
- if (IconResources == null)
- {
- Tizen.Log.Error(AppConstants.LogTag, "ThemesIconState needs to be set first");
- return;
- }
- ThemeType type = GetCurrentThemeType();
- if (iconResources.ContainsKey(type) == false)
- {
- Tizen.Log.Error(AppConstants.LogTag, "Theme state doesn't exists: " + type.ToString());
- return;
- }
- Dictionary<string, StringSelector> stateResource = iconResources[type];
- if (stateResource.ContainsKey(customStatevalue) == false)
- {
- Tizen.Log.Error(AppConstants.LogTag, "Invalid state: " + customStatevalue);
- return;
- }
- IconURLSelector = stateResource[customStatevalue];
- customState = customStatevalue;
- }
-
- private ThemeType GetCurrentThemeType()
- {
- ThemeType type;
- string id = ThemeManager.PlatformThemeId;
- if (id.Equals(AppConstants.LightPlatformThemeId))
- {
- type = ThemeType.Light;
- }
- else
- {
- type = ThemeType.Dark;
- }
- return type;
- }
-
- protected override void OnThemeChanged(object sender, ThemeChangedEventArgs e)
- {
- base.OnThemeChanged(sender, e);
- UpdateCustomState(CusotmState);
- }
- }
-}
-
+++ /dev/null
-using System;\r
-using Tizen.NUI;\r
-using Tizen.NUI.BaseComponents;\r
-\r
-namespace MusicPlayer\r
-{\r
- public partial class XamlPage : View\r
- {\r
- public XamlPage()\r
- {\r
- InitializeComponent();\r
- }\r
- }\r
-}\r
+++ /dev/null
-<Project Sdk="Microsoft.NET.Sdk">\r
-\r
- <PropertyGroup>\r
- <OutputType>Exe</OutputType>\r
- <TargetFramework>netcoreapp3.1</TargetFramework>\r
- <TargetFrameworkIdentifier>Tizen</TargetFrameworkIdentifier>\r
- <AssemblyName>MusicPlayer</AssemblyName>\r
- </PropertyGroup>\r
-\r
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
- <DebugType>portable</DebugType>\r
- </PropertyGroup>\r
- <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
- <DebugType>None</DebugType>\r
- </PropertyGroup>\r
-\r
- <ItemGroup>\r
- <Folder Include="lib\" />\r
- <Folder Include="res\images\" />\r
- </ItemGroup>\r
- \r
- <ItemGroup>\r
- <EmbeddedResource Include="res\layout\XamlPage.xaml">\r
- <Generator>MSBuild:Compile</Generator>\r
- </EmbeddedResource>\r
- </ItemGroup>\r
- \r
- <ItemGroup>\r
- <PackageReference Include="Tizen.NET" Version="9.0.0.16249" />\r
- <PackageReference Include="Tizen.NET.Sdk" Version="1.0.1" />\r
- <PackageReference Include="Tizen.NUI.XamlBuild" Version="1.0.11" />\r
- </ItemGroup>\r
-\r
-</Project>\r
--- /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";
+
+ // string literals
+ public const string TimeFormat = @"mm\:ss";
+ public const string LightPlatformThemeId = "org.tizen.default-light-theme";
+ public const string DarkPlatformThemeId = "org.tizen.default-dark-theme";
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace MusicPlayer.Common
+{
+ public enum ThemeType
+ {
+ Light,
+ Dark
+ };
+ public enum RepeatMode
+ {
+ Off,
+ RepeatOne,
+ RepeatAll,
+ }
+
+ public enum PlayingStatus
+ {
+ None,
+ Playing,
+ Paused,
+ Stopped,
+ }
+
+ public enum ShuffleMode
+ {
+ On,
+ Off,
+ }
+
+ public enum Favourite
+ {
+ On,
+ Off,
+ }
+
+ public enum EventType
+ {
+ Error,
+ PlaybackCompleted,
+ }
+
+ public class PlayerEventArgs : EventArgs
+ {
+ private readonly EventType type;
+ private readonly string description;
+
+ internal PlayerEventArgs(EventType eventType, string desc)
+ {
+ type = eventType;
+ description = desc;
+ }
+
+ public EventType Type
+ {
+ get => type;
+ }
+ public string Description
+ {
+ get => description;
+ }
+ }
+}
--- /dev/null
+using System;\r
+using System.Collections.Generic;\r
+using System.Text;\r
+using System.ComponentModel;\r
+using System.Runtime.CompilerServices;\r
+\r
+namespace MusicPlayer.Common\r
+{\r
+ class PropertyNotifier : INotifyPropertyChanged\r
+ {\r
+ public event PropertyChangedEventHandler PropertyChanged;\r
+\r
+ protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)\r
+ {\r
+ if (Equals(storage, value))\r
+ {\r
+ return false;\r
+ }\r
+\r
+ storage = value;\r
+ OnPropertyChanged(propertyName);\r
+ return true;\r
+ }\r
+\r
+ protected void OnPropertyChanged([CallerMemberName] string propertyName = null)\r
+ {\r
+ PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));\r
+ }\r
+ }\r
+}\r
--- /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/";
+ }
+
+ public static string GetThemePath()
+ {
+ return Tizen.Applications.Application.Current.DirectoryInfo.Resource + "themes/";
+ }
+ }
+}
--- /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);
+
+ }
+}
--- /dev/null
+using System.Threading;
+using System.Threading.Tasks;
+using Tizen.NUI;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Core
+{
+ static class ColorExtractor
+ {
+ public static async Task<Palette> GetPaletteAsync(string imagePath)
+ {
+ Tizen.Log.Debug(AppConstants.LogTag, "Main Thread Id: " + Thread.CurrentThread.ManagedThreadId);
+ return await Task.Run(() => GeneratePalette(imagePath));
+ }
+
+ private static Palette GeneratePalette(string imagePath)
+ {
+ PixelBuffer pixelBuffer = ImageLoading.LoadImageFromFile(imagePath);
+ if(pixelBuffer == null)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "Pixel buffer is null");
+ return null;
+ }
+
+ Palette palette = null;
+
+ try
+ {
+ palette = Palette.Generate(pixelBuffer);
+ }
+ catch(System.ArgumentNullException e)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "ArgumentNullException: " + e.Message);
+ }
+
+ return palette;
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Threading.Tasks;
+using Tizen.Multimedia;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Core
+{
+ public class MusicPlayer
+ {
+ private readonly Player player = new Player();
+
+ public MusicPlayer()
+ {
+ player.ErrorOccurred += OnErrorOccurred;
+ player.PlaybackCompleted += OnPlayBackCompleted;
+ }
+
+ public event EventHandler<PlayerEventArgs> PlayerEvent;
+
+ private enum PlayerValidationState
+ {
+ Start,
+ Stop,
+ Pause,
+ Resume,
+ Position,
+ }
+
+ public PlayerState State
+ {
+ get => player.State;
+ }
+
+ public void SetSource(string uri)
+ {
+ if(State != PlayerState.Idle)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "Player is not in idle state, can't set source");
+ return;
+ }
+ try
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "setting uri: " + uri);
+ player.SetSource(new MediaUriSource(uri));
+ }
+ catch (UnauthorizedAccessException ex)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "UnauthorizedAccessException: " + ex.Message);
+ }
+ catch (ObjectDisposedException ex)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "ObjectDisposed: " + ex.Message);
+ }
+ catch (InvalidOperationException ex)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "InvalidOperationException: " + ex.Message);
+ }
+ }
+
+ public async Task PreparePlayer()
+ {
+ try
+ {
+ await player.PrepareAsync();
+ }
+ catch (ObjectDisposedException ex)
+ {
+ Tizen.Log.Error("MusicPlayer", "ObjectDisposedException: "+ex.Message);
+ }
+ catch (InvalidOperationException ex)
+ {
+ Tizen.Log.Error("MusicPlayer", "InvalidOperationException: "+ex.Message);
+ }
+ finally // TODO do we really need this
+ {
+ //DisposePlayer();
+ }
+ }
+
+ public void Play()
+ {
+ if (ValidatePlayerState(PlayerValidationState.Start))
+ {
+ player.Start();
+ }
+ else
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "Invalid player state for playing: " + player.State.ToString());
+ }
+ }
+
+ public void Pause()
+ {
+ if(ValidatePlayerState(PlayerValidationState.Pause))
+ {
+ player.Pause();
+ }
+ }
+
+ public void Resume()
+ {
+ if (ValidatePlayerState(PlayerValidationState.Resume))
+ {
+ player.Start();
+ }
+ }
+
+ public void Stop()
+ {
+ if(ValidatePlayerState(PlayerValidationState.Stop))
+ {
+ player.Stop();
+ }
+ }
+
+ public int GetPosition()
+ {
+ if (ValidatePlayerState(PlayerValidationState.Position))
+ {
+ return player.GetPlayPosition();
+ }
+ else
+ {
+ return 0;
+ }
+ }
+
+ public void Unprepare()
+ {
+ player.Unprepare();
+ }
+
+ public void DisposePlayer()
+ {
+ player.Dispose();
+ }
+
+ public async Task SetPosition(int pos)
+ {
+ await player.SetPlayPositionAsync(pos, false);
+ }
+
+ private bool ValidatePlayerState(PlayerValidationState state)
+ {
+ if(state == PlayerValidationState.Start || state == PlayerValidationState.Position)
+ {
+ return (State == PlayerState.Ready || State == PlayerState.Playing || State == PlayerState.Paused);
+ }
+ else if(state == PlayerValidationState.Pause)
+ {
+ return (State == PlayerState.Playing);
+ }
+ else if(state == PlayerValidationState.Resume)
+ {
+ return (State == PlayerState.Paused);
+ }
+ else if(state == PlayerValidationState.Stop)
+ {
+ return (State == PlayerState.Paused || State == PlayerState.Playing);
+ }
+ else
+ {
+ return false;
+ }
+ }
+
+ private void OnPlayBackCompleted(object sender, EventArgs e)
+ {
+ PlayerEvent?.Invoke(this, new PlayerEventArgs(EventType.PlaybackCompleted, "Playback Completed"));
+ Tizen.Log.Error(AppConstants.LogTag, "Playback completed");
+ }
+
+ // TODO this event is called on a differnt thread..need to handle it
+ private void OnErrorOccurred(object sender, PlayerErrorOccurredEventArgs e)
+ {
+ PlayerEvent.Invoke(this, new PlayerEventArgs(EventType.Error, e.Error.ToString()));
+ Tizen.Log.Error(AppConstants.LogTag, "Error Occurred: " + e.Error.ToString());
+ }
+ }
+}
--- /dev/null
+using System;
+using Tizen.Multimedia;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Core
+{
+ class PlayerController
+ {
+ private readonly MusicPlayer musicPlayer;
+ private static PlayerController instance = instance ??= new PlayerController();
+
+ private PlayerController()
+ {
+ musicPlayer = new MusicPlayer();
+ musicPlayer.PlayerEvent += OnPlayerEvent;
+ }
+
+ public event EventHandler<PlayerEventArgs> PlayerEventOccurred;
+
+ public static PlayerController Instance
+ {
+ get => instance;
+ }
+
+ private string uri;
+
+ public string Uri
+ {
+ get => uri;
+ set => uri = value;
+ }
+
+ public async void Play()
+ {
+ if(Uri == null)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "Please set the uri to play");
+ return;
+ }
+ Tizen.Log.Error(AppConstants.LogTag, "Current player state: "+musicPlayer.State.ToString());
+ if (musicPlayer.State == PlayerState.Paused || musicPlayer.State == PlayerState.Playing)
+ {
+ musicPlayer.Stop();
+ }
+ if(musicPlayer.State == PlayerState.Ready)
+ {
+ musicPlayer.Unprepare();
+ }
+ musicPlayer.SetSource(Uri);
+ if(musicPlayer.State == PlayerState.Idle)
+ {
+ await musicPlayer.PreparePlayer();
+ }
+ musicPlayer.Play();
+ }
+
+ public void Destroy()
+ {
+ musicPlayer?.DisposePlayer();
+ }
+
+ public void SetSource()
+ {
+ musicPlayer.SetSource(Uri);
+ }
+
+ public void Pause()
+ {
+ musicPlayer.Pause();
+ }
+
+ public void Resume()
+ {
+ if (musicPlayer.State == PlayerState.Paused)
+ {
+ musicPlayer.Resume();
+ }
+ else
+ {
+ Play();
+ }
+ }
+
+ public void Stop()
+ {
+ musicPlayer.Stop();
+ }
+
+ public int GetPosition()
+ {
+ return musicPlayer.GetPosition();
+ }
+
+ public async void SetPosition(int pos)
+ {
+ await musicPlayer.SetPosition(pos);
+ }
+
+ private void OnPlayerEvent(object sender, PlayerEventArgs e)
+ {
+ PlayerEventOccurred?.Invoke(this, e);
+ }
+ }
+}
--- /dev/null
+using System;\r
+using System.Collections.Specialized;\r
+using Tizen.Content.MediaContent;\r
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.Media\r
+{\r
+ public static partial class Contents\r
+ {\r
+ public static OrderedDictionary GetAlbumList()\r
+ {\r
+ OrderedDictionary albumList = new OrderedDictionary();\r
+\r
+ SelectArguments albumSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, AlbumColumns.Name + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<Album> dataReader = albumInfo.Select(albumSelectArguments);\r
+\r
+ while (dataReader.Read())\r
+ {\r
+ Album info = dataReader.Current;\r
+ SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<MediaInfo> albumDataReader = albumInfo.SelectMember(info.Id, audioSelectArguments);\r
+ if (albumDataReader.Read())\r
+ albumList.Add(info.Id, info);\r
+ }\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Total album retrived from database: " + albumList.Count);\r
+ dataReader.Dispose();\r
+ return albumList;\r
+ }\r
+\r
+ public static int GetAlbumMemberCount(int albumId)\r
+ {\r
+ return albumInfo.CountMember(albumId);\r
+ }\r
+\r
+ public static OrderedDictionary GetAlbumMemberList(int albumId)\r
+ {\r
+ OrderedDictionary mediaList = new OrderedDictionary();\r
+ SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<MediaInfo> dataReader = albumInfo.SelectMember(albumId, audioSelectArguments);\r
+\r
+ while (dataReader.Read())\r
+ {\r
+ MediaInfo info = dataReader.Current;\r
+ mediaList.Add(info.Id, info);\r
+ }\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Total track retrived from currentAlbum: " + mediaList.Count);\r
+ dataReader.Dispose();\r
+ return mediaList;\r
+ }\r
+\r
+ public static string GetAlbumArtPath(int albumId)\r
+ {\r
+ string path = "";\r
+ SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<MediaInfo> dataReader = albumInfo.SelectMember(albumId, audioSelectArguments);\r
+ while (dataReader.Read())\r
+ {\r
+ MediaInfo info = dataReader.Current;\r
+ if (!string.IsNullOrEmpty(info.ThumbnailPath))\r
+ path = info.ThumbnailPath;\r
+ }\r
+ dataReader.Dispose();\r
+ return path;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System.Collections.Specialized;\r
+using System.Collections.Generic;\r
+using Tizen.Content.MediaContent;\r
+using System;\r
+using MusicPlayer.Common;\r
+\r
+\r
+namespace MusicPlayer.Media\r
+{\r
+ public static partial class Contents\r
+ {\r
+ public static List<string> GetArtistList()\r
+ {\r
+ List<string> artistList = new List<string>();\r
+\r
+ SelectArguments artistSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Artist + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<string> dataReader = mediaInfo.SelectGroupBy(MediaInfoColumnKey.Artist, artistSelectArguments);\r
+\r
+ while (dataReader.Read())\r
+ {\r
+ string info = (string)dataReader.Current;\r
+ artistList.Add(info);\r
+ }\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Total artists retrived from database: " + artistList.Count);\r
+ dataReader.Dispose();\r
+ return artistList;\r
+ }\r
+\r
+ public static OrderedDictionary GetAlbumListForArtist(string artistName)\r
+ {\r
+ OrderedDictionary albumList = new OrderedDictionary();\r
+ string expression = MEDIA_STORAGE_TYPE_QUERY + "AND " + AlbumColumns.Artist + "=\"" + artistName + "\"";\r
+ SelectArguments albumSelectArguments = CreateSelectArgument(expression, AlbumColumns.Name + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<Album> dataReader = albumInfo.Select(albumSelectArguments);\r
+\r
+ while (dataReader.Read())\r
+ {\r
+ Album info = dataReader.Current;\r
+ SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<MediaInfo> albumDataReader = albumInfo.SelectMember(info.Id, audioSelectArguments);\r
+ if(albumDataReader.Read())\r
+ albumList.Add(info.Id, info);\r
+ }\r
+ dataReader.Dispose();\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Total Albums retrived from Artist: " + albumList.Count);\r
+ return albumList;\r
+ }\r
+\r
+ public static OrderedDictionary GetTrackListForArtist(string artistName)\r
+ {\r
+ OrderedDictionary mediaList = new OrderedDictionary();\r
+ string expression = MEDIA_STORAGE_TYPE_QUERY + "AND " + AlbumColumns.Artist + "=\"" + artistName + "\"";\r
+ SelectArguments albumSelectArguments = CreateSelectArgument(expression, AlbumColumns.Name + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<Album> dataReader = albumInfo.Select(albumSelectArguments);\r
+\r
+ while (dataReader.Read())\r
+ {\r
+ Album info = dataReader.Current;\r
+ SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<MediaInfo> albumDataReader = albumInfo.SelectMember(info.Id, audioSelectArguments);\r
+\r
+ while (albumDataReader.Read())\r
+ {\r
+ MediaInfo mediaInfo = albumDataReader.Current;\r
+ mediaList.Add(mediaInfo.Id, mediaInfo);\r
+ }\r
+ albumDataReader.Dispose();\r
+ }\r
+ dataReader.Dispose();\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Total track retrived from Artist: " + mediaList.Count);\r
+ return mediaList;\r
+ }\r
+\r
+ public static string GetAlbumArtPathForArtist(string artistName)\r
+ {\r
+ string expression = MEDIA_STORAGE_TYPE_QUERY + "AND " + AlbumColumns.Artist + "=\"" + artistName + "\"";\r
+ SelectArguments albumSelectArguments = CreateSelectArgument(expression, AlbumColumns.Name + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<Album> dataReader = albumInfo.Select(albumSelectArguments);\r
+ string albumArtPath = "";\r
+\r
+ while (dataReader.Read())\r
+ {\r
+ Album info = dataReader.Current;\r
+ string path = "";\r
+ if (!string.IsNullOrEmpty(info.AlbumArtPath))\r
+ path = info.AlbumArtPath;\r
+ else\r
+ path = GetAlbumArtPath(info.Id);\r
+ if (!string.IsNullOrEmpty(path))\r
+ albumArtPath = path;\r
+ }\r
+ dataReader.Dispose();\r
+ return albumArtPath;\r
+ }\r
+\r
+ public static int GetAlbumCountForArtist(string artistName)\r
+ {\r
+ string expression = MEDIA_STORAGE_TYPE_QUERY + "AND " + AlbumColumns.Artist + "=\"" + artistName+"\"";\r
+ int count = 0;\r
+\r
+ SelectArguments albumSelectArguments = CreateSelectArgument(expression, AlbumColumns.Name + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<Album> dataReader = albumInfo.Select(albumSelectArguments);\r
+\r
+ while (dataReader.Read())\r
+ {\r
+ Album info = dataReader.Current;\r
+ SelectArguments audioSelectArguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<MediaInfo> albumDataReader = albumInfo.SelectMember(info.Id, audioSelectArguments);\r
+ if (albumDataReader.Read())\r
+ count++;\r
+ }\r
+ dataReader.Dispose();\r
+ return count;\r
+ }\r
+\r
+ public static int GetMediaCountForArtist(string artistName)\r
+ {\r
+ string expression = MEDIA_STORAGE_TYPE_QUERY + "AND " + MediaInfoColumns.Artist + "=\"" + artistName+"\"";\r
+ CountArguments audioCountArguments = CreateCountArgument(expression);\r
+ int count = 0;\r
+ try\r
+ {\r
+ count = mediaInfo.CountMedia(audioCountArguments);\r
+ }\r
+ catch (ObjectDisposedException ex)\r
+ {\r
+ Tizen.Log.Error(AppConstants.LogTag, "ObjectDisposedException: " + ex.Message);\r
+ }\r
+ catch (InvalidOperationException ex)\r
+ {\r
+ Tizen.Log.Error(AppConstants.LogTag, "InvalidOperationException: " + ex.Message);\r
+ }\r
+ catch (MediaDatabaseException ex)\r
+ {\r
+ Tizen.Log.Error(AppConstants.LogTag, "MediaDatabaseException: " + ex.Message);\r
+ }\r
+ catch (Exception ex)\r
+ {\r
+ Tizen.Log.Error(AppConstants.LogTag, "Unknown Exception: " + ex.Message);\r
+ }\r
+\r
+ return count;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System;\r
+using Tizen.Content.MediaContent;\r
+\r
+namespace MusicPlayer.Media\r
+{\r
+ public class MusicItemUpdateEventArgs : EventArgs\r
+ {\r
+ internal MusicItemUpdateEventArgs(int pid,\r
+ OperationType operationType, MediaType mediaType, string id, string path, string mimeType)\r
+ {\r
+ ProcessId = pid;\r
+ OperationType = operationType;\r
+ Id = id;\r
+ Path = path;\r
+ MediaType = mediaType;\r
+ MimeType = mimeType;\r
+ }\r
+ public int ProcessId { get; }\r
+\r
+ public OperationType OperationType { get; }\r
+\r
+ public string Id { get; }\r
+\r
+ public string Path { get; }\r
+\r
+ public MediaType MediaType { get; }\r
+\r
+ public string MimeType { get; }\r
+ }\r
+\r
+ public class MusicDBUpdateEventArgs : EventArgs\r
+ {\r
+ internal MusicDBUpdateEventArgs(OperationType operationType, string id, string path)\r
+ {\r
+ OperationType = operationType;\r
+ Id = id;\r
+ Path = path;\r
+ }\r
+\r
+ public OperationType OperationType { get; }\r
+\r
+ public string Id { get; }\r
+\r
+ public string Path { get; }\r
+ }\r
+\r
+ public static partial class Contents\r
+ {\r
+ private static Database database;\r
+ private static MediaInfoCommand mediaInfo;\r
+ private static AlbumCommand albumInfo;\r
+ private static PlaylistCommand playlistInfo;\r
+ private const string MEDIA_STORAGE_TYPE_QUERY = " (( MEDIA_STORAGE_TYPE IS NOT 101 ) AND (MEDIA_TYPE = 3)) ";\r
+ private const string MEDIA_SORT_ORDER_ASC = " COLLATE NOCASE ASC ";\r
+\r
+ public static event EventHandler<MusicItemUpdateEventArgs> MusicItemUpdate;\r
+ public static event EventHandler<MusicDBUpdateEventArgs> MusicDBUpdate;\r
+\r
+ static Contents()\r
+ {\r
+ database = new Database();\r
+ mediaInfo = new MediaInfoCommand(database.MediaDatabase);\r
+ albumInfo = new AlbumCommand(database.MediaDatabase);\r
+ playlistInfo = new PlaylistCommand(database.MediaDatabase);\r
+ MediaDatabase.MediaInfoUpdated += OnMediaDatabaseItemUpdate;\r
+ MediaDatabase.FolderUpdated += OnMediaDatabaseFolderUpdate;\r
+ }\r
+\r
+ private static void OnMediaDatabaseItemUpdate(object sender, MediaInfoUpdatedEventArgs e)\r
+ {\r
+ if(e.MediaType == MediaType.Music)\r
+ {\r
+ MusicItemUpdateEventArgs item = new MusicItemUpdateEventArgs(e.ProcessId, e.OperationType, e.MediaType,\r
+ e.Id, e.Path, e.MimeType);\r
+ MusicItemUpdate?.Invoke(null, item);\r
+ }\r
+ }\r
+\r
+ private static void OnMediaDatabaseFolderUpdate(object sender, FolderUpdatedEventArgs e)\r
+ {\r
+ MusicDBUpdateEventArgs item = new MusicDBUpdateEventArgs(e.OperationType, e.Id, e.Path);\r
+ MusicDBUpdate?.Invoke(null, item);\r
+ }\r
+\r
+ private static SelectArguments CreateSelectArgument(string filterExpression, string sortOrder)\r
+ {\r
+ SelectArguments arguments = new SelectArguments();\r
+ arguments.FilterExpression = filterExpression;\r
+ arguments.SortOrder = sortOrder;\r
+ return arguments;\r
+ }\r
+\r
+ private static CountArguments CreateCountArgument(string filterExpression)\r
+ {\r
+ CountArguments arguments = new CountArguments();\r
+ arguments.FilterExpression = filterExpression;\r
+ return arguments;\r
+ }\r
+\r
+ public static void Dispose()\r
+ {\r
+ database.Dispose();\r
+ }\r
+ }\r
+\r
+}
\ No newline at end of file
--- /dev/null
+using System;\r
+using Tizen.Content.MediaContent;\r
+\r
+namespace MusicPlayer.Media\r
+{\r
+ class Database : IDisposable\r
+ {\r
+ private MediaDatabase mediaDatabase;\r
+\r
+ public Database()\r
+ {\r
+ mediaDatabase = new MediaDatabase();\r
+ mediaDatabase.Connect();\r
+ }\r
+\r
+ private void TerminateDatabase()\r
+ {\r
+ mediaDatabase.Disconnect();\r
+ mediaDatabase.Dispose();\r
+ }\r
+\r
+ ~Database()\r
+ {\r
+ TerminateDatabase();\r
+ }\r
+\r
+ public void Dispose()\r
+ {\r
+ TerminateDatabase();\r
+ // This will informed gc to not call the finalize method as resources are already released.\r
+ GC.SuppressFinalize(this);\r
+ }\r
+\r
+ public MediaDatabase MediaDatabase\r
+ {\r
+ get { return mediaDatabase; }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System.Collections.Generic;\r
+using Tizen.Content.MediaContent;\r
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.Media\r
+{\r
+ public static partial class Contents\r
+ {\r
+ public static List<Playlist> GetPlaylists()\r
+ {\r
+ List<Playlist> playlists = new List<Playlist>();\r
+ SelectArguments arguments = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, PlaylistColumns.Name + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<Playlist> dataReader = playlistInfo.Select(arguments);\r
+\r
+ while(dataReader.Read())\r
+ {\r
+ Playlist playlist = dataReader.Current;\r
+ playlists.Add(playlist);\r
+ }\r
+ Tizen.Log.Debug(AppConstants.LogTag, "PlayLists Count : " + playlists.Count);\r
+ return playlists;\r
+ }\r
+\r
+ public static Playlist GetPlaylistByName(string name)\r
+ {\r
+ string filterExpression = MEDIA_STORAGE_TYPE_QUERY + " AND " + PlaylistColumns.Name + "=\"" + name + "\"";\r
+ SelectArguments arguments = CreateSelectArgument(filterExpression, PlaylistColumns.Name + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<Playlist> dataReader = playlistInfo.Select(arguments);\r
+\r
+ Playlist list = null;\r
+ while (dataReader.Read())\r
+ {\r
+ list = dataReader.Current;\r
+ }\r
+ return list;\r
+ }\r
+\r
+ public static Playlist GetPlaylistById(int playlistId)\r
+ {\r
+ Playlist list = null;\r
+ list = playlistInfo.Select(playlistId);\r
+ return list;\r
+ }\r
+\r
+ }\r
+}\r
--- /dev/null
+using System.Collections.Specialized;\r
+using Tizen.Content.MediaContent;\r
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.Media\r
+{\r
+ public static partial class Contents\r
+ {\r
+ public static OrderedDictionary GetTrackList()\r
+ {\r
+ OrderedDictionary mediaList = new OrderedDictionary();\r
+\r
+ SelectArguments argument = CreateSelectArgument(MEDIA_STORAGE_TYPE_QUERY, MediaInfoColumns.Title + MEDIA_SORT_ORDER_ASC);\r
+ MediaDataReader<MediaInfo> dataReader = mediaInfo.SelectMedia(argument);\r
+\r
+ while (dataReader.Read())\r
+ {\r
+ MediaInfo info = dataReader.Current;\r
+ mediaList.Add(info.Id, info);\r
+ }\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Total track retrived from database: " + mediaList.Count);\r
+ dataReader.Dispose();\r
+ return mediaList;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.Models\r
+{\r
+ class MusicAlbum : PropertyNotifier\r
+ {\r
+ public MusicAlbum()\r
+ {\r
+ //this is required for Activator.CreateInstance in ListViewModel\r
+ }\r
+\r
+ public MusicAlbum(Tizen.Content.MediaContent.Album album)\r
+ {\r
+ AlbumName = album.Name;\r
+ ArtistName = album.Artist;\r
+ Id = album.Id;\r
+ string text = album.AlbumArtPath;\r
+ if (string.IsNullOrEmpty(album.AlbumArtPath))\r
+ {\r
+ text = AlbumDataProvider.GetAlbumArtFromTracks(album.Id);\r
+ }\r
+ AlbumArtPath = text;\r
+ }\r
+\r
+ private string albumName;\r
+\r
+ public string AlbumName\r
+ {\r
+ get => albumName;\r
+ set\r
+ {\r
+ string text = string.IsNullOrEmpty(value) ? "Unknown" : value;\r
+ SetProperty(ref albumName, text);\r
+ }\r
+ }\r
+\r
+ private string artistName;\r
+\r
+ public string ArtistName\r
+ {\r
+ get => artistName;\r
+ set\r
+ {\r
+ string text = string.IsNullOrEmpty(value) ? "Unknown" : value;\r
+ SetProperty(ref artistName, text);\r
+ }\r
+ }\r
+\r
+ private int id;\r
+\r
+ public int Id\r
+ {\r
+ get => id;\r
+ set => id = value;\r
+ }\r
+\r
+ private string albumArtPath;\r
+\r
+ public string AlbumArtPath\r
+ {\r
+ get => albumArtPath;\r
+ set\r
+ {\r
+ string thumb = string.IsNullOrEmpty(value) ? Resources.GetImagePath() + "thumbnail.png" : value;\r
+ SetProperty(ref albumArtPath, thumb);\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System.Collections.Specialized;\r
+using MusicPlayer.Media;\r
+\r
+namespace MusicPlayer.Models\r
+{\r
+ public static class AlbumDataProvider\r
+ {\r
+ private static OrderedDictionary albumsList;\r
+\r
+ static AlbumDataProvider()\r
+ {\r
+ albumsList = Contents.GetAlbumList();\r
+ Contents.MusicItemUpdate += OnMusicItemUpdate;\r
+ Contents.MusicDBUpdate += OnMusicDatabaseUpdate;\r
+ }\r
+\r
+ private static void OnMusicDatabaseUpdate(object sender, MusicDBUpdateEventArgs e)\r
+ {\r
+ albumsList = Contents.GetAlbumList();\r
+ // TODO implement database update event handler\r
+ return;\r
+ }\r
+\r
+ private static void OnMusicItemUpdate(object sender, MusicItemUpdateEventArgs e)\r
+ {\r
+ // TODO implement database item update event handler\r
+ return;\r
+ }\r
+\r
+ public static OrderedDictionary CurrentAlbumList()\r
+ {\r
+ return albumsList;\r
+ }\r
+\r
+ public static OrderedDictionary GetAlbumTrackList(int albumId)\r
+ {\r
+ return Contents.GetAlbumMemberList(albumId);\r
+ }\r
+\r
+ public static string GetAlbumArtFromTracks(int albumId)\r
+ {\r
+ return Contents.GetAlbumArtPath(albumId);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Models
+{
+ class Artist : PropertyNotifier
+ {
+ public Artist()
+ {
+ //this is required for Activator.CreateInstance in ListViewModel
+ }
+
+ public Artist(string artistName)
+ {
+ ArtistName = artistName;
+ AlbumCount = ArtistDataProvider.GetArtistAlbumCount(artistName).ToString();
+ TrackCount = ArtistDataProvider.GetArtistTrackCount(artistName).ToString();
+ TotalCount = AlbumCount + " / " + TrackCount;
+ AlbumArtPath = ArtistDataProvider.GetArtistAlbumArtPath(artistName);
+ }
+
+ private string artistName;
+
+ public string ArtistName
+ {
+ get => artistName;
+ set
+ {
+ string text = string.IsNullOrEmpty(value) ? "Unknown" : value;
+ SetProperty(ref artistName, text);
+ }
+ }
+
+ private string albumCount;
+
+ public string AlbumCount
+ {
+ get => albumCount;
+ set
+ {
+ string text = string.Equals(value, "1") ? " album" : " albums";
+ SetProperty(ref albumCount, value + text);
+ }
+ }
+
+ private string trackCount;
+
+ public string TrackCount
+ {
+ get => trackCount;
+ set
+ {
+ string text = string.Equals(value, "1") ? " track" : " tracks";
+ SetProperty(ref trackCount, value + text);
+ }
+ }
+
+ private string totalCount;
+
+ public string TotalCount
+ {
+ get => totalCount;
+ set => SetProperty(ref totalCount, value);
+ }
+
+ private string albumArtPath;
+
+ public string AlbumArtPath
+ {
+ get => albumArtPath;
+ set
+ {
+ string thumb = string.IsNullOrEmpty(value) ? Resources.GetImagePath() + "thumbnail.png" : value;
+ SetProperty(ref albumArtPath, thumb);
+ }
+ }
+ }
+}
--- /dev/null
+using System.Collections.Specialized;
+using System.Collections.Generic;
+using MusicPlayer.Media;
+
+namespace MusicPlayer.Models
+{
+ public static class ArtistDataProvider
+ {
+ private static List<string> artistsList;
+
+ static ArtistDataProvider()
+ {
+ artistsList = Contents.GetArtistList();
+ Contents.MusicItemUpdate += OnMusicItemUpdate;
+ Contents.MusicDBUpdate += OnMusicDatabaseUpdate;
+ }
+
+ private static void OnMusicDatabaseUpdate(object sender, MusicDBUpdateEventArgs e)
+ {
+ artistsList = Contents.GetArtistList();
+ // TODO implement database update event handler
+ return;
+ }
+
+ private static void OnMusicItemUpdate(object sender, MusicItemUpdateEventArgs e)
+ {
+ // TODO implement database item update event handler
+ return;
+ }
+
+ public static List<string> CurrentArtistList()
+ {
+ return artistsList;
+ }
+
+ public static int GetArtistTrackCount(string artistName)
+ {
+ return Contents.GetMediaCountForArtist(artistName);
+ }
+
+ public static int GetArtistAlbumCount(string artistName)
+ {
+ return Contents.GetAlbumCountForArtist(artistName);
+ }
+
+ public static string GetArtistAlbumArtPath(string artistName)
+ {
+ return Contents.GetAlbumArtPathForArtist(artistName);
+ }
+
+ public static OrderedDictionary GetArtistAlbumList(string artistName)
+ {
+ return Contents.GetAlbumListForArtist(artistName);
+ }
+
+ public static OrderedDictionary GetArtistTrackList(string artistName)
+ {
+ return Contents.GetTrackListForArtist(artistName);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MusicPlayer.Common;
+using System.Collections.ObjectModel;
+
+namespace MusicPlayer.Models
+{
+ class ArtistDetailAlbum: ObservableCollection <Track>
+ {
+ public ArtistDetailAlbum()
+ {
+ //this is required for Activator.CreateInstance in ListViewModel
+ }
+
+ public ArtistDetailAlbum(MusicAlbum album)
+ {
+ AlbumArtPath = album.AlbumArtPath;
+ AlbumName = album.AlbumName;
+ }
+
+ public string AlbumName { get; set; }
+
+ public string AlbumArtPath { get; set; }
+ }
+}
--- /dev/null
+using Tizen.Multimedia;
+using System.ComponentModel;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Models
+{
+ class LyricsModel: PropertyNotifier
+ {
+ public LyricsModel()
+ {
+ }
+
+ public LyricsModel(string thumbPath, string lyrics)
+ {
+ ThumbPath = thumbPath;
+ Lyrics = lyrics;
+ }
+
+ private string thumbPath;
+
+ public string ThumbPath
+ {
+ get => thumbPath;
+ set => SetProperty(ref thumbPath, value);
+ }
+
+ private string lyrics;
+
+ public string Lyrics
+ {
+ get => lyrics;
+ set => SetProperty(ref lyrics, value);
+ }
+ }
+}
--- /dev/null
+using MusicPlayer.Common;
+using System;
+
+namespace MusicPlayer.Models
+{
+ class PlayerModel : PropertyNotifier
+ {
+ public PlayerModel()
+ {
+ }
+
+ private Track currentTrack;
+
+ public Track CurrentTrack
+ {
+ get => currentTrack;
+ set
+ {
+ currentTrack = value;
+ TrackName = currentTrack.TrackTitle;
+ TrackArtist = currentTrack.ArtistName;
+ TrackLength = currentTrack.Duration;
+ PlayingTime = TimeSpan.FromMilliseconds(0).ToString(AppConstants.TimeFormat);
+ ThumbnailPath = currentTrack.ThumbnailPath;
+ }
+ }
+
+ private string trackName;
+
+ public string TrackName
+ {
+ get => trackName;
+ set => SetProperty(ref trackName, value);
+ }
+
+ private string trackArtist;
+
+ public string TrackArtist
+ {
+ get => trackArtist;
+ set => SetProperty(ref trackArtist, value);
+ }
+
+ private string trackLength;
+
+ public string TrackLength
+ {
+ get => trackLength;
+ set => SetProperty(ref trackLength, value);
+ }
+
+ private string thumbnailPath;
+
+ public string ThumbnailPath
+ {
+ get => thumbnailPath;
+ set => SetProperty(ref thumbnailPath, value);
+ }
+
+ private string playingTime;
+
+ public string PlayingTime
+ {
+ get => playingTime;
+ set => SetProperty(ref playingTime, value);
+ }
+
+ private float elapsedTime;
+
+ public float ElapsedTime
+ {
+ get => elapsedTime;
+ set => SetProperty(ref elapsedTime, value);
+ }
+ }
+}
--- /dev/null
+using System;\r
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.Models\r
+{\r
+ class Track : PropertyNotifier\r
+ {\r
+ public Track()\r
+ {\r
+ //this is required for Activator.CreateInstance in ListViewModel\r
+ }\r
+\r
+ public Track(Tizen.Content.MediaContent.AudioInfo audioInfo)\r
+ {\r
+ TrackTitle = audioInfo.Title;\r
+ AlbumName = audioInfo.Album;\r
+ Id = audioInfo.Id;\r
+ ArtistName = audioInfo.Artist;\r
+ DurationInMS = audioInfo.Duration;\r
+ Duration = TimeSpan.FromMilliseconds(audioInfo.Duration).ToString(AppConstants.TimeFormat);\r
+ ThumbnailPath = audioInfo.ThumbnailPath;\r
+ FilePath = audioInfo.Path;\r
+ }\r
+\r
+ private string trackTitle;\r
+\r
+ public string TrackTitle\r
+ {\r
+ get => trackTitle;\r
+ set => SetProperty(ref trackTitle, value);\r
+ }\r
+\r
+ private string albumName;\r
+\r
+ public string AlbumName\r
+ {\r
+ get => albumName;\r
+ set\r
+ {\r
+ string name = string.IsNullOrEmpty(value) ? "Unknown" : value;\r
+ SetProperty(ref albumName, name);\r
+ }\r
+ }\r
+\r
+ private string artistName;\r
+\r
+ public string ArtistName\r
+ {\r
+ get => artistName;\r
+ set\r
+ {\r
+ string name = string.IsNullOrEmpty(value) ? "Unknown" : value;\r
+ SetProperty(ref artistName, name);\r
+ }\r
+ }\r
+\r
+ private string id;\r
+\r
+ public string Id\r
+ {\r
+ get => id;\r
+ set => id = value;\r
+ }\r
+\r
+ private string duration;\r
+\r
+ public string Duration\r
+ {\r
+ get => duration;\r
+ set => SetProperty(ref duration, value);\r
+ }\r
+\r
+ private int durationInMS;\r
+\r
+ public int DurationInMS\r
+ {\r
+ get => durationInMS;\r
+ set => SetProperty(ref durationInMS, value);\r
+ }\r
+\r
+ private string thumbnailPath;\r
+\r
+ public string ThumbnailPath\r
+ {\r
+ get => thumbnailPath;\r
+ set\r
+ {\r
+ string thumb = string.IsNullOrEmpty(value) ? Resources.GetImagePath() + "thumbnail.png" : value;\r
+ SetProperty(ref thumbnailPath, thumb);\r
+ }\r
+ }\r
+\r
+ private string filePath;\r
+\r
+ public string FilePath\r
+ {\r
+ get => filePath;\r
+ set { filePath = value; }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System.Collections.Specialized;\r
+using MusicPlayer.Media;\r
+\r
+namespace MusicPlayer.Models\r
+{\r
+ public static class TrackDataProvider\r
+ {\r
+ private static OrderedDictionary tracksList;\r
+\r
+ static TrackDataProvider()\r
+ {\r
+ tracksList = Contents.GetTrackList();\r
+ Contents.MusicItemUpdate += OnMusicItemUpdate;\r
+ Contents.MusicDBUpdate += OnMusicDatabaseUpdate;\r
+ }\r
+\r
+ private static void OnMusicDatabaseUpdate(object sender, MusicDBUpdateEventArgs e)\r
+ {\r
+ tracksList = Contents.GetTrackList();\r
+ // TODO implement database update event handler\r
+ return;\r
+ }\r
+\r
+ private static void OnMusicItemUpdate(object sender, MusicItemUpdateEventArgs e)\r
+ {\r
+ // TODO implement database item update event handler\r
+ return;\r
+ }\r
+\r
+ public static OrderedDictionary CurrentTrackList()\r
+ {\r
+ return tracksList;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System;
+using Tizen.NUI;
+using MusicPlayer.Views;
+using MusicPlayer.Common;
+
+namespace MusicPlayer
+{
+ public class Application : NUIApplication
+ {
+ public Application() : base(ThemeOptions.PlatformThemeEnabled)
+ {
+
+ }
+ protected override void OnCreate()
+ {
+ 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(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 == AppConstants.BackKeyCode || e.Key.KeyPressedName == AppConstants.EscapeKeyCode))
+ {
+ Exit();
+ }
+ }
+
+ static void Main(string[] args)
+ {
+ Tizen.Log.Info(AppConstants.LogTag, "Main statrted");
+ var app = new Application();
+ app.Run(args);
+ Tizen.Log.Info(AppConstants.LogTag, "Main finished");
+ }
+ }
+}
--- /dev/null
+\r
+Microsoft Visual Studio Solution File, Format Version 12.00\r
+# Visual Studio Version 16\r
+VisualStudioVersion = 16.0.30804.86\r
+MinimumVisualStudioVersion = 10.0.40219.1\r
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "music-player", "music-player.csproj", "{18A58E69-495D-4F9C-BA77-C969BE9D8104}"\r
+EndProject\r
+Global\r
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution\r
+ Debug|Any CPU = Debug|Any CPU\r
+ Release|Any CPU = Release|Any CPU\r
+ EndGlobalSection\r
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution\r
+ {18A58E69-495D-4F9C-BA77-C969BE9D8104}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\r
+ {18A58E69-495D-4F9C-BA77-C969BE9D8104}.Debug|Any CPU.Build.0 = Debug|Any CPU\r
+ {18A58E69-495D-4F9C-BA77-C969BE9D8104}.Release|Any CPU.ActiveCfg = Release|Any CPU\r
+ {18A58E69-495D-4F9C-BA77-C969BE9D8104}.Release|Any CPU.Build.0 = Release|Any CPU\r
+ EndGlobalSection\r
+ GlobalSection(SolutionProperties) = preSolution\r
+ HideSolutionNode = FALSE\r
+ EndGlobalSection\r
+ GlobalSection(ExtensibilityGlobals) = postSolution\r
+ SolutionGuid = {7072B878-F218-47CE-84F8-FC9AC39798C6}\r
+ EndGlobalSection\r
+EndGlobal\r
--- /dev/null
+using System.Collections.Specialized;\r
+using MusicPlayer.Models;\r
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.ViewModels\r
+{\r
+ using AudioInfo = Tizen.Content.MediaContent.AudioInfo;\r
+ class AlbumDetailViewModel : PropertyNotifier\r
+ {\r
+ public AlbumDetailViewModel(MusicAlbum album)\r
+ {\r
+ Id = album.Id;\r
+ AlbumName = album.AlbumName;\r
+ ArtistName = album.ArtistName;\r
+ AlbumArtPath = album.AlbumArtPath;\r
+ OrderedDictionary trackList = AlbumDataProvider.GetAlbumTrackList(album.Id);\r
+ listViewModel = new ListViewModel<Track>();\r
+ listViewModel.CreateData<AudioInfo>(trackList);\r
+ listViewModel.CollectionChanged += OnAlbumDetailListChanges;\r
+ TotalTracks = listViewModel.Count.ToString();\r
+ }\r
+\r
+ private void OnAlbumDetailListChanges(object sender, NotifyCollectionChangedEventArgs e)\r
+ {\r
+ //TODO\r
+ TotalTracks = listViewModel.Count.ToString();\r
+ }\r
+\r
+ private int id;\r
+\r
+ public int Id\r
+ {\r
+ get => id;\r
+ set => id = value;\r
+ }\r
+\r
+ private string albumName;\r
+\r
+ public string AlbumName\r
+ {\r
+ get => albumName;\r
+ set\r
+ {\r
+ string text = string.Equals(value,"Unknown") ? null : value;\r
+ SetProperty(ref albumName, text);\r
+ }\r
+ }\r
+\r
+ private string artistName;\r
+\r
+ public string ArtistName\r
+ {\r
+ get => artistName;\r
+ set\r
+ {\r
+ string text = string.Equals(value, "Unknown") ? null : value;\r
+ SetProperty(ref artistName, text);\r
+ }\r
+ }\r
+\r
+ private string albumArtPath;\r
+\r
+ public string AlbumArtPath\r
+ {\r
+ get => albumArtPath;\r
+ set => SetProperty(ref albumArtPath, value);\r
+ }\r
+\r
+ private ListViewModel<Track> listViewModel;\r
+\r
+ public ListViewModel<Track> ListViewModel\r
+ {\r
+ get => listViewModel;\r
+ }\r
+\r
+ private string totalTracks;\r
+\r
+ public string TotalTracks\r
+ {\r
+ get => totalTracks;\r
+ set\r
+ {\r
+ string text = string.Equals(value, "1") ? " Track" : " Tracks";\r
+ SetProperty(ref totalTracks, value + text);\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System.Collections.Specialized;\r
+using MusicPlayer.Models;\r
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.ViewModels\r
+{\r
+ using Album = Tizen.Content.MediaContent.Album;\r
+ class AlbumViewModel : PropertyNotifier\r
+ {\r
+ private AlbumDetailViewModel albumDetailViewModel;\r
+\r
+ public AlbumViewModel()\r
+ {\r
+ OrderedDictionary albumList = AlbumDataProvider.CurrentAlbumList();\r
+ listViewModel = new ListViewModel<MusicAlbum>();\r
+ listViewModel.CreateData<Album>(albumList);\r
+ listViewModel.CollectionChanged += OnAlbumListChanges;\r
+ AlbumCount = listViewModel.Count.ToString();\r
+ }\r
+\r
+ private void OnAlbumListChanges(object sender, NotifyCollectionChangedEventArgs e)\r
+ {\r
+ AlbumCount = listViewModel.Count.ToString();\r
+ }\r
+\r
+ public AlbumDetailViewModel getDetailViewModel(MusicAlbum musicAlbum)\r
+ {\r
+ if(albumDetailViewModel == null)\r
+ albumDetailViewModel = new AlbumDetailViewModel(musicAlbum);\r
+ else if (albumDetailViewModel.Id != musicAlbum.Id)\r
+ albumDetailViewModel = new AlbumDetailViewModel(musicAlbum);\r
+ return albumDetailViewModel;\r
+ }\r
+\r
+ private ListViewModel<MusicAlbum> listViewModel;\r
+\r
+ public ListViewModel<MusicAlbum> ListViewModel\r
+ {\r
+ get => listViewModel;\r
+ }\r
+\r
+ private string albumCount;\r
+\r
+ public string AlbumCount\r
+ {\r
+ get => albumCount;\r
+ set\r
+ {\r
+ string text = string.Equals(value, "1") ? " album" : " albums";\r
+ SetProperty(ref albumCount, value + text);\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System.Collections.Specialized;
+using MusicPlayer.Models;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.ViewModels
+{
+ using Album = Tizen.Content.MediaContent.Album;
+ using AudioInfo = Tizen.Content.MediaContent.AudioInfo;
+ class ArtistDetailViewModel : PropertyNotifier
+ {
+
+ public ArtistDetailViewModel(Artist artist)
+ {
+ ArtistName = artist.ArtistName;
+ TotalCount = artist.TotalCount;
+ string text = string.Equals(ArtistName, "Unknown") ? "" : ArtistName;
+
+ OrderedDictionary albumList = ArtistDataProvider.GetArtistAlbumList(text);
+ albumListViewModel = new ListViewModel<MusicAlbum>();
+ albumListViewModel.CreateData<Album>(albumList);
+
+ OrderedDictionary trackList = ArtistDataProvider.GetArtistTrackList(text);
+ trackListViewModel = new ListViewModel<Track>();
+ trackListViewModel.CreateData<AudioInfo>(trackList);
+
+ groupListViewModel = new ListViewModel<ArtistDetailAlbum>();
+
+ foreach(MusicAlbum album in albumListViewModel)
+ {
+ ArtistDetailAlbum artistAlbum = new ArtistDetailAlbum(album);
+ OrderedDictionary albumTrackList = AlbumDataProvider.GetAlbumTrackList(album.Id);
+ ListViewModel<Track> albumTrackListViewModel = new ListViewModel<Track>();
+ albumTrackListViewModel.CreateData<AudioInfo>(albumTrackList);
+ foreach (Track track in albumTrackListViewModel)
+ artistAlbum.Add(track);
+ groupListViewModel.Add(artistAlbum);
+ }
+ }
+
+ private string artistName;
+
+ public string ArtistName
+ {
+ get => artistName;
+ set => SetProperty(ref artistName, value);
+ }
+
+ private string totalCount;
+
+ public string TotalCount
+ {
+ get => totalCount;
+ set => SetProperty(ref totalCount, value);
+ }
+
+ private readonly ListViewModel<ArtistDetailAlbum> groupListViewModel;
+ public ListViewModel<ArtistDetailAlbum> GroupListViewModel => groupListViewModel;
+
+ private readonly ListViewModel<MusicAlbum> albumListViewModel;
+ public ListViewModel<MusicAlbum> AlbumListViewModel => albumListViewModel;
+
+ private readonly ListViewModel<Track> trackListViewModel;
+ public ListViewModel<Track> TrackListViewModel => trackListViewModel;
+ }
+}
--- /dev/null
+using System.Collections.Specialized;
+using System.Collections.Generic;
+using MusicPlayer.Models;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.ViewModels
+{
+ class ArtistViewModel : PropertyNotifier
+ {
+ private ArtistDetailViewModel artistDetailViewModel;
+
+ public ArtistViewModel()
+ {
+ List<string> artistList = ArtistDataProvider.CurrentArtistList();
+ listViewModel = new ListViewModel<Artist>();
+ listViewModel.CreateData<string>(artistList);
+ listViewModel.CollectionChanged += OnArtistListChanges;
+ ArtistCount = listViewModel.Count.ToString();
+ }
+
+ private void OnArtistListChanges(object sender, NotifyCollectionChangedEventArgs e)
+ {
+ artistCount = listViewModel.Count.ToString();
+ }
+
+ public ArtistDetailViewModel getDetailViewModel(Artist artist)
+ {
+ if (artistDetailViewModel == null)
+ artistDetailViewModel = new ArtistDetailViewModel(artist);
+ else if (artistDetailViewModel.ArtistName != artist.ArtistName)
+ artistDetailViewModel = new ArtistDetailViewModel(artist);
+ return artistDetailViewModel;
+ }
+
+ private ListViewModel<Artist> listViewModel;
+
+ public ListViewModel<Artist> ListViewModel
+ {
+ get => listViewModel;
+ }
+
+ private string artistCount;
+
+ public string ArtistCount
+ {
+ get => artistCount;
+ set
+ {
+ string text = string.Equals(value, "1") ? " artist" : " artists";
+ SetProperty(ref artistCount, value + text);
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using System.Collections;\r
+using System.Collections.Specialized;\r
+using System.Collections.ObjectModel;\r
+using MusicPlayer.Models;\r
+using Tizen.Content.MediaContent;\r
+using MusicPlayer.Common;\r
+using System;\r
+using System.Collections.Generic;\r
+\r
+namespace MusicPlayer.ViewModels\r
+{\r
+ class ListViewModel<T> : ObservableCollection<T> where T : new()\r
+ {\r
+ public ListViewModel()\r
+ {\r
+ }\r
+\r
+ public void CreateData<U>(OrderedDictionary dict)\r
+ {\r
+ foreach (DictionaryEntry item in dict)\r
+ {\r
+ Add((T)Activator.CreateInstance(typeof(T), new object[] { (U)item.Value }));\r
+ }\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Observable list item count: " + this.Count);\r
+ }\r
+\r
+ public void CreateData<U>(List<U> list)\r
+ {\r
+ foreach (var item in list)\r
+ {\r
+ Add((T)Activator.CreateInstance(typeof(T), new object[] { (U)item }));\r
+ }\r
+ Tizen.Log.Debug(AppConstants.LogTag, "Observable list item count: " + this.Count);\r
+ }\r
+\r
+\r
+ }\r
+}\r
--- /dev/null
+using Tizen.Multimedia;
+using MusicPlayer.Models;
+using MusicPlayer.Common;
+using Tizen.NUI;
+
+namespace MusicPlayer.ViewModels
+{
+ class LyricsViewModel : PropertyNotifier
+ {
+ internal LyricsModel lyricsModel;
+
+ public LyricsViewModel()
+ {
+ lyricsModel = new LyricsModel();
+ }
+
+ public LyricsViewModel(Track currentTrack)
+ {
+ FilePath = currentTrack.FilePath;
+ lyricsModel = new LyricsModel(currentTrack.ThumbnailPath, GetLyrics(FilePath));
+ }
+
+ public string FilePath { get; set; }
+
+ private Track currentTrack;
+
+ public Track CurrentTrack
+ {
+ get => currentTrack;
+ set
+ {
+ currentTrack = value;
+ FilePath = currentTrack.FilePath;
+ lyricsModel.ThumbPath = currentTrack.ThumbnailPath;
+ lyricsModel.Lyrics = GetLyrics(FilePath);
+ }
+ }
+
+ private Color lyricsBackgroundColor;
+
+ public Color LyricsBackgroundColor
+ {
+ get => lyricsBackgroundColor;
+ set => SetProperty(ref lyricsBackgroundColor, value);
+ }
+
+ private string GetLyrics(string path)
+ {
+ var metadataExtractor = new MetadataExtractor(path);
+ Metadata metadata = metadataExtractor.GetMetadata();
+ string lyrics = metadata.UnsyncLyrics;
+ if(string.IsNullOrEmpty(lyrics))
+ {
+ LyricsBackgroundColor = Color.Transparent;
+ return string.Empty;
+ }
+ else
+ {
+ LyricsBackgroundColor = UIColors.LyricsBackground;
+ return lyrics;
+ }
+ }
+ }
+}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Text;
+using MusicPlayer.Models;
+using MusicPlayer.Common;
+using MusicPlayer.Core;
+using Tizen.NUI;
+using Tizen.Multimedia;
+using System.Threading.Tasks;
+
+namespace MusicPlayer.ViewModels
+{
+ class PlayerViewModel : PropertyNotifier
+ {
+ public const string PlayState = "Play";
+ public const string PauseState = "Pause";
+ private const int PlaybackTimerDuration = 1000;
+ private const int MinPaletteColorCount = 2;
+
+ internal PlayerModel playerModel;
+ internal LyricsViewModel lyricsViewModel;
+ private Timer playbackTimer;
+ private bool isVolumeChanging;
+
+ public PlayerViewModel()
+ {
+ lyricsViewModel = new LyricsViewModel();
+ playingListViewModel = new PlayingListViewModel();
+ playerModel = new PlayerModel();
+ playerModel.ElapsedTime = 0.0f;
+ PlayingStatus = PlayingStatus.None;
+ PlayerController.Instance.PlayerEventOccurred += OnPlayerEventOccurred;
+ playbackTimer = new Timer(PlaybackTimerDuration);
+ playbackTimer.Tick += OnPlaybackTimerTick;
+ isVolumeChanging = false;
+ VolumeLevel = AudioManager.VolumeController.Level[AudioVolumeType.Media];
+ AudioManager.VolumeController.Changed += OnVolumeLevelChanged;
+ HasPreviousTrack = playingListViewModel.HasPrev();
+ HasNextTrack = playingListViewModel.HasNext();
+ }
+
+ internal PlayingListViewModel playingListViewModel;
+
+ public PlayingListViewModel CurrentPlayingListViewModel
+ {
+ get => playingListViewModel;
+ }
+
+ private string playButtonState;
+
+ public string PlayButtonState
+ {
+ get => playButtonState;
+ set => SetProperty(ref playButtonState, value);
+ }
+
+ private float volumeLevel;
+
+ public float VolumeLevel
+ {
+ get => volumeLevel;
+ set => SetProperty(ref volumeLevel, value);
+ }
+
+ private bool hasPreviousTrack;
+
+ public bool HasPreviousTrack
+ {
+ get => hasPreviousTrack;
+ set => SetProperty(ref hasPreviousTrack, value);
+ }
+
+ private bool hasNextTrack;
+
+ public bool HasNextTrack
+ {
+ get => hasNextTrack;
+ set => SetProperty(ref hasNextTrack, value);
+ }
+
+ private PropertyMap playerBackground;
+
+ public PropertyMap PlayerBackground
+ {
+ get => playerBackground;
+ set => SetProperty(ref playerBackground, value);
+ }
+
+ private PlayingStatus playingStatus;
+
+ public PlayingStatus PlayingStatus
+ {
+ get => playingStatus;
+ set => UpdatePlayingStatus(value);
+ }
+
+ public void SetPlayingList(ListViewModel<Track> trackListVM)
+ {
+ playingListViewModel.SetTrackListViewModel(trackListVM);
+ }
+
+ public void SetCurrentTrack(Track track)
+ {
+ Tizen.Log.Info(AppConstants.LogTag, "Setting Current track");
+ playerModel.CurrentTrack = track;
+ lyricsViewModel.CurrentTrack = track;
+ //TO DO need to set index properly
+ Track current = playingListViewModel.Current();
+ if (current == null)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "Current track is null so setting new track");
+ playingListViewModel.SetPlayingTrack(track);
+ }
+ // updating prev/next button state
+ HasPreviousTrack = playingListViewModel.HasPrev();
+ HasNextTrack = playingListViewModel.HasNext();
+
+ // SetBackground
+ SetExtractedBackground(track.ThumbnailPath);
+
+ PlayerController.Instance.Uri = track.FilePath;
+ StartPlayback();
+ }
+
+ public void NextButtonClicked()
+ {
+ Track nextTrack = playingListViewModel.Next();
+ if (nextTrack == null)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "nextTrack is null");
+ StopPlayback();
+ return;
+ }
+ Tizen.Log.Debug(AppConstants.LogTag, "Next track is: " + nextTrack.TrackTitle);
+ SetCurrentTrack(nextTrack);
+ }
+
+ public void PrevButtonClicked()
+ {
+ Track previousTrack = playingListViewModel.Prev();
+ if (previousTrack == null)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "previousTrack is null");
+ StopPlayback();
+ return;
+ }
+ Tizen.Log.Debug(AppConstants.LogTag, "Prev track is: " + previousTrack.TrackTitle);
+ SetCurrentTrack(previousTrack);
+ }
+
+ 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[] repeatArr = (RepeatMode[])values;
+ RepeatMode new_mode;
+ if (i + 1 >= values.Length)
+ {
+ new_mode = repeatArr[0];
+ }
+ else
+ {
+ new_mode = repeatArr[i + 1];
+ }
+ playingListViewModel.RepeatMode = new_mode;
+ }
+
+ public void PlayingStatusChanged()
+ {
+ if (PlayingStatus == PlayingStatus.Playing)
+ {
+ PlayingStatus = PlayingStatus.Paused;
+ Pause();
+ playbackTimer.Stop();
+ }
+ else
+ {
+ PlayingStatus = PlayingStatus.Playing;
+ Resume();
+ playbackTimer.Start();
+ }
+ }
+
+ public void UpdatePlayerPosition(float value)
+ {
+ int currentPosition = (int)(playerModel.CurrentTrack.DurationInMS * value);
+ PlayerController.Instance.SetPosition(currentPosition);
+ playerModel.PlayingTime = TimeSpan.FromMilliseconds(currentPosition).ToString(AppConstants.TimeFormat);
+ playbackTimer.Start();
+ }
+
+ public void StopPlaybackTimer()
+ {
+ playbackTimer.Stop();
+ }
+
+ public void SetElapsedTime(float value)
+ {
+ int currentPosition = (int)(playerModel.CurrentTrack.DurationInMS * value);
+ playerModel.PlayingTime = TimeSpan.FromMilliseconds(currentPosition).ToString(AppConstants.TimeFormat);
+ }
+
+ public void VolumeChangeStarted()
+ {
+ isVolumeChanging = true;
+ }
+
+ public void VolumeChangeFinished(int value)
+ {
+ VolumeLevelChanged(value);
+ isVolumeChanging = false;
+ }
+ public void VolumeLevelChanged(int value)
+ {
+ AudioManager.VolumeController.Level[AudioVolumeType.Media] = value;
+ }
+
+ private void UpdatePlayingStatus(PlayingStatus status)
+ {
+ playingStatus = status;
+ switch (status)
+ {
+ case PlayingStatus.Playing:
+ PlayButtonState = PauseState;
+ break;
+ case PlayingStatus.Paused: // Fall Through
+ case PlayingStatus.Stopped: // Fall Through
+ case PlayingStatus.None:
+ PlayButtonState = PlayState;
+ break;
+ }
+ }
+
+ private bool OnPlaybackTimerTick(object source, Timer.TickEventArgs e)
+ {
+ UpdatePlayingTime();
+ return true;
+ }
+
+ private void OnPlayerEventOccurred(object sender, PlayerEventArgs e)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "Player Event Occurred:");
+ Tizen.Log.Error(AppConstants.LogTag, "\t"+e.Type.ToString());
+ Tizen.Log.Error(AppConstants.LogTag, "\t:"+e.Description);
+ if(e.Type == EventType.PlaybackCompleted)
+ {
+ PlayNext();
+ }
+ }
+
+ private void PlayNext()
+ {
+ if(playingListViewModel.RepeatMode == RepeatMode.Off)
+ {
+ Tizen.Log.Debug(AppConstants.LogTag, "Repeat is off, can't play next");
+ StopPlayback();
+ UpdatePlayingTime();
+ return;
+ }
+ NextButtonClicked();
+ }
+
+ private void UpdatePlayingTime()
+ {
+ int position = PlayerController.Instance.GetPosition();
+ playerModel.ElapsedTime = position / (float)playerModel.CurrentTrack.DurationInMS;
+ playerModel.PlayingTime = TimeSpan.FromMilliseconds(position).ToString(AppConstants.TimeFormat);
+ }
+
+ private void StartPlayback()
+ {
+ PlayingStatus = PlayingStatus.Playing;
+ Play();
+ playbackTimer.Start();
+ }
+
+ private void StopPlayback()
+ {
+ PlayingStatus = PlayingStatus.Stopped;
+ Stop();
+ playbackTimer.Stop();
+ }
+
+ private void Play()
+ {
+ PlayerController.Instance.Play();
+ }
+ private void Pause()
+ {
+ PlayerController.Instance.Pause();
+ }
+ private void Resume()
+ {
+ PlayerController.Instance.Resume();
+ }
+ private void Stop()
+ {
+ PlayerController.Instance.Stop();
+ }
+
+ private void OnVolumeLevelChanged(object sender, VolumeChangedEventArgs e)
+ {
+ if(e.Type == AudioVolumeType.Media && isVolumeChanging == false)
+ {
+ VolumeLevel = e.Level;
+ }
+ }
+
+ private ImageVisual CreateImageVisual()
+ {
+ ImageVisual visual = new ImageVisual()
+ {
+ URL = Resources.GetImagePath() + "gradient_music_light.png",
+ };
+ return visual;
+ }
+
+ private GradientVisual CreateGradientVisual(PropertyArray stopColor)
+ {
+ GradientVisual gradientVisual = new GradientVisual()
+ {
+ StartPosition = new Vector2(0.0f, -1.0f),
+ EndPosition = new Vector2(0.0f, 1.0f),
+ StopColor = stopColor,
+ SpreadMethod = GradientVisualSpreadMethodType.Pad,
+ };
+ return gradientVisual;
+ }
+
+ private PropertyArray GetGradientStopColors(Palette palette)
+ {
+ PropertyArray propertyArray = new PropertyArray();
+ if(palette == null)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "Color palatte from background is null");
+ return propertyArray;
+ }
+
+ Palette.Swatch lightMutedSwatch = palette.GetLightMutedSwatch();
+ Palette.Swatch darkMutedSwatch = palette.GetDarkMutedSwatch();
+ if(lightMutedSwatch != null && darkMutedSwatch != null)
+ {
+ propertyArray.PushBack(new PropertyValue(lightMutedSwatch.GetRgb()));
+ propertyArray.PushBack(new PropertyValue(darkMutedSwatch.GetRgb()));
+ return propertyArray;
+ }
+
+ Palette.Swatch lightVibrantSwatch = palette.GetLightVibrantSwatch();
+ Palette.Swatch darkVibrantSwatch = palette.GetDarkVibrantSwatch();
+ if(lightVibrantSwatch != null && darkVibrantSwatch != null)
+ {
+ propertyArray.PushBack(new PropertyValue(lightVibrantSwatch.GetRgb()));
+ propertyArray.PushBack(new PropertyValue(darkVibrantSwatch.GetRgb()));
+ return propertyArray;
+ }
+
+ Palette.Swatch mutedSwatch = palette.GetMutedSwatch();
+ Palette.Swatch vibrantSwatch = palette.GetVibrantSwatch();
+ if(mutedSwatch != null && vibrantSwatch != null)
+ {
+ propertyArray.PushBack(new PropertyValue(mutedSwatch.GetRgb()));
+ propertyArray.PushBack(new PropertyValue(vibrantSwatch.GetRgb()));
+ return propertyArray;
+ }
+
+ IReadOnlyCollection<Palette.Swatch> swatches = palette.GetSwatches();
+ foreach(Palette.Swatch swatch in swatches)
+ {
+ if(propertyArray.Count() >= MinPaletteColorCount)
+ {
+ return propertyArray;
+ }
+ if(swatch != null)
+ {
+ propertyArray.PushBack(new PropertyValue(swatch.GetRgb()));
+ }
+ }
+ return propertyArray;
+ }
+
+ private async void SetExtractedBackground(string path)
+ {
+ Tizen.Log.Debug(AppConstants.LogTag, "Path for the color image thumbnail" + path);
+ Palette palette = await ColorExtractor.GetPaletteAsync(path);
+ PropertyArray stopColor = GetGradientStopColors(palette);
+ if (stopColor.Count() < MinPaletteColorCount)
+ {
+ Tizen.Log.Info(AppConstants.LogTag, "Palette or palatte values not valid, adding default gradient");
+ ImageVisual imageVisual = CreateImageVisual();
+ PlayerBackground = imageVisual.OutputVisualMap;
+ return;
+ }
+ else
+ {
+ Tizen.Log.Info(AppConstants.LogTag, "setting palette color");
+ GradientVisual gradientVisual = CreateGradientVisual(stopColor);
+ PlayerBackground = gradientVisual.OutputVisualMap;
+ }
+ }
+ }
+}
--- /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;
+using MusicPlayer.Models;
+
+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 ListViewModel<Track> 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(ListViewModel<Track> 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 = -1;
+ RepeatMode = RepeatMode.Off;
+ ShuffleMode = ShuffleMode.Off;
+ OnItemsSourceChanged(new EventArgs());
+ }
+
+ public ListViewModel<Track> TrackListVM
+ {
+ get => tracklistViewModel;
+ }
+
+ public string ShuffleButtonState
+ {
+ 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);
+ }
+ }
+ ShuffleButtonState = shuffleMode.ToString();
+ }
+ }
+
+ public string RepeatButtonState
+ {
+ get => repeatButtonUrl;
+ set => SetProperty(ref repeatButtonUrl, value);
+ }
+
+ public RepeatMode RepeatMode
+ {
+ get => repeatMode;
+ set
+ {
+ repeatMode = value;
+ RepeatButtonState = repeatMode.ToString();
+ }
+ }
+
+ public Track Next()
+ {
+ if(currentIndex < 0 )
+ {
+ Tizen.Log.Error(AppConstants.LogTag,"Invalid track index");
+ return null;
+ }
+ if(RepeatMode == RepeatMode.RepeatOne)
+ {
+ return tracklistViewModel[shuffleList[currentIndex]];
+ }
+ else if(RepeatMode == RepeatMode.Off)
+ {
+ if (currentIndex + 1 >= shuffleList.Count)
+ {
+ return null;
+ }
+ else
+ {
+ currentIndex += 1;
+ return tracklistViewModel[shuffleList[currentIndex]];
+ }
+ }
+ else
+ {
+ if (currentIndex + 1 >= shuffleList.Count)
+ {
+ currentIndex = 0;
+ return tracklistViewModel[shuffleList[currentIndex]];
+ }
+ else
+ {
+ currentIndex += 1;
+ return tracklistViewModel[shuffleList[currentIndex]];
+ }
+ }
+ }
+
+ public Track Prev()
+ {
+ if (currentIndex < 0)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "Invalid track index");
+ return null;
+ }
+ if (RepeatMode == RepeatMode.RepeatOne)
+ {
+ return tracklistViewModel[shuffleList[currentIndex]];
+ }
+ else if (RepeatMode == RepeatMode.Off)
+ {
+ if (currentIndex - 1 < 0)
+ {
+ return null;
+ }
+ else
+ {
+ currentIndex -= 1;
+ return tracklistViewModel[shuffleList[currentIndex]];
+ }
+ }
+ else
+ {
+ if (currentIndex - 1 < 0)
+ {
+ currentIndex = shuffleList.Count-1;
+ return tracklistViewModel[shuffleList[currentIndex]];
+ }
+ else
+ {
+ currentIndex -= 1;
+ return tracklistViewModel[shuffleList[currentIndex]];
+ }
+ }
+ }
+
+ public bool HasNext()
+ {
+ if (IsTrackIndexInvalid())
+ {
+ return false;
+ }
+ if(RepeatMode == RepeatMode.RepeatOne || RepeatMode == RepeatMode.RepeatAll)
+ {
+ return true;
+ }
+ else
+ {
+ return currentIndex + 1 < shuffleList.Count ? true : false;
+ }
+ }
+
+ public bool HasPrev()
+ {
+ if (IsTrackIndexInvalid())
+ {
+ return false;
+ }
+ if (RepeatMode == RepeatMode.RepeatOne || RepeatMode == RepeatMode.RepeatAll)
+ {
+ return true;
+ }
+ else
+ {
+ return currentIndex - 1 >= 0 ? true : false;
+ }
+ }
+
+ public Track Current()
+ {
+ if (IsTrackIndexInvalid())
+ {
+ return null;
+ }
+ else
+ {
+ return tracklistViewModel[shuffleList[currentIndex]];
+ }
+ }
+
+ public void SetPlayingTrack(string mediaId)
+ {
+ int count;
+ for (count = 0; count< tracklistViewModel.Count; ++count)
+ {
+ if (mediaId == tracklistViewModel[count].Id)
+ {
+ currentIndex = count;
+ return;
+ }
+ }
+ currentIndex = -1;
+ }
+
+ public void SetPlayingTrack(Track track)
+ {
+ int count;
+ for (count = 0; count < tracklistViewModel.Count; ++count)
+ {
+ if (track == tracklistViewModel[count])
+ {
+ Tizen.Log.Debug(AppConstants.LogTag, "Current track index is " + count);
+ currentIndex = count;
+ return;
+ }
+ }
+ currentIndex = -1;
+ }
+
+ private bool IsTrackIndexInvalid()
+ {
+ if(currentIndex < 0 || currentIndex > shuffleList.Count)
+ {
+ return true;
+ }
+ return false;
+ }
+ }
+}
--- /dev/null
+using System.Collections.Specialized;\r
+using MusicPlayer.Models;\r
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.ViewModels\r
+{\r
+ using AudioInfo = Tizen.Content.MediaContent.AudioInfo;\r
+ class TrackViewModel : PropertyNotifier\r
+ {\r
+ public TrackViewModel()\r
+ {\r
+ OrderedDictionary trackList = TrackDataProvider.CurrentTrackList();\r
+ listViewModel = new ListViewModel<Track>();\r
+ listViewModel.CreateData<AudioInfo>(trackList);\r
+ listViewModel.CollectionChanged += OnTrackListChanges;\r
+ TrackCount = listViewModel.Count.ToString();\r
+ }\r
+\r
+ private void OnTrackListChanges(object sender, NotifyCollectionChangedEventArgs e)\r
+ {\r
+ TrackCount = listViewModel.Count.ToString();\r
+ }\r
+\r
+ private ListViewModel<Track> listViewModel;\r
+\r
+ public ListViewModel<Track> ListViewModel\r
+ {\r
+ get => listViewModel;\r
+ }\r
+\r
+ private string trackCount;\r
+\r
+ public string TrackCount\r
+ {\r
+ get => trackCount;\r
+ set\r
+ {\r
+ string text = string.Equals(value, "1") ? " track" : " tracks";\r
+ SetProperty(ref trackCount, value + text);\r
+ }\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using Tizen.NUI.Components;\r
+using Tizen.NUI.BaseComponents;\r
+using Tizen.NUI;\r
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.Views\r
+{\r
+ class AlbumDetailLayout : RecyclerViewItem\r
+ {\r
+ private View itemSeperator;\r
+ private TextLabel titleLabel;\r
+ private TextLabel subtitleLabel;\r
+ private TextLabel additionalLabel;\r
+\r
+ private const int LayoutMargin = 16;\r
+ private const int LayoutPadding = 32;\r
+ private const int SeperatorHeight = 1;\r
+ private const int LeftPadding = 64;\r
+ private const int X = 0;\r
+\r
+ public AlbumDetailLayout(int width = 832, int height = 108) : base()\r
+ {\r
+ base.OnInitialize();\r
+ base.IsCreateByXaml = true;\r
+ WidthSpecification = width;\r
+ HeightSpecification = height;\r
+\r
+ // to show the rounded rect of the bg\r
+ BackgroundColor = Color.Transparent;\r
+\r
+ titleLabel = CreateTitleLabel();\r
+ subtitleLabel = CreateSubTitleLabel();\r
+ additionalLabel = CreateAdditionalLabel(width);\r
+ itemSeperator = CreateItemSeparator(width, height);\r
+ IsCreateByXaml = true;\r
+ }\r
+\r
+ private TextLabel CreateTitleLabel()\r
+ {\r
+ TextLabel titleLabel = new TextLabel()\r
+ {\r
+ Size2D = new Size2D(596, 40),\r
+ TextColor = UIColors.HEX001447,\r
+ PixelSize = 32,\r
+ FontFamily = "BreezeSans",\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ Padding=new Extents(LayoutPadding,0,0,0),\r
+ IsCreateByXaml = true,\r
+ Position2D = new Position2D(X , LayoutMargin),\r
+ };\r
+ base.Add(titleLabel);\r
+ return titleLabel;\r
+ }\r
+\r
+ private TextLabel CreateSubTitleLabel()\r
+ {\r
+ TextLabel subtitleLabel = new TextLabel()\r
+ {\r
+ Size2D= new Size2D(596,36),\r
+ TextColor = UIColors.HEX001447,\r
+ PixelSize = 28,\r
+ FontFamily = "BreezeSans",\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ Padding = new Extents(LayoutPadding, 0, 0, 0),\r
+ IsCreateByXaml = true,\r
+ Position2D = new Position2D(X , LayoutMargin + 40)\r
+ };\r
+ base.Add(subtitleLabel);\r
+ return subtitleLabel;\r
+ }\r
+\r
+ private TextLabel CreateAdditionalLabel(int width)\r
+ {\r
+ TextLabel additionalLabel = new TextLabel()\r
+ {\r
+ Size2D= new Size2D(108,36),\r
+ TextColor = UIColors.HEX001447,\r
+ PixelSize = 28,\r
+ FontFamily = "BreezeSans",\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ HorizontalAlignment =HorizontalAlignment.End,\r
+ IsCreateByXaml = true,\r
+ Position2D = new Position2D(width-LayoutPadding-LeftPadding-108, 36)\r
+ };\r
+ base.Add(additionalLabel);\r
+ return additionalLabel;\r
+ }\r
+\r
+ private View CreateItemSeparator(int width, int height)\r
+ {\r
+ View itemSeperator = new View()\r
+ {\r
+ Size2D = new Size2D(width, SeperatorHeight),\r
+ ExcludeLayouting = true,\r
+ Position2D = new Position2D(X , height - SeperatorHeight),\r
+ BackgroundColor = UIColors.ItemSeperator,\r
+ };\r
+ base.Add(itemSeperator);\r
+ return itemSeperator;\r
+ }\r
+\r
+ public TextLabel TitleLabel\r
+ {\r
+ get => titleLabel;\r
+ }\r
+ public TextLabel SubtitleLabel\r
+ {\r
+ get => subtitleLabel;\r
+ }\r
+ public TextLabel AdditionalLabel\r
+ {\r
+ get => additionalLabel;\r
+ }\r
+\r
+ protected override void Dispose(DisposeTypes type)\r
+ {\r
+ if (Disposed)\r
+ {\r
+ return;\r
+ }\r
+ if (type == DisposeTypes.Explicit)\r
+ {\r
+ base.Remove(itemSeperator);\r
+ itemSeperator?.Dispose();\r
+ itemSeperator = null;\r
+\r
+ base.Remove(titleLabel);\r
+ titleLabel?.Dispose();\r
+ titleLabel = null;\r
+\r
+ base.Remove(subtitleLabel);\r
+ subtitleLabel?.Dispose();\r
+ subtitleLabel = null;\r
+\r
+ base.Remove(additionalLabel);\r
+ additionalLabel?.Dispose();\r
+ additionalLabel = null;\r
+ }\r
+ base.Dispose(type);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using MusicPlayer.ViewModels;\r
+using Tizen.NUI.Components;\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
+ class AlbumDetailView : View\r
+ {\r
+ private const int LayoutPadding = 64;\r
+ private const int IconSize = 48;\r
+ private const int AlbumArtSize = 520;\r
+ private const int ControlViewWidth = 960;\r
+ private const int ControlViewHeight = 60;\r
+ private const int ControlViewMargin = 6;\r
+\r
+ private BaseView baseView;\r
+ private View contentView;\r
+ private View leftView;\r
+ private View rightView;\r
+ private ImageView albumArtIcon;\r
+ private TextLabel albumNameLabel;\r
+ private TextLabel albumArtistLabel;\r
+ private View controlsView;\r
+ private TextLabel trackCountLabel;\r
+ private Button playAllIcon; // TODO need to implement playall feature\r
+ private Button shuffleAndPlayAllIcon; // TODO need to implement playlist manager\r
+ private CollectionView collectionView;\r
+\r
+ private AlbumDetailViewModel viewModel;\r
+ public AlbumDetailView(AlbumDetailViewModel viewModel) : base()\r
+ {\r
+ this.viewModel = viewModel;\r
+ BindingContext = viewModel;\r
+ BackgroundColor = UIColors.HEXEEEFF1;\r
+ WidthResizePolicy = ResizePolicyType.FillToParent;\r
+ HeightResizePolicy = ResizePolicyType.FillToParent;\r
+\r
+ //TODO need to change this part after implementation of Command Interface\r
+ baseView = new BaseView()\r
+ {\r
+ Title = viewModel.AlbumName,\r
+ BackButton = true,\r
+ MoreButton = true,\r
+ SearchButton = true,\r
+ BackgroundColor = UIColors.HEXEEEFF1,\r
+ };\r
+ base.Add(baseView);\r
+ contentView = new View()\r
+ {\r
+ WidthSpecification = LayoutParamPolicies.MatchParent,\r
+ HeightSpecification = 876,\r
+ Layout = new FlexLayout()\r
+ {\r
+ Direction = FlexLayout.FlexDirection.Row,\r
+ ItemsAlignment = FlexLayout.AlignmentType.FlexStart,\r
+ Justification = FlexLayout.FlexJustification.FlexStart,\r
+ },\r
+ };\r
+ baseView.SetContent = contentView;\r
+\r
+ leftView = CreateLeftView();\r
+ rightView = CreateRightView();\r
+ controlsView = AddControlView();\r
+ AddControlElements();\r
+ collectionView = AddCollectionView();\r
+ AddAlbumArt();\r
+ AddAlbumInfo();\r
+ }\r
+\r
+ private void OnTrackSelection(object sender, SelectionChangedEventArgs e)\r
+ {\r
+\r
+ }\r
+\r
+ private Button CreateButton(string url, int x, int y)\r
+ {\r
+ ButtonStyle buttonStyle = new ButtonStyle()\r
+ {\r
+ Icon = new ImageViewStyle()\r
+ {\r
+ ResourceUrl = url,\r
+ },\r
+ IsSelectable = false,\r
+ IsEnabled = true,\r
+ };\r
+\r
+ Button button = new Button(buttonStyle)\r
+ {\r
+ Size2D = new Size2D(IconSize, IconSize),\r
+ Position2D = new Position2D(x, y),\r
+ };\r
+ return button;\r
+ }\r
+\r
+ private View CreateLeftView()\r
+ {\r
+ View leftView = new View()\r
+ {\r
+ BackgroundColor = UIColors.HEXEEEFF1,\r
+ Size2D = new Size2D(Window.Instance.WindowSize.Width / 2, 752),\r
+ Position2D = new Position2D(0, 0),\r
+ Layout = new FlexLayout\r
+ {\r
+ Direction = FlexLayout.FlexDirection.Column,\r
+ ItemsAlignment = FlexLayout.AlignmentType.Center,\r
+ Justification = FlexLayout.FlexJustification.FlexStart,\r
+ },\r
+ Padding = new Extents(0, 0, ControlViewHeight, 42),\r
+ };\r
+ contentView.Add(leftView);\r
+ return leftView;\r
+ }\r
+\r
+ private View CreateRightView()\r
+ {\r
+ View rightView = new View()\r
+ {\r
+ BackgroundColor = UIColors.HEXEEEFF1,\r
+ Size2D = new Size2D(Window.Instance.WindowSize.Width / 2, 752),\r
+ Position2D = new Position2D(Window.Instance.WindowSize.Width / 2, 0),\r
+ Layout = new FlexLayout\r
+ {\r
+ Direction = FlexLayout.FlexDirection.Column,\r
+ ItemsAlignment = FlexLayout.AlignmentType.Center,\r
+ Justification = FlexLayout.FlexJustification.FlexStart,\r
+ },\r
+ };\r
+ contentView.Add(rightView);\r
+ return rightView;\r
+ }\r
+\r
+ private void AddAlbumArt()\r
+ {\r
+ albumArtIcon = new ImageView()\r
+ {\r
+ BackgroundColor = UIColors.HEXEEEFF1,\r
+ Size2D = new Size2D(AlbumArtSize, AlbumArtSize),\r
+ };\r
+ albumArtIcon.SetBinding(ImageView.ResourceUrlProperty, "AlbumArtPath");\r
+ leftView.Add(albumArtIcon);\r
+ }\r
+ private void AddAlbumInfo()\r
+ {\r
+ albumNameLabel = new TextLabel()\r
+ {\r
+ Text = "ALBUM NAME",\r
+ Size2D = new Size2D(640, 48),\r
+ PixelSize = 36,\r
+ Margin = new Extents(0, 0, 32, 0),\r
+ FontFamily = "BreezeSans",\r
+ TextColor = UIColors.HEX001447,\r
+ HorizontalAlignment = HorizontalAlignment.Center,\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ Ellipsis = true,\r
+ };\r
+ albumNameLabel.SetBinding(TextLabel.TextProperty, "AlbumName");\r
+ leftView.Add(albumNameLabel);\r
+ albumArtistLabel = new TextLabel()\r
+ {\r
+ Text = "ARTIST NAME",\r
+ Size2D = new Size2D(640, 36),\r
+ PixelSize = 28,\r
+ Margin = new Extents(0, 0, 14, 0),\r
+ FontFamily = "BreezeSans",\r
+ TextColor = UIColors.HEX000209,\r
+ HorizontalAlignment = HorizontalAlignment.Center,\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ Ellipsis = true,\r
+ };\r
+ albumArtistLabel.SetBinding(TextLabel.TextProperty, "ArtistName");\r
+ leftView.Add(albumArtistLabel);\r
+\r
+ }\r
+ private View AddControlView()\r
+ {\r
+ View controlsView = new View()\r
+ {\r
+ BackgroundColor = UIColors.HEXEEEFF1,\r
+ Size2D = new Size2D(ControlViewWidth, ControlViewHeight),\r
+ Padding = new Extents(LayoutPadding, LayoutPadding, ControlViewMargin, ControlViewMargin),\r
+ };\r
+ rightView.Add(controlsView);\r
+ return controlsView;\r
+ }\r
+\r
+ private void AddControlElements()\r
+ {\r
+ trackCountLabel = new TextLabel()\r
+ {\r
+ Text = "TRACK COUNT",\r
+ Size2D = new Size2D(664, 36),\r
+ Position2D = new Position2D(LayoutPadding, 12),\r
+ PixelSize = 28,\r
+ Margin = new Extents(0, 0, ControlViewMargin, ControlViewMargin),\r
+ FontFamily = "BreezeSans",\r
+ TextColor = UIColors.HEX001447,\r
+ HorizontalAlignment = HorizontalAlignment.Begin,\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ };\r
+ trackCountLabel.SetBinding(TextLabel.TextProperty, "TotalTracks");\r
+ controlsView.Add(trackCountLabel);\r
+\r
+ playAllIcon = CreateButton(Resources.GetImagePath() + "playlist_active.png.png", Window.Instance.WindowSize.Width / 2 - LayoutPadding - IconSize, ControlViewMargin);\r
+ playAllIcon.Margin = new Extents(40, 0, 0, 0);\r
+ controlsView.Add(playAllIcon);\r
+\r
+ shuffleAndPlayAllIcon = CreateButton(Resources.GetImagePath() + "shuffle_on.png", Window.Instance.WindowSize.Width / 2 - LayoutPadding - 2 * IconSize - 40, ControlViewMargin);\r
+ playAllIcon.Margin = new Extents(32, 0, 0, 0);\r
+ controlsView.Add(shuffleAndPlayAllIcon);\r
+\r
+ }\r
+\r
+ private CollectionView AddCollectionView()\r
+ {\r
+ CollectionView collectionView = new CollectionView()\r
+ {\r
+ Size2D = new Size2D(832, 108),\r
+ BackgroundImage = Resources.GetImagePath() + "list_view_bg.png",\r
+ ItemsLayouter = new LinearLayouter(),\r
+ ItemTemplate = new DataTemplate(() =>\r
+ {\r
+ AlbumDetailLayout layout = new AlbumDetailLayout();\r
+ layout.TitleLabel.SetBinding(TextLabel.TextProperty, "TrackTitle");\r
+ layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName");\r
+ layout.AdditionalLabel.SetBinding(TextLabel.TextProperty, "Duration");\r
+ return layout;\r
+ }),\r
+ ScrollingDirection = ScrollableBase.Direction.Vertical,\r
+ HeightSpecification = LayoutParamPolicies.WrapContent,\r
+ SelectionMode = ItemSelectionMode.Single,\r
+ };\r
+ rightView.Add(collectionView);\r
+ FlexLayout.SetFlexGrow(collectionView, 1);\r
+ FlexLayout.SetFlexShrink(collectionView, 1);\r
+ collectionView.ItemsSource = viewModel.ListViewModel;\r
+ collectionView.SelectionChanged += OnTrackSelection;\r
+ return collectionView;\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using MusicPlayer.ViewModels;\r
+using Tizen.NUI.Components;\r
+using Tizen.NUI.BaseComponents;\r
+using Tizen.NUI;\r
+using Tizen.NUI.Binding;\r
+using MusicPlayer.Common;\r
+using MusicPlayer.Models;\r
+\r
+namespace MusicPlayer.Views\r
+{\r
+ class AlbumView : BaseContentView\r
+ {\r
+ private AlbumViewModel viewModel;\r
+ private TextLabel albumCountLabel;\r
+\r
+ public AlbumView(AlbumViewModel viewModel)\r
+ {\r
+ this.viewModel = viewModel;\r
+ BindingContext = viewModel;\r
+ collectionView.ItemsSource = viewModel.ListViewModel;\r
+ collectionView.ItemTemplate = new DataTemplate(() =>\r
+ {\r
+ ListItemLayout layout = new ListItemLayout();\r
+ layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "AlbumArtPath");\r
+ layout.TitleLabel.SetBinding(TextLabel.TextProperty, "AlbumName");\r
+ layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName");\r
+ return layout;\r
+ });\r
+ collectionView.ScrollingDirection = ScrollableBase.Direction.Vertical;\r
+ collectionView.WidthSpecification = LayoutParamPolicies.WrapContent;\r
+ collectionView.SelectionMode = ItemSelectionMode.Single;\r
+ collectionView.SelectionChanged += OnAlbumSelection;\r
+\r
+ albumCountLabel = new TextLabel()\r
+ {\r
+ PixelSize = 28,\r
+ Text = "ALBUM COUNT",\r
+ TextColor = UIColors.HEX001447,\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ FontFamily = "BreezeSans",\r
+ IsCreateByXaml = true,\r
+ };\r
+ titleView.Add(albumCountLabel);\r
+ albumCountLabel.SetBinding(TextLabel.TextProperty, "AlbumCount");\r
+ RelativeLayout.SetLeftTarget(albumCountLabel, titleView);\r
+ RelativeLayout.SetLeftRelativeOffset(albumCountLabel, 1.0f);\r
+ RelativeLayout.SetRightRelativeOffset(albumCountLabel, 0.0f);\r
+ RelativeLayout.SetFillHorizontal(albumCountLabel, true);\r
+ }\r
+ private void OnAlbumSelection(object sender, SelectionChangedEventArgs e)\r
+ {\r
+ MusicAlbum currentAlbum= (MusicAlbum)collectionView.SelectedItem;\r
+ // viewModel.getDetailViewModel(currentAlbum) => need to replace direct function call on viewModel class with command interface\r
+ AlbumDetailView view = new AlbumDetailView(viewModel.getDetailViewModel(currentAlbum));\r
+ Window.Instance.Add(view);\r
+ }\r
+ protected override void Dispose(DisposeTypes type)\r
+ {\r
+ if (Disposed)\r
+ {\r
+ return;\r
+ }\r
+ if (type == DisposeTypes.Explicit)\r
+ {\r
+ titleView.Remove(albumCountLabel);\r
+ albumCountLabel.Dispose();\r
+ albumCountLabel = null;\r
+ }\r
+ base.Dispose(type);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Views
+{
+ class ArtistDetailGroupLayout : RecyclerViewItem
+ {
+ private static int Width = 1792;
+ private static int Height = 108;
+
+ private const int IconSize = 64;
+ private const int LayoutPadding = 32;
+ private const int SeperatorHeight = 1;
+ private const int LeftPadding = 64;
+ private const int x = 0;
+
+ private View itemSeperator;
+ private TextLabel titleLabel;
+ private ImageView icon;
+
+ public ArtistDetailGroupLayout(int width = 1792, int height = 108) : base()
+ {
+ base.OnInitialize();
+ base.IsCreateByXaml = true;
+ Width = width;
+ Height = height;
+ WidthSpecification = Width;
+ HeightSpecification = Height;
+
+ // to show the rounded rect of the bg
+ BackgroundColor = Color.Transparent;
+
+ icon = CreateIcon();
+ titleLabel = CreateTitleLabel();
+ itemSeperator = CreateItemSeparator();
+ IsCreateByXaml = true;
+ }
+
+ private ImageView CreateIcon()
+ {
+ ImageView icon = new ImageView()
+ {
+ WidthSpecification = IconSize,
+ HeightSpecification = IconSize,
+ IsCreateByXaml = true,
+ Position2D = new Position2D(x, (Height / 2) - (IconSize / 2)),
+ };
+ base.Add(icon);
+ return icon;
+ }
+
+ private View CreateItemSeparator()
+ {
+ View itemSeperator = new View()
+ {
+ WidthSpecification = (Width - (2 * LeftPadding)),
+ HeightSpecification = SeperatorHeight,
+ ExcludeLayouting = true,
+ Position2D = new Position2D(x, Height - SeperatorHeight),
+ BackgroundColor = UIColors.ItemSeperator,
+ };
+ base.Add(itemSeperator);
+ return itemSeperator;
+ }
+
+ private TextLabel CreateTitleLabel()
+ {
+ TextLabel titleLabel = new TextLabel()
+ {
+ WidthSpecification = (Width - (2 * LeftPadding) - IconSize - LayoutPadding),
+ HeightSpecification = 40,
+ TextColor = UIColors.HEX001447,
+ PixelSize = 32,
+ FontFamily = "BreezeSans",
+ VerticalAlignment = VerticalAlignment.Center,
+ IsCreateByXaml = true,
+ Position2D = new Position2D(x + IconSize + LayoutPadding, 34),
+ };
+ base.Add(titleLabel);
+ return titleLabel;
+ }
+
+ public ImageView Icon
+ {
+ get => icon;
+ }
+
+ public TextLabel TitleLabel
+ {
+ get => titleLabel;
+ }
+
+ protected override void Dispose(DisposeTypes type)
+ {
+ if (Disposed)
+ {
+ return;
+ }
+ if (type == DisposeTypes.Explicit)
+ {
+ base.Remove(itemSeperator);
+ itemSeperator?.Dispose();
+ itemSeperator = null;
+
+ base.Remove(icon);
+ icon?.Dispose();
+ icon = null;
+
+ base.Remove(titleLabel);
+ titleLabel?.Dispose();
+ titleLabel = null;
+ }
+ base.Dispose(type);
+ }
+ }
+}
--- /dev/null
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Views
+{
+ class ArtistDetailItemLayout : RecyclerViewItem
+ {
+ private static int Width = 1792;
+ private static int Height = 108;
+
+ private const int LayoutPadding = 32;
+ private const int SeperatorHeight = 1;
+ private const int LeftPadding = 64;
+ private const int x = 0;
+
+ private View itemSeperator;
+ private TextLabel titleLabel;
+ private TextLabel extraLabel;
+
+ public ArtistDetailItemLayout(int width = 1792, int height = 108) : base()
+ {
+ base.OnInitialize();
+ base.IsCreateByXaml = true;
+ Width = width;
+ Height = height;
+ WidthSpecification = Width;
+ HeightSpecification = Height;
+
+ // to show the rounded rect of the bg
+ BackgroundColor = Color.Transparent;
+
+ titleLabel = CreateTitleLabel();
+ extraLabel = CreateExtraLabel();
+ itemSeperator = CreateItemSeparator();
+ IsCreateByXaml = true;
+ }
+
+ private View CreateItemSeparator()
+ {
+ View itemSeperator = new View()
+ {
+ WidthSpecification = (Width - (2 * LeftPadding)),
+ HeightSpecification = SeperatorHeight,
+ ExcludeLayouting = true,
+ Position2D = new Position2D(x, Height - SeperatorHeight),
+ BackgroundColor = UIColors.ItemSeperator,
+ };
+ base.Add(itemSeperator);
+ return itemSeperator;
+ }
+
+ private TextLabel CreateTitleLabel()
+ {
+ TextLabel titleLabel = new TextLabel()
+ {
+ WidthSpecification = 1272,
+ HeightSpecification = 40,
+ TextColor = UIColors.HEX001447,
+ PixelSize = 32,
+ FontFamily = "BreezeSans",
+ VerticalAlignment = VerticalAlignment.Center,
+ IsCreateByXaml = true,
+ Position2D = new Position2D(x, 34),
+ };
+ base.Add(titleLabel);
+ return titleLabel;
+ }
+
+ private TextLabel CreateExtraLabel()
+ {
+ TextLabel extraLabel = new TextLabel()
+ {
+ WidthSpecification = 360,
+ HeightSpecification = 36,
+ TextColor = UIColors.HEX001447,
+ PixelSize = 28,
+ FontFamily = "BreezeSans",
+ VerticalAlignment = VerticalAlignment.Center,
+ HorizontalAlignment = HorizontalAlignment.End,
+ IsCreateByXaml = true,
+ Position2D = new Position2D((x + 1272 + LayoutPadding), 36)
+ };
+ base.Add(extraLabel);
+ return extraLabel;
+ }
+
+ public TextLabel TitleLabel
+ {
+ get => titleLabel;
+ }
+
+ public TextLabel ExtraLabel
+ {
+ get => extraLabel;
+ }
+
+ protected override void Dispose(DisposeTypes type)
+ {
+ if (Disposed)
+ {
+ return;
+ }
+ if (type == DisposeTypes.Explicit)
+ {
+ base.Remove(itemSeperator);
+ itemSeperator?.Dispose();
+ itemSeperator = null;
+
+ base.Remove(titleLabel);
+ titleLabel?.Dispose();
+ titleLabel = null;
+
+ base.Remove(extraLabel);
+ extraLabel?.Dispose();
+ extraLabel = null;
+ }
+ base.Dispose(type);
+ }
+ }
+}
--- /dev/null
+using MusicPlayer.ViewModels;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+using MusicPlayer.Common;
+using MusicPlayer.Models;
+
+namespace MusicPlayer.Views
+{
+ class ArtistDetailView : View //BaseContentView
+ {
+ private const int LayoutPadding = 64;
+ private const int IconSize = 48;
+
+ private BaseView baseView;
+ private View contentView;
+ private View topView;
+ private TextLabel totalCountLabel;
+ private Button playAllIcon; // TODO need to implement playall feature
+ private Button shuffleAndPlayAllIcon; // TODO need to implement playlist manager
+ private CollectionView collectionView;
+
+ private ArtistDetailViewModel viewModel;
+
+ public ArtistDetailView(ArtistDetailViewModel viewModel) : base()
+ {
+ this.viewModel = viewModel;
+ BindingContext = viewModel;
+ BackgroundColor = UIColors.HEXEEEFF1;
+ WidthResizePolicy = ResizePolicyType.FillToParent;
+ HeightResizePolicy = ResizePolicyType.FillToParent;
+
+ //TODO need to change this part after implementation of Command Interface
+ baseView = new BaseView()
+ {
+ Title = viewModel.ArtistName,
+ BackButton = true,
+ MoreButton = true,
+ SearchButton = true,
+ BackgroundColor = UIColors.HEXEEEFF1,
+ };
+ base.Add(baseView);
+ contentView = new View()
+ {
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightSpecification = 876,
+ Layout = new FlexLayout()
+ {
+ Direction = FlexLayout.FlexDirection.Column,
+ Padding = new Extents(LayoutPadding, LayoutPadding, 0, 0),
+ },
+ };
+ baseView.SetContent = contentView;
+
+ topView = CreateTopView();
+ AddTitle();
+ AddButtons();
+ collectionView = AddCollectionView();
+ }
+
+ private void OnTrackSelection(object sender, SelectionChangedEventArgs e)
+ {
+
+ }
+
+ private Button CreateButton(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(IconSize, IconSize),
+ Position2D = new Position2D(x, y),
+ };
+ return button;
+ }
+
+ private View CreateTopView()
+ {
+ View topView = new View()
+ {
+ BackgroundColor = UIColors.HEXEEEFF1,
+ Size2D = new Size2D(Window.Instance.WindowSize.Width - 2 * LayoutPadding, 60),
+ };
+ contentView.Add(topView);
+ return topView;
+ }
+
+ private void AddTitle()
+ {
+ totalCountLabel = new TextLabel()
+ {
+ Size2D = new Size2D(1624, 36),
+ Position2D = new Position2D(0, 12),
+ PixelSize = 28,
+ Text = "TOTAL COUNT",
+ TextColor = UIColors.HEX001447,
+ VerticalAlignment = VerticalAlignment.Center,
+ FontFamily = "BreezeSans",
+ IsCreateByXaml = true,
+ };
+ topView.Add(totalCountLabel);
+ totalCountLabel.SetBinding(TextLabel.TextProperty, "TotalCount");
+ }
+
+ private void AddButtons()
+ {
+ playAllIcon = CreateButton(Resources.GetImagePath() + "playlist_active.png", Window.Instance.WindowSize.Width - 2 * LayoutPadding - IconSize, 6);
+ playAllIcon.Margin = new Extents(40, 0, 0, 0);
+ topView.Add(playAllIcon);
+
+ shuffleAndPlayAllIcon = CreateButton(Resources.GetImagePath() + "shuffle_on.png", Window.Instance.WindowSize.Width - 2 * LayoutPadding - 2 * IconSize - 40, 6);
+ playAllIcon.Margin = new Extents(32, 0, 0, 0);
+ topView.Add(shuffleAndPlayAllIcon);
+ }
+
+ private CollectionView AddCollectionView()
+ {
+ CollectionView collectionView = new CollectionView()
+ {
+ Size2D = new Size2D(1792, 108),
+ BackgroundImage = Resources.GetImagePath() + "list_view_bg.png",
+ ItemsLayouter = new LinearLayouter(),
+ ItemTemplate = new DataTemplate(() =>
+ {
+ ArtistDetailItemLayout layout = new ArtistDetailItemLayout();
+ layout.TitleLabel.SetBinding(TextLabel.TextProperty, "TrackTitle");
+ layout.ExtraLabel.SetBinding(TextLabel.TextProperty, "Duration");
+ return layout;
+ }),
+ GroupHeaderTemplate = new DataTemplate(() =>
+ {
+ ArtistDetailGroupLayout group = new ArtistDetailGroupLayout();
+ group.Icon.SetBinding(ImageView.ResourceUrlProperty, "AlbumArtPath");
+ group.TitleLabel.SetBinding(TextLabel.TextProperty, "AlbumName");
+ return group;
+ }),
+ IsGrouped = true,
+ ScrollingDirection = ScrollableBase.Direction.Vertical,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ SelectionMode = ItemSelectionMode.Single,
+ };
+ contentView.Add(collectionView);
+ FlexLayout.SetFlexGrow(collectionView, 1);
+ FlexLayout.SetFlexShrink(collectionView, 1);
+ collectionView.ItemsSource = viewModel.GroupListViewModel;
+ collectionView.SelectionChanged += OnTrackSelection;
+ return collectionView;
+ }
+ }
+}
--- /dev/null
+using MusicPlayer.ViewModels;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+using MusicPlayer.Common;
+using MusicPlayer.Models;
+
+namespace MusicPlayer.Views
+{
+ class ArtistView : BaseContentView
+ {
+ private ArtistViewModel viewModel;
+ private TextLabel artistCountLabel;
+
+ public ArtistView(ArtistViewModel viewModel)
+ {
+ this.viewModel = viewModel;
+ BindingContext = viewModel;
+ collectionView.ItemsSource = viewModel.ListViewModel;
+ collectionView.ItemTemplate = new DataTemplate(() =>
+ {
+ ListItemLayout layout = new ListItemLayout();
+ layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "AlbumArtPath");
+ layout.TitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName");
+ layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "TotalCount");
+ return layout;
+ });
+ collectionView.ScrollingDirection = ScrollableBase.Direction.Vertical;
+ collectionView.WidthSpecification = LayoutParamPolicies.WrapContent;
+ collectionView.SelectionMode = ItemSelectionMode.Single;
+ collectionView.SelectionChanged += OnArtistSelection;
+
+ artistCountLabel = new TextLabel()
+ {
+ PixelSize = 28,
+ Text = "ARTIST COUNT",
+ TextColor = UIColors.HEX001447,
+ VerticalAlignment = VerticalAlignment.Center,
+ FontFamily = "BreezeSans",
+ IsCreateByXaml = true,
+ };
+ titleView.Add(artistCountLabel);
+ artistCountLabel.SetBinding(TextLabel.TextProperty, "ArtistCount");
+ RelativeLayout.SetLeftTarget(artistCountLabel, titleView);
+ RelativeLayout.SetLeftRelativeOffset(artistCountLabel, 1.0f);
+ RelativeLayout.SetRightRelativeOffset(artistCountLabel, 0.0f);
+ RelativeLayout.SetFillHorizontal(artistCountLabel, true);
+ }
+ private void OnArtistSelection(object sender, SelectionChangedEventArgs e)
+ {
+ Artist currentArtist = (Artist)collectionView.SelectedItem;
+ ArtistDetailView view = new ArtistDetailView(viewModel.getDetailViewModel(currentArtist));
+ Window.Instance.Add(view);
+ }
+ protected override void Dispose(DisposeTypes type)
+ {
+ if (Disposed)
+ {
+ return;
+ }
+ if (type == DisposeTypes.Explicit)
+ {
+ titleView.Remove(artistCountLabel);
+ artistCountLabel.Dispose();
+ artistCountLabel = null;
+ }
+ base.Dispose(type);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using MusicPlayer.Common;\r
+using Tizen.NUI;\r
+using Tizen.NUI.BaseComponents;\r
+using Tizen.NUI.Components;\r
+\r
+namespace MusicPlayer.Views\r
+{\r
+ class BaseContentView : View\r
+ {\r
+ protected View titleView;\r
+ protected CollectionView collectionView;\r
+ public BaseContentView() : base()\r
+ {\r
+ ThemeChangeSensitive = true;\r
+ WidthResizePolicy = ResizePolicyType.FillToParent;\r
+ HeightResizePolicy = ResizePolicyType.FillToParent;\r
+ Layout = new FlexLayout()\r
+ {\r
+ Direction = FlexLayout.FlexDirection.Column,\r
+ Padding = new Extents(64, 64, 0, 0),\r
+ };\r
+ titleView = new View()\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ WidthSpecification = LayoutParamPolicies.MatchParent,\r
+ HeightSpecification = 60,\r
+ Layout = new RelativeLayout()\r
+ {\r
+ Padding = new Extents(0, 0, 13, 13),\r
+ },\r
+ };\r
+ base.Add(titleView);\r
+ FlexLayout.SetFlexGrow(titleView, 0);\r
+ FlexLayout.SetFlexShrink(titleView, 0);\r
+\r
+ collectionView = new CollectionView()\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ Size2D = new Size2D(1792, 108),\r
+ Margin = new Extents(0, 0, 0, 2),\r
+ BackgroundImage = GetBackgroundImagePath(ThemeManager.PlatformThemeId),\r
+ ItemsLayouter = new LinearLayouter(),\r
+ ScrollingDirection = ScrollableBase.Direction.Vertical,\r
+ WidthSpecification = LayoutParamPolicies.MatchParent,\r
+ HeightSpecification = LayoutParamPolicies.WrapContent,\r
+ SelectionMode = ItemSelectionMode.Single,\r
+ };\r
+ base.Add(collectionView);\r
+ FlexLayout.SetFlexGrow(collectionView, 1);\r
+ FlexLayout.SetFlexShrink(collectionView, 1);\r
+ }\r
+\r
+ private string GetBackgroundImagePath(string platformThemeId)\r
+ {\r
+ if(platformThemeId.Equals(AppConstants.DarkPlatformThemeId))\r
+ {\r
+ return Resources.GetImagePath() + "dark/list_view_bg.png";\r
+ }\r
+ else\r
+ {\r
+ return Resources.GetImagePath() + "light/list_view_bg.png";\r
+ }\r
+ }\r
+\r
+ protected override void OnThemeChanged(object sender, ThemeChangedEventArgs e)\r
+ {\r
+ base.OnThemeChanged(sender, e);\r
+ if(e.IsPlatformThemeChanged)\r
+ {\r
+ collectionView.BackgroundImage = GetBackgroundImagePath(e.PlatformThemeId);\r
+ }\r
+ }\r
+\r
+ protected override void Dispose(DisposeTypes type)\r
+ {\r
+ if (type == DisposeTypes.Explicit)\r
+ {\r
+ base.Remove(titleView);\r
+ titleView.Dispose();\r
+ titleView = null;\r
+\r
+ base.Remove(collectionView);\r
+ collectionView.Dispose();\r
+ collectionView = null;\r
+ }\r
+ base.Dispose(type);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System.Collections.Generic;\r
+using Tizen.NUI;\r
+using Tizen.NUI.BaseComponents;\r
+using Tizen.NUI.Components;\r
+using Tizen.NUI.Binding;\r
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.Views\r
+{\r
+ class BaseView : View\r
+ {\r
+ private View topView;\r
+ private View bottomView; // TODO Used this for MiniController UI\r
+ private View contentView;\r
+ private TextLabel titleLabel;\r
+ private Button backButton;\r
+ private Button moreButton;\r
+ private Button searchButton;\r
+ private Tab tabs;\r
+\r
+ // TODO these name strings are temporary...once the po files are added\r
+ // need to use Translatable names.\r
+ private static string[] TabNames = new string[]\r
+ {\r
+ "Playlists",\r
+ "Tracks",\r
+ "Albums",\r
+ "Artists",\r
+ };\r
+ public BaseView() : base()\r
+ {\r
+ ThemeChangeSensitive = true;\r
+ WidthSpecification = LayoutParamPolicies.MatchParent;\r
+ HeightSpecification = LayoutParamPolicies.MatchParent;\r
+ Layout = new FlexLayout()\r
+ {\r
+ Direction = FlexLayout.FlexDirection.Column,\r
+ ItemsAlignment = FlexLayout.AlignmentType.FlexStart,\r
+ Justification = FlexLayout.FlexJustification.FlexStart,\r
+ };\r
+ topView = new View()\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ WidthSpecification = LayoutParamPolicies.MatchParent,\r
+ HeightSpecification = 120,\r
+ Layout = new RelativeLayout()\r
+ {\r
+ Padding = new Extents(64, 64, 30, 30),\r
+ },\r
+ };\r
+ base.Add(topView);\r
+ FlexLayout.SetFlexGrow(topView, 0);\r
+ FlexLayout.SetFlexShrink(topView, 0);\r
+ titleLabel = new TextLabel()\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ Text = "Music",\r
+ PixelSize = 40,\r
+ FontFamily = "BreezeSans",\r
+ TextColor = UIColors.HEX000209,\r
+ HorizontalAlignment = HorizontalAlignment.Begin,\r
+ Margin = new Extents(0, 0, 6, 6),\r
+ Ellipsis = true,\r
+ };\r
+ topView.Add(titleLabel);\r
+ titleLabel.SetBinding(TextLabel.TextProperty, "Title");\r
+ RelativeLayout.SetLeftTarget(titleLabel, topView);\r
+ RelativeLayout.SetLeftRelativeOffset(titleLabel, 0.0f);\r
+ RelativeLayout.SetRightTarget(titleLabel, topView);\r
+ RelativeLayout.SetRightRelativeOffset(titleLabel, 1.0f);\r
+ RelativeLayout.SetFillHorizontal(titleLabel, true);\r
+\r
+ contentView = new View()\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ WidthSpecification = LayoutParamPolicies.MatchParent,\r
+ HeightSpecification = 876,\r
+ };\r
+ base.Add(contentView);\r
+ FlexLayout.SetFlexGrow(contentView, 1);\r
+ FlexLayout.SetFlexShrink(contentView, 1);\r
+\r
+ tabs = new Tab()\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ Size2D = new Size2D(Window.Instance.Size.Width, 84),\r
+ WidthSpecification = LayoutParamPolicies.MatchParent,\r
+ HeightSpecification = 84,\r
+ UnderLineBackgroundColor = Color.Blue,\r
+ UnderLineSize = new Size2D(1, 3),\r
+ PointSize = 25,\r
+ BackgroundColor = Color.White,\r
+ };\r
+ tabs.TextColorSelector = new ColorSelector\r
+ {\r
+ Normal = Color.Black,\r
+ Selected = Color.Magenta,\r
+ };\r
+ base.Add(tabs);\r
+ for(int i = 0; i<4; ++i)\r
+ {\r
+ Tab.TabItemData item = new Tab.TabItemData();\r
+ item.Text = TabNames[i];\r
+ tabs.AddItem(item);\r
+ }\r
+ tabs.SelectedItemIndex = 1;\r
+\r
+ backButton = null;\r
+ moreButton = null;\r
+ searchButton = null;\r
+ }\r
+\r
+ public Tab Tabs\r
+ {\r
+ get => tabs;\r
+ }\r
+\r
+ public string Title\r
+ {\r
+ get => titleLabel.Text;\r
+ set { titleLabel.Text = value;}\r
+ }\r
+\r
+ public bool BackButton\r
+ {\r
+ set\r
+ {\r
+ if (value)\r
+ {\r
+ ButtonStyle buttonStyle = new ButtonStyle()\r
+ {\r
+ Icon = new ImageViewStyle()\r
+ {\r
+ ResourceUrl = Resources.GetImagePath() + "back_button.png",\r
+ },\r
+ IsSelectable = false,\r
+ IsEnabled = true,\r
+ };\r
+\r
+ backButton = new Button(buttonStyle)\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ Size2D = new Size2D(48, 48),\r
+ Margin = new Extents(0, 24, 6, 6),\r
+ };\r
+ topView.Add(backButton);\r
+\r
+ RelativeLayout.SetLeftRelativeOffset(backButton, 0.0f);\r
+ RelativeLayout.SetRightRelativeOffset(backButton, 0.0f);\r
+ RelativeLayout.SetHorizontalAlignment(backButton, RelativeLayout.Alignment.Start);\r
+\r
+ RelativeLayout.SetLeftTarget(titleLabel, backButton);\r
+ RelativeLayout.SetLeftRelativeOffset(titleLabel, 1.0f);\r
+ }\r
+ }\r
+ }\r
+\r
+ public bool MoreButton\r
+ {\r
+ set\r
+ {\r
+ if (value)\r
+ {\r
+ ButtonStyle buttonStyle = new ButtonStyle()\r
+ {\r
+ Icon = new ImageViewStyle()\r
+ {\r
+ ResourceUrl = Resources.GetImagePath() + "more.png",\r
+ },\r
+ IsSelectable = false,\r
+ IsEnabled = true,\r
+ };\r
+ moreButton = new Button(buttonStyle)\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ Size2D = new Size2D(48, 48),\r
+ Margin = new Extents(32, 0, 6, 6),\r
+ };\r
+ topView.Add(moreButton);\r
+ RelativeLayout.SetLeftRelativeOffset(moreButton, 1.0f);\r
+ RelativeLayout.SetRightRelativeOffset(moreButton, 1.0f);\r
+ RelativeLayout.SetHorizontalAlignment(moreButton, RelativeLayout.Alignment.End);\r
+\r
+ RelativeLayout.SetRightTarget(titleLabel, moreButton);\r
+ RelativeLayout.SetRightRelativeOffset(titleLabel, 0.0f);\r
+ }\r
+ }\r
+ }\r
+\r
+ public bool SearchButton\r
+ {\r
+ set\r
+ {\r
+ if (value)\r
+ {\r
+ ButtonStyle buttonStyle = new ButtonStyle()\r
+ {\r
+ Icon = new ImageViewStyle()\r
+ {\r
+ ResourceUrl = Resources.GetImagePath() + "search_icon.png",\r
+ },\r
+ IsSelectable = false,\r
+ IsEnabled = true,\r
+ };\r
+ searchButton = new Button(buttonStyle)\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ Size2D = new Size2D(96, 60),\r
+ BackgroundImage = Resources.GetImagePath() + "search_button_bg.png",\r
+ Margin = new Extents(24, 0, 0, 0),\r
+ };\r
+ topView.Add(searchButton);\r
+ RelativeLayout.SetRightTarget(searchButton, moreButton);\r
+ RelativeLayout.SetRightRelativeOffset(searchButton, 0.0f);\r
+ RelativeLayout.SetHorizontalAlignment(searchButton, RelativeLayout.Alignment.End);\r
+\r
+ RelativeLayout.SetLeftTarget(titleLabel, RelativeLayout.GetLeftTarget(titleLabel));\r
+ RelativeLayout.SetLeftRelativeOffset(titleLabel, RelativeLayout.GetLeftRelativeOffset(titleLabel));\r
+ RelativeLayout.SetRightTarget(titleLabel, searchButton);\r
+ RelativeLayout.SetRightRelativeOffset(titleLabel, 0.0f);\r
+ }\r
+ }\r
+ }\r
+\r
+ public View SetContent\r
+ {\r
+ set\r
+ {\r
+ contentView.Add(value);\r
+ }\r
+ }\r
+\r
+ protected override void Dispose(DisposeTypes type)\r
+ {\r
+ if (Disposed)\r
+ {\r
+ return;\r
+ }\r
+ if (type == DisposeTypes.Explicit)\r
+ {\r
+ List<View> children = topView?.Children;\r
+ foreach (View child in children)\r
+ {\r
+ topView.Remove(child);\r
+ child?.Dispose();\r
+ }\r
+ base.Remove(topView);\r
+ topView?.Dispose();\r
+ topView = null;\r
+\r
+ // Do not delete the children of contentview as they are not owned by BaseView\r
+ base.Remove(contentView);\r
+ contentView?.Dispose();\r
+ contentView = null;\r
+\r
+ base.Remove(tabs);\r
+ tabs?.Dispose();\r
+ tabs = null;\r
+\r
+ base.Remove(bottomView);\r
+ bottomView?.Dispose();\r
+ bottomView = null;\r
+ }\r
+\r
+ base.Dispose(type);\r
+ }\r
+ }\r
+}
\ No newline at end of file
--- /dev/null
+using Tizen.NUI.Components;\r
+using Tizen.NUI.BaseComponents;\r
+using Tizen.NUI;\r
+using MusicPlayer.Common;\r
+\r
+namespace MusicPlayer.Views\r
+{\r
+ class ListItemLayout : RecyclerViewItem\r
+ {\r
+ private static int Width = 1792;\r
+ private static int Height = 108;\r
+\r
+ private const int IconSize = 64;\r
+ private const int LayoutMargin = 16;\r
+ private const int LayoutPadding = 32;\r
+ private const int SeperatorHeight = 1;\r
+ private const int LeftPadding = 64;\r
+ private const int x = 0;\r
+\r
+ private View itemSeperator;\r
+ private TextLabel titleLabel;\r
+ private TextLabel subtitleLabel;\r
+ private ImageView icon;\r
+\r
+ public ListItemLayout(int width = 1792, int height = 108) : base()\r
+ {\r
+ base.OnInitialize();\r
+ base.IsCreateByXaml = true;\r
+ Width = width;\r
+ Height = height;\r
+ WidthSpecification = Width;\r
+ HeightSpecification = Height;\r
+\r
+ // to show the rounded rect of the bg\r
+ BackgroundColor = Color.Transparent;\r
+\r
+ icon = new ImageView()\r
+ {\r
+ WidthSpecification = IconSize,\r
+ HeightSpecification = IconSize,\r
+ IsCreateByXaml = true,\r
+ Position2D = new Position2D(x, ((Height / 2) - (IconSize / 2))),\r
+ };\r
+ base.Add(icon);\r
+\r
+ itemSeperator = new View()\r
+ {\r
+ WidthSpecification = (Width - (2 * LeftPadding)),\r
+ HeightSpecification = SeperatorHeight,\r
+ ExcludeLayouting = true,\r
+ Position2D = new Position2D(x, Height - SeperatorHeight),\r
+ BackgroundColor = UIColors.ItemSeperator,\r
+ };\r
+ base.Add(itemSeperator);\r
+\r
+ titleLabel = new TextLabel("ItemLabel")\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ WidthSpecification = (Width - (2 * LeftPadding) - IconSize - LayoutPadding),\r
+ HeightSpecification = 40,\r
+ PixelSize = 32,\r
+ FontFamily = "BreezeSans",\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ IsCreateByXaml = true,\r
+ Position2D = new Position2D((x + IconSize + LayoutPadding), LayoutMargin),\r
+ };\r
+ // ToDo need to make this a readonly const\r
+ PropertyMap titleFontStyle = new PropertyMap();\r
+ titleFontStyle.Add("width", new PropertyValue("normal"));\r
+ titleFontStyle.Add("weight", new PropertyValue("light"));\r
+ titleLabel.FontStyle = titleFontStyle;\r
+ base.Add(titleLabel);\r
+\r
+ subtitleLabel = new TextLabel("ItemLabel")\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ WidthSpecification = (Width - (2 * LeftPadding) - IconSize - LayoutPadding),\r
+ HeightSpecification = 36,\r
+ PixelSize = 28,\r
+ FontFamily = "BreezeSans",\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ IsCreateByXaml = true,\r
+ Position2D = new Position2D((x + IconSize + LayoutPadding), LayoutMargin + 40)\r
+ };\r
+ // ToDo need to make this a readonly const\r
+ PropertyMap subtitleFontStyle = new PropertyMap();\r
+ subtitleFontStyle.Add("width", new PropertyValue("normal"));\r
+ subtitleFontStyle.Add("weight", new PropertyValue("normal"));\r
+ subtitleFontStyle.Add("slant", new PropertyValue("normal"));\r
+ subtitleLabel.FontStyle = subtitleFontStyle;\r
+ base.Add(subtitleLabel);\r
+ IsCreateByXaml = true;\r
+ }\r
+ public ImageView Icon\r
+ {\r
+ get => icon;\r
+ }\r
+ public TextLabel TitleLabel\r
+ {\r
+ get => titleLabel;\r
+ }\r
+ public TextLabel SubtitleLabel\r
+ {\r
+ get => subtitleLabel;\r
+ }\r
+\r
+ protected override void Dispose(DisposeTypes type)\r
+ {\r
+ if(Disposed)\r
+ {\r
+ return;\r
+ }\r
+ if (type == DisposeTypes.Explicit)\r
+ {\r
+ base.Remove(itemSeperator);\r
+ itemSeperator?.Dispose();\r
+ itemSeperator = null;\r
+\r
+ base.Remove(icon);\r
+ icon?.Dispose();\r
+ icon = null;\r
+\r
+ base.Remove(titleLabel);\r
+ titleLabel?.Dispose();\r
+ titleLabel = null;\r
+\r
+ base.Remove(subtitleLabel);\r
+ subtitleLabel?.Dispose();\r
+ subtitleLabel = null;\r
+ }\r
+\r
+ base.Dispose(type);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+using MusicPlayer.ViewModels;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Views
+{
+ class LyricsView : View
+ {
+ private const int ViewSize = 784;
+ private const int LyricsViewMargin = 40;
+ private const int LyricsViewSize = 704;
+
+ private readonly LyricsViewModel lyricsViewModel;
+
+ private ImageView thumbView;
+ private ScrollableBase scrollView;
+ private TextLabel lyricsLabel;
+
+ public LyricsView(LyricsViewModel lyricsViewModel) : base()
+ {
+ this.lyricsViewModel = lyricsViewModel;
+ BindingContext = lyricsViewModel.lyricsModel;
+ Size2D = new Size2D(ViewSize, ViewSize);
+
+ AddThumbnail();
+ AddLyricsView();
+ }
+
+ private void AddThumbnail()
+ {
+ thumbView = new ImageView()
+ {
+ HeightResizePolicy = ResizePolicyType.FillToParent,
+ WidthResizePolicy = ResizePolicyType.FillToParent,
+ };
+ thumbView.SetBinding(ImageView.ResourceUrlProperty, "ThumbPath");
+ base.Add(thumbView);
+ }
+
+ private void AddLyricsView()
+ {
+ scrollView = new ScrollableBase()
+ {
+ Position2D = new Position2D(LyricsViewMargin, LyricsViewMargin),
+ Size2D = new Size2D(LyricsViewSize, LyricsViewSize),
+ ScrollingDirection = ScrollableBase.Direction.Vertical,
+ BackgroundColor = Color.Transparent,
+ };
+ scrollView.BindingContext = lyricsViewModel;
+ scrollView.SetBinding(View.BackgroundColorProperty, "LyricsBackgroundColor");
+ base.Add(scrollView);
+
+ lyricsLabel = new TextLabel()
+ {
+ WidthResizePolicy = ResizePolicyType.FillToParent,
+ TextColor = Color.White,
+ MultiLine = true,
+ LineWrapMode = LineWrapMode.Word,
+ PointSize = 25.0f,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ };
+ lyricsLabel.BindingContext = lyricsViewModel.lyricsModel;
+ lyricsLabel.SetBinding(TextLabel.TextProperty, "Lyrics");
+ scrollView.Add(lyricsLabel);
+ }
+ }
+}
--- /dev/null
+using Tizen.NUI;
+using Tizen.Multimedia;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Binding;
+using MusicPlayer.Common;
+using MusicPlayer.ViewModels;
+using MusicPlayer.Views.Utils;
+using System.Collections.Generic;
+
+namespace MusicPlayer.Views
+{
+ class PlayerView : View
+ {
+ private enum PlayerViewState
+ {
+ AlbumArt,
+ TrackList,
+ }
+ private const int LayoutPadding = 64;
+ private const int IconSize = 48;
+ private const int TopBarSize = 120;
+ private const int ControlViewWidth = 640;
+ private const int ControlViewHeight = 384;
+ private const int ControlViewMargin = 315;
+ private const int TitleLabelHeight = 48;
+ private const int ArtistLabelHeight = 36;
+ private const int TopBarButtonsY = (TopBarSize / 2 - IconSize / 2);
+
+ private View playerBackgroundView;
+ private View leftView;
+ private View rightView;
+ private View rightViewBackground;
+ private Button backButton;
+ private Button moreButton;
+
+ private View controlsView;
+ private View sliderView;
+ private MultiStateButton playButton;
+ private Button prevButton;
+ private Button nextButton;
+ private MultiStateButton shuffleButton;
+ private MultiStateButton 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 MultiStateButton favouriteButton;
+ private PlayingListView currentListView;
+ private LyricsView lyricsView;
+
+ private PlayerViewModel viewModel;
+
+ private PlayerViewState viewState;
+
+ public PlayerView(PlayerViewModel viewModel) : base()
+ {
+ this.viewModel = viewModel;
+ BindingContext = viewModel.playerModel;
+ StyleName = "AppBackground";
+ WidthResizePolicy = ResizePolicyType.FillToParent;
+ HeightResizePolicy = ResizePolicyType.FillToParent;
+
+ AddPlayerBackground();
+
+ viewState = PlayerViewState.AlbumArt;
+
+ leftView = CreateLeftView();
+ rightView = CreateRightView();
+ AddRightViewBackground();
+
+ AddTopButtons();
+ AddControlView();
+ AddControlElements();
+ AddPlaybackSlider();
+ AddListActionButtons();
+ AddThumbnail();
+ AddLyricsView();
+ }
+
+ private void AddPlayerBackground()
+ {
+ playerBackgroundView = new View();
+ playerBackgroundView.Size2D = new Size2D(Window.Instance.WindowSize.Width, Window.Instance.WindowSize.Height);
+ WidthResizePolicy = ResizePolicyType.FillToParent;
+ HeightResizePolicy = ResizePolicyType.FillToParent;
+ base.Add(playerBackgroundView);
+ playerBackgroundView.BackgroundColor = Color.Transparent;
+ playerBackgroundView.BindingContext = viewModel;
+ playerBackgroundView.SetBinding(BackgroundProperty, "PlayerBackground");
+ }
+
+ 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.Transparent,
+ 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 AddRightViewBackground()
+ {
+ rightViewBackground = new View();
+ rightViewBackground.BackgroundColor = Color.Transparent;
+ rightViewBackground.SizeWidth = Window.Instance.WindowSize.Width / 2;
+ rightViewBackground.SizeHeight = Window.Instance.WindowSize.Height;
+ rightViewBackground.WidthResizePolicy = ResizePolicyType.FillToParent;
+ rightViewBackground.HeightResizePolicy = ResizePolicyType.FillToParent;
+ rightView.Add(rightViewBackground);
+ rightViewBackground.BindingContext = viewModel;
+ rightViewBackground.SetBinding(BackgroundProperty, "PlayerBackground");
+ rightViewBackground.Hide();
+ }
+
+ private void UpdatePlayerViewBackground(PlayerViewState state)
+ {
+ if (state == PlayerViewState.AlbumArt)
+ {
+ rightViewBackground.Hide();
+ playerBackgroundView.Show();
+ }
+ else
+ {
+ playerBackgroundView.Hide();
+ rightViewBackground.Show();
+ }
+ }
+
+ private void AddTopButtons()
+ {
+ backButton = new Button("BackButton");
+ backButton.ThemeChangeSensitive = true;
+ backButton.Position2D = new Position2D(LayoutPadding, TopBarButtonsY);
+ leftView.Add(backButton);
+
+ moreButton = new Button("MoreButton");
+ moreButton.ThemeChangeSensitive = true;
+ moreButton.Position2D = new Position2D(Window.Instance.WindowSize.Width / 2 - LayoutPadding - IconSize, TopBarButtonsY);
+ rightView.Add(moreButton);
+ }
+
+ private void AddControlView()
+ {
+ controlsView = new View()
+ {
+ BackgroundColor = Color.Transparent,
+ Size2D = new Size2D(ControlViewWidth, ControlViewHeight),
+ Position2D = new Position2D((Window.Instance.WindowSize.Width / 4 - ControlViewWidth / 2), TopBarSize + ControlViewMargin),
+ };
+ rightView.Add(controlsView);
+ }
+
+ private void AddTitleLabel()
+ {
+ titleLabel = new TextLabel("LabelText")
+ {
+ ThemeChangeSensitive = true,
+ Size2D = new Size2D(ControlViewWidth, TitleLabelHeight),
+ Position2D = new Position2D(0, 0),
+ PixelSize = 36,
+ FontFamily = "BreezeSans",
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center,
+ Ellipsis = true,
+ };
+ titleLabel.SetBinding(TextLabel.TextProperty, "TrackName");
+ controlsView.Add(titleLabel);
+ }
+
+ private void AddArtistLabel()
+ {
+ artistLabel = new TextLabel("LabelText")
+ {
+ ThemeChangeSensitive = true,
+ Size2D = new Size2D(ControlViewWidth, ArtistLabelHeight),
+ Position2D = new Position2D(0, 62),
+ PixelSize = 28,
+ FontFamily = "BreezeSans",
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center,
+ Ellipsis = true,
+ };
+ artistLabel.SetBinding(TextLabel.TextProperty, "TrackArtist");
+ controlsView.Add(artistLabel);
+ }
+
+ private void AddTextControlElements()
+ {
+ AddTitleLabel();
+ AddArtistLabel();
+ }
+
+ private void AddShuffleButton()
+ {
+ shuffleButton = new MultiStateButton()
+ {
+ Size2D = new Size2D(IconSize, IconSize),
+ Position2D = new Position2D(0, 196),
+ IconResources = new Dictionary<ThemeType, Dictionary<string, StringSelector>>()
+ {
+ {
+ ThemeType.Light,
+ new Dictionary<string, StringSelector>()
+ {
+ {
+ ShuffleMode.Off.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "light/shuffle_off.png",
+ }
+ },
+ {
+ ShuffleMode.On.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "light/shuffle_on.png",
+ }
+ },
+ }
+ },
+ {
+ ThemeType.Dark,
+ new Dictionary<string, StringSelector>()
+ {
+ {
+ ShuffleMode.Off.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "dark/shuffle_off.png",
+ }
+ },
+ {
+ ShuffleMode.On.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "dark/shuffle_on.png",
+ }
+ },
+ }
+ }
+ },
+ };
+ shuffleButton.BindingContext = viewModel.playingListViewModel;
+ shuffleButton.SetBinding(MultiStateButton.CustomStateProperty, "ShuffleButtonState");
+ // TODO need to implement command instead
+ shuffleButton.Clicked += (object sender, ClickedEventArgs e) =>
+ {
+ viewModel.ShuffleChanged();
+ };
+ controlsView.Add(shuffleButton);
+ }
+
+ private void AddPreviousButton()
+ {
+ prevButton = new Button("PrevButton");
+ prevButton.ThemeChangeSensitive = true;
+ // TODO need to implement command instead
+ prevButton.Clicked += (object sender, ClickedEventArgs e) =>
+ {
+ viewModel.PrevButtonClicked();
+ };
+ prevButton.BindingContext = viewModel;
+ prevButton.SetBinding(Button.IsEnabledProperty, "HasPreviousTrack");
+ controlsView.Add(prevButton);
+ }
+
+ private void AddPlayButton()
+ {
+ playButton = new MultiStateButton()
+ {
+ Size2D = new Size2D(IconSize, IconSize),
+ Position2D = new Position2D(296, 196),
+ BackgroundColor = Color.Transparent,
+ IconResources = new Dictionary<ThemeType, Dictionary<string, StringSelector>>()
+ {
+ {
+ ThemeType.Light,
+ new Dictionary<string, StringSelector>()
+ {
+ {
+ "Play",
+ new StringSelector()
+ {
+ Normal = Resources.GetImagePath() + "light/play.png",
+ Pressed = Resources.GetImagePath() + "play_pressed.png",
+ Disabled = Resources.GetImagePath() + "play_disabled.png",
+ }
+ },
+ {
+ "Pause",
+ new StringSelector()
+ {
+ Normal = Resources.GetImagePath() + "light/pause.png",
+ Pressed = Resources.GetImagePath() + "pause_pressed.png",
+ Disabled = Resources.GetImagePath() + "pause_disabled.png",
+ }
+ },
+ }
+ },
+ {
+ ThemeType.Dark,
+ new Dictionary<string, StringSelector>()
+ {
+ {
+ "Play",
+ new StringSelector()
+ {
+ Normal = Resources.GetImagePath() + "dark/play.png",
+ Pressed = Resources.GetImagePath() + "play_pressed.png",
+ Disabled = Resources.GetImagePath() + "play_disabled.png",
+ }
+ },
+ {
+ "Pause",
+ new StringSelector()
+ {
+ Normal = Resources.GetImagePath() + "dark/pause.png",
+ Pressed = Resources.GetImagePath() + "pause_pressed.png",
+ Disabled = Resources.GetImagePath() + "pause_disabled.png",
+ }
+ },
+ }
+ }
+ },
+ };
+ playButton.BindingContext = viewModel;
+ playButton.SetBinding(MultiStateButton.CustomStateProperty, "PlayButtonState");
+ controlsView.Add(playButton);
+ // TODO need to implement command instead
+ playButton.Clicked += (object sender, ClickedEventArgs e) =>
+ {
+ viewModel.PlayingStatusChanged();
+ };
+ }
+
+ private void AddNextButton()
+ {
+ nextButton = new Button("NextButton");
+ nextButton.ThemeChangeSensitive = true;
+ // TODO need to implement command instead
+ nextButton.Clicked += (object sender, ClickedEventArgs e) =>
+ {
+ viewModel.NextButtonClicked();
+ };
+ nextButton.BindingContext = viewModel;
+ nextButton.SetBinding(Button.IsEnabledProperty, "HasNextTrack");
+ controlsView.Add(nextButton);
+ }
+
+ private void AddRepeatButton()
+ {
+ repeatButton = new MultiStateButton()
+ {
+ Size2D = new Size2D(IconSize, IconSize),
+ Position2D = new Position2D(592, 196),
+ IconResources = new Dictionary<ThemeType, Dictionary<string, StringSelector>>()
+ {
+ {
+ ThemeType.Light,
+ new Dictionary<string, StringSelector>()
+ {
+ {
+ RepeatMode.Off.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "light/repeat_off.png",
+ }
+ },
+ {
+ RepeatMode.RepeatOne.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "light/repeat_one.png",
+ }
+ },
+ {
+ RepeatMode.RepeatAll.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "light/repeat_all.png",
+ }
+ },
+ }
+ },
+ {
+ ThemeType.Dark,
+ new Dictionary<string, StringSelector>()
+ {
+ {
+ RepeatMode.Off.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "dark/repeat_off.png",
+ }
+ },
+ {
+ RepeatMode.RepeatOne.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "dark/repeat_one.png",
+ }
+ },
+ {
+ RepeatMode.RepeatAll.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "dark/repeat_all.png",
+ }
+ },
+ }
+ }
+ },
+ };
+ repeatButton.BindingContext = viewModel.playingListViewModel;
+ repeatButton.SetBinding(MultiStateButton.CustomStateProperty, "RepeatButtonState");
+ controlsView.Add(repeatButton);
+ // TODO need to implement command instead
+ repeatButton.Clicked += (object sender, ClickedEventArgs e) =>
+ {
+ viewModel.RepeatChanged();
+ };
+ }
+
+ private void AddButtonControlElements()
+ {
+ AddShuffleButton();
+ AddPreviousButton();
+ AddPlayButton();
+ AddNextButton();
+ AddRepeatButton();
+ }
+
+ private void AddLeftVolumeIcon()
+ {
+ leftVolumeIcon = new ImageView()
+ {
+ ThemeChangeSensitive = true,
+ StyleName = "LeftVolume",
+ };
+ controlsView.Add(leftVolumeIcon);
+ }
+
+ private void AddRightVolumeIcon()
+ {
+ rightVolumeIcon = new ImageView()
+ {
+ ThemeChangeSensitive = true,
+ StyleName = "RightVolume",
+ };
+ controlsView.Add(rightVolumeIcon);
+ }
+
+ private void AddVolumeSliderEventHandlers()
+ {
+ volumeSlider.SlidingStarted += (object sender, SliderSlidingStartedEventArgs e) =>
+ {
+ viewModel.VolumeChangeStarted();
+ };
+ volumeSlider.ValueChanged += (object sender, SliderValueChangedEventArgs e) =>
+ {
+ viewModel.VolumeLevelChanged((int)e.CurrentValue);
+ };
+ volumeSlider.SlidingFinished += (object sender, SliderSlidingFinishedEventArgs e) =>
+ {
+ viewModel.VolumeChangeFinished((int)e.CurrentValue);
+ };
+ }
+
+ private void AddVolumeSlider()
+ {
+ volumeSlider = new Slider("Slider");
+ volumeSlider.ThemeChangeSensitive = true;
+ volumeSlider.Size2D = new Size2D(496, 48);
+ volumeSlider.Position2D = new Position2D(72, 336);
+ volumeSlider.ThumbSize = new Tizen.NUI.Size(36, 36);
+ volumeSlider.Direction = Slider.DirectionType.Horizontal;
+ volumeSlider.MinValue = 0;
+ volumeSlider.MaxValue = AudioManager.VolumeController.MaxLevel[AudioVolumeType.Media];
+ volumeSlider.CurrentValue = AudioManager.VolumeController.Level[AudioVolumeType.Media];
+ controlsView.Add(volumeSlider);
+ volumeSlider.BindingContext = viewModel;
+ volumeSlider.SetBinding(Slider.CurrentValueProperty, "VolumeLevel");
+ AddVolumeSliderEventHandlers();
+ }
+
+ private void AddVolumeSliderElements()
+ {
+ AddLeftVolumeIcon();
+ AddRightVolumeIcon();
+ AddVolumeSlider();
+ }
+
+ private void AddControlElements()
+ {
+ AddTextControlElements();
+ AddButtonControlElements();
+ AddVolumeSliderElements();
+ }
+
+ private void AddPlaybackSliderEventHandler()
+ {
+ playbackSlider.SlidingStarted += (object sender, SliderSlidingStartedEventArgs e) =>
+ {
+ viewModel.StopPlaybackTimer();
+ };
+ playbackSlider.ValueChanged += (object sender, SliderValueChangedEventArgs e) =>
+ {
+ viewModel.SetElapsedTime(e.CurrentValue);
+ };
+ playbackSlider.SlidingFinished += (object sender, SliderSlidingFinishedEventArgs e) =>
+ {
+ viewModel.UpdatePlayerPosition(e.CurrentValue);
+ };
+ }
+
+ private void AddPlaybackSlider(View sliderView)
+ {
+ playbackSlider = new Slider("Slider")
+ {
+ ThemeChangeSensitive = true,
+ MinValue = 0.0f,
+ MaxValue = 1.0f,
+ WidthResizePolicy = ResizePolicyType.FillToParent,
+ SizeHeight = 44,
+ ThumbSize = new Tizen.NUI.Size(36, 36),
+ Direction = Slider.DirectionType.Horizontal,
+ };
+ playbackSlider.SetBinding(Slider.CurrentValueProperty, "ElapsedTime");
+ sliderView.Add(playbackSlider);
+ AddPlaybackSliderEventHandler();
+ }
+
+ private void AddCurrentTimeLabel(View sliderView)
+ {
+ currentTime = new TextLabel("LabelText")
+ {
+ ThemeChangeSensitive = true,
+ Size2D = new Size2D(400, 32),
+ Position2D = new Position2D(0, 48),
+ PixelSize = 24,
+ FontFamily = "BreezeSans",
+ Text = "00::00:00",
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ };
+ currentTime.SetBinding(TextLabel.TextProperty, "PlayingTime");
+ sliderView.Add(currentTime);
+ }
+
+ private void AddTotalTimeLabel(View sliderView)
+ {
+ totalTime = new TextLabel("LabelText")
+ {
+ ThemeChangeSensitive = true,
+ Size2D = new Size2D(400, 32),
+ Position2D = new Position2D(1792 - 400, 48),
+ PixelSize = 24,
+ FontFamily = "BreezeSans",
+ HorizontalAlignment = HorizontalAlignment.End,
+ Text = "59:59:59",
+ };
+ totalTime.SetBinding(TextLabel.TextProperty, "TrackLength");
+ sliderView.Add(totalTime);
+ }
+
+ private void AddPlaybackSlider()
+ {
+ sliderView = new View()
+ {
+ Size2D = new Size2D(1792, 80),
+ Position2D = new Position2D(64, 950),
+ BackgroundColor = Color.Transparent,
+ };
+ Add(sliderView);
+
+ AddPlaybackSlider(sliderView);
+ AddCurrentTimeLabel(sliderView);
+ AddTotalTimeLabel(sliderView);
+ UpdatePlaybackSliderPosition(viewState);
+ }
+
+ private void UpdatePlaybackSliderPosition(PlayerViewState state)
+ {
+ if(state == PlayerViewState.AlbumArt)
+ {
+ sliderView.Size2D = new Size2D(1792, 80);
+ sliderView.Position2D = new Position2D(64, 950);
+ currentTime.Size2D = new Size2D(400, 32);
+ currentTime.Position2D = new Position2D(0, 48);
+ totalTime.Size2D = new Size2D(400, 32);
+ totalTime.Position2D = new Position2D(1392, 48);
+ }
+ else
+ {
+ sliderView.Size2D = new Size2D(640, 80);
+ sliderView.Position2D = new Position2D(1056, 950);
+ currentTime.Size2D = new Size2D(180, 32);
+ currentTime.Position2D = new Position2D(0, 48);
+ totalTime.Size2D = new Size2D(180, 32);
+ totalTime.Position2D = new Position2D(460, 48);
+ }
+ }
+
+ private void AddListActionButtons()
+ {
+ View actionButtonView = new View()
+ {
+ Size2D = new Size2D(224, 48),
+ Position2D = new Position2D((Window.Instance.WindowSize.Width / 2 - 224 - LayoutPadding), 120),
+ BackgroundColor = Color.Transparent,
+ };
+ rightView.Add(actionButtonView);
+
+ listButton = new Button("ListButton")
+ {
+ ThemeChangeSensitive = true,
+ };
+ listButton.Clicked += (object sender, ClickedEventArgs e) =>
+ {
+ if(viewState == PlayerViewState.AlbumArt)
+ {
+ Tizen.Log.Debug(AppConstants.LogTag, "Adding Playing list view");
+ viewState = PlayerViewState.TrackList;
+ RemoveLyricsView();
+ AddPlayingListView();
+ thumb.Show();
+ }
+ else
+ {
+ Tizen.Log.Debug(AppConstants.LogTag, "Adding album art view");
+ viewState = PlayerViewState.AlbumArt;
+ RemovePlayingListView();
+ AddLyricsView();
+ thumb.Hide();
+ }
+ UpdatePlaybackSliderPosition(viewState);
+ UpdatePlayerViewBackground(viewState);
+ };
+ actionButtonView.Add(listButton);
+
+ playlistButton = new Button("PlaylistButton")
+ {
+ ThemeChangeSensitive = true,
+ };
+ actionButtonView.Add(playlistButton);
+
+ favouriteButton = new MultiStateButton()
+ {
+ Size2D = new Size2D(IconSize, IconSize),
+ Position2D = new Position2D(176, 0),
+ IconResources = new Dictionary<ThemeType, Dictionary<string, StringSelector>>()
+ {
+ {
+ ThemeType.Light,
+ new Dictionary<string, StringSelector>()
+ {
+ {
+ Favourite.Off.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "light/favourite_off.png",
+ }
+ },
+ {
+ Favourite.On.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "light/favourite_on.png",
+ }
+ },
+ }
+ },
+ {
+ ThemeType.Dark,
+ new Dictionary<string, StringSelector>()
+ {
+ {
+ Favourite.Off.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "dark/favourite_off.png",
+ }
+ },
+ {
+ Favourite.On.ToString(),
+ new StringSelector()
+ {
+ All = Resources.GetImagePath() + "dark/favourite_on.png",
+ }
+ },
+ }
+ }
+ },
+ };
+ favouriteButton.CusotmState = Favourite.Off.ToString();
+ 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);
+ thumb.Hide();
+ }
+
+ 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);
+ currentListView.Show();
+ }
+
+ private void RemovePlayingListView()
+ {
+ if(currentListView == null)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "current listview is null, can't remove it");
+ return;
+ }
+ leftView.Remove(currentListView);
+ currentListView.Hide();
+ }
+
+ 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);
+ lyricsView.Show();
+ }
+
+ private void RemoveLyricsView()
+ {
+ if(lyricsView == null)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "lyricsview is null, can't remove it");
+ return;
+ }
+ leftView.Remove(lyricsView);
+ lyricsView.Hide();
+ }
+ }
+}
--- /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(() =>
+ {
+ ListItemLayout layout = new ListItemLayout(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;
+ }
+ }
+}
--- /dev/null
+using MusicPlayer.ViewModels;\r
+using Tizen.NUI.Components;\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
+ class TrackView : BaseContentView\r
+ {\r
+ private TrackViewModel viewModel;\r
+ private TextLabel trackCountLabel;\r
+ private Button playAllIcon; // TODO need to implement playall feature\r
+ private Button addToPlaylistIcon; // TODO need to implement playlist manager\r
+ public TrackView(TrackViewModel viewModel)\r
+ {\r
+ this.viewModel = viewModel;\r
+ collectionView.ItemsSource = viewModel.ListViewModel;\r
+ collectionView.ItemTemplate = new DataTemplate(() =>\r
+ {\r
+ ListItemLayout layout = new ListItemLayout();\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
+ collectionView.ScrollingDirection = ScrollableBase.Direction.Vertical;\r
+ collectionView.WidthSpecification = LayoutParamPolicies.WrapContent;\r
+ collectionView.SelectionMode = ItemSelectionMode.Single;\r
+ collectionView.SelectionChanged += OnTrackSelection;\r
+\r
+ trackCountLabel = new TextLabel("LabelText")\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ PixelSize = 28,\r
+ Text = "TRACK COUNT",\r
+ VerticalAlignment = VerticalAlignment.Center,\r
+ FontFamily = "BreezeSans",\r
+ };\r
+ trackCountLabel.BindingContext = viewModel;\r
+ titleView.Add(trackCountLabel);\r
+ trackCountLabel.SetBinding(TextLabel.TextProperty, "TrackCount");\r
+ RelativeLayout.SetLeftTarget(trackCountLabel, titleView);\r
+ RelativeLayout.SetLeftRelativeOffset(trackCountLabel, 1.0f);\r
+ RelativeLayout.SetRightRelativeOffset(trackCountLabel, 0.0f);\r
+ RelativeLayout.SetFillHorizontal(trackCountLabel, true);\r
+\r
+ playAllIcon = new Button("PlayAll")\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ };\r
+ titleView.Add(playAllIcon);\r
+ RelativeLayout.SetLeftRelativeOffset(playAllIcon, 1.0f);\r
+ RelativeLayout.SetRightRelativeOffset(playAllIcon, 1.0f);\r
+ RelativeLayout.SetHorizontalAlignment(playAllIcon, RelativeLayout.Alignment.End);\r
+\r
+ addToPlaylistIcon = new Button("PlaylistAdd")\r
+ {\r
+ ThemeChangeSensitive = true,\r
+ Margin = new Extents(32, 40, 0, 0),\r
+ };\r
+ titleView.Add(addToPlaylistIcon);\r
+ RelativeLayout.SetRightTarget(addToPlaylistIcon, playAllIcon);\r
+ RelativeLayout.SetRightRelativeOffset(addToPlaylistIcon, 0.0f);\r
+ RelativeLayout.SetHorizontalAlignment(addToPlaylistIcon, RelativeLayout.Alignment.End);\r
+ }\r
+\r
+ private void OnTrackSelection(object sender, SelectionChangedEventArgs e)\r
+ {\r
+ //TODO\r
+ }\r
+\r
+ protected override void OnThemeChanged(object sender, ThemeChangedEventArgs e)\r
+ {\r
+ base.OnThemeChanged(sender, e);\r
+ }\r
+ protected override void Dispose(DisposeTypes type)\r
+ {\r
+ if(Disposed)\r
+ {\r
+ return;\r
+ }\r
+ if(type == DisposeTypes.Explicit)\r
+ {\r
+ titleView.Remove(trackCountLabel);\r
+ trackCountLabel.Dispose();\r
+ trackCountLabel = null;\r
+\r
+ // TODO Uncomment after implementation is completed\r
+ titleView.Remove(playAllIcon);\r
+ playAllIcon.Dispose();\r
+ playAllIcon = null;\r
+\r
+ //titleView.Remove(addToPlaylistIcon);\r
+ addToPlaylistIcon.Dispose();\r
+ addToPlaylistIcon = null;\r
+ }\r
+ base.Dispose(type);\r
+ }\r
+ }\r
+}\r
--- /dev/null
+using System.Collections.Generic;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+using Tizen.NUI.Components;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Views.Utils
+{
+ class MultiStateButton: Button
+ {
+ public static readonly BindableProperty CustomStateProperty = BindableProperty.Create(nameof(CusotmState), typeof(string), typeof(MultiStateButton), null, propertyChanged: (bindable, oldValue, newValue) =>
+ {
+ var instance = (MultiStateButton)bindable;
+ if (newValue != null)
+ {
+ string newCustomState = (string)newValue;
+ instance.UpdateCustomState(newCustomState);
+ }
+ },
+ defaultValueCreator: (bindable) =>
+ {
+ var instance = (MultiStateButton)bindable;
+ return instance.customState;
+ });
+
+ public MultiStateButton() : base()
+ {
+ ThemeChangeSensitive = true;
+ EnableControlState = true;
+ BackgroundColor = Color.Transparent;
+ }
+
+ private Dictionary<ThemeType, Dictionary<string, StringSelector>> iconResources;
+
+ public Dictionary<ThemeType, Dictionary<string, StringSelector>> IconResources
+ {
+ get => iconResources;
+ set => iconResources = value;
+ }
+
+ private string customState;
+ public string CusotmState
+ {
+ get => (string)GetValue(CustomStateProperty);
+ set => SetValue(CustomStateProperty, value);
+ }
+
+ private void UpdateCustomState(string customStatevalue)
+ {
+ if (IconResources == null)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "ThemesIconState needs to be set first");
+ return;
+ }
+ ThemeType type = GetCurrentThemeType();
+ if (iconResources.ContainsKey(type) == false)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "Theme state doesn't exists: " + type.ToString());
+ return;
+ }
+ Dictionary<string, StringSelector> stateResource = iconResources[type];
+ if (stateResource.ContainsKey(customStatevalue) == false)
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "Invalid state: " + customStatevalue);
+ return;
+ }
+ IconURLSelector = stateResource[customStatevalue];
+ customState = customStatevalue;
+ }
+
+ private ThemeType GetCurrentThemeType()
+ {
+ ThemeType type;
+ string id = ThemeManager.PlatformThemeId;
+ if (id.Equals(AppConstants.LightPlatformThemeId))
+ {
+ type = ThemeType.Light;
+ }
+ else
+ {
+ type = ThemeType.Dark;
+ }
+ return type;
+ }
+
+ protected override void OnThemeChanged(object sender, ThemeChangedEventArgs e)
+ {
+ base.OnThemeChanged(sender, e);
+ UpdateCustomState(CusotmState);
+ }
+ }
+}
+
--- /dev/null
+using System;\r
+using Tizen.NUI;\r
+using Tizen.NUI.BaseComponents;\r
+\r
+namespace MusicPlayer\r
+{\r
+ public partial class XamlPage : View\r
+ {\r
+ public XamlPage()\r
+ {\r
+ InitializeComponent();\r
+ }\r
+ }\r
+}\r
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">\r
+\r
+ <PropertyGroup>\r
+ <OutputType>Exe</OutputType>\r
+ <TargetFramework>netcoreapp3.1</TargetFramework>\r
+ <TargetFrameworkIdentifier>Tizen</TargetFrameworkIdentifier>\r
+ <AssemblyName>MusicPlayer</AssemblyName>\r
+ </PropertyGroup>\r
+\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+ <DebugType>portable</DebugType>\r
+ </PropertyGroup>\r
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+ <DebugType>None</DebugType>\r
+ </PropertyGroup>\r
+\r
+ <ItemGroup>\r
+ <Folder Include="lib\" />\r
+ <Folder Include="res\images\" />\r
+ </ItemGroup>\r
+ \r
+ <ItemGroup>\r
+ <EmbeddedResource Include="res\layout\XamlPage.xaml">\r
+ <Generator>MSBuild:Compile</Generator>\r
+ </EmbeddedResource>\r
+ </ItemGroup>\r
+ \r
+ <ItemGroup>\r
+ <PackageReference Include="Tizen.NET" Version="9.0.0.16249" />\r
+ <PackageReference Include="Tizen.NET.Sdk" Version="1.0.1" />\r
+ <PackageReference Include="Tizen.NUI.XamlBuild" Version="1.0.11" />\r
+ </ItemGroup>\r
+\r
+</Project>\r
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" ?>\r
+<b:View x:Class="MusicPlayer.XamlPage"\r
+ xmlns="http://tizen.org/Tizen.NUI/2018/XAML"\r
+ xmlns:b="clr-namespace:Tizen.NUI.BaseComponents;assembly=Tizen.NUI"\r
+ xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">\r
+\r
+ <b:TextLabel x:Name="text" Text="Hello, NUI XAML APP!" PositionUsesPivotPoint="True" ParentOrigin="Center" PivotPoint="Center" Size="700,300,0" PointSize="17" TextColor="Yellow"/>\r
+\r
+</b:View>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Theme
+xmlns="http://tizen.org/Tizen.NUI/2018/XAML"
+xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+xmlns:c="clr-namespace:Tizen.NUI.Components;assembly=Tizen.NUI.Components"
+Id="LightTheme">
+
+ <ViewStyle x:Key="AppBackground" BackgroundColor="#0E1017" />
+
+ <c:ButtonStyle x:Key="PrevButton" Size="48, 48" Position="168, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/prev.png" Pressed="*Resource*/images/prev_pressed.png" Disabled="*Resource*/images/prev_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="NextButton" Size="48, 48" Position="424, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="ShuffleButton" Size="48, 48" Position="0, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="RepeatButton" Size="48, 48" Position="592, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="ListButton" Size="48, 48" Position="0, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/playing_queue.png" Pressed="*Resource*/images/playing_queue_pressed.png" Disabled="*Resource*/images/playing_queue_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="PlaylistButton" Size="48, 48" Position="88, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/addtoplaylist.png" Pressed="*Resource*/images/addtoplaylist_pressed.png" Disabled="*Resource*/images/addtoplaylist_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="FavouriteButton" Size="48, 48" Position="176, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="PlayAll" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/addtoplaylist.png" Pressed="*Resource*/images/addtoplaylist_pressed.png" Disabled="*Resource*/images/addtoplaylist_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="PlaylistAdd" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/shuffle_on.png" Pressed="*Resource*/images/shuffle_on_pressed.png" Disabled="*Resource*/images/shuffle_on_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:SliderStyle x:Key="Slider" TrackThickness="8" IndicatorType="Image">
+ <c:SliderStyle.Track>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>*Resource*/images/empty_track.png</ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:SliderStyle.Track>
+ <c:SliderStyle.Progress>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>*Resource*/images/dark/progress_track.png</ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:SliderStyle.Progress>
+ <c:SliderStyle.Thumb>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>*Resource*/images/dark/nomal_slider_handler.png</ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:SliderStyle.Thumb>
+ </c:SliderStyle>
+
+ <c:ButtonStyle x:Key="BackButton" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/back.png" Pressed="*Resource*/images/back_pressed.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="MoreButton" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/more.png" Pressed="*Resource*/images/more_pressed.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <ImageViewStyle x:Key="LeftVolume" Size="48, 48" Position="0, 336">
+ <ImageViewStyle.ResourceUrl>*Resource*/images/dark/left_sound_icon.png</ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+
+ <ImageViewStyle x:Key="RightVolume" Size="48, 48" Position="592, 336">
+ <ImageViewStyle.ResourceUrl>*Resource*/images/dark/right_sound_icon.png</ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+
+ <TextLabelStyle x:Key="LabelText" TextColor="#FFFFFF"></TextLabelStyle>
+
+ <TextLabelStyle x:Key="ItemLabel">
+ <TextLabelStyle.TextColor>
+ <Selector x:TypeArguments="Color" Normal="#FFFFFF" Selected="#1473E6"/>
+ </TextLabelStyle.TextColor>
+ </TextLabelStyle>
+
+</Theme>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>
+<Theme
+xmlns="http://tizen.org/Tizen.NUI/2018/XAML"
+xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
+xmlns:c="clr-namespace:Tizen.NUI.Components;assembly=Tizen.NUI.Components"
+Id="LightTheme">
+
+ <ViewStyle x:Key="AppBackground" BackgroundColor="#EEEFF1" />
+
+ <c:ButtonStyle x:Key="PrevButton" Size="48, 48" Position="168, 196" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/prev.png" Pressed="*Resource*/images/prev_pressed.png" Disabled="*Resource*/images/prev_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="NextButton" Size="48, 48" Position="424, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent" >
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="ShuffleButton" Size="48, 48" Position="0, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="RepeatButton" Size="48, 48" Position="592, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="ListButton" Size="48, 48" Position="0, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/playing_queue.png" Pressed="*Resource*/images/playing_queue_pressed.png" Disabled="*Resource*/images/playing_queue_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="PlaylistButton" Size="48, 48" Position="88, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/addtoplaylist.png" Pressed="*Resource*/images/addtoplaylist_pressed.png" Disabled="*Resource*/images/addtoplaylist_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="FavouriteButton" Size="48, 48" Position="176, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="PlayAll" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/addtoplaylist.png" Pressed="*Resource*/images/addtoplaylist_pressed.png" Disabled="*Resource*/images/addtoplaylist_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="PlaylistAdd" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/shuffle_on.png" Pressed="*Resource*/images/shuffle_on_pressed.png" Disabled="*Resource*/images/shuffle_on_disabled.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:SliderStyle x:Key="Slider" TrackThickness="8" IndicatorType="Image">
+ <c:SliderStyle.Track>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>*Resource*/images/empty_track.png</ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:SliderStyle.Track>
+ <c:SliderStyle.Progress>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>*Resource*/images/light/progress_track.png</ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:SliderStyle.Progress>
+ <c:SliderStyle.Thumb>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>*Resource*/images/light/nomal_slider_handler.png</ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:SliderStyle.Thumb>
+ </c:SliderStyle>
+
+ <c:ButtonStyle x:Key="BackButton" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/back.png" Pressed="*Resource*/images/back_pressed.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <c:ButtonStyle x:Key="MoreButton" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
+ <c:ButtonStyle.Icon>
+ <ImageViewStyle>
+ <ImageViewStyle.ResourceUrl>
+ <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/more.png" Pressed="*Resource*/images/more_pressed.png" />
+ </ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+ </c:ButtonStyle.Icon>
+ </c:ButtonStyle>
+
+ <ImageViewStyle x:Key="LeftVolume" Size="48, 48" Position="0, 336">
+ <ImageViewStyle.ResourceUrl>*Resource*/images/light/left_sound_icon.png</ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+
+ <ImageViewStyle x:Key="RightVolume" Size="48, 48" Position="592, 336">
+ <ImageViewStyle.ResourceUrl>*Resource*/images/light/right_sound_icon.png</ImageViewStyle.ResourceUrl>
+ </ImageViewStyle>
+
+ <TextLabelStyle x:Key="LabelText" TextColor="#001447"/>
+
+ <TextLabelStyle x:Key="ItemLabel">
+ <TextLabelStyle.TextColor>
+ <Selector x:TypeArguments="Color" Normal="#001447" Selected="#1473E6"/>
+ </TextLabelStyle.TextColor>
+ </TextLabelStyle>
+
+</Theme>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<manifest package="org.tizen.MusicPlayer" version="1.0.0" api-version="5.5" xmlns="http://tizen.org/ns/packages">\r
+ <profile name="common" />\r
+ <ui-application appid="org.tizen.MusicPlayer" exec="MusicPlayer.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">\r
+ <label>MusicPlayer</label>\r
+ <icon>MusicPlayer.png</icon>\r
+ <metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />\r
+ <splash-screens />\r
+ <background-category value="system"/>\r
+ </ui-application>\r
+ <shortcut-list />\r
+ <dependencies />\r
+ <provides-appdefined-privileges />\r
+</manifest>\r
--- /dev/null
+Name: org.tizen.MusicPlayer
+Summary: org.tizen.MusicPlayer
+Version: 1.0.0
+Release: 1
+Group: N/A
+License: Apache-2.0
+Source0: %{name}-%{version}.tar.gz
+
+ExclusiveArch: i586 x86 i486 i686 i386 armv7l arm aarch64
+
+
+BuildRequires: pkgconfig(libtzplatform-config)
+Requires(post): /usr/bin/tpk-backend
+
+%define internal_name org.tizen.MusicPlayer
+%define preload_tpk_path %{TZ_SYS_RO_APP}/.preload-tpk
+
+%description
+profile/iot/apps/dotnet/music-player
+This is a container package which have preload TPK/WGT files
+
+%prep
+%setup -q
+
+%build
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/%{preload_tpk_path}
+install packaging/%{internal_name}-%{version}.tpk %{buildroot}/%{preload_tpk_path}/
+
+%post
+
+%files
+%defattr(-,root,root,-)
+%{preload_tpk_path}/*
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" ?>\r
-<b:View x:Class="MusicPlayer.XamlPage"\r
- xmlns="http://tizen.org/Tizen.NUI/2018/XAML"\r
- xmlns:b="clr-namespace:Tizen.NUI.BaseComponents;assembly=Tizen.NUI"\r
- xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml">\r
-\r
- <b:TextLabel x:Name="text" Text="Hello, NUI XAML APP!" PositionUsesPivotPoint="True" ParentOrigin="Center" PivotPoint="Center" Size="700,300,0" PointSize="17" TextColor="Yellow"/>\r
-\r
-</b:View>\r
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<Theme
-xmlns="http://tizen.org/Tizen.NUI/2018/XAML"
-xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
-xmlns:c="clr-namespace:Tizen.NUI.Components;assembly=Tizen.NUI.Components"
-Id="LightTheme">
-
- <ViewStyle x:Key="AppBackground" BackgroundColor="#0E1017" />
-
- <c:ButtonStyle x:Key="PrevButton" Size="48, 48" Position="168, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/prev.png" Pressed="*Resource*/images/prev_pressed.png" Disabled="*Resource*/images/prev_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="NextButton" Size="48, 48" Position="424, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="ShuffleButton" Size="48, 48" Position="0, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="RepeatButton" Size="48, 48" Position="592, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="ListButton" Size="48, 48" Position="0, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/playing_queue.png" Pressed="*Resource*/images/playing_queue_pressed.png" Disabled="*Resource*/images/playing_queue_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="PlaylistButton" Size="48, 48" Position="88, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/addtoplaylist.png" Pressed="*Resource*/images/addtoplaylist_pressed.png" Disabled="*Resource*/images/addtoplaylist_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="FavouriteButton" Size="48, 48" Position="176, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="PlayAll" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/addtoplaylist.png" Pressed="*Resource*/images/addtoplaylist_pressed.png" Disabled="*Resource*/images/addtoplaylist_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="PlaylistAdd" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/shuffle_on.png" Pressed="*Resource*/images/shuffle_on_pressed.png" Disabled="*Resource*/images/shuffle_on_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:SliderStyle x:Key="Slider" TrackThickness="8" IndicatorType="Image">
- <c:SliderStyle.Track>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>*Resource*/images/empty_track.png</ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:SliderStyle.Track>
- <c:SliderStyle.Progress>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>*Resource*/images/dark/progress_track.png</ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:SliderStyle.Progress>
- <c:SliderStyle.Thumb>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>*Resource*/images/dark/nomal_slider_handler.png</ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:SliderStyle.Thumb>
- </c:SliderStyle>
-
- <c:ButtonStyle x:Key="BackButton" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/back.png" Pressed="*Resource*/images/back_pressed.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="MoreButton" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/dark/more.png" Pressed="*Resource*/images/more_pressed.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <ImageViewStyle x:Key="LeftVolume" Size="48, 48" Position="0, 336">
- <ImageViewStyle.ResourceUrl>*Resource*/images/dark/left_sound_icon.png</ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
-
- <ImageViewStyle x:Key="RightVolume" Size="48, 48" Position="592, 336">
- <ImageViewStyle.ResourceUrl>*Resource*/images/dark/right_sound_icon.png</ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
-
- <TextLabelStyle x:Key="LabelText" TextColor="#FFFFFF"></TextLabelStyle>
-
- <TextLabelStyle x:Key="ItemLabel">
- <TextLabelStyle.TextColor>
- <Selector x:TypeArguments="Color" Normal="#FFFFFF" Selected="#1473E6"/>
- </TextLabelStyle.TextColor>
- </TextLabelStyle>
-
-</Theme>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<Theme
-xmlns="http://tizen.org/Tizen.NUI/2018/XAML"
-xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
-xmlns:c="clr-namespace:Tizen.NUI.Components;assembly=Tizen.NUI.Components"
-Id="LightTheme">
-
- <ViewStyle x:Key="AppBackground" BackgroundColor="#EEEFF1" />
-
- <c:ButtonStyle x:Key="PrevButton" Size="48, 48" Position="168, 196" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/prev.png" Pressed="*Resource*/images/prev_pressed.png" Disabled="*Resource*/images/prev_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="NextButton" Size="48, 48" Position="424, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent" >
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="ShuffleButton" Size="48, 48" Position="0, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="RepeatButton" Size="48, 48" Position="592, 196" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="ListButton" Size="48, 48" Position="0, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/playing_queue.png" Pressed="*Resource*/images/playing_queue_pressed.png" Disabled="*Resource*/images/playing_queue_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="PlaylistButton" Size="48, 48" Position="88, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/addtoplaylist.png" Pressed="*Resource*/images/addtoplaylist_pressed.png" Disabled="*Resource*/images/addtoplaylist_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="FavouriteButton" Size="48, 48" Position="176, 0" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/next.png" Pressed="*Resource*/images/next_pressed.png" Disabled="*Resource*/images/next_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="PlayAll" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/addtoplaylist.png" Pressed="*Resource*/images/addtoplaylist_pressed.png" Disabled="*Resource*/images/addtoplaylist_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="PlaylistAdd" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/shuffle_on.png" Pressed="*Resource*/images/shuffle_on_pressed.png" Disabled="*Resource*/images/shuffle_on_disabled.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:SliderStyle x:Key="Slider" TrackThickness="8" IndicatorType="Image">
- <c:SliderStyle.Track>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>*Resource*/images/empty_track.png</ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:SliderStyle.Track>
- <c:SliderStyle.Progress>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>*Resource*/images/light/progress_track.png</ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:SliderStyle.Progress>
- <c:SliderStyle.Thumb>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>*Resource*/images/light/nomal_slider_handler.png</ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:SliderStyle.Thumb>
- </c:SliderStyle>
-
- <c:ButtonStyle x:Key="BackButton" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/back.png" Pressed="*Resource*/images/back_pressed.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <c:ButtonStyle x:Key="MoreButton" Size="48, 48" IsSelectable="false" IsEnabled="true" BackgroundColor="Transparent">
- <c:ButtonStyle.Icon>
- <ImageViewStyle>
- <ImageViewStyle.ResourceUrl>
- <Selector x:TypeArguments="x:String" Normal="*Resource*/images/light/more.png" Pressed="*Resource*/images/more_pressed.png" />
- </ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
- </c:ButtonStyle.Icon>
- </c:ButtonStyle>
-
- <ImageViewStyle x:Key="LeftVolume" Size="48, 48" Position="0, 336">
- <ImageViewStyle.ResourceUrl>*Resource*/images/light/left_sound_icon.png</ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
-
- <ImageViewStyle x:Key="RightVolume" Size="48, 48" Position="592, 336">
- <ImageViewStyle.ResourceUrl>*Resource*/images/light/right_sound_icon.png</ImageViewStyle.ResourceUrl>
- </ImageViewStyle>
-
- <TextLabelStyle x:Key="LabelText" TextColor="#001447"/>
-
- <TextLabelStyle x:Key="ItemLabel">
- <TextLabelStyle.TextColor>
- <Selector x:TypeArguments="Color" Normal="#001447" Selected="#1473E6"/>
- </TextLabelStyle.TextColor>
- </TextLabelStyle>
-
-</Theme>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>\r
-<manifest package="org.tizen.MusicPlayer" version="1.0.0" api-version="5.5" xmlns="http://tizen.org/ns/packages">\r
- <profile name="common" />\r
- <ui-application appid="org.tizen.MusicPlayer" exec="MusicPlayer.dll" multiple="false" nodisplay="false" taskmanage="true" type="dotnet" launch_mode="single">\r
- <label>MusicPlayer</label>\r
- <icon>MusicPlayer.png</icon>\r
- <metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />\r
- <splash-screens />\r
- <background-category value="system"/>\r
- </ui-application>\r
- <shortcut-list />\r
- <dependencies />\r
- <provides-appdefined-privileges />\r
-</manifest>\r