|
|
@@ -14,6 +14,12 @@ using System.Runtime.Serialization;
|
|
|
|
|
|
namespace InABox.Avalonia.Components;
|
|
|
|
|
|
+public class CalendarBlockEventArgs(TimeSpan start, TimeSpan end) : EventArgs
|
|
|
+{
|
|
|
+ public TimeSpan Start { get; set; } = start;
|
|
|
+ public TimeSpan End { get; set; } = end;
|
|
|
+}
|
|
|
+
|
|
|
public partial class CalendarView : UserControl
|
|
|
{
|
|
|
public static readonly StyledProperty<double> RowHeightProperty =
|
|
|
@@ -104,6 +110,9 @@ public partial class CalendarView : UserControl
|
|
|
set => SetValue(HeaderTemplateProperty, value);
|
|
|
}
|
|
|
|
|
|
+ public event EventHandler<CalendarBlockEventArgs>? EmptyBlockClicked;
|
|
|
+ public event EventHandler<CalendarBlockEventArgs>? EmptyBlockHeld;
|
|
|
+
|
|
|
static CalendarView()
|
|
|
{
|
|
|
ItemsSourceProperty.Changed.AddClassHandler<CalendarView>(ItemsSource_Changed);
|
|
|
@@ -230,6 +239,8 @@ public partial class CalendarView : UserControl
|
|
|
_oldSubscriptions.Add(block.GetObservable(Block.ColumnProperty).Skip(1).Subscribe(x => Render(itemsChanged: true)));
|
|
|
_oldSubscriptions.Add(block.GetObservable(Block.StartTimeProperty).Skip(1).Subscribe(x => UpdateBlock(block)));
|
|
|
_oldSubscriptions.Add(block.GetObservable(Block.EndTimeProperty).Skip(1).Subscribe(x => UpdateBlock(block)));
|
|
|
+ block.PointerPressed += Block_PointerPressed;
|
|
|
+ block.Background = new SolidColorBrush(Colors.Transparent);
|
|
|
|
|
|
var column = block.Column;
|
|
|
if(column is null)
|
|
|
@@ -240,6 +251,11 @@ public partial class CalendarView : UserControl
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ private void Block_PointerPressed(object? sender, global::Avalonia.Input.PointerPressedEventArgs e)
|
|
|
+ {
|
|
|
+ e.Handled = true;
|
|
|
+ }
|
|
|
+
|
|
|
private void Render(bool itemsChanged = false, bool recalculatePositions = false)
|
|
|
{
|
|
|
if (itemsChanged)
|
|
|
@@ -292,6 +308,42 @@ public partial class CalendarView : UserControl
|
|
|
|
|
|
foreach(var column in columnBlocks.Columns!)
|
|
|
{
|
|
|
+ for(int j = 0; j < Math.Ceiling(nRows); ++j)
|
|
|
+ {
|
|
|
+ var backgroundBlock = new Border
|
|
|
+ {
|
|
|
+ Width = colWidth,
|
|
|
+ Height = rowHeight,
|
|
|
+ Background = new SolidColorBrush(Colors.Transparent)
|
|
|
+ };
|
|
|
+ var start = RowInterval * j;
|
|
|
+ var end = RowInterval * (j + 1);
|
|
|
+ if(end.TotalHours >= 24)
|
|
|
+ {
|
|
|
+ end = TimeSpan.FromHours(24).Subtract(TimeSpan.FromTicks(1));
|
|
|
+ }
|
|
|
+ CancellationTokenSource? cts = null;
|
|
|
+ backgroundBlock.PointerPressed += (o, e) =>
|
|
|
+ {
|
|
|
+ cts = new();
|
|
|
+ Task.Delay(1000).ContinueWith(task =>
|
|
|
+ {
|
|
|
+ cts = null;
|
|
|
+ EmptyBlockHeld?.Invoke(this, new(start, end));
|
|
|
+ }, cts.Token, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext());
|
|
|
+ };
|
|
|
+ backgroundBlock.PointerReleased += (o, e) =>
|
|
|
+ {
|
|
|
+ if(cts is not null)
|
|
|
+ {
|
|
|
+ cts.Cancel();
|
|
|
+ EmptyBlockClicked?.Invoke(this, new(start, end));
|
|
|
+ }
|
|
|
+ };
|
|
|
+ Canvas.SetLeft(backgroundBlock, colX);
|
|
|
+ Canvas.SetTop(backgroundBlock, j * rowHeight);
|
|
|
+ Canvas.Children.Add(backgroundBlock);
|
|
|
+ }
|
|
|
foreach(var block in column)
|
|
|
{
|
|
|
Canvas.SetTop(block, GetRow(block.StartTime) * rowHeight);
|