using System.Collections.Generic; using System.Linq; using CommunityToolkit.Mvvm.Input; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Wino.Core.Domain.Models.Reader; using Wino.Core.UWP.Controls; using Wino.Helpers; namespace Wino.MenuFlyouts; public partial class FilterMenuFlyout : MenuFlyout { public static readonly DependencyProperty SelectedFilterChangedCommandProperty = DependencyProperty.Register(nameof(SelectedFilterChangedCommand), typeof(IRelayCommand), typeof(FilterMenuFlyout), new PropertyMetadata(null)); public static readonly DependencyProperty FilterOptionsProperty = DependencyProperty.Register(nameof(FilterOptions), typeof(List), typeof(FilterMenuFlyout), new PropertyMetadata(null, new PropertyChangedCallback(OnOptionsChanged))); public static readonly DependencyProperty SelectedFilterOptionProperty = DependencyProperty.Register(nameof(SelectedFilterOption), typeof(FilterOption), typeof(FilterMenuFlyout), new PropertyMetadata(null, OnSelectedFilterOptionChanged)); public static readonly DependencyProperty SelectedSortingOptionProperty = DependencyProperty.Register(nameof(SelectedSortingOption), typeof(SortingOption), typeof(FilterMenuFlyout), new PropertyMetadata(null, new PropertyChangedCallback(OnSelectedSortingOptionChanged))); public static readonly DependencyProperty SortingOptionsProperty = DependencyProperty.Register(nameof(SortingOptions), typeof(List), typeof(FilterMenuFlyout), new PropertyMetadata(null, new PropertyChangedCallback(OnOptionsChanged))); public static readonly DependencyProperty SelectedSortingOptionChangedCommandProperty = DependencyProperty.Register(nameof(SelectedSortingOptionChangedCommand), typeof(IRelayCommand), typeof(FilterMenuFlyout), new PropertyMetadata(null)); public IRelayCommand SelectedFilterChangedCommand { get { return (IRelayCommand)GetValue(SelectedFilterChangedCommandProperty); } set { SetValue(SelectedFilterChangedCommandProperty, value); } } public IRelayCommand SelectedSortingOptionChangedCommand { get { return (IRelayCommand)GetValue(SelectedSortingOptionChangedCommandProperty); } set { SetValue(SelectedSortingOptionChangedCommandProperty, value); } } public List FilterOptions { get { return (List)GetValue(FilterOptionsProperty); } set { SetValue(FilterOptionsProperty, value); } } public List SortingOptions { get { return (List)GetValue(SortingOptionsProperty); } set { SetValue(SortingOptionsProperty, value); } } public FilterOption SelectedFilterOption { get { return (FilterOption)GetValue(SelectedFilterOptionProperty); } set { SetValue(SelectedFilterOptionProperty, value); } } public SortingOption SelectedSortingOption { get { return (SortingOption)GetValue(SelectedSortingOptionProperty); } set { SetValue(SelectedSortingOptionProperty, value); } } private static void OnSelectedFilterOptionChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { if (obj is FilterMenuFlyout bar) { bar.SelectFilterOption(bar.SelectedFilterOption); bar.SelectedFilterChangedCommand?.Execute(bar.SelectedFilterOption); } } private static void OnSelectedSortingOptionChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { if (obj is FilterMenuFlyout bar) { bar.SelectSortingOption(bar.SelectedSortingOption); bar.SelectedSortingOptionChangedCommand?.Execute(bar.SelectedSortingOption); } } private ToggleMenuFlyoutItem CreateFilterToggleButton(FilterOption option) { var button = new ToggleMenuFlyoutItem() { Text = option.Title, Tag = option, Icon = new WinoFontIcon() { Icon = XamlHelpers.GetWinoIconGlyph(option.Type) }, IsChecked = option == SelectedFilterOption }; button.Click += FilterToggleChecked; return button; } private ToggleMenuFlyoutItem CreateSortingToggleButton(SortingOption option) { var button = new ToggleMenuFlyoutItem() { Text = option.Title, Tag = option, Icon = new WinoFontIcon() { Icon = XamlHelpers.GetWinoIconGlyph(option.Type)}, IsChecked = option == SelectedSortingOption }; button.Click += SortingOptionChecked; return button; } private void SortingOptionChecked(object sender, RoutedEventArgs e) { if (sender is ToggleMenuFlyoutItem button) { button.IsHitTestVisible = false; var optionModel = button.Tag as SortingOption; SelectSortingOption(optionModel); } } private void FilterToggleChecked(object sender, RoutedEventArgs e) { if (sender is ToggleMenuFlyoutItem button) { button.IsHitTestVisible = false; var optionModel = button.Tag as FilterOption; SelectFilterOption(optionModel); } } private void SelectFilterOption(FilterOption option) { SelectedFilterOption = option; UncheckOtherFilterOptions(); } private void SelectSortingOption(SortingOption option) { SelectedSortingOption = option; UncheckOtherSortingOptions(); } private void UnregisterCheckedHandler(ToggleMenuFlyoutItem button) { button.Click -= FilterToggleChecked; } private void UncheckOtherFilterOptions() { if (Items.Any()) { foreach (var item in Items) { if (item is ToggleMenuFlyoutItem toggleButton && toggleButton.Tag is FilterOption option && option != SelectedFilterOption) { toggleButton.IsChecked = false; toggleButton.IsHitTestVisible = true; } } } } private void UncheckOtherSortingOptions() { if (Items.Any()) { foreach (var item in Items) { if (item is ToggleMenuFlyoutItem toggleButton && toggleButton.Tag is SortingOption option && option != SelectedSortingOption) { toggleButton.IsChecked = false; toggleButton.IsHitTestVisible = true; } } } } public void Dispose() { foreach (var item in Items) { if (item is ToggleMenuFlyoutItem toggleButton) { UnregisterCheckedHandler(toggleButton); } } } private static void OnOptionsChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args) { if (obj is FilterMenuFlyout bar && bar.SortingOptions != null && bar.FilterOptions != null) { bar.Dispose(); bar.Items.Clear(); if (bar.FilterOptions != null) { foreach (var item in bar.FilterOptions) { bar.Items.Add(bar.CreateFilterToggleButton(item)); } } bar.Items.Add(new MenuFlyoutSeparator()); // Sorting options. if (bar.SortingOptions != null) { foreach (var item in bar.SortingOptions) { bar.Items.Add(bar.CreateSortingToggleButton(item)); } } } } }