Bunch of interaction updates for the calendar item control.

This commit is contained in:
Burak Kaan Köse
2025-01-02 00:18:34 +01:00
parent 215dc6ea6d
commit 8a9265eb79
24 changed files with 333 additions and 102 deletions

View File

@@ -29,6 +29,8 @@ namespace Wino.Calendar.ViewModels
IRecipient<NavigateManageAccountsRequested>,
IRecipient<CalendarDisplayTypeChangedMessage>
{
public IPreferencesService PreferencesService { get; }
public IStatePersistanceService StatePersistenceService { get; }
public IAccountCalendarStateService AccountCalendarStateService { get; }
@@ -65,6 +67,9 @@ namespace Wino.Calendar.ViewModels
[ObservableProperty]
private int _selectedDateNavigationHeaderIndex;
public bool IsVerticalCalendar => StatePersistenceService.CalendarDisplayType == CalendarDisplayType.Month;
// For updating account calendars asynchronously.
@@ -93,6 +98,11 @@ namespace Wino.Calendar.ViewModels
StatePersistenceService.StatePropertyChanged += PrefefencesChanged;
}
private void SelectedCalendarItemsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
throw new NotImplementedException();
}
private void PrefefencesChanged(object sender, string e)
{
if (e == nameof(StatePersistenceService.CalendarDisplayType))

View File

@@ -12,6 +12,7 @@ using MoreLinq;
using Serilog;
using Wino.Calendar.ViewModels.Data;
using Wino.Calendar.ViewModels.Interfaces;
using Wino.Calendar.ViewModels.Messages;
using Wino.Core.Domain.Collections;
using Wino.Core.Domain.Entities.Calendar;
using Wino.Core.Domain.Enums;
@@ -26,7 +27,10 @@ namespace Wino.Calendar.ViewModels
{
public partial class CalendarPageViewModel : CalendarBaseViewModel,
IRecipient<LoadCalendarMessage>,
IRecipient<CalendarSettingsUpdatedMessage>
IRecipient<CalendarSettingsUpdatedMessage>,
IRecipient<CalendarItemTappedMessage>,
IRecipient<CalendarItemDoubleTappedMessage>,
IRecipient<CalendarItemRightTappedMessage>
{
#region Quick Event Creation
@@ -101,6 +105,7 @@ namespace Wino.Calendar.ViewModels
private const int maxDayRangeSize = 10;
private readonly ICalendarService _calendarService;
private readonly IKeyPressService _keyPressService;
private readonly IPreferencesService _preferencesService;
// Store latest rendered options.
@@ -116,6 +121,7 @@ namespace Wino.Calendar.ViewModels
public CalendarPageViewModel(IStatePersistanceService statePersistanceService,
ICalendarService calendarService,
IKeyPressService keyPressService,
IAccountCalendarStateService accountCalendarStateService,
IPreferencesService preferencesService)
{
@@ -123,6 +129,7 @@ namespace Wino.Calendar.ViewModels
AccountCalendarStateService = accountCalendarStateService;
_calendarService = calendarService;
_keyPressService = keyPressService;
_preferencesService = preferencesService;
AccountCalendarStateService.AccountCalendarSelectionStateChanged += UpdateAccountCalendarRequested;
@@ -179,7 +186,7 @@ namespace Wino.Calendar.ViewModels
var testCalendarItem = new CalendarItem
{
CalendarId = Guid.Parse("40aa0bf0-9ea7-40d8-b426-9c78281723c9"),
CalendarId = SelectedQuickEventAccountCalendar.Id,
StartDate = QuickEventStartTime,
DurationInSeconds = durationSeconds,
CreatedAt = DateTime.UtcNow,
@@ -522,10 +529,6 @@ namespace Wino.Calendar.ViewModels
{
base.OnCalendarItemAdded(calendarItem);
// test
var calendar = await _calendarService.GetAccountCalendarAsync(Guid.Parse("40aa0bf0-9ea7-40d8-b426-9c78281723c9"));
calendarItem.AssignedCalendar = calendar;
// Check if event falls into the current date range.
var loadedDateRange = GetLoadedDateRange();
@@ -733,5 +736,72 @@ namespace Wino.Calendar.ViewModels
// Messenger.Send(new LoadCalendarMessage(DateTime.UtcNow.Date, CalendarInitInitiative.App, true));
}
private IEnumerable<CalendarItemViewModel> GetCalendarItems(Guid calendarItemId)
{
// Multi-day events are sprated in multiple days.
// We need to find the day that the event is in, and then select the event.
return DayRanges
.SelectMany(a => a.CalendarDays)
.Select(b => b.EventsCollection.GetCalendarItem(calendarItemId))
.Where(c => c != null)
.Cast<CalendarItemViewModel>()
.Distinct();
}
private void ResetSelectedItems()
{
foreach (var item in AccountCalendarStateService.SelectedItems)
{
var items = GetCalendarItems(item.Id);
foreach (var childItem in items)
{
childItem.IsSelected = false;
}
}
AccountCalendarStateService.SelectedItems.Clear();
}
public async void Receive(CalendarItemTappedMessage message)
{
if (message.CalendarItemViewModel == null) return;
await ExecuteUIThread(() =>
{
var calendarItems = GetCalendarItems(message.CalendarItemViewModel.Id);
if (!_keyPressService.IsCtrlKeyPressed())
{
ResetSelectedItems();
}
foreach (var item in calendarItems)
{
item.IsSelected = !item.IsSelected;
// Multi-select logic.
if (item.IsSelected && !AccountCalendarStateService.SelectedItems.Contains(item))
{
AccountCalendarStateService.SelectedItems.Add(message.CalendarItemViewModel);
}
else if (!item.IsSelected && AccountCalendarStateService.SelectedItems.Contains(item))
{
AccountCalendarStateService.SelectedItems.Remove(item);
}
}
});
}
public void Receive(CalendarItemDoubleTappedMessage message)
{
// TODO: Navigate to the event details page.
}
public void Receive(CalendarItemRightTappedMessage message)
{
}
}
}

View File

@@ -28,6 +28,11 @@ namespace Wino.Calendar.ViewModels.Data
public bool IsMultiDayEvent => ((ICalendarItem)CalendarItem).IsMultiDayEvent;
public bool IsRecurringEvent => !string.IsNullOrEmpty(CalendarItem.Recurrence);
[ObservableProperty]
private bool _isSelected;
public CalendarItemViewModel(CalendarItem calendarItem)
{
CalendarItem = calendarItem;

View File

@@ -1,13 +1,14 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain.Entities.Shared;
namespace Wino.Calendar.ViewModels.Interfaces
{
public interface IAccountCalendarStateService
public interface IAccountCalendarStateService : INotifyPropertyChanged
{
ReadOnlyObservableCollection<GroupedAccountCalendarViewModel> GroupedAccountCalendars { get; }
@@ -21,6 +22,9 @@ namespace Wino.Calendar.ViewModels.Interfaces
public void AddAccountCalendar(AccountCalendarViewModel accountCalendar);
public void RemoveAccountCalendar(AccountCalendarViewModel accountCalendar);
ObservableCollection<CalendarItemViewModel> SelectedItems { get; }
bool HasMultipleSelectedItems { get; }
/// <summary>
/// Enumeration of currently selected calendars.
/// </summary>

View File

@@ -0,0 +1,14 @@
using Wino.Calendar.ViewModels.Data;
namespace Wino.Calendar.ViewModels.Messages
{
public class CalendarItemDoubleTappedMessage
{
public CalendarItemDoubleTappedMessage(CalendarItemViewModel calendarItemViewModel)
{
CalendarItemViewModel = calendarItemViewModel;
}
public CalendarItemViewModel CalendarItemViewModel { get; }
}
}

View File

@@ -0,0 +1,14 @@
using Wino.Calendar.ViewModels.Data;
namespace Wino.Calendar.ViewModels.Messages
{
public class CalendarItemRightTappedMessage
{
public CalendarItemRightTappedMessage(CalendarItemViewModel calendarItemViewModel)
{
CalendarItemViewModel = calendarItemViewModel;
}
public CalendarItemViewModel CalendarItemViewModel { get; }
}
}

View File

@@ -0,0 +1,14 @@
using Wino.Calendar.ViewModels.Data;
namespace Wino.Calendar.ViewModels.Messages
{
public class CalendarItemTappedMessage
{
public CalendarItemTappedMessage(CalendarItemViewModel calendarItemViewModel)
{
CalendarItemViewModel = calendarItemViewModel;
}
public CalendarItemViewModel CalendarItemViewModel { get; }
}
}

View File

@@ -2,6 +2,7 @@
x:Class="Wino.Calendar.Controls.AllDayItemsControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:calendarHelpers="using:Wino.Calendar.Helpers"
xmlns:controls="using:Wino.Calendar.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:data="using:Wino.Calendar.ViewModels.Data"
@@ -15,7 +16,7 @@
<Grid>
<controls:CalendarItemControl
x:Name="SingleAllDayEventHolder"
CalendarItem="{x:Bind helpers:XamlHelpers.GetFirstAllDayEvent(EventCollection), Mode=OneWay}"
CalendarItem="{x:Bind calendarHelpers:CalendarXamlHelpers.GetFirstAllDayEvent(EventCollection), Mode=OneWay}"
Visibility="{x:Bind helpers:XamlHelpers.CountToVisibilityConverter(EventCollection.AllDayEvents.Count), Mode=OneWay}" />
<Button

View File

@@ -15,10 +15,23 @@
<Grid
x:Name="MainGrid"
BorderBrush="{ThemeResource CalendarSeperatorBrush}"
BorderThickness="1"
CornerRadius="6">
CornerRadius="4"
DoubleTapped="ControlDoubleTapped"
RightTapped="ControlRightTapped"
Tapped="ControlTapped">
<Grid.ContextFlyout>
<MenuFlyout Opened="ContextFlyoutOpened">
<MenuFlyoutItem Text="as" />
<MenuFlyoutItem Text="as" />
<MenuFlyoutItem Text="as" />
</MenuFlyout>
</Grid.ContextFlyout>
<Grid x:Name="MainBackground" Background="{x:Bind helpers:XamlHelpers.GetSolidColorBrushFromHex(CalendarItem.AssignedCalendar.BackgroundColorHex), Mode=OneWay}" />
<Rectangle
x:Name="MainBorder"
Stroke="{ThemeResource CalendarItemBorderBrush}"
StrokeThickness="0" />
<TextBlock
x:Name="EventTitleTextblock"
Margin="2,0"
@@ -26,12 +39,35 @@
VerticalAlignment="Center"
CharacterSpacing="8"
FontSize="13"
FontWeight="SemiBold"
Foreground="{x:Bind helpers:XamlHelpers.GetReadableTextColor(CalendarItem.AssignedCalendar.BackgroundColorHex), Mode=OneWay}"
Text="{x:Bind CalendarItem.Title}"
TextWrapping="Wrap" />
<!-- TODO: Event attributes -->
<StackPanel
HorizontalAlignment="Right"
VerticalAlignment="Top"
Orientation="Horizontal">
<PathIcon
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1 M 7.5 3.75 C 6.634114 3.75 5.82194 3.912762 5.063477 4.238281 C 4.305013 4.563803 3.642578 5.009766 3.076172 5.576172 C 2.509766 6.142578 2.063802 6.805014 1.738281 7.563477 C 1.41276 8.32194 1.25 9.134115 1.25 10 C 1.25 10.527344 1.318359 11.056315 1.455078 11.586914 C 1.591797 12.117514 1.79362 12.613933 2.060547 13.076172 C 2.099609 13.147787 2.150065 13.225912 2.211914 13.310547 C 2.273763 13.395183 2.333984 13.483073 2.392578 13.574219 C 2.451172 13.665365 2.501627 13.756511 2.543945 13.847656 C 2.586263 13.938803 2.607422 14.023438 2.607422 14.101562 C 2.607422 14.270834 2.545573 14.417318 2.421875 14.541016 C 2.298177 14.664714 2.151693 14.726562 1.982422 14.726562 C 1.871745 14.726562 1.778971 14.703776 1.704102 14.658203 C 1.629232 14.612631 1.55599 14.550781 1.484375 14.472656 C 1.24349 14.192709 1.030273 13.870443 0.844727 13.505859 C 0.65918 13.141276 0.504557 12.760417 0.380859 12.363281 C 0.257161 11.966146 0.16276 11.564128 0.097656 11.157227 C 0.032552 10.750326 0 10.364584 0 10 C 0 9.316406 0.089518 8.6556 0.268555 8.017578 C 0.447591 7.379558 0.69987 6.782227 1.025391 6.225586 C 1.350911 5.668945 1.741536 5.162761 2.197266 4.707031 C 2.652995 4.251303 3.157552 3.859051 3.710938 3.530273 C 4.264323 3.201498 4.861653 2.947592 5.50293 2.768555 C 6.144206 2.58952 6.809896 2.5 7.5 2.5 L 14.121094 2.5 L 12.685547 1.064453 C 12.561849 0.940756 12.5 0.794271 12.5 0.625 C 12.5 0.45573 12.561849 0.309246 12.685547 0.185547 C 12.809244 0.06185 12.955729 0 13.125 0 C 13.294271 0 13.440755 0.06185 13.564453 0.185547 L 16.064453 2.685547 C 16.18815 2.809246 16.25 2.95573 16.25 3.125 C 16.25 3.294271 16.18815 3.440756 16.064453 3.564453 L 13.564453 6.064453 C 13.440755 6.188151 13.294271 6.25 13.125 6.25 C 12.955729 6.25 12.809244 6.188151 12.685547 6.064453 C 12.561849 5.940756 12.5 5.794271 12.5 5.625 C 12.5 5.455729 12.561849 5.309245 12.685547 5.185547 L 14.121094 3.75 Z M 20 10 C 20 10.690104 19.91048 11.352539 19.731445 11.987305 C 19.552408 12.62207 19.300129 13.217773 18.974609 13.774414 C 18.649088 14.331055 18.258463 14.83724 17.802734 15.292969 C 17.347004 15.748698 16.842447 16.140951 16.289062 16.469727 C 15.735677 16.798502 15.138346 17.052408 14.49707 17.231445 C 13.855793 17.410482 13.190104 17.5 12.5 17.5 L 5.888672 17.5 L 7.314453 18.935547 C 7.43815 19.059244 7.5 19.205729 7.5 19.375 C 7.5 19.544271 7.43815 19.690756 7.314453 19.814453 C 7.190755 19.93815 7.044271 20 6.875 20 C 6.705729 20 6.559244 19.93815 6.435547 19.814453 L 3.935547 17.314453 C 3.811849 17.190756 3.75 17.044271 3.75 16.875 C 3.75 16.705729 3.811849 16.559244 3.935547 16.435547 L 6.435547 13.935547 C 6.559244 13.81185 6.705729 13.75 6.875 13.75 C 7.044271 13.75 7.190755 13.81185 7.314453 13.935547 C 7.43815 14.059245 7.5 14.205729 7.5 14.375 C 7.5 14.544271 7.43815 14.690756 7.314453 14.814453 L 5.888672 16.25 L 12.5 16.25 C 13.365885 16.25 14.178059 16.08724 14.936523 15.761719 C 15.694986 15.436198 16.357422 14.990234 16.923828 14.423828 C 17.490234 13.857422 17.936197 13.194987 18.261719 12.436523 C 18.587238 11.678061 18.75 10.865886 18.75 10 C 18.75 9.628906 18.723957 9.283854 18.671875 8.964844 C 18.619791 8.645834 18.541666 8.336589 18.4375 8.037109 C 18.333332 7.737631 18.204752 7.444662 18.051758 7.158203 C 17.898762 6.871746 17.721354 6.575521 17.519531 6.269531 C 17.473957 6.197917 17.441406 6.139323 17.421875 6.09375 C 17.402344 6.048178 17.392578 5.983074 17.392578 5.898438 C 17.392578 5.729168 17.452799 5.581056 17.573242 5.454102 C 17.693684 5.327149 17.841797 5.263673 18.017578 5.263672 C 18.128254 5.263673 18.221027 5.286459 18.295898 5.332031 C 18.370768 5.377604 18.44401 5.439453 18.515625 5.517578 C 18.75651 5.797527 18.969727 6.119793 19.155273 6.484375 C 19.34082 6.848959 19.495441 7.231445 19.619141 7.631836 C 19.742838 8.032227 19.837238 8.435873 19.902344 8.842773 C 19.967447 9.249675 20 9.635417 20 10 Z "
Visibility="{x:Bind CalendarItem.IsRecurringEvent}" />
</StackPanel>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="SelectionStates">
<VisualState x:Name="NonSelected" />
<VisualState x:Name="Selected">
<VisualState.Setters>
<Setter Target="MainBorder.StrokeThickness" Value="2" />
<Setter Target="MainBorder.Stroke" Value="{ThemeResource CalendarItemSelectedBorderBrush}" />
</VisualState.Setters>
<VisualState.StateTriggers>
<StateTrigger IsActive="{x:Bind CalendarItem.IsSelected, Mode=OneWay, FallbackValue=False}" />
</VisualState.StateTriggers>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="DraggingStates">
<VisualState x:Name="NotDragging" />
<VisualState x:Name="Dragging">
@@ -39,8 +75,10 @@
<StateTrigger IsActive="{x:Bind IsDragging, Mode=OneWay}" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="MainGrid.BorderThickness" Value="3" />
<Setter Target="MainGrid.BorderBrush" Value="Red" />
<Setter Target="MainBorder.StrokeThickness" Value="2" />
<Setter Target="MainBorder.Stroke" Value="{ThemeResource CalendarItemDraggingBorderBrush}" />
<Setter Target="MainBorder.StrokeDashArray" Value="2.5" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
@@ -57,7 +95,7 @@
<VisualState.Setters>
<Setter Target="MainBackground.Opacity" Value="0.6" />
<Setter Target="MainGrid.CornerRadius" Value="0" />
<Setter Target="MainGrid.BorderThickness" Value="0.5" />
<Setter Target="MainBorder.StrokeThickness" Value="0.5" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>

View File

@@ -1,16 +1,17 @@
using Windows.UI.Xaml;
using CommunityToolkit.Mvvm.Messaging;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain.Interfaces;
using Wino.Calendar.ViewModels.Messages;
namespace Wino.Calendar.Controls
{
public sealed partial class CalendarItemControl : UserControl
{
public static readonly DependencyProperty CalendarItemProperty = DependencyProperty.Register(nameof(CalendarItem), typeof(ICalendarItem), typeof(CalendarItemControl), new PropertyMetadata(null, new PropertyChangedCallback(OnCalendarItemChanged)));
public static readonly DependencyProperty CalendarItemProperty = DependencyProperty.Register(nameof(CalendarItem), typeof(CalendarItemViewModel), typeof(CalendarItemControl), new PropertyMetadata(null, new PropertyChangedCallback(OnCalendarItemChanged)));
public static readonly DependencyProperty IsDraggingProperty = DependencyProperty.Register(nameof(IsDragging), typeof(bool), typeof(CalendarItemControl), new PropertyMetadata(false));
public ICalendarItem CalendarItem
public CalendarItemViewModel CalendarItem
{
get { return (CalendarItemViewModel)GetValue(CalendarItemProperty); }
set { SetValue(CalendarItemProperty, value); }
@@ -56,5 +57,36 @@ namespace Wino.Calendar.Controls
private void ControlDragStarting(UIElement sender, DragStartingEventArgs args) => IsDragging = true;
private void ControlDropped(UIElement sender, DropCompletedEventArgs args) => IsDragging = false;
private void ControlTapped(object sender, Windows.UI.Xaml.Input.TappedRoutedEventArgs e)
{
if (CalendarItem == null) return;
WeakReferenceMessenger.Default.Send(new CalendarItemTappedMessage(CalendarItem));
}
private void ControlDoubleTapped(object sender, Windows.UI.Xaml.Input.DoubleTappedRoutedEventArgs e)
{
if (CalendarItem == null) return;
WeakReferenceMessenger.Default.Send(new CalendarItemDoubleTappedMessage(CalendarItem));
}
private void ControlRightTapped(object sender, Windows.UI.Xaml.Input.RightTappedRoutedEventArgs e)
{
if (CalendarItem == null) return;
WeakReferenceMessenger.Default.Send(new CalendarItemRightTappedMessage(CalendarItem));
}
private void ContextFlyoutOpened(object sender, object e)
{
if (CalendarItem == null) return;
if (!CalendarItem.IsSelected)
{
WeakReferenceMessenger.Default.Send(new CalendarItemTappedMessage(CalendarItem));
}
}
}
}

View File

@@ -1,9 +1,12 @@
using System;
using System.Collections.ObjectModel;
using System.Linq;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Wino.Calendar.Args;
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain.Models.Calendar;
using Wino.Helpers;
namespace Wino.Calendar.Controls
{
@@ -176,5 +179,12 @@ namespace Wino.Calendar.Controls
InternalFlipView.GoPreviousFlip();
}
public CalendarItemControl GetCalendarItemControl(CalendarItemViewModel calendarItemViewModel)
{
if (ActiveCanvas == null) return null;
return this.FindDescendants<CalendarItemControl>().FirstOrDefault(a => a.CalendarItem == calendarItemViewModel);
}
}
}

View File

@@ -76,6 +76,7 @@ namespace Wino.Calendar.Controls
Canvas = GetTemplateChild(PART_InternalCanvas) as CanvasControl;
// TODO: These will leak. Dispose them properly when needed.
Canvas.Draw += OnCanvasDraw;
Canvas.PointerPressed += OnCanvasPointerPressed;

View File

@@ -0,0 +1,12 @@
using System.Linq;
using Wino.Calendar.ViewModels.Data;
using Wino.Core.Domain.Collections;
namespace Wino.Calendar.Helpers
{
public static class CalendarXamlHelpers
{
public static CalendarItemViewModel GetFirstAllDayEvent(CalendarEventCollection collection)
=> (CalendarItemViewModel)collection.AllDayEvents.FirstOrDefault();
}
}

View File

@@ -18,6 +18,11 @@ namespace Wino.Calendar.Services
public event EventHandler<GroupedAccountCalendarViewModel> CollectiveAccountGroupSelectionStateChanged;
public event EventHandler<AccountCalendarViewModel> AccountCalendarSelectionStateChanged;
[ObservableProperty]
public ObservableCollection<CalendarItemViewModel> _selectedItems = new ObservableCollection<CalendarItemViewModel>();
public bool HasMultipleSelectedItems => SelectedItems.Count > 1;
[ObservableProperty]
private ReadOnlyObservableCollection<GroupedAccountCalendarViewModel> groupedAccountCalendars;
@@ -47,6 +52,13 @@ namespace Wino.Calendar.Services
public AccountCalendarStateService()
{
GroupedAccountCalendars = new ReadOnlyObservableCollection<GroupedAccountCalendarViewModel>(_internalGroupedAccountCalendars);
SelectedItems.CollectionChanged += SelectedCalendarItemsUpdated;
}
private void SelectedCalendarItemsUpdated(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
OnPropertyChanged(nameof(HasMultipleSelectedItems));
}
private void SingleGroupCalendarCollectiveStateChanged(object sender, EventArgs e)

View File

@@ -5,26 +5,35 @@
<ResourceDictionary.ThemeDictionaries>
<ResourceDictionary x:Key="Light">
<!-- CalendarControl -->
<SolidColorBrush x:Key="CalendarSeperatorBrush">#D9D9D9</SolidColorBrush>
<SolidColorBrush x:Key="CalendarFieldWorkingHoursBackgroundBrush">#32000000</SolidColorBrush>
<SolidColorBrush x:Key="CalendarFieldSelectedBackgroundBrush">#ebebeb</SolidColorBrush>
<SolidColorBrush x:Key="CalendarSeperatorBrush">#b2bec3</SolidColorBrush>
<SolidColorBrush x:Key="CalendarFieldWorkingHoursBackgroundBrush">#dfe4ea</SolidColorBrush>
<SolidColorBrush x:Key="CalendarFieldSelectedBackgroundBrush">#2e86de</SolidColorBrush>
<!-- CalendarView -->
<SolidColorBrush x:Key="WinoCalendarViewBorderBrush">#2e86de</SolidColorBrush>
<SolidColorBrush x:Key="WinoCalendarViewVisibleDayBackgroundBrush">#dfe4ea</SolidColorBrush>
<!-- Calendar Item Control -->
<SolidColorBrush x:Key="CalendarItemBorderBrush">#000000</SolidColorBrush>
<SolidColorBrush x:Key="CalendarItemSelectedBorderBrush">#000000</SolidColorBrush>
<SolidColorBrush x:Key="CalendarItemDraggingBorderBrush">#000000</SolidColorBrush>
</ResourceDictionary>
<ResourceDictionary x:Key="Dark">
<!-- CalendarControl -->
<SolidColorBrush x:Key="CalendarSeperatorBrush">#525252</SolidColorBrush>
<SolidColorBrush x:Key="CalendarFieldWorkingHoursBackgroundBrush">#32262626</SolidColorBrush>
<SolidColorBrush x:Key="CalendarFieldWorkingHoursBackgroundBrush">#262626</SolidColorBrush>
<SolidColorBrush x:Key="CalendarFieldSelectedBackgroundBrush">#121212</SolidColorBrush>
<!-- CalendarView -->
<SolidColorBrush x:Key="WinoCalendarViewBorderBrush">#3d3d3d</SolidColorBrush>
<SolidColorBrush x:Key="WinoCalendarViewVisibleDayBackgroundBrush">#4b4b4b</SolidColorBrush>
<!-- Calendar Item Control -->
<SolidColorBrush x:Key="CalendarItemBorderBrush">#000000</SolidColorBrush>
<SolidColorBrush x:Key="CalendarItemSelectedBorderBrush">#FFFFFF</SolidColorBrush>
<SolidColorBrush x:Key="CalendarItemDraggingBorderBrush">#000000</SolidColorBrush>
</ResourceDictionary>
</ResourceDictionary.ThemeDictionaries>
</ResourceDictionary>

View File

@@ -92,6 +92,8 @@
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<!-- Rendering left hour headers. -->
<ItemsControl ItemTemplate="{StaticResource DayCalendarHourHeaderTemplate}" ItemsSource="{x:Bind DayHeaders}" />

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -3,6 +3,7 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:abstract="using:Wino.Calendar.Views.Abstract"
xmlns:animations="using:CommunityToolkit.WinUI.Animations"
xmlns:calendarControls="using:Wino.Calendar.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:data="using:Wino.Calendar.ViewModels.Data"
@@ -15,12 +16,6 @@
mc:Ignorable="d">
<Page.Resources>
<!-- Teaching tip dialog sizing. -->
<x:Double x:Key="TeachingTipMinHeight">600</x:Double>
<x:Double x:Key="TeachingTipMaxHeight">600</x:Double>
<x:Double x:Key="TeachingTipMinWidth">600</x:Double>
<x:Double x:Key="TeachingTipMaxWidth">600</x:Double>
<CollectionViewSource
x:Key="GroupedCalendarEnumerableViewSource"
IsSourceGrouped="True"
@@ -28,11 +23,12 @@
</Page.Resources>
<Border
Margin="0,0,7,7"
Margin="4,0,7,7"
BorderBrush="{StaticResource CardStrokeColorDefaultBrush}"
BorderThickness="1"
CornerRadius="7">
<Grid>
<!-- Calendar control -->
<calendarControls:WinoCalendarControl
x:Name="CalendarControl"
DayRanges="{x:Bind ViewModel.DayRanges}"
@@ -42,6 +38,7 @@
TimelineCellSelected="CellSelected"
TimelineCellUnselected="CellUnselected" />
<!-- Popup canvas -->
<Canvas x:Name="CalendarOverlayCanvas" IsHitTestVisible="False">
<!-- Invisible target UI element for teaching tip display. -->
<Grid
@@ -50,13 +47,14 @@
IsHitTestVisible="False"
Visibility="Visible" />
<!-- Single popup to display create event dialog. -->
<!-- Popup to display create event dialog. -->
<Popup
x:Name="QuickEventPopupDialog"
ActualPlacementChanged="QuickEventPopupPlacementChanged"
ActualPlacementChanged="PopupPlacementChanged"
Closed="QuickEventPopupClosed"
DesiredPlacement="{x:Bind helpers:XamlHelpers.GetPlaccementModeForCalendarType(ViewModel.StatePersistanceService.CalendarDisplayType), Mode=OneWay}"
HorizontalOffset="16"
IsLightDismissEnabled="True"
IsOpen="{x:Bind ViewModel.IsQuickEventDialogOpen, Mode=TwoWay}"
PlacementTarget="{x:Bind TeachingTipPositionerGrid}"
VerticalOffset="16">
@@ -207,18 +205,20 @@
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<PathIcon
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="F1 M 7.900391 17.5 C 8.011067 17.721354 8.129883 17.936197 8.256836 18.144531 C 8.383789 18.352865 8.522135 18.554688 8.671875 18.75 L 4.921875 18.75 C 4.433594 18.75 3.966471 18.650717 3.520508 18.452148 C 3.074544 18.25358 2.683919 17.986654 2.348633 17.651367 C 2.013346 17.31608 1.746419 16.925455 1.547852 16.479492 C 1.349284 16.033529 1.25 15.566406 1.25 15.078125 L 1.25 4.921875 C 1.25 4.433594 1.349284 3.966473 1.547852 3.520508 C 1.746419 3.074545 2.013346 2.68392 2.348633 2.348633 C 2.683919 2.013348 3.074544 1.74642 3.520508 1.547852 C 3.966471 1.349285 4.433594 1.25 4.921875 1.25 L 15.078125 1.25 C 15.566406 1.25 16.033527 1.349285 16.479492 1.547852 C 16.925455 1.74642 17.31608 2.013348 17.651367 2.348633 C 17.986652 2.68392 18.25358 3.074545 18.452148 3.520508 C 18.650715 3.966473 18.75 4.433594 18.75 4.921875 L 18.75 8.671875 C 18.554688 8.522136 18.352863 8.383789 18.144531 8.256836 C 17.936197 8.129883 17.721354 8.011068 17.5 7.900391 L 17.5 6.25 L 2.5 6.25 L 2.5 15.048828 C 2.5 15.38737 2.568359 15.704753 2.705078 16.000977 C 2.841797 16.297201 3.024088 16.55599 3.251953 16.777344 C 3.479818 16.998697 3.745117 17.174479 4.047852 17.304688 C 4.350586 17.434896 4.667969 17.5 5 17.5 Z M 4.951172 2.5 C 4.619141 2.5 4.303385 2.568359 4.003906 2.705078 C 3.704427 2.841797 3.44401 3.02409 3.222656 3.251953 C 3.001302 3.479818 2.825521 3.745117 2.695312 4.047852 C 2.565104 4.350587 2.5 4.66797 2.5 5 L 17.5 5 L 17.5 4.951172 C 17.5 4.625651 17.433268 4.314779 17.299805 4.018555 C 17.16634 3.722332 16.987305 3.461914 16.762695 3.237305 C 16.538086 3.012695 16.277668 2.83366 15.981445 2.700195 C 15.685221 2.566732 15.374349 2.5 15.048828 2.5 Z M 20 14.375 C 20 15.14974 19.851887 15.878906 19.555664 16.5625 C 19.259439 17.246094 18.857422 17.841797 18.349609 18.349609 C 17.841797 18.857422 17.246094 19.259439 16.5625 19.555664 C 15.878906 19.851889 15.149739 20 14.375 20 C 13.59375 20 12.861328 19.853516 12.177734 19.560547 C 11.494141 19.267578 10.898438 18.867188 10.390625 18.359375 C 9.882812 17.851562 9.482422 17.255859 9.189453 16.572266 C 8.896484 15.888672 8.75 15.15625 8.75 14.375 C 8.75 13.600261 8.898111 12.871094 9.194336 12.1875 C 9.49056 11.503906 9.892578 10.908203 10.400391 10.400391 C 10.908203 9.892578 11.503906 9.490561 12.1875 9.194336 C 12.871093 8.898112 13.60026 8.75 14.375 8.75 C 14.889322 8.75 15.385741 8.816732 15.864258 8.950195 C 16.342773 9.083659 16.790363 9.272461 17.207031 9.516602 C 17.623697 9.760742 18.004557 10.055339 18.349609 10.400391 C 18.69466 10.745443 18.989258 11.126303 19.233398 11.542969 C 19.477539 11.959636 19.66634 12.407227 19.799805 12.885742 C 19.933268 13.364258 20 13.860678 20 14.375 Z M 16.25 15 C 16.41927 15 16.565754 14.938151 16.689453 14.814453 C 16.81315 14.690756 16.875 14.544271 16.875 14.375 C 16.875 14.205729 16.81315 14.059245 16.689453 13.935547 C 16.565754 13.81185 16.41927 13.75 16.25 13.75 L 15 13.75 L 15 11.875 C 14.999999 11.705729 14.93815 11.559245 14.814453 11.435547 C 14.690755 11.31185 14.544271 11.25 14.375 11.25 C 14.205729 11.25 14.059244 11.31185 13.935547 11.435547 C 13.811849 11.559245 13.75 11.705729 13.75 11.875 L 13.75 14.375 C 13.75 14.544271 13.811849 14.690756 13.935547 14.814453 C 14.059244 14.938151 14.205729 15 14.375 15 Z " />
<ComboBox
Grid.Column="1"
HorizontalAlignment="Stretch"
TextSubmitted="ComboBox_TextSubmitted"
IsEditable="True"
IsEnabled="{x:Bind helpers:XamlHelpers.ReverseBoolConverter(ViewModel.IsAllDay), Mode=OneWay}"
ItemsSource="{x:Bind ViewModel.HourSelectionStrings, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.SelectedStartTimeString, Mode=TwoWay}" />
SelectedItem="{x:Bind ViewModel.SelectedStartTimeString, Mode=TwoWay}"
TextSubmitted="StartTimeDurationSubmitted" />
<TextBlock
Grid.Column="2"
@@ -231,7 +231,8 @@
IsEditable="True"
IsEnabled="{x:Bind helpers:XamlHelpers.ReverseBoolConverter(ViewModel.IsAllDay), Mode=OneWay}"
ItemsSource="{x:Bind ViewModel.HourSelectionStrings, Mode=OneWay}"
SelectedItem="{x:Bind ViewModel.SelectedEndTimeString, Mode=TwoWay}" />
SelectedItem="{x:Bind ViewModel.SelectedEndTimeString, Mode=TwoWay}"
TextSubmitted="EndTimeDurationSubmitted" />
</Grid>
<!-- Location -->
@@ -281,26 +282,8 @@
Style="{ThemeResource AccentButtonStyle}" />
</Grid>
</Grid>
<!-- Create events dialog -->
<!--<Button
x:Name="AddEvent"
Grid.Row="1"
Click="AddEventClicked"
Content="Add Event" />-->
</Grid>
</Popup>
<!--<muxc:TeachingTip
x:Name="NewEventTip"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Target="{x:Bind TeachingTipPositionerGrid}">
</muxc:TeachingTip>-->
</Canvas>
</Grid>
</Border>

View File

@@ -1,8 +1,10 @@
using System;
using CommunityToolkit.Mvvm.Messaging;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Navigation;
using Wino.Calendar.Args;
using Wino.Calendar.ViewModels.Messages;
using Wino.Calendar.Views.Abstract;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Models.Calendar;
@@ -13,7 +15,8 @@ namespace Wino.Calendar.Views
public sealed partial class CalendarPage : CalendarPageAbstract,
IRecipient<ScrollToDateMessage>,
IRecipient<GoNextDateRequestedMessage>,
IRecipient<GoPreviousDateRequestedMessage>
IRecipient<GoPreviousDateRequestedMessage>,
IRecipient<CalendarItemRightTappedMessage>
{
private const int PopupDialogOffset = 12;
@@ -83,34 +86,44 @@ namespace Wino.Calendar.Views
CalendarControl.ResetTimelineSelection();
}
private void QuickEventPopupPlacementChanged(object sender, object e)
private void PopupPlacementChanged(object sender, object e)
{
// When the quick event Popup is positioned for different calendar types,
// we must adjust the offset to make sure the tip is not hidden and has nice
// spacing from the cell.
switch (QuickEventPopupDialog.ActualPlacement)
if (sender is Popup senderPopup)
{
case Windows.UI.Xaml.Controls.Primitives.PopupPlacementMode.Top:
QuickEventPopupDialog.VerticalOffset = PopupDialogOffset * -1;
break;
case Windows.UI.Xaml.Controls.Primitives.PopupPlacementMode.Bottom:
QuickEventPopupDialog.VerticalOffset = PopupDialogOffset;
break;
case Windows.UI.Xaml.Controls.Primitives.PopupPlacementMode.Left:
QuickEventPopupDialog.HorizontalOffset = PopupDialogOffset * -1;
break;
case Windows.UI.Xaml.Controls.Primitives.PopupPlacementMode.Right:
QuickEventPopupDialog.HorizontalOffset = PopupDialogOffset;
break;
default:
break;
// When the quick event Popup is positioned for different calendar types,
// we must adjust the offset to make sure the tip is not hidden and has nice
// spacing from the cell.
switch (senderPopup.ActualPlacement)
{
case PopupPlacementMode.Top:
senderPopup.VerticalOffset = PopupDialogOffset * -1;
break;
case PopupPlacementMode.Bottom:
senderPopup.VerticalOffset = PopupDialogOffset;
break;
case PopupPlacementMode.Left:
senderPopup.HorizontalOffset = PopupDialogOffset * -1;
break;
case PopupPlacementMode.Right:
senderPopup.HorizontalOffset = PopupDialogOffset;
break;
default:
break;
}
}
}
private void ComboBox_TextSubmitted(ComboBox sender, ComboBoxTextSubmittedEventArgs args)
public void Receive(CalendarItemRightTappedMessage message)
{
ViewModel.SelectedStartTimeString = args.Text;
}
private void StartTimeDurationSubmitted(ComboBox sender, ComboBoxTextSubmittedEventArgs args)
=> ViewModel.SelectedStartTimeString = args.Text;
private void EndTimeDurationSubmitted(ComboBox sender, ComboBoxTextSubmittedEventArgs args)
=> ViewModel.SelectedEndTimeString = args.Text;
}
}

View File

@@ -152,6 +152,7 @@
<Compile Include="Controls\WinoCalendarTypeSelectorControl.cs" />
<Compile Include="Controls\WinoCalendarView.cs" />
<Compile Include="Controls\WinoDayTimelineCanvas.cs" />
<Compile Include="Helpers\CalendarXamlHelpers.cs" />
<Compile Include="MainPage.xaml.cs">
<DependentUpon>MainPage.xaml</DependentUpon>
</Compile>

View File

@@ -35,6 +35,11 @@ namespace Wino.Core.Domain.Collections
public bool HasCalendarEvent(AccountCalendar accountCalendar)
=> _allItems.Any(x => x.AssignedCalendar.Id == accountCalendar.Id);
public ICalendarItem GetCalendarItem(Guid calendarItemId)
{
return _allItems.FirstOrDefault(x => x.Id == calendarItemId);
}
public void FilterByCalendars(IEnumerable<Guid> visibleCalendarIds)
{
foreach (var item in _allItems)

View File

@@ -43,8 +43,6 @@ namespace Wino.Core.UWP.Controls
set { SetValue(CoreWindowTextProperty, value); }
}
public bool IsDragArea
{
get { return (bool)GetValue(IsDragAreaProperty); }
@@ -52,9 +50,6 @@ namespace Wino.Core.UWP.Controls
}
public double SystemReserved
{
get { return (double)GetValue(SystemReservedProperty); }
@@ -109,9 +104,6 @@ namespace Wino.Core.UWP.Controls
set { SetValue(IsRenderingPaneVisibleProperty, value); }
}
public double ReadingPaneLength
{
get { return (double)GetValue(ReadingPaneLengthProperty); }

View File

@@ -11,9 +11,7 @@ using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Markup;
using Windows.UI.Xaml.Media;
using Wino.Core.Domain;
using Wino.Core.Domain.Collections;
using Wino.Core.Domain.Enums;
using Wino.Core.Domain.Interfaces;
using Wino.Core.Domain.Models.MailItem;
using Wino.Core.UWP.Controls;
@@ -36,8 +34,7 @@ namespace Wino.Helpers
_ => PopupPlacementMode.Bottom,
};
}
public static ICalendarItem GetFirstAllDayEvent(CalendarEventCollection collection)
=> collection.AllDayEvents.FirstOrDefault();
public static Visibility ReverseBoolToVisibilityConverter(bool value) => value ? Visibility.Collapsed : Visibility.Visible;
public static Visibility ReverseVisibilityConverter(Visibility visibility) => visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;