Better creation of context menu items for calendar events.
This commit is contained in:
@@ -1,56 +1,30 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using CommunityToolkit.Mvvm.Input;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
|
||||||
using Microsoft.UI.Xaml;
|
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
using Wino.Calendar.ViewModels.Messages;
|
|
||||||
using Wino.Calendar.ViewModels.Data;
|
using Wino.Calendar.ViewModels.Data;
|
||||||
|
using Wino.Calendar.ViewModels.Messages;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain;
|
||||||
using Wino.Core.Domain.Enums;
|
using Wino.Core.Domain.Enums;
|
||||||
using Wino.Core.Domain.Interfaces;
|
|
||||||
using Wino.Core.Domain.Models.Calendar;
|
using Wino.Core.Domain.Models.Calendar;
|
||||||
using Wino.Mail.WinUI;
|
|
||||||
using Wino.Mail.WinUI.Controls;
|
using Wino.Mail.WinUI.Controls;
|
||||||
|
|
||||||
namespace Wino.Calendar.Controls;
|
namespace Wino.Calendar.Controls;
|
||||||
|
|
||||||
public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
||||||
{
|
{
|
||||||
private readonly ICalendarContextMenuItemService _contextMenuItemService;
|
private readonly RelayCommand<CalendarContextMenuAction> _executeActionCommand;
|
||||||
|
|
||||||
public static readonly DependencyProperty ItemProperty = DependencyProperty.Register(nameof(Item), typeof(CalendarItemViewModel), typeof(CalendarItemCommandBarFlyout), new PropertyMetadata(null, new PropertyChangedCallback(OnItemChanged)));
|
|
||||||
|
|
||||||
public CalendarItemViewModel Item
|
|
||||||
{
|
|
||||||
get { return (CalendarItemViewModel)GetValue(ItemProperty); }
|
|
||||||
set { SetValue(ItemProperty, value); }
|
|
||||||
}
|
|
||||||
|
|
||||||
public CalendarItemCommandBarFlyout()
|
public CalendarItemCommandBarFlyout()
|
||||||
{
|
{
|
||||||
_contextMenuItemService = WinoApplication.Current.Services.GetRequiredService<ICalendarContextMenuItemService>();
|
_executeActionCommand = new RelayCommand<CalendarContextMenuAction>(ExecuteAction);
|
||||||
Opening += FlyoutOpening;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
public CalendarItemViewModel? Item { get; set; }
|
||||||
|
|
||||||
|
public void SetMenuItems(IReadOnlyList<CalendarContextMenuItem> menuItems)
|
||||||
{
|
{
|
||||||
if (d is CalendarItemCommandBarFlyout flyout)
|
ClearMenuItems();
|
||||||
{
|
|
||||||
flyout.UpdateMenuItems();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void FlyoutOpening(object sender, object e) => UpdateMenuItems();
|
|
||||||
|
|
||||||
private void UpdateMenuItems()
|
|
||||||
{
|
|
||||||
PrimaryCommands.Clear();
|
|
||||||
SecondaryCommands.Clear();
|
|
||||||
|
|
||||||
if (Item?.CalendarItem == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var menuItems = _contextMenuItemService.GetContextMenuItems(Item.CalendarItem);
|
|
||||||
|
|
||||||
foreach (var menuItem in menuItems)
|
foreach (var menuItem in menuItems)
|
||||||
{
|
{
|
||||||
@@ -63,12 +37,20 @@ public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearMenuItems()
|
||||||
|
{
|
||||||
|
PrimaryCommands.Clear();
|
||||||
|
SecondaryCommands.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
private AppBarButton BuildAppBarButton(CalendarContextMenuItem menuItem)
|
private AppBarButton BuildAppBarButton(CalendarContextMenuItem menuItem)
|
||||||
{
|
{
|
||||||
var button = new AppBarButton
|
var button = new AppBarButton
|
||||||
{
|
{
|
||||||
Label = GetActionLabel(menuItem.Action),
|
Label = GetActionLabel(menuItem.Action),
|
||||||
IsEnabled = menuItem.IsEnabled,
|
IsEnabled = menuItem.IsEnabled,
|
||||||
|
Command = _executeActionCommand,
|
||||||
|
CommandParameter = menuItem.Action,
|
||||||
Icon = new WinoFontIcon
|
Icon = new WinoFontIcon
|
||||||
{
|
{
|
||||||
Icon = GetActionIcon(menuItem.Action),
|
Icon = GetActionIcon(menuItem.Action),
|
||||||
@@ -82,10 +64,6 @@ public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
|||||||
PopulateMenuFlyoutItems(flyout.Items, menuItem.Children);
|
PopulateMenuFlyoutItems(flyout.Items, menuItem.Children);
|
||||||
button.Flyout = flyout;
|
button.Flyout = flyout;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
button.Click += (_, _) => ExecuteAction(menuItem.Action);
|
|
||||||
}
|
|
||||||
|
|
||||||
return button;
|
return button;
|
||||||
}
|
}
|
||||||
@@ -110,10 +88,11 @@ public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
|||||||
var flyoutItem = new MenuFlyoutItem
|
var flyoutItem = new MenuFlyoutItem
|
||||||
{
|
{
|
||||||
Text = GetActionLabel(menuItem.Action),
|
Text = GetActionLabel(menuItem.Action),
|
||||||
IsEnabled = menuItem.IsEnabled
|
IsEnabled = menuItem.IsEnabled,
|
||||||
|
Command = _executeActionCommand,
|
||||||
|
CommandParameter = menuItem.Action
|
||||||
};
|
};
|
||||||
|
|
||||||
flyoutItem.Click += (_, _) => ExecuteAction(menuItem.Action);
|
|
||||||
items.Add(flyoutItem);
|
items.Add(flyoutItem);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,7 +100,8 @@ public partial class CalendarItemCommandBarFlyout : CommandBarFlyout
|
|||||||
|
|
||||||
private void ExecuteAction(CalendarContextMenuAction action)
|
private void ExecuteAction(CalendarContextMenuAction action)
|
||||||
{
|
{
|
||||||
if (Item == null)
|
// We don't want to trigger any action or hide the flyout if it's a sub menu item.
|
||||||
|
if (Item == null || (action.ShowAs == null && action.ResponseStatus == null && action.TargetType == null))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WeakReferenceMessenger.Default.Send(new CalendarItemContextActionRequestedMessage(Item, action));
|
WeakReferenceMessenger.Default.Send(new CalendarItemContextActionRequestedMessage(Item, action));
|
||||||
|
|||||||
@@ -31,9 +31,10 @@
|
|||||||
<Grid.ContextFlyout>
|
<Grid.ContextFlyout>
|
||||||
<local:CalendarItemCommandBarFlyout
|
<local:CalendarItemCommandBarFlyout
|
||||||
AlwaysExpanded="True"
|
AlwaysExpanded="True"
|
||||||
Item="{x:Bind CalendarItem, Mode=OneWay}"
|
Closed="CalendarItemCommandBarFlyout_Closed"
|
||||||
|
Opening="CalendarItemCommandBarFlyout_Opening"
|
||||||
Placement="BottomEdgeAlignedLeft"
|
Placement="BottomEdgeAlignedLeft"
|
||||||
ShowMode="Transient" />
|
ShowMode="Auto" />
|
||||||
</Grid.ContextFlyout>
|
</Grid.ContextFlyout>
|
||||||
|
|
||||||
|
|
||||||
@@ -80,8 +81,8 @@
|
|||||||
<muxc:ProgressRing
|
<muxc:ProgressRing
|
||||||
x:Name="BusyRing"
|
x:Name="BusyRing"
|
||||||
Grid.Column="2"
|
Grid.Column="2"
|
||||||
Width="14"
|
Width="10"
|
||||||
Height="14"
|
Height="10"
|
||||||
Margin="0,2,2,0"
|
Margin="0,2,2,0"
|
||||||
HorizontalAlignment="Right"
|
HorizontalAlignment="Right"
|
||||||
VerticalAlignment="Top"
|
VerticalAlignment="Top"
|
||||||
@@ -111,6 +112,7 @@
|
|||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
<VisualStateManager.VisualStateGroups>
|
<VisualStateManager.VisualStateGroups>
|
||||||
|
<!-- TODO: Selection of items are disabled temporarily. -->
|
||||||
<VisualStateGroup x:Name="SelectionStates">
|
<VisualStateGroup x:Name="SelectionStates">
|
||||||
<VisualState x:Name="NonSelected" />
|
<VisualState x:Name="NonSelected" />
|
||||||
<VisualState x:Name="Selected">
|
<VisualState x:Name="Selected">
|
||||||
|
|||||||
@@ -1,19 +1,20 @@
|
|||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using CommunityToolkit.Mvvm.Messaging;
|
using CommunityToolkit.Mvvm.Messaging;
|
||||||
using CommunityToolkit.WinUI;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Itenso.TimePeriod;
|
|
||||||
using Microsoft.UI.Xaml;
|
using Microsoft.UI.Xaml;
|
||||||
using Microsoft.UI.Xaml.Controls;
|
using Microsoft.UI.Xaml.Controls;
|
||||||
using Microsoft.UI.Xaml.Input;
|
using Microsoft.UI.Xaml.Input;
|
||||||
using Microsoft.UI.Xaml.Media;
|
|
||||||
using Windows.ApplicationModel.DataTransfer;
|
using Windows.ApplicationModel.DataTransfer;
|
||||||
using Wino.Calendar.ViewModels.Data;
|
using Wino.Calendar.ViewModels.Data;
|
||||||
using Wino.Calendar.ViewModels.Messages;
|
using Wino.Calendar.ViewModels.Messages;
|
||||||
using Wino.Core.Domain;
|
using Wino.Core.Domain.Interfaces;
|
||||||
|
using Wino.Mail.WinUI;
|
||||||
namespace Wino.Calendar.Controls;
|
namespace Wino.Calendar.Controls;
|
||||||
|
|
||||||
public sealed partial class CalendarItemControl : UserControl
|
public sealed partial class CalendarItemControl : UserControl
|
||||||
{
|
{
|
||||||
|
private readonly ICalendarContextMenuItemService _contextMenuItemService;
|
||||||
|
|
||||||
// Single tap has a delay to report double taps properly.
|
// Single tap has a delay to report double taps properly.
|
||||||
private bool isSingleTap = false;
|
private bool isSingleTap = false;
|
||||||
|
|
||||||
@@ -44,6 +45,7 @@ public sealed partial class CalendarItemControl : UserControl
|
|||||||
|
|
||||||
public CalendarItemControl()
|
public CalendarItemControl()
|
||||||
{
|
{
|
||||||
|
_contextMenuItemService = WinoApplication.Current.Services.GetRequiredService<ICalendarContextMenuItemService>();
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -141,4 +143,33 @@ public sealed partial class CalendarItemControl : UserControl
|
|||||||
|
|
||||||
WeakReferenceMessenger.Default.Send(new CalendarItemRightTappedMessage(CalendarItem));
|
WeakReferenceMessenger.Default.Send(new CalendarItemRightTappedMessage(CalendarItem));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void CalendarItemCommandBarFlyout_Opening(object sender, object e)
|
||||||
|
{
|
||||||
|
if (sender is not CalendarItemCommandBarFlyout flyout)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flyout.Item = CalendarItem;
|
||||||
|
|
||||||
|
if (CalendarItem?.CalendarItem == null)
|
||||||
|
{
|
||||||
|
flyout.ClearMenuItems();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flyout.SetMenuItems(_contextMenuItemService.GetContextMenuItems(CalendarItem.CalendarItem));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CalendarItemCommandBarFlyout_Closed(object sender, object e)
|
||||||
|
{
|
||||||
|
if (sender is not CalendarItemCommandBarFlyout flyout)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
flyout.ClearMenuItems();
|
||||||
|
flyout.Item = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,7 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
|||||||
private CancellationTokenSource? _searchCancellationTokenSource;
|
private CancellationTokenSource? _searchCancellationTokenSource;
|
||||||
private long _calendarTypeSelectorChangedToken;
|
private long _calendarTypeSelectorChangedToken;
|
||||||
private bool _suppressSelectionResetOnPopupClose;
|
private bool _suppressSelectionResetOnPopupClose;
|
||||||
|
private bool _hasAttachedNavigationLifetimeEvents;
|
||||||
|
|
||||||
public ObservableCollection<TitleBarSearchSuggestion> SearchSuggestions { get; } = [];
|
public ObservableCollection<TitleBarSearchSuggestion> SearchSuggestions { get; } = [];
|
||||||
|
|
||||||
@@ -42,13 +43,6 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
|||||||
public CalendarPage()
|
public CalendarPage()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
_calendarTypeSelectorChangedToken = CalendarToolbar.RegisterSelectedTypeChanged(CalendarTypeSelectorSelectedTypeChanged);
|
|
||||||
CalendarToolbar.PreviousDateRequested += CalendarToolbarPreviousDateRequested;
|
|
||||||
CalendarToolbar.NextDateRequested += CalendarToolbarNextDateRequested;
|
|
||||||
ViewModel.PropertyChanged += ViewModelPropertyChanged;
|
|
||||||
CalendarShellClient.PropertyChanged += CalendarShellClientPropertyChanged;
|
|
||||||
CalendarShellClient.StatePersistenceService.StatePropertyChanged += CalendarStatePersistenceServiceChanged;
|
|
||||||
Unloaded += CalendarPageUnloaded;
|
|
||||||
RefreshCalendarToolbar();
|
RefreshCalendarToolbar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,6 +55,8 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
|||||||
protected override void OnNavigatedTo(NavigationEventArgs e)
|
protected override void OnNavigatedTo(NavigationEventArgs e)
|
||||||
{
|
{
|
||||||
base.OnNavigatedTo(e);
|
base.OnNavigatedTo(e);
|
||||||
|
Bindings.Update();
|
||||||
|
AttachNavigationLifetimeEvents();
|
||||||
RefreshCalendarToolbar();
|
RefreshCalendarToolbar();
|
||||||
|
|
||||||
if (e.NavigationMode == NavigationMode.Back && ViewModel.RestoreVisibleState())
|
if (e.NavigationMode == NavigationMode.Back && ViewModel.RestoreVisibleState())
|
||||||
@@ -79,6 +75,12 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
|||||||
WeakReferenceMessenger.Default.Send(new LoadCalendarMessage(request));
|
WeakReferenceMessenger.Default.Send(new LoadCalendarMessage(request));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void OnNavigatedFrom(NavigationEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnNavigatedFrom(e);
|
||||||
|
DetachNavigationLifetimeEvents();
|
||||||
|
}
|
||||||
|
|
||||||
public async Task OnTitleBarSearchTextChangedAsync()
|
public async Task OnTitleBarSearchTextChangedAsync()
|
||||||
{
|
{
|
||||||
_searchCancellationTokenSource?.Cancel();
|
_searchCancellationTokenSource?.Cancel();
|
||||||
@@ -272,9 +274,31 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CalendarPageUnloaded(object sender, RoutedEventArgs e)
|
private void AttachNavigationLifetimeEvents()
|
||||||
{
|
{
|
||||||
|
if (_hasAttachedNavigationLifetimeEvents)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
_calendarTypeSelectorChangedToken = CalendarToolbar.RegisterSelectedTypeChanged(CalendarTypeSelectorSelectedTypeChanged);
|
||||||
|
CalendarToolbar.PreviousDateRequested += CalendarToolbarPreviousDateRequested;
|
||||||
|
CalendarToolbar.NextDateRequested += CalendarToolbarNextDateRequested;
|
||||||
|
ViewModel.PropertyChanged += ViewModelPropertyChanged;
|
||||||
|
CalendarShellClient.PropertyChanged += CalendarShellClientPropertyChanged;
|
||||||
|
CalendarShellClient.StatePersistenceService.StatePropertyChanged += CalendarStatePersistenceServiceChanged;
|
||||||
|
_hasAttachedNavigationLifetimeEvents = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DetachNavigationLifetimeEvents()
|
||||||
|
{
|
||||||
|
if (!_hasAttachedNavigationLifetimeEvents)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
CloseQuickEventPopup(clearSelection: true);
|
CloseQuickEventPopup(clearSelection: true);
|
||||||
|
Bindings.StopTracking();
|
||||||
CalendarToolbar.UnregisterSelectedTypeChanged(_calendarTypeSelectorChangedToken);
|
CalendarToolbar.UnregisterSelectedTypeChanged(_calendarTypeSelectorChangedToken);
|
||||||
CalendarToolbar.PreviousDateRequested -= CalendarToolbarPreviousDateRequested;
|
CalendarToolbar.PreviousDateRequested -= CalendarToolbarPreviousDateRequested;
|
||||||
CalendarToolbar.NextDateRequested -= CalendarToolbarNextDateRequested;
|
CalendarToolbar.NextDateRequested -= CalendarToolbarNextDateRequested;
|
||||||
@@ -283,7 +307,8 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
|||||||
CalendarShellClient.StatePersistenceService.StatePropertyChanged -= CalendarStatePersistenceServiceChanged;
|
CalendarShellClient.StatePersistenceService.StatePropertyChanged -= CalendarStatePersistenceServiceChanged;
|
||||||
_searchCancellationTokenSource?.Cancel();
|
_searchCancellationTokenSource?.Cancel();
|
||||||
_searchCancellationTokenSource?.Dispose();
|
_searchCancellationTokenSource?.Dispose();
|
||||||
Unloaded -= CalendarPageUnloaded;
|
_searchCancellationTokenSource = null;
|
||||||
|
_hasAttachedNavigationLifetimeEvents = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void SaveQuickEventClicked(object sender, RoutedEventArgs e)
|
private async void SaveQuickEventClicked(object sender, RoutedEventArgs e)
|
||||||
|
|||||||
Reference in New Issue
Block a user