diff --git a/README.md b/README.md index b9f27a1..3950ab0 100644 --- a/README.md +++ b/README.md @@ -6,12 +6,14 @@ Ursa is a UI library for building cross-platform UIs with Avalonia UI. +![Demo](./assets/demo.png) + ## How to use 1. Ursa Add nuget package: ```bash -dotnet add package Irihi.Ursa --version 0.1.0-beta20230702 +dotnet add package Irihi.Ursa --version 0.2.0-beta20240129 ``` You can now use Ursa controls in your Avalonia Application. @@ -39,14 +41,18 @@ Ursa.Themes.Semi is a theme package for Ursa inspired by Semi Design. You can ad Add nuget package: ```bash -dotnet add package Semi.Avalonia --version 11.0.0-rc1 -dotnet add package Irihi.Ursa.Themes.Semi --version 0.1.0-beta20230702 +dotnet add package Semi.Avalonia --version 11.0.7 +dotnet add package Irihi.Ursa.Themes.Semi --version 0.2.0-beta20240129 ``` Include Styles in application: ```xaml + + - + -``` \ No newline at end of file +``` diff --git a/Ursa.sln b/Ursa.sln index 9b2953a..d46008b 100644 --- a/Ursa.sln +++ b/Ursa.sln @@ -16,6 +16,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.Demo.iOS", "demo\Ursa. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.Demo.Browser", "demo\Ursa.Demo.Browser\Ursa.Demo.Browser.csproj", "{D1942476-8473-4608-BB9F-5AC01083BBDA}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.PrismExtension", "src\Ursa.PrismExtension\Ursa.PrismExtension.csproj", "{2E934F60-F5DF-4856-B05A-B949C7F9D948}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Ursa.PrismDialogDemo", "demo\Ursa.PrismDialogDemo\Ursa.PrismDialogDemo.csproj", "{F99B3D07-4560-4B05-892C-0FF2757FEF2E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -50,6 +54,14 @@ Global {D1942476-8473-4608-BB9F-5AC01083BBDA}.Debug|Any CPU.Build.0 = Debug|Any CPU {D1942476-8473-4608-BB9F-5AC01083BBDA}.Release|Any CPU.ActiveCfg = Release|Any CPU {D1942476-8473-4608-BB9F-5AC01083BBDA}.Release|Any CPU.Build.0 = Release|Any CPU + {2E934F60-F5DF-4856-B05A-B949C7F9D948}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2E934F60-F5DF-4856-B05A-B949C7F9D948}.Debug|Any CPU.Build.0 = Debug|Any CPU + {2E934F60-F5DF-4856-B05A-B949C7F9D948}.Release|Any CPU.ActiveCfg = Release|Any CPU + {2E934F60-F5DF-4856-B05A-B949C7F9D948}.Release|Any CPU.Build.0 = Release|Any CPU + {F99B3D07-4560-4B05-892C-0FF2757FEF2E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {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 EndGlobalSection GlobalSection(NestedProjects) = preSolution {407A91FD-A88B-459B-8DCE-8C6AA98279FE} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66} @@ -57,5 +69,6 @@ Global {B6BAB821-A9FE-44F3-B9CD-06E27FDB63F6} = {A41BAF0D-DA61-4A63-889A-084BAD36FD66} {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} EndGlobalSection EndGlobal diff --git a/assets/demo.png b/assets/demo.png new file mode 100644 index 0000000..8bee762 Binary files /dev/null and b/assets/demo.png differ diff --git a/demo/Directory.Build.props b/demo/Directory.Build.props index ae8bdf5..c950d6a 100644 --- a/demo/Directory.Build.props +++ b/demo/Directory.Build.props @@ -1,6 +1,6 @@ enable - 11.0.0 + 11.0.9 diff --git a/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj b/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj index 3d3f388..64e44ce 100644 --- a/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj +++ b/demo/Ursa.Demo.Desktop/Ursa.Demo.Desktop.csproj @@ -6,6 +6,7 @@ net7.0 enable true + false diff --git a/demo/Ursa.Demo/App.axaml b/demo/Ursa.Demo/App.axaml index 8326f56..abf9048 100644 --- a/demo/Ursa.Demo/App.axaml +++ b/demo/Ursa.Demo/App.axaml @@ -1,9 +1,10 @@ + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" + xmlns:u-semi="https://irihi.tech/ursa/themes/semi"> - + \ No newline at end of file diff --git a/demo/Ursa.Demo/Assets/IRIHI.png b/demo/Ursa.Demo/Assets/IRIHI.png new file mode 100644 index 0000000..3f405aa Binary files /dev/null and b/demo/Ursa.Demo/Assets/IRIHI.png differ diff --git a/demo/Ursa.Demo/Assets/WORLD.png b/demo/Ursa.Demo/Assets/WORLD.png new file mode 100644 index 0000000..7c5b71f Binary files /dev/null and b/demo/Ursa.Demo/Assets/WORLD.png differ diff --git a/demo/Ursa.Demo/Converters/IconNameToPathConverter.cs b/demo/Ursa.Demo/Converters/IconNameToPathConverter.cs new file mode 100644 index 0000000..4451895 --- /dev/null +++ b/demo/Ursa.Demo/Converters/IconNameToPathConverter.cs @@ -0,0 +1,42 @@ +using System; +using System.Globalization; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Data.Converters; +using Avalonia.Media; + +namespace Ursa.Demo.Converters; + +public class IconNameToPathConverter: IValueConverter +{ + private string[] paths = new[] + { + "M12,4A4,4 0 0,1 16,8A4,4 0 0,1 12,12A4,4 0 0,1 8,8A4,4 0 0,1 12,4M12,14C16.42,14 20,15.79 20,18V20H4V18C4,15.79 7.58,14 12,14Z", + "M16 12L9 2L2 12H3.86L0 18H7V22H11V18H18L14.14 12H16M20.14 12H22L15 2L12.61 5.41L17.92 13H15.97L19.19 18H24L20.14 12M13 19H17V22H13V19Z", + "M15,9H5V5H15M12,19A3,3 0 0,1 9,16A3,3 0 0,1 12,13A3,3 0 0,1 15,16A3,3 0 0,1 12,19M17,3H5C3.89,3 3,3.9 3,5V19A2,2 0 0,0 5,21H19A2,2 0 0,0 21,19V7L17,3Z", + "M5 21C3.9 21 3 20.1 3 19V5C3 3.9 3.9 3 5 3H19C20.1 3 21 3.9 21 5V19C21 20.1 20.1 21 19 21H5M15.3 16L13.2 13.9L17 10L14.2 7.2L10.4 11.1L8.2 8.9V16H15.3Z", + "M16,9V7H12V12.5C11.58,12.19 11.07,12 10.5,12A2.5,2.5 0 0,0 8,14.5A2.5,2.5 0 0,0 10.5,17A2.5,2.5 0 0,0 13,14.5V9H16M12,2A10,10 0 0,1 22,12A10,10 0 0,1 12,22A10,10 0 0,1 2,12A10,10 0 0,1 12,2Z", + "M16.67,4H15V2H9V4H7.33A1.33,1.33 0 0,0 6,5.33V20.67C6,21.4 6.6,22 7.33,22H16.67A1.33,1.33 0 0,0 18,20.67V5.33C18,4.6 17.4,4 16.67,4Z", + "M12 2C6.5 2 2 6.5 2 12C2 17.5 6.5 22 12 22C17.5 22 22 17.5 22 12S17.5 2 12 2M12.5 13H11V7H12.5V11.3L16.2 9.2L17 10.5L12.5 13Z" + }; + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is int i) + { + string s = paths[i % paths.Length]; + return StreamGeometry.Parse(s); + } + else if (value is string s) + { + int hash = s.GetHashCode(); + string path = paths[Math.Abs(hash) % paths.Length]; + return StreamGeometry.Parse(path); + } + return AvaloniaProperty.UnsetValue; + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + return AvaloniaProperty.UnsetValue; + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Converters/TimelineIconConverter.cs b/demo/Ursa.Demo/Converters/TimelineIconConverter.cs new file mode 100644 index 0000000..04d46f4 --- /dev/null +++ b/demo/Ursa.Demo/Converters/TimelineIconConverter.cs @@ -0,0 +1,32 @@ +using System; +using System.Globalization; +using Avalonia; +using Avalonia.Data; +using Avalonia.Data.Converters; +using Avalonia.Media; +using Ursa.Controls; + +namespace Ursa.Demo.Converters; + +public class TimelineIconConverter: IValueConverter +{ + public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture) + { + if (value is TimelineItemType t) + { + return t switch + { + TimelineItemType.Success => Brushes.Green, + TimelineItemType.Ongoing => Brushes.Blue, + TimelineItemType.Error => Brushes.Red, + _ => Brushes.Gray + }; + } + return AvaloniaProperty.UnsetValue; + } + + public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Converters/MenuDataTemplateSelector.cs b/demo/Ursa.Demo/DataTemplates/MenuDataTemplateSelector.cs similarity index 100% rename from demo/Ursa.Demo/Converters/MenuDataTemplateSelector.cs rename to demo/Ursa.Demo/DataTemplates/MenuDataTemplateSelector.cs diff --git a/demo/Ursa.Demo/DataTemplates/ToolBarItemTemplateSelector.cs b/demo/Ursa.Demo/DataTemplates/ToolBarItemTemplateSelector.cs new file mode 100644 index 0000000..bfd9c76 --- /dev/null +++ b/demo/Ursa.Demo/DataTemplates/ToolBarItemTemplateSelector.cs @@ -0,0 +1,56 @@ +using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Controls.Templates; +using Avalonia.Data; +using Ursa.Controls; +using Ursa.Demo.ViewModels; + +namespace Ursa.Demo.Converters; + +public class ToolBarItemTemplateSelector: IDataTemplate +{ + + public static ToolBarItemTemplateSelector Instance { get; } = new(); + public Control? Build(object? param) + { + if (param is null) return null; + if (param is ToolBarSeparatorViewModel sep) + { + return new ToolBarSeparator(); + } + if (param is ToolBarButtonItemViewModel vm) + { + return new Button() + { + [!ContentControl.ContentProperty] = new Binding() { Path = "Content" }, + [!Button.CommandProperty] = new Binding() { Path = "Command" }, + [!ToolBar.OverflowModeProperty] = new Binding(){Path = nameof(ToolBarItemViewModel.OverflowMode)}, + }; + } + if (param is ToolBarCheckBoxItemViweModel cb) + { + return new CheckBox() + { + [!ContentControl.ContentProperty] = new Binding() { Path = "Content" }, + [!ToggleButton.IsCheckedProperty] = new Binding() { Path = "IsChecked" }, + [!ToolBar.OverflowModeProperty] = new Binding(){Path = nameof(ToolBarItemViewModel.OverflowMode)}, + }; + } + if (param is ToolBarComboBoxItemViewModel combo) + { + return new ComboBox() + { + [!ContentControl.ContentProperty] = new Binding() { Path = "Content" }, + [!SelectingItemsControl.SelectedItemProperty] = new Binding() { Path = "SelectedItem" }, + [!ItemsControl.ItemsSourceProperty] = new Binding() { Path = "Items" }, + [!ToolBar.OverflowModeProperty] = new Binding(){Path = nameof(ToolBarItemViewModel.OverflowMode)}, + }; + } + return new Button() { Content = "Undefined Item" }; + } + + public bool Match(object? data) + { + return data is ToolBarItemViewModel; + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Converters/ViewLocator.cs b/demo/Ursa.Demo/DataTemplates/ViewLocator.cs similarity index 100% rename from demo/Ursa.Demo/Converters/ViewLocator.cs rename to demo/Ursa.Demo/DataTemplates/ViewLocator.cs diff --git a/demo/Ursa.Demo/Dialogs/DialogWithAction.axaml b/demo/Ursa.Demo/Dialogs/DialogWithAction.axaml new file mode 100644 index 0000000..4132581 --- /dev/null +++ b/demo/Ursa.Demo/Dialogs/DialogWithAction.axaml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/DisableContainerDemo.axaml.cs b/demo/Ursa.Demo/Pages/DisableContainerDemo.axaml.cs new file mode 100644 index 0000000..68b6fbd --- /dev/null +++ b/demo/Ursa.Demo/Pages/DisableContainerDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class DisableContainerDemo : UserControl +{ + public DisableContainerDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/DrawerDemo.axaml b/demo/Ursa.Demo/Pages/DrawerDemo.axaml new file mode 100644 index 0000000..c613b4e --- /dev/null +++ b/demo/Ursa.Demo/Pages/DrawerDemo.axaml @@ -0,0 +1,99 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/NavMenuDemo.axaml.cs b/demo/Ursa.Demo/Pages/NavMenuDemo.axaml.cs new file mode 100644 index 0000000..eac27af --- /dev/null +++ b/demo/Ursa.Demo/Pages/NavMenuDemo.axaml.cs @@ -0,0 +1,27 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Shapes; +using Avalonia.Input; +using Avalonia.LogicalTree; +using Avalonia.Markup.Xaml; +using Ursa.Demo.ViewModels; + +namespace Ursa.Demo.Pages; + +public partial class NavMenuDemo : UserControl +{ + public NavMenuDemo() + { + InitializeComponent(); + this.DataContext = new NavMenuDemoViewModel(); + } + + private void InputElement_OnPointerPressed(object? sender, PointerPressedEventArgs e) + { + if (sender is Rectangle c) + { + c.ApplyStyling(); + var ancestors = c.GetLogicalAncestors(); + } + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/NavigationMenuDemo.axaml b/demo/Ursa.Demo/Pages/NavigationMenuDemo.axaml deleted file mode 100644 index 651c3e8..0000000 --- a/demo/Ursa.Demo/Pages/NavigationMenuDemo.axaml +++ /dev/null @@ -1,66 +0,0 @@ - - - - M12 16C13.9818 16 15.7453 14.3394 16.7142 11.8589C17.3163 11.6122 17.8892 10.8644 18.1508 9.88823C18.4909 8.61881 18.4234 7.48536 17.4964 7.13266C17.4064 2.7111 15.6617 1 12 1C8.33858 1 6.59387 2.71088 6.50372 7.13179C5.57454 7.48354 5.50668 8.61777 5.84709 9.8882C6.10904 10.8658 6.68318 11.6143 7.28626 11.8599C8.2552 14.3398 10.0186 16 12 16Z M19.6049 22C20.8385 22 21.7171 20.8487 20.867 19.9547C19.1971 18.1985 15.853 17 12 17C8.14699 17 4.80292 18.1985 3.133 19.9547C2.2829 20.8487 3.16148 22 4.39513 22H19.6049Z - M10.7525 1.90411C11.1451 0.698628 12.8549 0.698631 13.2475 1.90411L15.2395 8.01946H21.6858C22.9565 8.01946 23.4848 9.64143 22.4568 10.3865L17.2417 14.1659L19.2337 20.2813C19.6263 21.4868 18.2431 22.4892 17.2151 21.7442L12 17.9647L6.78489 21.7442C5.75687 22.4892 4.37368 21.4868 4.76635 20.2813L6.75834 14.1659L1.54323 10.3865C0.515206 9.64142 1.04354 8.01946 2.31425 8.01946H8.76048L10.7525 1.90411Z - M7.99973 5.07197C7.19713 5.53535 6.20729 5.53113 5.40866 5.06092L5.1637 4.91669C4.55751 4.55978 3.77662 4.65563 3.34264 5.20927C2.69567 6.03462 2.17585 6.94251 1.79166 7.90124C1.53027 8.55354 1.83733 9.27693 2.449 9.62286L2.69407 9.76145C3.50107 10.2178 4.00002 11.0732 4.00002 12.0003C4.00002 12.9271 3.50145 13.7822 2.69492 14.2387L2.44842 14.3783C1.83596 14.725 1.52888 15.4497 1.79213 16.1024C1.98358 16.577 2.21048 17.044 2.47374 17.5C2.73723 17.9564 3.0285 18.3868 3.34416 18.7902C3.77773 19.3443 4.5588 19.4406 5.16498 19.0834L5.40839 18.9399C6.20714 18.4692 7.19739 18.4648 8.0003 18.9284C8.80291 19.3918 9.29417 20.2511 9.28627 21.1778L9.28386 21.4601C9.27787 22.1629 9.75107 22.7906 10.4468 22.8903C11.4692 23.0368 12.5154 23.0404 13.5537 22.8927C14.2499 22.7936 14.7231 22.1653 14.7169 21.462L14.7143 21.1785C14.7061 20.2514 15.1974 19.3916 16.0003 18.928C16.8029 18.4647 17.7927 18.4689 18.5914 18.9391L18.8363 19.0833C19.4425 19.4402 20.2234 19.3444 20.6574 18.7907C21.3044 17.9654 21.8242 17.0575 22.2084 16.0988C22.4698 15.4465 22.1627 14.7231 21.551 14.3772L21.306 14.2386C20.499 13.7822 20 12.9268 20 11.9997C20 11.0729 20.4986 10.2178 21.3051 9.76126L21.5516 9.62174C22.1641 9.27506 22.4712 8.55029 22.2079 7.89761C22.0165 7.42297 21.7896 6.95598 21.5263 6.50001C21.2628 6.04362 20.9715 5.61325 20.6559 5.20982C20.2223 4.65568 19.4412 4.55944 18.8351 4.91665L18.5916 5.06009C17.7929 5.53078 16.8026 5.53519 15.9997 5.07163C15.1971 4.60825 14.7059 3.74891 14.7138 2.82218L14.7162 2.53994C14.7222 1.83708 14.249 1.20945 13.5532 1.10973C12.5308 0.963214 11.4846 0.959581 10.4464 1.10733C9.75011 1.20641 9.27691 1.83473 9.28317 2.53798L9.28569 2.82154C9.29395 3.74862 8.80264 4.60841 7.99973 5.07197ZM14 15.4641C15.9132 14.3595 16.5687 11.9132 15.4641 9.99999C14.3595 8.08682 11.9132 7.43132 10 8.53589C8.08684 9.64046 7.43134 12.0868 8.53591 14C9.64048 15.9132 12.0868 16.5687 14 15.4641Z - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/demo/Ursa.Demo/Pages/NumberDisplayerDemo.axaml b/demo/Ursa.Demo/Pages/NumberDisplayerDemo.axaml new file mode 100644 index 0000000..c550a8c --- /dev/null +++ b/demo/Ursa.Demo/Pages/NumberDisplayerDemo.axaml @@ -0,0 +1,31 @@ + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/NumberDisplayerDemo.axaml.cs b/demo/Ursa.Demo/Pages/NumberDisplayerDemo.axaml.cs new file mode 100644 index 0000000..35df3ef --- /dev/null +++ b/demo/Ursa.Demo/Pages/NumberDisplayerDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class NumberDisplayerDemo : UserControl +{ + public NumberDisplayerDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/NumericUpDownDemo.axaml b/demo/Ursa.Demo/Pages/NumericUpDownDemo.axaml new file mode 100644 index 0000000..afe4496 --- /dev/null +++ b/demo/Ursa.Demo/Pages/NumericUpDownDemo.axaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/NumericUpDownDemo.axaml.cs b/demo/Ursa.Demo/Pages/NumericUpDownDemo.axaml.cs new file mode 100644 index 0000000..4bdf06d --- /dev/null +++ b/demo/Ursa.Demo/Pages/NumericUpDownDemo.axaml.cs @@ -0,0 +1,15 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; +using Ursa.Demo.ViewModels; + +namespace Ursa.Demo.Pages; + +public partial class NumericUpDownDemo : UserControl +{ + public NumericUpDownDemo() + { + InitializeComponent(); + DataContext = new NumericUpDownDemoViewModel(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/RangeSliderDemo.axaml b/demo/Ursa.Demo/Pages/RangeSliderDemo.axaml new file mode 100644 index 0000000..7aa427b --- /dev/null +++ b/demo/Ursa.Demo/Pages/RangeSliderDemo.axaml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/NavigationMenuDemo.axaml.cs b/demo/Ursa.Demo/Pages/RangeSliderDemo.axaml.cs similarity index 53% rename from demo/Ursa.Demo/Pages/NavigationMenuDemo.axaml.cs rename to demo/Ursa.Demo/Pages/RangeSliderDemo.axaml.cs index 0f369fc..fe3181d 100644 --- a/demo/Ursa.Demo/Pages/NavigationMenuDemo.axaml.cs +++ b/demo/Ursa.Demo/Pages/RangeSliderDemo.axaml.cs @@ -5,11 +5,11 @@ using Ursa.Demo.ViewModels; namespace Ursa.Demo.Pages; -public partial class NavigationMenuDemo : UserControl +public partial class RangeSliderDemo : UserControl { - public NavigationMenuDemo() + public RangeSliderDemo() { InitializeComponent(); - this.DataContext = new NavigationMenuDemoViewModel(); + this.DataContext = new RangeSliderDemoViewModel(); } } \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/SelectionBoxDemo.axaml b/demo/Ursa.Demo/Pages/SelectionBoxDemo.axaml new file mode 100644 index 0000000..18068cf --- /dev/null +++ b/demo/Ursa.Demo/Pages/SelectionBoxDemo.axaml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/SelectionBoxDemo.axaml.cs b/demo/Ursa.Demo/Pages/SelectionBoxDemo.axaml.cs new file mode 100644 index 0000000..60d5ccd --- /dev/null +++ b/demo/Ursa.Demo/Pages/SelectionBoxDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class SelectionListDemo : UserControl +{ + public SelectionListDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/TagInputDemo.axaml b/demo/Ursa.Demo/Pages/TagInputDemo.axaml index 822f316..fc94f33 100644 --- a/demo/Ursa.Demo/Pages/TagInputDemo.axaml +++ b/demo/Ursa.Demo/Pages/TagInputDemo.axaml @@ -5,6 +5,9 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:u="https://irihi.tech/ursa" + xmlns:vm="using:Ursa.Demo.ViewModels" + x:DataType="vm:TagInputDemoViewModel" + x:CompileBindings="True" d:DesignHeight="450" d:DesignWidth="800" mc:Ignorable="d"> @@ -12,14 +15,14 @@ - + Tags="{Binding DistinctTags}" /> + diff --git a/demo/Ursa.Demo/Pages/ThemeTogglerDemo.axaml b/demo/Ursa.Demo/Pages/ThemeTogglerDemo.axaml new file mode 100644 index 0000000..021c289 --- /dev/null +++ b/demo/Ursa.Demo/Pages/ThemeTogglerDemo.axaml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/ThemeTogglerDemo.axaml.cs b/demo/Ursa.Demo/Pages/ThemeTogglerDemo.axaml.cs new file mode 100644 index 0000000..a8e48c6 --- /dev/null +++ b/demo/Ursa.Demo/Pages/ThemeTogglerDemo.axaml.cs @@ -0,0 +1,13 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace Ursa.Demo.Pages; + +public partial class ThemeTogglerDemo : UserControl +{ + public ThemeTogglerDemo() + { + InitializeComponent(); + } +} \ No newline at end of file diff --git a/demo/Ursa.Demo/Pages/TimelineDemo.axaml b/demo/Ursa.Demo/Pages/TimelineDemo.axaml index b217fad..262ac3e 100644 --- a/demo/Ursa.Demo/Pages/TimelineDemo.axaml +++ b/demo/Ursa.Demo/Pages/TimelineDemo.axaml @@ -4,55 +4,84 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" + xmlns:selectors="clr-namespace:Ursa.Demo.TemplateSelectors" xmlns:u="https://irihi.tech/ursa" xmlns:viewModels="clr-namespace:Ursa.Demo.ViewModels" d:DesignHeight="450" d:DesignWidth="800" - x:CompileBindings="False" + x:CompileBindings="True" x:DataType="viewModels:TimelineDemoViewModel" mc:Ignorable="d"> - + + + + + + + + + - - - - - - + + + - - - - - - - - - - - - + - + + + + + + + + + + diff --git a/demo/Ursa.Demo/Pages/ToolBarDemo.axaml b/demo/Ursa.Demo/Pages/ToolBarDemo.axaml new file mode 100644 index 0000000..b00fc45 --- /dev/null +++ b/demo/Ursa.Demo/Pages/ToolBarDemo.axaml @@ -0,0 +1,136 @@ + + + + M13.5,15.5H10V12.5H13.5A1.5,1.5 0 0,1 15,14A1.5,1.5 0 0,1 13.5,15.5M10,6.5H13A1.5,1.5 0 0,1 14.5,8A1.5,1.5 0 0,1 13,9.5H10M15.6,10.79C16.57,10.11 17.25,9 17.25,8C17.25,5.74 15.5,4 13.25,4H7V18H14.04C16.14,18 17.75,16.3 17.75,14.21C17.75,12.69 16.89,11.39 15.6,10.79Z + M10,4V7H12.21L8.79,15H6V18H14V15H11.79L15.21,7H18V4H10Z + + + + + + + + + + + diff --git a/demo/Ursa.PrismDialogDemo/MainWindow.axaml.cs b/demo/Ursa.PrismDialogDemo/MainWindow.axaml.cs new file mode 100644 index 0000000..1b51033 --- /dev/null +++ b/demo/Ursa.PrismDialogDemo/MainWindow.axaml.cs @@ -0,0 +1,28 @@ +using Avalonia.Controls; +using Avalonia.Interactivity; +using DryIoc; +using Ursa.PrismExtension; + +namespace Ursa.PrismDialogDemo; + +public partial class MainWindow : Window +{ + private IUrsaOverlayDialogService _dialogService; + private IUrsaDrawerService _drawerService; + public MainWindow(IUrsaOverlayDialogService dialogService, IUrsaDrawerService drawerService) + { + InitializeComponent(); + _dialogService = dialogService; + _drawerService = drawerService; + } + + private void DialogButton_OnClick(object? sender, RoutedEventArgs e) + { + _dialogService.ShowModal("Default", null, null, null); + } + + private void DrawerButton_OnClick(object? sender, RoutedEventArgs e) + { + _drawerService.ShowModal("Default", null, null, null); + } +} \ No newline at end of file diff --git a/demo/Ursa.PrismDialogDemo/Program.cs b/demo/Ursa.PrismDialogDemo/Program.cs new file mode 100644 index 0000000..7d86295 --- /dev/null +++ b/demo/Ursa.PrismDialogDemo/Program.cs @@ -0,0 +1,21 @@ +using Avalonia; +using System; + +namespace Ursa.PrismDialogDemo; + +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() + .WithInterFont() + .LogToTrace(); +} \ No newline at end of file diff --git a/demo/Ursa.PrismDialogDemo/Ursa.PrismDialogDemo.csproj b/demo/Ursa.PrismDialogDemo/Ursa.PrismDialogDemo.csproj new file mode 100644 index 0000000..2d2c855 --- /dev/null +++ b/demo/Ursa.PrismDialogDemo/Ursa.PrismDialogDemo.csproj @@ -0,0 +1,28 @@ + + + WinExe + net8.0 + enable + true + app.manifest + true + + + + + + + + + + + + + + + + + + + + diff --git a/demo/Ursa.PrismDialogDemo/app.manifest b/demo/Ursa.PrismDialogDemo/app.manifest new file mode 100644 index 0000000..6fe501d --- /dev/null +++ b/demo/Ursa.PrismDialogDemo/app.manifest @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + diff --git a/global.json b/global.json new file mode 100644 index 0000000..b5b37b6 --- /dev/null +++ b/global.json @@ -0,0 +1,7 @@ +{ + "sdk": { + "version": "8.0.0", + "rollForward": "latestMajor", + "allowPrerelease": false + } +} \ No newline at end of file diff --git a/src/Ursa.PrismExtension/IUrsaDialogService.cs b/src/Ursa.PrismExtension/IUrsaDialogService.cs new file mode 100644 index 0000000..26a3844 --- /dev/null +++ b/src/Ursa.PrismExtension/IUrsaDialogService.cs @@ -0,0 +1,15 @@ +using Avalonia.Controls; +using Ursa.Controls; + +namespace Ursa.PrismExtension; + +public interface IUrsaDialogService +{ + public void ShowCustom(string viewName, object? vm, Window? owner = null, DialogOptions? options = null); + + public Task ShowModal(string viewName, object? vm, Window? owner = null, + DialogOptions? options = null); + + public Task ShowCustomModal(string viewName, object? vm, Window? owner = null, + DialogOptions? options = null); +} \ No newline at end of file diff --git a/src/Ursa.PrismExtension/IUrsaDrawerService.cs b/src/Ursa.PrismExtension/IUrsaDrawerService.cs new file mode 100644 index 0000000..77f7dc9 --- /dev/null +++ b/src/Ursa.PrismExtension/IUrsaDrawerService.cs @@ -0,0 +1,12 @@ +using Ursa.Controls; +using Ursa.Controls.Options; + +namespace Ursa.PrismExtension; + +public interface IUrsaDrawerService +{ + public void Show(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null); + public void ShowCustom(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null); + public Task ShowModal(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null); + public Task ShowCustomModal(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null); +} \ No newline at end of file diff --git a/src/Ursa.PrismExtension/IUrsaOverlayDialogService.cs b/src/Ursa.PrismExtension/IUrsaOverlayDialogService.cs new file mode 100644 index 0000000..fd282e4 --- /dev/null +++ b/src/Ursa.PrismExtension/IUrsaOverlayDialogService.cs @@ -0,0 +1,17 @@ +using Avalonia.Controls; +using Ursa.Controls; + +namespace Ursa.PrismExtension; + +public interface IUrsaOverlayDialogService +{ + public void Show(string viewName, object? vm, string? hostId = null, OverlayDialogOptions? options = null); + + public void ShowCustom(string viewName, object? vm, string? hostId = null, OverlayDialogOptions? options = null); + + public Task ShowModal(string viewName, object? vm, string? hostId = null, + OverlayDialogOptions? options = null); + + public Task ShowCustomModal(string viewName, object? vm, string? hostId = null, + OverlayDialogOptions? options = null); +} \ No newline at end of file diff --git a/src/Ursa.PrismExtension/Ursa.PrismExtension.csproj b/src/Ursa.PrismExtension/Ursa.PrismExtension.csproj new file mode 100644 index 0000000..11d4647 --- /dev/null +++ b/src/Ursa.PrismExtension/Ursa.PrismExtension.csproj @@ -0,0 +1,21 @@ + + + + netstandard2.0 + 0.2.0-beta20240213 + enable + IRIHI Technology Co., Ltd. + enable + latest + Irihi.Ursa.PrismExtension + + + + + + + + + + + diff --git a/src/Ursa.PrismExtension/UrsaDialogService.cs b/src/Ursa.PrismExtension/UrsaDialogService.cs new file mode 100644 index 0000000..41a8c9d --- /dev/null +++ b/src/Ursa.PrismExtension/UrsaDialogService.cs @@ -0,0 +1,26 @@ +using Avalonia.Controls; +using Prism.Ioc; +using Ursa.Controls; + +namespace Ursa.PrismExtension; + +public class UrsaDialogService(IContainerExtension container) : IUrsaDialogService +{ + public void ShowCustom(string viewName, object? vm, Window? owner = null, DialogOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + Dialog.ShowCustom(v, vm, owner, options); + } + + public Task ShowModal(string viewName, object? vm, Window? owner = null, DialogOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + return Dialog.ShowModal(v, vm, owner, options); + } + + public Task ShowCustomModal(string viewName, object? vm, Window? owner = null, DialogOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + return Dialog.ShowCustomModal(v, vm, owner, options); + } +} \ No newline at end of file diff --git a/src/Ursa.PrismExtension/UrsaDialogServiceExtension.cs b/src/Ursa.PrismExtension/UrsaDialogServiceExtension.cs new file mode 100644 index 0000000..d362ce6 --- /dev/null +++ b/src/Ursa.PrismExtension/UrsaDialogServiceExtension.cs @@ -0,0 +1,21 @@ +using Avalonia.Controls; +using Prism.Ioc; + +namespace Ursa.PrismExtension; + +public static class UrsaDialogServiceExtension +{ + internal const string UrsaDialogViewPrefix = "URSA_DIALOG_VIEW_"; + + public static void RegisterUrsaDialogService(this IContainerRegistry containerRegistry) + { + containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); + containerRegistry.RegisterSingleton(); + } + + public static void RegisterUrsaDialogView(this IContainerRegistry containerRegistry, string name) where T : Control + { + containerRegistry.Register(UrsaDialogViewPrefix+name); + } +} \ No newline at end of file diff --git a/src/Ursa.PrismExtension/UrsaDrawerService.cs b/src/Ursa.PrismExtension/UrsaDrawerService.cs new file mode 100644 index 0000000..7cd7add --- /dev/null +++ b/src/Ursa.PrismExtension/UrsaDrawerService.cs @@ -0,0 +1,33 @@ +using Avalonia.Controls; +using Prism.Ioc; +using Ursa.Controls; +using Ursa.Controls.Options; + +namespace Ursa.PrismExtension; + +public class UrsaDrawerService(IContainerExtension container): IUrsaDrawerService +{ + public void Show(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + Drawer.Show(v, vm, hostId, options); + } + + public void ShowCustom(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + Drawer.ShowCustom(v, vm, hostId, options); + } + + public Task ShowModal(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + return Drawer.ShowModal(v, vm, hostId, options); + } + + public Task ShowCustomModal(string viewName, object? vm, string? hostId = null, DrawerOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + return Drawer.ShowCustomModal(v, vm, hostId, options); + } +} \ No newline at end of file diff --git a/src/Ursa.PrismExtension/UrsaOverlayDialogService.cs b/src/Ursa.PrismExtension/UrsaOverlayDialogService.cs new file mode 100644 index 0000000..25c6c0c --- /dev/null +++ b/src/Ursa.PrismExtension/UrsaOverlayDialogService.cs @@ -0,0 +1,32 @@ +using Avalonia.Controls; +using Prism.Ioc; +using Ursa.Controls; + +namespace Ursa.PrismExtension; + +public class UrsaOverlayDialogService(IContainerExtension container): IUrsaOverlayDialogService +{ + public void Show(string viewName, object? vm, string? hostId = null, OverlayDialogOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + OverlayDialog.Show(v, vm, hostId, options); + } + + public void ShowCustom(string viewName, object? vm, string? hostId = null, OverlayDialogOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + OverlayDialog.ShowCustom(v, vm, hostId, options); + } + + public Task ShowModal(string viewName, object? vm, string? hostId = null, OverlayDialogOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + return OverlayDialog.ShowModal(v, vm, hostId, options); + } + + public Task ShowCustomModal(string viewName, object? vm, string? hostId = null, OverlayDialogOptions? options = null) + { + var v = container.Resolve(UrsaDialogServiceExtension.UrsaDialogViewPrefix + viewName); + return OverlayDialog.ShowCustomModal(v, vm, hostId, options); + } +} \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/AssemblyInfo.cs b/src/Ursa.Themes.Semi/AssemblyInfo.cs new file mode 100644 index 0000000..d15efbd --- /dev/null +++ b/src/Ursa.Themes.Semi/AssemblyInfo.cs @@ -0,0 +1,4 @@ +using Avalonia.Metadata; + +[assembly:XmlnsPrefix("https://irihi.tech/ursa/themes/semi", "u-semi")] +[assembly:XmlnsDefinition("https://irihi.tech/ursa/themes/semi", "Ursa.Themes.Semi")] \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Behaviors/ClassHelper.cs b/src/Ursa.Themes.Semi/Behaviors/ClassHelper.cs new file mode 100644 index 0000000..22e11c2 --- /dev/null +++ b/src/Ursa.Themes.Semi/Behaviors/ClassHelper.cs @@ -0,0 +1,24 @@ +using Avalonia; + +namespace Ursa.Themes.Semi; + +internal class ClassHelper: AvaloniaObject +{ + static ClassHelper() + { + ClassesProperty.Changed.AddClassHandler(OnClassesChanged); + } + + public static readonly AttachedProperty ClassesProperty = + AvaloniaProperty.RegisterAttached("Classes"); + + public static void SetClasses(AvaloniaObject obj, string value) => obj.SetValue(ClassesProperty, value); + public static string GetClasses(AvaloniaObject obj) => obj.GetValue(ClassesProperty); + + private static void OnClassesChanged(StyledElement sender, AvaloniaPropertyChangedEventArgs value) + { + string classes = value.GetNewValue(); + sender.Classes.Clear(); + sender.Classes.Add(classes); + } +} \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Controls/Badge.axaml b/src/Ursa.Themes.Semi/Controls/Badge.axaml index fdb21ed..4402f05 100644 --- a/src/Ursa.Themes.Semi/Controls/Badge.axaml +++ b/src/Ursa.Themes.Semi/Controls/Badge.axaml @@ -9,22 +9,23 @@ - - - - - - - - - - + + + + + + + + + + + + - + TextElement.FontSize="{TemplateBinding BadgeFontSize}" + TextElement.Foreground="{TemplateBinding Foreground}"> - + @@ -83,7 +84,7 @@ ContentTemplate="{TemplateBinding ContentTemplate}" /> @@ -130,5 +131,56 @@ + + + + + + + + + + + + + + + + - + \ No newline at end of file diff --git a/src/Ursa.Themes.Semi/Controls/Banner.axaml b/src/Ursa.Themes.Semi/Controls/Banner.axaml index 27f68b2..7f6dd4a 100644 --- a/src/Ursa.Themes.Semi/Controls/Banner.axaml +++ b/src/Ursa.Themes.Semi/Controls/Banner.axaml @@ -80,6 +80,19 @@ + + + + - - - - diff --git a/src/Ursa.Themes.Semi/Controls/ButtonGroup.axaml b/src/Ursa.Themes.Semi/Controls/ButtonGroup.axaml index 15a70c1..06136d4 100644 --- a/src/Ursa.Themes.Semi/Controls/ButtonGroup.axaml +++ b/src/Ursa.Themes.Semi/Controls/ButtonGroup.axaml @@ -63,6 +63,7 @@ HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Content="{TemplateBinding Content}" + ContentTemplate="{TemplateBinding ContentTemplate}" FontWeight="{TemplateBinding FontWeight}" Foreground="{TemplateBinding Foreground}" /> diff --git a/src/Ursa.Themes.Semi/Controls/ControlClassesInput.axaml b/src/Ursa.Themes.Semi/Controls/ControlClassesInput.axaml new file mode 100644 index 0000000..3f5f640 --- /dev/null +++ b/src/Ursa.Themes.Semi/Controls/ControlClassesInput.axaml @@ -0,0 +1,27 @@ + + + + + + + + + + + + diff --git a/src/Ursa.Themes.Semi/Controls/Dialog.axaml b/src/Ursa.Themes.Semi/Controls/Dialog.axaml new file mode 100644 index 0000000..5980151 --- /dev/null +++ b/src/Ursa.Themes.Semi/Controls/Dialog.axaml @@ -0,0 +1,716 @@ + + + + + + + + + + + + + + + + + + + + + +