Calendar improvements cycle 2
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#ecf0f1</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#B2FCFCFC</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#D9ECEFF1</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#4D0078D4</SolidColorBrush>
|
||||
|
||||
<local:AcrylicBrush
|
||||
x:Key="WinoApplicationBackgroundColor"
|
||||
@@ -27,6 +28,7 @@
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#2C2C2C</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#662C2C2C</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#992C2C2C</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#66399BFF</SolidColorBrush>
|
||||
|
||||
<local:AcrylicBrush
|
||||
x:Key="WinoApplicationBackgroundColor"
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b2dffc</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#33B2DFFC</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#66B2DFFC</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#4D0078D4</SolidColorBrush>
|
||||
|
||||
<SolidColorBrush x:Key="CalendarSeperatorBrush">#222f3e</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
@@ -21,6 +22,7 @@
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b2dffc</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#33B2DFFC</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#66B2DFFC</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#66399BFF</SolidColorBrush>
|
||||
|
||||
<SolidColorBrush x:Key="CalendarSeperatorBrush">#222f3e</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
<Color x:Key="MainCustomThemeColor">#D9FFFFFF</Color>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush" Color="{StaticResource MainCustomThemeColor}" Opacity="0.55" />
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush" Color="{StaticResource MainCustomThemeColor}" Opacity="0.85" />
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#4D0078D4</SolidColorBrush>
|
||||
|
||||
<SolidColorBrush x:Key="AppBarBackgroundColor" Color="{StaticResource MainCustomThemeColor}" />
|
||||
<SolidColorBrush x:Key="NavigationViewContentBackground" Color="Transparent" />
|
||||
@@ -37,6 +38,7 @@
|
||||
<Color x:Key="MainCustomThemeColor">#E61F1F1F</Color>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush" Color="{StaticResource MainCustomThemeColor}" Opacity="0.55" />
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush" Color="{StaticResource MainCustomThemeColor}" Opacity="0.85" />
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#66399BFF</SolidColorBrush>
|
||||
|
||||
<!-- Reading Pane Background -->
|
||||
<SolidColorBrush x:Key="ReadingPaneBackgroundColorBrush" Color="{StaticResource MainCustomThemeColor}" />
|
||||
|
||||
@@ -15,11 +15,13 @@
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#ecf0f1</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#F7F9FA</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#DFE4EA</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#4D0078D4</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Name="Dark">
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#1f1f1f</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#1F1F1F</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#262626</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#66399BFF</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -14,11 +14,13 @@
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#A800D608</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#2200D608</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#4D00D608</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#4D0078D4</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Name="Dark">
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#59001C01</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#22001C01</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#59001C01</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#66399BFF</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#dcfad8</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#26DCFAD8</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#59DCFAD8</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#4D0078D4</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSeperatorBrush">#576574</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -22,6 +23,7 @@
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#dcfad8</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#26576574</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#59576574</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#66399BFF</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#fdcb6e</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#33FDCB6E</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#66FDCB6E</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#4D0078D4</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Name="Dark">
|
||||
<!-- Brushes -->
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#5413191F</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#2213191F</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#5413191F</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#66399BFF</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -15,12 +15,14 @@
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b0c6dd</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#33B0C6DD</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#66B0C6DD</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#4D0078D4</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
<ResourceDictionary x:Name="Dark">
|
||||
<!-- Brushes -->
|
||||
<SolidColorBrush x:Key="MailListHeaderBackgroundColor">#b0c6dd</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarDefaultHourBackgroundBrush">#33B0C6DD</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarWorkHourBackgroundBrush">#66B0C6DD</SolidColorBrush>
|
||||
<SolidColorBrush x:Key="CalendarSelectedHourBackgroundBrush">#66399BFF</SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
</ResourceDictionary.ThemeDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
@@ -6,14 +6,14 @@ namespace Wino.Calendar.Controls;
|
||||
|
||||
public sealed class CalendarEmptySlotTappedEventArgs : EventArgs
|
||||
{
|
||||
public CalendarEmptySlotTappedEventArgs(DateTime clickedDate, Point positionerPoint, Size cellSize)
|
||||
public CalendarEmptySlotTappedEventArgs(DateTime clickedDate, Point anchorPoint, Size cellSize)
|
||||
{
|
||||
ClickedDate = clickedDate;
|
||||
PositionerPoint = positionerPoint;
|
||||
AnchorPoint = anchorPoint;
|
||||
CellSize = cellSize;
|
||||
}
|
||||
|
||||
public DateTime ClickedDate { get; }
|
||||
public Point PositionerPoint { get; }
|
||||
public Point AnchorPoint { get; }
|
||||
public Size CellSize { get; }
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:skia="using:SkiaSharp.Views.Windows"
|
||||
xmlns:viewModels="using:Wino.Calendar.ViewModels.Data"
|
||||
|
||||
x:Name="Root"
|
||||
SizeChanged="ControlSizeChanged"
|
||||
mc:Ignorable="d">
|
||||
@@ -22,10 +21,7 @@
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="MonthEventTemplate" x:DataType="viewModels:CalendarItemViewModel">
|
||||
<local:CalendarItemControl
|
||||
Margin="0,2,0,0"
|
||||
CalendarItem="{x:Bind}"
|
||||
IsCustomEventArea="True" />
|
||||
<local:CalendarItemControl CalendarItem="{x:Bind}" IsCustomEventArea="True" />
|
||||
</DataTemplate>
|
||||
|
||||
<DataTemplate x:Key="TimedHeaderTemplate" x:DataType="local:HeaderTextLayout">
|
||||
@@ -77,8 +73,8 @@
|
||||
x:Name="TimedHeaderHost"
|
||||
Grid.Row="0"
|
||||
Grid.ColumnSpan="2"
|
||||
Margin="64,0,0,0"
|
||||
Height="44"
|
||||
Margin="64,0,0,0"
|
||||
Background="{ThemeResource LayerFillColorDefaultBrush}">
|
||||
<skia:SKXamlCanvas x:Name="TimedHeaderCanvas" PaintSurface="TimedHeaderCanvasPaintSurface" />
|
||||
<ItemsControl
|
||||
@@ -159,7 +155,13 @@
|
||||
Background="Transparent"
|
||||
Tapped="MonthInteractionLayerTapped" />
|
||||
<Canvas x:Name="MonthCellLabelsCanvas" IsHitTestVisible="False" />
|
||||
<Canvas x:Name="MonthItemsCanvas" />
|
||||
<Canvas x:Name="MonthItemsCanvas">
|
||||
<Canvas.Transitions>
|
||||
<TransitionCollection>
|
||||
<AddDeleteThemeTransition />
|
||||
</TransitionCollection>
|
||||
</Canvas.Transitions>
|
||||
</Canvas>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -35,6 +35,7 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
private const double TimedHourColumnWidth = 64d;
|
||||
private const double TimedGridIntervalMinutes = 30d;
|
||||
private const double TimedSelectionIntervalMinutes = 30d;
|
||||
private const double TimedItemRightSpacing = 10d;
|
||||
private VisibleDateRange _currentRange = new(
|
||||
CalendarDisplayType.Month,
|
||||
DateOnly.FromDateTime(DateTime.Today),
|
||||
@@ -78,6 +79,12 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
[GeneratedDependencyProperty]
|
||||
public partial Brush? WorkHourBackground { get; set; }
|
||||
|
||||
[GeneratedDependencyProperty]
|
||||
public partial Brush? SelectedSlotBackground { get; set; }
|
||||
|
||||
[GeneratedDependencyProperty]
|
||||
public partial DateTime? SelectedDateTime { get; set; }
|
||||
|
||||
public CalendarPeriodControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
@@ -153,6 +160,8 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
partial void OnVisibleRangeChanged(VisibleDateRange? newValue) => RequestRefresh();
|
||||
partial void OnCalendarSettingsChanged(CalendarSettings? newValue) => RequestRefresh();
|
||||
partial void OnTimedHeaderDateFormatChanged(string? newValue) => RequestRefresh();
|
||||
partial void OnSelectedSlotBackgroundChanged(Brush? newValue) => InvalidateStructureCanvases();
|
||||
partial void OnSelectedDateTimeChanged(DateTime? newValue) => InvalidateStructureCanvases();
|
||||
|
||||
partial void OnCalendarItemsChanged(IReadOnlyList<CalendarItemViewModel>? newValue)
|
||||
{
|
||||
@@ -231,6 +240,12 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
QueueRefresh();
|
||||
}
|
||||
|
||||
private void InvalidateStructureCanvases()
|
||||
{
|
||||
TimedStructureCanvas.Invalidate();
|
||||
MonthStructureCanvas.Invalidate();
|
||||
}
|
||||
|
||||
private void Refresh()
|
||||
{
|
||||
if (!_refreshPending || !IsLoaded || ActualWidth <= 0 || VisibleRange is null || CalendarSettings is null)
|
||||
@@ -461,6 +476,7 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
using var minorLinePaint = CreateMinorLinePaint();
|
||||
using var defaultFillPaint = CreateFillPaint(DefaultHourBackground ?? new SolidColorBrush(Colors.Transparent));
|
||||
using var workFillPaint = CreateFillPaint(WorkHourBackground ?? new SolidColorBrush(Colors.Transparent));
|
||||
using var selectedFillPaint = CreateFillPaint(SelectedSlotBackground ?? new SolidColorBrush(Colors.Transparent));
|
||||
var canvas = e.Surface.Canvas;
|
||||
canvas.Clear(SKColors.Transparent);
|
||||
|
||||
@@ -499,6 +515,12 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
}
|
||||
}
|
||||
|
||||
var selectedTimedSlotRect = GetSelectedTimedSlotRect(dayWidth, intervalHeight, intervalCount);
|
||||
if (selectedTimedSlotRect.HasValue && selectedFillPaint.Color.Alpha > 0)
|
||||
{
|
||||
canvas.DrawRect(selectedTimedSlotRect.Value, selectedFillPaint);
|
||||
}
|
||||
|
||||
for (var intervalIndex = 0; intervalIndex <= intervalCount; intervalIndex++)
|
||||
{
|
||||
var y = intervalIndex * intervalHeight;
|
||||
@@ -522,6 +544,7 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
Color = new SKColor(0, 120, 215, 26),
|
||||
IsAntialias = true
|
||||
};
|
||||
using var selectedPaint = CreateFillPaint(SelectedSlotBackground ?? new SolidColorBrush(Colors.Transparent));
|
||||
|
||||
var canvas = e.Surface.Canvas;
|
||||
canvas.Clear(SKColors.Transparent);
|
||||
@@ -545,6 +568,12 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
canvas.DrawRect((float)cell.Bounds.X, (float)cell.Bounds.Y, (float)cell.Bounds.Width, (float)cell.Bounds.Height, todayPaint);
|
||||
}
|
||||
|
||||
var selectedMonthCellRect = GetSelectedMonthCellRect();
|
||||
if (selectedMonthCellRect.HasValue && selectedPaint.Color.Alpha > 0)
|
||||
{
|
||||
canvas.DrawRect(selectedMonthCellRect.Value, selectedPaint);
|
||||
}
|
||||
|
||||
for (var row = 0; row <= MonthCalendarLayoutCalculator.RowCount; row++)
|
||||
{
|
||||
var y = row * cellHeight;
|
||||
@@ -604,7 +633,7 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
{
|
||||
var presenter = new ContentPresenter
|
||||
{
|
||||
Width = item.Bounds.Width,
|
||||
Width = Math.Max(0d, item.Bounds.Width - TimedItemRightSpacing),
|
||||
Height = item.Bounds.Height,
|
||||
Content = item.Item,
|
||||
ContentTemplate = item.Template
|
||||
@@ -669,12 +698,13 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
var slotIndex = Math.Clamp((int)(position.Y / intervalHeight), 0, (int)((24d * 60d / TimedSelectionIntervalMinutes) - 1));
|
||||
var slotStart = TimeSpan.FromMinutes(slotIndex * TimedSelectionIntervalMinutes);
|
||||
var clickedDate = _timedLayout.VisibleDates[dayIndex].ToDateTime(TimeOnly.MinValue).Add(slotStart);
|
||||
var anchorPoint = TimedViewport.TransformToVisual(Root).TransformPoint(position);
|
||||
|
||||
EmptySlotTapped?.Invoke(
|
||||
this,
|
||||
new CalendarEmptySlotTappedEventArgs(
|
||||
clickedDate,
|
||||
new Point(dayIndex * _timedLayout.DayWidth, slotIndex * intervalHeight),
|
||||
anchorPoint,
|
||||
new Size(_timedLayout.DayWidth, intervalHeight)));
|
||||
}
|
||||
|
||||
@@ -690,15 +720,75 @@ public sealed partial class CalendarPeriodControl : UserControl, INotifyProperty
|
||||
var row = Math.Clamp((int)(position.Y / _monthLayout.CellHeight), 0, MonthCalendarLayoutCalculator.RowCount - 1);
|
||||
var cellIndex = Math.Clamp((row * MonthCalendarLayoutCalculator.ColumnCount) + column, 0, _monthLayout.Cells.Count - 1);
|
||||
var cell = _monthLayout.Cells[cellIndex];
|
||||
var anchorPoint = MonthViewport.TransformToVisual(Root).TransformPoint(position);
|
||||
|
||||
EmptySlotTapped?.Invoke(
|
||||
this,
|
||||
new CalendarEmptySlotTappedEventArgs(
|
||||
cell.Date.ToDateTime(TimeOnly.MinValue),
|
||||
new Point(cell.Bounds.X, cell.Bounds.Y),
|
||||
anchorPoint,
|
||||
new Size(cell.Bounds.Width, cell.Bounds.Height)));
|
||||
}
|
||||
|
||||
private SKRect? GetSelectedTimedSlotRect(float dayWidth, float intervalHeight, int intervalCount)
|
||||
{
|
||||
if (SelectedDateTime is not DateTime selectedDateTime || _timedLayout.VisibleDates.Count == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var dayIndex = FindVisibleDateIndex(DateOnly.FromDateTime(selectedDateTime));
|
||||
if (dayIndex < 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var slotIndex = (int)Math.Floor(selectedDateTime.TimeOfDay.TotalMinutes / TimedSelectionIntervalMinutes);
|
||||
slotIndex = Math.Clamp(slotIndex, 0, intervalCount - 1);
|
||||
|
||||
var x = dayIndex * dayWidth;
|
||||
var y = slotIndex * intervalHeight;
|
||||
return new SKRect(x, y, x + dayWidth, y + intervalHeight);
|
||||
}
|
||||
|
||||
private SKRect? GetSelectedMonthCellRect()
|
||||
{
|
||||
if (SelectedDateTime is not DateTime selectedDateTime)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var selectedDate = DateOnly.FromDateTime(selectedDateTime);
|
||||
foreach (var cell in _monthLayout.Cells)
|
||||
{
|
||||
if (cell.Date != selectedDate)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return new SKRect(
|
||||
(float)cell.Bounds.X,
|
||||
(float)cell.Bounds.Y,
|
||||
(float)(cell.Bounds.X + cell.Bounds.Width),
|
||||
(float)(cell.Bounds.Y + cell.Bounds.Height));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private int FindVisibleDateIndex(DateOnly date)
|
||||
{
|
||||
for (var index = 0; index < _timedLayout.VisibleDates.Count; index++)
|
||||
{
|
||||
if (_timedLayout.VisibleDates[index] == date)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private double GetTimedSurfaceWidth() => Math.Max(0d, ActualWidth - TimedHourColumnWidth);
|
||||
|
||||
private string GetTimedHeaderText(DateOnly date)
|
||||
|
||||
@@ -66,7 +66,8 @@ internal static class MonthCalendarLayoutCalculator
|
||||
|
||||
private const double CellPadding = 4d;
|
||||
private const double DayLabelHeight = 20d;
|
||||
private const double ItemHeight = 18d;
|
||||
private const double RegularItemHeight = 18d;
|
||||
private const double ExpandedItemHeight = 30d;
|
||||
private const double ItemGap = 2d;
|
||||
|
||||
public static MonthCalendarLayoutResult Calculate(VisibleDateRange range, IEnumerable<CalendarItemViewModel> items, double availableWidth, double availableHeight)
|
||||
@@ -92,12 +93,13 @@ internal static class MonthCalendarLayoutCalculator
|
||||
foreach (var cell in cells)
|
||||
{
|
||||
var cellItems = GetCellItems(items, cell.Date).ToList();
|
||||
var nextItemY = cell.Bounds.Y + DayLabelHeight + CellPadding;
|
||||
|
||||
for (var index = 0; index < cellItems.Count; index++)
|
||||
{
|
||||
var y = cell.Bounds.Y + DayLabelHeight + CellPadding + (index * (ItemHeight + ItemGap));
|
||||
var itemHeight = GetItemHeight(cellItems[index]);
|
||||
|
||||
if (y + ItemHeight > cell.Bounds.Y + cell.Bounds.Height - CellPadding)
|
||||
if (nextItemY + itemHeight > cell.Bounds.Y + cell.Bounds.Height - CellPadding)
|
||||
{
|
||||
break;
|
||||
}
|
||||
@@ -108,9 +110,11 @@ internal static class MonthCalendarLayoutCalculator
|
||||
cell.Date,
|
||||
new LayoutRect(
|
||||
cell.Bounds.X + CellPadding,
|
||||
y,
|
||||
nextItemY,
|
||||
Math.Max(0, cell.Bounds.Width - (CellPadding * 2)),
|
||||
ItemHeight)));
|
||||
itemHeight)));
|
||||
|
||||
nextItemY += itemHeight + ItemGap;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,4 +147,9 @@ internal static class MonthCalendarLayoutCalculator
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static double GetItemHeight(CalendarItemViewModel item)
|
||||
=> item.IsAllDayEvent || item.IsMultiDayEvent
|
||||
? ExpandedItemHeight
|
||||
: RegularItemHeight;
|
||||
}
|
||||
|
||||
@@ -44,6 +44,8 @@
|
||||
DefaultHourBackground="{ThemeResource CalendarDefaultHourBackgroundBrush}"
|
||||
EmptySlotTapped="CalendarSurfaceEmptySlotTapped"
|
||||
IsEnabled="{x:Bind ViewModel.IsCalendarEnabled, Mode=OneWay}"
|
||||
SelectedDateTime="{x:Bind ViewModel.SelectedQuickEventDate, Mode=OneWay}"
|
||||
SelectedSlotBackground="{ThemeResource CalendarSelectedHourBackgroundBrush}"
|
||||
VisibleRange="{x:Bind ViewModel.CurrentVisibleRange, Mode=OneWay}"
|
||||
WorkHourBackground="{ThemeResource CalendarWorkHourBackgroundBrush}" />
|
||||
</Border>
|
||||
@@ -64,7 +66,6 @@
|
||||
Closed="QuickEventPopupClosed"
|
||||
DesiredPlacement="{x:Bind helpers:XamlHelpers.GetPlaccementModeForCalendarType(ViewModel.StatePersistanceService.CalendarDisplayType), Mode=OneWay}"
|
||||
IsLightDismissEnabled="True"
|
||||
IsOpen="{x:Bind ViewModel.IsQuickEventDialogOpen, Mode=TwoWay}"
|
||||
PlacementTarget="{x:Bind TeachingTipPositionerGrid}">
|
||||
<Popup.ChildTransitions>
|
||||
<TransitionCollection>
|
||||
@@ -226,14 +227,17 @@
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Command="{x:Bind ViewModel.MoreDetailsCommand}" -->
|
||||
<Button HorizontalAlignment="Stretch" Content="{x:Bind domain:Translator.QuickEventDialogMoreDetailsButtonText}" />
|
||||
<Button
|
||||
HorizontalAlignment="Stretch"
|
||||
Click="MoreDetailsClicked"
|
||||
Content="{x:Bind domain:Translator.QuickEventDialogMoreDetailsButtonText}" />
|
||||
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
HorizontalAlignment="Stretch"
|
||||
Command="{x:Bind ViewModel.SaveQuickEventCommand}"
|
||||
Click="SaveQuickEventClicked"
|
||||
Content="{x:Bind domain:Translator.Buttons_Save}"
|
||||
IsEnabled="{x:Bind ViewModel.CanSaveQuickEvent, Mode=OneWay}"
|
||||
Style="{ThemeResource AccentButtonStyle}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
@@ -12,6 +12,7 @@ using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
using Windows.Foundation;
|
||||
using Wino.Core.Domain;
|
||||
using Wino.Core.Domain.Enums;
|
||||
using Wino.Calendar.Controls;
|
||||
using Wino.Calendar.Views.Abstract;
|
||||
using Wino.Core.Domain.Entities.Calendar;
|
||||
@@ -30,6 +31,7 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
private ICalendarShellClient CalendarShellClient { get; } = WinoApplication.Current.Services.GetRequiredService<ICalendarShellClient>();
|
||||
private CancellationTokenSource? _searchCancellationTokenSource;
|
||||
private long _calendarTypeSelectorChangedToken;
|
||||
private bool _suppressSelectionResetOnPopupClose;
|
||||
|
||||
public ObservableCollection<TitleBarSearchSuggestion> SearchSuggestions { get; } = [];
|
||||
|
||||
@@ -52,6 +54,7 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
|
||||
protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
|
||||
{
|
||||
CloseQuickEventPopup(clearSelection: true);
|
||||
base.OnNavigatingFrom(e);
|
||||
}
|
||||
|
||||
@@ -146,21 +149,28 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
}
|
||||
|
||||
ViewModel.SelectedQuickEventDate = e.ClickedDate;
|
||||
ViewModel.IsAllDay = ViewModel.CurrentVisibleRange?.DisplayType == CalendarDisplayType.Month;
|
||||
|
||||
var transform = CalendarSurface.TransformToVisual(CalendarOverlayCanvas);
|
||||
var canvasPoint = transform.TransformPoint(e.PositionerPoint);
|
||||
var canvasPoint = transform.TransformPoint(e.AnchorPoint);
|
||||
|
||||
TeachingTipPositionerGrid.Width = e.CellSize.Width;
|
||||
TeachingTipPositionerGrid.Height = e.CellSize.Height;
|
||||
TeachingTipPositionerGrid.Width = 1;
|
||||
TeachingTipPositionerGrid.Height = 1;
|
||||
|
||||
Canvas.SetLeft(TeachingTipPositionerGrid, canvasPoint.X);
|
||||
Canvas.SetTop(TeachingTipPositionerGrid, canvasPoint.Y);
|
||||
|
||||
var startTime = e.ClickedDate.TimeOfDay;
|
||||
var endTime = startTime.Add(TimeSpan.FromMinutes(30));
|
||||
ViewModel.SelectQuickEventTimeRange(startTime, endTime);
|
||||
if (!ViewModel.IsAllDay)
|
||||
{
|
||||
var startTime = e.ClickedDate.TimeOfDay;
|
||||
var endTime = startTime.Add(TimeSpan.FromMinutes(30));
|
||||
ViewModel.SelectQuickEventTimeRange(startTime, endTime);
|
||||
}
|
||||
|
||||
_suppressSelectionResetOnPopupClose = true;
|
||||
QuickEventPopupDialog.IsOpen = false;
|
||||
QuickEventPopupDialog.IsOpen = true;
|
||||
_suppressSelectionResetOnPopupClose = false;
|
||||
}
|
||||
|
||||
private void QuickEventAccountSelectorSelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
@@ -168,6 +178,10 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
|
||||
private void QuickEventPopupClosed(object sender, object e)
|
||||
{
|
||||
if (!_suppressSelectionResetOnPopupClose)
|
||||
{
|
||||
ViewModel.SelectedQuickEventDate = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void PopupPlacementChanged(object sender, object e)
|
||||
@@ -257,6 +271,7 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
|
||||
private void CalendarPageUnloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
CloseQuickEventPopup(clearSelection: true);
|
||||
CalendarToolbar.UnregisterSelectedTypeChanged(_calendarTypeSelectorChangedToken);
|
||||
CalendarToolbar.PreviousDateRequested -= CalendarToolbarPreviousDateRequested;
|
||||
CalendarToolbar.NextDateRequested -= CalendarToolbarNextDateRequested;
|
||||
@@ -267,4 +282,58 @@ public sealed partial class CalendarPage : CalendarPageAbstract, ITitleBarSearch
|
||||
_searchCancellationTokenSource?.Dispose();
|
||||
Unloaded -= CalendarPageUnloaded;
|
||||
}
|
||||
|
||||
private async void SaveQuickEventClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!ViewModel.SaveQuickEventCommand.CanExecute(null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_suppressSelectionResetOnPopupClose = true;
|
||||
|
||||
try
|
||||
{
|
||||
QuickEventPopupDialog.IsOpen = false;
|
||||
await ViewModel.SaveQuickEventCommand.ExecuteAsync(null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_suppressSelectionResetOnPopupClose = false;
|
||||
ViewModel.SelectedQuickEventDate = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void MoreDetailsClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!ViewModel.GoToEventComposePageCommand.CanExecute(null))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
_suppressSelectionResetOnPopupClose = true;
|
||||
|
||||
try
|
||||
{
|
||||
QuickEventPopupDialog.IsOpen = false;
|
||||
ViewModel.GoToEventComposePageCommand.Execute(null);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_suppressSelectionResetOnPopupClose = false;
|
||||
ViewModel.SelectedQuickEventDate = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void CloseQuickEventPopup(bool clearSelection)
|
||||
{
|
||||
_suppressSelectionResetOnPopupClose = !clearSelection;
|
||||
QuickEventPopupDialog.IsOpen = false;
|
||||
_suppressSelectionResetOnPopupClose = false;
|
||||
|
||||
if (clearSelection)
|
||||
{
|
||||
ViewModel.SelectedQuickEventDate = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user