From 6461490c3461cd271ab7d5d63202cd5fe31b09bd Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Wed, 19 Feb 2025 21:35:44 +0800 Subject: [PATCH 1/5] feat: make text editable. --- .../Controls/DateRangePicker.axaml | 3 +- .../Controls/DateTimePicker/DatePicker.cs | 54 +++--- .../DateTimePicker/DateRangePicker.cs | 105 +++++++++++- .../Controls/DateTimePicker/DateTimePicker.cs | 102 +++++++----- .../Controls/DateTimePicker/TimePicker.cs | 33 +++- .../DateTimePicker/TimeRangePicker.cs | 156 +++++++++++++++--- 6 files changed, 356 insertions(+), 97 deletions(-) diff --git a/src/Ursa.Themes.Semi/Controls/DateRangePicker.axaml b/src/Ursa.Themes.Semi/Controls/DateRangePicker.axaml index c9ba2ed..db9c77b 100644 --- a/src/Ursa.Themes.Semi/Controls/DateRangePicker.axaml +++ b/src/Ursa.Themes.Semi/Controls/DateRangePicker.axaml @@ -26,7 +26,7 @@ BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" /> - + + - - - - - - - - - - - - + + + + + + + - + \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/DatePickerDemo.axaml.cs b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml.cs index 74214c7..4bb0d49 100644 --- a/demo/Ursa.Demo/Pages/DatePickerDemo.axaml.cs +++ b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml.cs @@ -10,14 +10,4 @@ public partial class DatePickerDemo : UserControl { InitializeComponent(); } - - private void CalendarView_OnOnDateSelected(object? _, CalendarDayButtonEventArgs e) - { - Debug.WriteLine("Pressed: "+ e.Date?.ToLongDateString()); - } - - private void CalendarView_OnOnDatePreviewed(object? _, CalendarDayButtonEventArgs e) - { - Debug.WriteLine("Hovered: "+e.Date?.ToLongDateString()); - } } \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/DateRangePickerDemo.axaml b/demo/Ursa.Demo/Pages/DateRangePickerDemo.axaml new file mode 100644 index 0000000..f4f2071 --- /dev/null +++ b/demo/Ursa.Demo/Pages/DateRangePickerDemo.axaml @@ -0,0 +1,37 @@ + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/DateRangePickerDemo.axaml.cs b/demo/Ursa.Demo/Pages/DateRangePickerDemo.axaml.cs new file mode 100644 index 0000000..56acc29 --- /dev/null +++ b/demo/Ursa.Demo/Pages/DateRangePickerDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class DateRangePickerDemo : UserControl +{ + public DateRangePickerDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/TimePickerDemo.axaml b/demo/Ursa.Demo/Pages/TimePickerDemo.axaml index 4b849fd..9ffc7fe 100644 --- a/demo/Ursa.Demo/Pages/TimePickerDemo.axaml +++ b/demo/Ursa.Demo/Pages/TimePickerDemo.axaml @@ -43,10 +43,6 @@ InnerRightContent="截止" NeedConfirmation="True" PanelFormat="{Binding #panelFormat.Text}" /> - - diff --git a/demo/Ursa.Demo/Pages/TimeRangePickerDemo.axaml b/demo/Ursa.Demo/Pages/TimeRangePickerDemo.axaml new file mode 100644 index 0000000..7d98aec --- /dev/null +++ b/demo/Ursa.Demo/Pages/TimeRangePickerDemo.axaml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/TimeRangePickerDemo.axaml.cs b/demo/Ursa.Demo/Pages/TimeRangePickerDemo.axaml.cs new file mode 100644 index 0000000..564a507 --- /dev/null +++ b/demo/Ursa.Demo/Pages/TimeRangePickerDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class TimeRangePickerDemo : UserControl +{ + public TimeRangePickerDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/DatePickerDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/DatePickerDemoViewModel.cs index 693ab0f..a1bf3c4 100644 --- a/demo/Ursa.Demo/ViewModels/DatePickerDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/DatePickerDemoViewModel.cs @@ -7,22 +7,9 @@ namespace Ursa.Demo.ViewModels; public partial class DatePickerDemoViewModel: ObservableObject { [ObservableProperty] private DateTime? _selectedDate; - [ObservableProperty] private DateTime? _startDate; - [ObservableProperty] private DateTime? _endDate; public DatePickerDemoViewModel() { SelectedDate = DateTime.Today; - StartDate = DateTime.Today; - EndDate = DateTime.Today.AddDays(7); - } - - protected override void OnPropertyChanged(PropertyChangedEventArgs e) - { - base.OnPropertyChanged(e); - if (e.PropertyName == nameof(SelectedDate)) - { - - } } } \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/DateRangePickerDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/DateRangePickerDemoViewModel.cs new file mode 100644 index 0000000..1bcaa2c --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/DateRangePickerDemoViewModel.cs @@ -0,0 +1,16 @@ +using System; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace Ursa.Demo.ViewModels; + +public partial class DateRangePickerDemoViewModel: ObservableObject +{ + [ObservableProperty] private DateTime? _startDate; + [ObservableProperty] private DateTime? _endDate; + + public DateRangePickerDemoViewModel() + { + StartDate = DateTime.Today; + EndDate = DateTime.Today.AddDays(7); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs index 2abaaf4..161df53 100644 --- a/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MainViewViewModel.cs @@ -41,6 +41,7 @@ public partial class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyClassInput => new ClassInputDemoViewModel(), MenuKeys.MenuKeyClock => new ClockDemoViewModel(), MenuKeys.MenuKeyDatePicker => new DatePickerDemoViewModel(), + MenuKeys.MenuKeyDateRangePicker => new DateRangePickerDemoViewModel(), MenuKeys.MenuKeyDateTimePicker => new DateTimePickerDemoViewModel(), MenuKeys.MenuKeyDialog => new DialogDemoViewModel(), MenuKeys.MenuKeyDisableContainer => new DisableContainerDemoViewModel(), @@ -75,6 +76,7 @@ public partial class MainViewViewModel : ViewModelBase MenuKeys.MenuKeyTimeBox => new TimeBoxDemoViewModel(), MenuKeys.MenuKeyTimeline => new TimelineDemoViewModel(), MenuKeys.MenuKeyTimePicker => new TimePickerDemoViewModel(), + MenuKeys.MenuKeyTimeRangePicker => new TimeRangePickerDemoViewModel(), MenuKeys.MenuKeyToast => new ToastDemoViewModel(), MenuKeys.MenuKeyToolBar => new ToolBarDemoViewModel(), MenuKeys.MenuKeyTreeComboBox => new TreeComboBoxDemoViewModel(), diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs index b044516..d1a92a4 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -53,9 +53,11 @@ public class MenuViewModel : ViewModelBase MenuHeader = "Date & Time", Children = new ObservableCollection { new() { MenuHeader = "Date Picker", Key = MenuKeys.MenuKeyDatePicker }, + new() { MenuHeader = "Date Range Picker", Key = MenuKeys.MenuKeyDateRangePicker }, new() { MenuHeader = "Date Time Picker", Key = MenuKeys.MenuKeyDateTimePicker }, new() { MenuHeader = "Time Box", Key = MenuKeys.MenuKeyTimeBox }, - new() { MenuHeader = "TimePicker", Key = MenuKeys.MenuKeyTimePicker }, + new() { MenuHeader = "Time Picker", Key = MenuKeys.MenuKeyTimePicker }, + new() { MenuHeader = "Time Range Picker", Key = MenuKeys.MenuKeyTimeRangePicker }, new() { MenuHeader = "Clock", Key = MenuKeys.MenuKeyClock } } }, @@ -108,6 +110,7 @@ public static class MenuKeys public const string MenuKeyClassInput = "Class Input"; public const string MenuKeyClock = "Clock"; public const string MenuKeyDatePicker = "DatePicker"; + public const string MenuKeyDateRangePicker = "DateRangePicker"; public const string MenuKeyDateTimePicker = "DateTimePicker"; public const string MenuKeyDialog = "Dialog"; public const string MenuKeyDisableContainer = "DisableContainer"; @@ -142,6 +145,7 @@ public static class MenuKeys public const string MenuKeyTimeBox = "TimeBox"; public const string MenuKeyTimeline = "Timeline"; public const string MenuKeyTimePicker = "TimePicker"; + public const string MenuKeyTimeRangePicker = "TimeRangePicker"; public const string MenuKeyToast = "Toast"; public const string MenuKeyToolBar = "ToolBar"; public const string MenuKeyTreeComboBox = "TreeComboBox"; diff --git a/demo/Ursa.Demo/ViewModels/TimePickerDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/TimePickerDemoViewModel.cs index 7b93e1a..fed5690 100644 --- a/demo/Ursa.Demo/ViewModels/TimePickerDemoViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/TimePickerDemoViewModel.cs @@ -6,13 +6,9 @@ namespace Ursa.Demo.ViewModels; public partial class TimePickerDemoViewModel: ObservableObject { [ObservableProperty] private TimeSpan? _time; - [ObservableProperty] private TimeSpan? _startTime; - [ObservableProperty] private TimeSpan? _endTime; - + public TimePickerDemoViewModel() { Time = new TimeSpan(12, 20, 0); - StartTime = new TimeSpan(8, 21, 0); - EndTime = new TimeSpan(18, 22, 0); } } \ No newline at end of file diff --git a/demo/Ursa.Demo/ViewModels/TimeRangePickerDemoViewModel.cs b/demo/Ursa.Demo/ViewModels/TimeRangePickerDemoViewModel.cs new file mode 100644 index 0000000..5369eaf --- /dev/null +++ b/demo/Ursa.Demo/ViewModels/TimeRangePickerDemoViewModel.cs @@ -0,0 +1,16 @@ +using System; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace Ursa.Demo.ViewModels; + +public partial class TimeRangePickerDemoViewModel: ObservableObject +{ + [ObservableProperty] private TimeSpan? _startTime; + [ObservableProperty] private TimeSpan? _endTime; + + public TimeRangePickerDemoViewModel() + { + StartTime = new TimeSpan(8, 21, 0); + EndTime = new TimeSpan(18, 22, 0); + } +} \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Controls/TimeRangePicker.axaml b/src/Ursa.Themes.Semi/Controls/TimeRangePicker.axaml index 639be37..850f505 100644 --- a/src/Ursa.Themes.Semi/Controls/TimeRangePicker.axaml +++ b/src/Ursa.Themes.Semi/Controls/TimeRangePicker.axaml @@ -70,6 +70,7 @@ Margin="8,0" Content="{DynamicResource TimePickerIconGlyph}" Focusable="False" + IsVisible="{Binding !#ClearButton.IsVisible}" Theme="{DynamicResource InnerIconButton}" /> - diff --git a/src/Ursa/Controls/DateTimePicker/TimeRangePicker.cs b/src/Ursa/Controls/DateTimePicker/TimeRangePicker.cs index 22f5236..a331bce 100644 --- a/src/Ursa/Controls/DateTimePicker/TimeRangePicker.cs +++ b/src/Ursa/Controls/DateTimePicker/TimeRangePicker.cs @@ -18,6 +18,7 @@ namespace Ursa.Controls; [TemplatePart(PART_StartPresenter, typeof(TimePickerPresenter))] [TemplatePart(PART_EndPresenter, typeof(TimePickerPresenter))] [TemplatePart(PART_Button, typeof(Button))] +[PseudoClasses(PseudoClassName.PC_Empty)] public class TimeRangePicker : TimePickerBase, IClearControl { public const string PART_StartTextBox = "PART_StartTextBox"; @@ -92,6 +93,8 @@ public class TimeRangePicker : TimePickerBase, IClearControl public void Clear() { Focus(NavigationMethod.Pointer); + SetCurrentValue(StartTimeProperty, null); + SetCurrentValue(EndTimeProperty, null); _startPresenter?.SyncTime(null); _endPresenter?.SyncTime(null); } @@ -120,10 +123,10 @@ public class TimeRangePicker : TimePickerBase, IClearControl textBox.Text = null; return; } - var date = new DateTime(1, 1, 1, time.Value.Hours, time.Value.Minutes, time.Value.Seconds); var text = date.ToString(DisplayFormat); textBox.Text = text; + PseudoClasses.Set(PseudoClassName.PC_Empty, StartTime is null && EndTime is null); } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) From d6b50ce1503e837c573aa8c7edc89bf97b43db33 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Wed, 19 Feb 2025 22:12:06 +0800 Subject: [PATCH 3/5] feat: add menu tag. --- demo/Ursa.Demo/ViewModels/MenuViewModel.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs index d1a92a4..fde221b 100644 --- a/demo/Ursa.Demo/ViewModels/MenuViewModel.cs +++ b/demo/Ursa.Demo/ViewModels/MenuViewModel.cs @@ -52,12 +52,12 @@ public class MenuViewModel : ViewModelBase { MenuHeader = "Date & Time", Children = new ObservableCollection { - new() { MenuHeader = "Date Picker", Key = MenuKeys.MenuKeyDatePicker }, - new() { MenuHeader = "Date Range Picker", Key = MenuKeys.MenuKeyDateRangePicker }, - new() { MenuHeader = "Date Time Picker", Key = MenuKeys.MenuKeyDateTimePicker }, + new() { MenuHeader = "Date Picker", Key = MenuKeys.MenuKeyDatePicker, Status = "Updated" }, + new() { MenuHeader = "Date Range Picker", Key = MenuKeys.MenuKeyDateRangePicker, Status = "Updated" }, + new() { MenuHeader = "Date Time Picker", Key = MenuKeys.MenuKeyDateTimePicker, Status = "Updated" }, new() { MenuHeader = "Time Box", Key = MenuKeys.MenuKeyTimeBox }, - new() { MenuHeader = "Time Picker", Key = MenuKeys.MenuKeyTimePicker }, - new() { MenuHeader = "Time Range Picker", Key = MenuKeys.MenuKeyTimeRangePicker }, + new() { MenuHeader = "Time Picker", Key = MenuKeys.MenuKeyTimePicker, Status = "Updated" }, + new() { MenuHeader = "Time Range Picker", Key = MenuKeys.MenuKeyTimeRangePicker, Status = "Updated" }, new() { MenuHeader = "Clock", Key = MenuKeys.MenuKeyClock } } }, From fa86d34e2be92504441a3301fe6e9d98a4c1d1c4 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Wed, 19 Feb 2025 22:28:26 +0800 Subject: [PATCH 4/5] fix: fix a ut after behavior change. --- .../Controls/DateTimePicker/DatePickerTests.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/tests/HeadlessTest.Ursa/Controls/DateTimePicker/DatePickerTests.cs b/tests/HeadlessTest.Ursa/Controls/DateTimePicker/DatePickerTests.cs index af5e41f..005e16a 100644 --- a/tests/HeadlessTest.Ursa/Controls/DateTimePicker/DatePickerTests.cs +++ b/tests/HeadlessTest.Ursa/Controls/DateTimePicker/DatePickerTests.cs @@ -270,9 +270,18 @@ public class DatePickerTests HorizontalAlignment = HorizontalAlignment.Left, VerticalAlignment = VerticalAlignment.Top }; - window.Content = picker; + var focustextBox = new TextBox(); + window.Content = new StackPanel() + { + Children = + { + picker, + focustextBox, + } + }; window.Show(); Dispatcher.UIThread.RunJobs(); + picker.Focus(); var textBox = picker.GetTemplateChildOfType(DatePicker.PART_TextBox); Dispatcher.UIThread.RunJobs(); Assert.Null(picker.SelectedDate); @@ -280,6 +289,7 @@ public class DatePickerTests Dispatcher.UIThread.RunJobs(); Assert.Equal(new DateTime(2025, 2, 18), picker.SelectedDate); textBox?.SetValue(TextBox.TextProperty, "2025-02-18-"); + focustextBox.Focus(); Dispatcher.UIThread.RunJobs(); Assert.Null(picker.SelectedDate); } From 862baea730925156ebba16d5cde3dda4d5731668 Mon Sep 17 00:00:00 2001 From: Dong Bin Date: Thu, 20 Feb 2025 02:14:21 +0800 Subject: [PATCH 5/5] misc: fix a minor issue in demo. --- demo/Ursa.Demo/Pages/DatePickerDemo.axaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/demo/Ursa.Demo/Pages/DatePickerDemo.axaml b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml index 448cbca..ffbd131 100644 --- a/demo/Ursa.Demo/Pages/DatePickerDemo.axaml +++ b/demo/Ursa.Demo/Pages/DatePickerDemo.axaml @@ -11,7 +11,7 @@ x:DataType="viewModels:DatePickerDemoViewModel" mc:Ignorable="d"> - +