text = AlbumDataProvider.GetAlbumArtFromTracks(album.Id);\r
}\r
AlbumArtPath = text;\r
+ IsSelected = false;\r
}\r
\r
private string albumName;\r
SetProperty(ref albumArtPath, thumb);\r
}\r
}\r
+\r
+ private bool isSelected;\r
+\r
+ public bool IsSelected\r
+ {\r
+ get => isSelected;\r
+ set => SetProperty(ref isSelected, value);\r
+ }\r
}\r
}\r
TrackCount = ArtistDataProvider.GetArtistTrackCount(artistName).ToString();
TotalCount = AlbumCount + " / " + TrackCount;
AlbumArtPath = ArtistDataProvider.GetArtistAlbumArtPath(artistName);
+ IsSelected = false;
}
private string artistName;
SetProperty(ref albumArtPath, thumb);
}
}
+
+ private bool isSelected;
+
+ public bool IsSelected
+ {
+ get => isSelected;
+ set => SetProperty(ref isSelected, value);
+ }
}
}
--- /dev/null
+using System.Collections.ObjectModel;
+
+namespace MusicPlayer.Models
+{
+ class SearchGroup : ObservableCollection<SearchModel>
+ {
+ public SearchGroup()
+ {
+ //this is required for Activator.CreateInstance in ListViewModel
+ }
+
+ public SearchGroup(string count)
+ {
+ DataCount = count;
+ }
+
+ public string DataCount { get; set; }
+ }
+}
--- /dev/null
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Models
+{
+ class SearchModel : PropertyNotifier
+ {
+ public SearchModel()
+ {
+ //this is required for Activator.CreateInstance in ListViewModel
+ }
+
+ public SearchModel(Artist artist =null, MusicAlbum musicAlbum = null, Track track= null, int type =0)
+ {
+ AlbumDetail = musicAlbum;
+ ArtistDetail = artist;
+ TrackDetail = track;
+ ItemType = type;
+ if(type ==0)
+ {
+ Thumbnail = artist.AlbumArtPath;
+ Title = artist.ArtistName;
+ SubTitle = "";
+ }
+ else if (type == 1)
+ {
+ Thumbnail = musicAlbum.AlbumArtPath;
+ Title = musicAlbum.AlbumName;
+ SubTitle = musicAlbum.ArtistName;
+ }
+ else if (type == 2)
+ {
+ Thumbnail = track.ThumbnailPath;
+ Title = track.TrackTitle;
+ SubTitle = track.ArtistName;
+ }
+ }
+
+ private string thumbnail;
+
+ public string Thumbnail
+ {
+ get => thumbnail;
+ set => SetProperty(ref thumbnail, value);
+ }
+
+ private string title;
+
+ public string Title
+ {
+ get => title;
+ set => SetProperty(ref title, value);
+ }
+
+ private string subTitle;
+
+ public string SubTitle
+ {
+ get => subTitle;
+ set => SetProperty(ref subTitle, value);
+ }
+
+ public int ItemType { get; set; }
+
+ public MusicAlbum AlbumDetail { get; set; }
+ public Artist ArtistDetail { get; set; }
+ public Track TrackDetail { get; set; }
+ }
+}
Duration = TimeSpan.FromMilliseconds(audioInfo.Duration).ToString(AppConstants.TimeFormat);\r
ThumbnailPath = audioInfo.ThumbnailPath;\r
FilePath = audioInfo.Path;\r
+ IsSelected = false;\r
}\r
\r
private string trackTitle;\r
public string FilePath\r
{\r
get => filePath;\r
- set { filePath = value; }\r
+ set => filePath = value;\r
+ }\r
+\r
+ private bool isSelected;\r
+\r
+ public bool IsSelected\r
+ {\r
+ get => isSelected;\r
+ set => SetProperty(ref isSelected, value);\r
}\r
}\r
}\r
--- /dev/null
+using System.Collections.Specialized;
+using System.Collections.Generic;
+using MusicPlayer.Models;
+using MusicPlayer.Common;
+using MusicPlayer.Core;
+
+namespace MusicPlayer.ViewModels
+{
+ using Album = Tizen.Content.MediaContent.Album;
+ using AudioInfo = Tizen.Content.MediaContent.AudioInfo;
+ class SearchViewModel : PropertyNotifier
+ {
+ public SearchViewModel()
+ {
+ List<string> artistList = ArtistDataProvider.CurrentArtistList();
+ List<Album> albumList = AlbumDataProvider.CurrentAlbumList();
+ List<AudioInfo> trackList = TrackDataProvider.CurrentTrackList();
+ ArtistViewModelInSearch = new ArtistViewModel();
+ AlbumViewModelInSearch = new AlbumViewModel();
+ TrackViewModelInSearch = new TrackViewModel();
+
+ GroupListViewModel = new ListViewModel<SearchGroup>();
+
+ if(artistList.Count >0)
+ {
+ SearchGroup searchGroup = new SearchGroup(ArtistViewModelInSearch.ArtistCount);
+ ListViewModel<SearchModel> searchListViewModel = new ListViewModel<SearchModel>();
+ foreach (Artist artist in ArtistViewModelInSearch.ListViewModel)
+ searchListViewModel.Add(new SearchModel(artist, null, null, 0));
+ foreach (SearchModel item in searchListViewModel)
+ searchGroup.Add(item);
+
+ GroupListViewModel.Add(searchGroup);
+ }
+ if (albumList.Count > 0)
+ {
+ SearchGroup searchGroup = new SearchGroup(AlbumViewModelInSearch.AlbumCount);
+ ListViewModel<SearchModel> searchListViewModel = new ListViewModel<SearchModel>();
+ foreach (MusicAlbum musicAlbum in AlbumViewModelInSearch.ListViewModel)
+ searchListViewModel.Add(new SearchModel(null, musicAlbum, null, 1));
+ foreach (SearchModel item in searchListViewModel)
+ searchGroup.Add(item);
+
+ GroupListViewModel.Add(searchGroup);
+ }
+ if (trackList.Count > 0)
+ {
+ SearchGroup searchGroup = new SearchGroup(TrackViewModelInSearch.TrackCount);
+ ListViewModel<SearchModel> searchListViewModel = new ListViewModel<SearchModel>();
+ foreach (Track track in TrackViewModelInSearch.ListViewModel)
+ searchListViewModel.Add(new SearchModel(null, null, track, 2));
+ foreach (SearchModel item in searchListViewModel)
+ searchGroup.Add(item);
+
+ GroupListViewModel.Add(searchGroup);
+ }
+ }
+
+ public ListViewModel<SearchGroup> GroupListViewModel { get; set; }
+
+ public ArtistViewModel ArtistViewModelInSearch { get; set; }
+
+ public AlbumViewModel AlbumViewModelInSearch { get; set; }
+
+ public TrackViewModel TrackViewModelInSearch { get; set; }
+
+ public void UpdateSearchViewModel(string searchText)
+ {
+ ArtistViewModelInSearch.ListViewModel.Clear();
+ AlbumViewModelInSearch.ListViewModel.Clear();
+ TrackViewModelInSearch.ListViewModel.Clear();
+ List<string> artistList;
+ List<Album> albumList;
+ List<AudioInfo> trackList;
+ if (!string.IsNullOrEmpty(searchText))
+ {
+ artistList = ArtistDataProvider.GetSearchedArtistList(searchText);
+ albumList = AlbumDataProvider.GetSearchedAlbumList(searchText);
+ trackList = TrackDataProvider.GetSearchedTrackList(searchText);
+ }
+ else
+ {
+ artistList = ArtistDataProvider.CurrentArtistList();
+ albumList = AlbumDataProvider.CurrentAlbumList();
+ trackList = TrackDataProvider.CurrentTrackList();
+ }
+ ArtistViewModelInSearch.ListViewModel.CreateData(artistList);
+ AlbumViewModelInSearch.ListViewModel.CreateData(albumList);
+ TrackViewModelInSearch.ListViewModel.CreateData<AudioInfo>(trackList);
+
+ if(GroupListViewModel.Count >0)
+ GroupListViewModel.Clear();
+
+ if (artistList.Count > 0)
+ {
+ SearchGroup searchGroup = new SearchGroup(ArtistViewModelInSearch.ArtistCount);
+ ListViewModel<SearchModel> searchListViewModel = new ListViewModel<SearchModel>();
+ foreach (Artist artist in ArtistViewModelInSearch.ListViewModel)
+ searchListViewModel.Add(new SearchModel(artist, null, null, 0));
+ foreach (SearchModel item in searchListViewModel)
+ searchGroup.Add(item);
+
+ GroupListViewModel.Add(searchGroup);
+ }
+ if (albumList.Count > 0)
+ {
+ SearchGroup searchGroup = new SearchGroup(AlbumViewModelInSearch.AlbumCount);
+ ListViewModel<SearchModel> searchListViewModel = new ListViewModel<SearchModel>();
+ foreach (MusicAlbum musicAlbum in AlbumViewModelInSearch.ListViewModel)
+ searchListViewModel.Add(new SearchModel(null, musicAlbum, null, 1));
+ foreach (SearchModel item in searchListViewModel)
+ searchGroup.Add(item);
+
+ GroupListViewModel.Add(searchGroup);
+ }
+ if (trackList.Count > 0)
+ {
+ SearchGroup searchGroup = new SearchGroup(TrackViewModelInSearch.TrackCount);
+ ListViewModel<SearchModel> searchListViewModel = new ListViewModel<SearchModel>();
+ foreach (Track track in TrackViewModelInSearch.ListViewModel)
+ searchListViewModel.Add(new SearchModel(null, null, track, 2));
+ foreach (SearchModel item in searchListViewModel)
+ searchGroup.Add(item);
+
+ GroupListViewModel.Add(searchGroup);
+ }
+ }
+
+ public void PlayTrack(Track currentTrack)
+ {
+ ListViewModel<Track> trackList = new ListViewModel<Track>();
+ trackList.Add(currentTrack);
+ PlaybackHelper.Instance.PlayCurrent(trackList, currentTrack);
+ }
+ }
+}
--- /dev/null
+using System.Collections.Generic;
+using MusicPlayer.Models;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.ViewModels
+{
+ class SelectorViewModel<T> : PropertyNotifier where T : new()
+ {
+ public SelectorViewModel(ListViewModel<T> viewModel)
+ {
+ listViewModel = viewModel;
+ SelectedCount = "0";
+ TotalCount = ListViewModel.Count;
+ }
+
+ private readonly ListViewModel<T> listViewModel;
+
+ public ListViewModel<T> ListViewModel => listViewModel;
+
+ private string selectedCount;
+ public string SelectedCount
+ {
+ get => selectedCount;
+ set
+ {
+ string text = string.Equals(value, "0") ? "Select Items" : value + " Selected";
+ SetProperty(ref selectedCount, text);
+ }
+ }
+
+ public int TotalCount { get; set; }
+
+ public List<string> TrackList { get; set; }
+
+ public int ShareMediaList(List<string> shareList)
+ {
+ int tracksShared = TrackDataProvider.ShareTrackList(shareList);
+ Tizen.Log.Debug(AppConstants.LogTag, "Shared track count: " + tracksShared);
+ return tracksShared;
+ }
+ }
+}
--- /dev/null
+using System;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+using MusicPlayer.Common;
+using MusicPlayer.Models;
+using MusicPlayer.ViewModels;
+using MusicPlayer.Views.Utils;
+
+namespace MusicPlayer.Views
+{
+ class SearchView : View
+ {
+ private CollectionView collectionView;
+ private View topView;
+ private bool noItemFound;
+ private View noItemView;
+ private TextField textField;
+ private Button backButton;
+ private Button crossButton;
+ private View searchBox;
+ private TextLabel searchLabel;
+
+ private SearchViewModel viewModel;
+
+ public event EventHandler<SubContentViewAddEventArgs> LaunchDetailView;
+
+ public SearchView(SearchViewModel viewModel) : base()
+ {
+ this.viewModel = viewModel;
+ noItemFound = false;
+ noItemView = null;
+ WidthResizePolicy = ResizePolicyType.FillToParent;
+ HeightResizePolicy = ResizePolicyType.FillToParent;
+ BackgroundColor = UIColors.HEXEEEFF1;
+ Layout = new FlexLayout()
+ {
+ Direction = FlexLayout.FlexDirection.Column,
+ Padding = new Extents(64, 64, 0, 0),
+ };
+ AddTopView();
+ AddTopViewElements();
+ AddSearchBox();
+ AddCollectionView();
+ Window.Instance.Add(this);
+ }
+
+ private void AddTopView()
+ {
+ topView = new View()
+ {
+ BackgroundColor = UIColors.HEXEEEFF1,
+ Size2D = new Size2D(Window.Instance.WindowSize.Width - 128, 120),
+ Position2D = new Position2D(64, 0),
+ Layout = new FlexLayout
+ {
+ Direction = FlexLayout.FlexDirection.Row,
+ ItemsAlignment = FlexLayout.AlignmentType.Center,
+ },
+ };
+ base.Add(topView);
+ FlexLayout.SetFlexGrow(topView, 0);
+ FlexLayout.SetFlexShrink(topView, 0);
+ }
+
+ private void AddTopViewElements()
+ {
+ ButtonStyle buttonStyle = new ButtonStyle()
+ {
+ Icon = new ImageViewStyle()
+ {
+ ResourceUrl = Resources.GetImagePath() + "back.png",
+ },
+ IsSelectable = false,
+ IsEnabled = true,
+ };
+
+ backButton = new Button(buttonStyle)
+ {
+ Size2D = new Size2D(48, 48),
+ Margin = new Extents(0, 24, 0, 0),
+ };
+ topView.Add(backButton);
+ backButton.Clicked += BackButtonClicked;
+
+ searchLabel = new TextLabel()
+ {
+ Size2D = new Size2D(960, 48),
+ Text = "Search",
+ TextColor = UIColors.HEX001447,
+ PixelSize = 36,
+ FontFamily = "BreezeSans",
+ Margin = new Extents(0, 32, 0, 0),
+ };
+ topView.Add(searchLabel);
+ }
+
+ private void AddSearchBox()
+ {
+ searchBox = new View()
+ {
+ Size2D = new Size2D(648, 60),
+ Margin = new Extents(0, 32, 0, 0),
+ BackgroundImage = Resources.GetImagePath() + "search_box_bg.png",
+ Layout = new FlexLayout()
+ {
+ Direction = FlexLayout.FlexDirection.Row,
+ ItemsAlignment = FlexLayout.AlignmentType.Center,
+ Justification = FlexLayout.FlexJustification.FlexStart,
+ },
+ };
+ ButtonStyle searchButtonStyle = new ButtonStyle()
+ {
+ Icon = new ImageViewStyle()
+ {
+ ResourceUrl = Resources.GetImagePath() + "search_icon.png",
+ },
+ IsSelectable = false,
+ IsEnabled = true,
+ };
+ Button searchButton = new Button(searchButtonStyle)
+ {
+ Size2D = new Size2D(40, 40),
+ Margin = new Extents(24, 0, 10, 10),
+ Position2D = new Position2D(24, 10),
+ };
+ textField = new TextField()
+ {
+ Size2D = new Size2D(460, 40),
+ BackgroundColor = Color.White,
+ Position2D = new Position2D(88, 10),
+ Margin = new Extents(24, 0, 10, 10),
+ TextColor = UIColors.HEX001447,
+ PlaceholderText = "Type Here",
+ PlaceholderTextFocused = "Search music",
+ };
+ textField.TextChanged += TextFieldTextChanged;
+
+ ButtonStyle crossButtonStyle = new ButtonStyle()
+ {
+ Icon = new ImageViewStyle()
+ {
+ ResourceUrl = Resources.GetImagePath() + "cross_button.png",
+ },
+ IsSelectable = true,
+ IsEnabled = true,
+ };
+
+ crossButton = new Button(crossButtonStyle)
+ {
+ Size2D = new Size2D(48, 48),
+ Margin = new Extents(24, 0, 6, 6),
+ Position2D = new Position2D(572, 6),
+ };
+ crossButton.Clicked += CrossButtonClicked;
+
+ searchBox.Add(searchButton);
+ searchBox.Add(textField);
+ searchBox.Add(crossButton);
+ crossButton.Hide();
+ topView.Add(searchBox);
+ }
+
+ private void TextFieldTextChanged(object sender, TextField.TextChangedEventArgs e)
+ {
+ string searchText = e.TextField.Text;
+ if (string.IsNullOrEmpty(searchText))
+ {
+ crossButton.Hide();
+ crossButton.IsSelectable = false;
+ }
+ else
+ {
+ crossButton.Show();
+ crossButton.IsSelectable = true;
+ }
+ viewModel.UpdateSearchViewModel(searchText);
+ UpdateSearchView();
+ }
+
+ private void CrossButtonClicked(object sender, ClickedEventArgs e)
+ {
+ textField.Text = "";
+ }
+
+ private void BackButtonClicked(object sender, ClickedEventArgs e)
+ {
+ Window.Instance.Remove(this);
+ }
+
+ private void AddCollectionView()
+ {
+ collectionView = new CollectionView()
+ {
+ Size2D = new Size2D(1792, 108),
+ BackgroundImage = Resources.GetImagePath() + "list_view_bg.png",
+ Padding = new Extents(0, 0, 0, 0),
+ ItemsLayouter = new LinearLayouter(),
+ ItemTemplate = new DataTemplate(() =>
+ {
+ ListItemLayout layout = new ListItemLayout();
+ layout.Padding = new Extents(0, 0, 0, 0);
+ layout.Margin = new Extents(0, 0, 0, 0);
+ layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "Thumbnail");
+ layout.TitleLabel.SetBinding(TextLabel.TextProperty, "Title");
+ layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "SubTitle");
+ return layout;
+ }),
+ GroupHeaderTemplate = new DataTemplate(() =>
+ {
+ DefaultTitleItem group = new DefaultTitleItem();
+ group.WidthSpecification = 1792;
+ group.Padding = new Extents(0, 0, 0, 0);
+ group.Margin = new Extents(0, 0, 0, 0);
+ group.Label.SetBinding(TextLabel.TextProperty, "DataCount");
+ group.Label.HorizontalAlignment = HorizontalAlignment.Begin;
+ group.Label.VerticalAlignment = VerticalAlignment.Center;
+ return group;
+ }),
+ IsGrouped = true,
+ ScrollingDirection = ScrollableBase.Direction.Vertical,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ SelectionMode = ItemSelectionMode.Single,
+ };
+ base.Add(collectionView);
+ FlexLayout.SetFlexGrow(collectionView, 1);
+ FlexLayout.SetFlexShrink(collectionView, 1);
+ collectionView.ItemsSource = viewModel.GroupListViewModel;
+ collectionView.SelectionChanged += OnItemSelection;
+ }
+
+ private void OnItemSelection(object sender, SelectionChangedEventArgs e)
+ {
+ object selectedObject = collectionView.SelectedItem;
+ if (selectedObject is SearchModel)
+ {
+ Window.Instance.Remove(this);
+ SearchModel searchModel = (SearchModel)selectedObject;
+ if (searchModel.ItemType == 0)
+ {
+ Artist currentArtist = searchModel.ArtistDetail;
+ SubContentViewAddEventArgs artistDetailViewArgs = new SubContentViewAddEventArgs(SubContentViewType.ArtistDetails, currentArtist.ArtistName, currentArtist);
+ LaunchDetailView?.Invoke(this, artistDetailViewArgs);
+ }
+ else if (searchModel.ItemType == 1)
+ {
+ MusicAlbum currentAlbum = searchModel.AlbumDetail;
+ SubContentViewAddEventArgs albumDetailViewArgs = new SubContentViewAddEventArgs(SubContentViewType.AlbumDetails, currentAlbum.AlbumName, currentAlbum);
+ LaunchDetailView?.Invoke(this, albumDetailViewArgs);
+ }
+ else if (searchModel.ItemType == 2)
+ {
+ Track currentTrack = searchModel.TrackDetail;
+ viewModel.PlayTrack(currentTrack);
+ }
+ }
+ }
+
+ public void UpdateSearchView()
+ {
+ if (viewModel.GroupListViewModel.Count > 0)
+ {
+ if (noItemFound)
+ {
+ base.Remove(noItemView);
+ base.Add(collectionView);
+ }
+ noItemFound = false;
+ }
+ else
+ {
+ if (noItemView == null)
+ {
+ noItemView = new View()
+ {
+ BackgroundColor = UIColors.HEXEEEFF1,
+ WidthSpecification = LayoutParamPolicies.MatchParent,
+ HeightResizePolicy = ResizePolicyType.FillToParent,
+ Layout = new FlexLayout
+ {
+ Direction = FlexLayout.FlexDirection.Column,
+ ItemsAlignment = FlexLayout.AlignmentType.Center,
+ Justification = FlexLayout.FlexJustification.FlexStart,
+ Padding = new Extents(0, 0, 40, 0),
+ }
+ };
+ ImageView noResultsIcon = new ImageView()
+ {
+ BackgroundColor = UIColors.HEXEEEFF1,
+ ResourceUrl = Resources.GetImagePath() + "no_results_found.png",
+ Size2D = new Size2D(264, 292),
+ };
+ noItemView.Add(noResultsIcon);
+ TextLabel textLabel = new TextLabel()
+ {
+ Size2D = new Size2D(1124, 36),
+ Text = "No results found",
+ TextColor = UIColors.HEX001447,
+ PixelSize = 28,
+ FontFamily = "BreezeSans",
+ HorizontalAlignment = HorizontalAlignment.Center,
+ Margin = new Extents(0, 0, 32, 0),
+ };
+ noItemView.Add(textLabel);
+ }
+ if (!noItemFound)
+ {
+ base.Remove(collectionView);
+ base.Add(noItemView);
+ }
+ noItemFound = true;
+ }
+ }
+ }
+}
--- /dev/null
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI;
+using MusicPlayer.Common;
+
+namespace MusicPlayer.Views
+{
+ class SelectListLayout : RecyclerViewItem
+ {
+ private static int Width = 1792;
+ private static int Height = 108;
+
+ private const int BoxSize = 36;
+ private const int IconSize = 64;
+ private const int LayoutMargin = 16;
+ private const int LayoutPadding = 32;
+ private const int SeperatorHeight = 1;
+ private const int LeftPadding = 64;
+ private const int x = 0;
+
+ private CheckBox checkBox;
+ private View itemSeperator;
+ private TextLabel titleLabel;
+ private TextLabel subtitleLabel;
+ private ImageView icon;
+
+ public SelectListLayout(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;
+
+ StringSelector iconURL = new StringSelector()
+ {
+ Disabled = Resources.GetImagePath() + "check_off.png",
+ DisabledSelected = Resources.GetImagePath() + "check_on.png",
+ };
+
+ checkBox = new CheckBox()
+ {
+ Size2D = new Size2D(BoxSize, BoxSize),
+ IsCreateByXaml = true,
+ Position2D = new Position2D(x, BoxSize),
+ IconURLSelector = iconURL,
+ IsSelected = false,
+ IsEnabled =false,
+ };
+
+ checkBox.Icon.Opacity = 1.0f;
+ checkBox.Icon.Size = new Size2D(BoxSize, BoxSize);
+ base.Add(checkBox);
+
+ icon = new ImageView()
+ {
+ WidthSpecification = IconSize,
+ HeightSpecification = IconSize,
+ IsCreateByXaml = true,
+ Position2D = new Position2D(x + BoxSize + LayoutPadding, ((Height / 2) - (IconSize / 2))),
+ };
+ base.Add(icon);
+
+ itemSeperator = new View()
+ {
+ WidthSpecification = (Width - (2 * LeftPadding)),
+ HeightSpecification = SeperatorHeight,
+ ExcludeLayouting = true,
+ Position2D = new Position2D(x, Height - SeperatorHeight),
+ BackgroundColor = UIColors.ItemSeperator,
+ };
+ base.Add(itemSeperator);
+
+ titleLabel = new TextLabel()
+ {
+ WidthSpecification = (Width - (2 * LeftPadding) - IconSize - 2 * LayoutPadding - BoxSize),
+ HeightSpecification = 40,
+ TextColor = UIColors.HEX001447,
+ PixelSize = 32,
+ FontFamily = "BreezeSans",
+ VerticalAlignment = VerticalAlignment.Center,
+ IsCreateByXaml = true,
+ Position2D = new Position2D((x + IconSize + 2 * LayoutPadding + BoxSize), LayoutMargin),
+ };
+ base.Add(titleLabel);
+
+ subtitleLabel = new TextLabel()
+ {
+ WidthSpecification = (Width - (2 * LeftPadding) - IconSize - 2* LayoutPadding - BoxSize),
+ HeightSpecification = 36,
+ TextColor = UIColors.HEX001447,
+ PixelSize = 28,
+ FontFamily = "BreezeSans",
+ VerticalAlignment = VerticalAlignment.Center,
+ IsCreateByXaml = true,
+ Position2D = new Position2D((x + IconSize + 2 * LayoutPadding + BoxSize), LayoutMargin + 40)
+ };
+ base.Add(subtitleLabel);
+ IsCreateByXaml = true;
+ IsSelected = false;
+ }
+
+ public ImageView Icon
+ {
+ get => icon;
+ }
+ public TextLabel TitleLabel
+ {
+ get => titleLabel;
+ }
+ public TextLabel SubtitleLabel
+ {
+ get => subtitleLabel;
+ }
+
+ public CheckBox Checkbox
+ {
+ get => checkBox;
+ }
+
+ protected override void Dispose(DisposeTypes type)
+ {
+ if (Disposed)
+ {
+ return;
+ }
+ if (type == DisposeTypes.Explicit)
+ {
+ base.Remove(itemSeperator);
+ itemSeperator?.Dispose();
+ itemSeperator = null;
+
+ base.Remove(checkBox);
+ checkBox?.Dispose();
+ checkBox = null;
+
+ base.Remove(icon);
+ icon?.Dispose();
+ icon = null;
+
+ base.Remove(titleLabel);
+ titleLabel?.Dispose();
+ titleLabel = null;
+
+ base.Remove(subtitleLabel);
+ subtitleLabel?.Dispose();
+ subtitleLabel = null;
+ }
+
+ base.Dispose(type);
+ }
+ }
+}
--- /dev/null
+using System.Collections;
+using System.Collections.Specialized;
+using System.Collections.Generic;
+using MusicPlayer.ViewModels;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+using MusicPlayer.Common;
+using MusicPlayer.Models;
+using MusicPlayer.Core;
+using MusicPlayer.Views.Utils;
+
+namespace MusicPlayer.Views
+{
+ // This class need to be refactored for better design
+ // Need to create BaseSelectorView classs
+ // And Derive PlaylistSelectorView, TrackSelectorView, AlbumSelectorView, ArtistSelectorView for better code quality
+ using AudioInfo = Tizen.Content.MediaContent.AudioInfo;
+ class SelectorView <T>: View where T : new()
+ {
+ private const int LayoutPadding = 64;
+ private const int TextLabelHeight = 48;
+ private const int TextButtonWidth = 260;
+ private const int LayoutMargin = 36;
+
+ private View topView;
+ private View selAllView;
+ private TextLabel selectedCountLabel;
+ private CheckBox selAllButton;
+ private Button cancelButton;
+ private Button doneButton;
+ private CollectionView collectionView;
+
+ int itemCount = 0;
+ public List<string> selectedItemList;
+
+ private SelectorViewModel<T> viewModel;
+ private OperationViewType currentViewType;
+
+
+ public SelectorView(OperationViewType viewType, SelectorViewModel<T> viewModel) : base()
+ {
+ currentViewType = viewType;
+ selectedItemList = new List<string>();
+ this.viewModel = viewModel;
+ BindingContext = viewModel;
+ BackgroundColor = UIColors.HEXEEEFF1;
+ WidthResizePolicy = ResizePolicyType.FillToParent;
+ HeightResizePolicy = ResizePolicyType.FillToParent;
+
+ Layout = new FlexLayout()
+ {
+ Direction = FlexLayout.FlexDirection.Column,
+ ItemsAlignment = FlexLayout.AlignmentType.FlexStart,
+ Justification = FlexLayout.FlexJustification.FlexStart,
+ };
+
+ topView = AddTopView();
+ AddSelectCountLabel();
+ AddButtons();
+ selAllView = AddSelAllView();
+ AddSelAllViewElements();
+ collectionView = AddCollectionView();
+ itemCount = 0;
+
+ Window.Instance.Add(this);
+ }
+
+ public List<string> SelectedItemList => selectedItemList;
+
+ private Button CreateButton(string url, int x, int y)
+ {
+ ButtonStyle buttonStyle = new ButtonStyle()
+ {
+ Text = new TextLabelStyle()
+ {
+ Text = url,
+ PixelSize = 28,
+ FontFamily = "BreezeSans",
+ TextColor = UIColors.HEX000C2B,
+ HorizontalAlignment = HorizontalAlignment.Center,
+ VerticalAlignment = VerticalAlignment.Center,
+ },
+ IsSelectable = false,
+ };
+
+ Button button = new Button(buttonStyle)
+ {
+ Size2D = new Size2D(TextButtonWidth, TextLabelHeight),
+ Position2D = new Position2D(x, y),
+ IsEnabled = false,
+ IsSelectable = true,
+ };
+ return button;
+ }
+
+ private View AddTopView()
+ {
+ View topView = new View()
+ {
+ WidthSpecification = Window.Instance.WindowSize.Width,
+ HeightSpecification = 120,
+ Layout = new FlexLayout()
+ {
+ Direction = FlexLayout.FlexDirection.Row,
+ Padding = new Extents(LayoutPadding, LayoutPadding, LayoutMargin, LayoutMargin),
+ },
+ };
+ base.Add(topView);
+ return topView;
+ }
+
+ private void AddSelectCountLabel()
+ {
+ selectedCountLabel = new TextLabel()
+ {
+ Size2D = new Size2D(1192, TextLabelHeight),
+ Position2D = new Position2D(LayoutPadding, 0),
+ PixelSize = 36,
+ FontFamily = "BreezeSans",
+ TextColor = UIColors.HEX000209,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Center,
+ Ellipsis = true,
+ };
+ selectedCountLabel.SetBinding(TextLabel.TextProperty, "SelectedCount");
+ topView.Add(selectedCountLabel);
+ }
+
+ private void AddButtons()
+ {
+ cancelButton = CreateButton("Cancel", Window.Instance.WindowSize.Width - LayoutPadding - 2 * TextButtonWidth -40, LayoutMargin);
+ cancelButton.Margin = new Extents(40, 0, 0, 0);
+ cancelButton.IsEnabled = true;
+ topView.Add(cancelButton);
+ cancelButton.Clicked += (object o, ClickedEventArgs args) =>
+ {
+ OnCancel();
+ };
+
+ doneButton = CreateButton("Done", Window.Instance.WindowSize.Width - LayoutPadding - TextButtonWidth, LayoutMargin);
+ doneButton.Margin = new Extents(40, 0, 0, 0);
+ topView.Add(doneButton);
+ doneButton.Clicked += (object o, ClickedEventArgs args) =>
+ {
+ OnDone();
+ };
+ }
+
+ private void OnCancel()
+ {
+ ClearSelectionAndRemove();
+ }
+
+ private void OnDone()
+ {
+ Tizen.Log.Error(AppConstants.LogTag, "OnDone, Operation Type is: " + currentViewType.ToString());
+ if (currentViewType == OperationViewType.Share)
+ {
+ int sharedItems = viewModel.ShareMediaList(SelectedItemList);
+ Tizen.Log.Debug(AppConstants.LogTag, "Total shared items: " + sharedItems);
+ }
+ else
+ {
+ if (typeof(T) == typeof(PlaylistModel))
+ {
+ int playlistDeleted = PlaylistManager.Instance.DeletePlaylists(SelectedItemList);
+ Tizen.Log.Debug(AppConstants.LogTag, "Total playlist deleted: " + playlistDeleted);
+ }
+ else
+ {
+ int tracksDeleted = TrackDataProvider.DeleteTrackList(SelectedItemList);
+ Tizen.Log.Debug(AppConstants.LogTag, "Total tracks deleted: " + tracksDeleted);
+ }
+ }
+ ClearSelectionAndRemove();
+ }
+
+ private void ClearSelectionAndRemove()
+ {
+ collectionView.SelectedItems.Clear();
+ Window.Instance.Remove(this);
+ }
+
+ private View AddSelAllView()
+ {
+ View selAllView = new View()
+ {
+ WidthSpecification = Window.Instance.WindowSize.Width - 2 * LayoutPadding,
+ HeightSpecification = 108,
+ Position2D = new Position2D(LayoutPadding,120),
+ Margin = new Extents(LayoutPadding,LayoutPadding,0,40),
+ BackgroundImage = Resources.GetImagePath() + "list_view_bg.png",
+ };
+ base.Add(selAllView);
+ return selAllView;
+ }
+
+ private void AddSelAllViewElements()
+ {
+ selAllButton = new CheckBox()
+ {
+ Size2D = new Size2D(36, 36),
+ Position2D = new Position2D(LayoutPadding, LayoutMargin),
+ Margin = new Extents(LayoutPadding, 32, LayoutMargin, LayoutMargin),
+ };
+ selAllView.Add(selAllButton);
+ selAllButton.Clicked += OnSelAllClicked;
+
+ TextLabel selAll = new TextLabel()
+ {
+ Text = "Select All",
+ Size2D = new Size2D(1596, 40),
+ Margin = new Extents(0,LayoutPadding,34,34),
+ Position2D = new Position2D(LayoutPadding+36+32, 34),
+ PixelSize = 32,
+ FontFamily = "BreezeSans",
+ TextColor = UIColors.HEX001447,
+ HorizontalAlignment = HorizontalAlignment.Begin,
+ VerticalAlignment = VerticalAlignment.Center,
+ Ellipsis = true,
+ };
+ selAllView.Add(selAll);
+ }
+
+ private void OnSelAllClicked(object sender, ClickedEventArgs e)
+ {
+ if(selAllButton.IsSelected)
+ {
+ doneButton.IsEnabled = true;
+ foreach (object item in collectionView.ItemsSource)
+ {
+ if (!collectionView.SelectedItems.Contains(item))
+ {
+ collectionView.SelectedItems.Add(item);
+ }
+ }
+ itemCount = viewModel.TotalCount;
+ }
+ else
+ {
+ doneButton.IsEnabled = false;
+ collectionView.SelectedItems.Clear();
+ itemCount = 0;
+ selectedItemList.Clear();
+ }
+ viewModel.SelectedCount = itemCount.ToString();
+ Tizen.Log.Debug(AppConstants.LogTag, "Total tracks selected " + selectedItemList.Count);
+ }
+
+ public void CancelSelection()
+ {
+ collectionView.SelectedItems.Clear();
+ Window.Instance.Remove(this);
+ }
+
+ public void DoneSelection()
+ {
+ collectionView.SelectedItems.Clear();
+ Window.Instance.Remove(this);
+ }
+
+ private CollectionView AddCollectionView()
+ {
+ CollectionView collectionView = new CollectionView()
+ {
+ Size2D = new Size2D(1792, 108),
+ Margin = new Extents(LayoutPadding, LayoutPadding, 0, 0),
+ BackgroundImage = Resources.GetImagePath() + "list_view_bg.png",
+ ItemsLayouter = new LinearLayouter(),
+ ScrollingDirection = ScrollableBase.Direction.Vertical,
+ HeightSpecification = LayoutParamPolicies.WrapContent,
+ SelectionMode = ItemSelectionMode.Multiple,
+ };
+ base.Add(collectionView);
+ FlexLayout.SetFlexGrow(collectionView, 1);
+ FlexLayout.SetFlexShrink(collectionView, 1);
+ if (typeof(T) == typeof(MusicAlbum))
+ {
+ collectionView.ItemTemplate = new DataTemplate(() =>
+ {
+ SelectListLayout layout = new SelectListLayout();
+ layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "AlbumArtPath");
+ layout.TitleLabel.SetBinding(TextLabel.TextProperty, "AlbumName");
+ layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName");
+ layout.Checkbox.SetBinding(Button.IsSelectedProperty, "IsSelected");
+ return layout;
+ });
+ collectionView.ItemsSource = viewModel.ListViewModel;
+ }
+ else if (typeof(T) == typeof(Track))
+ {
+ collectionView.ItemTemplate = new DataTemplate(() =>
+ {
+ SelectListLayout layout = new SelectListLayout();
+ layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "ThumbnailPath");
+ layout.TitleLabel.SetBinding(TextLabel.TextProperty, "TrackTitle");
+ layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName");
+ layout.Checkbox.SetBinding(Button.IsSelectedProperty, "IsSelected");
+ return layout;
+ });
+ collectionView.ItemsSource = viewModel.ListViewModel;
+ }
+ else if (typeof(T) == typeof(Artist))
+ {
+ collectionView.ItemTemplate = new DataTemplate(() =>
+ {
+ SelectListLayout layout = new SelectListLayout();
+ layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "AlbumArtPath");
+ layout.TitleLabel.SetBinding(TextLabel.TextProperty, "ArtistName");
+ layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "TotalCount");
+ layout.Checkbox.SetBinding(Button.IsSelectedProperty, "IsSelected");
+ return layout;
+ });
+ collectionView.ItemsSource = viewModel.ListViewModel;
+ }
+ else if(typeof(T) == typeof(PlaylistModel))
+ {
+ collectionView.ItemTemplate = new DataTemplate(() =>
+ {
+ SelectListLayout layout = new SelectListLayout();
+ layout.Icon.SetBinding(ImageView.ResourceUrlProperty, "PlaylistThumbnailPath");
+ layout.TitleLabel.SetBinding(TextLabel.TextProperty, "PlaylistName");
+ layout.SubtitleLabel.SetBinding(TextLabel.TextProperty, "PlaylistTrackCount");
+ layout.Checkbox.SetBinding(Button.IsSelectedProperty, "PlaylistIsSelected");
+ return layout;
+ });
+ collectionView.ItemsSource = viewModel.ListViewModel;
+ }
+ collectionView.SelectionChanged += SelectionEvent;
+ return collectionView;
+ }
+
+ public void SelectionEvent(object sender, SelectionChangedEventArgs ev)
+ {
+ List<object> oldSel = new List<object>(ev.PreviousSelection);
+ List<object> newSel = new List<object>(ev.CurrentSelection);
+
+ foreach (object item in oldSel)
+ {
+ if (item != null && !newSel.Contains(item))
+ {
+ itemCount--;
+ if (item is Track)
+ {
+ Track trackItem = (Track)item;
+ trackItem.IsSelected = false;
+ selectedItemList.Remove(trackItem.Id);
+ }
+ else if (item is Artist)
+ {
+ Artist artistItem = (Artist)item;
+ artistItem.IsSelected = false;
+ string text = artistItem.ArtistName;
+ if (text == "Unknown")
+ text = "";
+ List<AudioInfo> artistTrackList = ArtistDataProvider.GetArtistTrackList(text);
+ foreach (AudioInfo track in artistTrackList)
+ {
+ selectedItemList.Remove(track.Id);
+ }
+ }
+ else if (item is MusicAlbum)
+ {
+ MusicAlbum albumItem = (MusicAlbum)item;
+ albumItem.IsSelected = false;
+ List<AudioInfo> albumTrackList = AlbumDataProvider.GetAlbumTrackList(albumItem.Id);
+ foreach (AudioInfo track in albumTrackList)
+ {
+ selectedItemList.Remove(track.Id);
+ }
+ }
+ else if(item is PlaylistModel)
+ {
+ PlaylistModel playlistItem = (PlaylistModel)item;
+ playlistItem.PlaylistIsSelected = false;
+ selectedItemList.Remove(playlistItem.PlaylistId.ToString());
+ }
+ }
+ }
+
+ foreach (object item in newSel)
+ {
+ if (item != null && !oldSel.Contains(item))
+ {
+ itemCount++;
+ if (item is Track)
+ {
+ Track trackItem = (Track)item;
+ trackItem.IsSelected = true;
+ selectedItemList.Add(trackItem.Id);
+ }
+ else if (item is Artist)
+ {
+ Artist artistItem = (Artist)item;
+ artistItem.IsSelected = true;
+ string text = artistItem.ArtistName;
+ if (text == "Unknown")
+ text = "";
+ List<AudioInfo> artistTrackList = ArtistDataProvider.GetArtistTrackList(text);
+ foreach (AudioInfo track in artistTrackList)
+ {
+ selectedItemList.Add(track.Id);
+ }
+ }
+ else if (item is MusicAlbum)
+ {
+ MusicAlbum albumItem = (MusicAlbum)item;
+ albumItem.IsSelected = true;
+ List<AudioInfo> albumTrackList = AlbumDataProvider.GetAlbumTrackList(albumItem.Id);
+ foreach (AudioInfo track in albumTrackList)
+ {
+ selectedItemList.Add(track.Id);
+ }
+ }
+ else if (item is PlaylistModel)
+ {
+ PlaylistModel playlistItem = (PlaylistModel)item;
+ playlistItem.PlaylistIsSelected = true;
+ selectedItemList.Add(playlistItem.PlaylistId.ToString());
+ }
+ }
+ }
+
+ viewModel.SelectedCount = itemCount.ToString();
+
+ if (itemCount == 0)
+ doneButton.IsEnabled = false;
+ else
+ doneButton.IsEnabled = true;
+
+ Tizen.Log.Debug(AppConstants.LogTag, "Total tracks selected " + selectedItemList.Count);
+ if (itemCount == viewModel.TotalCount)
+ selAllButton.IsSelected = true;
+ else
+ selAllButton.IsSelected = false;
+ }
+ }
+}