feat: logical scrollable.
This commit is contained in:
110
src/Ursa/Controls/DateTimePicker/TimePicker.cs
Normal file
110
src/Ursa/Controls/DateTimePicker/TimePicker.cs
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Data;
|
||||||
|
using Irihi.Avalonia.Shared.Contracts;
|
||||||
|
|
||||||
|
namespace Ursa.Controls.TimePicker;
|
||||||
|
|
||||||
|
public class TimePicker: TemplatedControl, IClearControl
|
||||||
|
{
|
||||||
|
private TimeSpan? _selectedTimeHolder;
|
||||||
|
|
||||||
|
public static readonly StyledProperty<string> DisplayFormatProperty = AvaloniaProperty.Register<TimePicker, string>(
|
||||||
|
nameof(DisplayFormat), defaultValue: "HH:mm:ss");
|
||||||
|
|
||||||
|
public string DisplayFormat
|
||||||
|
{
|
||||||
|
get => GetValue(DisplayFormatProperty);
|
||||||
|
set => SetValue(DisplayFormatProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<string> PanelFormatProperty = AvaloniaProperty.Register<TimePicker, string>(
|
||||||
|
nameof(PanelFormat), defaultValue: "HH mm ss");
|
||||||
|
|
||||||
|
public string PanelFormat
|
||||||
|
{
|
||||||
|
get => GetValue(PanelFormatProperty);
|
||||||
|
set => SetValue(PanelFormatProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<TimeSpan?> SelectedTimeProperty = AvaloniaProperty.Register<TimePicker, TimeSpan?>(
|
||||||
|
nameof(SelectedTime));
|
||||||
|
|
||||||
|
public TimeSpan? SelectedTime
|
||||||
|
{
|
||||||
|
get => GetValue(SelectedTimeProperty);
|
||||||
|
set => SetValue(SelectedTimeProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<bool> NeedConfirmationProperty = AvaloniaProperty.Register<TimePicker, bool>(
|
||||||
|
nameof(NeedConfirmation));
|
||||||
|
|
||||||
|
public bool NeedConfirmation
|
||||||
|
{
|
||||||
|
get => GetValue(NeedConfirmationProperty);
|
||||||
|
set => SetValue(NeedConfirmationProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<bool> IsLoopingProperty = AvaloniaProperty.Register<TimePicker, bool>(
|
||||||
|
nameof(IsLooping));
|
||||||
|
|
||||||
|
public bool IsLooping
|
||||||
|
{
|
||||||
|
get => GetValue(IsLoopingProperty);
|
||||||
|
set => SetValue(IsLoopingProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static TimePicker()
|
||||||
|
{
|
||||||
|
PanelFormatProperty.Changed.AddClassHandler<TimePicker, string>((picker, args)=> picker.OnPanelFormatChanged(args));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnPanelFormatChanged(AvaloniaPropertyChangedEventArgs<string> args)
|
||||||
|
{
|
||||||
|
var format = args.NewValue.Value;
|
||||||
|
string[] parts = format.Split(new char[] { ' ', '-', ':' });
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
protected override void OnApplyTemplate(TemplateAppliedEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnApplyTemplate(e);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnSelectionChanged()
|
||||||
|
{
|
||||||
|
if (NeedConfirmation)
|
||||||
|
{
|
||||||
|
_selectedTimeHolder = new TimeSpan();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
SelectedTime = new TimeSpan();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Clear()
|
||||||
|
{
|
||||||
|
SetCurrentValue(SelectedTimeProperty, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Confirm()
|
||||||
|
{
|
||||||
|
if (NeedConfirmation)
|
||||||
|
{
|
||||||
|
// TODO: close popup.
|
||||||
|
SetCurrentValue(SelectedTimeProperty, _selectedTimeHolder);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UpdateDataValidation(AvaloniaProperty property, BindingValueType state, Exception? error)
|
||||||
|
{
|
||||||
|
base.UpdateDataValidation(property, state, error);
|
||||||
|
if (property == SelectedTimeProperty)
|
||||||
|
{
|
||||||
|
DataValidationErrors.SetError(this, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
62
src/Ursa/Controls/DateTimePicker/UrsaTimePickerPanel.cs
Normal file
62
src/Ursa/Controls/DateTimePicker/UrsaTimePickerPanel.cs
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
using Avalonia;
|
||||||
|
using Avalonia.Controls;
|
||||||
|
using Avalonia.Controls.Primitives;
|
||||||
|
using Avalonia.Input;
|
||||||
|
using Avalonia.Interactivity;
|
||||||
|
|
||||||
|
namespace Ursa.Controls.Panels;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The panel to display items for time selection
|
||||||
|
/// </summary>
|
||||||
|
public class UrsaTimePickerPanel: Panel, ILogicalScrollable
|
||||||
|
{
|
||||||
|
public static readonly StyledProperty<double> ItemHeightProperty =
|
||||||
|
AvaloniaProperty.Register<UrsaTimePickerPanel, double>(
|
||||||
|
nameof(ItemHeight), defaultValue: 32);
|
||||||
|
|
||||||
|
public double ItemHeight
|
||||||
|
{
|
||||||
|
get => GetValue(ItemHeightProperty);
|
||||||
|
set => SetValue(ItemHeightProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly StyledProperty<bool> ShouldLoopProperty = AvaloniaProperty.Register<UrsaTimePickerPanel, bool>(
|
||||||
|
nameof(ShouldLoop));
|
||||||
|
|
||||||
|
public bool ShouldLoop
|
||||||
|
{
|
||||||
|
get => GetValue(ShouldLoopProperty);
|
||||||
|
set => SetValue(ShouldLoopProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
static UrsaTimePickerPanel()
|
||||||
|
{
|
||||||
|
ItemHeightProperty.Changed.AddClassHandler<UrsaTimePickerPanel, double>((panel, args) => panel.OnItemHeightChanged(args));
|
||||||
|
AffectsArrange<UrsaTimePickerPanel>(ItemHeightProperty);
|
||||||
|
AffectsMeasure<UrsaTimePickerPanel>(ItemHeightProperty);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Size _scrollSize;
|
||||||
|
private Size _pageScrollSize;
|
||||||
|
private void OnItemHeightChanged(AvaloniaPropertyChangedEventArgs<double> args)
|
||||||
|
{
|
||||||
|
var newValue = args.NewValue.Value;
|
||||||
|
_scrollSize = new Size(0, newValue);
|
||||||
|
_pageScrollSize = new Size(0, newValue * 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
public event EventHandler? OnSelectionChanged;
|
||||||
|
public Size Extent { get; private set; }
|
||||||
|
public Vector Offset { get; set; }
|
||||||
|
public Size Viewport => Bounds.Size;
|
||||||
|
public bool BringIntoView(Control target, Rect targetRect) => false;
|
||||||
|
public Control? GetControlInDirection(NavigationDirection direction, Control? from) => null;
|
||||||
|
public void RaiseScrollInvalidated(System.EventArgs e) => ScrollInvalidated?.Invoke(this, e);
|
||||||
|
public bool CanHorizontallyScroll { get => false; set { } }
|
||||||
|
public bool CanVerticallyScroll { get => false; set {} }
|
||||||
|
public bool IsLogicalScrollEnabled => true;
|
||||||
|
public Size ScrollSize => _scrollSize;
|
||||||
|
public Size PageScrollSize => _pageScrollSize;
|
||||||
|
public event EventHandler? ScrollInvalidated;
|
||||||
|
}
|
||||||
@@ -1,28 +0,0 @@
|
|||||||
using Avalonia;
|
|
||||||
using Avalonia.Controls;
|
|
||||||
using Avalonia.Controls.Primitives;
|
|
||||||
using Avalonia.Input;
|
|
||||||
|
|
||||||
namespace Ursa.Controls.Panels;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The panel to display items for time selection
|
|
||||||
/// </summary>
|
|
||||||
public class UrsaTimePickerPanel: Panel
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Defines whether the panel is looping.
|
|
||||||
/// This is ont applicable for columns like year and AM/PM designation.
|
|
||||||
/// </summary>
|
|
||||||
public static readonly StyledProperty<bool> IsLoopingProperty = AvaloniaProperty.Register<UrsaTimePickerPanel, bool>(
|
|
||||||
nameof(IsLooping));
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets the value of <see cref="IsLoopingProperty"/>.
|
|
||||||
/// </summary>
|
|
||||||
public bool IsLooping
|
|
||||||
{
|
|
||||||
get => GetValue(IsLoopingProperty);
|
|
||||||
set => SetValue(IsLoopingProperty, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,44 +0,0 @@
|
|||||||
using Avalonia;
|
|
||||||
using Avalonia.Controls.Primitives;
|
|
||||||
|
|
||||||
namespace Ursa.Controls.TimePicker;
|
|
||||||
|
|
||||||
public class TimePicker: TemplatedControl
|
|
||||||
{
|
|
||||||
public static readonly StyledProperty<string> DisplayFormatProperty = AvaloniaProperty.Register<TimePicker, string>(
|
|
||||||
nameof(DisplayFormat), defaultValue:"HH:mm:ss");
|
|
||||||
|
|
||||||
public string DisplayFormat
|
|
||||||
{
|
|
||||||
get => GetValue(DisplayFormatProperty);
|
|
||||||
set => SetValue(DisplayFormatProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly StyledProperty<string> PanelPlacementProperty =
|
|
||||||
AvaloniaProperty.Register<TimePicker, string>(
|
|
||||||
nameof(PanelPlacement), defaultValue: "HH mm ss");
|
|
||||||
|
|
||||||
public string PanelPlacement
|
|
||||||
{
|
|
||||||
get => GetValue(PanelPlacementProperty);
|
|
||||||
set => SetValue(PanelPlacementProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly StyledProperty<TimeSpan?> SelectedTimeProperty = AvaloniaProperty.Register<TimePicker, TimeSpan?>(
|
|
||||||
nameof(SelectedTime));
|
|
||||||
|
|
||||||
public TimeSpan? SelectedTime
|
|
||||||
{
|
|
||||||
get => GetValue(SelectedTimeProperty);
|
|
||||||
set => SetValue(SelectedTimeProperty, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static readonly StyledProperty<bool> NeedConfirmProperty = AvaloniaProperty.Register<TimePicker, bool>(
|
|
||||||
nameof(NeedConfirm));
|
|
||||||
|
|
||||||
public bool NeedConfirm
|
|
||||||
{
|
|
||||||
get => GetValue(NeedConfirmProperty);
|
|
||||||
set => SetValue(NeedConfirmProperty, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -24,4 +24,8 @@
|
|||||||
<None Include="irihi.png" Pack="true" PackagePath=""/>
|
<None Include="irihi.png" Pack="true" PackagePath=""/>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Controls\Panels\" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
Reference in New Issue
Block a user