Proper handling of DateTimeOffset, support for Multi-Day events and reacting to adding/removing events for the days.
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using System.Collections.Generic;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Wino.Core.Domain.Collections;
|
||||
using Wino.Core.Domain.Interfaces;
|
||||
@@ -76,9 +75,6 @@ namespace Wino.Calendar.Controls
|
||||
collection.CalendarItemAdded += SingleEventUpdated;
|
||||
collection.CalendarItemRemoved += SingleEventUpdated;
|
||||
|
||||
collection.CalendarItemRangeAdded += CollectionOfEventsUpdated;
|
||||
collection.CalendarItemRangeRemoved += CollectionOfEventsUpdated;
|
||||
|
||||
collection.CalendarItemsCleared += EventsCleared;
|
||||
}
|
||||
|
||||
@@ -87,14 +83,10 @@ namespace Wino.Calendar.Controls
|
||||
collection.CalendarItemAdded -= SingleEventUpdated;
|
||||
collection.CalendarItemRemoved -= SingleEventUpdated;
|
||||
|
||||
collection.CalendarItemRangeAdded -= CollectionOfEventsUpdated;
|
||||
collection.CalendarItemRangeRemoved -= CollectionOfEventsUpdated;
|
||||
|
||||
collection.CalendarItemsCleared -= EventsCleared;
|
||||
}
|
||||
|
||||
private void SingleEventUpdated(object sender, ICalendarItem calendarItem) => UpdateCollectionVisuals();
|
||||
private void CollectionOfEventsUpdated(object sender, List<ICalendarItem> calendarItems) => UpdateCollectionVisuals();
|
||||
private void EventsCleared(object sender, System.EventArgs e) => UpdateCollectionVisuals();
|
||||
|
||||
private void UpdateCollectionVisuals()
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Diagnostics;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Wino.Calendar.Args;
|
||||
@@ -95,8 +94,6 @@ namespace Wino.Calendar.Controls
|
||||
{
|
||||
if (canvas == null) return;
|
||||
|
||||
Debug.WriteLine("Deregister active canvas.");
|
||||
|
||||
canvas.SelectedDateTime = null;
|
||||
canvas.TimelineCellSelected -= ActiveTimelineCellSelected;
|
||||
canvas.TimelineCellUnselected -= ActiveTimelineCellUnselected;
|
||||
@@ -106,8 +103,6 @@ namespace Wino.Calendar.Controls
|
||||
{
|
||||
if (canvas == null) return;
|
||||
|
||||
Debug.WriteLine("Register new canvas.");
|
||||
|
||||
canvas.SelectedDateTime = null;
|
||||
canvas.TimelineCellSelected += ActiveTimelineCellSelected;
|
||||
canvas.TimelineCellUnselected += ActiveTimelineCellUnselected;
|
||||
@@ -127,13 +122,6 @@ namespace Wino.Calendar.Controls
|
||||
InternalFlipView = GetTemplateChild(PART_WinoFlipView) as WinoCalendarFlipView;
|
||||
}
|
||||
|
||||
private void FlipViewsActiveTimelineCanvasChanged(object sender, WinoDayTimelineCanvas e)
|
||||
{
|
||||
ActiveCanvas = e;
|
||||
|
||||
SelectedFlipViewDayRange = InternalFlipView.SelectedItem as DayRangeRenderModel;
|
||||
}
|
||||
|
||||
private void ActiveTimelineCellUnselected(object sender, TimelineCellUnselectedArgs e)
|
||||
=> TimelineCellUnselected?.Invoke(this, e);
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using Itenso.TimePeriod;
|
||||
using Windows.Foundation;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
@@ -21,6 +22,14 @@ namespace Wino.Calendar.Controls
|
||||
|
||||
public static readonly DependencyProperty EventItemMarginProperty = DependencyProperty.Register(nameof(EventItemMargin), typeof(Thickness), typeof(WinoCalendarPanel), new PropertyMetadata(new Thickness(0, 0, 0, 0)));
|
||||
public static readonly DependencyProperty HourHeightProperty = DependencyProperty.Register(nameof(HourHeight), typeof(double), typeof(WinoCalendarPanel), new PropertyMetadata(0d));
|
||||
public static readonly DependencyProperty PeriodProperty = DependencyProperty.Register(nameof(Period), typeof(ITimePeriod), typeof(WinoCalendarPanel), new PropertyMetadata(null));
|
||||
|
||||
|
||||
public ITimePeriod Period
|
||||
{
|
||||
get { return (ITimePeriod)GetValue(PeriodProperty); }
|
||||
set { SetValue(PeriodProperty, value); }
|
||||
}
|
||||
|
||||
public double HourHeight
|
||||
{
|
||||
@@ -41,11 +50,18 @@ namespace Wino.Calendar.Controls
|
||||
|
||||
private double GetChildTopMargin(ICalendarItem calendarItemViewModel, double availableHeight)
|
||||
{
|
||||
var childStart = calendarItemViewModel.StartTime;
|
||||
var childStart = calendarItemViewModel.StartDate;
|
||||
|
||||
double totalMinutes = 1440;
|
||||
double minutesFromStart = (childStart - childStart.DateTime.Date).TotalMinutes;
|
||||
return (minutesFromStart / totalMinutes) * availableHeight;
|
||||
if (childStart <= Period.Start)
|
||||
{
|
||||
// Event started before or exactly at the periods tart. This might be a multi-day event.
|
||||
// We can simply consider event must not have a top margin.
|
||||
|
||||
return 0d;
|
||||
}
|
||||
|
||||
double minutesFromStart = (childStart - Period.Start).TotalMinutes;
|
||||
return (minutesFromStart / 1440) * availableHeight;
|
||||
}
|
||||
|
||||
private double GetChildWidth(CalendarItemMeasurement calendarItemMeasurement, double availableWidth)
|
||||
@@ -56,16 +72,48 @@ namespace Wino.Calendar.Controls
|
||||
private double GetChildLeftMargin(CalendarItemMeasurement calendarItemMeasurement, double availableWidth)
|
||||
=> availableWidth * calendarItemMeasurement.Left;
|
||||
|
||||
private double GetChildHeight(DateTimeOffset childStart, DateTimeOffset childEnd)
|
||||
private double GetChildHeight(ICalendarItem child)
|
||||
{
|
||||
double totalMinutes = 1440;
|
||||
double childDurationInMinutes = 0d;
|
||||
|
||||
double availableHeight = HourHeight * 24;
|
||||
double childDuration = (childEnd - childStart).TotalMinutes;
|
||||
return (childDuration / totalMinutes) * availableHeight;
|
||||
|
||||
var childStart = child.Period.Start;
|
||||
var childEnd = child.Period.End;
|
||||
|
||||
// Multi-day event.
|
||||
|
||||
if (childStart < Period.Start)
|
||||
{
|
||||
if (childEnd >= Period.End)
|
||||
{
|
||||
// Event spans the whole period.
|
||||
return availableHeight;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Check how many of the event falls into the current period.
|
||||
childDurationInMinutes = (childEnd - Period.Start).TotalMinutes;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
childDurationInMinutes = (childEnd - childStart).TotalMinutes;
|
||||
}
|
||||
|
||||
return (childDurationInMinutes / 1440) * availableHeight;
|
||||
}
|
||||
|
||||
protected override Size MeasureOverride(Size availableSize)
|
||||
{
|
||||
ResetMeasurements();
|
||||
return base.MeasureOverride(availableSize);
|
||||
}
|
||||
|
||||
protected override Size ArrangeOverride(Size finalSize)
|
||||
{
|
||||
if (Period == null || HourHeight == 0d) return finalSize;
|
||||
|
||||
// Measure/arrange each child height and width.
|
||||
// This is a vertical calendar. Therefore the height of each child is the duration of the event.
|
||||
// Children weights for left and right will be saved if they don't exist.
|
||||
@@ -99,7 +147,7 @@ namespace Wino.Calendar.Controls
|
||||
|
||||
var childMeasurement = _measurements[child.Id];
|
||||
|
||||
double childHeight = Math.Max(0, GetChildHeight(child.StartTime, child.StartTime.AddMinutes(child.DurationInMinutes)));
|
||||
double childHeight = Math.Max(0, GetChildHeight(child));
|
||||
double childWidth = Math.Max(0, GetChildWidth(childMeasurement, finalSize.Width));
|
||||
double childTop = Math.Max(0, GetChildTopMargin(child, availableHeight));
|
||||
double childLeft = Math.Max(0, GetChildLeftMargin(childMeasurement, availableWidth));
|
||||
@@ -142,7 +190,7 @@ namespace Wino.Calendar.Controls
|
||||
var columns = new List<List<ICalendarItem>>();
|
||||
DateTime? lastEventEnding = null;
|
||||
|
||||
foreach (var ev in events.OrderBy(ev => ev.Period.Start).ThenBy(ev => ev.Period.End))
|
||||
foreach (var ev in events.OrderBy(ev => ev.StartDate).ThenBy(ev => ev.EndDate))
|
||||
{
|
||||
if (ev.Period.Start >= lastEventEnding)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user