diff --git a/Ursa.sln b/Ursa.sln index a7328fd..8e0c259 100644 --- a/Ursa.sln +++ b/Ursa.sln @@ -26,6 +26,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Files", "Solution demo\Directory.Build.props = demo\Directory.Build.props EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandbox", "demo\Sandbox\Sandbox.csproj", "{1E94BAFD-867E-425F-8E12-7F416D523C94}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -68,6 +70,10 @@ Global {F99B3D07-4560-4B05-892C-0FF2757FEF2E}.Debug|Any CPU.Build.0 = Debug|Any CPU {F99B3D07-4560-4B05-892C-0FF2757FEF2E}.Release|Any CPU.ActiveCfg = Release|Any CPU {F99B3D07-4560-4B05-892C-0FF2757FEF2E}.Release|Any CPU.Build.0 = Release|Any CPU + {1E94BAFD-867E-425F-8E12-7F416D523C94}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1E94BAFD-867E-425F-8E12-7F416D523C94}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1E94BAFD-867E-425F-8E12-7F416D523C94}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1E94BAFD-867E-425F-8E12-7F416D523C94}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(NestedProjects) = preSolution {407A91FD-A88B-459B-8DCE-8C6AA98279FE} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66} @@ -76,5 +82,6 @@ Global {94C2BBD9-8B57-4AE9-AAFD-7D4335B15A8E} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66} {D1942476-8473-4608-BB9F-5AC01083BBDA} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66} {F99B3D07-4560-4B05-892C-0FF2757FEF2E} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66} + {1E94BAFD-867E-425F-8E12-7F416D523C94} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66} EndGlobalSection EndGlobal diff --git a/demo/Directory.Build.props b/demo/Directory.Build.props index 4832db9..d93f9fc 100644 --- a/demo/Directory.Build.props +++ b/demo/Directory.Build.props @@ -1,6 +1,6 @@ enable - 11.1.0-rc2 + 11.1.1 diff --git a/demo/Sandbox/App.axaml b/demo/Sandbox/App.axaml new file mode 100644 index 0000000..0652fc9 --- /dev/null +++ b/demo/Sandbox/App.axaml @@ -0,0 +1,19 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/demo/Sandbox/App.axaml.cs b/demo/Sandbox/App.axaml.cs new file mode 100644 index 0000000..c6033ba --- /dev/null +++ b/demo/Sandbox/App.axaml.cs @@ -0,0 +1,33 @@ +using Avalonia; +using Avalonia.Controls.ApplicationLifetimes; +using Avalonia.Data.Core; +using Avalonia.Data.Core.Plugins; +using Avalonia.Markup.Xaml; +using Sandbox.ViewModels; +using Sandbox.Views; + +namespace Sandbox; + +public partial class App : Application +{ + public override void Initialize() + { + AvaloniaXamlLoader.Load(this); + } + + public override void OnFrameworkInitializationCompleted() + { + if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop) + { + // Line below is needed to remove Avalonia data validation. + // Without this line you will get duplicate validations from both Avalonia and CT + BindingPlugins.DataValidators.RemoveAt(0); + desktop.MainWindow = new MainWindow + { + DataContext = new MainWindowViewModel(), + }; + } + + base.OnFrameworkInitializationCompleted(); + } +} \ No newline at end of file diff --git a/demo/Sandbox/Assets/avalonia-logo.ico b/demo/Sandbox/Assets/avalonia-logo.ico new file mode 100644 index 0000000..da8d49f Binary files /dev/null and b/demo/Sandbox/Assets/avalonia-logo.ico differ diff --git a/demo/Sandbox/Program.cs b/demo/Sandbox/Program.cs new file mode 100644 index 0000000..a63c30c --- /dev/null +++ b/demo/Sandbox/Program.cs @@ -0,0 +1,20 @@ +using Avalonia; +using System; + +namespace Sandbox; + +sealed class Program +{ + // Initialization code. Don't use any Avalonia, third-party APIs or any + // SynchronizationContext-reliant code before AppMain is called: things aren't initialized + // yet and stuff might break. + [STAThread] + public static void Main(string[] args) => BuildAvaloniaApp() + .StartWithClassicDesktopLifetime(args); + + // Avalonia configuration, don't remove; also used by visual designer. + public static AppBuilder BuildAvaloniaApp() + => AppBuilder.Configure() + .UsePlatformDetect() + .LogToTrace(); +} \ No newline at end of file diff --git a/demo/Sandbox/Sandbox.csproj b/demo/Sandbox/Sandbox.csproj new file mode 100644 index 0000000..dac917c --- /dev/null +++ b/demo/Sandbox/Sandbox.csproj @@ -0,0 +1,30 @@ + + + WinExe + net8.0 + enable + true + app.manifest + true + + + + + + + + + + + + + + + + + + + + + + diff --git a/demo/Sandbox/ViewLocator.cs b/demo/Sandbox/ViewLocator.cs new file mode 100644 index 0000000..e99b34b --- /dev/null +++ b/demo/Sandbox/ViewLocator.cs @@ -0,0 +1,32 @@ +using System; +using Avalonia.Controls; +using Avalonia.Controls.Templates; +using Sandbox.ViewModels; + +namespace Sandbox; + +public class ViewLocator : IDataTemplate +{ + public Control? Build(object? data) + { + if (data is null) + return null; + + var name = data.GetType().FullName!.Replace("ViewModel", "View", StringComparison.Ordinal); + var type = Type.GetType(name); + + if (type != null) + { + var control = (Control)Activator.CreateInstance(type)!; + control.DataContext = data; + return control; + } + + return new TextBlock { Text = "Not Found: " + name }; + } + + public bool Match(object? data) + { + return data is ViewModelBase; + } +} \ No newline at end of file diff --git a/demo/Sandbox/ViewModels/MainWindowViewModel.cs b/demo/Sandbox/ViewModels/MainWindowViewModel.cs new file mode 100644 index 0000000..d7998a1 --- /dev/null +++ b/demo/Sandbox/ViewModels/MainWindowViewModel.cs @@ -0,0 +1,30 @@ +using System.Collections.ObjectModel; +using System.Net; + +namespace Sandbox.ViewModels; + +public partial class MainWindowViewModel : ViewModelBase +{ + public ObservableCollection Items { get; set; } + + public MainWindowViewModel() + { + Items = new ObservableCollection() + { + new DataGridItem() { Name = "John Doe", Age = 42 }, + new DataGridItem() { Name = "Jane Doe", Age = 39 }, + new DataGridItem() { Name = "Sammy Doe", Age = 13 }, + new DataGridItem() { Name = "Barry Doe", Age = 7 }, + new DataGridItem() { Name = "Molly Doe", Age = 5 }, + }; + } + + +} + +public class DataGridItem +{ + public string? Name { get; set; } + public int Age { get; set; } + public IPAddress? Address { get; set; } +} \ No newline at end of file diff --git a/demo/Sandbox/ViewModels/ViewModelBase.cs b/demo/Sandbox/ViewModels/ViewModelBase.cs new file mode 100644 index 0000000..a7f267e --- /dev/null +++ b/demo/Sandbox/ViewModels/ViewModelBase.cs @@ -0,0 +1,7 @@ +using CommunityToolkit.Mvvm.ComponentModel; + +namespace Sandbox.ViewModels; + +public class ViewModelBase : ObservableObject +{ +} \ No newline at end of file diff --git a/demo/Sandbox/Views/MainWindow.axaml b/demo/Sandbox/Views/MainWindow.axaml new file mode 100644 index 0000000..ba61022 --- /dev/null +++ b/demo/Sandbox/Views/MainWindow.axaml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demo/Sandbox/Views/MainWindow.axaml.cs b/demo/Sandbox/Views/MainWindow.axaml.cs new file mode 100644 index 0000000..7430fad --- /dev/null +++ b/demo/Sandbox/Views/MainWindow.axaml.cs @@ -0,0 +1,11 @@ +using Avalonia.Controls; + +namespace Sandbox.Views; + +public partial class MainWindow : Window +{ + public MainWindow() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Sandbox/app.manifest b/demo/Sandbox/app.manifest new file mode 100644 index 0000000..e3ab431 --- /dev/null +++ b/demo/Sandbox/app.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Ursa.Demo.csproj b/demo/Ursa.Demo/Ursa.Demo.csproj index 6631379..2a2c8a8 100644 --- a/demo/Ursa.Demo/Ursa.Demo.csproj +++ b/demo/Ursa.Demo/Ursa.Demo.csproj @@ -19,7 +19,7 @@ - + diff --git a/src/Package.props b/src/Package.props index de51260..6cce184 100644 --- a/src/Package.props +++ b/src/Package.props @@ -1,5 +1,5 @@ - 11.1.0-rc2 + 11.1.1 \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Controls/IPv4Box.axaml b/src/Ursa.Themes.Semi/Controls/IPv4Box.axaml index ff98e38..4cd290f 100644 --- a/src/Ursa.Themes.Semi/Controls/IPv4Box.axaml +++ b/src/Ursa.Themes.Semi/Controls/IPv4Box.axaml @@ -42,6 +42,7 @@ + gestures) => gestures.Any(g => g.Matches(e)); if (e.Key is Key.Enter or Key.Return) @@ -141,25 +145,36 @@ public class IPv4Box: TemplatedControl ParseBytes(ShowLeadingZero); SetIPAddressInternal(); base.OnKeyDown(e); + e.Handled = true; return; } if (keymap is not null && Match(keymap.SelectAll)) { _currentActivePresenter.SelectionStart = 0; _currentActivePresenter.SelectionEnd = _currentActivePresenter.Text?.Length ?? 0; + e.Handled = true; return; } - else if (keymap is not null && Match(keymap.Copy)) + + if (keymap is not null && Match(keymap.Copy)) { Copy(); + e.Handled = true; + return; } - else if (keymap is not null && Match(keymap.Paste)) + + if (keymap is not null && Match(keymap.Paste)) { Paste(); + e.Handled = true; + return; } - else if (keymap is not null && Match(keymap.Cut)) + + if (keymap is not null && Match(keymap.Cut)) { Cut(); + e.Handled = true; + return; } if (e.Key == Key.Tab) { @@ -173,23 +188,30 @@ public class IPv4Box: TemplatedControl MoveToNextPresenter(_currentActivePresenter, true); _currentActivePresenter?.ShowCaret(); e.Handled = true; + return; } - else if (e.Key == Key.Back) + + if (e.Key == Key.Back) { DeleteImplementation(_currentActivePresenter); + e.Handled = true; + return; } - else if (e.Key == Key.Right ) + + if (e.Key == Key.Right ) { OnPressRightKey(); + e.Handled = true; + return; } - else if (e.Key == Key.Left) + + if (e.Key == Key.Left) { OnPressLeftKey(); + e.Handled = true; + return; } - else - { - base.OnKeyDown(e); - } + base.OnKeyDown(e); } protected override void OnTextInput(TextInputEventArgs e) @@ -201,9 +223,11 @@ public class IPv4Box: TemplatedControl { _currentActivePresenter?.HideCaret(); _currentActivePresenter.ClearSelection(); - MoveToNextPresenter(_currentActivePresenter, false); - _currentActivePresenter?.ShowCaret(); - _currentActivePresenter.MoveCaretToStart(); + if (MoveToNextPresenter(_currentActivePresenter, false)) + { + _currentActivePresenter?.ShowCaret(); + _currentActivePresenter.MoveCaretToStart(); + } e.Handled = false; return; } @@ -274,6 +298,7 @@ public class IPv4Box: TemplatedControl } } base.OnPointerPressed(e); + e.Handled = true; } protected override void OnLostFocus(RoutedEventArgs e)