diff --git a/AtomUI.sln b/AtomUI.sln index bf29748..64ef0fb 100644 --- a/AtomUI.sln +++ b/AtomUI.sln @@ -1,31 +1,34 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Theme", "src\AtomUI.Theme\AtomUI.Theme.csproj", "{87085491-3C99-4C8F-8FA6-F179B9569CE8}" +# Visual Studio Version 17 +VisualStudioVersion = 17.11.35125.118 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Theme", "src\AtomUI.Theme\AtomUI.Theme.csproj", "{87085491-3C99-4C8F-8FA6-F179B9569CE8}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Base", "src\AtomUI.Base\AtomUI.Base.csproj", "{8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Base", "src\AtomUI.Base\AtomUI.Base.csproj", "{8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Icon", "src\AtomUI.Icon\AtomUI.Icon.csproj", "{B2A7349B-4B38-45CB-8D22-3E06D1E3650F}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Icon", "src\AtomUI.Icon\AtomUI.Icon.csproj", "{B2A7349B-4B38-45CB-8D22-3E06D1E3650F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Icon.Generator", "src\AtomUI.Icon.Generator\AtomUI.Icon.Generator.csproj", "{954FB7F2-7706-4E2B-86D1-624F66C1EFF0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Icon.Generator", "src\AtomUI.Icon.Generator\AtomUI.Icon.Generator.csproj", "{954FB7F2-7706-4E2B-86D1-624F66C1EFF0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Icon.AntDesign", "src\AtomUI.Icon.AntDesign\AtomUI.Icon.AntDesign.csproj", "{021AE0B0-B148-4925-9C22-EBD5A7B43E95}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Icon.AntDesign", "src\AtomUI.Icon.AntDesign\AtomUI.Icon.AntDesign.csproj", "{021AE0B0-B148-4925-9C22-EBD5A7B43E95}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Generator", "src\AtomUI.Generator\AtomUI.Generator.csproj", "{30910056-F8F6-4429-B25E-722C57440210}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Generator", "src\AtomUI.Generator\AtomUI.Generator.csproj", "{30910056-F8F6-4429-B25E-722C57440210}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Demo.Desktop", "Samples\AtomUI.Demo.Desktop\AtomUI.Demo.Desktop.csproj", "{59931F42-8DD8-4DFC-9060-563841F39669}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Demo.Desktop", "Samples\AtomUI.Demo.Desktop\AtomUI.Demo.Desktop.csproj", "{59931F42-8DD8-4DFC-9060-563841F39669}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.TestBase", "tests\AtomUI.TestBase\AtomUI.TestBase.csproj", "{EADEF2AC-B7E5-436A-8B39-8BBECF8706AB}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.TestBase", "tests\AtomUI.TestBase\AtomUI.TestBase.csproj", "{EADEF2AC-B7E5-436A-8B39-8BBECF8706AB}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Base.Tests", "tests\AtomUI.Base.Tests\AtomUI.Base.Tests.csproj", "{E41D737A-5CF0-4B33-9F51-2C1B1541659C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Base.Tests", "tests\AtomUI.Base.Tests\AtomUI.Base.Tests.csproj", "{E41D737A-5CF0-4B33-9F51-2C1B1541659C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI.Controls", "src\AtomUI.Controls\AtomUI.Controls.csproj", "{A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI.Controls", "src\AtomUI.Controls\AtomUI.Controls.csproj", "{A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{5EB2524C-30A5-4031-B424-4510E36C753E}" ProjectSection(SolutionItems) = preProject - Directory.Build.props = Directory.Build.props - Directory.Packages.props = Directory.Packages.props - Directory.Build.targets = Directory.Build.targets build\Common.props = build\Common.props + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets + Directory.Packages.props = Directory.Packages.props build\Internal.Using.props = build\Internal.Using.props build\Nuget.props = build\Nuget.props build\Output.App.props = build\Output.App.props @@ -38,7 +41,14 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{279BC2C9 EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Generators", "Generators", "{B4C46C3E-0CCC-4861-95B6-CA08D501A46F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AtomUI", "packages\AtomUI\AtomUI.csproj", "{89A98C0D-B6F7-48CD-91C4-79FC0FED3615}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AtomUI", "packages\AtomUI\AtomUI.csproj", "{89A98C0D-B6F7-48CD-91C4-79FC0FED3615}" + ProjectSection(ProjectDependencies) = postProject + {021AE0B0-B148-4925-9C22-EBD5A7B43E95} = {021AE0B0-B148-4925-9C22-EBD5A7B43E95} + {87085491-3C99-4C8F-8FA6-F179B9569CE8} = {87085491-3C99-4C8F-8FA6-F179B9569CE8} + {8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9} = {8FFEB15F-7E48-4AF4-B708-8E96A68CF2D9} + {A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D} = {A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D} + {B2A7349B-4B38-45CB-8D22-3E06D1E3650F} = {B2A7349B-4B38-45CB-8D22-3E06D1E3650F} + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -73,15 +83,12 @@ Global {59931F42-8DD8-4DFC-9060-563841F39669}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {59931F42-8DD8-4DFC-9060-563841F39669}.Debug|Any CPU.Build.0 = Debug|Any CPU {59931F42-8DD8-4DFC-9060-563841F39669}.Release|Any CPU.ActiveCfg = Release|Any CPU - {59931F42-8DD8-4DFC-9060-563841F39669}.Release|Any CPU.Build.0 = Release|Any CPU {EADEF2AC-B7E5-436A-8B39-8BBECF8706AB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {EADEF2AC-B7E5-436A-8B39-8BBECF8706AB}.Debug|Any CPU.Build.0 = Debug|Any CPU {EADEF2AC-B7E5-436A-8B39-8BBECF8706AB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {EADEF2AC-B7E5-436A-8B39-8BBECF8706AB}.Release|Any CPU.Build.0 = Release|Any CPU {E41D737A-5CF0-4B33-9F51-2C1B1541659C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E41D737A-5CF0-4B33-9F51-2C1B1541659C}.Debug|Any CPU.Build.0 = Debug|Any CPU {E41D737A-5CF0-4B33-9F51-2C1B1541659C}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E41D737A-5CF0-4B33-9F51-2C1B1541659C}.Release|Any CPU.Build.0 = Release|Any CPU {A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D}.Debug|Any CPU.Build.0 = Debug|Any CPU {A07CB66E-7A5F-4C44-BB16-02A0A99D6C2D}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -89,13 +96,18 @@ Global {89A98C0D-B6F7-48CD-91C4-79FC0FED3615}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {89A98C0D-B6F7-48CD-91C4-79FC0FED3615}.Debug|Any CPU.Build.0 = Debug|Any CPU {89A98C0D-B6F7-48CD-91C4-79FC0FED3615}.Release|Any CPU.ActiveCfg = Release|Any CPU - {89A98C0D-B6F7-48CD-91C4-79FC0FED3615}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {E41D737A-5CF0-4B33-9F51-2C1B1541659C} = {279BC2C9-A818-4D6C-9274-678649932057} - {59931F42-8DD8-4DFC-9060-563841F39669} = {279BC2C9-A818-4D6C-9274-678649932057} {954FB7F2-7706-4E2B-86D1-624F66C1EFF0} = {B4C46C3E-0CCC-4861-95B6-CA08D501A46F} {30910056-F8F6-4429-B25E-722C57440210} = {B4C46C3E-0CCC-4861-95B6-CA08D501A46F} + {59931F42-8DD8-4DFC-9060-563841F39669} = {279BC2C9-A818-4D6C-9274-678649932057} {EADEF2AC-B7E5-436A-8B39-8BBECF8706AB} = {279BC2C9-A818-4D6C-9274-678649932057} + {E41D737A-5CF0-4B33-9F51-2C1B1541659C} = {279BC2C9-A818-4D6C-9274-678649932057} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {056F1B83-F604-4F7D-A255-0B40FB31A8F6} EndGlobalSection EndGlobal diff --git a/AtomUI.sln.DotSettings b/AtomUI.sln.DotSettings index 0a9b71f..e039917 100644 --- a/AtomUI.sln.DotSettings +++ b/AtomUI.sln.DotSettings @@ -23,4 +23,5 @@ True True True + True True \ No newline at end of file diff --git a/Directory.Packages.props b/Directory.Packages.props index a000cf5..ddc9f48 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -1,5 +1,4 @@ - true @@ -12,6 +11,8 @@ + + diff --git a/README.md b/README.md index 9b93967..49d7ca3 100644 --- a/README.md +++ b/README.md @@ -33,107 +33,69 @@ Documentation Language: [English](README.md) | [简体中文](README.zh-CN.md) + + #### Introduce AtomUI is an implementation of Ant Design based on .NET technology, dedicated to bringing the excellent and efficient design language and experience of Ant Design to the Avalonia/.NET cross-platform desktop software development field. Welcome to communicate and give suggestions to AtomUI, thank you for giving the project a Star. + -#### Control library completion +#### Features -##### General -| Control Name | Status | -|:-------------|:-----------| -| Button | Completed ✅| -| PathIcon | Completed ✅| -| SpiltButton | Completed ✅| - -##### Navigation -| Control Name | Status | -|:-------------|:------------| -| Breadcrumb | TODO | -| Dropdown | Completed ✅ | -| Menu | Completed ✅ | -| Pagination | TODO | -| Steps | TODO | - -##### Data Entry -| Control Name | Status | -|:----------------|:---------------| -| AutoComplete | TODO | -| Cascader | TODO | -| Checkbox | Completed ✅ | -| ColorPicker | Developing 💪 | -| DatePicker | Developing 💪 | -| Form | TODO | -| Input | Completed ✅ | -| NumberUpDown | Completed ✅ | -| ButtonSpinner | Completed ✅ | -| Mentions | TODO | -| Radio | Completed ✅ | -| OptionButtonBox | Completed ✅ | -| Rate | TODO | -| Select | TODO | -| Slider | Completed ✅ | -| Switch | Completed ✅ | -| TimePicker | Completed ✅ | -| Transfer | TODO | -| Upload | Need Review 🤔 | - -##### Data Display -| Control Name | Status | -|:---------------|:---------------| -| Avatar | TODO | -| Badge | Completed ✅ | -| Calendar | Developing 💪| -| Card | TODO | -| GroupBox | Completed ✅ | -| Carousel | Developing 💪 | -| Collapse | Completed ✅ | -| Expander | Completed ✅ | -| Descriptions | TODO | -| EmptyIndicator | Completed ✅ | -| Image | TODO | -| ListBox | Completed ✅ | -| Popover | Completed ✅ | -| QRCode | TODO | -| Segmented | Completed ✅ | -| Statistic | TODO | -| Table | TODO | -| TabControl | Completed ✅ | -| Tag | Completed ✅ | -| Timeline | Developing 💪 | -| Tooltip | Completed ✅ | -| Tour | TODO | -| Tree | Completed ✅ | - -##### Feedback -| Control Name | Status | -|:-------------------|:-----------| -| Alert | Completed ✅ | -| Drawer | Completed ✅ | -| Message | Completed ✅ | -| Modal | Developing 💪 | -| Notification | Completed ✅ | -| Popconfirm | Completed ✅ | -| ProgressBar | Completed ✅ | -| Result | Need Review 🤔 | -| Skeleton | TODO | -| LoadingIndicator | Completed ✅ | -| Watermark | Completed ✅| +- Enterprise-class UI designed from Ant Design system for cross platform desktop applications. +- A set of high-quality Avalonia Controls out of the box. +- Use .NET development to achieve one-stop writing, seamless compilation on mainstream operating system platforms and render a consistent UI experience. +- Based on Avalonia's powerful style system, Ant Design's theme customization capabilities are fully implemented. #### Some screenshots of the running effect -#### Button Controls - -![Button](docs/images/controls/ButtonControl.png) - -#### Progress bar control -![Progress](docs/images/controls/ProgressBarControl.png) - -#### Slider control -![Slider](docs/images/controls/SliderControl.png) + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
diff --git a/README.zh-CN.md b/README.zh-CN.md index d1329a1..261a6b9 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -33,16 +33,21 @@ 文档语言: [English](README.md) | [简体中文](README.zh-CN.md) + + #### 介绍 AtomUI 是基于 .NET 技术的 Ant Design 实现,致力于将 Ant Design 优秀而高效的设计语言和体验带入 Avalonia/.NET 跨平台桌面软件开发领域。 欢迎与 AtomUI 进行交流并提出建议,感谢您为该项目点赞。 -#### 感谢 Gitee 对 AtomUI 的认可 + -

- -

+#### 特性 + +- 实现 Ant Design 提炼自企业级中后台产品的交互语言和视觉风格。 +- 开箱即用的高质量 Avalonia 组件。 +- 使用 .NET 开发,实现一处编写,无缝在主流操作系统平台编译并且渲染出一致的 UI 体验。 +- 基于 Avalonia 强大的风格系统,完整实现了 Ant Design 的主题定制能力。 #### 运行环境 @@ -50,6 +55,12 @@ AtomUI 是基于 .NET 技术的 Ant Design 实现,致力于将 Ant Design 优 Avalonia 11.1.1 及其以上
PS: AtomUI 目前仅在 Windows 11 平台测试
+#### 感谢 Gitee 对 AtomUI 的认可 + +

+ +

+ #### 中文社区 目前我们暂时只创建 QQ 和微信开发者群的交流方式,下面是二维码,有兴趣的同学可以扫码加入: @@ -64,106 +75,56 @@ PS: AtomUI 目前仅在 Windows 11 平台测试
- +
> PS:扫码请注明来意,比如:学习`AtomUI`或者`Avalonia`爱好者 -#### 当前完成度 -##### (通用) General -| Control Name | Status | -|:-------------|:-------| -| Button | 已完成 ✅ | -| PathIcon | 已完成 ✅ | -| SpiltButton | 已完成 ✅ | - -##### (导航)Navigation -| 控件名 | 完成情况 | -|:---------------|:-------| -| Breadcrumb 面包屑 | 未完成 | -| Dropdown 下拉菜单 | 已完成 ✅ | -| Menu 导航菜单 | 已完成 ✅ | -| Pagination 分页 | 进行中 💪 | -| Steps 步骤条 | 未完成 | - -##### (数据录入)Data Entry -| 控件名 | 完成情况 | -|:---------------------|:-------| -| AutoComplete 自动完成 | 未完成 | -| ComboBox 下拉选择 | 进行中 💪 | -| Cascader 级联选择 | 未完成 | -| Checkbox 多选框 | 已完成 ✅ | -| ColorPicker 颜色选择器 | 进行中 💪 | -| DatePicker 日期选择框 | 进行中 💪 | -| Form 表单 | 未完成 | -| Input 输入框 | 已完成 ✅ | -| NumberUpDown 数字输入框 | 已完成 ✅ | -| ButtonSpinner 按钮切换控件 | 已完成 ✅ | -| Mentions 提及 | 未完成 | -| Radio 单选框 | 已完成 ✅ | -| OptionButtonBox 单选组 | 已完成 ✅ | -| Rate 评分 | 未完成 | -| Select 选择器 | 进行中 💪 | -| Slider 滑动输入条 | 已完成 ✅ | -| Switch 开关 | 已完成 ✅ | -| TimePicker 时间选择框 | 已完成 ✅ | -| Transfer 穿梭框 | 未完成 | -| Upload 上传 | 需评估 🤔 | - -##### (数据展示)Data Display -| 控件名 | 完成情况 | -|:-----------------------|:-------| -| Avatar 头像 | 未完成 | -| Badge 徽标数 | 已完成 ✅ | -| Calendar 日历 | 进行中 💪 | -| Card 卡片 | 未完成 | -| GroupBox 控件 | 已完成 ✅ | -| Carousel 走马灯 | 进行中 💪 | -| Collapse 折叠面板 | 已完成 ✅ | -| Expander 折叠面板 | 已完成 ✅ | -| Descriptions 描述列表 | 未完成 | -| EmptyIndicator 空状态 | 已完成 ✅ | -| PathIcon 图标 | 已完成 ✅ | -| Image 图片 | 未完成 | -| ListBox 列表 | 已完成 ✅ | -| Popover 气泡卡片 | 已完成 ✅ | -| QRCode 二维码 | 未完成 | -| Segmented 分段控制器 | 已完成 ✅ | -| Statistic 统计数值 | 未完成 | -| Table 表格 | 未完成 | -| TabControl 标签页 | 已完成 ✅ | -| Tag 标签 | 已完成 ✅ | -| MarqueeLabel 跑马灯 Label | 已完成 ✅ | -| Timeline 时间轴 | 进行中 💪 | -| Tooltip 文字提示 | 已完成 ✅ | -| Tour 漫游式引导 | 未完成 | -| Tree 树形控件 | 已完成 ✅ | - -##### (反馈)Feedback -| 控件名 | 完成情况 | -|:---------------------|:-------| -| Alert 警告提示 | 已完成 ✅ | -| Drawer 抽屉 | 已完成 ✅ | -| Message 全局提示 | 已完成 ✅ | -| Modal 对话框 | 进行中 💪 | -| Notification 通知提醒框 | 已完成 ✅ | -| Popconfirm 气泡确认框 | 已完成 ✅ | -| ProgressBar 进度条 | 已完成 ✅ | -| Result 结果 | 需评估 🤔 | -| Skeleton 骨架屏 | 未完成 | -| LoadingIndicator 加载中 | 已完成 ✅ | -| Watermark 水印 | 已完成 ✅ | - #### 运行效果部分截图 -#### 按钮控件 - -![按钮控件](docs/images/controls/ButtonControl.png) - -#### 进度条控件 -![进度条控件](docs/images/controls/ProgressBarControl.png) - -#### Slider 控件 -![Slider 控件](docs/images/controls/SliderControl.png) + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+ + + +
+ + + +
+ + + +
+ + + +
diff --git a/build/!Package.All.Release.bat b/build/!Package.All.Release.bat index 579254e..6c78243 100644 --- a/build/!Package.All.Release.bat +++ b/build/!Package.All.Release.bat @@ -1,9 +1,13 @@ %~dp0 -rd/s/q ..\_output\ +rd/s/q ../_output/ -cd ..\ +cd ../ -dotnet msbuild .\AtomUI.sln /p:Configuration=Release +dotnet msbuild ./AtomUI.sln /p:Configuration=Release + +cd packages/AtomUI/ + +dotnet msbuild ./AtomUI.csproj /p:Configuration=Release pause \ No newline at end of file diff --git a/build/CoreLibraries.props b/build/CoreLibraries.props deleted file mode 100644 index 6dda09c..0000000 --- a/build/CoreLibraries.props +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/build/Version.props b/build/Version.props index 7212cfe..93b72cb 100644 --- a/build/Version.props +++ b/build/Version.props @@ -3,8 +3,8 @@ $(NoWarn);CS7035 - 11.1.2 - 11.1.2 + 11.1.3 + 11.1.3 0.0.1 $(LibVersion)-local.1 $(LibVersion)-preview.1 diff --git a/docs/images/Gallery.png b/docs/images/Gallery.png new file mode 100644 index 0000000..00a4a70 Binary files /dev/null and b/docs/images/Gallery.png differ diff --git a/docs/images/Release.jpg b/docs/images/Release.jpg new file mode 100644 index 0000000..8994ef1 Binary files /dev/null and b/docs/images/Release.jpg differ diff --git a/docs/images/controls/Badge.png b/docs/images/controls/Badge.png new file mode 100644 index 0000000..670c91d Binary files /dev/null and b/docs/images/controls/Badge.png differ diff --git a/docs/images/controls/Button.png b/docs/images/controls/Button.png new file mode 100644 index 0000000..cf1d664 Binary files /dev/null and b/docs/images/controls/Button.png differ diff --git a/docs/images/controls/ButtonControl.png b/docs/images/controls/ButtonControl.png deleted file mode 100644 index 1ba8b6d..0000000 Binary files a/docs/images/controls/ButtonControl.png and /dev/null differ diff --git a/docs/images/controls/DatePicker.png b/docs/images/controls/DatePicker.png new file mode 100644 index 0000000..b01e029 Binary files /dev/null and b/docs/images/controls/DatePicker.png differ diff --git a/docs/images/controls/LineEdit.png b/docs/images/controls/LineEdit.png new file mode 100644 index 0000000..a816d75 Binary files /dev/null and b/docs/images/controls/LineEdit.png differ diff --git a/docs/images/controls/Menu.png b/docs/images/controls/Menu.png new file mode 100644 index 0000000..56cb6ef Binary files /dev/null and b/docs/images/controls/Menu.png differ diff --git a/docs/images/controls/Notification.png b/docs/images/controls/Notification.png new file mode 100644 index 0000000..f20f0b1 Binary files /dev/null and b/docs/images/controls/Notification.png differ diff --git a/docs/images/controls/PopupConfirm.png b/docs/images/controls/PopupConfirm.png new file mode 100644 index 0000000..f5c7a3c Binary files /dev/null and b/docs/images/controls/PopupConfirm.png differ diff --git a/docs/images/controls/ProgressBarControl.png b/docs/images/controls/ProgressBar.png similarity index 100% rename from docs/images/controls/ProgressBarControl.png rename to docs/images/controls/ProgressBar.png diff --git a/docs/images/controls/RadioButton.png b/docs/images/controls/RadioButton.png new file mode 100644 index 0000000..f00e1fb Binary files /dev/null and b/docs/images/controls/RadioButton.png differ diff --git a/docs/images/controls/SliderControl.png b/docs/images/controls/SliderControl.png deleted file mode 100644 index 19d5fb7..0000000 Binary files a/docs/images/controls/SliderControl.png and /dev/null differ diff --git a/docs/images/controls/TreeView.png b/docs/images/controls/TreeView.png new file mode 100644 index 0000000..cb9587b Binary files /dev/null and b/docs/images/controls/TreeView.png differ diff --git a/packages/AtomUI/AtomUI.csproj b/packages/AtomUI/AtomUI.csproj index 8e551c7..36a5d9f 100644 --- a/packages/AtomUI/AtomUI.csproj +++ b/packages/AtomUI/AtomUI.csproj @@ -1,14 +1,42 @@ - + - - - - net6.0 - enable - enable - AtomUI - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/samples/AtomUI.Demo.Desktop/App.axaml b/samples/AtomUI.Demo.Desktop/App.axaml deleted file mode 100644 index 89f21aa..0000000 --- a/samples/AtomUI.Demo.Desktop/App.axaml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/App.axaml.cs b/samples/AtomUI.Demo.Desktop/App.axaml.cs deleted file mode 100644 index 19e13d4..0000000 --- a/samples/AtomUI.Demo.Desktop/App.axaml.cs +++ /dev/null @@ -1,29 +0,0 @@ -using AtomUI.Demo.Desktop.Views; -using Avalonia; -using Avalonia.Controls.ApplicationLifetimes; -using Avalonia.Markup.Xaml; - -namespace AtomUI.Demo.Desktop; - -public class App : Application -{ - public override void Initialize() - { - AvaloniaXamlLoader.Load(this); - } - - public override void OnFrameworkInitializationCompleted() - { - switch (ApplicationLifetime) - { - case IClassicDesktopStyleApplicationLifetime desktop: - desktop.MainWindow = new MainWindow(); - break; - case ISingleViewApplicationLifetime singleView: - singleView.MainView = new MainView(); - break; - } - - base.OnFrameworkInitializationCompleted(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Assets/ATOMUI-LOGO.png b/samples/AtomUI.Demo.Desktop/Assets/ATOMUI-LOGO.png deleted file mode 100644 index 82bd40d..0000000 Binary files a/samples/AtomUI.Demo.Desktop/Assets/ATOMUI-LOGO.png and /dev/null differ diff --git a/samples/AtomUI.Demo.Desktop/Assets/EmptyShowCase/empty.svg b/samples/AtomUI.Demo.Desktop/Assets/EmptyShowCase/empty.svg deleted file mode 100644 index b3f7ef0..0000000 --- a/samples/AtomUI.Demo.Desktop/Assets/EmptyShowCase/empty.svg +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Assets/avalonia-logo.ico b/samples/AtomUI.Demo.Desktop/Assets/avalonia-logo.ico deleted file mode 100644 index da8d49f..0000000 Binary files a/samples/AtomUI.Demo.Desktop/Assets/avalonia-logo.ico and /dev/null differ diff --git a/samples/AtomUI.Demo.Desktop/Assets/watermark-sample.png b/samples/AtomUI.Demo.Desktop/Assets/watermark-sample.png deleted file mode 100644 index 15c73c9..0000000 Binary files a/samples/AtomUI.Demo.Desktop/Assets/watermark-sample.png and /dev/null differ diff --git a/samples/AtomUI.Demo.Desktop/AtomUI.Demo.Desktop.csproj b/samples/AtomUI.Demo.Desktop/AtomUI.Demo.Desktop.csproj deleted file mode 100644 index 20eb948..0000000 --- a/samples/AtomUI.Demo.Desktop/AtomUI.Demo.Desktop.csproj +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - WinExe - net8.0 - AtomUI.Demo.Desktop - - true - - - - - - - - - - - - true - true - true - - - - true - app.manifest - - - - - - - - - - - - - - - - - diff --git a/samples/AtomUI.Demo.Desktop/AtomUI.Demo.Desktop.csproj.DotSettings b/samples/AtomUI.Demo.Desktop/AtomUI.Demo.Desktop.csproj.DotSettings deleted file mode 100644 index afb8627..0000000 --- a/samples/AtomUI.Demo.Desktop/AtomUI.Demo.Desktop.csproj.DotSettings +++ /dev/null @@ -1,5 +0,0 @@ - - True - True - True - False diff --git a/samples/AtomUI.Demo.Desktop/Base/ShowCaseItem.cs b/samples/AtomUI.Demo.Desktop/Base/ShowCaseItem.cs deleted file mode 100644 index 576a1ef..0000000 --- a/samples/AtomUI.Demo.Desktop/Base/ShowCaseItem.cs +++ /dev/null @@ -1,65 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; -using Avalonia.LogicalTree; -using Avalonia.Media; -using Separator = AtomUI.Controls.Separator; - -namespace AtomUI.Demo.Desktop; - -public class ShowCaseItem : ContentControl -{ - private bool _initialized; - public string Title { get; set; } = string.Empty; - public string Description { get; set; } = string.Empty; - - private void SetupUi() - { - var mainLayout = new StackPanel(); - var showCaseTitle = new Separator - { - Title = Title, - TitlePosition = SeparatorTitlePosition.Left, - FontWeight = FontWeight.Bold - }; - - if (Content is Control contentControl) - { - LogicalChildren.Remove(contentControl); - mainLayout.Children.Add(contentControl); - } - - mainLayout.Children.Add(new Border - { - Height = 10, - Background = Brushes.Transparent - }); - mainLayout.Children.Add(showCaseTitle); - mainLayout.Children.Add(new TextBlock - { - Text = Description, - TextWrapping = TextWrapping.Wrap, - Margin = new Thickness(0, 10, 0, 0) - }); - - var outerBorder = new Border - { - BorderBrush = new SolidColorBrush(new Color(10, 5, 5, 5)), - BorderThickness = new Thickness(1), - Padding = new Thickness(20), - Child = mainLayout, - CornerRadius = new CornerRadius(8) - }; - - Content = outerBorder; - } - - protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) - { - if (!_initialized) - { - SetupUi(); - _initialized = true; - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Base/ShowCasePanel.cs b/samples/AtomUI.Demo.Desktop/Base/ShowCasePanel.cs deleted file mode 100644 index 4c3bcf6..0000000 --- a/samples/AtomUI.Demo.Desktop/Base/ShowCasePanel.cs +++ /dev/null @@ -1,94 +0,0 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; -using Avalonia.Layout; -using Avalonia.LogicalTree; -using Avalonia.Metadata; -using AvaloniaControlList = Avalonia.Controls.Controls; - -namespace AtomUI.Demo.Desktop; - -public class ShowCasePanel : Control -{ - public string? Id { get; protected set; } - private bool _initialized; - private StackPanel _leftContainer = default!; - private StackPanel _rightContainer = default!; - - [Content] public AvaloniaControlList Children { get; } = new(); - - protected void SetupUi() - { - var mainLayout = new UniformGrid - { - Rows = 1, - Columns = 2, - Margin = new Thickness(0) - }; - _leftContainer = new StackPanel - { - Orientation = Orientation.Vertical, - Spacing = 10, - Margin = new Thickness(0, 0, 10, 0) - }; - _rightContainer = new StackPanel - { - Orientation = Orientation.Vertical, - Spacing = 10 - }; - mainLayout.Children.Add(_leftContainer); - mainLayout.Children.Add(_rightContainer); - - for (var i = 0; i < Children.Count; ++i) - { - var control = Children[i]; - if (i % 2 == 0) - { - _leftContainer.Children.Add(control); - } - else - { - _rightContainer.Children.Add(control); - } - } - - var scrollView = new ScrollViewer - { - Content = mainLayout - }; - LogicalChildren.Add(scrollView); - VisualChildren.Add(scrollView); - } - - protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) - { - if (!_initialized) - { - SetupUi(); - NotifyShowCaseLayoutReady(); - _initialized = true; - } - - base.OnAttachedToLogicalTree(e); - } - - internal virtual void NotifyAboutToActive() - { - } - - internal virtual void NotifyActivated() - { - } - - internal virtual void NotifyAboutToDeactivated() - { - } - - internal virtual void NotifyDeactivated() - { - } - - protected virtual void NotifyShowCaseLayoutReady() - { - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.axaml b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.axaml deleted file mode 100644 index 96f4e4e..0000000 --- a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.axaml +++ /dev/null @@ -1,42 +0,0 @@ - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.cs b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.cs deleted file mode 100644 index 28884ce..0000000 --- a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorItemControl.cs +++ /dev/null @@ -1,38 +0,0 @@ -using AtomUI.Demo.Desktop.ViewModels; -using Avalonia; -using Avalonia.Controls.Primitives; -using Avalonia.Input; -using CommunityToolkit.Mvvm.Messaging; - -namespace AtomUI.Demo.Desktop.Controls; - -public class ColorItemControl : TemplatedControl -{ - public static readonly StyledProperty ColorNameProperty = - AvaloniaProperty.Register( - nameof(ColorName)); - - public string? ColorName - { - get => GetValue(ColorNameProperty); - set => SetValue(ColorNameProperty, value); - } - - public static readonly StyledProperty HexProperty = AvaloniaProperty.Register( - nameof(Hex)); - - public string? Hex - { - get => GetValue(HexProperty); - set => SetValue(HexProperty, value); - } - - protected override void OnPointerPressed(PointerPressedEventArgs e) - { - base.OnPointerPressed(e); - if (DataContext is ColorItemViewModel v) - { - WeakReferenceMessenger.Default.Send(v); - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListControl.axaml b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListControl.axaml deleted file mode 100644 index ce5fb48..0000000 --- a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListControl.axaml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListControl.cs b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListControl.cs deleted file mode 100644 index 402783a..0000000 --- a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListControl.cs +++ /dev/null @@ -1,18 +0,0 @@ -using AtomUI.Demo.Desktop.ViewModels; -using Avalonia; -using Avalonia.Controls.Primitives; - -namespace AtomUI.Demo.Desktop.Controls; - -public class ColorListControl : TemplatedControl -{ - public static readonly StyledProperty ListDataProperty = - AvaloniaProperty.Register( - nameof(ListData), new ColorListViewModel()); - - public ColorListViewModel ListData - { - get => GetValue(ListDataProperty); - set => SetValue(ListDataProperty, value); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListGroupControl.axaml b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListGroupControl.axaml deleted file mode 100644 index 68bd36d..0000000 --- a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListGroupControl.axaml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListGroupControl.cs b/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListGroupControl.cs deleted file mode 100644 index aa4e09c..0000000 --- a/samples/AtomUI.Demo.Desktop/Controls/Colors/ColorListGroupControl.cs +++ /dev/null @@ -1,18 +0,0 @@ -using AtomUI.Demo.Desktop.ViewModels; -using Avalonia; -using Avalonia.Controls.Primitives; - -namespace AtomUI.Demo.Desktop.Controls; - -public class ColorListGroupControl : TemplatedControl -{ - public static readonly StyledProperty GroupDataProperty = - AvaloniaProperty.Register( - nameof(GroupData), new ColorGroupViewModel()); - - public ColorGroupViewModel GroupData - { - get => GetValue(GroupDataProperty); - set => SetValue(GroupDataProperty, value); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconGallery.axaml b/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconGallery.axaml deleted file mode 100644 index cbeb89b..0000000 --- a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconGallery.axaml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconGallery.axaml.cs b/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconGallery.axaml.cs deleted file mode 100644 index 350edf6..0000000 --- a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconGallery.axaml.cs +++ /dev/null @@ -1,54 +0,0 @@ -using AtomUI.Demo.Desktop.ViewModels; -using AtomUI.Icon; -using Avalonia; -using Avalonia.Controls.Primitives; -using Avalonia.Input; -using Avalonia.LogicalTree; -using CommunityToolkit.Mvvm.Messaging; - -namespace AtomUI.Demo.Desktop.Controls; - -public class IconGallery : TemplatedControl -{ - private bool _initialized; - private readonly IconGalleryModel _galleryModel; - - public static readonly StyledProperty IconThemeTypeProperty = - AvaloniaProperty.Register( - nameof(IconThemeType)); - - public IconThemeType? IconThemeType - { - get => GetValue(IconThemeTypeProperty); - set => SetValue(IconThemeTypeProperty, value); - } - - public IconGallery() - { - _galleryModel = new IconGalleryModel(); - DataContext = _galleryModel; - } - - protected override void OnPointerPressed(PointerPressedEventArgs e) - { - base.OnPointerPressed(e); - if (DataContext is ColorItemViewModel v) - { - WeakReferenceMessenger.Default.Send(v); - } - } - - protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e) - { - base.OnAttachedToLogicalTree(e); - if (!_initialized) - { - if (IconThemeType.HasValue) - { - _galleryModel.LoadThemeIcons(IconThemeType.Value); - } - - _initialized = true; - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconInfoItem.axaml b/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconInfoItem.axaml deleted file mode 100644 index 7823a50..0000000 --- a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconInfoItem.axaml +++ /dev/null @@ -1,41 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconInfoItem.axaml.cs b/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconInfoItem.axaml.cs deleted file mode 100644 index 8745fca..0000000 --- a/samples/AtomUI.Demo.Desktop/Controls/PathIcon/IconInfoItem.axaml.cs +++ /dev/null @@ -1,25 +0,0 @@ -using Avalonia; -using Avalonia.Controls.Primitives; - -namespace AtomUI.Demo.Desktop.Controls; - -public class IconInfoItem : TemplatedControl -{ - public static readonly StyledProperty IconNameProperty = AvaloniaProperty.Register( - nameof(IconName)); - - public string IconName - { - get => GetValue(IconNameProperty); - set => SetValue(IconNameProperty, value); - } - - public static readonly StyledProperty IconKindProperty = AvaloniaProperty.Register( - nameof(IconKind)); - - public string IconKind - { - get => GetValue(IconKindProperty); - set => SetValue(IconKindProperty, value); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Program.cs b/samples/AtomUI.Demo.Desktop/Program.cs deleted file mode 100644 index 21ca5f5..0000000 --- a/samples/AtomUI.Demo.Desktop/Program.cs +++ /dev/null @@ -1,57 +0,0 @@ -using AtomUI.Icon; -using AtomUI.Icon.AntDesign; -using AtomUI.Theme; -using Avalonia; -using Avalonia.Dialogs; -using Avalonia.Media; -#if DEBUG -using Nlnet.Avalonia.DevTools; -#endif - -namespace AtomUI.Demo.Desktop; - -internal 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) - { - try - { - BuildAvaloniaApp() - .With(new FontManagerOptions - { - FontFallbacks = new[] - { - new FontFallback - { - FontFamily = new FontFamily("Microsoft YaHei") - } - } - }) - .StartWithClassicDesktopLifetime(args); - } - catch (Exception ex) - { - File.WriteAllText("error.log", ex.ToString()); -#if DEBUG - throw; -#endif - } - } - - public static AppBuilder BuildAvaloniaApp() - => AppBuilder.Configure() - .ConfigureAtomUI() - .UseManagedSystemDialogs() - .UsePlatformDetect() - .UseAtomUI() -#if DEBUG - .UseDevToolsForAvalonia() -#endif - .UseIconPackage(true) - .With(new Win32PlatformOptions()) - .LogToTrace(); -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Roots.xml b/samples/AtomUI.Demo.Desktop/Roots.xml deleted file mode 100644 index 44df280..0000000 --- a/samples/AtomUI.Demo.Desktop/Roots.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml deleted file mode 100644 index b33c71f..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml +++ /dev/null @@ -1,160 +0,0 @@ - - - - - Success Text - - - - - - Success Text - Info Text - Warning Text - Error Text - - - - - - - Warning Text Warning Text Warning Text Warning Text Warning Text Warning TextWarning Text - - - Error Text - - - Error Text - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - UNDO - - Success Tips - - - - - Detail - - Error Text - - - - - Done - - Warning Text - - - - - - Accept - Decline - - - Info Text - - - - - - - I can be a React component, multiple React components, or just some text, Info Description Info Description Info Description Info Description - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml.cs deleted file mode 100644 index d57fb13..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/AlertShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class AlertShowCase : UserControl -{ - public AlertShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml deleted file mode 100644 index cbf6c2b..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml +++ /dev/null @@ -1,10 +0,0 @@ - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml.cs deleted file mode 100644 index eed53d3..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/AvatarShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class AvatarShowCase : UserControl -{ - public AvatarShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/BadgeShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/BadgeShowCase.axaml deleted file mode 100644 index c860bd7..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/BadgeShowCase.axaml +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Add - Sub - Random - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Pushes open the window - - - and raises the spyglass. - - - - - - - - - Pushes open the window - - - and raises the spyglass. - - - - - - - - - Pushes open the window - - - and raises the spyglass. - - - - - - - - - Pushes open the window - - - and raises the spyglass. - - - - - - - - - Pushes open the window - - - and raises the spyglass. - - - - - - - - - Pushes open the window - - - and raises the spyglass. - - - - - - - - - Pushes open the window - - - and raises the spyglass. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/BadgeShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/BadgeShowCase.axaml.cs deleted file mode 100644 index 8ff927e..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/BadgeShowCase.axaml.cs +++ /dev/null @@ -1,107 +0,0 @@ -using Avalonia; -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class BadgeShowCase : UserControl -{ - public static readonly StyledProperty DynamicBadgeCountProperty = - AvaloniaProperty.Register(nameof(DynamicBadgeCount), 5); - - public static readonly StyledProperty DynamicDotBadgeVisibleProperty = - AvaloniaProperty.Register(nameof(DynamicDotBadgeVisible), true); - - public static readonly StyledProperty StandaloneSwitchCheckedProperty = - AvaloniaProperty.Register(nameof(StandaloneSwitchChecked), true); - - public static readonly StyledProperty StandaloneBadgeCount1Property = - AvaloniaProperty.Register(nameof(StandaloneBadgeCount1), 11); - - public static readonly StyledProperty StandaloneBadgeCount2Property = - AvaloniaProperty.Register(nameof(StandaloneBadgeCount2), 25); - - public static readonly StyledProperty StandaloneBadgeCount3Property = - AvaloniaProperty.Register(nameof(StandaloneBadgeCount3), 109); - - public double DynamicBadgeCount - { - get => GetValue(DynamicBadgeCountProperty); - set => SetValue(DynamicBadgeCountProperty, value); - } - - public bool DynamicDotBadgeVisible - { - get => GetValue(DynamicDotBadgeVisibleProperty); - set => SetValue(DynamicDotBadgeVisibleProperty, value); - } - - public bool StandaloneSwitchChecked - { - get => GetValue(StandaloneSwitchCheckedProperty); - set => SetValue(StandaloneSwitchCheckedProperty, value); - } - - public double StandaloneBadgeCount1 - { - get => GetValue(StandaloneBadgeCount1Property); - set => SetValue(StandaloneBadgeCount1Property, value); - } - - public double StandaloneBadgeCount2 - { - get => GetValue(StandaloneBadgeCount2Property); - set => SetValue(StandaloneBadgeCount2Property, value); - } - - public double StandaloneBadgeCount3 - { - get => GetValue(StandaloneBadgeCount3Property); - set => SetValue(StandaloneBadgeCount3Property, value); - } - - public BadgeShowCase() - { - DataContext = this; - InitializeComponent(); - } - - public void AddDynamicBadgeCount() - { - DynamicBadgeCount += 1; - } - - public void SubDynamicBadgeCount() - { - var value = DynamicBadgeCount; - value -= 1; - value = Math.Max(value, 0); - DynamicBadgeCount = value; - } - - public void RandomDynamicBadgeCount() - { - var random = new Random(); - DynamicBadgeCount = random.Next(0, 110); - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs args) - { - base.OnPropertyChanged(args); - if (args.Property == StandaloneSwitchCheckedProperty) - { - var isChecked = args.GetNewValue(); - if (isChecked) - { - StandaloneBadgeCount1 = 11; - StandaloneBadgeCount2 = 25; - StandaloneBadgeCount3 = 109; - } - else - { - StandaloneBadgeCount1 = 0; - StandaloneBadgeCount2 = 0; - StandaloneBadgeCount3 = 0; - } - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml deleted file mode 100644 index e7bb987..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml +++ /dev/null @@ -1,325 +0,0 @@ - - - - - - - - Primary Button - Default Button - Text Button - Link Button - - - - - - - Primary - Default - Text - Link - - - Primary - Default - Text - Link - - - AA - AA - AA - AA - - - - - - - - - Expand direction: - - Large - Default - Small - - - - - - Primary - Default - Link - - - - - - - Download - - - Download - - - - - - - - - - - - Search - - - - - Search - - - - Search - - - - Search - - - - - - Search - - - - Search - - - - Search - - - - Search - - - - - - - - - - Loading - Loading - - - - Click me! - - Click me! - - - - - - - - - - - Primary - - - Default - - - Text - - - Link - - - - - - - - Primary - - - Default - - - Text - - - Link - - - - - - - - - - Primary - - - Default - - - Text - - - Link - - - Danger - - - - - Primary - - - Default - - - Text - - - Link - - - Danger - - - - - - - - - - - Primary - - - Primary(disabled) - - - - - Default - - - Default(disabled) - - - - - Text - - - Text(disabled) - - - - - Link - - - Link(disabled) - - - - - - Danger Primary - - - Danger Primary(disabled) - - - - - Danger Default - - - Danger Default(disabled) - - - - - Danger Text - - - Danger Text(disabled) - - - - - Danger Link - - - Danger Link(disabled) - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml.cs deleted file mode 100644 index ed70372..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonShowCase.axaml.cs +++ /dev/null @@ -1,60 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Interactivity; -using Avalonia.Threading; -using Button = AtomUI.Controls.Button; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class ButtonShowCase : UserControl -{ - public static readonly StyledProperty ButtonSizeTypeProperty = - AvaloniaProperty.Register(nameof(ButtonSizeType)); - - public SizeType ButtonSizeType - { - get => GetValue(ButtonSizeTypeProperty); - set => SetValue(ButtonSizeTypeProperty, value); - } - - public ButtonShowCase() - { - InitializeComponent(); - DataContext = this; - - ButtonSizeTypeOptionGroup.OptionCheckedChanged += HandleButtonSizeTypeOptionCheckedChanged; - LoadingBtn1.Click += HandleLoadingBtnClick; - LoadingBtn2.Click += HandleLoadingBtnClick; - LoadingBtn3.Click += HandleLoadingBtnClick; - } - - private void HandleButtonSizeTypeOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) - { - ButtonSizeType = SizeType.Large; - } - else if (args.Index == 1) - { - ButtonSizeType = SizeType.Middle; - } - else - { - ButtonSizeType = SizeType.Small; - } - } - - private void HandleLoadingBtnClick(object? sender, RoutedEventArgs args) - { - if (sender is Button button) - { - button.IsLoading = true; - Dispatcher.UIThread.InvokeAsync(async () => - { - await Task.Delay(TimeSpan.FromSeconds(3)); - button.IsLoading = false; - }); - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml deleted file mode 100644 index eb2914f..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml +++ /dev/null @@ -1,248 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml.cs deleted file mode 100644 index 24987c3..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ButtonSpinnerShowCase.axaml.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class ButtonSpinnerShowCase : UserControl -{ - public ButtonSpinnerShowCase() - { - InitializeComponent(); - } - - public void HandleSpin(object sender, SpinEventArgs e) - { - var spinner = (ButtonSpinner)sender; - - if (spinner.Content is TextBlock textBlock) - { - var value = Array.IndexOf(_spinnerItems, textBlock.Text); - if (e.Direction == SpinDirection.Increase) - { - value++; - } - else - { - value--; - } - - if (value < 0) - { - value = _spinnerItems.Length - 1; - } - else if (value >= _spinnerItems.Length) - { - value = 0; - } - - textBlock.Text = _spinnerItems[value]; - } - } - - private readonly string[] _spinnerItems = - { - "床前明月光", - "疑是地上霜", - "举头望明月", - "低头思故乡" - }; -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml deleted file mode 100644 index b8c274e..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml.cs deleted file mode 100644 index 1e4e2f3..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CalendarShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class CalendarShowCase : UserControl -{ - public CalendarShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml deleted file mode 100644 index 7d3bb61..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml +++ /dev/null @@ -1,10 +0,0 @@ - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml.cs deleted file mode 100644 index 27982f0..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CardShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class CardShowCase : UserControl -{ - public CardShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml deleted file mode 100644 index d2b3de3..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml +++ /dev/null @@ -1,125 +0,0 @@ - - - - - - - - Checkbox - - - - - - UnChecked - Indeterminate - Checked - - - - - - - - - - - - - - - - - Apple - Pear - Orange - - - Apple - Pear - Orange - - - Apple - Pear - Orange - - - - - - - - - - Check all - - - - - Apple - - - Pear - - - Orange - - - - - - - - A - B - C - D - D - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml.cs deleted file mode 100644 index d2f01c1..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CheckBoxShowCase.axaml.cs +++ /dev/null @@ -1,13 +0,0 @@ -using AtomUI.Demo.Desktop.ViewModels; -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class CheckBoxShowCase : UserControl -{ - public CheckBoxShowCase() - { - DataContext = new CheckBoxShowCaseModel(); - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml deleted file mode 100644 index 1760d3a..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml +++ /dev/null @@ -1,250 +0,0 @@ - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - Expand Icon Position: - - Start - End - - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml.cs deleted file mode 100644 index 593b765..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/CollapseShowCase.axaml.cs +++ /dev/null @@ -1,36 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class CollapseShowCase : UserControl -{ - public static readonly StyledProperty CollapseExpandIconPositionProperty = - AvaloniaProperty.Register(nameof(CollapseExpandIconPosition)); - - public CollapseExpandIconPosition CollapseExpandIconPosition - { - get => GetValue(CollapseExpandIconPositionProperty); - set => SetValue(CollapseExpandIconPositionProperty, value); - } - - public CollapseShowCase() - { - InitializeComponent(); - DataContext = this; - //ExpandButtonPosGroup.OptionCheckedChanged += HandleExpandButtonPosOptionCheckedChanged; - } - - private void HandleExpandButtonPosOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) - { - CollapseExpandIconPosition = CollapseExpandIconPosition.Start; - } - else if (args.Index == 1) - { - CollapseExpandIconPosition = CollapseExpandIconPosition.End; - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml deleted file mode 100644 index d75e863..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - - - - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - - - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - 床前明月光 - 疑是地上霜 - 举头望明月 - 低头思故乡 - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml.cs deleted file mode 100644 index 2552c89..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ComboBoxShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class ComboBoxShowCase : UserControl -{ - public ComboBoxShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs b/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs deleted file mode 100644 index 62d4bf7..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class DatePickerShowCase : UserControl -{ - public DatePickerShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs.axaml deleted file mode 100644 index b36de15..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DatePickerShowCase.cs.axaml +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml deleted file mode 100644 index 74b9266..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml +++ /dev/null @@ -1,286 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml.cs deleted file mode 100644 index fe1e85b..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DrawerShowCase.axaml.cs +++ /dev/null @@ -1,35 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Interactivity; -using Button = AtomUI.Controls.Button; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class DrawerShowCase : UserControl -{ - public DrawerShowCase() - { - InitializeComponent(); - } - - private void Button_OnClick(object? sender, RoutedEventArgs e) - { - if (sender is not Button button) - { - return; - } - - if (Drawer.GetDrawer(button) is not { } drawer) - { - return; - } - - drawer.IsOpen = false; - } - - private void ButtonOpenOnCurrentParent_OnClick(object? sender, RoutedEventArgs e) - { - Drawer1.OpenOn = Drawer1.OpenOn?.Parent as Visual; - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml deleted file mode 100644 index 867deff..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml +++ /dev/null @@ -1,299 +0,0 @@ - - - - - Hover me - - - - - - - - - - - - - - - - - - Edit File - - - - - - - - - - - Edit File - - - - - - - - - - - Edit File - - - - - - - - - - - Edit File - - - - - - - - - - - - - - - - - - BottomLeft - - - - - - - - - - - Bottom - - - - - - - - - - - BottomRight - - - - - - - - - - - TopLeft - - - - - - - - - - - Top - - - - - - - - - - - TopRight - - - - - - - - - - - - - - - - - - BottomLeft - - - - - - - - - - - Bottom - - - - - - - - - - - BottomRight - - - - - - - - - - - TopLeft - - - - - - - - - - - Top - - - - - - - - - - - TopRight - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml.cs deleted file mode 100644 index ae93eb5..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/DropdownButtonShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class DropdownButtonShowCase : UserControl -{ - public DropdownButtonShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml deleted file mode 100644 index 36b6390..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - - - - - - - - - - - - - Create Now - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml.cs deleted file mode 100644 index afcaa1e..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/EmptyShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class EmptyShowCase : UserControl -{ - public EmptyShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ExpanderShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ExpanderShowCase.axaml deleted file mode 100644 index f4dee05..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ExpanderShowCase.axaml +++ /dev/null @@ -1,168 +0,0 @@ - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - Expand direction: - - Down - Up - Left - Right - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - Expand Icon Position: - - Start - End - - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found as a welcome guest in many households across the world. - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ExpanderShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ExpanderShowCase.axaml.cs deleted file mode 100644 index abd1881..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ExpanderShowCase.axaml.cs +++ /dev/null @@ -1,66 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class ExpanderShowCase : UserControl -{ - public static readonly StyledProperty ToggleIconPositionProperty = - AvaloniaProperty.Register(nameof(ToggleIconPosition)); - - public ExpanderIconPosition ToggleIconPosition - { - get => GetValue(ToggleIconPositionProperty); - set => SetValue(ToggleIconPositionProperty, value); - } - - public static readonly StyledProperty ExpandDirectionProperty = - AvaloniaProperty.Register(nameof(ExpandDirection)); - - public ExpandDirection ExpandDirection - { - get => GetValue(ExpandDirectionProperty); - set => SetValue(ExpandDirectionProperty, value); - } - - public ExpanderShowCase() - { - InitializeComponent(); - DataContext = this; - ExpandButtonPosGroup.OptionCheckedChanged += HandleExpandButtonPosOptionCheckedChanged; - ExpandDirectionOptionGroup.OptionCheckedChanged += HandleExpandDirectionOptionCheckedChanged; - } - - private void HandleExpandButtonPosOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) - { - ToggleIconPosition = ExpanderIconPosition.Start; - } - else if (args.Index == 1) - { - ToggleIconPosition = ExpanderIconPosition.End; - } - } - - private void HandleExpandDirectionOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) - { - ExpandDirection = ExpandDirection.Down; - } - else if (args.Index == 1) - { - ExpandDirection = ExpandDirection.Up; - } - else if (args.Index == 2) - { - ExpandDirection = ExpandDirection.Left; - } - else if (args.Index == 3) - { - ExpandDirection = ExpandDirection.Right; - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml deleted file mode 100644 index 0b19d68..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - - Content of group box - - - - - - - - - - - Content of group box - - - - - - - Content of group box - - - - - - - Content of group box - - - - - - - - - - - - Content of group box - - - - - - - Content of group box - - - - - - - Content of group box - - - - - - - Content of group box - - - - - - - - - - - Content of group box - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml.cs deleted file mode 100644 index 42e7a90..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/GroupBoxShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class GroupBoxShowCase : UserControl -{ - public GroupBoxShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/IconShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/IconShowCase.axaml deleted file mode 100644 index 8d20026..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/IconShowCase.axaml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/IconShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/IconShowCase.axaml.cs deleted file mode 100644 index d7d3095..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/IconShowCase.axaml.cs +++ /dev/null @@ -1,22 +0,0 @@ -using AtomUI.Demo.Desktop.ViewModels; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; -using Avalonia.Threading; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class IconShowCase : UserControl -{ - public IconShowCase() - { - InitializeComponent(); - } - - protected override async void OnApplyTemplate(TemplateAppliedEventArgs e) - { - base.OnApplyTemplate(e); - var vm = new PaletteDemoViewModel(); - await Dispatcher.UIThread.InvokeAsync(() => { vm.InitializeResources(); }); - DataContext = vm; - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml deleted file mode 100644 index 62abbed..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml +++ /dev/null @@ -1,379 +0,0 @@ - - - - - - - - The most basic example. - - - Hover me - - - - - - - - - - The most basic example. - - - Hover me - - - - - The most basic example. - - - Click me - - - - - - - - - - - - - - - - - - - - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - - - - Show - Hide - Center - - - - - - - - - - - - - - - - - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - The most basic example. - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml.cs deleted file mode 100644 index 550f5f5..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/InfoFlyoutShowCase.axaml.cs +++ /dev/null @@ -1,54 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class InfoFlyoutShowCase : UserControl -{ - public static readonly StyledProperty ShowArrowProperty = - AvaloniaProperty.Register(nameof(ShowArrow), true); - - public static readonly StyledProperty IsPointAtCenterProperty = - AvaloniaProperty.Register(nameof(IsPointAtCenter)); - - private readonly Segmented _segmented; - - public bool ShowArrow - { - get => GetValue(ShowArrowProperty); - set => SetValue(ShowArrowProperty, value); - } - - public bool IsPointAtCenter - { - get => GetValue(IsPointAtCenterProperty); - set => SetValue(IsPointAtCenterProperty, value); - } - - public InfoFlyoutShowCase() - { - DataContext = this; - InitializeComponent(); - var control = this as Control; - _segmented = control.FindControl("ArrowSegmented")!; - _segmented.SelectionChanged += (sender, args) => - { - if (_segmented.SelectedIndex == 0) - { - ShowArrow = true; - IsPointAtCenter = false; - } - else if (_segmented.SelectedIndex == 1) - { - ShowArrow = false; - IsPointAtCenter = false; - } - else if (_segmented.SelectedIndex == 2) - { - IsPointAtCenter = true; - ShowArrow = true; - } - }; - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml deleted file mode 100644 index a4905bb..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml +++ /dev/null @@ -1,150 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml.cs deleted file mode 100644 index 3a337d9..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/LineEditShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class LineEditShowCase : UserControl -{ - public LineEditShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml deleted file mode 100644 index ae14d00..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml +++ /dev/null @@ -1,45 +0,0 @@ - - - - - Blue - Green - Red - Yellow - - - - - - Blue - Green - Red - Yellow - - - - - - Blue - Green - Red - Yellow - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml.cs deleted file mode 100644 index 50c1f1a..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ListBoxShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class ListBoxShowCase : UserControl -{ - public ListBoxShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml deleted file mode 100644 index 84fc3a0..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml +++ /dev/null @@ -1,93 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Loading state: - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml.cs deleted file mode 100644 index 46b3f9c..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/LoadingIndicatorShowCase.axaml.cs +++ /dev/null @@ -1,22 +0,0 @@ -using Avalonia; -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class LoadingIndicatorShowCase : UserControl -{ - public static readonly StyledProperty IsLoadingSwitchCheckedProperty = - AvaloniaProperty.Register(nameof(IsLoadingSwitchChecked)); - - public bool IsLoadingSwitchChecked - { - get => GetValue(IsLoadingSwitchCheckedProperty); - set => SetValue(IsLoadingSwitchCheckedProperty, value); - } - - public LoadingIndicatorShowCase() - { - DataContext = this; - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml deleted file mode 100644 index 1e414fc..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml +++ /dev/null @@ -1,192 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml.cs deleted file mode 100644 index ef812aa..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/MenuShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class MenuShowCase : UserControl -{ - public MenuShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml deleted file mode 100644 index 24358a1..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - Display normal message - - - - - - - Success - - - Info - - - Warning - - - Error - - - - - - - Display a loading indicator - - - - - - Display a loading indicator - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml.cs deleted file mode 100644 index d6fea18..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/MessageShowCase.axaml.cs +++ /dev/null @@ -1,98 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Interactivity; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class MessageShowCase : UserControl -{ - private WindowMessageManager? _messageManager; - - public MessageShowCase() - { - InitializeComponent(); - } - - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - var topLevel = TopLevel.GetTopLevel(this); - _messageManager = new WindowMessageManager(topLevel) - { - MaxItems = 10 - }; - } - - private void ShowSimpleMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowInfoMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Information, - content: "This is a information message." - )); - } - - private void ShowSuccessMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Success, - content: "This is a success message." - )); - } - - private void ShowWarningMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Warning, - content: "This is a warning message." - )); - } - - private void ShowErrorMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Error, - content: "This is a error message." - )); - } - - private void ShowLoadingMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Loading, - content: "Action in progress..." - )); - } - - private void ShowSequentialMessage(object? sender, RoutedEventArgs e) - { - _messageManager?.Show(new Message( - type: MessageType.Loading, - content: "Action in progress...", - expiration: TimeSpan.FromSeconds(2.5), - onClose: () => - { - _messageManager?.Show(new Message( - type: MessageType.Success, - expiration: TimeSpan.FromSeconds(2.5), - content: "Loading finished", - onClose: () => - { - _messageManager?.Show(new Message( - type: MessageType.Information, - expiration: TimeSpan.FromSeconds(2.5), - content: "Loading finished" - )); - } - )); - } - )); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml deleted file mode 100644 index 8ce5316..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml +++ /dev/null @@ -1,92 +0,0 @@ - - - - - Show Notification - - - - - - Open the notification box - - - - - - - Success - - - Info - - - Warning - - - Error - - - - - - - - - Top - - - Bottom - - - - - - TopLeft - - - TopRight - - - - - - BottomLeft - - - BottomRight - - - - - - - - Open the notification box - - - - - - - Pause on hover - Don't pause on hover - - - Show Notification - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml.cs deleted file mode 100644 index 8faa2f2..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/NotificationShowCase.axaml.cs +++ /dev/null @@ -1,215 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Interactivity; -using PathIcon = AtomUI.Controls.PathIcon; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class NotificationShowCase : UserControl -{ - private WindowNotificationManager? _basicManager; - private WindowNotificationManager? _topLeftManager; - private WindowNotificationManager? _topManager; - private WindowNotificationManager? _topRightManager; - - private WindowNotificationManager? _bottomLeftManager; - private WindowNotificationManager? _bottomManager; - private WindowNotificationManager? _bottomRightManager; - - public NotificationShowCase() - { - InitializeComponent(); - HoverOptionGroup.OptionCheckedChanged += HandleHoverOptionGroupCheckedChanged; - } - - private void HandleHoverOptionGroupCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (_basicManager is not null) - { - if (args.Index == 0) - { - _basicManager.IsPauseOnHover = true; - } - else - { - _basicManager.IsPauseOnHover = false; - } - } - } - - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - var topLevel = TopLevel.GetTopLevel(this); - _basicManager = new WindowNotificationManager(topLevel) - { - MaxItems = 3 - }; - - _topLeftManager = new WindowNotificationManager(topLevel) - { - MaxItems = 3, - Position = NotificationPosition.TopLeft - }; - - _topManager = new WindowNotificationManager(topLevel) - { - Position = NotificationPosition.TopCenter, - MaxItems = 3 - }; - - _topRightManager = new WindowNotificationManager(topLevel) - { - Position = NotificationPosition.TopRight, - MaxItems = 3 - }; - - _bottomLeftManager = new WindowNotificationManager(topLevel) - { - Position = NotificationPosition.BottomLeft, - MaxItems = 3 - }; - - _bottomManager = new WindowNotificationManager(topLevel) - { - Position = NotificationPosition.BottomCenter, - MaxItems = 3 - }; - - _bottomRightManager = new WindowNotificationManager(topLevel) - { - Position = NotificationPosition.BottomRight, - MaxItems = 3 - }; - } - - private void ShowSimpleNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - "Notification Title", - "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowNeverCloseNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - expiration: TimeSpan.Zero, - title: "Notification Title", - content: - "I will never close automatically. This is a purposely very very long description that has many many characters and words." - )); - } - - private void ShowSuccessNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - type: NotificationType.Success, - title: "Notification Title", - content: - "This is the content of the notification. This is the content of the notification. This is the content of the notification." - )); - } - - private void ShowInfoNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - type: NotificationType.Information, - title: "Notification Title", - content: - "This is the content of the notification. This is the content of the notification. This is the content of the notification." - )); - } - - private void ShowWarningNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - type: NotificationType.Warning, - title: "Notification Title", - content: - "This is the content of the notification. This is the content of the notification. This is the content of the notification." - )); - } - - private void ShowErrorNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - type: NotificationType.Error, - title: "Notification Title", - content: - "This is the content of the notification. This is the content of the notification. This is the content of the notification." - )); - } - - private void ShowTopNotification(object? sender, RoutedEventArgs e) - { - _topManager?.Show(new Notification( - "Notification Top", - "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowBottomNotification(object? sender, RoutedEventArgs e) - { - _bottomManager?.Show(new Notification( - "Notification Bottom", - "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowTopLeftNotification(object? sender, RoutedEventArgs e) - { - _topLeftManager?.Show(new Notification( - "Notification TopLeft", - "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowTopRightNotification(object? sender, RoutedEventArgs e) - { - _topRightManager?.Show(new Notification( - "Notification TopRight", - "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowBottomLeftNotification(object? sender, RoutedEventArgs e) - { - _bottomLeftManager?.Show(new Notification( - "Notification BottomLeft", - "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowBottomRightNotification(object? sender, RoutedEventArgs e) - { - _bottomRightManager?.Show(new Notification( - "Notification BottomRight", - "Hello, AtomUI/Avalonia!" - )); - } - - private void ShowCustomIconNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - "Notification Title", - "This is the content of the notification. This is the content of the notification. This is the content of the notification.", - icon: new PathIcon - { - Kind = "SettingOutlined" - } - )); - } - - private void ShowProgressNotification(object? sender, RoutedEventArgs e) - { - _basicManager?.Show(new Notification( - type: NotificationType.Information, - title: "Notification Title", - content: - "This is the content of the notification. This is the content of the notification. This is the content of the notification.", - showProgress: true - )); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml deleted file mode 100644 index 729cf0c..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml +++ /dev/null @@ -1,99 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml.cs deleted file mode 100644 index 2379bcc..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/NumberUpDownShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class NumberUpDownShowCase : UserControl -{ - public NumberUpDownShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml deleted file mode 100644 index 8cd133f..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml +++ /dev/null @@ -1,425 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml.cs deleted file mode 100644 index 40a4037..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/Overview.axaml.cs +++ /dev/null @@ -1,43 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class Overview : UserControl -{ - public Overview() - { - InitializeComponent(); - } - - public string MainInstall { get; set; } = "dotnet add package AtomUI --version 11.0.7"; - - public string MainStyle { get; set; } = """ - - - - """; - - public string ColorPickerInstall { get; set; } = "dotnet add package AtomUI.ColorPicker --version 11.0.7"; - - public string ColorPickerStyle { get; set; } = """ - - - - """; - - public string DataGridInstall { get; set; } = "dotnet add package AtomUI.DataGrid --version 11.0.7"; - - public string DataGridStyle { get; set; } = """ - - - - """; - - public string TreeDataGridInstall { get; set; } = "dotnet add package AtomUI.TreeDataGrid --version 11.0.7"; - - public string TreeDataGridStyle { get; set; } = """ - - - - """; -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml deleted file mode 100644 index 7c82c72..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml +++ /dev/null @@ -1,11 +0,0 @@ - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml.cs deleted file mode 100644 index 34080ce..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PaginationShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class PaginationShowCase : UserControl -{ - public PaginationShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PaletteShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/PaletteShowCase.axaml deleted file mode 100644 index fe1ad49..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PaletteShowCase.axaml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PaletteShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/PaletteShowCase.axaml.cs deleted file mode 100644 index 10e8e31..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PaletteShowCase.axaml.cs +++ /dev/null @@ -1,22 +0,0 @@ -using AtomUI.Demo.Desktop.ViewModels; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; -using Avalonia.Threading; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class PaletteShowCase : UserControl -{ - public PaletteShowCase() - { - InitializeComponent(); - } - - protected override async void OnApplyTemplate(TemplateAppliedEventArgs e) - { - base.OnApplyTemplate(e); - var vm = new PaletteDemoViewModel(); - await Dispatcher.UIThread.InvokeAsync(() => { vm.InitializeResources(); }); - DataContext = vm; - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml deleted file mode 100644 index 87b4466..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml +++ /dev/null @@ -1,184 +0,0 @@ - - - - - Delete - - - - - - Delete - - - - - - - - - - - - - - - - - - - - - - - - - LT - - - - Left - - - - LB - - - - TL - - - - Top - - - - TR - - - - RT - - - - Right - - - - RB - - - - BL - - - - Bottom - - - - BR - - - - - - - - Delete - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml.cs deleted file mode 100644 index 3b418fb..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/PopupConfirmShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class PopupConfirmShowCase : UserControl -{ - public PopupConfirmShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml deleted file mode 100644 index bbbf7a6..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml +++ /dev/null @@ -1,382 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Sub - Add - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml.cs deleted file mode 100644 index 1da51c4..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ProgressBarShowCase.axaml.cs +++ /dev/null @@ -1,139 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Media; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class ProgressBarShowCase : UserControl -{ - public LinearGradientBrush TwoStopsGradientStrokeColor { get; set; } - - public LinearGradientBrush ThreeStopsGradientStrokeColor { get; set; } - - public List StepsChunkBrushes { get; set; } - - public PercentPosition InnerStartPercentPosition { get; set; } - public PercentPosition InnerCenterPercentPosition { get; set; } - public PercentPosition InnerEndPercentPosition { get; set; } - - public PercentPosition OutterStartPercentPosition { get; set; } - public PercentPosition OutterCenterPercentPosition { get; set; } - public PercentPosition OutterEndPercentPosition { get; set; } - - public static readonly StyledProperty ProgressValueProperty = - AvaloniaProperty.Register(nameof(ProgressValue), 30); - - public static readonly StyledProperty ToggleDisabledTextProperty = - AvaloniaProperty.Register(nameof(ToggleDisabledText), "Disable"); - - public static readonly StyledProperty ToggleStatusProperty = - AvaloniaProperty.Register(nameof(ToggleStatus), true); - - public double ProgressValue - { - get => GetValue(ProgressValueProperty); - set => SetValue(ProgressValueProperty, value); - } - - public string ToggleDisabledText - { - get => GetValue(ToggleDisabledTextProperty); - set => SetValue(ToggleDisabledTextProperty, value); - } - - public bool ToggleStatus - { - get => GetValue(ToggleStatusProperty); - set => SetValue(ToggleStatusProperty, value); - } - - public ProgressBarShowCase() - { - InitializeComponent(); - DataContext = this; - - TwoStopsGradientStrokeColor = new LinearGradientBrush - { - GradientStops = - { - new GradientStop(Color.Parse("#108ee9"), 0), - new GradientStop(Color.Parse("#87d068"), 1) - } - }; - ThreeStopsGradientStrokeColor = new LinearGradientBrush - { - GradientStops = - { - new GradientStop(Color.Parse("#87d068"), 0), - new GradientStop(Color.Parse("#ffe58f"), 0.5), - new GradientStop(Color.Parse("#ffccc7"), 1) - } - }; - StepsChunkBrushes = new List - { - new SolidColorBrush(Colors.Green), - new SolidColorBrush(Colors.Green), - new SolidColorBrush(Colors.Red) - }; - - InnerStartPercentPosition = new PercentPosition - { - IsInner = true, - Alignment = LinePercentAlignment.Start - }; - InnerCenterPercentPosition = new PercentPosition - { - IsInner = true, - Alignment = LinePercentAlignment.Center - }; - InnerEndPercentPosition = new PercentPosition - { - IsInner = true, - Alignment = LinePercentAlignment.End - }; - - OutterStartPercentPosition = new PercentPosition - { - IsInner = false, - Alignment = LinePercentAlignment.Start - }; - OutterCenterPercentPosition = new PercentPosition - { - IsInner = false, - Alignment = LinePercentAlignment.Center - }; - OutterEndPercentPosition = new PercentPosition - { - IsInner = false, - Alignment = LinePercentAlignment.End - }; - } - - public void AddProgressValue() - { - var value = ProgressValue; - value += 10; - ProgressValue = Math.Min(value, 100); - } - - public void SubProgressValue() - { - var value = ProgressValue; - value -= 10; - ProgressValue = Math.Max(value, 0); - } - - public void ToggleEnabledStatus() - { - ToggleStatus = !ToggleStatus; - if (ToggleStatus) - { - ToggleDisabledText = "Disable"; - } - else - { - ToggleDisabledText = "Enable"; - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml deleted file mode 100644 index cb49aba..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml +++ /dev/null @@ -1,185 +0,0 @@ - - - - - - - - Radio - - - - - - - Radio1 - Radio2 - - - toggle disabled - - - - - - - A - B - C - D - - - - - - Option A - Option B - Option C - Option D - - - - - - - Apple - Pear - Orange - - - Apple - Pear - Orange - - - - - Apple - Pear - Orange - - - - Apple - Pear - Orange - - - - - - - - Hangzhou - Shanghai - Beijing - Chengdu - - - - Hangzhou - Shanghai - Beijing - Chengdu - - - - - Hangzhou - Shanghai - Beijing - Chengdu - - - - - - - - - - Hangzhou - Shanghai - Beijing - Chengdu - - - - Hangzhou - Shanghai - Beijing - Chengdu - - - - - Hangzhou - Shanghai - Beijing - Chengdu - - - - - - - - - Hangzhou - Shanghai - Beijing - Chengdu - - - - Hangzhou - Shanghai - Beijing - Chengdu - - - - - Hangzhou - Shanghai - Beijing - Chengdu - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml.cs deleted file mode 100644 index fc8766f..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/RadioButtonShowCase.axaml.cs +++ /dev/null @@ -1,35 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class RadioButtonShowCase : UserControl -{ - protected List CheckRadios { get; set; } - - public RadioButtonShowCase() - { - CheckRadios = new List - { - "ToggleDisabledRadioUnChecked", - "ToggleDisabledRadioChecked" - }; - InitializeComponent(); - } - - public static void ToggleDisabledStatus(object arg) - { - var btn = (arg as Button)!; - var stackPanel = btn.Parent as StackPanel; - var radioBtn1 = stackPanel?.FindControl("ToggleDisabledRadioUnChecked"); - var radioBtn2 = stackPanel?.FindControl("ToggleDisabledRadioChecked"); - if (radioBtn1 != null) - { - radioBtn1.IsEnabled = !radioBtn1.IsEnabled; - } - - if (radioBtn2 != null) - { - radioBtn2.IsEnabled = !radioBtn2.IsEnabled; - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml deleted file mode 100644 index 1db81db..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml +++ /dev/null @@ -1,134 +0,0 @@ - - - - - - Daily - Weekly - Monthly - Quarterly - Yearly - - - - - - - - 123 - 456 - longtext-longtext-longtext-longtext - - - - - - - - Map - Transit - Satellite - - - Daily - Weekly - Monthly - Quarterly - Yearly - - - - - - - - Daily - Weekly - Monthly - Quarterly - Yearly - - - - Daily - Weekly - Monthly - Quarterly - Yearly - - - - Daily - Weekly - Monthly - Quarterly - Yearly - - - - - - - - - - - - - - - - - - List - - - - - - - Ava 牛逼 - - - - - - - - - - Ava 牛逼 - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml.cs deleted file mode 100644 index 6033ca1..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SegmentedShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class SegmentedShowCase : UserControl -{ - public SegmentedShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml deleted file mode 100644 index 3d70c9d..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml +++ /dev/null @@ -1,104 +0,0 @@ - - - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed nonne merninisti licere mihi ista probare, quae sunt a te dicta? Refert tamen, quo modo. - - - - - - - - Item1 - - - - Item2 - - - - Item3 - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml.cs deleted file mode 100644 index ae05067..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SeparatorShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class SeparatorShowCase : UserControl -{ - public SeparatorShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SliderShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/SliderShowCase.axaml deleted file mode 100644 index e549789..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SliderShowCase.axaml +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - - - - - - Disabled: - - - - - - - - - - - - - - - - - - - - - - - - - - included=true - - - - - included=false - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SliderShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/SliderShowCase.axaml.cs deleted file mode 100644 index 444abb5..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SliderShowCase.axaml.cs +++ /dev/null @@ -1,43 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Collections; -using Avalonia.Controls; -using Avalonia.Media; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class SliderShowCase : UserControl -{ - public static readonly StyledProperty?> SliderMarksProperty = - AvaloniaProperty.Register?>(nameof(SliderMarks)); - - public static readonly StyledProperty NormalDisabledProperty = - AvaloniaProperty.Register(nameof(NormalEnabled), true); - - public AvaloniaList? SliderMarks - { - get => GetValue(SliderMarksProperty); - set => SetValue(SliderMarksProperty, value); - } - - public bool NormalEnabled - { - get => GetValue(NormalDisabledProperty); - set => SetValue(NormalDisabledProperty, value); - } - - public SliderShowCase() - { - InitializeComponent(); - SliderMarks = new AvaloniaList(); - SliderMarks.Add(new SliderMark("0°C", 0)); - SliderMarks.Add(new SliderMark("26°C", 26)); - SliderMarks.Add(new SliderMark("37°C", 37)); - SliderMarks.Add(new SliderMark("100°C", 100) - { - LabelFontWeight = FontWeight.Bold, - LabelBrush = new SolidColorBrush(Colors.Red) - }); - DataContext = this; - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SplitButtonShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/SplitButtonShowCase.axaml deleted file mode 100644 index 4f80620..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SplitButtonShowCase.axaml +++ /dev/null @@ -1,243 +0,0 @@ - - - - - Hover me - - - - - - - - - - - - - - - - - - Large - - - - - - - - - - Middle - - - - - - - - - - Small - - - - - - - - - - - - Large - - - - - - - - - - Middle - - - - - - - - - - Small - - - - - - - - - - - - - - - - - - - Default - - - - - - - - - - - Primary - - - - - - - - - - - - - - - - - - Default - - - - - - - - - - - Primary - - - - - - - - - - - - - - - - - - Hover Me - - - - - - - - - - - Click Me - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SplitButtonShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/SplitButtonShowCase.axaml.cs deleted file mode 100644 index 324936c..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SplitButtonShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class SplitButtonShowCase : UserControl -{ - public SplitButtonShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SwitchShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/SwitchShowCase.axaml deleted file mode 100644 index 55172df..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SwitchShowCase.axaml +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - - - - - - - toggle disabled - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - toggle loading - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/SwitchShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/SwitchShowCase.axaml.cs deleted file mode 100644 index b7c0141..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/SwitchShowCase.axaml.cs +++ /dev/null @@ -1,36 +0,0 @@ -using Avalonia.Controls; -using Button = AtomUI.Controls.Button; -using ToggleSwitch = AtomUI.Controls.ToggleSwitch; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class SwitchShowCase : UserControl -{ - public SwitchShowCase() - { - InitializeComponent(); - } - - public static void ToggleDisabledStatus(object arg) - { - var switchBtn = (arg as ToggleSwitch)!; - switchBtn.IsEnabled = !switchBtn.IsEnabled; - } - - public static void ToggleLoadingStatus(object arg) - { - var btn = (arg as Button)!; - var stackPanel = btn.Parent as StackPanel; - var toggleSwitchDefault = stackPanel?.Children[0] as ToggleSwitch; - var toggleSwitchSmall = stackPanel?.Children[1] as ToggleSwitch; - if (toggleSwitchDefault is not null) - { - toggleSwitchDefault.IsLoading = !toggleSwitchDefault.IsLoading; - } - - if (toggleSwitchSmall is not null) - { - toggleSwitchSmall.IsLoading = !toggleSwitchSmall.IsLoading; - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TabControlShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/TabControlShowCase.axaml deleted file mode 100644 index 08ce3fa..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TabControlShowCase.axaml +++ /dev/null @@ -1,481 +0,0 @@ - - - - - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - - - - - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - - - - - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - - - - - - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - - - - - - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - Content of Tab Pane 4 - Content of Tab Pane 5 - Content of Tab Pane 6 - Content of Tab Pane 7 - Content of Tab Pane 8 - Content of Tab Pane 9 - Content of Tab Pane 10 - Content of Tab Pane 11 - Content of Tab Pane 12 - Content of Tab Pane 13 - Content of Tab Pane 14 - Content of Tab Pane 15 - Content of Tab Pane 16 - Content of Tab Pane 17 - Content of Tab Pane 18 - Content of Tab Pane 19 - Content of Tab Pane 20 - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - Content of Tab Pane 4 - Content of Tab Pane 5 - Content of Tab Pane 6 - Content of Tab Pane 7 - Content of Tab Pane 8 - Content of Tab Pane 9 - Content of Tab Pane 10 - Content of Tab Pane 11 - Content of Tab Pane 12 - Content of Tab Pane 13 - Content of Tab Pane 14 - Content of Tab Pane 15 - Content of Tab Pane 16 - Content of Tab Pane 17 - Content of Tab Pane 18 - Content of Tab Pane 19 - Content of Tab Pane 20 - - - - - - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - - - - - - - - - Tab position: - - Top - Bottom - Left - Right - - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - Content of Tab Pane 4 - Content of Tab Pane 5 - Content of Tab Pane 6 - Content of Tab Pane 7 - Content of Tab Pane 8 - - - - - - - - - Tab position: - - Top - Bottom - Left - Right - - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - Content of Tab Pane 4 - Content of Tab Pane 5 - Content of Tab Pane 6 - Content of Tab Pane 7 - Content of Tab Pane 8 - Content of Tab Pane 9 - Content of Tab Pane 10 - Content of Tab Pane 11 - Content of Tab Pane 12 - - - - - - - - - Tab position: - - Small - Middle - Large - - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - Content of Tab Pane 4 - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - Content of Tab Pane 4 - - - - - - - - Content of Tab Pane 1 - Content of Tab Pane 2 - Content of Tab Pane 3 - Content of Tab Pane 4 - - - - - - - - - - - - Tab 1 - Tab 2 - Tab 3 - - - - - - - - Tab 1 - Tab 2 - Tab 3 - - - - Tab 1 - Tab 2 - Tab 3 - - - - - - - - Tab 1 - Tab 2 - Tab 3 - - - - Tab 1 - Tab 2 - Tab 3 - - - - - - - - - Tab 1 - Tab 2 - Tab 3 - - - - - - - - Tab 1 - Tab 2 - Tab 3 - Tab 4 - Tab 5 - Tab 6 - Tab 7 - Tab 8 - Tab 9 - Tab 10 - Tab 11 - Tab 12 - Tab 13 - Tab 14 - Tab 15 - Tab 16 - Tab 17 - Tab 18 - Tab 19 - Tab 20 - Tab 21 - Tab 22 - Tab 23 - - - - - - - - Tab 1 - Tab 2 - Tab 3 - Tab 4 - - - - - - - - - Tab position: - - Top - Bottom - Left - Right - - - - - - Tab 1 - Tab 2 - Tab 3 - Tab 4 - - - Tab Content - - - - - - - - - - Tab position: - - Top - Bottom - Left - Right - - - - - - Tab 1 - Tab 2 - Tab 3 - Tab 4 - - - Tab Content - - - - - - - - - - Tab position: - - Small - Middle - Large - - - - - Tab 1 - Tab 2 - Tab 3 - Tab 4 - - - - Tab 1 - Tab 2 - Tab 3 - Tab 4 - - - - - - - - - Tab 1 - Tab 2 - Tab 3 - Tab 4 - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TabControlShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/TabControlShowCase.axaml.cs deleted file mode 100644 index d557d50..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TabControlShowCase.axaml.cs +++ /dev/null @@ -1,228 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Interactivity; -using TabItem = AtomUI.Controls.TabItem; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class TabControlShowCase : UserControl -{ - #region TabStrip - - public static readonly StyledProperty PositionTabStripPlacementProperty = - AvaloniaProperty.Register(nameof(PositionTabStripPlacement), Dock.Top); - - public static readonly StyledProperty PositionCardTabStripPlacementProperty = - AvaloniaProperty.Register(nameof(PositionCardTabStripPlacement), Dock.Top); - - public static readonly StyledProperty SizeTypeTabStripProperty = - AvaloniaProperty.Register(nameof(SizeTypeTabStrip), SizeType.Middle); - - public Dock PositionTabStripPlacement - { - get => GetValue(PositionTabStripPlacementProperty); - set => SetValue(PositionTabStripPlacementProperty, value); - } - - public Dock PositionCardTabStripPlacement - { - get => GetValue(PositionCardTabStripPlacementProperty); - set => SetValue(PositionCardTabStripPlacementProperty, value); - } - - public SizeType SizeTypeTabStrip - { - get => GetValue(SizeTypeTabStripProperty); - set => SetValue(SizeTypeTabStripProperty, value); - } - - #endregion - - #region TabControl - - public static readonly StyledProperty PositionTabControlPlacementProperty = - AvaloniaProperty.Register(nameof(PositionTabControlPlacement), Dock.Top); - - public static readonly StyledProperty PositionCardTabControlPlacementProperty = - AvaloniaProperty.Register(nameof(PositionCardTabControlPlacement), Dock.Top); - - public static readonly StyledProperty SizeTypeTabControlProperty = - AvaloniaProperty.Register(nameof(SizeTypeTabControl), SizeType.Middle); - - public Dock PositionTabControlPlacement - { - get => GetValue(PositionTabControlPlacementProperty); - set => SetValue(PositionTabControlPlacementProperty, value); - } - - public Dock PositionCardTabControlPlacement - { - get => GetValue(PositionCardTabControlPlacementProperty); - set => SetValue(PositionCardTabControlPlacementProperty, value); - } - - public SizeType SizeTypeTabControl - { - get => GetValue(SizeTypeTabControlProperty); - set => SetValue(SizeTypeTabControlProperty, value); - } - - #endregion - - public TabControlShowCase() - { - InitializeComponent(); - DataContext = this; - PositionTabStripOptionGroup.OptionCheckedChanged += HandleTabStripPlacementOptionCheckedChanged; - PositionCardTabStripOptionGroup.OptionCheckedChanged += HandleCardTabStripPlacementOptionCheckedChanged; - SizeTypeTabStripOptionGroup.OptionCheckedChanged += HandleTabStripSizeTypeOptionCheckedChanged; - AddTabDemoStrip.AddTabRequest += HandleTabStripAddTabRequest; - - PositionTabControlOptionGroup.OptionCheckedChanged += HandleTabControlPlacementOptionCheckedChanged; - PositionCardTabControlOptionGroup.OptionCheckedChanged += HandleCardTabControlPlacementOptionCheckedChanged; - SizeTypeTabControlOptionGroup.OptionCheckedChanged += HandleTabControlSizeTypeOptionCheckedChanged; - AddTabDemoTabControl.AddTabRequest += HandleTabControlAddTabRequest; - } - - #region TabStrip - - private void HandleTabStripPlacementOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) - { - PositionTabStripPlacement = Dock.Top; - } - else if (args.Index == 1) - { - PositionTabStripPlacement = Dock.Bottom; - } - else if (args.Index == 2) - { - PositionTabStripPlacement = Dock.Left; - } - else - { - PositionTabStripPlacement = Dock.Right; - } - } - - private void HandleCardTabStripPlacementOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) - { - PositionCardTabStripPlacement = Dock.Top; - } - else if (args.Index == 1) - { - PositionCardTabStripPlacement = Dock.Bottom; - } - else if (args.Index == 2) - { - PositionCardTabStripPlacement = Dock.Left; - } - else - { - PositionCardTabStripPlacement = Dock.Right; - } - } - - private void HandleTabStripSizeTypeOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) - { - SizeTypeTabStrip = SizeType.Small; - } - else if (args.Index == 1) - { - SizeTypeTabStrip = SizeType.Middle; - } - else - { - SizeTypeTabStrip = SizeType.Large; - } - } - - private void HandleTabStripAddTabRequest(object? sender, RoutedEventArgs args) - { - var index = AddTabDemoStrip.ItemCount; - AddTabDemoStrip.Items.Add(new TabStripItem - { - Content = $"new tab {index}", - IsClosable = true - }); - } - - #endregion - - #region TabControl - - private void HandleTabControlPlacementOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) - { - PositionTabControlPlacement = Dock.Top; - } - else if (args.Index == 1) - { - PositionTabControlPlacement = Dock.Bottom; - } - else if (args.Index == 2) - { - PositionTabControlPlacement = Dock.Left; - } - else - { - PositionTabControlPlacement = Dock.Right; - } - } - - private void HandleCardTabControlPlacementOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) - { - PositionCardTabControlPlacement = Dock.Top; - } - else if (args.Index == 1) - { - PositionCardTabControlPlacement = Dock.Bottom; - } - else if (args.Index == 2) - { - PositionCardTabControlPlacement = Dock.Left; - } - else - { - PositionCardTabControlPlacement = Dock.Right; - } - } - - private void HandleTabControlSizeTypeOptionCheckedChanged(object? sender, OptionCheckedChangedEventArgs args) - { - if (args.Index == 0) - { - SizeTypeTabControl = SizeType.Small; - } - else if (args.Index == 1) - { - SizeTypeTabControl = SizeType.Middle; - } - else - { - SizeTypeTabControl = SizeType.Large; - } - } - - private void HandleTabControlAddTabRequest(object? sender, RoutedEventArgs args) - { - var index = AddTabDemoTabControl.ItemCount; - AddTabDemoTabControl.Items.Add(new TabItem - { - Header = $"new tab {index}", - Content = $"new tab content {index}", - IsClosable = true - }); - } - - #endregion -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TagShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/TagShowCase.axaml deleted file mode 100644 index f8d96fa..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TagShowCase.axaml +++ /dev/null @@ -1,186 +0,0 @@ - - - - - - - - Tag 1 - Link - Prevent Default - - - - - Tag 2 - - - - - - - Presets - - magenta - red - volcano - orange - gold - lime - green - cyan - blue - geekblue - purple - - - Custom - - #f50 - #2db7f5 - #87d068 - #108ee9 - - - - - - - - Without icon - - success - processing - error - warning - default - - - Custom - - - - - - success - - - - - - processing - - - - - - error - - - - - - warning - - - - - - default - - - - - - default - - - - - - - - - - - - - Twitter - - - - - - Youtube - - - - - - Facebook - - - - - - Linkedin - - - - - - - - Tag1 - Tag2 - Tag3 - Tag4 - - - - - magenta - red - volcano - orange - gold - lime - green - cyan - blue - geekblue - purple - - success - processing - error - warning - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TagShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/TagShowCase.axaml.cs deleted file mode 100644 index a0cec81..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TagShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class TagShowCase : UserControl -{ - public TagShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TimePickerShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/TimePickerShowCase.axaml deleted file mode 100644 index 45f8ce6..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TimePickerShowCase.axaml +++ /dev/null @@ -1,156 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TimePickerShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/TimePickerShowCase.axaml.cs deleted file mode 100644 index a5a7b78..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TimePickerShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class TimePickerShowCase : UserControl -{ - public TimePickerShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TimelineShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/TimelineShowCase.axaml deleted file mode 100644 index 9266649..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TimelineShowCase.axaml +++ /dev/null @@ -1,169 +0,0 @@ - - - - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-08-12 After more than 7 months of development, AtomUI is officially open-source. - Welcome everyone to follow us. - - - - - 2024-10-01 Release of the 0.0.1 Preview Version - - - - - - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - - - - - - - 2024-01-01 AtomUI Officially Initiated. 1 - - - - - 2024-01-01 AtomUI Officially Initiated. 2 - - - - - 2024-01-01 AtomUI Officially Initiated. 3 - - - - - Toggle Reverse - - - - - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - - - - - Left - Right - Alternate - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - - - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - 2024-01-01 AtomUI Officially Initiated - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TimelineShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/TimelineShowCase.axaml.cs deleted file mode 100644 index 2218ab3..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TimelineShowCase.axaml.cs +++ /dev/null @@ -1,49 +0,0 @@ -using AtomUI.Controls; -using Avalonia.Controls; -using Avalonia.Markup.Xaml; -using Avalonia.Media; -using RadioButton = Avalonia.Controls.RadioButton; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class TimelineShowCase : UserControl -{ - - public TimelineShowCase() - { - InitializeComponent(); - - ModeLeft.Checked += ModeChecked; - - ModeRight.Checked += ModeChecked; - - ModeAlternate.Checked += ModeChecked; - - ReverseButton.Click += ReverseButtonClick; - - } - - private void ReverseButtonClick(object? sender, Avalonia.Interactivity.RoutedEventArgs e) - { - ReverseTimeline.Reverse = !ReverseTimeline.Reverse; - } - - private void ModeChecked(object? sender, Avalonia.Interactivity.RoutedEventArgs e) - { - if (sender is RadioButton radioButton) - { - if (radioButton.Content?.ToString() == "Left") - { - LabelTimeline.Mode = TimeLineMode.Left; - } - else if (radioButton.Content?.ToString() == "Right") - { - LabelTimeline.Mode = TimeLineMode.Right; - } - else if (radioButton.Content?.ToString() == "Alternate") - { - LabelTimeline.Mode = TimeLineMode.Alternate; - } - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml deleted file mode 100644 index 9962a68..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml +++ /dev/null @@ -1,11 +0,0 @@ - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml.cs deleted file mode 100644 index 533f12a..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TitleBarShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class TitleBarShowCase : UserControl -{ - public TitleBarShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml deleted file mode 100644 index 2d1f375..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml +++ /dev/null @@ -1,11 +0,0 @@ - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml.cs deleted file mode 100644 index 4771d92..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/ToolBarShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class ToolBarShowCase : UserControl -{ - public ToolBarShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TooltipShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/TooltipShowCase.axaml deleted file mode 100644 index 9ca06e0..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TooltipShowCase.axaml +++ /dev/null @@ -1,324 +0,0 @@ - - - - - - Tooltip will show on mouse enter. - prompt text - - - - - - - - - - - - - - - - - - - - - - - - - - prompt text - LeftEdgeAlignedTop - - - prompt text - Left - - - prompt text - LeftEdgeAlignedBottom - - - - prompt text - TopEdgeAlignedLeft - - - prompt text - Top - - - prompt text - TopEdgeAlignedRight - - - - prompt text - RightEdgeAlignedTop - - - prompt text - Right - - - prompt text - RightEdgeAlignedBottom - - - - prompt text - BottomEdgeAlignedLeft - - - prompt text - Bottom - - - prompt text - BottomEdgeAlignedRight - - - - - - - - - Show - Hide - Center - - - - - - - - - - - - - - - - - - - - - - prompt text - LeftEdgeAlignedTop - - - prompt text - Left - - - prompt text - LeftEdgeAlignedBottom - - - - prompt text - TopEdgeAlignedLeft - - - prompt text - Top - - - prompt text - TopEdgeAlignedRight - - - - prompt text - RightEdgeAlignedTop - - - - prompt text - Right - - - - prompt text - RightEdgeAlignedBottom - - - - prompt text - BottomEdgeAlignedLeft - - - - prompt text - Bottom - - - - prompt text - BottomEdgeAlignedRight - - - - - - - - - - - - Presets - - - prompt text - Top - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - Custom - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - prompt text - Top - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TooltipShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/TooltipShowCase.axaml.cs deleted file mode 100644 index 99e109d..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TooltipShowCase.axaml.cs +++ /dev/null @@ -1,54 +0,0 @@ -using AtomUI.Controls; -using Avalonia; -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class TooltipShowCase : UserControl -{ - public static readonly StyledProperty ShowArrowProperty = - AvaloniaProperty.Register(nameof(ShowArrow), true); - - public static readonly StyledProperty IsPointAtCenterProperty = - AvaloniaProperty.Register(nameof(IsPointAtCenter)); - - private readonly Segmented _segmented; - - public bool ShowArrow - { - get => GetValue(ShowArrowProperty); - set => SetValue(ShowArrowProperty, value); - } - - public bool IsPointAtCenter - { - get => GetValue(IsPointAtCenterProperty); - set => SetValue(IsPointAtCenterProperty, value); - } - - public TooltipShowCase() - { - DataContext = this; - InitializeComponent(); - var control = this as Control; - _segmented = control.FindControl("ArrowSegmented")!; - _segmented.SelectionChanged += (sender, args) => - { - if (_segmented.SelectedIndex == 0) - { - ShowArrow = true; - IsPointAtCenter = false; - } - else if (_segmented.SelectedIndex == 1) - { - ShowArrow = false; - IsPointAtCenter = false; - } - else if (_segmented.SelectedIndex == 2) - { - IsPointAtCenter = true; - ShowArrow = true; - } - }; - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TreeViewShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/TreeViewShowCase.axaml deleted file mode 100644 index 8ce42ca..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TreeViewShowCase.axaml +++ /dev/null @@ -1,122 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - showLine: - - - - - showIcon: - - - - - ShowLeafSwitcher: - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/TreeViewShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/TreeViewShowCase.axaml.cs deleted file mode 100644 index 1433d58..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/TreeViewShowCase.axaml.cs +++ /dev/null @@ -1,40 +0,0 @@ -using Avalonia; -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class TreeViewShowCase : UserControl -{ - public static readonly StyledProperty ShowLineSwitchCheckedProperty = - AvaloniaProperty.Register(nameof(ShowLineSwitchChecked), true); - - public static readonly StyledProperty ShowIconSwitchCheckedProperty = - AvaloniaProperty.Register(nameof(ShowIconSwitchChecked)); - - public static readonly StyledProperty ShowLeafSwitcherSwitchCheckedProperty = - AvaloniaProperty.Register(nameof(ShowLeafSwitcherSwitchChecked)); - - public bool ShowLineSwitchChecked - { - get => GetValue(ShowLineSwitchCheckedProperty); - set => SetValue(ShowLineSwitchCheckedProperty, value); - } - - public bool ShowIconSwitchChecked - { - get => GetValue(ShowIconSwitchCheckedProperty); - set => SetValue(ShowIconSwitchCheckedProperty, value); - } - - public bool ShowLeafSwitcherSwitchChecked - { - get => GetValue(ShowLeafSwitcherSwitchCheckedProperty); - set => SetValue(ShowLeafSwitcherSwitchCheckedProperty, value); - } - - public TreeViewShowCase() - { - InitializeComponent(); - DataContext = this; - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/WatermarkShowCase.axaml b/samples/AtomUI.Demo.Desktop/ShowCase/WatermarkShowCase.axaml deleted file mode 100644 index 491e3f4..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/WatermarkShowCase.axaml +++ /dev/null @@ -1,46 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - The light-speed iteration of the digital world makes products more complex. However, human consciousness and attention resources are limited. Facing this design contradiction, the pursuit of natural interaction will be the consistent direction of Ant Design. - - Natural user cognition: According to cognitive psychology, about 80% of external information is obtained through visual channels. The most important visual elements in the interface design, including layout, colors, illustrations, icons, etc., should fully absorb the laws of nature, thereby reducing the user's cognitive cost and bringing authentic and smooth feelings. In some scenarios, opportunely adding other sensory channels such as hearing, touch can create a richer and more natural product experience. - - Natural user behavior: In the interaction with the system, the designer should fully understand the relationship between users, system roles, and task objectives, and also contextually organize system functions and services. At the same time, a series of methods such as behavior analysis, artificial intelligence and sensors could be applied to assist users to make effective decisions and reduce extra operations of users, to save users' mental and physical resources and make human-computer interaction more natural. - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ShowCase/WatermarkShowCase.axaml.cs b/samples/AtomUI.Demo.Desktop/ShowCase/WatermarkShowCase.axaml.cs deleted file mode 100644 index 7a4ab75..0000000 --- a/samples/AtomUI.Demo.Desktop/ShowCase/WatermarkShowCase.axaml.cs +++ /dev/null @@ -1,11 +0,0 @@ -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.ShowCase; - -public partial class WatermarkShowCase : UserControl -{ - public WatermarkShowCase() - { - InitializeComponent(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Themes/TabMenu.axaml b/samples/AtomUI.Demo.Desktop/Themes/TabMenu.axaml deleted file mode 100644 index 0a1d6fe..0000000 --- a/samples/AtomUI.Demo.Desktop/Themes/TabMenu.axaml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Themes/ToggleButton.axaml b/samples/AtomUI.Demo.Desktop/Themes/ToggleButton.axaml deleted file mode 100644 index 96805b5..0000000 --- a/samples/AtomUI.Demo.Desktop/Themes/ToggleButton.axaml +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Utils/EnumExtension.cs b/samples/AtomUI.Demo.Desktop/Utils/EnumExtension.cs deleted file mode 100644 index f66f8c6..0000000 --- a/samples/AtomUI.Demo.Desktop/Utils/EnumExtension.cs +++ /dev/null @@ -1,26 +0,0 @@ -using Avalonia.Markup.Xaml; - -namespace AtomUI.Demo.Desktop; - -/// -/// Xaml markup to get the enum values. -/// -/// TODO 优化性能时可以考虑缓存类型和列表 -public class EnumExtension : MarkupExtension -{ - [ConstructorArgument(nameof(Type))] public Type Type { get; set; } - - public EnumExtension(Type type) - { - Type = type; - } - - public override object ProvideValue(IServiceProvider serviceProvider) - { - // Issue I7: - // Array can not perform well for Items of ListBox. - // Version : 11.0.0-preview4 - // By nlb at 2023.3.28. - return Enum.GetValuesAsUnderlyingType(Type).OfType().ToList(); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ViewModels/CheckBoxShowCaseModel.cs b/samples/AtomUI.Demo.Desktop/ViewModels/CheckBoxShowCaseModel.cs deleted file mode 100644 index 67a49dc..0000000 --- a/samples/AtomUI.Demo.Desktop/ViewModels/CheckBoxShowCaseModel.cs +++ /dev/null @@ -1,193 +0,0 @@ -using CommunityToolkit.Mvvm.ComponentModel; - -namespace AtomUI.Demo.Desktop.ViewModels; - -public class CheckBoxShowCaseModel : ObservableObject -{ - public bool? _controlledCheckBoxCheckedStatus; - - public bool? ControlledCheckBoxCheckedStatus - { - get => _controlledCheckBoxCheckedStatus; - set => SetProperty(ref _controlledCheckBoxCheckedStatus, value); - } - - public bool _controlledCheckBoxEnabledStatus; - - public bool ControlledCheckBoxEnabledStatus - { - get => _controlledCheckBoxEnabledStatus; - set => SetProperty(ref _controlledCheckBoxEnabledStatus, value); - } - - private string? _checkStatusBtnText; - - public string? CheckStatusBtnText - { - get => _checkStatusBtnText; - set => SetProperty(ref _checkStatusBtnText, value); - } - - private string? _enableStatusBtnText; - - public string? EnableStatusBtnText - { - get => _enableStatusBtnText; - set => SetProperty(ref _enableStatusBtnText, value); - } - - private string? _controlledCheckBoxText; - - public string? ControlledCheckBoxText - { - get => _controlledCheckBoxText; - set => SetProperty(ref _controlledCheckBoxText, value); - } - - // CheckAll 例子 - private bool? _checkedAllStatus; - - public bool? CheckedAllStatus - { - get => _checkedAllStatus; - set => SetProperty(ref _checkedAllStatus, value); - } - - private bool _appleCheckedStatus; - - public bool AppleCheckedStatus - { - get => _appleCheckedStatus; - set => SetProperty(ref _appleCheckedStatus, value); - } - - private bool _pearCheckedStatus; - - public bool PearCheckedStatus - { - get => _pearCheckedStatus; - set => SetProperty(ref _pearCheckedStatus, value); - } - - private bool _orangeCheckedStatus; - - public bool OrangeCheckedStatus - { - get => _orangeCheckedStatus; - set => SetProperty(ref _orangeCheckedStatus, value); - } - - public CheckBoxShowCaseModel() - { - CheckStatusBtnText = "UnCheck"; - EnableStatusBtnText = "Disable"; - ControlledCheckBoxCheckedStatus = true; - ControlledCheckBoxEnabledStatus = true; - SetupControlledCheckBoxText(); - - AppleCheckedStatus = false; - PearCheckedStatus = true; - OrangeCheckedStatus = true; - CheckedAllStatus = null; - } - - public void CheckStatusHandler(object arg) - { - ControlledCheckBoxCheckedStatus = !ControlledCheckBoxCheckedStatus; - SetupCheckBtnText(); - SetupControlledCheckBoxText(); - } - - public void EnableStatusHandler(object arg) - { - ControlledCheckBoxEnabledStatus = !ControlledCheckBoxEnabledStatus; - SetupEnabledBtnText(); - SetupControlledCheckBoxText(); - } - - public void CheckBoxHandler(object arg) - { - SetupCheckBtnText(); - SetupControlledCheckBoxText(); - } - - private void SetupCheckBtnText() - { - if (ControlledCheckBoxCheckedStatus.HasValue) - { - if (ControlledCheckBoxCheckedStatus.Value) - { - CheckStatusBtnText = "UnCheck"; - } - else - { - CheckStatusBtnText = "Check"; - } - } - else - { - CheckStatusBtnText = "Check"; - } - } - - private void SetupEnabledBtnText() - { - if (ControlledCheckBoxEnabledStatus) - { - EnableStatusBtnText = "Disable"; - } - else - { - EnableStatusBtnText = "Enable"; - } - } - - private void SetupControlledCheckBoxText() - { - var checkedText = "UnChecked"; - if (ControlledCheckBoxCheckedStatus.HasValue && ControlledCheckBoxCheckedStatus.Value) - { - checkedText = "Checked"; - } - - var enabledText = "Disabled"; - if (ControlledCheckBoxEnabledStatus) - { - enabledText = "Enabled"; - } - - ControlledCheckBoxText = $"{checkedText}-{enabledText}"; - } - - public void CheckedAllStatusHandler() - { - if (!CheckedAllStatus.HasValue || !CheckedAllStatus.Value) - { - AppleCheckedStatus = false; - PearCheckedStatus = false; - OrangeCheckedStatus = false; - } - else - { - AppleCheckedStatus = true; - PearCheckedStatus = true; - OrangeCheckedStatus = true; - } - } - - public void CheckedItemStatusHandler(object arg) - { - if (OrangeCheckedStatus && PearCheckedStatus && AppleCheckedStatus) - { - CheckedAllStatus = true; - } - else if (!OrangeCheckedStatus && !PearCheckedStatus && !AppleCheckedStatus) - { - CheckedAllStatus = false; - } - else - { - CheckedAllStatus = null; - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ViewModels/DataGridDemoViewModel.cs b/samples/AtomUI.Demo.Desktop/ViewModels/DataGridDemoViewModel.cs deleted file mode 100644 index df65e44..0000000 --- a/samples/AtomUI.Demo.Desktop/ViewModels/DataGridDemoViewModel.cs +++ /dev/null @@ -1,162 +0,0 @@ -using System.Collections.ObjectModel; -using Avalonia.Collections; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Input; - -namespace AtomUI.Demo.Desktop.ViewModels; - -public class DataGridDemoViewModel : ObservableObject -{ - public ObservableCollection GridData1 { get; set; } - - public DataGridCollectionView GridData2 { get; set; } - - public ObservableCollection GridData3 { get; set; } - - public RelayCommand AddCommand { get; set; } - - public DataGridDemoViewModel() - { - GridData1 = new ObservableCollection(Song.Songs); - GridData2 = new DataGridCollectionView(Song.Songs); - GridData2.GroupDescriptions.Add(new DataGridPathGroupDescription("Album")); - GridData3 = new ObservableCollection(Song.Songs.Take(10).Select(a => new SongViewModel - { - Title = a.Title, - Artist = a.Artist, - Album = a.Album, - CountOfComment = a.CountOfComment, - IsSelected = false - })); - AddCommand = new RelayCommand(Add); - } - - private void Add() - { - GridData3.Add(new SongViewModel()); - } -} - -public class Song -{ - public string? Title { get; set; } - public string? Artist { get; set; } - public TimeSpan? Duration { get; set; } - public string? Album { get; set; } - public int CountOfComment { get; set; } - public string Url { get; set; } - - public Song(string title, string artist, int m, int s, string album, int countOfComment, int netEaseId) - { - Title = title; - Artist = artist; - Duration = new TimeSpan(0, m, s); - Album = album; - CountOfComment = countOfComment; - Url = $"https://music.163.com/song?id={netEaseId}"; - } - - public static List Songs { get; set; } = new() - { - new("好肚有肚(feat.李玲玉)", "熊猫堂ProducePandas", 2, 50, "A.S.I.A", 730, 1487039339), - new("荒诞秀", "熊猫堂ProducePandas", 3, 15, "A.S.I.A", 639, 1487037601), - new("长大", "熊猫堂ProducePandas", 4, 6, "A.S.I.A", 1114, 1487037690), - new("招财猫(feat.纪粹希(G-Tracy))", "熊猫堂ProducePandas", 3, 37, "A.S.I.A", 361, 1487039632), - new("千转", "熊猫堂ProducePandas", 4, 0, "A.S.I.A", 1115, 1477312398), - new("辣辣辣", "熊猫堂ProducePandas", 3, 24, "A.S.I.A", 1873, 1465043716), - new("碎碎念", "熊猫堂ProducePandas", 3, 25, "A.S.I.A", 676, 1474142064), - new("盘他", "熊猫堂ProducePandas", 2, 16, "A.S.I.A", 365, 1481652786), - new("Na Na Na", "熊猫堂ProducePandas", 3, 26, "A.S.I.A", 312, 1469022662), - new("Indigo", "熊猫堂ProducePandas", 3, 15, "A.S.I.A", 137, 1487039517), - new("饕餮人间", "熊猫堂ProducePandas", 3, 20, "饕餮人间", 1295, 1499584605), - new("七步咙咚呛", "熊猫堂ProducePandas", 3, 10, "七步咙咚呛", 175, 1809095152), - new("大惊小怪", "熊猫堂ProducePandas", 3, 32, "大惊小怪", 10420, 1847477425), - new("工具人", "熊猫堂ProducePandas", 2, 46, "大惊小怪", 1135, 1847476499), - new("以梦为马", "熊猫堂ProducePandas", 4, 19, "大惊小怪", 18361, 1836034373), - new("以梦为马(Piano Version)", "熊猫堂ProducePandas", 3, 4, "大惊小怪", 570, 1847477423), - new("The ONE", "熊猫堂ProducePandas", 2, 58, "The ONE", 1508, 1864329424), - new("The ONE(日文版)", "熊猫堂ProducePandas", 2, 57, "The ONE", 385, 1864329429), - new("以梦为马 (壮志骄阳版)", "熊猫堂ProducePandas", 4, 19, "以梦为马 (壮志骄阳版)", 161, 1865138896), - new("New Horse", "熊猫堂ProducePandas", 2, 30, "emo了", 643, 1887021307), - new("不例外", "熊猫堂ProducePandas", 3, 31, "emo了", 1818, 1887022665), - new("满意", "熊猫堂ProducePandas", 4, 32, "emo了", 1081, 1882433472), - new("就算与全世界为敌也要跟你在一起", "熊猫堂ProducePandas", 3, 32, "emo了", 2119, 1881759960), - new("The ONE", "熊猫堂ProducePandas", 2, 58, "emo了", 67, 1887022648), - new("口香糖", "熊猫堂ProducePandas", 3, 10, "emo了", 2181, 1885502254), - new("Suuuuuuper Mario", "熊猫堂ProducePandas", 3, 32, "emo了", 1010, 1887021318), - new("饕餮人间", "熊猫堂ProducePandas", 3, 22, "emo了", 109, 1887021320), - new("以梦为马 (壮志骄阳版)", "熊猫堂ProducePandas", 4, 21, "emo了", 34, 1887022666), - new("The ONE(日文版)", "熊猫堂ProducePandas", 2, 57, "emo了", 27, 1887022646), - new("满意(DJheap九天版)", "熊猫堂ProducePandas", 4, 31, "emo了", 31, 1901605941), - new("一眼万年", "熊猫堂ProducePandas", 3, 54, "一眼万年", 20, 1922599361), - new("冲刺", "熊猫堂ProducePandas", 3, 49, "冲刺吧", 1006, 1932878194), - new("滴答滴", "熊猫堂ProducePandas", 2, 30, "爱的赏味期限", 86, 1957515790), - new("热带季风", "熊猫堂ProducePandas", 2, 45, "爱的赏味期限", 212, 1957514964), - new("渣", "熊猫堂ProducePandas", 3, 28, "爱的赏味期限", 22, 1957514965), - new("独特", "熊猫堂ProducePandas", 3, 33, "爱的赏味期限", 62, 1957514966), - new("雨后", "熊猫堂ProducePandas", 4, 15, "爱的赏味期限", 23, 1957514967), - new("然后然后", "熊猫堂ProducePandas", 3, 50, "爱的赏味期限", 108, 1957514968), - new("丢", "熊猫堂ProducePandas", 3, 26, "爱的赏味期限", 30, 1957515792), - new("热带疾风(FACEVOID桃心连哥 Remix)", "熊猫堂ProducePandas", 3, 23, "爱的赏味期限", 55, 1957515793), - new("COSMIC ANTHEM -Japanese Ver.-", "熊猫堂ProducePandas", 3, 11, "COSMIC ANTHEM / 手紙", 0, 1977171493), - new("手紙 (「長大-You Raise Me Up-」-Japanese Ver.-)", "熊猫堂ProducePandas", 4, 11, "COSMIC ANTHEM / 手紙", 0, - 1977171494), - new("COSMIC ANTHEM -Chinese Ver.-", "熊猫堂ProducePandas", 3, 31, "COSMIC ANTHEM / 手紙", 0, 1977172202), - new("世界晚安", "熊猫堂ProducePandas", 2, 59, "世界晚安", 652, 1985063377), - new("世界晚安(泰文版)", "熊猫堂ProducePandas", 2, 59, "世界晚安", 134, 1987842504), - new("世界晚安(钢琴版)", "熊猫堂ProducePandas", 3, 2, "世界晚安", 76, 1990475933), - new("世界晚安(泰文钢琴版)", "熊猫堂ProducePandas", 3, 2, "世界晚安", 29, 1990475934), - new("世界晚安(DJ沈念版)", "熊猫堂ProducePandas", 3, 9, "世界晚安", 34, 2014263184), - new("世界晚安(钢琴配乐)", "熊猫堂ProducePandas", 2, 59, "世界晚安", 11, 2014263185), - new("明年也要好好长大", "熊猫堂ProducePandas", 3, 12, "明年也要好好长大", 0, 2010515162), - new("320万年前(DJ沈念版)", "熊猫堂ProducePandas", 3, 21, "320万年前", 8, 2055888636), - new("320万年前", "熊猫堂ProducePandas", 3, 7, "W.O.R.L.D.", 329, 2049770469), - new("隐德来希", "熊猫堂ProducePandas", 3, 3, "W.O.R.L.D.", 594, 2061317924), - new("孔明", "熊猫堂ProducePandas", 3, 59, "W.O.R.L.D.", 91, 2063175274), - new("锦鲤卟噜噜", "熊猫堂ProducePandas", 3, 5, "W.O.R.L.D.", 67, 2059208262), - new("指鹿为马", "熊猫堂ProducePandas", 3, 12, "W.O.R.L.D.", 74, 2063175272), - new("热带季风Remix", "熊猫堂ProducePandas", 3, 22, "W.O.R.L.D.", 23, 2063173319), - new("加州梦境", "熊猫堂ProducePandas", 2, 56, "W.O.R.L.D.", 1662, 2063173324), - new("渐近自由", "熊猫堂ProducePandas", 4, 19, "W.O.R.L.D.", 124, 2063173321), - new("世界所有的烂漫", "熊猫堂ProducePandas", 3, 30, "W.O.R.L.D.", 335, 2053388775) - }; -} - -public class SongViewModel : ObservableObject -{ - private string? _title; - private string? _artist; - private string? _album; - private int _countOfComment; - private bool? _isSelected; - - public string? Title - { - get => _title; - set => SetProperty(ref _title, value); - } - - public string? Artist - { - get => _artist; - set => SetProperty(ref _artist, value); - } - - public string? Album - { - get => _album; - set => SetProperty(ref _album, value); - } - - public int CountOfComment - { - get => _countOfComment; - set => SetProperty(ref _countOfComment, value); - } - - public bool? IsSelected - { - get => _isSelected; - set => SetProperty(ref _isSelected, value); - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ViewModels/PaletteDemoViewModel.cs b/samples/AtomUI.Demo.Desktop/ViewModels/PaletteDemoViewModel.cs deleted file mode 100644 index fff8529..0000000 --- a/samples/AtomUI.Demo.Desktop/ViewModels/PaletteDemoViewModel.cs +++ /dev/null @@ -1,244 +0,0 @@ -using System.Collections.ObjectModel; -using AtomUI.Theme.Palette; -using Avalonia.Media; -using CommunityToolkit.Mvvm.ComponentModel; -using CommunityToolkit.Mvvm.Messaging; -using SolidColorBrush = Avalonia.Media.SolidColorBrush; - -namespace AtomUI.Demo.Desktop.ViewModels; - -public class PaletteMetaItem -{ - public string Title; - public string Desc; - public PresetPrimaryColor PresetPrimaryColor; - - public PaletteMetaItem(string title, string desc, PresetPrimaryColor presetPrimaryColor) - { - Title = title; - Desc = desc; - PresetPrimaryColor = presetPrimaryColor; - } -} - -public class PaletteDemoViewModel : ObservableObject -{ - private readonly PaletteMetaItem[] _presetPaletteInfos = - { - new("Dust Red / 薄暮", "斗志、奔放", PresetPrimaryColor.Red), - new("Volcano / 火山", "醒目、澎湃", PresetPrimaryColor.Volcano), - new("Sunset Orange / 日暮", "温暖、欢快", PresetPrimaryColor.Orange), - new("Calendula Gold / 金盏花", "活力、积极", PresetPrimaryColor.Gold), - new("Sunrise Yellow / 日出", "出生、阳光", PresetPrimaryColor.Yellow), - new("Lime / 青柠", "自然、生机", PresetPrimaryColor.Lime), - new("Polar Green / 极光绿", "健康、创新", PresetPrimaryColor.Green), - new("Cyan / 明青", "希望、坚强", PresetPrimaryColor.Cyan), - new("Daybreak Blue / 拂晓蓝", "包容、科技、普惠", PresetPrimaryColor.Blue), - new("Geek Blue / 极客蓝", "探索、钻研", PresetPrimaryColor.GeekBlue), - new("Golden Purple / 酱紫", "优雅、浪漫", PresetPrimaryColor.Purple), - new("Magenta / 法式洋红", "明快、感性", PresetPrimaryColor.Magenta) - }; - - private ColorItemViewModel _selectedColor = null!; - - public ColorItemViewModel SelectedColor - { - get => _selectedColor; - set => SetProperty(ref _selectedColor, value); - } - - private ObservableCollection? _lightLists; - - public ObservableCollection? LightLists - { - get => _lightLists; - set => SetProperty(ref _lightLists, value); - } - - private ObservableCollection? _darkLists; - - public ObservableCollection? DarkLists - { - get => _darkLists; - set => SetProperty(ref _darkLists, value); - } - - public PaletteDemoViewModel() - { - WeakReferenceMessenger.Default.Register(this, OnClickColorItem); - } - - public void InitializeResources() - { - InitializePalette(); - } - - private void InitializePalette() - { - LightLists = new ObservableCollection(); - var cycleColorList = new ObservableCollection(); - var cycleCount = 0; - for (var i = 0; i < _presetPaletteInfos.Length; ++i) - { - var metaInfo = _presetPaletteInfos[i]; - var colorListViewModel = new ColorListViewModel(); - colorListViewModel.Title = metaInfo.Title; - colorListViewModel.Desc = metaInfo.Desc; - var paletteInfo = PresetPalettes.GetPresetPalette(metaInfo.PresetPrimaryColor); - var colorItemViewModels = new ObservableCollection(); - var presetColorName = metaInfo.PresetPrimaryColor.Name(); - - for (var j = 0; j < paletteInfo.ColorSequence.Count; j++) - { - var color = paletteInfo.ColorSequence[j]; - var colorItem = new ColorItemViewModel($"{presetColorName}-{j + 1}", - new SolidColorBrush(color), - true, - j); - colorItemViewModels.Add(colorItem); - } - - colorListViewModel.Colors = colorItemViewModels; - cycleColorList.Add(colorListViewModel); - ++cycleCount; - - if (cycleCount == 3) - { - var colorGroupModel = new ColorGroupViewModel(); - colorGroupModel.ColorList = cycleColorList; - LightLists.Add(colorGroupModel); - cycleColorList = new ObservableCollection(); - cycleCount = 0; - } - } - - DarkLists = new ObservableCollection(); - - for (var i = 0; i < _presetPaletteInfos.Length; ++i) - { - var metaInfo = _presetPaletteInfos[i]; - var colorListViewModel = new ColorListViewModel(); - colorListViewModel.Title = metaInfo.Title; - colorListViewModel.Desc = metaInfo.Desc; - var paletteInfo = PresetPalettes.GetPresetPalette(metaInfo.PresetPrimaryColor, true); - var colorItemViewModels = new ObservableCollection(); - var presetColorName = metaInfo.PresetPrimaryColor.Name(); - - for (var j = 0; j < paletteInfo.ColorSequence.Count; j++) - { - var color = paletteInfo.ColorSequence[j]; - var colorItem = new ColorItemViewModel($"{presetColorName}-{j + 1}", - new SolidColorBrush(color), - false, - j); - colorItemViewModels.Add(colorItem); - } - - colorListViewModel.Colors = colorItemViewModels; - cycleColorList.Add(colorListViewModel); - ++cycleCount; - - if (cycleCount == 3) - { - var colorGroupModel = new ColorGroupViewModel(); - colorGroupModel.ColorList = cycleColorList; - DarkLists.Add(colorGroupModel); - cycleColorList = new ObservableCollection(); - cycleCount = 0; - } - } - } - - private void OnClickColorItem(PaletteDemoViewModel vm, ColorItemViewModel item) - { - SelectedColor = item; - } -} - -public class ColorGroupViewModel : ObservableObject -{ - private ObservableCollection? _colorList; - - public ObservableCollection? ColorList - { - get => _colorList; - set => SetProperty(ref _colorList, value); - } -} - -public class ColorListViewModel : ObservableObject -{ - private ObservableCollection? _colors; - - public ObservableCollection? Colors - { - get => _colors; - set => SetProperty(ref _colors, value); - } - - private string? _title; - - public string? Title - { - get => _title; - set => SetProperty(ref _title, value); - } - - private string? _desc; - - public string? Desc - { - get => _desc; - set => SetProperty(ref _desc, value); - } -} - -public class ColorItemViewModel : ObservableObject -{ - private IBrush _brush = null!; - - public IBrush Brush - { - get => _brush; - set => SetProperty(ref _brush, value); - } - - private IBrush _textBrush = null!; - - public IBrush TextBrush - { - get => _textBrush; - set => SetProperty(ref _textBrush, value); - } - - private string _colorDisplayName = null!; - - public string ColorDisplayName - { - get => _colorDisplayName; - set => SetProperty(ref _colorDisplayName, value); - } - - private string _hex = null!; - - public string Hex - { - get => _hex; - set => SetProperty(ref _hex, value); - } - - public ColorItemViewModel(string colorDisplayName, ISolidColorBrush brush, bool light, int index) - { - ColorDisplayName = colorDisplayName; - Brush = brush; - Hex = brush.ToString()!.ToUpperInvariant(); - if ((light && index < 5) || (!light && index >= 5)) - { - TextBrush = Brushes.Black; - } - else - { - TextBrush = Brushes.White; - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ViewModels/PathIconModel.cs b/samples/AtomUI.Demo.Desktop/ViewModels/PathIconModel.cs deleted file mode 100644 index 5c15f9a..0000000 --- a/samples/AtomUI.Demo.Desktop/ViewModels/PathIconModel.cs +++ /dev/null @@ -1,70 +0,0 @@ -using System.Collections.ObjectModel; -using AtomUI.Icon; -using AtomUI.Icon.AntDesign; -using CommunityToolkit.Mvvm.ComponentModel; - -namespace AtomUI.Demo.Desktop.ViewModels; - -public class IconInfoItemModel : ObservableObject -{ - private string _iconName = null!; - - public string IconName - { - get => _iconName; - set => SetProperty(ref _iconName, value); - } - - private string _iconKind = null!; - - public string IconKind - { - get => _iconKind; - set => SetProperty(ref _iconKind, value); - } - - public IconInfoItemModel(string iconName, string iconKind) - { - IconName = iconName; - IconKind = iconKind; - } -} - -public class IconGalleryModel : ObservableObject -{ - private readonly IconThemeType? _iconThemeType; - - private ObservableCollection? _iconInfos; - - public ObservableCollection? IconInfos - { - get => _iconInfos; - set => SetProperty(ref _iconInfos, value); - } - - public IconGalleryModel(IconThemeType? iconThemeType = null) - { - _iconThemeType = iconThemeType; - if (_iconThemeType.HasValue) - { - LoadThemeIcons(_iconThemeType.Value); - } - } - - public void LoadThemeIcons(IconThemeType iconThemeType) - { - var iconPackage = IconManager.Current.GetIconProvider(); - if (iconPackage is null) - { - return; - } - - IconInfos = new ObservableCollection(); - var iconInfos = iconPackage.GetIconInfos(iconThemeType); - foreach (var iconInfo in iconInfos) - { - var iconInfoModel = new IconInfoItemModel(iconInfo.Name, iconInfo.Name); - IconInfos.Add(iconInfoModel); - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/ViewModels/TabControlDemoViewModel.cs b/samples/AtomUI.Demo.Desktop/ViewModels/TabControlDemoViewModel.cs deleted file mode 100644 index 6fb751a..0000000 --- a/samples/AtomUI.Demo.Desktop/ViewModels/TabControlDemoViewModel.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System.Collections.ObjectModel; -using CommunityToolkit.Mvvm.ComponentModel; - -namespace AtomUI.Demo.Desktop.ViewModels; - -public class TabControlDemoViewModel : ObservableObject -{ - public TabControlDemoViewModel() - { - Items = new ObservableCollection(Enumerable.Range(1, 200).Select(a => "Tab " + a)); - } - - public ObservableCollection Items { get; set; } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Views/MainView.axaml b/samples/AtomUI.Demo.Desktop/Views/MainView.axaml deleted file mode 100644 index 158ac51..0000000 --- a/samples/AtomUI.Demo.Desktop/Views/MainView.axaml +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Views/MainView.axaml.cs b/samples/AtomUI.Demo.Desktop/Views/MainView.axaml.cs deleted file mode 100644 index 4762fd8..0000000 --- a/samples/AtomUI.Demo.Desktop/Views/MainView.axaml.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Avalonia; -using Avalonia.Controls; -using Avalonia.Interactivity; -using Avalonia.Styling; - -namespace AtomUI.Demo.Desktop.Views; - -public partial class MainView : UserControl -{ - public MainView() - { - InitializeComponent(); - } - - private void ToggleButton_OnIsCheckedChanged(object sender, RoutedEventArgs e) - { - var app = Application.Current; - if (app is not null) - { - var theme = app.ActualThemeVariant; - app.RequestedThemeVariant = theme == ThemeVariant.Dark ? ThemeVariant.Light : ThemeVariant.Dark; - } - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Views/MainWindow.axaml b/samples/AtomUI.Demo.Desktop/Views/MainWindow.axaml deleted file mode 100644 index 9cfd635..0000000 --- a/samples/AtomUI.Demo.Desktop/Views/MainWindow.axaml +++ /dev/null @@ -1,15 +0,0 @@ - - - \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/Views/MainWindow.axaml.cs b/samples/AtomUI.Demo.Desktop/Views/MainWindow.axaml.cs deleted file mode 100644 index e3869dd..0000000 --- a/samples/AtomUI.Demo.Desktop/Views/MainWindow.axaml.cs +++ /dev/null @@ -1,15 +0,0 @@ -using Avalonia; -using Avalonia.Controls; - -namespace AtomUI.Demo.Desktop.Views; - -public partial class MainWindow : Window -{ - public MainWindow() - { - InitializeComponent(); -#if DEBUG - this.AttachDevTools(); -#endif - } -} \ No newline at end of file diff --git a/samples/AtomUI.Demo.Desktop/app.manifest b/samples/AtomUI.Demo.Desktop/app.manifest deleted file mode 100644 index 207806b..0000000 --- a/samples/AtomUI.Demo.Desktop/app.manifest +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/AtomUI.Base/AtomUI.Base.csproj b/src/AtomUI.Base/AtomUI.Base.csproj index 479b625..f7f2ebc 100644 --- a/src/AtomUI.Base/AtomUI.Base.csproj +++ b/src/AtomUI.Base/AtomUI.Base.csproj @@ -1,5 +1,6 @@  + diff --git a/src/AtomUI.Base/Input/IClickableControl.cs b/src/AtomUI.Base/Input/IClickableControl.cs new file mode 100644 index 0000000..4130a5f --- /dev/null +++ b/src/AtomUI.Base/Input/IClickableControl.cs @@ -0,0 +1,15 @@ +using Avalonia.Interactivity; + +namespace AtomUI.Input; + +internal interface IClickableControl +{ + event EventHandler Click; + + void RaiseClick(); + + /// + /// Gets a value indicating whether this control and all its parents are enabled. + /// + bool IsEffectivelyEnabled { get; } +} \ No newline at end of file diff --git a/src/AtomUI.Base/MotionScene/MotionActor.cs b/src/AtomUI.Base/MotionScene/MotionActor.cs index 33195cf..0239e72 100644 --- a/src/AtomUI.Base/MotionScene/MotionActor.cs +++ b/src/AtomUI.Base/MotionScene/MotionActor.cs @@ -248,7 +248,6 @@ public class MotionActor : Animatable, IMotionActor { DisableMotion(); BuildGhost(); - RelayMotionProperties(); var transitions = new Transitions(); foreach (var transition in _motion.BuildTransitions(GetAnimatableGhost())) { @@ -258,17 +257,6 @@ public class MotionActor : Animatable, IMotionActor Transitions = transitions; } - protected void RelayMotionProperties() - { - // var ghost = GetAnimatableGhost(); - // // TODO 这个看是否需要管理起来 - // - // var motionProperties = Motion.GetActivatedProperties(); - // foreach (var property in motionProperties) { - // BindUtils.RelayBind(this, property, ghost, property); - // } - } - /// /// 当动画目标控件被添加到动画场景中之后调用,这里需要根据 Motion 的种类设置初始位置和大小 /// diff --git a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxToken.cs b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxToken.cs index bfd99be..d4643be 100644 --- a/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxToken.cs +++ b/src/AtomUI.Controls/AddOnDecoratedBox/AddOnDecoratedBoxToken.cs @@ -112,25 +112,25 @@ internal class AddOnDecoratedBoxToken : AbstractControlDesignToken internal override void CalculateFromAlias() { base.CalculateFromAlias(); - var fontSize = _globalToken.FontToken.FontSize; - var fontSizeLG = _globalToken.FontToken.FontSizeLG; - var lineHeight = _globalToken.FontToken.LineHeight; - var lineHeightLG = _globalToken.FontToken.LineHeightLG; - var lineWidth = _globalToken.SeedToken.LineWidth; + var fontSize = _globalToken.FontSize; + var fontSizeLG = _globalToken.FontSizeLG; + var lineHeight = _globalToken.LineHeight; + var lineHeightLG = _globalToken.LineHeightLG; + var lineWidth = _globalToken.LineWidth; Padding = new Thickness(_globalToken.PaddingSM - lineWidth, - Math.Round((_globalToken.SeedToken.ControlHeight - fontSize * lineHeight) / 2 * 10) / 10 - lineWidth); + Math.Round((_globalToken.ControlHeight - fontSize * lineHeight) / 2 * 10) / 10 - lineWidth); PaddingSM = new Thickness(_globalToken.ControlPaddingSM - lineWidth, - Math.Round((_globalToken.HeightToken.ControlHeightSM - fontSize * lineHeight) / 2 * 10) / 10 - lineWidth); + Math.Round((_globalToken.ControlHeightSM - fontSize * lineHeight) / 2 * 10) / 10 - lineWidth); PaddingLG = new Thickness(_globalToken.ControlPadding - lineWidth, - Math.Ceiling((_globalToken.HeightToken.ControlHeightLG - fontSizeLG * lineHeightLG) / 2 * 10) / 10 - + Math.Ceiling((_globalToken.ControlHeightLG - fontSizeLG * lineHeightLG) / 2 * 10) / 10 - lineWidth); AddOnPadding = new Thickness(_globalToken.PaddingSM, 0); AddOnPaddingSM = new Thickness(_globalToken.ControlPaddingSM, 0); AddOnPaddingLG = new Thickness(_globalToken.ControlPadding, 0); AddonBg = _globalToken.ColorFillAlter; - ActiveBorderColor = _globalToken.ColorToken.ColorPrimaryToken.ColorPrimary; - HoverBorderColor = _globalToken.ColorToken.ColorPrimaryToken.ColorPrimaryHover; + ActiveBorderColor = _globalToken.ColorPrimary; + HoverBorderColor = _globalToken.ColorPrimaryHover; ActiveShadow = new BoxShadow { Spread = _globalToken.ControlOutlineWidth, @@ -146,11 +146,11 @@ internal class AddOnDecoratedBoxToken : AbstractControlDesignToken Spread = _globalToken.ControlOutlineWidth, Color = _globalToken.ColorWarningOutline }; - HoverBg = _globalToken.ColorToken.ColorNeutralToken.ColorBgContainer; - ActiveBg = _globalToken.SeedToken.ColorTransparent; - FontSize = _globalToken.FontToken.FontSize; - FontSizeLG = _globalToken.FontToken.FontSizeLG; - FontSizeSM = _globalToken.FontToken.FontSizeSM; + HoverBg = _globalToken.ColorBgContainer; + ActiveBg = _globalToken.ColorTransparent; + FontSize = _globalToken.FontSize; + FontSizeLG = _globalToken.FontSizeLG; + FontSizeSM = _globalToken.FontSizeSM; LeftInnerAddOnMargin = new Thickness(0, 0, _globalToken.MarginXXS, 0); RightInnerAddOnMargin = new Thickness(_globalToken.MarginXXS, 0, 0, 0); diff --git a/src/AtomUI.Controls/Alert/AlertToken.cs b/src/AtomUI.Controls/Alert/AlertToken.cs index 419291a..64ba84b 100644 --- a/src/AtomUI.Controls/Alert/AlertToken.cs +++ b/src/AtomUI.Controls/Alert/AlertToken.cs @@ -62,7 +62,7 @@ internal class AlertToken : AbstractControlDesignToken { base.CalculateFromAlias(); const double paddingHorizontal = 12; // Fixed value here. - WithDescriptionIconSize = _globalToken.FontToken.FontSizeHeading3; + WithDescriptionIconSize = _globalToken.FontSizeHeading3; DefaultPadding = new Thickness(paddingHorizontal, _globalToken.PaddingContentVerticalSM); WithDescriptionPadding = new Thickness(_globalToken.PaddingContentHorizontalLG, _globalToken.PaddingMD); @@ -72,6 +72,6 @@ internal class AlertToken : AbstractControlDesignToken ExtraElementMargin = new Thickness(_globalToken.MarginXS, 0, 0, 0); CloseIconSize = _globalToken.FontSizeIcon + 2; - IconSize = _globalToken.FontToken.FontSizeLG; + IconSize = _globalToken.FontSizeLG; } } \ No newline at end of file diff --git a/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBox.cs b/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBox.cs index 10f8e59..9f1392f 100644 --- a/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBox.cs +++ b/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBox.cs @@ -1,11 +1,6 @@ -using AtomUI.Media; -using AtomUI.Theme.Styling; -using AtomUI.Utils; -using Avalonia; +using Avalonia; using Avalonia.Controls; using Avalonia.Controls.Primitives; -using Avalonia.Layout; -using Avalonia.Media; namespace AtomUI.Controls; @@ -80,8 +75,7 @@ public enum ArrowPosition RightEdgeAlignedBottom } -public class ArrowDecoratedBox : ContentControl, - IShadowMaskInfoProvider +public class ArrowDecoratedBox : ContentControl, IShadowMaskInfoProvider { #region 公共属性定义 @@ -117,6 +111,9 @@ public class ArrowDecoratedBox : ContentControl, internal static readonly StyledProperty ArrowSizeProperty = AvaloniaProperty.Register(nameof(ArrowSize)); + internal static readonly StyledProperty ArrowDirectionProperty + = AvaloniaProperty.Register(nameof(ArrowDirection)); + /// /// 箭头的大小 /// @@ -125,21 +122,25 @@ public class ArrowDecoratedBox : ContentControl, get => GetValue(ArrowSizeProperty); set => SetValue(ArrowSizeProperty, value); } - + + internal Direction ArrowDirection + { + get => GetValue(ArrowDirectionProperty); + set => SetValue(ArrowDirectionProperty, value); + } + #endregion // 指针最顶点位置 // 相对坐标 - private (double, double) _arrowVertexPoint; internal (double, double) ArrowVertexPoint => GetArrowVertexPoint(); - private Geometry? _arrowGeometry; - private Rect _contentRect; - private Rect _arrowRect; - private bool _needGenerateArrowVertexPoint = true; + private Border? _contentDecorator; + private Control? _arrowIndicatorLayout; static ArrowDecoratedBox() { - AffectsMeasure(ArrowPositionProperty, IsShowArrowProperty); + AffectsMeasure(IsShowArrowProperty); + AffectsArrange(ArrowDirectionProperty, ArrowPositionProperty); } public static Direction GetDirection(ArrowPosition arrowPosition) @@ -169,7 +170,10 @@ public class ArrowDecoratedBox : ContentControl, protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) { base.OnPropertyChanged(e); - HandlePropertyChangedForStyle(e); + if (e.Property == ArrowPositionProperty) + { + ArrowDirection = GetDirection(ArrowPosition); + } } public CornerRadius GetMaskCornerRadius() @@ -179,317 +183,162 @@ public class ArrowDecoratedBox : ContentControl, public Rect GetMaskBounds() { - return GetContentRect(DesiredSize).Deflate(0.5); + Rect targetRect = default; + if (_contentDecorator is not null) + { + targetRect = _contentDecorator.Bounds; + } + return targetRect; } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); - HandleTemplateApplied(e.NameScope); - } - - private void HandleTemplateApplied(INameScope scope) - { - if (IsShowArrow) - { - BuildGeometry(true); - } + _contentDecorator = e.NameScope.Get(ArrowDecoratedBoxTheme.ContentDecoratorPart); + _arrowIndicatorLayout = e.NameScope.Get(ArrowDecoratedBoxTheme.ArrowIndicatorLayoutPart); + ArrowDirection = GetDirection(ArrowPosition); } private (double, double) GetArrowVertexPoint() { - if (_needGenerateArrowVertexPoint) + if (_arrowIndicatorLayout is null) { - BuildGeometry(true); - _arrowRect = GetArrowRect(DesiredSize); - _needGenerateArrowVertexPoint = false; + return default; } - - return _arrowVertexPoint; - } - - private void HandlePropertyChangedForStyle(AvaloniaPropertyChangedEventArgs e) - { - if (e.Property == IsShowArrowProperty || - e.Property == ArrowPositionProperty || - e.Property == ArrowSizeProperty || - e.Property == VisualParentProperty) + var targetRect = _arrowIndicatorLayout.Bounds; + var center = targetRect.Center; + var controlSize = Bounds.Size; + + // 计算中点 + var direction = GetDirection(ArrowPosition); + if (direction == Direction.Left || direction == Direction.Right) { - if (e.Property == IsShowArrowProperty && VisualRoot is null) - { - // 当开启的时候,但是还没有加入的渲染树,这个时候我们取不到 Token 需要在取值的时候重新生成一下 - _needGenerateArrowVertexPoint = true; - } - - if (VisualRoot is not null) - { - BuildGeometry(true); - _arrowRect = GetArrowRect(DesiredSize); - } + return (center.Y, controlSize.Height - center.Y); } - } - - private void BuildGeometry(bool force = false) - { - if (_arrowGeometry is null || force) - { - _arrowGeometry = CommonShapeBuilder.BuildArrow(ArrowSize, 1.5); - } - } - - public sealed override void Render(DrawingContext context) - { - if (IsShowArrow) - { - var direction = GetDirection(ArrowPosition); - var matrix = Matrix.CreateTranslation(-ArrowSize / 2, -ArrowSize / 2); - - if (direction == Direction.Right) - { - matrix *= Matrix.CreateRotation(MathUtils.Deg2Rad(90)); - matrix *= Matrix.CreateTranslation(ArrowSize / 2, ArrowSize / 2); - } - else if (direction == Direction.Top) - { - matrix *= Matrix.CreateTranslation(ArrowSize / 2, 0); - } - else if (direction == Direction.Left) - { - matrix *= Matrix.CreateRotation(MathUtils.Deg2Rad(-90)); - matrix *= Matrix.CreateTranslation(0, ArrowSize / 2); - } - else - { - matrix *= Matrix.CreateRotation(MathUtils.Deg2Rad(180)); - matrix *= Matrix.CreateTranslation(ArrowSize / 2, ArrowSize / 2); - } - - matrix *= Matrix.CreateTranslation(_arrowRect.X, _arrowRect.Y); - _arrowGeometry!.Transform = new MatrixTransform(matrix); - context.DrawGeometry(Background, null, _arrowGeometry); - } - } - - protected override Size MeasureOverride(Size availableSize) - { - var size = base.MeasureOverride(availableSize); - var targetWidth = size.Width; - var targetHeight = size.Height; - targetHeight = Math.Max(MinHeight, targetHeight); - - if (IsShowArrow) - { - BuildGeometry(); - var realArrowSize = Math.Min(_arrowGeometry!.Bounds.Size.Height, _arrowGeometry!.Bounds.Size.Width); - var direction = GetDirection(ArrowPosition); - if (direction == Direction.Left || direction == Direction.Right) - { - targetWidth += realArrowSize; - } - else - { - targetHeight += realArrowSize; - } - } - - var targetSize = new Size(targetWidth, targetHeight); - _arrowRect = GetArrowRect(targetSize); - return targetSize; + return (center.X, controlSize.Width - center.X); } protected override Size ArrangeOverride(Size finalSize) { - var visualChildren = VisualChildren; - var visualCount = visualChildren.Count; - _contentRect = GetContentRect(finalSize); - for (var i = 0; i < visualCount; ++i) - { - var child = visualChildren[i]; - if (child is Layoutable layoutable) - { - layoutable.Arrange(_contentRect); - } - } - - return finalSize; - } - - internal Rect GetContentRect(Size finalSize) - { - var offsetX = 0d; - var offsetY = 0d; - var targetWidth = finalSize.Width; - var targetHeight = finalSize.Height; + var size = base.ArrangeOverride(finalSize); if (IsShowArrow) { - var arrowSize = Math.Min(_arrowGeometry!.Bounds.Size.Height, _arrowGeometry!.Bounds.Size.Width) + 0.5; - var direction = GetDirection(ArrowPosition); - if (direction == Direction.Left || direction == Direction.Right) - { - targetWidth -= arrowSize; - } - else - { - targetHeight -= arrowSize; - } - - if (direction == Direction.Right) - { - offsetX = 0.5; - } - else if (direction == Direction.Bottom) - { - offsetY = 0.5; - } - else if (direction == Direction.Top) - { - offsetY = arrowSize - 0.5; - } - else - { - offsetX = arrowSize - 0.5; - } + ArrangeArrow(finalSize); } - - return new Rect(offsetX, offsetY, targetWidth, targetHeight); + return size; } - private Rect GetArrowRect(Size finalSize) + private void ArrangeArrow(Size finalSize) { + if (_arrowIndicatorLayout is null) + { + return; + } var offsetX = 0d; var offsetY = 0d; - var targetWidth = 0d; - var targetHeight = 0d; var position = ArrowPosition; - if (IsShowArrow) + var size = _arrowIndicatorLayout.DesiredSize; + + var minValue = Math.Min(size.Width, size.Height); + var maxValue = Math.Max(size.Width, size.Height); + if (position == ArrowPosition.Left || + position == ArrowPosition.LeftEdgeAlignedTop || + position == ArrowPosition.LeftEdgeAlignedBottom) { - var size = _arrowGeometry!.Bounds.Size; - - var minValue = Math.Min(size.Width, size.Height); - var maxValue = Math.Max(size.Width, size.Height); - if (position == ArrowPosition.Left || - position == ArrowPosition.LeftEdgeAlignedTop || - position == ArrowPosition.LeftEdgeAlignedBottom) + offsetX = 0.5d; + if (position == ArrowPosition.Left) { - targetWidth = minValue; - targetHeight = maxValue; - if (position == ArrowPosition.Left) - { - offsetY = (finalSize.Height - maxValue) / 2; - } - else if (position == ArrowPosition.LeftEdgeAlignedTop) - { - if (maxValue * 2 > finalSize.Height / 2) - { - offsetY = minValue; - } - else - { - offsetY = maxValue; - } - } - else - { - if (maxValue * 2 > finalSize.Height / 2) - { - offsetY = finalSize.Height - minValue - maxValue; - } - else - { - offsetY = finalSize.Height - maxValue * 2; - } - } + offsetY = (finalSize.Height - maxValue) / 2; } - else if (position == ArrowPosition.Top || - position == ArrowPosition.TopEdgeAlignedLeft || - position == ArrowPosition.TopEdgeAlignedRight) + else if (position == ArrowPosition.LeftEdgeAlignedTop) { - if (position == ArrowPosition.TopEdgeAlignedLeft) + if (maxValue * 2 > finalSize.Height / 2) { - offsetX = maxValue; - } - else if (position == ArrowPosition.Top) - { - offsetX = (finalSize.Width - maxValue) / 2; + offsetY = minValue; } else { - offsetX = finalSize.Width - maxValue * 2; + offsetY = maxValue; } - - targetWidth = maxValue; - targetHeight = minValue; - } - else if (position == ArrowPosition.Right || - position == ArrowPosition.RightEdgeAlignedTop || - position == ArrowPosition.RightEdgeAlignedBottom) - { - offsetX = finalSize.Width - minValue; - if (position == ArrowPosition.Right) - { - offsetY = (finalSize.Height - maxValue) / 2; - } - else if (position == ArrowPosition.RightEdgeAlignedTop) - { - if (maxValue * 2 > finalSize.Height / 2) - { - offsetY = minValue; - } - else - { - offsetY = maxValue; - } - } - else - { - if (maxValue * 2 > finalSize.Height / 2) - { - offsetY = finalSize.Height - minValue - maxValue; - } - else - { - offsetY = finalSize.Height - maxValue * 2; - } - } - - targetWidth = minValue; - targetHeight = maxValue; } else { - offsetY = finalSize.Height - minValue; - targetWidth = maxValue; - targetHeight = minValue; - if (position == ArrowPosition.BottomEdgeAlignedLeft) + if (maxValue * 2 > finalSize.Height / 2) { - offsetX = maxValue; - } - else if (position == ArrowPosition.Bottom) - { - offsetX = (finalSize.Width - maxValue) / 2; + offsetY = finalSize.Height - minValue - maxValue; } else { - offsetX = finalSize.Width - maxValue * 2; + offsetY = finalSize.Height - maxValue * 2; } } } - - var targetRect = new Rect(offsetX, offsetY, targetWidth, targetHeight); - var center = targetRect.Center; - - // 计算中点 - var direction = GetDirection(position); - if (direction == Direction.Left || direction == Direction.Right) + else if (position == ArrowPosition.Top || + position == ArrowPosition.TopEdgeAlignedLeft || + position == ArrowPosition.TopEdgeAlignedRight) { - _arrowVertexPoint = (center.Y, finalSize.Height - center.Y); + offsetY = 0.5d; + if (position == ArrowPosition.TopEdgeAlignedLeft) + { + offsetX = maxValue; + } + else if (position == ArrowPosition.Top) + { + offsetX = (finalSize.Width - maxValue) / 2; + } + else + { + offsetX = finalSize.Width - maxValue * 2; + } } - else if (direction == Direction.Top || direction == Direction.Bottom) + else if (position == ArrowPosition.Right || + position == ArrowPosition.RightEdgeAlignedTop || + position == ArrowPosition.RightEdgeAlignedBottom) { - _arrowVertexPoint = (center.X, finalSize.Width - center.X); + offsetX = -0.5d; + if (position == ArrowPosition.Right) + { + offsetY = (finalSize.Height - maxValue) / 2; + } + else if (position == ArrowPosition.RightEdgeAlignedTop) + { + if (maxValue * 2 > finalSize.Height / 2) + { + offsetY = minValue; + } + else + { + offsetY = maxValue; + } + } + else + { + if (maxValue * 2 > finalSize.Height / 2) + { + offsetY = finalSize.Height - minValue - maxValue; + } + else + { + offsetY = finalSize.Height - maxValue * 2; + } + } } - - return targetRect; + else + { + offsetY = -0.5d; + if (position == ArrowPosition.BottomEdgeAlignedLeft) + { + offsetX = maxValue; + } + else if (position == ArrowPosition.Bottom) + { + offsetX = (finalSize.Width - maxValue) / 2; + } + else + { + offsetX = finalSize.Width - maxValue * 2; + } + } + _arrowIndicatorLayout.Arrange(new Rect(new Point(offsetX, offsetY), size)); } - } \ No newline at end of file diff --git a/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBoxTheme.cs b/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBoxTheme.cs index 4b7b038..30516e0 100644 --- a/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBoxTheme.cs +++ b/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBoxTheme.cs @@ -6,6 +6,7 @@ using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Layout; +using Avalonia.Media; using Avalonia.Styling; namespace AtomUI.Controls; @@ -13,8 +14,12 @@ namespace AtomUI.Controls; [ControlThemeProvider] internal class ArrowDecoratedBoxTheme : BaseControlTheme { - public const string DecoratorPart = "PART_Decorator"; + public const string ContentDecoratorPart = "PART_ContentDecorator"; + public const string ContentLayoutPart = "PART_ContentLayout"; public const string ContentPresenterPart = "PART_ContentPresenter"; + public const string ArrowIndicatorPart = "PART_ArrowIndicator"; + public const string ArrowIndicatorLayoutPart = "PART_ArrowIndicatorLayout"; + public const string ArrowPositionLayoutPart = "PART_ArrowPositionLayout"; public ArrowDecoratedBoxTheme() : this(typeof(ArrowDecoratedBox)) { @@ -28,32 +33,62 @@ internal class ArrowDecoratedBoxTheme : BaseControlTheme { return new FuncControlTemplate((box, scope) => { - var decorator = new Border + var contentLayout = new DockPanel() { - Name = DecoratorPart, + Name = ContentLayoutPart, + LastChildFill = true + }; + + var arrowIndicatorLayout = new LayoutTransformControl() + { + Name = ArrowIndicatorLayoutPart, + HorizontalAlignment = HorizontalAlignment.Left, + VerticalAlignment = VerticalAlignment.Top + }; + arrowIndicatorLayout.RegisterInNameScope(scope); + CreateTemplateParentBinding(arrowIndicatorLayout, LayoutTransformControl.IsVisibleProperty, ArrowDecoratedBox.IsShowArrowProperty); + + var arrowIndicator = new ArrowIndicator() + { + Name = ArrowIndicatorPart + }; + CreateTemplateParentBinding(arrowIndicator, ArrowIndicator.FilledColorProperty, ArrowDecoratedBox.BackgroundProperty); + + arrowIndicatorLayout.Child = arrowIndicator; + + var arrowPositionLayout = new Panel() + { + Name = ArrowPositionLayoutPart + }; + arrowPositionLayout.Children.Add(arrowIndicatorLayout); + + contentLayout.Children.Add(arrowPositionLayout); + + var content = BuildContent(scope); + var contentDecorator = new Border + { + Name = ContentDecoratorPart, Margin = new Thickness(0) }; + contentDecorator.RegisterInNameScope(scope); +; CreateTemplateParentBinding(contentDecorator, Border.BackgroundSizingProperty, TemplatedControl.BackgroundSizingProperty); + CreateTemplateParentBinding(contentDecorator, Border.BackgroundProperty, TemplatedControl.BackgroundProperty); + CreateTemplateParentBinding(contentDecorator, Border.CornerRadiusProperty, TemplatedControl.CornerRadiusProperty); + CreateTemplateParentBinding(contentDecorator, Decorator.PaddingProperty, TemplatedControl.PaddingProperty); - decorator.RegisterInNameScope(scope); - - decorator.Child = BuildContent(scope); - - CreateTemplateParentBinding(decorator, Border.BackgroundSizingProperty, - TemplatedControl.BackgroundSizingProperty); - CreateTemplateParentBinding(decorator, Border.BackgroundProperty, TemplatedControl.BackgroundProperty); - CreateTemplateParentBinding(decorator, Border.CornerRadiusProperty, TemplatedControl.CornerRadiusProperty); - CreateTemplateParentBinding(decorator, Decorator.PaddingProperty, TemplatedControl.PaddingProperty); - - return decorator; + contentDecorator.Child = content; + contentLayout.Children.Add(contentDecorator); + return contentLayout; }); } - + protected virtual Control BuildContent(INameScope scope) { var contentPresenter = new ContentPresenter { Name = ContentPresenterPart }; + CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentProperty, ContentControl.ContentProperty); CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentTemplateProperty, ContentControl.ContentTemplateProperty); @@ -69,6 +104,62 @@ internal class ArrowDecoratedBoxTheme : BaseControlTheme commonStyle.Add(TemplatedControl.PaddingProperty, ArrowDecoratedBoxTokenResourceKey.Padding); commonStyle.Add(ArrowDecoratedBox.ArrowSizeProperty, ArrowDecoratedBoxTokenResourceKey.ArrowSize); commonStyle.Add(TemplatedControl.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadius); + BuildArrowDirectionStyle(commonStyle); Add(commonStyle); } + + private void BuildArrowDirectionStyle(Style commonStyle) + { + var arrowIndicatorStyle = new Style(selector => selector.Nesting().Template().Name(ArrowIndicatorPart)); + arrowIndicatorStyle.Add(ArrowIndicator.ArrowSizeProperty, ArrowDecoratedBoxTokenResourceKey.ArrowSize); + commonStyle.Add(arrowIndicatorStyle); + + var topDirectionStyle = new Style(selector => selector.Nesting().PropertyEquals(ArrowDecoratedBox.ArrowDirectionProperty, Direction.Top)); + { + var arrowIndicatorLayoutStyle = new Style(selector => selector.Nesting().Template().Name(ArrowIndicatorLayoutPart)); + topDirectionStyle.Add(arrowIndicatorLayoutStyle); + } + { + var arrowPositionLayoutStyle = new Style(selector => selector.Nesting().Template().Name(ArrowPositionLayoutPart)); + arrowPositionLayoutStyle.Add(DockPanel.DockProperty, Dock.Top); + topDirectionStyle.Add(arrowPositionLayoutStyle); + } + commonStyle.Add(topDirectionStyle); + var rightDirectionStyle = new Style(selector => selector.Nesting().PropertyEquals(ArrowDecoratedBox.ArrowDirectionProperty, Direction.Right)); + { + var arrowIndicatorLayoutStyle = new Style(selector => selector.Nesting().Template().Name(ArrowIndicatorLayoutPart)); + arrowIndicatorLayoutStyle.Add(LayoutTransformControl.LayoutTransformProperty, new RotateTransform(90)); + rightDirectionStyle.Add(arrowIndicatorLayoutStyle); + } + { + var arrowPositionLayoutStyle = new Style(selector => selector.Nesting().Template().Name(ArrowPositionLayoutPart)); + arrowPositionLayoutStyle.Add(DockPanel.DockProperty, Dock.Right); + rightDirectionStyle.Add(arrowPositionLayoutStyle); + } + commonStyle.Add(rightDirectionStyle); + var bottomDirectionStyle = new Style(selector => selector.Nesting().PropertyEquals(ArrowDecoratedBox.ArrowDirectionProperty, Direction.Bottom)); + { + var arrowIndicatorLayoutStyle = new Style(selector => selector.Nesting().Template().Name(ArrowIndicatorLayoutPart)); + arrowIndicatorLayoutStyle.Add(LayoutTransformControl.LayoutTransformProperty, new RotateTransform(180)); + bottomDirectionStyle.Add(arrowIndicatorLayoutStyle); + } + { + var arrowPositionLayoutStyle = new Style(selector => selector.Nesting().Template().Name(ArrowPositionLayoutPart)); + arrowPositionLayoutStyle.Add(DockPanel.DockProperty, Dock.Bottom); + bottomDirectionStyle.Add(arrowPositionLayoutStyle); + } + commonStyle.Add(bottomDirectionStyle); + var leftDirectionStyle = new Style(selector => selector.Nesting().PropertyEquals(ArrowDecoratedBox.ArrowDirectionProperty, Direction.Left)); + { + var arrowIndicatorLayoutStyle = new Style(selector => selector.Nesting().Template().Name(ArrowIndicatorLayoutPart)); + arrowIndicatorLayoutStyle.Add(LayoutTransformControl.LayoutTransformProperty, new RotateTransform(-90)); + leftDirectionStyle.Add(arrowIndicatorLayoutStyle); + } + { + var arrowPositionLayoutStyle = new Style(selector => selector.Nesting().Template().Name(ArrowPositionLayoutPart)); + arrowPositionLayoutStyle.Add(DockPanel.DockProperty, Dock.Left); + leftDirectionStyle.Add(arrowPositionLayoutStyle); + } + commonStyle.Add(leftDirectionStyle); + } } \ No newline at end of file diff --git a/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBoxToken.cs b/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBoxToken.cs index 03560d5..66feba1 100644 --- a/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBoxToken.cs +++ b/src/AtomUI.Controls/ArrowDecoratedBox/ArrowDecoratedBoxToken.cs @@ -26,7 +26,7 @@ public class ArrowDecoratedBoxToken : AbstractControlDesignToken internal override void CalculateFromAlias() { base.CalculateFromAlias(); - ArrowSize = _globalToken.SeedToken.SizePopupArrow / 1.3; + ArrowSize = _globalToken.SizePopupArrow / 1.3; Padding = new Thickness(_globalToken.PaddingXS); } } \ No newline at end of file diff --git a/src/AtomUI.Controls/ArrowDecoratedBox/ArrowIndicator.cs b/src/AtomUI.Controls/ArrowDecoratedBox/ArrowIndicator.cs new file mode 100644 index 0000000..abdf8c8 --- /dev/null +++ b/src/AtomUI.Controls/ArrowDecoratedBox/ArrowIndicator.cs @@ -0,0 +1,67 @@ +using AtomUI.Media; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Layout; +using Avalonia.Media; + +namespace AtomUI.Controls; + +public class ArrowIndicator : Control +{ + public static readonly StyledProperty ArrowSizeProperty + = AvaloniaProperty.Register(nameof(ArrowSize)); + + public static readonly StyledProperty FilledColorProperty = + AvaloniaProperty.Register(nameof(FilledColor)); + + public double ArrowSize + { + get => GetValue(ArrowSizeProperty); + set => SetValue(ArrowSizeProperty, value); + } + + public IBrush? FilledColor + { + get => GetValue(FilledColorProperty); + set => SetValue(FilledColorProperty, value); + } + + private Geometry? _arrowGeometry; + + static ArrowIndicator() + { + AffectsMeasure(ArrowSizeProperty); + HorizontalAlignmentProperty.OverrideDefaultValue(HorizontalAlignment.Left); + VerticalAlignmentProperty.OverrideDefaultValue(VerticalAlignment.Top); + ClipToBoundsProperty.OverrideDefaultValue(true); + } + + private void BuildGeometry(bool force = false) + { + if (_arrowGeometry is null || force) + { + _arrowGeometry = CommonShapeBuilder.BuildArrow(ArrowSize, 1.5); + var matrix = Matrix.CreateTranslation(_arrowGeometry.Bounds.X, -_arrowGeometry.Bounds.Y); + _arrowGeometry.Transform = new MatrixTransform(matrix); + } + } + + public sealed override void ApplyTemplate() + { + base.ApplyTemplate(); + BuildGeometry(); + } + + protected override Size MeasureOverride(Size availableSize) + { + return _arrowGeometry?.Bounds.Size ?? new Size(ArrowSize, ArrowSize); + } + + public sealed override void Render(DrawingContext context) + { + if (_arrowGeometry is not null) + { + context.DrawGeometry(FilledColor, null, _arrowGeometry); + } + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls/AtomUI.Controls.csproj b/src/AtomUI.Controls/AtomUI.Controls.csproj index ae845dc..e004f8d 100644 --- a/src/AtomUI.Controls/AtomUI.Controls.csproj +++ b/src/AtomUI.Controls/AtomUI.Controls.csproj @@ -1,5 +1,6 @@  + diff --git a/src/AtomUI.Controls/Badge/BadgeToken.cs b/src/AtomUI.Controls/Badge/BadgeToken.cs index d27f3ed..0597347 100644 --- a/src/AtomUI.Controls/Badge/BadgeToken.cs +++ b/src/AtomUI.Controls/Badge/BadgeToken.cs @@ -68,23 +68,21 @@ internal class BadgeToken : AbstractControlDesignToken internal override void CalculateFromAlias() { base.CalculateFromAlias(); - var fontToken = _globalToken.FontToken; - var lineWidth = _globalToken.SeedToken.LineWidth; - IndicatorHeight = Math.Round(fontToken.FontSize * fontToken.LineHeight) - 2 * lineWidth; - IndicatorHeightSM = _globalToken.FontToken.FontSize; - DotSize = fontToken.FontSizeSM / 2; - TextFontSize = fontToken.FontSizeSM; - TextFontSizeSM = fontToken.FontSizeSM; + var lineWidth = _globalToken.LineWidth; + IndicatorHeight = Math.Round(_globalToken.FontSize * _globalToken.LineHeight) - 2 * lineWidth; + IndicatorHeightSM = _globalToken.FontSize; + DotSize = _globalToken.FontSizeSM / 2; + TextFontSize = _globalToken.FontSizeSM; + TextFontSizeSM = _globalToken.FontSizeSM; TextFontWeight = FontWeight.Normal; - StatusSize = fontToken.FontSizeSM / 2; + StatusSize = _globalToken.FontSizeSM / 2; // 设置内部 token - var colorNeutralToken = _globalToken.ColorToken.ColorNeutralToken; - BadgeFontHeight = fontToken.FontHeight; + BadgeFontHeight = _globalToken.FontHeight; BadgeShadowSize = lineWidth; - BadgeTextColor = colorNeutralToken.ColorBgContainer; - BadgeColor = _globalToken.ColorToken.ColorErrorToken.ColorError; - BadgeColorHover = _globalToken.ColorToken.ColorErrorToken.ColorErrorHover; + BadgeTextColor = _globalToken.ColorBgContainer; + BadgeColor = _globalToken.ColorError; + BadgeColorHover = _globalToken.ColorErrorHover; BadgeShadowColor = _globalToken.ColorBorderBg; BadgeProcessingDuration = TimeSpan.FromMilliseconds(1200); BadgeRibbonOffset = new Point(_globalToken.MarginXS, _globalToken.MarginXS); diff --git a/src/AtomUI.Controls/ButtonSpinner/ButtonSpinnerToken.cs b/src/AtomUI.Controls/ButtonSpinner/ButtonSpinnerToken.cs index 46a7987..f37d895 100644 --- a/src/AtomUI.Controls/ButtonSpinner/ButtonSpinnerToken.cs +++ b/src/AtomUI.Controls/ButtonSpinner/ButtonSpinnerToken.cs @@ -62,15 +62,14 @@ internal class ButtonSpinnerToken : LineEditToken internal override void CalculateFromAlias() { base.CalculateFromAlias(); - var colorNeutral = _globalToken.ColorToken.ColorNeutralToken; ControlWidth = 90; - HandleWidth = _globalToken.HeightToken.ControlHeightSM; - HandleIconSize = _globalToken.FontToken.FontSize / 2; + HandleWidth = _globalToken.ControlHeightSM; + HandleIconSize = _globalToken.FontSize / 2; HandleActiveBg = _globalToken.ColorFillAlter; - HandleBg = colorNeutral.ColorBgContainer; - FilledHandleBg = ColorUtils.OnBackground(colorNeutral.ColorFillSecondary, + HandleBg = _globalToken.ColorBgContainer; + FilledHandleBg = ColorUtils.OnBackground(_globalToken.ColorFillSecondary, HandleBg); - HandleHoverColor = _globalToken.ColorToken.ColorPrimaryToken.ColorPrimary; - HandleBorderColor = colorNeutral.ColorBorder; + HandleHoverColor = _globalToken.ColorPrimary; + HandleBorderColor = _globalToken.ColorBorder; } } \ No newline at end of file diff --git a/src/AtomUI.Controls/Buttons/Button.cs b/src/AtomUI.Controls/Buttons/Button.cs index c26a2c2..2db1ee7 100644 --- a/src/AtomUI.Controls/Buttons/Button.cs +++ b/src/AtomUI.Controls/Buttons/Button.cs @@ -396,7 +396,8 @@ public class Button : AvaloniaButton, } if (e.Property == BorderBrushProperty || - e.Property == ButtonTypeProperty) + e.Property == ButtonTypeProperty || + e.Property == IsEnabledProperty) { SetupEffectiveBorderThickness(); } @@ -539,7 +540,7 @@ public class Button : AvaloniaButton, } else if (ButtonType == ButtonType.Primary) { - if (IsGhost) + if (IsGhost || !IsEnabled) { EffectiveBorderThickness = BorderThickness; } diff --git a/src/AtomUI.Controls/Buttons/ButtonToken.cs b/src/AtomUI.Controls/Buttons/ButtonToken.cs index af173e0..a0a18ef 100644 --- a/src/AtomUI.Controls/Buttons/ButtonToken.cs +++ b/src/AtomUI.Controls/Buttons/ButtonToken.cs @@ -252,8 +252,8 @@ internal class ButtonToken : AbstractControlDesignToken internal override void CalculateFromAlias() { base.CalculateFromAlias(); - var fontSize = _globalToken.FontToken.FontSize; - var fontSizeLG = _globalToken.FontToken.FontSizeLG; + var fontSize = _globalToken.FontSize; + var fontSizeLG = _globalToken.FontSizeLG; ContentFontSize = !double.IsNaN(ContentFontSize) ? ContentFontSize : fontSize; ContentFontSizeSM = !double.IsNaN(ContentFontSizeSM) ? ContentFontSizeSM : fontSize; @@ -296,38 +296,35 @@ internal class ButtonToken : AbstractControlDesignToken Spread = 0, Color = _globalToken.ColorErrorOutline }; - - var colorToken = _globalToken.ColorToken; - var neutralColorToken = colorToken.ColorNeutralToken; - var primaryColorToken = colorToken.ColorPrimaryToken; - var lineWidth = _globalToken.SeedToken.LineWidth; + + var lineWidth = _globalToken.LineWidth; PrimaryColor = _globalToken.ColorTextLightSolid; DangerColor = _globalToken.ColorTextLightSolid; - BorderColorDisabled = neutralColorToken.ColorBorder; - DefaultGhostColor = neutralColorToken.ColorBgContainer; + BorderColorDisabled = _globalToken.ColorBorder; + DefaultGhostColor = _globalToken.ColorBgContainer; GhostBg = Colors.Transparent; - DefaultGhostBorderColor = neutralColorToken.ColorBgContainer; + DefaultGhostBorderColor = _globalToken.ColorBgContainer; - GroupBorderColor = primaryColorToken.ColorPrimaryHover; + GroupBorderColor = _globalToken.ColorPrimaryHover; LinkHoverBg = Colors.Transparent; TextHoverBg = _globalToken.ColorBgTextHover; - DefaultColor = neutralColorToken.ColorText; - DefaultBg = neutralColorToken.ColorBgContainer; - DefaultBorderColor = neutralColorToken.ColorBorder; - DefaultBorderColorDisabled = neutralColorToken.ColorBorder; - DefaultHoverBg = neutralColorToken.ColorBgContainer; - DefaultHoverColor = primaryColorToken.ColorPrimaryHover; - DefaultHoverBorderColor = primaryColorToken.ColorPrimaryHover; - DefaultActiveBg = neutralColorToken.ColorBgContainer; - DefaultActiveColor = primaryColorToken.ColorPrimaryActive; - DefaultActiveBorderColor = primaryColorToken.ColorPrimaryActive; + DefaultColor = _globalToken.ColorText; + DefaultBg = _globalToken.ColorBgContainer; + DefaultBorderColor = _globalToken.ColorBorder; + DefaultBorderColorDisabled = _globalToken.ColorBorder; + DefaultHoverBg = _globalToken.ColorBgContainer; + DefaultHoverColor = _globalToken.ColorPrimaryHover; + DefaultHoverBorderColor = _globalToken.ColorPrimaryHover; + DefaultActiveBg = _globalToken.ColorBgContainer; + DefaultActiveColor = _globalToken.ColorPrimaryActive; + DefaultActiveBorderColor = _globalToken.ColorPrimaryActive; - var controlHeightSM = _globalToken.HeightToken.ControlHeightSM; - var controlHeight = _globalToken.SeedToken.ControlHeight; - var controlHeightLG = _globalToken.HeightToken.ControlHeightLG; + var controlHeightSM = _globalToken.ControlHeightSM; + var controlHeight = _globalToken.ControlHeight; + var controlHeightLG = _globalToken.ControlHeightLG; - PaddingSM = new Thickness(8 - _globalToken.SeedToken.LineWidth, + PaddingSM = new Thickness(8 - _globalToken.LineWidth, Math.Max((controlHeightSM - ContentLineHeightSM) / 2 - lineWidth, 0)); Padding = new Thickness(_globalToken.PaddingContentHorizontal - lineWidth, Math.Max((controlHeight - ContentLineHeight) / 2 - lineWidth, 0)); diff --git a/src/AtomUI.Controls/Calendar/CalendarToken.cs b/src/AtomUI.Controls/Calendar/CalendarToken.cs index 8a552e4..8331723 100644 --- a/src/AtomUI.Controls/Calendar/CalendarToken.cs +++ b/src/AtomUI.Controls/Calendar/CalendarToken.cs @@ -105,17 +105,17 @@ internal class CalendarToken : AbstractControlDesignToken { base.CalculateFromAlias(); - var colorPrimary = _globalToken.ColorToken.ColorPrimaryToken.ColorPrimary; + var colorPrimary = _globalToken.ColorPrimary; CellHoverBg = _globalToken.ControlItemBgHover; CellActiveWithRangeBg = _globalToken.ControlItemBgActive; CellHoverWithRangeBg = colorPrimary.Lighten(35); CellRangeBorderColor = colorPrimary.Lighten(20); CellBgDisabled = _globalToken.ColorBgContainerDisabled; - CellWidth = _globalToken.HeightToken.ControlHeightSM; - CellHeight = _globalToken.HeightToken.ControlHeightSM; - TextHeight = _globalToken.HeightToken.ControlHeightLG; - WithoutTimeCellHeight = _globalToken.HeightToken.ControlHeightLG * 1.65; + CellWidth = _globalToken.ControlHeightSM; + CellHeight = _globalToken.ControlHeightSM; + TextHeight = _globalToken.ControlHeightLG; + WithoutTimeCellHeight = _globalToken.ControlHeightLG * 1.65; CellMargin = new Thickness(_globalToken.MarginXXS); PanelContentPadding = new Thickness(_globalToken.PaddingSM); ItemPanelMinWidth = 260; diff --git a/src/AtomUI.Controls/Calendar/DateTimeHelper.cs b/src/AtomUI.Controls/Calendar/DateTimeHelper.cs index ab0d48e..e5ec2ae 100644 --- a/src/AtomUI.Controls/Calendar/DateTimeHelper.cs +++ b/src/AtomUI.Controls/Calendar/DateTimeHelper.cs @@ -49,6 +49,11 @@ internal static class DateTimeHelper { return DateTime.Compare(DiscardTime(dt1), DiscardTime(dt2)); } + + public static int CompareDateTime(DateTime dt1, DateTime dt2) + { + return DateTime.Compare(dt1, dt2); + } public static int CompareYearMonth(DateTime dt1, DateTime dt2) { diff --git a/src/AtomUI.Controls/CheckBox/CheckBox.cs b/src/AtomUI.Controls/CheckBox/CheckBox.cs index 1675f3c..1cfb8c3 100644 --- a/src/AtomUI.Controls/CheckBox/CheckBox.cs +++ b/src/AtomUI.Controls/CheckBox/CheckBox.cs @@ -1,17 +1,4 @@ -using AtomUI.Controls.Utils; -using AtomUI.Media; -using AtomUI.Theme.Data; -using AtomUI.Theme.Styling; -using AtomUI.Theme.Utils; -using AtomUI.Utils; using Avalonia; -using Avalonia.Animation; -using Avalonia.Animation.Easings; -using Avalonia.Controls.Primitives; -using Avalonia.Data; -using Avalonia.Input; -using Avalonia.Layout; -using Avalonia.Media; using Avalonia.Rendering; namespace AtomUI.Controls; @@ -19,309 +6,10 @@ namespace AtomUI.Controls; using AvaloniaCheckBox = Avalonia.Controls.CheckBox; public class CheckBox : AvaloniaCheckBox, - ICustomHitTest, - IWaveAdornerInfoProvider + ICustomHitTest { - #region 内部属性定义 - - internal static readonly StyledProperty CheckIndicatorSizeProperty = - AvaloniaProperty.Register(nameof(CheckIndicatorSize)); - - internal static readonly StyledProperty PaddingInlineProperty = - AvaloniaProperty.Register(nameof(PaddingInline)); - - internal static readonly StyledProperty IndicatorBorderBrushProperty = - AvaloniaProperty.Register(nameof(IndicatorBorderBrush)); - - internal static readonly StyledProperty IndicatorCheckedMarkBrushProperty = - AvaloniaProperty.Register(nameof(IndicatorCheckedMarkBrush)); - - internal static readonly StyledProperty IndicatorCheckedMarkEffectSizeProperty = - AvaloniaProperty.Register(nameof(IndicatorCheckedMarkEffectSize)); - - internal static readonly StyledProperty IndicatorTristateMarkBrushProperty = - AvaloniaProperty.Register(nameof(IndicatorTristateMarkBrush)); - - internal static readonly StyledProperty IndicatorTristateMarkSizeProperty = - AvaloniaProperty.Register(nameof(IndicatorTristateMarkSize)); - - internal static readonly StyledProperty IndicatorBackgroundProperty = - AvaloniaProperty.Register(nameof(IndicatorBackground)); - - internal static readonly StyledProperty IndicatorBorderThicknessProperty = - AvaloniaProperty.Register(nameof(IndicatorBorderThickness)); - - internal static readonly StyledProperty IndicatorBorderRadiusProperty = - AvaloniaProperty.Register(nameof(IndicatorBorderRadius)); - - internal double CheckIndicatorSize - { - get => GetValue(CheckIndicatorSizeProperty); - set => SetValue(CheckIndicatorSizeProperty, value); - } - - internal double PaddingInline - { - get => GetValue(PaddingInlineProperty); - set => SetValue(PaddingInlineProperty, value); - } - - internal IBrush? IndicatorBorderBrush - { - get => GetValue(IndicatorBorderBrushProperty); - set => SetValue(IndicatorBorderBrushProperty, value); - } - - internal IBrush? IndicatorCheckedMarkBrush - { - get => GetValue(IndicatorCheckedMarkBrushProperty); - set => SetValue(IndicatorCheckedMarkBrushProperty, value); - } - - internal double IndicatorCheckedMarkEffectSize - { - get => GetValue(IndicatorCheckedMarkEffectSizeProperty); - set => SetValue(IndicatorCheckedMarkEffectSizeProperty, value); - } - - internal IBrush? IndicatorTristateMarkBrush - { - get => GetValue(IndicatorTristateMarkBrushProperty); - set => SetValue(IndicatorTristateMarkBrushProperty, value); - } - - internal double IndicatorTristateMarkSize - { - get => GetValue(IndicatorTristateMarkSizeProperty); - set => SetValue(IndicatorTristateMarkSizeProperty, value); - } - - internal IBrush? IndicatorBackground - { - get => GetValue(IndicatorBackgroundProperty); - set => SetValue(IndicatorBackgroundProperty, value); - } - - internal Thickness IndicatorBorderThickness - { - get => GetValue(IndicatorBorderThicknessProperty); - set => SetValue(IndicatorBorderThicknessProperty, value); - } - - internal CornerRadius IndicatorBorderRadius - { - get => GetValue(IndicatorBorderRadiusProperty); - set => SetValue(IndicatorBorderRadiusProperty, value); - } - - #endregion - - private ControlStyleState _styleState; - private readonly BorderRenderHelper _borderRenderHelper; - - static CheckBox() - { - AffectsRender( - IsCheckedProperty, - IndicatorCheckedMarkEffectSizeProperty, - PaddingInlineProperty, - IndicatorBorderBrushProperty, - IndicatorCheckedMarkBrushProperty, - IndicatorTristateMarkBrushProperty, - IndicatorBackgroundProperty, - IndicatorBorderThicknessProperty, - IndicatorBorderRadiusProperty); - } - - public CheckBox() - { - _borderRenderHelper = new BorderRenderHelper(); - } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) - { - base.OnPropertyChanged(e); - HandlePropertyChangedForStyle(e); - } - - protected override Size MeasureOverride(Size availableSize) - { - var size = base.MeasureOverride(availableSize); - var targetWidth = size.Width + CheckIndicatorSize + PaddingInline; - var targetHeight = Math.Max(size.Height, CheckIndicatorSize); - return new Size(targetWidth, targetHeight); - } - - protected override Size ArrangeOverride(Size finalSize) - { - var arrangeRect = TextRect(); - - var visualChildren = VisualChildren; - var visualCount = visualChildren.Count; - - for (var i = 0; i < visualCount; i++) - { - var visual = visualChildren[i]; - if (visual is Layoutable layoutable) - { - layoutable.Arrange(arrangeRect); - } - } - - return finalSize; - } - - public sealed override void Render(DrawingContext context) - { - var indicatorRect = IndicatorRect(); - var penWidth = IndicatorBorderThickness.Top; - var borderRadius = GeometryUtils.CornerRadiusScalarValue(IndicatorBorderRadius); - { - _borderRenderHelper.Render(context, indicatorRect.Size, - new Thickness(penWidth), - new CornerRadius(borderRadius), - BackgroundSizing.OuterBorderEdge, - IndicatorBackground, - IndicatorBorderBrush, - new BoxShadows()); - } - if (_styleState.HasFlag(ControlStyleState.On)) - { - var checkMarkGeometry = - CommonShapeBuilder.BuildCheckMark(new Size(IndicatorCheckedMarkEffectSize, - IndicatorCheckedMarkEffectSize)); - var checkMarkPen = new Pen(IndicatorCheckedMarkBrush, 2); - context.DrawGeometry(null, checkMarkPen, checkMarkGeometry); - } - else if (_styleState.HasFlag(ControlStyleState.Indeterminate)) - { - var deltaSize = (CheckIndicatorSize - IndicatorTristateMarkSize) / 2.0; - var offsetX = indicatorRect.X + deltaSize; - var offsetY = indicatorRect.Y + deltaSize; - var indicatorTristateRect = - new Rect(offsetX, offsetY, IndicatorTristateMarkSize, IndicatorTristateMarkSize); - context.FillRectangle(IndicatorTristateMarkBrush!, indicatorTristateRect); - } - } - public bool HitTest(Point point) { return true; } - - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) - { - base.OnApplyTemplate(e); - TokenResourceBinder.CreateGlobalResourceBinding(this, IndicatorBorderThicknessProperty, - GlobalTokenResourceKey.BorderThickness, BindingPriority.Template, - new RenderScaleAwareThicknessConfigure(this)); - HorizontalAlignment = HorizontalAlignment.Left; - Cursor = new Cursor(StandardCursorType.Hand); - CollectStyleState(); - SetupIndicatorCheckedMarkEffectSize(); - SetupTransitions(); - } - - private void CollectStyleState() - { - ControlStateUtils.InitCommonState(this, ref _styleState); - switch (IsChecked) - { - case true: - _styleState |= ControlStyleState.On; - break; - case false: - _styleState |= ControlStyleState.Off; - break; - default: - _styleState |= ControlStyleState.Indeterminate; - break; - } - - if (IsPressed) - { - _styleState |= ControlStyleState.Sunken; - } - else - { - _styleState |= ControlStyleState.Raised; - } - } - - // Measure 之后才有值 - private Rect IndicatorRect() - { - return new Rect(0d, 0d, CheckIndicatorSize, CheckIndicatorSize); - } - - private Rect TextRect() - { - var offsetX = CheckIndicatorSize + PaddingInline; - return new Rect(offsetX, 0d, DesiredSize.Width - offsetX, DesiredSize.Height); - } - - private void SetupIndicatorCheckedMarkEffectSize() - { - if (_styleState.HasFlag(ControlStyleState.Enabled)) - { - if (_styleState.HasFlag(ControlStyleState.On)) - { - IndicatorCheckedMarkEffectSize = CheckIndicatorSize; - } - else if (_styleState.HasFlag(ControlStyleState.Off)) - { - IndicatorCheckedMarkEffectSize = CheckIndicatorSize * 0.7; - } - else if (_styleState.HasFlag(ControlStyleState.Indeterminate)) - { - IndicatorCheckedMarkEffectSize = CheckIndicatorSize * 0.7; - } - } - else - { - if (_styleState.HasFlag(ControlStyleState.On)) - { - IndicatorCheckedMarkEffectSize = CheckIndicatorSize; - } - } - } - - private void SetupTransitions() - { - Transitions = new Transitions - { - AnimationUtils.CreateTransition(IndicatorBackgroundProperty), - AnimationUtils.CreateTransition(IndicatorBorderBrushProperty), - AnimationUtils.CreateTransition(IndicatorTristateMarkBrushProperty), - AnimationUtils.CreateTransition(IndicatorCheckedMarkEffectSizeProperty, - GlobalTokenResourceKey.MotionDurationMid, new BackEaseOut()) - }; - } - - private void HandlePropertyChangedForStyle(AvaloniaPropertyChangedEventArgs e) - { - if (e.Property == IsPointerOverProperty || - e.Property == IsCheckedProperty || - e.Property == IsEnabledProperty) - { - CollectStyleState(); - SetupIndicatorCheckedMarkEffectSize(); - if (e.Property == IsCheckedProperty && - _styleState.HasFlag(ControlStyleState.Enabled) && - _styleState.HasFlag(ControlStyleState.On)) - { - WaveSpiritAdorner.ShowWaveAdorner(this, WaveType.RoundRectWave); - } - } - } - - public Rect WaveGeometry() - { - return IndicatorRect(); - } - - public CornerRadius WaveBorderRadius() - { - return IndicatorBorderRadius; - } } \ No newline at end of file diff --git a/src/AtomUI.Controls/CheckBox/CheckBoxIndicator.cs b/src/AtomUI.Controls/CheckBox/CheckBoxIndicator.cs new file mode 100644 index 0000000..f8d8313 --- /dev/null +++ b/src/AtomUI.Controls/CheckBox/CheckBoxIndicator.cs @@ -0,0 +1,254 @@ +using AtomUI.Controls.Utils; +using AtomUI.Media; +using AtomUI.Theme.Data; +using AtomUI.Theme.Styling; +using AtomUI.Theme.Utils; +using AtomUI.Utils; +using Avalonia; +using Avalonia.Animation; +using Avalonia.Animation.Easings; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Data; +using Avalonia.Media; + +namespace AtomUI.Controls; + +internal class CheckBoxIndicator : Control, IWaveAdornerInfoProvider +{ + public static readonly StyledProperty IsCheckedProperty = + ToggleButton.IsCheckedProperty.AddOwner(); + + public static readonly StyledProperty SizeProperty = + AvaloniaProperty.Register(nameof(Size)); + + public static readonly StyledProperty BorderBrushProperty = + Border.BorderBrushProperty.AddOwner(); + + public static readonly StyledProperty CheckedMarkBrushProperty = + AvaloniaProperty.Register(nameof(CheckedMarkBrush)); + + public static readonly StyledProperty CheckedMarkEffectSizeProperty = + AvaloniaProperty.Register(nameof(CheckedMarkEffectSize)); + + public static readonly StyledProperty TristateMarkBrushProperty = + AvaloniaProperty.Register(nameof(TristateMarkBrush)); + + public static readonly StyledProperty TristateMarkSizeProperty = + AvaloniaProperty.Register(nameof(TristateMarkSize)); + + public static readonly StyledProperty BackgroundProperty = + Border.BackgroundProperty.AddOwner(); + + public static readonly StyledProperty BorderThicknessProperty = + Border.BorderThicknessProperty.AddOwner(); + + public static readonly StyledProperty CornerRadiusProperty = + Border.CornerRadiusProperty.AddOwner(); + + public bool? IsChecked + { + get => GetValue(IsCheckedProperty); + set => SetValue(IsCheckedProperty, value); + } + + public double Size + { + get => GetValue(SizeProperty); + set => SetValue(SizeProperty, value); + } + + public IBrush? BorderBrush + { + get => GetValue(BorderBrushProperty); + set => SetValue(BorderBrushProperty, value); + } + + public IBrush? CheckedMarkBrush + { + get => GetValue(CheckedMarkBrushProperty); + set => SetValue(CheckedMarkBrushProperty, value); + } + + public double CheckedMarkEffectSize + { + get => GetValue(CheckedMarkEffectSizeProperty); + set => SetValue(CheckedMarkEffectSizeProperty, value); + } + + public IBrush? TristateMarkBrush + { + get => GetValue(TristateMarkBrushProperty); + set => SetValue(TristateMarkBrushProperty, value); + } + + public double TristateMarkSize + { + get => GetValue(TristateMarkSizeProperty); + set => SetValue(TristateMarkSizeProperty, value); + } + + public IBrush? Background + { + get => GetValue(BackgroundProperty); + set => SetValue(BackgroundProperty, value); + } + + public Thickness BorderThickness + { + get => GetValue(BorderThicknessProperty); + set => SetValue(BorderThicknessProperty, value); + } + + public CornerRadius CornerRadius + { + get => GetValue(CornerRadiusProperty); + set => SetValue(CornerRadiusProperty, value); + } + + private ControlStyleState _styleState; + private readonly BorderRenderHelper _borderRenderHelper; + + static CheckBoxIndicator() + { + AffectsRender( + IsCheckedProperty, + CheckedMarkEffectSizeProperty, + BorderBrushProperty, + CheckedMarkBrushProperty, + TristateMarkBrushProperty, + BackgroundProperty, + BorderThicknessProperty, + CornerRadiusProperty); + } + + public CheckBoxIndicator() + { + _borderRenderHelper = new BorderRenderHelper(); + } + + public override void ApplyTemplate() + { + base.ApplyTemplate(); + Transitions ??= new Transitions + { + AnimationUtils.CreateTransition(BackgroundProperty), + AnimationUtils.CreateTransition(BorderBrushProperty), + AnimationUtils.CreateTransition(TristateMarkBrushProperty), + AnimationUtils.CreateTransition(CheckedMarkEffectSizeProperty, + GlobalTokenResourceKey.MotionDurationMid, new BackEaseOut()) + }; + TokenResourceBinder.CreateGlobalResourceBinding(this, BorderThicknessProperty, + GlobalTokenResourceKey.BorderThickness, BindingPriority.Template, + new RenderScaleAwareThicknessConfigure(this)); + } + + private void CollectStyleState() + { + ControlStateUtils.InitCommonState(this, ref _styleState); + switch (IsChecked) + { + case true: + _styleState |= ControlStyleState.On; + break; + case false: + _styleState |= ControlStyleState.Off; + break; + default: + _styleState |= ControlStyleState.Indeterminate; + break; + } + } + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs e) + { + base.OnPropertyChanged(e); + if (e.Property == IsPointerOverProperty || + e.Property == IsCheckedProperty || + e.Property == IsEnabledProperty) + { + CollectStyleState(); + SetupIndicatorCheckedMarkEffectSize(); + if (e.Property == IsCheckedProperty && + _styleState.HasFlag(ControlStyleState.Enabled) && + _styleState.HasFlag(ControlStyleState.On)) + { + WaveSpiritAdorner.ShowWaveAdorner(this, WaveType.RoundRectWave); + } + } + + if (e.Property == SizeProperty) + { + CollectStyleState(); + SetupIndicatorCheckedMarkEffectSize(); + } + } + + private void SetupIndicatorCheckedMarkEffectSize() + { + if (_styleState.HasFlag(ControlStyleState.Enabled)) + { + if (_styleState.HasFlag(ControlStyleState.On)) + { + CheckedMarkEffectSize = Size; + } + else if (_styleState.HasFlag(ControlStyleState.Off)) + { + CheckedMarkEffectSize = Size * 0.7; + } + else if (_styleState.HasFlag(ControlStyleState.Indeterminate)) + { + CheckedMarkEffectSize = Size * 0.7; + } + } + else + { + if (_styleState.HasFlag(ControlStyleState.On)) + { + CheckedMarkEffectSize = Size; + } + } + } + + public sealed override void Render(DrawingContext context) + { + var penWidth = BorderThickness.Top; + var borderRadius = GeometryUtils.CornerRadiusScalarValue(CornerRadius); + { + _borderRenderHelper.Render(context, Bounds.Size, + new Thickness(penWidth), + new CornerRadius(borderRadius), + BackgroundSizing.OuterBorderEdge, + Background, + BorderBrush, + new BoxShadows()); + } + if (_styleState.HasFlag(ControlStyleState.On)) + { + var checkMarkGeometry = + CommonShapeBuilder.BuildCheckMark(new Size(CheckedMarkEffectSize, + CheckedMarkEffectSize)); + var checkMarkPen = new Pen(CheckedMarkBrush, 2); + context.DrawGeometry(null, checkMarkPen, checkMarkGeometry); + } + else if (_styleState.HasFlag(ControlStyleState.Indeterminate)) + { + var deltaSize = (Size - TristateMarkSize) / 2.0; + var offsetX = deltaSize; + var offsetY = deltaSize; + var indicatorTristateRect = + new Rect(offsetX, offsetY, TristateMarkSize, TristateMarkSize); + context.FillRectangle(TristateMarkBrush!, indicatorTristateRect); + } + } + + public Rect WaveGeometry() + { + return new Rect(Bounds.Size); + } + + public CornerRadius WaveBorderRadius() + { + return CornerRadius; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls/CheckBox/CheckBoxTheme.cs b/src/AtomUI.Controls/CheckBox/CheckBoxTheme.cs index 0609888..7870d24 100644 --- a/src/AtomUI.Controls/CheckBox/CheckBoxTheme.cs +++ b/src/AtomUI.Controls/CheckBox/CheckBoxTheme.cs @@ -1,7 +1,13 @@ using AtomUI.Theme; using AtomUI.Theme.Styling; +using Avalonia.Controls; +using Avalonia.Controls.Presenters; using Avalonia.Controls.Primitives; +using Avalonia.Controls.Templates; +using Avalonia.Data; +using Avalonia.Data.Converters; using Avalonia.Input; +using Avalonia.Layout; using Avalonia.Styling; namespace AtomUI.Controls; @@ -9,74 +15,172 @@ namespace AtomUI.Controls; [ControlThemeProvider] internal class CheckBoxTheme : BaseControlTheme { + internal const string FramePart = "PART_Frame"; + internal const string IndicatorPart = "PART_Indicator"; + internal const string ContentPresenterPart = "PART_ContentPresenter"; + public CheckBoxTheme() : base(typeof(CheckBox)) { } + + protected override IControlTemplate? BuildControlTemplate() + { + return new FuncControlTemplate((checkBox, scope) => + { + var frame = new Border() + { + Name = FramePart + }; + CreateTemplateParentBinding(frame, Border.BackgroundProperty, CheckBox.BackgroundProperty); + CreateTemplateParentBinding(frame, Border.BorderBrushProperty, CheckBox.BorderBrushProperty); + CreateTemplateParentBinding(frame, Border.BorderThicknessProperty, CheckBox.BorderThicknessProperty); + CreateTemplateParentBinding(frame, Border.CornerRadiusProperty, CheckBox.CornerRadiusProperty); + + var layout = new DockPanel() + { + LastChildFill = true + }; + + var indicator = new CheckBoxIndicator() + { + Name = IndicatorPart + }; + DockPanel.SetDock(indicator, Dock.Left); + CreateTemplateParentBinding(indicator, CheckBoxIndicator.IsEnabledProperty, CheckBox.IsEnabledProperty); + CreateTemplateParentBinding(indicator, CheckBoxIndicator.IsCheckedProperty, CheckBox.IsCheckedProperty); + layout.Children.Add(indicator); + + var contentPresenter = new ContentPresenter() + { + Name = ContentPresenterPart, + RecognizesAccessKey = true + }; + CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentTemplateProperty, CheckBox.ContentTemplateProperty); + CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentProperty, CheckBox.ContentProperty); + CreateTemplateParentBinding(contentPresenter, ContentPresenter.FontSizeProperty, CheckBox.FontSizeProperty); + CreateTemplateParentBinding(contentPresenter, ContentPresenter.IsVisibleProperty, CheckBox.ContentProperty, + BindingMode.Default, ObjectConverters.IsNotNull); + layout.Children.Add(contentPresenter); + frame.Child = layout; + return frame; + }); + } protected override void BuildStyles() { - this.Add(CheckBox.CheckIndicatorSizeProperty, CheckBoxTokenResourceKey.CheckIndicatorSize); - this.Add(CheckBox.PaddingInlineProperty, GlobalTokenResourceKey.PaddingXS); - this.Add(CheckBox.IndicatorBorderRadiusProperty, GlobalTokenResourceKey.BorderRadiusSM); - this.Add(CheckBox.IndicatorTristateMarkSizeProperty, CheckBoxTokenResourceKey.IndicatorTristateMarkSize); - this.Add(CheckBox.IndicatorTristateMarkBrushProperty, GlobalTokenResourceKey.ColorPrimary); - BuildEnabledStyle(); - BuildDisabledStyle(); - } + BuildIndicatorStyle(); - private void BuildDisabledStyle() - { + var commonStyle = new Style(selector => selector.Nesting()); + commonStyle.Add(CheckBox.CursorProperty, new Cursor(StandardCursorType.Hand)); + commonStyle.Add(CheckBox.HorizontalAlignmentProperty, HorizontalAlignment.Left); + + var contentPresenterStyle = new Style(selector => selector.Nesting().Template().Name(ContentPresenterPart)); + contentPresenterStyle.Add(ContentPresenter.MarginProperty, CheckBoxTokenResourceKey.TextMargin); + commonStyle.Add(contentPresenterStyle); + + Add(commonStyle); + var disableStyle = new Style(selector => selector.Nesting().PropertyEquals(InputElement.IsEnabledProperty, false)); - disableStyle.Add(CheckBox.IndicatorBackgroundProperty, GlobalTokenResourceKey.ColorBgContainerDisabled); - disableStyle.Add(CheckBox.IndicatorBorderBrushProperty, GlobalTokenResourceKey.ColorBorder); disableStyle.Add(TemplatedControl.ForegroundProperty, GlobalTokenResourceKey.ColorTextDisabled); - - var checkedStyle = - new Style(selector => selector.Nesting().PropertyEquals(ToggleButton.IsCheckedProperty, true)); - checkedStyle.Add(CheckBox.IndicatorCheckedMarkBrushProperty, GlobalTokenResourceKey.ColorTextDisabled); - disableStyle.Add(checkedStyle); - - var indeterminateStyle = - new Style(selector => selector.Nesting().PropertyEquals(ToggleButton.IsCheckedProperty, null)); - indeterminateStyle.Add(CheckBox.IndicatorTristateMarkBrushProperty, GlobalTokenResourceKey.ColorTextDisabled); - disableStyle.Add(indeterminateStyle); Add(disableStyle); - } - - private void BuildEnabledStyle() - { var enabledStyle = new Style(selector => selector.Nesting().PropertyEquals(InputElement.IsEnabledProperty, true)); enabledStyle.Add(TemplatedControl.ForegroundProperty, GlobalTokenResourceKey.ColorText); - enabledStyle.Add(CheckBox.IndicatorBackgroundProperty, GlobalTokenResourceKey.ColorBgContainer); - enabledStyle.Add(CheckBox.IndicatorCheckedMarkBrushProperty, GlobalTokenResourceKey.ColorBgContainer); - enabledStyle.Add(CheckBox.IndicatorBorderBrushProperty, GlobalTokenResourceKey.ColorBorder); - - // 选中 - var checkedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Checked)); - checkedStyle.Add(CheckBox.IndicatorBackgroundProperty, GlobalTokenResourceKey.ColorPrimary); - checkedStyle.Add(CheckBox.IndicatorBorderBrushProperty, GlobalTokenResourceKey.ColorPrimary); - - // 选中 hover - var checkedHoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); - checkedHoverStyle.Add(CheckBox.IndicatorBackgroundProperty, GlobalTokenResourceKey.ColorPrimaryHover); - checkedHoverStyle.Add(CheckBox.IndicatorBorderBrushProperty, GlobalTokenResourceKey.ColorPrimaryHover); - checkedStyle.Add(checkedHoverStyle); - enabledStyle.Add(checkedStyle); - - // 没选中 - var unCheckedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); - unCheckedStyle.Add(CheckBox.IndicatorBorderBrushProperty, GlobalTokenResourceKey.ColorPrimaryHover); - enabledStyle.Add(unCheckedStyle); - - // 中间状态 - var indeterminateStyle = new Style(selector => - selector.Nesting().Class($"{StdPseudoClass.Indeterminate}{StdPseudoClass.PointerOver}")); - indeterminateStyle.Add(CheckBox.IndicatorBorderBrushProperty, GlobalTokenResourceKey.ColorPrimaryHover); - enabledStyle.Add(indeterminateStyle); + Add(enabledStyle); + } + private void BuildIndicatorStyle() + { + { + var indicatorStyle = new Style(selector => selector.Nesting().Template().Name(IndicatorPart)); + indicatorStyle.Add(CheckBoxIndicator.SizeProperty, CheckBoxTokenResourceKey.CheckIndicatorSize); + indicatorStyle.Add(CheckBoxIndicator.WidthProperty, CheckBoxTokenResourceKey.CheckIndicatorSize); + indicatorStyle.Add(CheckBoxIndicator.HeightProperty, CheckBoxTokenResourceKey.CheckIndicatorSize); + indicatorStyle.Add(CheckBoxIndicator.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadiusSM); + indicatorStyle.Add(CheckBoxIndicator.TristateMarkSizeProperty, CheckBoxTokenResourceKey.IndicatorTristateMarkSize); + indicatorStyle.Add(CheckBoxIndicator.TristateMarkBrushProperty, GlobalTokenResourceKey.ColorPrimary); + Add(indicatorStyle); + } + + var disableStyle = + new Style(selector => selector.Nesting().PropertyEquals(InputElement.IsEnabledProperty, false)); + { + { + var indicatorStyle = new Style(selector => selector.Nesting().Template().Name(IndicatorPart)); + indicatorStyle.Add(CheckBoxIndicator.BackgroundProperty, GlobalTokenResourceKey.ColorBgContainerDisabled); + indicatorStyle.Add(CheckBoxIndicator.BorderBrushProperty, GlobalTokenResourceKey.ColorBorder); + disableStyle.Add(indicatorStyle); + } + var checkedStyle = + new Style(selector => selector.Nesting().PropertyEquals(ToggleButton.IsCheckedProperty, true)); + { + var indicatorStyle = new Style(selector => selector.Nesting().Template().Name(IndicatorPart)); + indicatorStyle.Add(CheckBoxIndicator.CheckedMarkBrushProperty, GlobalTokenResourceKey.ColorTextDisabled); + checkedStyle.Add(indicatorStyle); + } + disableStyle.Add(checkedStyle); + + var indeterminateStyle = + new Style(selector => selector.Nesting().PropertyEquals(ToggleButton.IsCheckedProperty, null)); + { + var indicatorStyle = new Style(selector => selector.Nesting().Template().Name(IndicatorPart)); + indicatorStyle.Add(CheckBoxIndicator.TristateMarkBrushProperty, GlobalTokenResourceKey.ColorTextDisabled); + indeterminateStyle.Add(indicatorStyle); + } + disableStyle.Add(indeterminateStyle); + } + + Add(disableStyle); + + var enabledStyle = + new Style(selector => selector.Nesting().PropertyEquals(InputElement.IsEnabledProperty, true)); + + { + { + var indicatorStyle = new Style(selector => selector.Nesting().Template().Name(IndicatorPart)); + indicatorStyle.Add(CheckBoxIndicator.BackgroundProperty, GlobalTokenResourceKey.ColorBgContainer); + indicatorStyle.Add(CheckBoxIndicator.CheckedMarkBrushProperty, GlobalTokenResourceKey.ColorBgContainer); + indicatorStyle.Add(CheckBoxIndicator.BorderBrushProperty, GlobalTokenResourceKey.ColorBorder); + enabledStyle.Add(indicatorStyle); + } + + var checkedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.Checked)); + { + var indicatorStyle = new Style(selector => selector.Nesting().Template().Name(IndicatorPart)); + indicatorStyle.Add(CheckBoxIndicator.BackgroundProperty, GlobalTokenResourceKey.ColorPrimary); + indicatorStyle.Add(CheckBoxIndicator.BorderBrushProperty, GlobalTokenResourceKey.ColorPrimary); + checkedStyle.Add(indicatorStyle); + } + + var checkedHoverStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); + { + var indicatorStyle = new Style(selector => selector.Nesting().Template().Name(IndicatorPart)); + indicatorStyle.Add(CheckBoxIndicator.BackgroundProperty, GlobalTokenResourceKey.ColorPrimaryHover); + indicatorStyle.Add(CheckBoxIndicator.BorderBrushProperty, GlobalTokenResourceKey.ColorPrimaryHover); + checkedHoverStyle.Add(indicatorStyle); + } + checkedStyle.Add(checkedHoverStyle); + enabledStyle.Add(checkedStyle); + + var unCheckedStyle = new Style(selector => selector.Nesting().Class(StdPseudoClass.PointerOver)); + { + var indicatorStyle = new Style(selector => selector.Nesting().Template().Name(IndicatorPart)); + indicatorStyle.Add(CheckBoxIndicator.BorderBrushProperty, GlobalTokenResourceKey.ColorPrimaryHover); + checkedHoverStyle.Add(indicatorStyle); + } + enabledStyle.Add(unCheckedStyle); + + var indeterminateStyle = new Style(selector => + selector.Nesting().Class($"{StdPseudoClass.Indeterminate}{StdPseudoClass.PointerOver}")); + { + var indicatorStyle = new Style(selector => selector.Nesting().Template().Name(IndicatorPart)); + indicatorStyle.Add(CheckBoxIndicator.BorderBrushProperty, GlobalTokenResourceKey.ColorPrimaryHover); + checkedHoverStyle.Add(indicatorStyle); + } + enabledStyle.Add(indeterminateStyle); + } Add(enabledStyle); } } \ No newline at end of file diff --git a/src/AtomUI.Controls/CheckBox/CheckBoxToken.cs b/src/AtomUI.Controls/CheckBox/CheckBoxToken.cs index 3e9e5a1..538a239 100644 --- a/src/AtomUI.Controls/CheckBox/CheckBoxToken.cs +++ b/src/AtomUI.Controls/CheckBox/CheckBoxToken.cs @@ -1,4 +1,5 @@ using AtomUI.Theme.TokenSystem; +using Avalonia; namespace AtomUI.Controls; @@ -11,18 +12,18 @@ internal class CheckBoxToken : AbstractControlDesignToken : base(ID) { } - - /// - /// 复选框标志的大小 - /// + public double CheckIndicatorSize { get; set; } public double IndicatorTristateMarkSize { get; set; } + + public Thickness TextMargin { get; set; } internal override void CalculateFromAlias() { base.CalculateFromAlias(); CheckIndicatorSize = _globalToken.ControlInteractiveSize; - IndicatorTristateMarkSize = _globalToken.FontToken.FontSizeLG / 2; + IndicatorTristateMarkSize = _globalToken.FontSizeLG / 2; + TextMargin = new Thickness(_globalToken.MarginXXS, 0, 0, 0); } } \ No newline at end of file diff --git a/src/AtomUI.Controls/Collapse/Collapse.cs b/src/AtomUI.Controls/Collapse/Collapse.cs index ad6823d..c2d61a5 100644 --- a/src/AtomUI.Controls/Collapse/Collapse.cs +++ b/src/AtomUI.Controls/Collapse/Collapse.cs @@ -115,6 +115,7 @@ public class Collapse : SelectingItemsControl { SelectionModeProperty.OverrideDefaultValue(SelectionMode.Multiple | SelectionMode.Toggle); ItemsPanelProperty.OverrideDefaultValue(DefaultPanel); + AffectsRender(SelectionModeProperty); } public Collapse() diff --git a/src/AtomUI.Controls/Collapse/CollapseItem.cs b/src/AtomUI.Controls/Collapse/CollapseItem.cs index 697952f..6ec9226 100644 --- a/src/AtomUI.Controls/Collapse/CollapseItem.cs +++ b/src/AtomUI.Controls/Collapse/CollapseItem.cs @@ -1,16 +1,16 @@ -using AtomUI.Controls.MotionScene; +using AtomUI.Controls.Primitives; using AtomUI.Controls.Utils; -using AtomUI.MotionScene; using AtomUI.Theme.Styling; using AtomUI.Utils; using Avalonia; +using Avalonia.Animation; +using Avalonia.Animation.Easings; using Avalonia.Automation.Peers; using Avalonia.Controls; using Avalonia.Controls.Metadata; using Avalonia.Controls.Mixins; using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; -using Avalonia.Layout; namespace AtomUI.Controls; @@ -183,7 +183,7 @@ public class CollapseItem : HeaderedContentControl, ISelectable } private bool _enableAnimation = true; - private AnimationTargetPanel? _animationTarget; + private MotionActorControl? _motionActor; private Border? _headerDecorator; private IconButton? _expandButton; @@ -225,7 +225,7 @@ public class CollapseItem : HeaderedContentControl, ISelectable protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); - _animationTarget = e.NameScope.Find(CollapseItemTheme.ContentAnimationTargetPart); + _motionActor = e.NameScope.Find(CollapseItemTheme.ContentMotionActorPart); _headerDecorator = e.NameScope.Find(CollapseItemTheme.HeaderDecoratorPart); _expandButton = e.NameScope.Find(CollapseItemTheme.ExpandButtonPart); TokenResourceBinder.CreateTokenBinding(this, MotionDurationProperty, GlobalTokenResourceKey.MotionDurationSlow); @@ -296,65 +296,51 @@ public class CollapseItem : HeaderedContentControl, ISelectable private void ExpandItemContent() { - if (_animationTarget is null || InAnimating) + if (_motionActor is null || InAnimating) { return; } if (!_enableAnimation) { - _animationTarget.IsVisible = true; + _motionActor.IsVisible = true; return; } - - _animationTarget.IsVisible = true; - LayoutHelper.MeasureChild(_animationTarget, new Size(Bounds.Width, double.PositiveInfinity), new Thickness()); + InAnimating = true; - var director = Director.Instance; - var motion = new ExpandMotion(); - motion.ConfigureOpacity(MotionDuration); - motion.ConfigureHeight(MotionDuration); - var motionActor = new MotionActor(_animationTarget, motion); - motionActor.DispatchInSceneLayer = false; - _animationTarget.InAnimation = true; - motionActor.Completed += (sender, args) => + var slideDownInMotionConfig = MotionFactory.BuildSlideUpInMotion(MotionDuration, new CubicEaseOut(), + FillMode.Forward); + _motionActor.RenderTransformOrigin = slideDownInMotionConfig.RenderTransformOrigin; + MotionInvoker.Invoke(_motionActor, slideDownInMotionConfig, () => { - _animationTarget.InAnimation = false; - InAnimating = false; - }; - director?.Schedule(motionActor); + _motionActor.SetCurrentValue(IsVisibleProperty, true); + }, () => + { + InAnimating = false; + }); } private void CollapseItemContent() { - if (_animationTarget is null || InAnimating) + if (_motionActor is null || InAnimating) { return; } if (!_enableAnimation) { - _animationTarget.IsVisible = false; + _motionActor.IsVisible = false; return; } InAnimating = true; - - LayoutHelper.MeasureChild(_animationTarget, new Size(Bounds.Width, double.PositiveInfinity), new Thickness()); - var director = Director.Instance; - var motion = new CollapseMotion(); - motion.ConfigureOpacity(MotionDuration); - motion.ConfigureHeight(MotionDuration); - var motionActor = new MotionActor(_animationTarget!, motion); - motionActor.DispatchInSceneLayer = false; - _animationTarget.InAnimation = true; - motionActor.Completed += (sender, args) => + var slideDownOutMotionConfig = MotionFactory.BuildSlideUpOutMotion(MotionDuration, new CubicEaseIn(), + FillMode.Forward); + MotionInvoker.Invoke(_motionActor, slideDownOutMotionConfig, null, () => { - InAnimating = false; - _animationTarget.InAnimation = false; - _animationTarget.IsVisible = false; - }; - director?.Schedule(motionActor); + _motionActor.SetCurrentValue(IsVisibleProperty, false); + InAnimating = false; + }); } private void SetupIconButton() diff --git a/src/AtomUI.Controls/Collapse/CollapseItemTheme.cs b/src/AtomUI.Controls/Collapse/CollapseItemTheme.cs index e6aee71..5cffa41 100644 --- a/src/AtomUI.Controls/Collapse/CollapseItemTheme.cs +++ b/src/AtomUI.Controls/Collapse/CollapseItemTheme.cs @@ -1,4 +1,5 @@ -using AtomUI.MotionScene; +using AtomUI.Controls.Primitives; +using AtomUI.MotionScene; using AtomUI.Theme; using AtomUI.Theme.Styling; using AtomUI.Theme.Utils; @@ -26,7 +27,7 @@ internal class CollapseItemTheme : BaseControlTheme public const string HeaderDecoratorPart = "PART_HeaderDecorator"; public const string ContentPresenterPart = "PART_ContentPresenter"; public const string AddOnContentPresenterPart = "PART_AddOnContentPresenter"; - public const string ContentAnimationTargetPart = "PART_ContentAnimationTarget"; + public const string ContentMotionActorPart = "PART_ContentMotionActor"; public CollapseItemTheme() : base(typeof(CollapseItem)) { @@ -43,16 +44,16 @@ internal class CollapseItemTheme : BaseControlTheme }; BuildHeader(mainLayout, scope); - var animationPanel = new AnimationTargetPanel + var motionActor = new MotionActorControl() { - Name = ContentAnimationTargetPart + Name = ContentMotionActorPart }; - animationPanel.SetCurrentValue(Visual.IsVisibleProperty, false); + motionActor.SetCurrentValue(Visual.IsVisibleProperty, false); var contentPresenter = new ContentPresenter { Name = ContentPresenterPart }; - animationPanel.Children.Add(contentPresenter); + motionActor.Child = contentPresenter; TokenResourceBinder.CreateGlobalTokenBinding(contentPresenter, ContentPresenter.BorderBrushProperty, GlobalTokenResourceKey.ColorBorder); CreateTemplateParentBinding(contentPresenter, ContentPresenter.ContentProperty, @@ -61,8 +62,8 @@ internal class CollapseItemTheme : BaseControlTheme ContentControl.ContentTemplateProperty); CreateTemplateParentBinding(contentPresenter, ContentPresenter.BorderThicknessProperty, CollapseItem.ContentBorderThicknessProperty); - mainLayout.Children.Add(animationPanel); - animationPanel.RegisterInNameScope(scope); + mainLayout.Children.Add(motionActor); + motionActor.RegisterInNameScope(scope); contentPresenter.RegisterInNameScope(scope); return mainLayout; }); diff --git a/src/AtomUI.Controls/Collapse/CollapseToken.cs b/src/AtomUI.Controls/Collapse/CollapseToken.cs index a231c28..89b62ff 100644 --- a/src/AtomUI.Controls/Collapse/CollapseToken.cs +++ b/src/AtomUI.Controls/Collapse/CollapseToken.cs @@ -54,10 +54,10 @@ internal class CollapseToken : AbstractControlDesignToken ContentPadding = new Thickness(16, _globalToken.Padding); CollapseContentPaddingSM = new Thickness(_globalToken.PaddingSM); CollapseContentPaddingLG = new Thickness(_globalToken.PaddingLG); - ContentBg = _globalToken.ColorToken.ColorNeutralToken.ColorBgContainer; + ContentBg = _globalToken.ColorBgContainer; CollapseHeaderPaddingSM = new Thickness(_globalToken.PaddingSM, _globalToken.PaddingXS); CollapseHeaderPaddingLG = new Thickness(_globalToken.PaddingLG, _globalToken.Padding); - CollapsePanelBorderRadius = _globalToken.StyleToken.BorderRadiusLG; + CollapsePanelBorderRadius = _globalToken.BorderRadiusLG; LeftExpandButtonMargin = new Thickness(0, 0, _globalToken.MarginSM, 0); RightExpandButtonMargin = new Thickness(_globalToken.MarginSM, 0, 0, 0); } diff --git a/src/AtomUI.Controls/ComboBox/ComboBoxToken.cs b/src/AtomUI.Controls/ComboBox/ComboBoxToken.cs index 9258d20..0960b7f 100644 --- a/src/AtomUI.Controls/ComboBox/ComboBoxToken.cs +++ b/src/AtomUI.Controls/ComboBox/ComboBoxToken.cs @@ -88,20 +88,19 @@ internal class ComboBoxToken : ButtonSpinnerToken { base.CalculateFromAlias(); OpenIndicatorWidth = _globalToken.IconSizeSM * 2.5; - PopupBorderRadius = _globalToken.StyleToken.BorderRadiusLG; + PopupBorderRadius = _globalToken.BorderRadiusLG; PopupContentPadding = new Thickness(_globalToken.PaddingXXS, PopupBorderRadius.TopLeft / 2); PopupBoxShadows = _globalToken.BoxShadowsSecondary; PopupMarginToAnchor = _globalToken.MarginXXS; - - var colorNeutralToken = _globalToken.ColorToken.ColorNeutralToken; + var colorTextDisabled = _globalToken.ColorTextDisabled; - var colorTextSecondary = colorNeutralToken.ColorTextSecondary; - var colorBgContainer = colorNeutralToken.ColorBgContainer; + var colorTextSecondary = _globalToken.ColorTextSecondary; + var colorBgContainer = _globalToken.ColorBgContainer; var colorBgTextHover = _globalToken.ColorBgTextHover; ItemColor = colorTextSecondary; ItemHoverColor = colorTextSecondary; - ItemSelectedColor = colorNeutralToken.ColorText; + ItemSelectedColor = _globalToken.ColorText; ItemBgColor = colorBgContainer; ItemHoverBgColor = colorBgTextHover; diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/Calendar.cs b/src/AtomUI.Controls/DatePicker/CalendarView/Calendar.cs index 1a29222..10af795 100644 --- a/src/AtomUI.Controls/DatePicker/CalendarView/Calendar.cs +++ b/src/AtomUI.Controls/DatePicker/CalendarView/Calendar.cs @@ -13,16 +13,15 @@ namespace AtomUI.Controls.CalendarView; public class DateSelectedEventArgs : EventArgs { - public DateTime? Value { get; } + public DateTime? Date { get; } public DateSelectedEventArgs(DateTime? value) { - Value = value; + Date = value; } } -[TemplatePart(RangeCalendarTheme.CalendarItemPart, typeof(CalendarItem))] -[TemplatePart(RangeCalendarTheme.RootPart, typeof(Panel))] -public class Calendar : TemplatedControl +[TemplatePart(CalendarTheme.CalendarItemPart, typeof(CalendarItem))] +internal class Calendar : TemplatedControl { internal const int RowsPerMonth = 7; internal const int ColumnsPerMonth = 7; @@ -446,8 +445,8 @@ public class Calendar : TemplatedControl /// The DependencyPropertyChangedEventArgs. private void OnDisplayModePropertyChanged(AvaloniaPropertyChangedEventArgs e) { - var mode = (CalendarMode)e.NewValue!; - var oldMode = (CalendarMode)e.OldValue!; + var mode = (CalendarMode)e.NewValue!; + var oldMode = (CalendarMode)e.OldValue!; if (CalendarItem != null) { @@ -527,13 +526,17 @@ public class Calendar : TemplatedControl return; } - c.DisplayDateInternal = DateTimeHelper.DiscardDayTime(addedDate); - + c.SetupDisplayDateInternal(addedDate); c.UpdateMonths(); c.OnDisplayDate(new CalendarDateChangedEventArgs(removedDate, addedDate)); } + + protected virtual void SetupDisplayDateInternal(DateTime displayDate) + { + DisplayDateInternal = DateTimeHelper.DiscardDayTime(displayDate); + } - protected void OnDisplayDate(CalendarDateChangedEventArgs e) + protected void OnDisplayDate(CalendarDateChangedEventArgs e) { DisplayDateChanged?.Invoke(this, e); } @@ -663,9 +666,10 @@ public class Calendar : TemplatedControl } } - internal void ResetStates() + internal virtual void ResetStates() { - var count = RowsPerMonth * ColumnsPerMonth; + var count = RowsPerMonth * ColumnsPerMonth; + if (CalendarItem?.MonthView != null) { for (var childIndex = ColumnsPerMonth; childIndex < count; childIndex++) @@ -903,7 +907,12 @@ public class Calendar : TemplatedControl DateSelected?.Invoke(this, new DateSelectedEventArgs(SelectedDate)); } - internal void NotifyHoverDateChanged(DateTime? hoverDate) + internal void NotifyDateSelected(DateTime? selected) + { + DateSelected?.Invoke(this, new DateSelectedEventArgs(selected)); + } + + internal virtual void NotifyHoverDateChanged(DateTime? hoverDate) { HoverDateChanged?.Invoke(this, new DateSelectedEventArgs(hoverDate)); } @@ -1412,7 +1421,7 @@ public class Calendar : TemplatedControl protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { base.OnApplyTemplate(e); - CalendarItem = e.NameScope.Find(RangeCalendarTheme.CalendarItemPart); + CalendarItem = e.NameScope.Find(CalendarTheme.CalendarItemPart); if (SelectedDate is not null) { @@ -1470,27 +1479,22 @@ public class Calendar : TemplatedControl Debug.Assert(CalendarItem is not null); if (CalendarItem.MonthView is not null) { - var monthView = CalendarItem.MonthView; - var count = monthView.Children.Count; - for (var i = 0; i < count; i++) + UnHighlightDays(CalendarItem.MonthView); + } + } + + protected void UnHighlightDays(Grid monthView) + { + var count = monthView.Children.Count; + for (var i = 0; i < count; i++) + { + if (monthView.Children[i] is CalendarDayButton dayButton) { - if (monthView.Children[i] is CalendarDayButton b) - { - b.IsSelected = false; - } + dayButton.IsSelected = false; } } } - - protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) - { - base.OnPropertyChanged(change); - if (change.Property == SelectedDateProperty) - { - UpdateHighlightDays(); - } - } - + protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { base.OnAttachedToVisualTree(e); diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/CalendarBlackoutDatesCollection.cs b/src/AtomUI.Controls/DatePicker/CalendarView/CalendarBlackoutDatesCollection.cs index 0ffb9bf..9c9ecdb 100644 --- a/src/AtomUI.Controls/DatePicker/CalendarView/CalendarBlackoutDatesCollection.cs +++ b/src/AtomUI.Controls/DatePicker/CalendarView/CalendarBlackoutDatesCollection.cs @@ -3,7 +3,7 @@ using Avalonia.Threading; namespace AtomUI.Controls.CalendarView; -public sealed class CalendarBlackoutDatesCollection : ObservableCollection +internal sealed class CalendarBlackoutDatesCollection : ObservableCollection { /// /// The Calendar whose dates this object represents. diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/CalendarItem.cs b/src/AtomUI.Controls/DatePicker/CalendarView/CalendarItem.cs index 753c0ea..882322a 100644 --- a/src/AtomUI.Controls/DatePicker/CalendarView/CalendarItem.cs +++ b/src/AtomUI.Controls/DatePicker/CalendarView/CalendarItem.cs @@ -13,7 +13,6 @@ using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.Interactivity; using Avalonia.Media; -using Avalonia.Threading; namespace AtomUI.Controls.CalendarView; @@ -225,10 +224,7 @@ internal class CalendarItem : TemplatedControl private void PopulateGrids() { - if (MonthView != null) - { - PopulateMonthViewGrids(MonthView); - } + PopulateMonthViewsGrid(); if (YearView != null) { @@ -263,7 +259,15 @@ internal class CalendarItem : TemplatedControl } } - private void PopulateMonthViewGrids(Grid monthView) + protected virtual void PopulateMonthViewsGrid() + { + if (MonthView != null) + { + PopulateMonthViewGrid(MonthView); + } + } + + protected void PopulateMonthViewGrid(Grid monthView) { var childCount = Calendar.RowsPerMonth + Calendar.RowsPerMonth * Calendar.ColumnsPerMonth; using var children = new PooledList(childCount); @@ -315,17 +319,17 @@ internal class CalendarItem : TemplatedControl /// protected override void OnApplyTemplate(TemplateAppliedEventArgs e) { - HeaderButton = e.NameScope.Find(CalendarItemTheme.HeaderButtonPart); - PreviousButton = e.NameScope.Find(CalendarItemTheme.PreviousButtonPart); + HeaderButton = e.NameScope.Get(CalendarItemTheme.HeaderButtonPart); + PreviousButton = e.NameScope.Get(CalendarItemTheme.PreviousButtonPart); PreviousMonthButton = - e.NameScope.Find(CalendarItemTheme.PreviousMonthButtonPart); - NextButton = e.NameScope.Find(CalendarItemTheme.NextButtonPart); - NextMonthButton = e.NameScope.Find(CalendarItemTheme.NextMonthButtonPart); + e.NameScope.Get(CalendarItemTheme.PreviousMonthButtonPart); + NextButton = e.NameScope.Get(CalendarItemTheme.NextButtonPart); + NextMonthButton = e.NameScope.Get(CalendarItemTheme.NextMonthButtonPart); - MonthViewLayout = e.NameScope.Find(CalendarItemTheme.MonthViewLayoutPart); - MonthView = e.NameScope.Find(CalendarItemTheme.MonthViewPart); - YearView = e.NameScope.Find(CalendarItemTheme.YearViewPart); - _headerLayout = e.NameScope.Find(CalendarItemTheme.HeaderLayoutPart); + MonthViewLayout = e.NameScope.Get(CalendarItemTheme.MonthViewLayoutPart); + MonthView = e.NameScope.Get(CalendarItemTheme.MonthViewPart); + YearView = e.NameScope.Get(CalendarItemTheme.YearViewPart); + _headerLayout = e.NameScope.Get(CalendarItemTheme.HeaderLayoutPart); if (Owner != null) { @@ -373,7 +377,7 @@ internal class CalendarItem : TemplatedControl SetupHeaderForDisplayModeChanged(); } - private void SetupHeaderForDisplayModeChanged() + protected virtual void SetupHeaderForDisplayModeChanged() { if (Owner is null || MonthViewLayout is null || _headerLayout is null) { @@ -383,7 +387,7 @@ internal class CalendarItem : TemplatedControl IsMonthViewMode = Owner.DisplayMode == CalendarMode.Month; } - protected void SetDayTitles() + protected virtual void SetDayTitles() { if (MonthView is not null) { @@ -455,10 +459,15 @@ internal class CalendarItem : TemplatedControl if (MonthViewLayout != null) { SetDayTitles(); - if (MonthView is not null) - { - SetCalendarDayButtons(_currentMonth, MonthView); - } + SetCalendarDayButtons(); + } + } + + protected virtual void SetCalendarDayButtons() + { + if (MonthView is not null) + { + SetCalendarDayButtons(_currentMonth, MonthView); } } @@ -540,17 +549,12 @@ internal class CalendarItem : TemplatedControl // SET IF THE DAY IS INACTIVE OR NOT: set if the day is a // trailing day or not - childButton.IsInactive = CheckDayInactiveState(dateToAdd); + childButton.IsInactive = CheckDayInactiveState(childButton, dateToAdd); // SET IF THE DAY IS TODAY OR NOT childButton.IsToday = CheckDayIsTodayState(dateToAdd); - // SET IF THE DAY IS SELECTED OR NOT - childButton.IsSelected = false; - if (Owner.SelectedDate.HasValue) - { - childButton.IsSelected = DateTimeHelper.CompareDays(Owner.SelectedDate.Value, dateToAdd) == 0; - } + CheckButtonSelectedState(childButton, dateToAdd); // SET THE FOCUS ELEMENT if (Owner.LastSelectedDate != null) @@ -577,7 +581,20 @@ internal class CalendarItem : TemplatedControl } } - protected virtual bool CheckDayInactiveState(DateTime dateToAdd) + protected virtual void CheckButtonSelectedState(CalendarDayButton childButton, DateTime dateToAdd) + { + // SET IF THE DAY IS SELECTED OR NOT + childButton.IsSelected = false; + if (Owner is not null) + { + if (Owner.SelectedDate.HasValue) + { + childButton.IsSelected = DateTimeHelper.CompareDays(Owner.SelectedDate.Value, dateToAdd) == 0; + } + } + } + + protected virtual bool CheckDayInactiveState(CalendarDayButton childButton, DateTime dateToAdd) { if (Owner is not null) { @@ -985,13 +1002,21 @@ internal class CalendarItem : TemplatedControl if (sender is CalendarDayButton { IsEnabled: true, IsBlackout: false, DataContext: DateTime selectedDate - } b) + } dayButton) { - Owner.NotifyHoverDateChanged(selectedDate); + NotifyCellMouseEntered(dayButton, selectedDate); } } } + protected virtual void NotifyCellMouseEntered(CalendarDayButton dayButton, DateTime selectedDate) + { + if (Owner != null) + { + Owner.NotifyHoverDateChanged(selectedDate); + } + } + internal void HandleCellMouseLeftButtonDown(object? sender, PointerPressedEventArgs e) { if (Owner != null) @@ -1001,14 +1026,22 @@ internal class CalendarItem : TemplatedControl Owner.Focus(); } - if (sender is CalendarDayButton b) + if (sender is CalendarDayButton dayButton) { - if (b.IsEnabled && !b.IsBlackout && b.DataContext is DateTime selectedDate) - { - Owner.SelectedDate = selectedDate; - Owner.NotifyDateSelected(); - Owner.UpdateHighlightDays(); - } + NotifyCellMouseLeftButtonDown(dayButton); + } + } + } + + protected virtual void NotifyCellMouseLeftButtonDown(CalendarDayButton dayButton) + { + if (Owner is not null) + { + if (dayButton.IsEnabled && !dayButton.IsBlackout && dayButton.DataContext is DateTime selectedDate) + { + Owner.SelectedDate = selectedDate; + Owner.NotifyDateSelected(); + Owner.UpdateHighlightDays(); } } } @@ -1017,17 +1050,27 @@ internal class CalendarItem : TemplatedControl { if (Owner != null) { - CalendarDayButton? b = sender as CalendarDayButton; - if (b != null && !b.IsBlackout) + if (sender is CalendarDayButton dayButton) { - Owner.OnDayButtonMouseUp(e); - } + if (!dayButton.IsBlackout) + { + Owner.OnDayButtonMouseUp(e); + } - if (b != null && b.DataContext is DateTime selectedDate) + NotifyCellMouseLeftButtonUp(dayButton); + } + } + } + + protected virtual void NotifyCellMouseLeftButtonUp(CalendarDayButton dayButton) + { + if (Owner is not null) + { + if (dayButton.DataContext is DateTime selectedDate) { // If the day is Disabled but a trailing day we should // be able to switch months - if (b.IsInactive) + if (dayButton.IsInactive) { Owner.NotifyDayClick(selectedDate); } @@ -1099,17 +1142,29 @@ internal class CalendarItem : TemplatedControl if (args is RawPointerEventArgs pointerEventArgs) { + var originState = Owner.IsPointerInMonthView; if (!IsPointerInMonthView(pointerEventArgs.Position)) { Owner.IsPointerInMonthView = false; + NotifyPointerOutMonthView(originState); } else { Owner.IsPointerInMonthView = true; + NotifyPointerInMonthView(originState); } } } + protected virtual void NotifyPointerInMonthView(bool originInMonthView) + { + } + + protected virtual void NotifyPointerOutMonthView(bool originInMonthView) + { + + } + protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) { base.OnDetachedFromVisualTree(e); @@ -1131,7 +1186,7 @@ internal class CalendarItem : TemplatedControl return false; } - private Rect GetMonthViewRect(Grid monthView) + protected Rect GetMonthViewRect(Grid monthView) { var firstDay = (monthView.Children[7] as CalendarDayButton)!; var firstDayPos = firstDay.TranslatePoint(new Point(0, 0), TopLevel.GetTopLevel(monthView)!) ?? default; diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/CalendarItemTheme.cs b/src/AtomUI.Controls/DatePicker/CalendarView/CalendarItemTheme.cs index bc90420..cac18cd 100644 --- a/src/AtomUI.Controls/DatePicker/CalendarView/CalendarItemTheme.cs +++ b/src/AtomUI.Controls/DatePicker/CalendarView/CalendarItemTheme.cs @@ -29,7 +29,11 @@ internal class CalendarItemTheme : BaseControlTheme public const string NextButtonPart = "PART_NextButton"; public CalendarItemTheme() - : base(typeof(CalendarItem)) + : this(typeof(CalendarItem)) + { + } + + public CalendarItemTheme(Type targetType) : base(targetType) { } @@ -65,7 +69,7 @@ internal class CalendarItemTheme : BaseControlTheme calendarItem.DayTitleTemplate = new DayTitleTemplate(); } - protected virtual void BuildHeader(DockPanel layout, INameScope scope) + protected void BuildHeader(DockPanel layout, INameScope scope) { var headerFrame = new Border() { @@ -78,16 +82,38 @@ internal class CalendarItemTheme : BaseControlTheme Name = HeaderLayoutPart, Columns = 1 }; - headerLayout.RegisterInNameScope(scope); - BuildHeaderItem(headerLayout, scope); + NotifyConfigureHeaderLayout(headerLayout); + NotifyBuildHeaderItems(headerLayout, scope); DockPanel.SetDock(headerFrame, Dock.Top); headerFrame.Child = headerLayout; layout.Children.Add(headerFrame); } - private void BuildHeaderItem(UniformGrid layout, INameScope scope) + protected virtual void NotifyConfigureHeaderLayout(UniformGrid headerLayout) + { + headerLayout.Columns = 1; + } + + protected virtual void NotifyBuildHeaderItems(UniformGrid headerLayout, INameScope scope) + { + BuildHeaderItem(headerLayout, + PreviousButtonPart, + PreviousMonthButtonPart, + HeaderButtonPart, + NextButtonPart, + NextMonthButtonPart, + scope); + } + + protected void BuildHeaderItem(UniformGrid layout, + string previousButtonName, + string previousMonthButtonName, + string headerButtonName, + string nextButtonName, + string nextMonthButtonName, + INameScope scope) { var headerLayout = new Grid { @@ -101,12 +127,12 @@ internal class CalendarItemTheme : BaseControlTheme } }; - var previousButton = BuildPreviousButton(PreviousButtonPart); + var previousButton = BuildPreviousButton(previousButtonName); previousButton.RegisterInNameScope(scope); Grid.SetColumn(previousButton, 0); headerLayout.Children.Add(previousButton); - var previousMonthButton = BuildPreviousMonthButton(PreviousMonthButtonPart); + var previousMonthButton = BuildPreviousMonthButton(previousMonthButtonName); CreateTemplateParentBinding(previousMonthButton, Visual.IsVisibleProperty, CalendarItem.IsMonthViewModeProperty); previousMonthButton.RegisterInNameScope(scope); @@ -115,20 +141,20 @@ internal class CalendarItemTheme : BaseControlTheme var headerButton = new HeadTextButton { - Name = HeaderButtonPart + Name = headerButtonName }; Grid.SetColumn(headerButton, 2); headerButton.RegisterInNameScope(scope); headerLayout.Children.Add(headerButton); - var nextMonthButton = BuildNextMonthButton(NextMonthButtonPart); + var nextMonthButton = BuildNextMonthButton(nextMonthButtonName); CreateTemplateParentBinding(nextMonthButton, Visual.IsVisibleProperty, CalendarItem.IsMonthViewModeProperty); nextMonthButton.IsVisible = false; nextMonthButton.RegisterInNameScope(scope); Grid.SetColumn(nextMonthButton, 3); headerLayout.Children.Add(nextMonthButton); - var nextButton = BuildNextButton(NextButtonPart); + var nextButton = BuildNextButton(nextButtonName); nextButton.RegisterInNameScope(scope); Grid.SetColumn(nextButton, 4); headerLayout.Children.Add(nextButton); @@ -245,14 +271,11 @@ internal class CalendarItemTheme : BaseControlTheme Columns = 1, IsVisible = false }; - - var monthView = BuildMonthViewItem(MonthViewPart); - monthView.RegisterInNameScope(scope); - monthViewLayout.Children.Add(monthView); - - BindUtils.RelayBind(monthViewLayout, Visual.IsVisibleProperty, monthView, Visual.IsVisibleProperty); - monthViewLayout.RegisterInNameScope(scope); + + NotifyConfigureMonthViewLayout(monthViewLayout, scope); + NotifyBuildMonthViews(monthViewLayout, scope); + layout.Children.Add(monthViewLayout); var yearView = new Grid @@ -276,8 +299,21 @@ internal class CalendarItemTheme : BaseControlTheme yearView.RegisterInNameScope(scope); layout.Children.Add(yearView); } + + protected virtual void NotifyConfigureMonthViewLayout(UniformGrid monthViewLayout, INameScope scope) + { + monthViewLayout.Columns = 1; + } - private Grid BuildMonthViewItem(string name) + protected virtual void NotifyBuildMonthViews(UniformGrid monthViewLayout, INameScope scope) + { + var monthView = BuildMonthViewItem(MonthViewPart); + BindUtils.RelayBind(monthViewLayout, Visual.IsVisibleProperty, monthView, Visual.IsVisibleProperty); + monthView.RegisterInNameScope(scope); + monthViewLayout.Children.Add(monthView); + } + + protected Grid BuildMonthViewItem(string name) { var monthViewLayout = new Grid { @@ -314,6 +350,7 @@ internal class CalendarItemTheme : BaseControlTheme commonStyle.Add(CalendarItem.MinHeightProperty, DatePickerTokenResourceKey.ItemPanelMinHeight); commonStyle.Add(CalendarItem.MinWidthProperty, DatePickerTokenResourceKey.ItemPanelMinWidth); + var headerFrameStyle = new Style(selector => selector.Nesting().Template().Name(HeaderFramePart)); headerFrameStyle.Add(Border.MarginProperty, DatePickerTokenResourceKey.HeaderMargin); headerFrameStyle.Add(Border.PaddingProperty, DatePickerTokenResourceKey.HeaderPadding); diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/CalendarTheme.cs b/src/AtomUI.Controls/DatePicker/CalendarView/CalendarTheme.cs index 401e0a7..b4d981e 100644 --- a/src/AtomUI.Controls/DatePicker/CalendarView/CalendarTheme.cs +++ b/src/AtomUI.Controls/DatePicker/CalendarView/CalendarTheme.cs @@ -37,20 +37,24 @@ internal class CalendarTheme : BaseControlTheme CreateTemplateParentBinding(frame, Border.MinWidthProperty, Calendar.MinWidthProperty); CreateTemplateParentBinding(frame, Border.MinHeightProperty, Calendar.MinHeightProperty); - var calendarItem = new CalendarItem - { - Name = CalendarItemPart, - HorizontalAlignment = HorizontalAlignment.Stretch - }; - - calendarItem.RegisterInNameScope(scope); - - frame.Child = calendarItem; + frame.Child = BuildCalendarItem(scope); return frame; }); } + protected virtual CalendarItem BuildCalendarItem(INameScope scope) + { + var calendarItem = new CalendarItem + { + Name = CalendarItemPart, + HorizontalAlignment = HorizontalAlignment.Stretch + }; + + calendarItem.RegisterInNameScope(scope); + return calendarItem; + } + protected override void BuildStyles() { base.BuildStyles(); diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthCalendarItem.cs b/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthCalendarItem.cs new file mode 100644 index 0000000..cd6d03f --- /dev/null +++ b/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthCalendarItem.cs @@ -0,0 +1,292 @@ +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; + +namespace AtomUI.Controls.CalendarView; + +internal class DualMonthCalendarItem : RangeCalendarItem +{ + protected override Type StyleKeyOverride => typeof(DualMonthCalendarItem); + + #region 内部属性定义 + + protected HeadTextButton? _secondaryHeaderButton; + internal HeadTextButton? SecondaryHeaderButton + { + get => _secondaryHeaderButton; + + private set + { + if (_secondaryHeaderButton != null) + { + _secondaryHeaderButton.Click -= HandleHeaderButtonClick; + } + + _secondaryHeaderButton = value; + + if (_secondaryHeaderButton != null) + { + _secondaryHeaderButton.Click += HandleHeaderButtonClick; + _secondaryHeaderButton.Focusable = false; + } + } + } + + protected IconButton? _secondaryNextButton; + + /// + /// Gets the button that displays the next page of the calendar when it + /// is clicked. + /// + internal IconButton? SecondaryNextButton + { + get => _secondaryNextButton; + + private set + { + if (_secondaryNextButton != null) + { + _secondaryNextButton.Click -= HandleNextButtonClick; + } + + _secondaryNextButton = value; + + if (_secondaryNextButton != null) + { + _secondaryNextButton.Click += HandleNextButtonClick; + _secondaryNextButton.Focusable = false; + } + } + } + + protected IconButton? _secondaryNextMonthButton; + internal IconButton? SecondaryNextMonthButton + { + get => _secondaryNextMonthButton; + + private set + { + if (_secondaryNextMonthButton != null) + { + _secondaryNextMonthButton.Click -= HandleNextMonthButtonClick; + } + + _secondaryNextMonthButton = value; + + if (_secondaryNextMonthButton != null) + { + _secondaryNextMonthButton.Click += HandleNextMonthButtonClick; + _secondaryNextMonthButton.Focusable = false; + } + } + } + + protected IconButton? _secondaryPreviousButton; + /// + /// Gets the button that displays the previous page of the calendar when + /// it is clicked. + /// + internal IconButton? SecondaryPreviousButton + { + get => _secondaryPreviousButton; + + private set + { + if (_secondaryPreviousButton != null) + { + _secondaryPreviousButton.Click -= HandlePreviousButtonClick; + } + + _secondaryPreviousButton = value; + + if (_secondaryPreviousButton != null) + { + _secondaryPreviousButton.Click += HandlePreviousButtonClick; + _secondaryPreviousButton.Focusable = false; + } + } + } + + protected IconButton? _secondaryPreviousMonthButton; + internal IconButton? SecondaryPreviousMonthButton + { + get => _secondaryPreviousMonthButton; + + private set + { + if (_secondaryPreviousMonthButton != null) + { + _secondaryPreviousMonthButton.Click -= HandlePreviousMonthButtonClick; + } + + _secondaryPreviousMonthButton = value; + + if (_secondaryPreviousMonthButton != null) + { + _secondaryPreviousMonthButton.Click += HandlePreviousMonthButtonClick; + _secondaryPreviousMonthButton.Focusable = false; + } + } + } + + internal Grid? SecondaryMonthView { get; set; } + + #endregion + + protected DateTime _nextMonth; + + protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs change) + { + base.OnPropertyChanged(change); + SetupMonthViewMode(); + } + + protected override bool IsPointerInMonthView(Point position) + { + if (Owner is null || Owner.DisplayMode != CalendarMode.Month) + { + return false; + } + if (base.IsPointerInMonthView(position)) + { + return true; + } + + return GetMonthViewRect(SecondaryMonthView!).Contains(position); + } + + protected override void OnApplyTemplate(TemplateAppliedEventArgs e) + { + SecondaryMonthView = e.NameScope.Get(DualMonthCalendarItemTheme.SecondaryMonthViewPart); + SecondaryHeaderButton = e.NameScope.Get(DualMonthCalendarItemTheme.SecondaryHeaderButtonPart); + SecondaryPreviousButton = e.NameScope.Get(DualMonthCalendarItemTheme.SecondaryPreviousButtonPart); + SecondaryPreviousMonthButton = e.NameScope.Find(DualMonthCalendarItemTheme.SecondaryPreviousMonthButtonPart); + SecondaryNextButton = e.NameScope.Get(DualMonthCalendarItemTheme.SecondaryNextButtonPart); + SecondaryNextMonthButton = e.NameScope.Get(DualMonthCalendarItemTheme.SecondaryNextMonthButtonPart); + + base.OnApplyTemplate(e); + SetupMonthViewMode(); + } + + private void SetupMonthViewMode() + { + if (SecondaryMonthView is null || + _previousButton is null || + _previousMonthButton is null || + _nextButton is null || + _nextMonthButton is null || + _secondaryHeaderButton is null || + _secondaryPreviousButton is null || + _secondaryPreviousMonthButton is null || + _secondaryNextButton is null || + _secondaryNextMonthButton is null) + { + return; + } + + _previousButton.IsVisible = false; + _previousMonthButton.IsVisible = false; + _nextButton.IsVisible = false; + _nextMonthButton.IsVisible = false; + _secondaryPreviousButton.IsVisible = false; + _secondaryPreviousMonthButton.IsVisible = false; + _secondaryNextButton.IsVisible = false; + _secondaryNextMonthButton.IsVisible = false; + + if (IsMonthViewMode) + { + SecondaryMonthView.IsVisible = true; + _secondaryHeaderButton.IsVisible = true; + _previousButton.IsVisible = true; + _previousMonthButton.IsVisible = true; + _secondaryNextButton.IsVisible = true; + _secondaryNextMonthButton.IsVisible = true; + } + else + { + SecondaryMonthView.IsVisible = false; + _secondaryHeaderButton.IsVisible = false; + _previousButton.IsVisible = true; + _previousMonthButton.IsVisible = true; + _nextButton.IsVisible = true; + _nextMonthButton.IsVisible = true; + } + } + + protected override void PopulateMonthViewsGrid() + { + base.PopulateMonthViewsGrid(); + if (SecondaryMonthView != null) + { + PopulateMonthViewGrid(SecondaryMonthView); + } + } + + protected override void SetDayTitles() + { + base.SetDayTitles(); + if (SecondaryMonthView is not null) + { + SetDayTitles(SecondaryMonthView); + } + } + + protected override void SetupHeaderForDisplayModeChanged() + { + base.SetupHeaderForDisplayModeChanged(); + if (Owner is not null && _headerLayout is not null && MonthViewLayout is not null) + { + if (Owner.DisplayMode == CalendarMode.Month) + { + MonthViewLayout.Columns = 2; + _headerLayout.Columns = 2; + } + else if (Owner.DisplayMode == CalendarMode.Year || Owner.DisplayMode == CalendarMode.Decade) + { + MonthViewLayout.Columns = 1; + _headerLayout.Columns = 1; + } + } + } + + protected internal override void UpdateMonthMode() + { + if (Owner is DualMonthRangeCalendar dualMonthRangeCalendar) + { + _nextMonth = dualMonthRangeCalendar.SecondaryDisplayDateInternal; + } + else + { + _nextMonth = DateTime.Today; + } + base.UpdateMonthMode(); + } + + protected override void SetCalendarDayButtons() + { + base.SetCalendarDayButtons(); + if (SecondaryMonthView is not null) + { + SetCalendarDayButtons(_nextMonth, SecondaryMonthView); + } + } + + protected override void SetMonthModeHeaderButton() + { + base.SetMonthModeHeaderButton(); + if (SecondaryHeaderButton is not null) + { + if (Owner is DualMonthRangeCalendar owner) + { + SecondaryHeaderButton.Content = + owner.SecondaryDisplayDateInternal.ToString("Y", DateTimeHelper.GetCurrentDateFormat()); + SecondaryHeaderButton.IsEnabled = true; + } + else + { + SecondaryHeaderButton.Content = DateTime.Today.ToString("Y", DateTimeHelper.GetCurrentDateFormat()); + } + } + } + +} \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthCalendarItemTheme.cs b/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthCalendarItemTheme.cs new file mode 100644 index 0000000..1f4d43c --- /dev/null +++ b/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthCalendarItemTheme.cs @@ -0,0 +1,75 @@ +using AtomUI.Data; +using AtomUI.Theme.Styling; +using AtomUI.Utils; +using Avalonia; +using Avalonia.Controls; +using Avalonia.Controls.Primitives; +using Avalonia.Controls.Templates; +using Avalonia.Data; +using Avalonia.Layout; + +namespace AtomUI.Controls.CalendarView; + +[ControlThemeProvider] +internal class DualMonthCalendarItemTheme : CalendarItemTheme +{ + public const string SecondaryMonthViewPart = "PART_SecondaryMonthView"; + public const string SecondaryPreviousButtonPart = "PART_SecondaryPreviousButton"; + public const string SecondaryPreviousMonthButtonPart = "PART_SecondaryPreviousMonthButton"; + public const string SecondaryHeaderButtonPart = "PART_SecondaryHeaderButton"; + public const string SecondaryNextMonthButtonPart = "PART_SecondaryNextMonthButton"; + public const string SecondaryNextButtonPart = "PART_SecondaryNextButton"; + + public DualMonthCalendarItemTheme() + : this(typeof(DualMonthCalendarItem)) + { + } + + public DualMonthCalendarItemTheme(Type targetType) : base(targetType) + { + } + + protected override void NotifyConfigureHeaderLayout(UniformGrid headerLayout) + { + headerLayout.Columns = 2; + } + + protected override void NotifyBuildHeaderItems(UniformGrid headerLayout, INameScope scope) + { + base.NotifyBuildHeaderItems(headerLayout, scope); + BuildHeaderItem(headerLayout, + SecondaryPreviousButtonPart, + SecondaryPreviousMonthButtonPart, + SecondaryHeaderButtonPart, + SecondaryNextButtonPart, + SecondaryNextMonthButtonPart, + scope); + } + + protected override void NotifyConfigureMonthViewLayout(UniformGrid monthViewLayout, INameScope scope) + { + monthViewLayout.Columns = 2; + } + + protected override void NotifyBuildMonthViews(UniformGrid monthViewLayout, INameScope scope) + { + base.NotifyBuildMonthViews(monthViewLayout, scope); + var monthView = BuildMonthViewItem(SecondaryMonthViewPart); + BindUtils.RelayBind(monthViewLayout, Visual.IsVisibleProperty, monthView, Visual.IsVisibleProperty); + + TokenResourceBinder.CreateTokenBinding(monthView, Layoutable.MarginProperty, + DatePickerTokenResourceKey.RangeCalendarSpacing, BindingPriority.Template, + v => + { + if (v is double dval) + { + return new Thickness(dval, 0, 0, 0); + } + + return new Thickness(); + }); + + monthView.RegisterInNameScope(scope); + monthViewLayout.Children.Add(monthView); + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthRangeCalendar.cs b/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthRangeCalendar.cs new file mode 100644 index 0000000..25974fa --- /dev/null +++ b/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthRangeCalendar.cs @@ -0,0 +1,58 @@ +using System.Diagnostics; + +namespace AtomUI.Controls.CalendarView; + +internal class DualMonthRangeCalendar : RangeCalendar +{ + protected override Type StyleKeyOverride => typeof(DualMonthRangeCalendar); + + internal override void ResetStates() + { + base.ResetStates(); + var count = RowsPerMonth * ColumnsPerMonth; + if (CalendarItem is DualMonthCalendarItem dualMonthCalendarItem) + { + if (dualMonthCalendarItem.SecondaryMonthView is not null) + { + var monthView = dualMonthCalendarItem.SecondaryMonthView; + for (var childIndex = ColumnsPerMonth; childIndex < count; childIndex++) + { + var d = (CalendarDayButton)monthView.Children[childIndex]; + d.IgnoreMouseOverState(); + } + } + } + } + + internal override void UpdateHighlightDays() + { + DateTime? rangeStart = default; + DateTime? rangeEnd = default; + SortHoverIndexes(out rangeStart, out rangeEnd); + Debug.Assert(CalendarItem is not null); + if (CalendarItem is DualMonthCalendarItem dualMonthCalendarItem) + { + if (dualMonthCalendarItem.MonthView is not null) + { + UpdateHighlightDays(dualMonthCalendarItem.MonthView, rangeStart, rangeEnd); + } + + if (dualMonthCalendarItem.SecondaryMonthView is not null) + { + UpdateHighlightDays(dualMonthCalendarItem.SecondaryMonthView, rangeStart, rangeEnd); + } + } + } + + internal override void UnHighlightDays() + { + base.UnHighlightDays(); + if (CalendarItem is DualMonthCalendarItem dualMonthCalendarItem) + { + if (dualMonthCalendarItem.SecondaryMonthView is not null) + { + UnHighlightDays(dualMonthCalendarItem.SecondaryMonthView); + } + } + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthRangeCalendarTheme.cs b/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthRangeCalendarTheme.cs new file mode 100644 index 0000000..e6746a2 --- /dev/null +++ b/src/AtomUI.Controls/DatePicker/CalendarView/DualMonthRangeCalendarTheme.cs @@ -0,0 +1,27 @@ +using AtomUI.Theme.Styling; +using Avalonia.Controls; +using Avalonia.Controls.Templates; +using Avalonia.Layout; + +namespace AtomUI.Controls.CalendarView; + +[ControlThemeProvider] +internal class DualMonthRangeCalendarTheme : CalendarTheme +{ + public DualMonthRangeCalendarTheme() + : base(typeof(DualMonthRangeCalendar)) + { + } + + protected override CalendarItem BuildCalendarItem(INameScope scope) + { + var calendarItem = new DualMonthCalendarItem + { + Name = CalendarItemPart, + HorizontalAlignment = HorizontalAlignment.Stretch + }; + + calendarItem.RegisterInNameScope(scope); + return calendarItem; + } +} \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendar.cs b/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendar.cs index 55c3279..1571329 100644 --- a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendar.cs +++ b/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendar.cs @@ -1,870 +1,91 @@ using System.Diagnostics; using System.Text; -using AtomUI.Theme.Data; -using AtomUI.Theme.Styling; -using AtomUI.Utils; using Avalonia; using Avalonia.Controls; -using Avalonia.Controls.Metadata; -using Avalonia.Controls.Primitives; using Avalonia.Data; -using Avalonia.Input; -using Avalonia.Interactivity; -using Avalonia.Layout; -using Avalonia.Media; namespace AtomUI.Controls.CalendarView; -public class RangeDateSelectedEventArgs : RoutedEventArgs +public class RangeDateSelectedEventArgs : EventArgs { public CalendarDateRange Range { get; } - public RangeDateSelectedEventArgs(CalendarDateRange range) + public bool IsFixedRange { get; } + + public RangeDateSelectedEventArgs(CalendarDateRange range, bool isFixedRange) { - Range = range; + Range = range; + IsFixedRange = isFixedRange; } } -public class HoverDateSelectedEventArgs : RoutedEventArgs +internal class RangeCalendar : Calendar { - public DateTime? HoverDate { get; } - public HoverDateSelectedEventArgs(DateTime? date) - { - HoverDate = date; - } -} - -[TemplatePart(RangeCalendarTheme.CalendarItemPart, typeof(RangeCalendarItem))] -[TemplatePart(RangeCalendarTheme.RootPart, typeof(Panel))] -public class RangeCalendar : TemplatedControl -{ - internal const int RowsPerMonth = 7; - internal const int ColumnsPerMonth = 7; - internal const int RowsPerYear = 3; - internal const int ColumnsPerYear = 4; - + protected override Type StyleKeyOverride => typeof(RangeCalendar); + #region 公共属性定义 - public static readonly StyledProperty FirstDayOfWeekProperty = - AvaloniaProperty.Register( - nameof(FirstDayOfWeek), - DateTimeHelper.GetCurrentDateFormat().FirstDayOfWeek); - - /// - /// Gets or sets the day that is considered the beginning of the week. - /// - /// - /// A representing the beginning of - /// the week. The default is . - /// - public DayOfWeek FirstDayOfWeek - { - get => GetValue(FirstDayOfWeekProperty); - set => SetValue(FirstDayOfWeekProperty, value); - } - - public static readonly StyledProperty IsTodayHighlightedProperty = - AvaloniaProperty.Register( - nameof(IsTodayHighlighted), - true); - - /// - /// Gets or sets a value indicating whether the current date is - /// highlighted. - /// - /// - /// True if the current date is highlighted; otherwise, false. The - /// default is true. - /// - public bool IsTodayHighlighted - { - get => GetValue(IsTodayHighlightedProperty); - set => SetValue(IsTodayHighlightedProperty, value); - } - - public static readonly StyledProperty HeaderBackgroundProperty = - AvaloniaProperty.Register(nameof(HeaderBackground)); - - public IBrush? HeaderBackground - { - get => GetValue(HeaderBackgroundProperty); - set => SetValue(HeaderBackgroundProperty, value); - } - - public static readonly StyledProperty DisplayModeProperty = - AvaloniaProperty.Register( - nameof(DisplayMode), - validate: IsValidDisplayMode); - - /// - /// Gets or sets a value indicating whether the calendar is displayed in - /// months, years, or decades. - /// - /// - /// A value indicating what length of time the - /// should display. - /// - public CalendarMode DisplayMode - { - get => GetValue(DisplayModeProperty); - set => SetValue(DisplayModeProperty, value); - } - - public static readonly StyledProperty SelectedRangeStartDateProperty = - AvaloniaProperty.Register(nameof(SelectedRangeStartDate), + public static readonly StyledProperty SecondarySelectedDateProperty = + AvaloniaProperty.Register(nameof(SecondarySelectedDate), defaultBindingMode: BindingMode.TwoWay); - public DateTime? SelectedRangeStartDate + public DateTime? SecondarySelectedDate { - get => GetValue(SelectedRangeStartDateProperty); - set => SetValue(SelectedRangeStartDateProperty, value); + get => GetValue(SecondarySelectedDateProperty); + set => SetValue(SecondarySelectedDateProperty, value); } - - public static readonly StyledProperty SelectedRangeEndDateProperty = - AvaloniaProperty.Register(nameof(SelectedRangeEndDate), - defaultBindingMode: BindingMode.TwoWay); - - public DateTime? SelectedRangeEndDate - { - get => GetValue(SelectedRangeEndDateProperty); - set => SetValue(SelectedRangeEndDateProperty, value); - } - - public static readonly StyledProperty DisplayDateProperty = - AvaloniaProperty.Register(nameof(DisplayDate), - defaultBindingMode: BindingMode.TwoWay); - - /// - /// Gets or sets the date to display. - /// - /// The date to display. - /// - /// The given date is not in the range specified by - /// - /// and - /// . - /// - /// - /// - /// This property allows the developer to specify a date to display. If - /// this property is a null reference (Nothing in Visual Basic), - /// SelectedDate is displayed. If SelectedDate is also a null reference - /// (Nothing in Visual Basic), Today is displayed. The default is - /// Today. - /// - /// - /// To set this property in XAML, use a date specified in the format - /// yyyy/mm/dd. The mm and dd components must always consist of two - /// characters, with a leading zero if necessary. For instance, the - /// month of May should be specified as 05. - /// - /// - public DateTime DisplayDate - { - get => GetValue(DisplayDateProperty); - set => SetValue(DisplayDateProperty, value); - } - - public static readonly StyledProperty DisplayDateStartProperty = - AvaloniaProperty.Register(nameof(DisplayDateStart), - defaultBindingMode: BindingMode.TwoWay); - - /// - /// Gets or sets the first date to be displayed. - /// - /// The first date to display. - /// - /// To set this property in XAML, use a date specified in the format - /// yyyy/mm/dd. The mm and dd components must always consist of two - /// characters, with a leading zero if necessary. For instance, the - /// month of May should be specified as 05. - /// - public DateTime? DisplayDateStart - { - get => GetValue(DisplayDateStartProperty); - set => SetValue(DisplayDateStartProperty, value); - } - - public static readonly StyledProperty DisplayDateEndProperty = - AvaloniaProperty.Register(nameof(DisplayDateEnd), - defaultBindingMode: BindingMode.TwoWay); - - /// - /// Gets or sets the last date to be displayed. - /// - /// The last date to display. - /// - /// To set this property in XAML, use a date specified in the format - /// yyyy/mm/dd. The mm and dd components must always consist of two - /// characters, with a leading zero if necessary. For instance, the - /// month of May should be specified as 05. - /// - public DateTime? DisplayDateEnd - { - get => GetValue(DisplayDateEndProperty); - set => SetValue(DisplayDateEndProperty, value); - } - - /// - /// 设置是否固定 RangeStart - /// - public bool FixedRangeStart { get; set; } = true; /// /// 是否修复选择结果,当开始日期大于结束日期的时候进行位置调换 /// public bool IsRepairReverseRange { get; set; } = true; - + + /// + /// 当前是否在选择范围开始日期 + /// + public bool IsSelectRangeStart { get; set; } = true; + #endregion #region 内部属性定义 - internal RangeCalendarDayButton? FocusButton { get; set; } - internal RangeCalendarButton? FocusCalendarButton { get; set; } - - internal Panel? Root { get; set; } - - internal RangeCalendarItem? MonthControl - { - get - { - if (Root != null && Root.Children.Count > 0) - { - return Root.Children[0] as RangeCalendarItem; - } - - return null; - } - } - - internal DateTime? LastSelectedDateInternal { get; set; } - - internal DateTime? LastSelectedDate - { - get => LastSelectedDateInternal; - - set - { - LastSelectedDateInternal = value; - - if (FocusButton != null) - { - FocusButton.IsCurrent = false; - } - - FocusButton = FindDayButtonFromDay(LastSelectedDate!.Value); - if (FocusButton != null) - { - FocusButton.IsCurrent = HasFocusInternal; - } - } - } - - internal DateTime SelectedMonth - { - get => _selectedMonth; - - set - { - var monthDifferenceStart = DateTimeHelper.CompareYearMonth(value, DisplayDateRangeStart); - var monthDifferenceEnd = DateTimeHelper.CompareYearMonth(value, DisplayDateRangeEnd); - - if (monthDifferenceStart >= 0 && monthDifferenceEnd <= 0) - { - _selectedMonth = DateTimeHelper.DiscardDayTime(value); - } - else - { - if (monthDifferenceStart < 0) - { - _selectedMonth = DateTimeHelper.DiscardDayTime(DisplayDateRangeStart); - } - else - { - Debug.Assert(monthDifferenceEnd > 0, "monthDifferenceEnd should be greater than 0!"); - _selectedMonth = DateTimeHelper.DiscardDayTime(DisplayDateRangeEnd); - } - } - } - } - - internal DateTime SelectedYear - { - get => _selectedYear; - - set - { - if (value.Year < DisplayDateRangeStart.Year) - { - _selectedYear = DisplayDateRangeStart; - } - else - { - if (value.Year > DisplayDateRangeEnd.Year) - { - _selectedYear = DisplayDateRangeEnd; - } - else - { - _selectedYear = value; - } - } - } - } - - internal DateTime DisplayDateInternal { get; set; } internal DateTime SecondaryDisplayDateInternal { get; set; } + internal DateTime? HoverDateTime { get; set; } #endregion - private bool _displayDateIsChanging; - private DateTime _selectedMonth; - private DateTime _selectedYear; - - static RangeCalendar() - { - IsEnabledProperty.Changed.AddClassHandler((x, e) => x.OnIsEnabledChanged(e)); - FirstDayOfWeekProperty.Changed.AddClassHandler((x, e) => x.OnFirstDayOfWeekChanged(e)); - IsTodayHighlightedProperty.Changed.AddClassHandler((x, e) => x.OnIsTodayHighlightedChanged(e)); - DisplayModeProperty.Changed.AddClassHandler((x, e) => x.OnDisplayModePropertyChanged(e)); - DisplayDateProperty.Changed.AddClassHandler((x, e) => x.OnDisplayDateChanged(e)); - DisplayDateStartProperty.Changed.AddClassHandler((x, e) => x.OnDisplayDateStartChanged(e)); - DisplayDateEndProperty.Changed.AddClassHandler((x, e) => x.OnDisplayDateEndChanged(e)); - KeyDownEvent.AddClassHandler((x, e) => x.HandleCalendarKeyDown(e)); - HorizontalAlignmentProperty.OverrideDefaultValue(HorizontalAlignment.Left); - VerticalAlignmentProperty.OverrideDefaultValue(VerticalAlignment.Top); - } + #region 公共事件定义 /// - /// Initializes a new instance of the - /// class. + /// 当范围选择完成的时候派发这个事件 /// - public RangeCalendar() + public event EventHandler? RangeDateSelected; + + #endregion + + protected override void SetupDisplayDateInternal(DateTime displayDate) { - SetCurrentValue(DisplayDateProperty, DateTime.Today); - UpdateDisplayDate(this, DisplayDate, DateTime.MinValue); - BlackoutDates = new RangeCalendarBlackoutDatesCollection(this); + base.SetupDisplayDateInternal(displayDate); + SecondaryDisplayDateInternal = DateTimeHelper.AddMonths(DisplayDateInternal, 1) ?? DisplayDateInternal; } - /// - /// Gets a collection of dates that are marked as not selectable. - /// - /// - /// A collection of dates that cannot be selected. The default value is - /// an empty collection. - /// - /// - /// Adding a date to this collection when it is already selected or - /// adding a date outside the range specified by DisplayDateStart and - /// DisplayDateEnd. - /// - /// - /// - /// Dates in this collection will appear as disabled on the calendar. - /// - /// - /// To make all past dates not selectable, you can use the - /// AddDatesInPast method provided by the collection returned by this - /// property. - /// - /// - public RangeCalendarBlackoutDatesCollection BlackoutDates { get; } - - internal DateTime DisplayDateRangeStart => DisplayDateStart.GetValueOrDefault(DateTime.MinValue); - - internal DateTime DisplayDateRangeEnd => DisplayDateEnd.GetValueOrDefault(DateTime.MaxValue); - - internal DateTime? HoverDateTime { get; set; } - internal bool HasFocusInternal { get; set; } - - /// - /// FirstDayOfWeekProperty property changed handler. - /// - /// The DependencyPropertyChangedEventArgs. - private void OnFirstDayOfWeekChanged(AvaloniaPropertyChangedEventArgs e) - { - if (IsValidFirstDayOfWeek(e.NewValue!)) - { - UpdateMonths(); - } - else - { - throw new ArgumentOutOfRangeException(nameof(e), "Invalid DayOfWeek"); - } - } - - /// - /// Inherited code: Requires comment. - /// - /// Inherited code: Requires comment 1. - /// Inherited code: Requires comment 2. - private static bool IsValidFirstDayOfWeek(object value) - { - var day = (DayOfWeek)value; - - return day == DayOfWeek.Sunday - || day == DayOfWeek.Monday - || day == DayOfWeek.Tuesday - || day == DayOfWeek.Wednesday - || day == DayOfWeek.Thursday - || day == DayOfWeek.Friday - || day == DayOfWeek.Saturday; - } - - /// - /// IsTodayHighlightedProperty property changed handler. - /// - /// The DependencyPropertyChangedEventArgs. - private void OnIsTodayHighlightedChanged(AvaloniaPropertyChangedEventArgs e) - { - var i = DateTimeHelper.CompareYearMonth(DisplayDateInternal, DateTime.Today); - - if (i > -2 && i < 2) - { - UpdateMonths(); - } - } - - /// - /// DisplayModeProperty property changed handler. - /// - /// The DependencyPropertyChangedEventArgs. - private void OnDisplayModePropertyChanged(AvaloniaPropertyChangedEventArgs e) - { - var mode = (CalendarMode)e.NewValue!; - var oldMode = (CalendarMode)e.OldValue!; - var monthControl = MonthControl; - - if (monthControl != null) - { - switch (oldMode) - { - case CalendarMode.Month: - { - SelectedYear = DisplayDateInternal; - SelectedMonth = DisplayDateInternal; - break; - } - case CalendarMode.Year: - { - SetCurrentValue(DisplayDateProperty, SelectedMonth); - SelectedYear = SelectedMonth; - break; - } - case CalendarMode.Decade: - { - SetCurrentValue(DisplayDateProperty, SelectedYear); - SelectedMonth = SelectedYear; - break; - } - } - - switch (mode) - { - case CalendarMode.Month: - { - OnMonthClick(); - break; - } - case CalendarMode.Year: - case CalendarMode.Decade: - { - OnHeaderClick(); - break; - } - } - } - - OnDisplayModeChanged(new CalendarModeChangedEventArgs((CalendarMode)e.OldValue, mode)); - } - - private static bool IsValidDisplayMode(CalendarMode mode) - { - return mode == CalendarMode.Month - || mode == CalendarMode.Year - || mode == CalendarMode.Decade; - } - - private void OnDisplayModeChanged(CalendarModeChangedEventArgs args) - { - DisplayModeChanged?.Invoke(this, args); - } - - internal void NotifyRangeDateSelected() - { - if (SelectedRangeStartDate is not null && SelectedRangeEndDate is not null) - { - var rangeStart = SelectedRangeStartDate.Value; - var rangeEnd = SelectedRangeEndDate.Value; - if (DateTimeHelper.CompareDays(SelectedRangeStartDate.Value, SelectedRangeEndDate.Value) > 0 && IsRepairReverseRange) - { - rangeStart = SelectedRangeEndDate.Value; - rangeEnd = SelectedRangeStartDate.Value; - } - RangeDateSelected?.Invoke(this, new RangeDateSelectedEventArgs(new CalendarDateRange(rangeStart, rangeEnd))); - } - } - - internal void NotifyHoverDateChanged(DateTime? hoverDate) - { - HoverDateChanged?.Invoke(this, new HoverDateSelectedEventArgs(hoverDate)); - } - - /// - /// Inherited code: Requires comment. - /// - /// Inherited code: Requires comment 1. - /// Inherited code: Requires comment 2. - private static bool IsValidSelectionMode(object value) - { - var mode = (CalendarSelectionMode)value; - - return mode == CalendarSelectionMode.SingleDate - || mode == CalendarSelectionMode.SingleRange - || mode == CalendarSelectionMode.MultipleRange - || mode == CalendarSelectionMode.None; - } - - private static bool IsSelectionChanged(SelectionChangedEventArgs e) - { - if (e.AddedItems.Count != e.RemovedItems.Count) - { - return true; - } - - foreach (DateTime addedDate in e.AddedItems) - { - if (!e.RemovedItems.Contains(addedDate)) - { - return true; - } - } - - return false; - } - - protected virtual void OnDisplayDateChanged(AvaloniaPropertyChangedEventArgs e) - { - UpdateDisplayDate(this, (DateTime)e.NewValue!, (DateTime)e.OldValue!); - } - - private static void UpdateDisplayDate(RangeCalendar c, DateTime addedDate, DateTime removedDate) - { - _ = c ?? throw new ArgumentNullException(nameof(c)); - - // If DisplayDate < DisplayDateStart, DisplayDate = DisplayDateStart - if (DateTime.Compare(addedDate, c.DisplayDateRangeStart) < 0) - { - c.DisplayDate = c.DisplayDateRangeStart; - return; - } - - // If DisplayDate > DisplayDateEnd, DisplayDate = DisplayDateEnd - if (DateTime.Compare(addedDate, c.DisplayDateRangeEnd) > 0) - { - c.DisplayDate = c.DisplayDateRangeEnd; - return; - } - - c.DisplayDateInternal = DateTimeHelper.DiscardDayTime(addedDate); - c.SecondaryDisplayDateInternal = DateTimeHelper.AddMonths(c.DisplayDateInternal, 1) ?? c.DisplayDateInternal; - - c.UpdateMonths(); - c.OnDisplayDate(new CalendarDateChangedEventArgs(removedDate, addedDate)); - } - - protected void OnDisplayDate(CalendarDateChangedEventArgs e) - { - DisplayDateChanged?.Invoke(this, e); - } - - private void OnDisplayDateStartChanged(AvaloniaPropertyChangedEventArgs e) - { - if (!_displayDateIsChanging) - { - var newValue = e.NewValue as DateTime?; - - if (newValue.HasValue) - { - // DisplayDateStart coerces to the value of the - // SelectedDateMin if SelectedDateMin < DisplayDateStart - - var selectedDateMin = SelectedRangeStartDate; - - if (selectedDateMin.HasValue && DateTime.Compare(selectedDateMin.Value, newValue.Value) < 0) - { - SetCurrentValue(DisplayDateStartProperty, selectedDateMin.Value); - return; - } - - // if DisplayDateStart > DisplayDateEnd, - // DisplayDateEnd = DisplayDateStart - if (DateTime.Compare(newValue.Value, DisplayDateRangeEnd) > 0) - { - SetCurrentValue(DisplayDateEndProperty, DisplayDateStart); - } - - // If DisplayDate < DisplayDateStart, - // DisplayDate = DisplayDateStart - if (DateTimeHelper.CompareYearMonth(newValue.Value, DisplayDateInternal) > 0) - { - SetCurrentValue(DisplayDateProperty, newValue.Value); - } - } - - UpdateMonths(); - } - } - - private void OnDisplayDateEndChanged(AvaloniaPropertyChangedEventArgs e) - { - if (!_displayDateIsChanging) - { - var newValue = e.NewValue as DateTime?; - - if (newValue.HasValue) - { - // DisplayDateEnd coerces to the value of the - // SelectedDateMax if SelectedDateMax > DisplayDateEnd - var selectedDateMax = SelectedRangeEndDate; - - if (selectedDateMax.HasValue && DateTime.Compare(selectedDateMax.Value, newValue.Value) > 0) - { - SetCurrentValue(DisplayDateEndProperty, selectedDateMax.Value); - return; - } - - // if DisplayDateEnd < DisplayDateStart, - // DisplayDateEnd = DisplayDateStart - if (DateTime.Compare(newValue.Value, DisplayDateRangeStart) < 0) - { - SetCurrentValue(DisplayDateEndProperty, DisplayDateStart); - return; - } - - // If DisplayDate > DisplayDateEnd, - // DisplayDate = DisplayDateEnd - if (DateTimeHelper.CompareYearMonth(newValue.Value, DisplayDateInternal) < 0) - { - SetCurrentValue(DisplayDateProperty, newValue.Value); - } - } - - UpdateMonths(); - } - } - - internal RangeCalendarDayButton? FindDayButtonFromDay(DateTime day) - { - var monthControl = MonthControl; - - // REMOVE_RTM: should be updated if we support MultiCalendar - var count = RowsPerMonth * ColumnsPerMonth; - if (monthControl != null) - { - if (monthControl.PrimaryMonthView != null) - { - for (var childIndex = ColumnsPerMonth; childIndex < count; childIndex++) - { - if (monthControl.PrimaryMonthView.Children[childIndex] is RangeCalendarDayButton b) - { - var d = b.DataContext as DateTime?; - - if (d.HasValue) - { - if (DateTimeHelper.CompareDays(d.Value, day) == 0) - { - return b; - } - } - } - } - } - - if (monthControl.SecondaryMonthView != null) - { - for (var childIndex = ColumnsPerMonth; childIndex < count; childIndex++) - { - if (monthControl.SecondaryMonthView.Children[childIndex] is RangeCalendarDayButton b) - { - var d = b.DataContext as DateTime?; - - if (d.HasValue) - { - if (DateTimeHelper.CompareDays(d.Value, day) == 0) - { - return b; - } - } - } - } - } - } - - return null; - } - - private void OnSelectedMonthChanged(DateTime? selectedMonth) - { - if (selectedMonth.HasValue) - { - Debug.Assert(DisplayMode == CalendarMode.Year, "DisplayMode should be Year!"); - SelectedMonth = selectedMonth.Value; - UpdateMonths(); - } - } - - private void OnSelectedYearChanged(DateTime? selectedYear) - { - if (selectedYear.HasValue) - { - Debug.Assert(DisplayMode == CalendarMode.Decade, "DisplayMode should be Decade!"); - SelectedYear = selectedYear.Value; - UpdateMonths(); - } - } - - internal void OnHeaderClick() - { - Debug.Assert(DisplayMode == CalendarMode.Year || DisplayMode == CalendarMode.Decade, - "The DisplayMode should be Year or Decade"); - var monthControl = MonthControl; - if (monthControl != null && monthControl.MonthView != null && monthControl.YearView != null) - { - monthControl.MonthView.IsVisible = false; - monthControl.YearView.IsVisible = true; - UpdateMonths(); - } - } - - internal void ResetStates() - { - var monthControl = MonthControl; - var count = RowsPerMonth * ColumnsPerMonth; - if (monthControl != null) - { - if (monthControl.PrimaryMonthView != null) - { - for (var childIndex = ColumnsPerMonth; childIndex < count; childIndex++) - { - var d = (RangeCalendarDayButton)monthControl.PrimaryMonthView.Children[childIndex]; - d.IgnoreMouseOverState(); - } - } - - if (monthControl.SecondaryMonthView != null) - { - for (var childIndex = ColumnsPerMonth; childIndex < count; childIndex++) - { - var d = (RangeCalendarDayButton)monthControl.SecondaryMonthView.Children[childIndex]; - d.IgnoreMouseOverState(); - } - } - } - } - - protected internal virtual void UpdateMonths() - { - var monthControl = MonthControl; - if (monthControl != null) - { - UpdateCalendarMonths(monthControl); - } - } - - internal void UpdateCalendarMonths(RangeCalendarItem calendarItem) - { - switch (DisplayMode) - { - case CalendarMode.Month: - { - calendarItem.UpdateMonthMode(); - break; - } - case CalendarMode.Year: - { - calendarItem.UpdateYearMode(); - break; - } - case CalendarMode.Decade: - { - calendarItem.UpdateDecadeMode(); - break; - } - } - } - - internal static bool IsValidDateSelection(RangeCalendar cal, DateTime? value) - { - if (!value.HasValue) - { - return true; - } - - if (cal.BlackoutDates.Contains(value.Value)) - { - return false; - } - - cal._displayDateIsChanging = true; - if (DateTime.Compare(value.Value, cal.DisplayDateRangeStart) < 0) - { - cal.DisplayDateStart = value; - } - else if (DateTime.Compare(value.Value, cal.DisplayDateRangeEnd) > 0) - { - cal.DisplayDateEnd = value; - } - - cal._displayDateIsChanging = false; - - return true; - } - - private static bool IsValidKeyboardSelection(RangeCalendar cal, DateTime? value) - { - if (!value.HasValue) - { - return true; - } - - if (cal.BlackoutDates.Contains(value.Value)) - { - return false; - } - - return DateTime.Compare(value.Value, cal.DisplayDateRangeStart) >= 0 && - DateTime.Compare(value.Value, cal.DisplayDateRangeEnd) <= 0; - } - - /// - /// This method highlights the days in MultiSelection mode without - /// adding them to the SelectedDates collection. - /// - internal void UpdateHighlightDays() + internal override void UpdateHighlightDays() { DateTime? rangeStart = default; DateTime? rangeEnd = default; SortHoverIndexes(out rangeStart, out rangeEnd); - Debug.Assert(MonthControl is not null); - var monthControl = MonthControl; - // This assumes a contiguous set of dates: - if (monthControl.PrimaryMonthView is not null) - { - UpdateHighlightDays(monthControl.PrimaryMonthView, rangeStart, rangeEnd); - } - - if (monthControl.SecondaryMonthView is not null) - { - UpdateHighlightDays(monthControl.SecondaryMonthView, rangeStart, rangeEnd); + Debug.Assert(CalendarItem is not null); + if (CalendarItem.MonthView is not null) + { + UpdateHighlightDays(CalendarItem.MonthView, rangeStart, rangeEnd); } } - private void UpdateHighlightDays(Grid targetMonthView, DateTime? rangeStart, DateTime? rangeEnd) + protected void UpdateHighlightDays(Grid targetMonthView, DateTime? rangeStart, DateTime? rangeEnd) { var count = targetMonthView.Children.Count; for (var i = 0; i < count; i++) { - if (targetMonthView.Children[i] is RangeCalendarDayButton b) + if (targetMonthView.Children[i] is CalendarDayButton b) { var d = b.DataContext as DateTime?; if (d.HasValue) @@ -872,13 +93,13 @@ public class RangeCalendar : TemplatedControl if (rangeStart is not null && rangeEnd is not null) { b.IsSelected = DateTimeHelper.InRange(d.Value, rangeStart.Value, rangeEnd.Value); - } else if (SelectedRangeStartDate is not null) + } else if (SelectedDate is not null) { - b.IsSelected = DateTimeHelper.CompareDays(SelectedRangeStartDate.Value, d.Value) == 0; + b.IsSelected = DateTimeHelper.CompareDays(SelectedDate.Value, d.Value) == 0; } - else if (SelectedRangeEndDate is not null) + else if (SecondarySelectedDate is not null) { - b.IsSelected = DateTimeHelper.CompareDays(SelectedRangeEndDate.Value, d.Value) == 0; + b.IsSelected = DateTimeHelper.CompareDays(SecondarySelectedDate.Value, d.Value) == 0; } else { @@ -903,258 +124,38 @@ public class RangeCalendar : TemplatedControl } } } - - // 无条件取消所有的所有的高亮 - internal void UnHighlightDays() - { - Debug.Assert(MonthControl is not null); - var monthControl = MonthControl; - // This assumes a contiguous set of dates: - if (monthControl.PrimaryMonthView is not null) - { - UnHighlightDays(monthControl.PrimaryMonthView); - } - - if (monthControl.SecondaryMonthView is not null) - { - UnHighlightDays(monthControl.SecondaryMonthView); - } - } - - private void UnHighlightDays(Grid targetMonthView) - { - var count = targetMonthView.Children.Count; - for (var i = 0; i < count; i++) - { - if (targetMonthView.Children[i] is RangeCalendarDayButton b) - { - var d = b.DataContext as DateTime?; - if (d.HasValue) - { - if ((SelectedRangeStartDate.HasValue && - DateTimeHelper.CompareDays(d.Value, SelectedRangeStartDate.Value) == 0) || - (SelectedRangeEndDate.HasValue && - DateTimeHelper.CompareDays(d.Value, SelectedRangeEndDate.Value) == 0)) - { - b.IsSelected = true; - } - else - { - b.IsSelected = false; - } - } - } - } - } - + internal void SortHoverIndexes(out DateTime? rangeStart, out DateTime? rangeEnd) { - if (FixedRangeStart) + if (IsSelectRangeStart) { - rangeStart = HoverDateTime ?? SelectedRangeStartDate; - rangeEnd = SelectedRangeEndDate; - if (rangeStart is not null && rangeEnd is not null) - { - if (DateTimeHelper.CompareDays(rangeEnd.Value, rangeStart.Value) < 0) - { - var temp = rangeStart.Value; - rangeStart = rangeEnd; - rangeEnd = temp; - } - } + rangeStart = HoverDateTime ?? SelectedDate; + rangeEnd = SecondarySelectedDate; } else { - rangeStart = SelectedRangeStartDate; - rangeEnd = HoverDateTime ?? SelectedRangeEndDate; - if (rangeStart is not null && rangeEnd is not null) + rangeStart = SelectedDate; + rangeEnd = HoverDateTime ?? SecondarySelectedDate; + } + if (rangeStart is not null && rangeEnd is not null) + { + if (DateTimeHelper.CompareDateTime(rangeEnd.Value, rangeStart.Value) < 0) { - if (DateTimeHelper.CompareDays(rangeEnd.Value, rangeStart.Value) < 0) - { - var temp = rangeStart.Value; - rangeStart = rangeEnd; - rangeEnd = temp; - } + var temp = rangeStart.Value; + rangeStart = rangeEnd; + rangeEnd = temp; } } } - - internal void OnPreviousMonthClick() - { - if (DisplayMode == CalendarMode.Month) - { - var d = DateTimeHelper.AddMonths(DateTimeHelper.DiscardDayTime(DisplayDate), -1); - if (d.HasValue) - { - if (!LastSelectedDate.HasValue || DateTimeHelper.CompareYearMonth(LastSelectedDate.Value, d.Value) != 0) - { - LastSelectedDate = d.Value; - } - - SetCurrentValue(DisplayDateProperty, d.Value); - } - } - } - - internal void OnPreviousClick() - { - if (DisplayMode == CalendarMode.Month) - { - var d = DateTimeHelper.AddYears(DateTimeHelper.DiscardDayTime(DisplayDate), -1); - if (d.HasValue) - { - if (!LastSelectedDate.HasValue || DateTimeHelper.CompareYearMonth(LastSelectedDate.Value, d.Value) != 0) - { - LastSelectedDate = d.Value; - } - - SetCurrentValue(DisplayDateProperty, d.Value); - } - } - else if (DisplayMode == CalendarMode.Year) - { - var d = DateTimeHelper.AddYears(new DateTime(SelectedMonth.Year, 1, 1), -1); - - if (d.HasValue) - { - SelectedMonth = d.Value; - } - else - { - SelectedMonth = DateTimeHelper.DiscardDayTime(DisplayDateRangeStart); - } - } - else if (DisplayMode == CalendarMode.Decade) - { - Debug.Assert(DisplayMode == CalendarMode.Decade, "DisplayMode should be Decade!"); - - var d = DateTimeHelper.AddYears(new DateTime(SelectedYear.Year, 1, 1), -10); - - if (d.HasValue) - { - var decade = Math.Max(1, DateTimeHelper.DecadeOfDate(d.Value)); - SelectedYear = new DateTime(decade, 1, 1); - } - else - { - SelectedYear = DateTimeHelper.DiscardDayTime(DisplayDateRangeStart); - } - } - - UpdateMonths(); - } - - internal void OnNextMonthClick() - { - if (DisplayMode == CalendarMode.Month) - { - var d = DateTimeHelper.AddMonths(DateTimeHelper.DiscardDayTime(DisplayDate), 1); - if (d.HasValue) - { - if (!LastSelectedDate.HasValue || DateTimeHelper.CompareYearMonth(LastSelectedDate.Value, d.Value) != 0) - { - LastSelectedDate = d.Value; - } - - SetCurrentValue(DisplayDateProperty, d.Value); - } - } - } - - internal void OnNextClick() - { - if (DisplayMode == CalendarMode.Month) - { - var d = DateTimeHelper.AddYears(DateTimeHelper.DiscardDayTime(DisplayDate), 1); - if (d.HasValue) - { - if (!LastSelectedDate.HasValue || DateTimeHelper.CompareYearMonth(LastSelectedDate.Value, d.Value) != 0) - { - LastSelectedDate = d.Value; - } - - SetCurrentValue(DisplayDateProperty, d.Value); - } - } - else if (DisplayMode == CalendarMode.Year) - { - var d = DateTimeHelper.AddYears(new DateTime(SelectedMonth.Year, 1, 1), 1); - - if (d.HasValue) - { - SelectedMonth = d.Value; - } - else - { - SelectedMonth = DateTimeHelper.DiscardDayTime(DisplayDateRangeEnd); - } - } - else if (DisplayMode == CalendarMode.Decade) - { - Debug.Assert(DisplayMode == CalendarMode.Decade, "DisplayMode should be Decade"); - - var d = DateTimeHelper.AddYears(new DateTime(SelectedYear.Year, 1, 1), 10); - - if (d.HasValue) - { - var decade = Math.Max(1, DateTimeHelper.DecadeOfDate(d.Value)); - SelectedYear = new DateTime(decade, 1, 1); - } - else - { - SelectedYear = DateTimeHelper.DiscardDayTime(DisplayDateRangeEnd); - } - } - - UpdateMonths(); - } - - /// - /// If the day is a trailing day, Update the DisplayDate. - /// - /// Inherited code: Requires comment. - internal void OnDayClick(DateTime selectedDate) - { - Debug.Assert(DisplayMode == CalendarMode.Month, "DisplayMode should be Month!"); - var i = DateTimeHelper.CompareYearMonth(selectedDate, DisplayDateInternal); - - if (i > 1) - { - OnNextMonthClick(); - } - else if (i < 0) - { - OnPreviousMonthClick(); - } - } - - private void OnMonthClick() - { - Debug.Assert(MonthControl is not null); - - var monthControl = MonthControl; - if (monthControl != null && monthControl.YearView != null && monthControl.MonthView != null) - { - monthControl.YearView.IsVisible = false; - monthControl.MonthView.IsVisible = true; - - if (!LastSelectedDate.HasValue || DateTimeHelper.CompareYearMonth(LastSelectedDate.Value, DisplayDate) != 0) - { - LastSelectedDate = DisplayDate; - } - - UpdateMonths(); - } - } - + public override string ToString() { - if (SelectedRangeStartDate != null || SelectedRangeEndDate != null) + if (SelectedDate != null || SecondarySelectedDate != null) { var builder = new StringBuilder(); - if (SelectedRangeStartDate != null) + if (SelectedDate != null) { - builder.Append(SelectedRangeStartDate.Value.ToString(DateTimeHelper.GetCurrentDateFormat())); + builder.Append(SelectedDate.Value.ToString(DateTimeHelper.GetCurrentDateFormat())); } else { @@ -1162,9 +163,9 @@ public class RangeCalendar : TemplatedControl } builder.Append(" - "); - if (SelectedRangeEndDate != null) + if (SecondarySelectedDate != null) { - builder.Append(SelectedRangeEndDate.Value.ToString(DateTimeHelper.GetCurrentDateFormat())); + builder.Append(SecondarySelectedDate.Value.ToString(DateTimeHelper.GetCurrentDateFormat())); } else { @@ -1176,540 +177,27 @@ public class RangeCalendar : TemplatedControl return string.Empty; } - - /// - /// Occurs when the - /// - /// property is changed. - /// - /// - /// This event occurs after DisplayDate is assigned its new value. - /// - public event EventHandler? DisplayDateChanged; - - /// - /// Occurs when the - /// - /// property is changed. - /// - public event EventHandler? DisplayModeChanged; - - /// - /// Inherited code: Requires comment. - /// - internal event EventHandler? DayButtonMouseUp; - /// - /// 当范围选择完成的时候派发这个事件 - /// - public event EventHandler? RangeDateSelected; - - /// - /// 当前 Pointer 选中的日期事件 - /// - public event EventHandler? HoverDateChanged; - - protected override void OnPointerReleased(PointerReleasedEventArgs e) + internal void NotifyRangeDateSelected() { - base.OnPointerReleased(e); - if (!HasFocusInternal && e.InitialPressMouseButton == MouseButton.Left) + if (SelectedDate is not null && SecondarySelectedDate is not null) { - Focus(); + var rangeStart = SelectedDate.Value; + var rangeEnd = SecondarySelectedDate.Value; + bool isFixedRange = false; + if (DateTimeHelper.CompareDays(SelectedDate.Value, SecondarySelectedDate.Value) > 0 && IsRepairReverseRange) + { + rangeStart = SecondarySelectedDate.Value; + rangeEnd = SelectedDate.Value; + isFixedRange = true; + } + RangeDateSelected?.Invoke(this, new RangeDateSelectedEventArgs(new CalendarDateRange(rangeStart, rangeEnd), isFixedRange)); } } - internal void OnDayButtonMouseUp(PointerReleasedEventArgs e) + internal override void NotifyHoverDateChanged(DateTime? hoverDate) { - DayButtonMouseUp?.Invoke(this, e); - } - - /// - /// Default mouse wheel handler for the calendar control. - /// - /// Mouse wheel event args. - protected override void OnPointerWheelChanged(PointerWheelEventArgs e) - { - base.OnPointerWheelChanged(e); - if (!e.Handled) - { - CalendarExtensions.GetMetaKeyState(e.KeyModifiers, out var ctrl, out var shift); - - if (!ctrl) - { - if (e.Delta.Y > 0) - { - ProcessPageUpKey(false); - } - else - { - ProcessPageDownKey(false); - } - } - else - { - if (e.Delta.Y > 0) - { - ProcessDownKey(ctrl, shift); - } - else - { - ProcessUpKey(ctrl, shift); - } - } - - e.Handled = true; - } - } - - internal void HandleCalendarKeyDown(KeyEventArgs e) - { - if (!e.Handled && IsEnabled) - { - e.Handled = ProcessCalendarKey(e); - } - } - - internal bool ProcessCalendarKey(KeyEventArgs e) - { - if (DisplayMode == CalendarMode.Month) - { - if (LastSelectedDate.HasValue) - { - // If a blackout day is inactive, when clicked on it, the - // previous inactive day which is not a blackout day can get - // the focus. In this case we should allow keyboard - // functions on that inactive day - if (DateTimeHelper.CompareYearMonth(LastSelectedDate.Value, DisplayDateInternal) != 0 && - FocusButton != null && !FocusButton.IsInactive) - { - return true; - } - } - } - - // Some keys (e.g. Left/Right) need to be translated in RightToLeft mode - var invariantKey = e.Key; //InteractionHelper.GetLogicalKey(FlowDirection, e.Key); - - CalendarExtensions.GetMetaKeyState(e.KeyModifiers, out var ctrl, out var shift); - - switch (invariantKey) - { - case Key.Up: - { - ProcessUpKey(ctrl, shift); - return true; - } - case Key.Down: - { - ProcessDownKey(ctrl, shift); - return true; - } - case Key.Left: - { - ProcessLeftKey(shift); - return true; - } - case Key.Right: - { - ProcessRightKey(shift); - return true; - } - case Key.PageDown: - { - ProcessPageDownKey(shift); - return true; - } - case Key.PageUp: - { - ProcessPageUpKey(shift); - return true; - } - case Key.Home: - { - ProcessHomeKey(shift); - return true; - } - case Key.End: - { - ProcessEndKey(shift); - return true; - } - case Key.Enter: - case Key.Space: - { - return ProcessEnterKey(); - } - } - - return false; - } - - internal void ProcessUpKey(bool ctrl, bool shift) - { - switch (DisplayMode) - { - case CalendarMode.Month: - { - if (ctrl) - { - SelectedMonth = DisplayDateInternal; - SetCurrentValue(DisplayModeProperty, CalendarMode.Year); - } - break; - } - case CalendarMode.Year: - { - if (ctrl) - { - SelectedYear = SelectedMonth; - SetCurrentValue(DisplayModeProperty, CalendarMode.Decade); - } - else - { - var selectedMonth = DateTimeHelper.AddMonths(_selectedMonth, -ColumnsPerYear); - OnSelectedMonthChanged(selectedMonth); - } - - break; - } - case CalendarMode.Decade: - { - if (!ctrl) - { - var selectedYear = DateTimeHelper.AddYears(SelectedYear, -ColumnsPerYear); - OnSelectedYearChanged(selectedYear); - } - - break; - } - } - } - - internal void ProcessDownKey(bool ctrl, bool shift) - { - switch (DisplayMode) - { - case CalendarMode.Month: - { - break; - } - case CalendarMode.Year: - { - if (ctrl) - { - SetCurrentValue(DisplayDateProperty, SelectedMonth); - SetCurrentValue(DisplayModeProperty, CalendarMode.Month); - } - else - { - var selectedMonth = DateTimeHelper.AddMonths(_selectedMonth, ColumnsPerYear); - OnSelectedMonthChanged(selectedMonth); - } - - break; - } - case CalendarMode.Decade: - { - if (ctrl) - { - SelectedMonth = SelectedYear; - SetCurrentValue(DisplayModeProperty, CalendarMode.Year); - } - else - { - var selectedYear = DateTimeHelper.AddYears(SelectedYear, ColumnsPerYear); - OnSelectedYearChanged(selectedYear); - } - - break; - } - } - } - - internal void ProcessLeftKey(bool shift) - { - switch (DisplayMode) - { - case CalendarMode.Month: - { - break; - } - case CalendarMode.Year: - { - var selectedMonth = DateTimeHelper.AddMonths(_selectedMonth, -1); - OnSelectedMonthChanged(selectedMonth); - break; - } - case CalendarMode.Decade: - { - var selectedYear = DateTimeHelper.AddYears(SelectedYear, -1); - OnSelectedYearChanged(selectedYear); - break; - } - } - } - - internal void ProcessRightKey(bool shift) - { - switch (DisplayMode) - { - case CalendarMode.Month: - { - break; - } - case CalendarMode.Year: - { - var selectedMonth = DateTimeHelper.AddMonths(_selectedMonth, 1); - OnSelectedMonthChanged(selectedMonth); - break; - } - case CalendarMode.Decade: - { - var selectedYear = DateTimeHelper.AddYears(SelectedYear, 1); - OnSelectedYearChanged(selectedYear); - break; - } - } - } - - private bool ProcessEnterKey() - { - switch (DisplayMode) - { - case CalendarMode.Year: - { - SetCurrentValue(DisplayDateProperty, SelectedMonth); - SetCurrentValue(DisplayModeProperty, CalendarMode.Month); - return true; - } - case CalendarMode.Decade: - { - SelectedMonth = SelectedYear; - SetCurrentValue(DisplayModeProperty, CalendarMode.Year); - return true; - } - } - - return false; - } - - internal void ProcessHomeKey(bool shift) - { - switch (DisplayMode) - { - case CalendarMode.Month: - { - break; - } - case CalendarMode.Year: - { - var selectedMonth = new DateTime(_selectedMonth.Year, 1, 1); - OnSelectedMonthChanged(selectedMonth); - break; - } - case CalendarMode.Decade: - { - DateTime? selectedYear = new DateTime(DateTimeHelper.DecadeOfDate(SelectedYear), 1, 1); - OnSelectedYearChanged(selectedYear); - break; - } - } - } - - internal void ProcessEndKey(bool shift) - { - switch (DisplayMode) - { - case CalendarMode.Month: - { - break; - } - case CalendarMode.Year: - { - var selectedMonth = new DateTime(_selectedMonth.Year, 12, 1); - OnSelectedMonthChanged(selectedMonth); - break; - } - case CalendarMode.Decade: - { - DateTime? selectedYear = new DateTime(DateTimeHelper.EndOfDecade(SelectedYear), 1, 1); - OnSelectedYearChanged(selectedYear); - break; - } - } - } - - internal void ProcessPageDownKey(bool shift) - { - if (!shift) - { - OnNextClick(); - return; - } - - switch (DisplayMode) - { - case CalendarMode.Month: - { - break; - } - case CalendarMode.Year: - { - var selectedMonth = DateTimeHelper.AddYears(_selectedMonth, 1); - OnSelectedMonthChanged(selectedMonth); - break; - } - case CalendarMode.Decade: - { - var selectedYear = DateTimeHelper.AddYears(SelectedYear, 10); - OnSelectedYearChanged(selectedYear); - break; - } - } - } - - internal void ProcessPageUpKey(bool shift) - { - if (!shift) - { - OnPreviousClick(); - return; - } - - switch (DisplayMode) - { - case CalendarMode.Month: - { - break; - } - case CalendarMode.Year: - { - var selectedMonth = DateTimeHelper.AddYears(_selectedMonth, -1); - OnSelectedMonthChanged(selectedMonth); - break; - } - case CalendarMode.Decade: - { - var selectedYear = DateTimeHelper.AddYears(SelectedYear, -10); - OnSelectedYearChanged(selectedYear); - break; - } - } - } - - protected override void OnGotFocus(GotFocusEventArgs e) - { - base.OnGotFocus(e); - HasFocusInternal = true; - - switch (DisplayMode) - { - case CalendarMode.Month: - { - DateTime focusDate; - if (LastSelectedDate.HasValue && - DateTimeHelper.CompareYearMonth(DisplayDateInternal, LastSelectedDate.Value) == 0) - { - focusDate = LastSelectedDate.Value; - } - else - { - focusDate = DisplayDate; - LastSelectedDate = DisplayDate; - } - - FocusButton = FindDayButtonFromDay(focusDate); - - if (FocusButton != null) - { - FocusButton.IsCurrent = true; - } - - break; - } - case CalendarMode.Year: - case CalendarMode.Decade: - { - if (FocusCalendarButton != null) - { - FocusCalendarButton.IsCalendarButtonFocused = true; - } - - break; - } - } - } - - protected override void OnLostFocus(RoutedEventArgs e) - { - base.OnLostFocus(e); - HasFocusInternal = false; - - switch (DisplayMode) - { - case CalendarMode.Month: - { - if (FocusButton != null) - { - FocusButton.IsCurrent = false; - } - - break; - } - case CalendarMode.Year: - case CalendarMode.Decade: - { - if (FocusCalendarButton != null) - { - FocusCalendarButton.IsCalendarButtonFocused = false; - } - - break; - } - } - } - - /// - /// Called when the IsEnabled property changes. - /// - /// Property changed args. - private void OnIsEnabledChanged(AvaloniaPropertyChangedEventArgs e) - { - Debug.Assert(e.NewValue is bool, "NewValue should be a boolean!"); - var isEnabled = (bool)e.NewValue; - - MonthControl?.UpdateDisabled(isEnabled); - } - - /// - /// Builds the visual tree for the - /// when a new - /// template is applied. - /// - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) - { - Root = e.NameScope.Find(RangeCalendarTheme.RootPart); - - SelectedMonth = DisplayDate; - SelectedYear = DisplayDate; - - if (Root != null) - { - var month = e.NameScope.Find(RangeCalendarTheme.CalendarItemPart); - - if (month != null) - { - month.Owner = this; - } - } - } - - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - TokenResourceBinder.CreateGlobalTokenBinding(this, BorderThicknessProperty, - GlobalTokenResourceKey.BorderThickness, - BindingPriority.Template, - new RenderScaleAwareThicknessConfigure(this)); + base.NotifyHoverDateChanged(hoverDate); + HoverDateTime = hoverDate; } } \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarBlackoutDatesCollection.cs b/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarBlackoutDatesCollection.cs deleted file mode 100644 index 42c0187..0000000 --- a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarBlackoutDatesCollection.cs +++ /dev/null @@ -1,208 +0,0 @@ -using System.Collections.ObjectModel; -using Avalonia.Threading; - -namespace AtomUI.Controls.CalendarView; - -public sealed class RangeCalendarBlackoutDatesCollection : ObservableCollection -{ - /// - /// The Calendar whose dates this object represents. - /// - private readonly RangeCalendar _owner; - - /// - /// Initializes a new instance of the - /// - /// class. - /// - /// - /// The whose dates - /// this object represents. - /// - public RangeCalendarBlackoutDatesCollection(RangeCalendar owner) - { - _owner = owner ?? throw new ArgumentNullException(nameof(owner)); - } - - /// - /// Adds all dates before to the - /// collection. - /// - public void AddDatesInPast() - { - Add(new CalendarDateRange(DateTime.MinValue, DateTime.Today.AddDays(-1))); - } - - /// - /// Returns a value that represents whether this collection contains the - /// specified date. - /// - /// The date to search for. - /// - /// True if the collection contains the specified date; otherwise, - /// false. - /// - public bool Contains(DateTime date) - { - var count = Count; - for (var i = 0; i < count; i++) - { - if (DateTimeHelper.InRange(date, this[i])) - { - return true; - } - } - - return false; - } - - /// - /// Returns a value that represents whether this collection contains the - /// specified range of dates. - /// - /// The start of the date range. - /// The end of the date range. - /// - /// True if all dates in the range are contained in the collection; - /// otherwise, false. - /// - public bool Contains(DateTime start, DateTime end) - { - DateTime rangeStart; - DateTime rangeEnd; - - if (DateTime.Compare(end, start) > -1) - { - rangeStart = DateTimeHelper.DiscardTime(start); - rangeEnd = DateTimeHelper.DiscardTime(end); - } - else - { - rangeStart = DateTimeHelper.DiscardTime(end); - rangeEnd = DateTimeHelper.DiscardTime(start); - } - - var count = Count; - for (var i = 0; i < count; i++) - { - var range = this[i]; - if (DateTime.Compare(range.Start, rangeStart) == 0 && DateTime.Compare(range.End, rangeEnd) == 0) - { - return true; - } - } - - return false; - } - - /// - /// Returns a value that represents whether this collection contains any - /// date in the specified range. - /// - /// The range of dates to search for. - /// - /// True if any date in the range is contained in the collection; - /// otherwise, false. - /// - public bool ContainsAny(CalendarDateRange range) - { - return this.Any(r => r.ContainsAny(range)); - } - - /// - /// Removes all items from the collection. - /// - /// - /// This implementation raises the CollectionChanged event. - /// - protected override void ClearItems() - { - EnsureValidThread(); - - base.ClearItems(); - _owner.UpdateMonths(); - } - - /// - /// Inserts an item into the collection at the specified index. - /// - /// - /// The zero-based index at which item should be inserted. - /// - /// The object to insert. - /// - /// This implementation raises the CollectionChanged event. - /// - protected override void InsertItem(int index, CalendarDateRange item) - { - EnsureValidThread(); - - if (!IsValid(item)) - { - throw new ArgumentOutOfRangeException(nameof(item), "Value is not valid."); - } - - base.InsertItem(index, item); - _owner.UpdateMonths(); - } - - /// - /// Removes the item at the specified index of the collection. - /// - /// - /// The zero-based index of the element to remove. - /// - /// - /// This implementation raises the CollectionChanged event. - /// - protected override void RemoveItem(int index) - { - EnsureValidThread(); - - base.RemoveItem(index); - _owner.UpdateMonths(); - } - - /// - /// Replaces the element at the specified index. - /// - /// - /// The zero-based index of the element to replace. - /// - /// - /// The new value for the element at the specified index. - /// - /// - /// This implementation raises the CollectionChanged event. - /// - protected override void SetItem(int index, CalendarDateRange item) - { - EnsureValidThread(); - - if (!IsValid(item)) - { - throw new ArgumentOutOfRangeException(nameof(item), "Value is not valid."); - } - - base.SetItem(index, item); - _owner.UpdateMonths(); - } - - private bool IsValid(CalendarDateRange item) - { - if ((_owner.SelectedRangeStartDate is not null && - DateTimeHelper.InRange(_owner.SelectedRangeStartDate.Value, item)) || - (_owner.SelectedRangeEndDate is not null && - DateTimeHelper.InRange(_owner.SelectedRangeEndDate.Value, item))) - { - return false; - } - - return true; - } - - private static void EnsureValidThread() - { - Dispatcher.UIThread.VerifyAccess(); - } -} \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarButton.cs b/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarButton.cs deleted file mode 100644 index beb8bbe..0000000 --- a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarButton.cs +++ /dev/null @@ -1,11 +0,0 @@ -namespace AtomUI.Controls.CalendarView; - -internal sealed class RangeCalendarButton : BaseCalendarButton -{ - protected override Type StyleKeyOverride => typeof(BaseCalendarButton); - - /// - /// Gets or sets the Calendar associated with this button. - /// - internal RangeCalendar? Owner { get; set; } -} \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarDayButton.cs b/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarDayButton.cs deleted file mode 100644 index 551828a..0000000 --- a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarDayButton.cs +++ /dev/null @@ -1,16 +0,0 @@ -namespace AtomUI.Controls.CalendarView; - -internal sealed class RangeCalendarDayButton : BaseCalendarDayButton -{ - protected override Type StyleKeyOverride => typeof(BaseCalendarDayButton); - - /// - /// Gets or sets the Calendar associated with this button. - /// - internal RangeCalendar? Owner { get; set; } - - /// - /// 是否在主要的 Month View 里面 - /// - internal bool IsInPrimaryMonView { get; set; } -} \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarItem.cs b/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarItem.cs index c6b500d..aaa3792 100644 --- a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarItem.cs +++ b/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarItem.cs @@ -1,1370 +1,94 @@ -using System.Diagnostics; -using System.Globalization; -using AtomUI.Collections.Pooled; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.Metadata; -using Avalonia.Controls.Primitives; -using Avalonia.Data; -using Avalonia.Input; -using Avalonia.Input.Raw; -using Avalonia.Interactivity; -using Avalonia.Media; +namespace AtomUI.Controls.CalendarView; -namespace AtomUI.Controls.CalendarView; - -[TemplatePart(RangeCalendarItemTheme.PrimaryHeaderButtonPart, typeof(HeadTextButton))] -[TemplatePart(RangeCalendarItemTheme.SecondaryHeaderButtonPart, typeof(HeadTextButton))] -[TemplatePart(RangeCalendarItemTheme.MonthViewPart, typeof(Grid))] -[TemplatePart(RangeCalendarItemTheme.PrimaryPreviousButtonPart, typeof(IconButton))] -[TemplatePart(RangeCalendarItemTheme.PrimaryPreviousMonthButtonPart, typeof(IconButton))] -[TemplatePart(RangeCalendarItemTheme.PrimaryNextButtonPart, typeof(IconButton))] -[TemplatePart(RangeCalendarItemTheme.PrimaryNextMonthButtonPart, typeof(IconButton))] -[TemplatePart(RangeCalendarItemTheme.SecondaryPreviousButtonPart, typeof(IconButton))] -[TemplatePart(RangeCalendarItemTheme.SecondaryPreviousMonthButtonPart, typeof(IconButton))] -[TemplatePart(RangeCalendarItemTheme.SecondaryNextButtonPart, typeof(IconButton))] -[TemplatePart(RangeCalendarItemTheme.SecondaryNextMonthButtonPart, typeof(IconButton))] -[TemplatePart(RangeCalendarItemTheme.YearViewPart, typeof(Grid))] -internal class RangeCalendarItem : TemplatedControl +internal class RangeCalendarItem : CalendarItem { - internal const string CalendarDisabledPC = ":calendardisabled"; - internal const int MonthViewSize = 49; // 7 x 7 - - /// - /// The number of days per week. - /// - internal const int NumberOfDaysPerWeek = 7; - - protected readonly System.Globalization.Calendar _calendar = new GregorianCalendar(); - - #region 公共属性定义 - - public static readonly StyledProperty HeaderBackgroundProperty = - RangeCalendar.HeaderBackgroundProperty.AddOwner(); - - public IBrush? HeaderBackground + protected override Type StyleKeyOverride => typeof(CalendarItem); + + protected override void CheckButtonSelectedState(CalendarDayButton childButton, DateTime dateToAdd) { - get => GetValue(HeaderBackgroundProperty); - set => SetValue(HeaderBackgroundProperty, value); - } - - public static readonly StyledProperty?> DayTitleTemplateProperty = - AvaloniaProperty.Register?>( - nameof(DayTitleTemplate), - defaultBindingMode: BindingMode.OneTime); - - public ITemplate? DayTitleTemplate - { - get => GetValue(DayTitleTemplateProperty); - set => SetValue(DayTitleTemplateProperty, value); - } - - #endregion - - #region 内部属性定义 - - internal static readonly DirectProperty IsMonthViewModeProperty = - AvaloniaProperty.RegisterDirect(nameof(IsMonthViewMode), - o => o.IsMonthViewMode, - (o, v) => o.IsMonthViewMode = v); - - private bool _isMonthViewMode = true; - - // 当鼠标移动到日历单元格外面的时候还原 hover 临时的高亮 - private IDisposable? _restoreHoverPositionDisposable; - - internal bool IsMonthViewMode - { - get => _isMonthViewMode; - set => SetAndRaise(IsMonthViewModeProperty, ref _isMonthViewMode, value); - } - - /// - /// Gets the button that allows switching between month mode, year mode, - /// and decade mode. - /// - internal HeadTextButton? PrimaryHeaderButton - { - get => _primaryHeaderButton; - - private set + // SET IF THE DAY IS SELECTED OR NOT + childButton.IsSelected = false; + if (Owner is RangeCalendar owner) { - if (_primaryHeaderButton != null) + DateTime? rangeStart = default; + DateTime? rangeEnd = default; + owner.SortHoverIndexes(out rangeStart, out rangeEnd); + if (rangeStart != null && rangeEnd != null) { - _primaryHeaderButton.Click -= HandleHeaderButtonClick; + childButton.IsSelected = DateTimeHelper.InRange(dateToAdd, rangeStart.Value, rangeEnd.Value); } - - _primaryHeaderButton = value; - - if (_primaryHeaderButton != null) + else if (rangeStart is not null) { - _primaryHeaderButton.Click += HandleHeaderButtonClick; - _primaryHeaderButton.Focusable = false; + childButton.IsSelected = DateTimeHelper.CompareDays(rangeStart.Value, dateToAdd) == 0; + } + else if (rangeEnd is not null) + { + childButton.IsSelected = DateTimeHelper.CompareDays(rangeEnd.Value, dateToAdd) == 0; } } } - /// - /// Gets the button that allows switching between month mode, year mode, - /// and decade mode. - /// - internal HeadTextButton? SecondaryHeaderButton + protected override bool CheckDayInactiveState(CalendarDayButton childButton, DateTime dateToAdd) { - get => _secondaryHeaderButton; - - private set + if (childButton.Parent == MonthView) { - if (_secondaryHeaderButton != null) - { - _secondaryHeaderButton.Click -= HandleHeaderButtonClick; - } + return base.CheckDayInactiveState(childButton, dateToAdd); + } + + var isSecondaryDayInactive = false; + if (Owner is RangeCalendar owner) + { + isSecondaryDayInactive = DateTimeHelper.CompareYearMonth(dateToAdd, owner.SecondaryDisplayDateInternal) != 0; + } - _secondaryHeaderButton = value; - - if (_secondaryHeaderButton != null) - { - _secondaryHeaderButton.Click += HandleHeaderButtonClick; - _secondaryHeaderButton.Focusable = false; - } + return isSecondaryDayInactive; + } + + protected override void NotifyCellMouseEntered(CalendarDayButton dayButton, DateTime selectedDate) + { + if (Owner is RangeCalendar owner) + { + owner.NotifyHoverDateChanged(selectedDate); + owner.UpdateHighlightDays(); } } - /// - /// Gets the button that displays the next page of the calendar when it - /// is clicked. - /// - internal IconButton? PrimaryNextButton + protected override void NotifyCellMouseLeftButtonDown(CalendarDayButton dayButton) { - get => _primaryNextButton; - - private set + if (Owner is RangeCalendar owner) { - if (_primaryNextButton != null) + if (dayButton.IsEnabled && !dayButton.IsBlackout && dayButton.DataContext is DateTime selectedDate) { - _primaryNextButton.Click -= HandleNextButtonClick; - } - - _primaryNextButton = value; - - if (_primaryNextButton != null) - { - _primaryNextButton.Click += HandleNextButtonClick; - _primaryNextButton.Focusable = false; - } - } - } - - internal IconButton? PrimaryNextMonthButton - { - get => _primaryNextMonthButton; - - private set - { - if (_primaryNextMonthButton != null) - { - _primaryNextMonthButton.Click -= HandleNextMonthButtonClick; - } - - _primaryNextMonthButton = value; - - if (_primaryNextMonthButton != null) - { - _primaryNextMonthButton.Click += HandleNextMonthButtonClick; - _primaryNextMonthButton.Focusable = false; - } - } - } - - /// - /// Gets the button that displays the previous page of the calendar when - /// it is clicked. - /// - internal IconButton? PrimaryPreviousButton - { - get => _primaryPreviousButton; - - private set - { - if (_primaryPreviousButton != null) - { - _primaryPreviousButton.Click -= HandlePreviousButtonClick; - } - - _primaryPreviousButton = value; - - if (_primaryPreviousButton != null) - { - _primaryPreviousButton.Click += HandlePreviousButtonClick; - _primaryPreviousButton.Focusable = false; - } - } - } - - internal IconButton? PrimaryPreviousMonthButton - { - get => _primaryPreviousMonthButton; - - private set - { - if (_primaryPreviousMonthButton != null) - { - _primaryPreviousMonthButton.Click -= HandlePreviousMonthButtonClick; - } - - _primaryPreviousMonthButton = value; - - if (_primaryPreviousMonthButton != null) - { - _primaryPreviousMonthButton.Click += HandlePreviousMonthButtonClick; - _primaryPreviousMonthButton.Focusable = false; - } - } - } - - /// - /// Gets the button that displays the next page of the calendar when it - /// is clicked. - /// - internal IconButton? SecondaryNextButton - { - get => _secondaryNextButton; - - private set - { - if (_secondaryNextButton != null) - { - _secondaryNextButton.Click -= HandleNextButtonClick; - } - - _secondaryNextButton = value; - - if (_secondaryNextButton != null) - { - _secondaryNextButton.Click += HandleNextButtonClick; - _secondaryNextButton.Focusable = false; - } - } - } - - internal IconButton? SecondaryNextMonthButton - { - get => _secondaryNextMonthButton; - - private set - { - if (_secondaryNextMonthButton != null) - { - _secondaryNextMonthButton.Click -= HandleNextMonthButtonClick; - } - - _secondaryNextMonthButton = value; - - if (_secondaryNextMonthButton != null) - { - _secondaryNextMonthButton.Click += HandleNextMonthButtonClick; - _secondaryNextMonthButton.Focusable = false; - } - } - } - - /// - /// Gets the button that displays the previous page of the calendar when - /// it is clicked. - /// - internal IconButton? SecondaryPreviousButton - { - get => _secondaryPreviousButton; - - private set - { - if (_secondaryPreviousButton != null) - { - _secondaryPreviousButton.Click -= HandlePreviousButtonClick; - } - - _secondaryPreviousButton = value; - - if (_secondaryPreviousButton != null) - { - _secondaryPreviousButton.Click += HandlePreviousButtonClick; - _secondaryPreviousButton.Focusable = false; - } - } - } - - internal IconButton? SecondaryPreviousMonthButton - { - get => _secondaryPreviousMonthButton; - - private set - { - if (_secondaryPreviousMonthButton != null) - { - _secondaryPreviousMonthButton.Click -= HandlePreviousMonthButtonClick; - } - - _secondaryPreviousMonthButton = value; - - if (_secondaryPreviousMonthButton != null) - { - _secondaryPreviousMonthButton.Click += HandlePreviousMonthButtonClick; - _secondaryPreviousMonthButton.Focusable = false; - } - } - } - - #endregion - - protected DateTime _currentMonth; - protected UniformGrid? _headerLayout; - protected bool _isMouseLeftButtonDownYearView; - protected DateTime _nextMonth; - - protected HeadTextButton? _primaryHeaderButton; - protected IconButton? _primaryNextButton; - protected IconButton? _primaryNextMonthButton; - protected IconButton? _primaryPreviousButton; - protected IconButton? _primaryPreviousMonthButton; - protected HeadTextButton? _secondaryHeaderButton; - - protected IconButton? _secondaryNextButton; - protected IconButton? _secondaryNextMonthButton; - protected IconButton? _secondaryPreviousButton; - protected IconButton? _secondaryPreviousMonthButton; - - internal RangeCalendar? Owner { get; set; } - - /// - /// Gets the Grid that hosts the content when in month mode. - /// - internal UniformGrid? MonthView { get; set; } - - internal Grid? PrimaryMonthView { get; set; } - internal Grid? SecondaryMonthView { get; set; } - private bool _pointerInMonthView; - - /// - /// Gets the Grid that hosts the content when in year or decade mode. - /// - internal Grid? YearView { get; set; } - - private void PopulateGrids() - { - if (MonthView != null) - { - if (PrimaryMonthView is not null) - { - PopulateMonthViewGrids(PrimaryMonthView); - } - - if (SecondaryMonthView is not null) - { - PopulateMonthViewGrids(SecondaryMonthView); - } - } - - if (YearView != null) - { - var childCount = RangeCalendar.RowsPerYear * RangeCalendar.ColumnsPerYear; - using var children = new PooledList(childCount); - - EventHandler monthCalendarButtonMouseDown = HandleMonthCalendarButtonMouseDown; - EventHandler monthCalendarButtonMouseUp = HandleMonthCalendarButtonMouseUp; - EventHandler monthMouseEntered = HandleMonthMouseEntered; - - for (var i = 0; i < RangeCalendar.RowsPerYear; i++) - { - for (var j = 0; j < RangeCalendar.ColumnsPerYear; j++) + // Set the start or end of the selection + // range + if (owner.IsSelectRangeStart) { - var month = new RangeCalendarButton(); - - if (Owner != null) - { - month.Owner = Owner; - } - - month.SetValue(Grid.RowProperty, i); - month.SetValue(Grid.ColumnProperty, j); - month.CalendarLeftMouseButtonDown += monthCalendarButtonMouseDown; - month.CalendarLeftMouseButtonUp += monthCalendarButtonMouseUp; - month.PointerEntered += monthMouseEntered; - children.Add(month); - } - } - - YearView.Children.AddRange(children); - } - } - - private void PopulateMonthViewGrids(Grid monthView) - { - var childCount = RangeCalendar.RowsPerMonth + RangeCalendar.RowsPerMonth * RangeCalendar.ColumnsPerMonth; - using var children = new PooledList(childCount); - - for (var i = 0; i < RangeCalendar.ColumnsPerMonth; i++) - { - if (DayTitleTemplate?.Build() is Control cell) - { - cell.DataContext = string.Empty; - cell.SetValue(Grid.RowProperty, 0); - cell.SetValue(Grid.ColumnProperty, i); - children.Add(cell); - } - } - - EventHandler cellMouseLeftButtonDown = HandleCellMouseLeftButtonDown; - EventHandler cellMouseLeftButtonUp = HandleCellMouseLeftButtonUp; - EventHandler cellMouseEntered = HandleCellMouseEntered; - EventHandler cellClick = HandleCellClick; - - for (var i = 1; i < RangeCalendar.RowsPerMonth; i++) - { - for (var j = 0; j < RangeCalendar.ColumnsPerMonth; j++) - { - var cell = new RangeCalendarDayButton(); - - if (Owner != null) - { - cell.Owner = Owner; - } - - cell.IsInPrimaryMonView = monthView == PrimaryMonthView; - - cell.SetValue(Grid.RowProperty, i); - cell.SetValue(Grid.ColumnProperty, j); - cell.CalendarDayButtonMouseDown += cellMouseLeftButtonDown; - cell.CalendarDayButtonMouseUp += cellMouseLeftButtonUp; - cell.PointerEntered += cellMouseEntered; - cell.Click += cellClick; - children.Add(cell); - } - } - - monthView.Children.AddRange(children); - } - - /// - /// Builds the visual tree for the - /// - /// when a new template is applied. - /// - protected override void OnApplyTemplate(TemplateAppliedEventArgs e) - { - PrimaryHeaderButton = e.NameScope.Find(RangeCalendarItemTheme.PrimaryHeaderButtonPart); - SecondaryHeaderButton = e.NameScope.Find(RangeCalendarItemTheme.SecondaryHeaderButtonPart); - PrimaryPreviousButton = e.NameScope.Find(RangeCalendarItemTheme.PrimaryPreviousButtonPart); - PrimaryPreviousMonthButton = - e.NameScope.Find(RangeCalendarItemTheme.PrimaryPreviousMonthButtonPart); - PrimaryNextButton = e.NameScope.Find(RangeCalendarItemTheme.PrimaryNextButtonPart); - PrimaryNextMonthButton = e.NameScope.Find(RangeCalendarItemTheme.PrimaryNextMonthButtonPart); - - SecondaryPreviousButton = e.NameScope.Find(RangeCalendarItemTheme.SecondaryPreviousButtonPart); - SecondaryPreviousMonthButton = - e.NameScope.Find(RangeCalendarItemTheme.SecondaryPreviousMonthButtonPart); - SecondaryNextButton = e.NameScope.Find(RangeCalendarItemTheme.SecondaryNextButtonPart); - SecondaryNextMonthButton = e.NameScope.Find(RangeCalendarItemTheme.SecondaryNextMonthButtonPart); - - MonthView = e.NameScope.Find(RangeCalendarItemTheme.MonthViewPart); - PrimaryMonthView = e.NameScope.Find(RangeCalendarItemTheme.PrimaryMonthViewPart); - SecondaryMonthView = e.NameScope.Find(RangeCalendarItemTheme.SecondaryMonthViewPart); - YearView = e.NameScope.Find(RangeCalendarItemTheme.YearViewPart); - _headerLayout = e.NameScope.Find(RangeCalendarItemTheme.HeaderLayoutPart); - - if (Owner != null) - { - UpdateDisabled(Owner.IsEnabled); - } - - PopulateGrids(); - - if (MonthView != null && YearView != null) - { - if (Owner != null) - { - Owner.SelectedMonth = Owner.DisplayDateInternal; - Owner.SelectedYear = Owner.DisplayDateInternal; - - if (Owner.DisplayMode == CalendarMode.Year) - { - UpdateYearMode(); - } - else if (Owner.DisplayMode == CalendarMode.Decade) - { - UpdateDecadeMode(); - } - - if (Owner.DisplayMode == CalendarMode.Month) - { - UpdateMonthMode(); - MonthView.IsVisible = true; - YearView.IsVisible = false; + owner.SelectedDate = selectedDate; + owner.NotifyDateSelected(selectedDate); } else { - YearView.IsVisible = true; - MonthView.IsVisible = false; + owner.SecondarySelectedDate = selectedDate; + owner.NotifyDateSelected(selectedDate); } - } - else - { - UpdateMonthMode(); - MonthView.IsVisible = true; - YearView.IsVisible = false; - } - } - - SetupHeaderForDisplayModeChanged(); - } - - private void SetupHeaderForDisplayModeChanged() - { - if (Owner is null || MonthView is null || _headerLayout is null) - { - return; - } - - if (Owner.DisplayMode == CalendarMode.Month) - { - MonthView.Columns = 2; - _headerLayout.Columns = 2; - } - else if (Owner.DisplayMode == CalendarMode.Year || Owner.DisplayMode == CalendarMode.Decade) - { - MonthView.Columns = 1; - _headerLayout.Columns = 1; - } - - IsMonthViewMode = Owner.DisplayMode == CalendarMode.Month; - } - - protected void SetDayTitles() - { - if (PrimaryMonthView is not null) - { - SetDayTitles(PrimaryMonthView); - } - - if (SecondaryMonthView is not null) - { - SetDayTitles(SecondaryMonthView); - } - } - - protected void SetDayTitles(Grid monthView) - { - for (var childIndex = 0; childIndex < RangeCalendar.ColumnsPerMonth; childIndex++) - { - var dayTitle = monthView.Children[childIndex]; - if (Owner != null) - { - dayTitle.DataContext = DateTimeHelper.GetCurrentDateFormat() - .ShortestDayNames[ - (childIndex + (int)Owner.FirstDayOfWeek) % - NumberOfDaysPerWeek]; - } - else - { - dayTitle.DataContext = DateTimeHelper.GetCurrentDateFormat().ShortestDayNames[ - (childIndex + (int)DateTimeHelper.GetCurrentDateFormat().FirstDayOfWeek) % NumberOfDaysPerWeek]; - } - } - } - - /// - /// How many days of the previous month need to be displayed. - /// - private int PreviousMonthDays(DateTime firstOfMonth) - { - var day = _calendar.GetDayOfWeek(firstOfMonth); - int i; - - if (Owner != null) - { - i = (day - Owner.FirstDayOfWeek + NumberOfDaysPerWeek) % NumberOfDaysPerWeek; - } - else - { - i = (day - DateTimeHelper.GetCurrentDateFormat().FirstDayOfWeek + NumberOfDaysPerWeek) % - NumberOfDaysPerWeek; - } - - if (i == 0) - { - return NumberOfDaysPerWeek; - } - - return i; - } - - protected internal virtual void UpdateMonthMode() - { - if (Owner != null) - { - _currentMonth = Owner.DisplayDateInternal; - _nextMonth = Owner.SecondaryDisplayDateInternal; - } - else - { - _currentMonth = DateTime.Today; - _nextMonth = DateTime.Today; - } - - SetMonthModeHeaderButton(); - SetMonthModePreviousButton(_currentMonth); - SetMonthModeNextButton(_currentMonth); - - if (MonthView != null) - { - SetDayTitles(); - if (PrimaryMonthView is not null) - { - SetCalendarDayButtons(_currentMonth, PrimaryMonthView); - } - - if (SecondaryMonthView is not null) - { - SetCalendarDayButtons(_nextMonth, SecondaryMonthView); - } - } - } - - protected virtual void SetMonthModeHeaderButton() - { - if (PrimaryHeaderButton is not null) - { - if (Owner is not null) - { - PrimaryHeaderButton.Content = - Owner.DisplayDateInternal.ToString("Y", DateTimeHelper.GetCurrentDateFormat()); - PrimaryHeaderButton.IsEnabled = true; - } - else - { - PrimaryHeaderButton.Content = DateTime.Today.ToString("Y", DateTimeHelper.GetCurrentDateFormat()); - } - } - - if (SecondaryHeaderButton is not null) - { - if (Owner is not null) - { - SecondaryHeaderButton.Content = - Owner.SecondaryDisplayDateInternal.ToString("Y", DateTimeHelper.GetCurrentDateFormat()); - SecondaryHeaderButton.IsEnabled = true; - } - else - { - SecondaryHeaderButton.Content = DateTime.Today.ToString("Y", DateTimeHelper.GetCurrentDateFormat()); - } - } - } - - protected void SetMonthModeNextButton(DateTime firstDayOfMonth) - { - if (Owner != null && PrimaryNextButton != null) - { - // DisplayDate is equal to DateTime.MaxValue - if (DateTimeHelper.CompareYearMonth(firstDayOfMonth, DateTime.MaxValue) == 0) - { - PrimaryNextButton.IsEnabled = false; - } - else - { - // Since we are sure DisplayDate is not equal to - // DateTime.MaxValue, it is safe to use AddMonths - var firstDayOfNextMonth = _calendar.AddMonths(firstDayOfMonth, 1); - PrimaryNextButton.IsEnabled = - DateTimeHelper.CompareDays(Owner.DisplayDateRangeEnd, firstDayOfNextMonth) > -1; - } - } - } - - protected void SetMonthModePreviousButton(DateTime firstDayOfMonth) - { - if (Owner != null && PrimaryPreviousButton != null) - { - PrimaryPreviousButton.IsEnabled = - DateTimeHelper.CompareDays(Owner.DisplayDateRangeStart, firstDayOfMonth) < 0; - } - } - - private void SetButtonState(RangeCalendarDayButton childButton, DateTime dateToAdd, Grid monthView) - { - if (Owner != null) - { - childButton.Opacity = 1; - - // If the day is outside the DisplayDateStart/End boundary, do - // not show it - if (DateTimeHelper.CompareDays(dateToAdd, Owner.DisplayDateRangeStart) < 0 || - DateTimeHelper.CompareDays(dateToAdd, Owner.DisplayDateRangeEnd) > 0) - { - childButton.IsEnabled = false; - childButton.IsToday = false; - childButton.IsSelected = false; - childButton.Opacity = 0; - } - else - { - // SET IF THE DAY IS SELECTABLE OR NOT - if (Owner.BlackoutDates.Contains(dateToAdd)) + + if (owner.SelectedDate is not null && owner.SecondarySelectedDate is not null) { - childButton.IsBlackout = true; - } - else - { - childButton.IsBlackout = false; + owner.NotifyRangeDateSelected(); } - childButton.IsEnabled = true; - - // SET IF THE DAY IS INACTIVE OR NOT: set if the day is a - // trailing day or not - childButton.IsInactive = CheckDayInactiveState(dateToAdd, monthView); - - // SET IF THE DAY IS TODAY OR NOT - childButton.IsToday = CheckDayIsTodayState(dateToAdd); - - // SET IF THE DAY IS SELECTED OR NOT - childButton.IsSelected = false; - DateTime? rangeStart = default; - DateTime? rangeEnd = default; - Owner.SortHoverIndexes(out rangeStart, out rangeEnd); - if (rangeStart != null && rangeEnd != null) - { - childButton.IsSelected = DateTimeHelper.InRange(dateToAdd, rangeStart.Value, rangeEnd.Value); - } - else if (rangeStart is not null) - { - childButton.IsSelected = DateTimeHelper.CompareDays(rangeStart.Value, dateToAdd) == 0; - } - else if (rangeEnd is not null) - { - childButton.IsSelected = DateTimeHelper.CompareDays(rangeEnd.Value, dateToAdd) == 0; - } - - // SET THE FOCUS ELEMENT - if (Owner.LastSelectedDate != null) - { - if (DateTimeHelper.CompareDays(Owner.LastSelectedDate.Value, dateToAdd) == 0) - { - if (Owner.FocusButton != null) - { - Owner.FocusButton.IsCurrent = false; - } - - Owner.FocusButton = childButton; - if (Owner.HasFocusInternal) - { - Owner.FocusButton.IsCurrent = true; - } - } - else - { - childButton.IsCurrent = false; - } - } + owner.HoverDateTime = null; + owner.UpdateHighlightDays(); } } } - - protected virtual bool CheckDayInactiveState(DateTime dateToAdd, Grid monthView) + + protected override void NotifyPointerOutMonthView(bool originInMonthView) { - if (Owner is not null) + if (Owner is RangeCalendar owner) { - if (monthView == PrimaryMonthView) - { - return DateTimeHelper.CompareYearMonth(dateToAdd, Owner.DisplayDateInternal) != 0; - } - - if (monthView == SecondaryMonthView) - { - return DateTimeHelper.CompareYearMonth(dateToAdd, Owner.SecondaryDisplayDateInternal) != 0; - } + owner.HoverDateTime = null; + Owner.UpdateHighlightDays(); } - - return false; - } - - protected virtual bool CheckDayIsTodayState(DateTime dateToAdd) - { - if (Owner is not null) - { - return Owner.IsTodayHighlighted && dateToAdd == DateTime.Today; - } - - return false; - } - - protected void SetCalendarDayButtons(DateTime firstDayOfMonth, Grid monthView) - { - var lastMonthToDisplay = PreviousMonthDays(firstDayOfMonth); - DateTime dateToAdd; - - if (DateTimeHelper.CompareYearMonth(firstDayOfMonth, DateTime.MinValue) > 0) - { - // DisplayDate is not equal to DateTime.MinValue we can subtract - // days from the DisplayDate - dateToAdd = _calendar.AddDays(firstDayOfMonth, -lastMonthToDisplay); - } - else - { - dateToAdd = firstDayOfMonth; - } - - var count = RangeCalendar.RowsPerMonth * RangeCalendar.ColumnsPerMonth; - - for (var childIndex = RangeCalendar.ColumnsPerMonth; childIndex < count; childIndex++) - { - var childButton = (RangeCalendarDayButton)monthView!.Children[childIndex]; - - childButton.Index = childIndex; - if (monthView == SecondaryMonthView) - { - childButton.Index += MonthViewSize; - } - - SetButtonState(childButton, dateToAdd, monthView); - - //childButton.Focusable = false; - childButton.Content = dateToAdd.Day.ToString(DateTimeHelper.GetCurrentDateFormat()); - childButton.DataContext = dateToAdd; - - if (DateTime.Compare(DateTimeHelper.DiscardTime(DateTime.MaxValue), dateToAdd) > 0) - { - // Since we are sure DisplayDate is not equal to - // DateTime.MaxValue, it is safe to use AddDays - dateToAdd = _calendar.AddDays(dateToAdd, 1); - } - else - { - // DisplayDate is equal to the DateTime.MaxValue, so there - // are no trailing days - childIndex++; - for (var i = childIndex; i < count; i++) - { - childButton = (RangeCalendarDayButton)monthView.Children[i]; - // button needs a content to occupy the necessary space - // for the content presenter - childButton.Content = i.ToString(DateTimeHelper.GetCurrentDateFormat()); - childButton.IsEnabled = false; - childButton.Opacity = 0; - } - - return; - } - } - } - - internal void UpdateYearMode() - { - if (Owner != null) - { - _currentMonth = Owner.SelectedMonth; - } - else - { - _currentMonth = DateTime.Today; - } - - SetYearModeHeaderButton(); - SetYearModePreviousButton(); - SetYearModeNextButton(); - - if (YearView != null) - { - SetMonthButtonsForYearMode(); - } - } - - private void SetYearModeHeaderButton() - { - if (PrimaryHeaderButton != null) - { - PrimaryHeaderButton.IsEnabled = true; - PrimaryHeaderButton.Content = _currentMonth.Year.ToString(DateTimeHelper.GetCurrentDateFormat()); - } - } - - private void SetYearModePreviousButton() - { - if (Owner != null && PrimaryPreviousButton != null) - { - PrimaryPreviousButton.IsEnabled = Owner.DisplayDateRangeStart.Year != _currentMonth.Year; - } - } - - private void SetYearModeNextButton() - { - if (Owner != null && PrimaryNextButton != null) - { - PrimaryNextButton.IsEnabled = Owner.DisplayDateRangeEnd.Year != _currentMonth.Year; - } - } - - private void SetMonthButtonsForYearMode() - { - var count = 0; - foreach (object child in YearView!.Children) - { - var childButton = (RangeCalendarButton)child; - // There should be no time component. Time is 12:00 AM - var day = new DateTime(_currentMonth.Year, count + 1, 1); - childButton.DataContext = day; - - childButton.Content = DateTimeHelper.GetCurrentDateFormat().AbbreviatedMonthNames[count]; - childButton.IsVisible = true; - - if (Owner != null) - { - if (day.Year == _currentMonth.Year && day.Month == _currentMonth.Month && day.Day == _currentMonth.Day) - { - Owner.FocusCalendarButton = childButton; - childButton.IsCalendarButtonFocused = Owner.HasFocusInternal; - } - else - { - childButton.IsCalendarButtonFocused = false; - } - - childButton.IsSelected = DateTimeHelper.CompareYearMonth(day, Owner.DisplayDateInternal) == 0; - - if (DateTimeHelper.CompareYearMonth(day, Owner.DisplayDateRangeStart) < 0 || - DateTimeHelper.CompareYearMonth(day, Owner.DisplayDateRangeEnd) > 0) - { - childButton.IsEnabled = false; - childButton.Opacity = 0; - } - else - { - childButton.IsEnabled = true; - childButton.Opacity = 1; - } - } - - childButton.IsInactive = false; - count++; - } - } - - internal void UpdateDecadeMode() - { - DateTime selectedYear; - - if (Owner != null) - { - selectedYear = Owner.SelectedYear; - _currentMonth = Owner.SelectedMonth; - } - else - { - _currentMonth = DateTime.Today; - selectedYear = DateTime.Today; - } - - var decade = DateTimeHelper.DecadeOfDate(selectedYear); - var decadeEnd = DateTimeHelper.EndOfDecade(selectedYear); - - SetDecadeModeHeaderButton(decade, decadeEnd); - SetDecadeModePreviousButton(decade); - SetDecadeModeNextButton(decadeEnd); - - if (YearView != null) - { - SetYearButtons(decade, decadeEnd); - } - } - - internal void UpdateYearViewSelection(RangeCalendarButton? calendarButton) - { - if (Owner != null && calendarButton?.DataContext is DateTime selectedDate) - { - Owner.FocusCalendarButton!.IsCalendarButtonFocused = false; - Owner.FocusCalendarButton = calendarButton; - calendarButton.IsCalendarButtonFocused = Owner.HasFocusInternal; - - if (Owner.DisplayMode == CalendarMode.Year) - { - Owner.SelectedMonth = selectedDate; - } - else - { - Owner.SelectedYear = selectedDate; - } - } - } - - private void SetYearButtons(int decade, int decadeEnd) - { - int year; - var count = -1; - foreach (var child in YearView!.Children) - { - var childButton = (RangeCalendarButton)child; - year = decade + count; - - if (year <= DateTime.MaxValue.Year && year >= DateTime.MinValue.Year) - { - // There should be no time component. Time is 12:00 AM - var day = new DateTime(year, 1, 1); - childButton.DataContext = day; - childButton.Content = year.ToString(DateTimeHelper.GetCurrentDateFormat()); - childButton.IsVisible = true; - - if (Owner != null) - { - if (year == Owner.SelectedYear.Year) - { - Owner.FocusCalendarButton = childButton; - childButton.IsCalendarButtonFocused = Owner.HasFocusInternal; - } - else - { - childButton.IsCalendarButtonFocused = false; - } - - childButton.IsSelected = Owner.DisplayDate.Year == year; - - if (year < Owner.DisplayDateRangeStart.Year || year > Owner.DisplayDateRangeEnd.Year) - { - childButton.IsEnabled = false; - childButton.Opacity = 0; - } - else - { - childButton.IsEnabled = true; - childButton.Opacity = 1; - } - } - - // SET IF THE YEAR IS INACTIVE OR NOT: set if the year is a - // trailing year or not - childButton.IsInactive = year < decade || year > decadeEnd; - } - else - { - childButton.IsEnabled = false; - childButton.Opacity = 0; - } - - count++; - } - } - - private void SetDecadeModeHeaderButton(int decade, int decadeEnd) - { - if (PrimaryHeaderButton != null) - { - PrimaryHeaderButton.Content = decade.ToString(CultureInfo.CurrentCulture) + "-" + - decadeEnd.ToString(CultureInfo.CurrentCulture); - PrimaryHeaderButton.IsEnabled = false; - } - } - - private void SetDecadeModeNextButton(int decadeEnd) - { - if (Owner != null && PrimaryNextButton != null) - { - PrimaryNextButton.IsEnabled = Owner.DisplayDateRangeEnd.Year > decadeEnd; - } - } - - private void SetDecadeModePreviousButton(int decade) - { - if (Owner != null && PrimaryPreviousButton != null) - { - PrimaryPreviousButton.IsEnabled = decade > Owner.DisplayDateRangeStart.Year; - } - } - - protected internal virtual void HandleHeaderButtonClick(object? sender, RoutedEventArgs e) - { - if (Owner != null) - { - if (!Owner.HasFocusInternal) - { - Owner.Focus(); - } - - var b = (HeadTextButton)sender!; - DateTime d; - - if (b.IsEnabled) - { - if (Owner.DisplayMode == CalendarMode.Month) - { - d = Owner.DisplayDateInternal; - Owner.SelectedMonth = new DateTime(d.Year, d.Month, 1); - Owner.DisplayMode = CalendarMode.Year; - } - else - { - Debug.Assert(Owner.DisplayMode == CalendarMode.Year, - "The Owner RangeCalendar's DisplayMode should be Year!"); - d = Owner.SelectedMonth; - Owner.SelectedYear = new DateTime(d.Year, d.Month, 1); - Owner.DisplayMode = CalendarMode.Decade; - } - - SetupHeaderForDisplayModeChanged(); - } - } - } - - internal void HandlePreviousMonthButtonClick(object? sender, RoutedEventArgs e) - { - if (Owner != null) - { - if (!Owner.HasFocusInternal) - { - Owner.Focus(); - } - - var b = (IconButton)sender!; - if (b.IsEnabled) - { - Owner.OnPreviousMonthClick(); - } - } - } - - internal void HandlePreviousButtonClick(object? sender, RoutedEventArgs e) - { - if (Owner != null) - { - if (!Owner.HasFocusInternal) - { - Owner.Focus(); - } - - var b = (IconButton)sender!; - if (b.IsEnabled) - { - Owner.OnPreviousClick(); - } - } - } - - internal void HandleNextMonthButtonClick(object? sender, RoutedEventArgs e) - { - if (Owner != null) - { - if (!Owner.HasFocusInternal) - { - Owner.Focus(); - } - - var b = (IconButton)sender!; - - if (b.IsEnabled) - { - Owner.OnNextMonthClick(); - } - } - } - - internal void HandleNextButtonClick(object? sender, RoutedEventArgs e) - { - if (Owner != null) - { - if (!Owner.HasFocusInternal) - { - Owner.Focus(); - } - - var b = (IconButton)sender!; - - if (b.IsEnabled) - { - Owner.OnNextClick(); - } - } - } - - internal void HandleCellMouseEntered(object? sender, PointerEventArgs e) - { - if (Owner != null) - { - if (sender is RangeCalendarDayButton - { - IsEnabled: true, IsBlackout: false, DataContext: DateTime selectedDate - } b) - { - Owner.HoverDateTime = selectedDate; - // Update the States of the buttons - Owner.UpdateHighlightDays(); - Owner.NotifyHoverDateChanged(selectedDate); - } - } - } - - internal void HandleCellMouseLeftButtonDown(object? sender, PointerPressedEventArgs e) - { - if (Owner != null) - { - if (!Owner.HasFocusInternal) - { - Owner.Focus(); - } - - if (sender is RangeCalendarDayButton b) - { - if (b.IsEnabled && !b.IsBlackout && b.DataContext is DateTime selectedDate) - { - // Set the start or end of the selection - // range - if (Owner.FixedRangeStart) - { - Owner.SelectedRangeStartDate = selectedDate; - } - else - { - Owner.SelectedRangeEndDate = selectedDate; - } - - Owner.UpdateHighlightDays(); - if (Owner.SelectedRangeStartDate is not null && Owner.SelectedRangeEndDate is not null) - { - Owner.NotifyRangeDateSelected(); - } - } - } - } - } - - internal void HandleCellMouseLeftButtonUp(object? sender, PointerReleasedEventArgs e) - { - if (Owner != null) - { - RangeCalendarDayButton? b = sender as RangeCalendarDayButton; - if (b != null && !b.IsBlackout) - { - Owner.OnDayButtonMouseUp(e); - } - - if (b != null && b.DataContext is DateTime selectedDate) - { - // If the day is Disabled but a trailing day we should - // be able to switch months - if (b.IsInactive) - { - Owner.OnDayClick(selectedDate); - } - } - } - } - - private void HandleCellClick(object? sender, RoutedEventArgs e) - { - } - - private void HandleMonthCalendarButtonMouseDown(object? sender, PointerPressedEventArgs e) - { - _isMouseLeftButtonDownYearView = true; - - UpdateYearViewSelection(sender as RangeCalendarButton); - } - - protected internal virtual void HandleMonthCalendarButtonMouseUp(object? sender, PointerReleasedEventArgs e) - { - _isMouseLeftButtonDownYearView = false; - - if (Owner != null && (sender as RangeCalendarButton)?.DataContext is DateTime newMonth) - { - if (Owner.DisplayMode == CalendarMode.Year) - { - Owner.DisplayDate = newMonth; - Owner.DisplayMode = CalendarMode.Month; - } - else - { - Debug.Assert(Owner.DisplayMode == CalendarMode.Decade, "The owning Calendar should be in decade mode!"); - Owner.SelectedMonth = newMonth; - Owner.DisplayMode = CalendarMode.Year; - } - - SetupHeaderForDisplayModeChanged(); - } - } - - private void HandleMonthMouseEntered(object? sender, PointerEventArgs e) - { - if (_isMouseLeftButtonDownYearView) - { - UpdateYearViewSelection(sender as RangeCalendarButton); - } - } - - internal void UpdateDisabled(bool isEnabled) - { - PseudoClasses.Set(CalendarDisabledPC, !isEnabled); - } - - protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnAttachedToVisualTree(e); - var inputManager = AvaloniaLocator.Current.GetService()!; - _restoreHoverPositionDisposable = inputManager.Process.Subscribe(DetectRestoreHoverPosition); - } - - protected override void OnDetachedFromVisualTree(VisualTreeAttachmentEventArgs e) - { - base.OnDetachedFromVisualTree(e); - _restoreHoverPositionDisposable?.Dispose(); - } - - private void DetectRestoreHoverPosition(RawInputEventArgs args) - { - if (Owner is null) - { - return; - } - - if (args is RawPointerEventArgs pointerEventArgs) - { - if (!IsPointerInMonthView(pointerEventArgs.Position)) - { - Owner.HoverDateTime = Owner.FixedRangeStart - ? Owner.SelectedRangeStartDate - : Owner.SelectedRangeEndDate; - // Update the States of the buttons - if (_pointerInMonthView) - { - Owner.HoverDateTime = null; - Owner.UpdateHighlightDays(); - } - - _pointerInMonthView = false; - } - else - { - _pointerInMonthView = true; - } - } - } - - private bool IsPointerInMonthView(Point position) - { - if (Owner is null) - { - return false; - } - - if (Owner.DisplayMode == CalendarMode.Month) - { - return GetMonthViewRect(PrimaryMonthView!).Contains(position) || - GetMonthViewRect(SecondaryMonthView!).Contains(position); - } - - return false; - } - - private Rect GetMonthViewRect(Grid monthView) - { - var firstDay = (monthView.Children[7] as RangeCalendarDayButton)!; - var firstDayPos = firstDay.TranslatePoint(new Point(0, 0), TopLevel.GetTopLevel(monthView)!) ?? default; - var monthViewPos = monthView.TranslatePoint(new Point(0, 0), TopLevel.GetTopLevel(monthView)!) ?? default; - return new Rect(firstDayPos, - new Size(monthView.Bounds.Width, monthViewPos.Y + monthView.Bounds.Height - firstDayPos.Y)); } } \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarItemTheme.cs b/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarItemTheme.cs deleted file mode 100644 index fe404fc..0000000 --- a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarItemTheme.cs +++ /dev/null @@ -1,409 +0,0 @@ -using AtomUI.Data; -using AtomUI.Theme; -using AtomUI.Theme.Styling; -using AtomUI.Utils; -using Avalonia; -using Avalonia.Controls; -using Avalonia.Controls.Primitives; -using Avalonia.Controls.Templates; -using Avalonia.Data; -using Avalonia.Data.Converters; -using Avalonia.Layout; -using Avalonia.Styling; - -namespace AtomUI.Controls.CalendarView; - -[ControlThemeProvider] -internal class RangeCalendarItemTheme : BaseControlTheme -{ - public const string ItemFramePart = "PART_ItemFrame"; - public const string ItemRootLayoutPart = "PART_ItemRootLayout"; - public const string MonthViewPart = "PART_MonthView"; - public const string PrimaryMonthViewPart = "PART_PrimaryMonthView"; - public const string SecondaryMonthViewPart = "PART_SecondaryMonthView"; - public const string YearViewPart = "PART_YearView"; - public const string HeaderLayoutPart = "PART_HeaderLayout"; - - public const string PrimaryPreviousButtonPart = "PART_PrimaryPreviousButton"; - public const string PrimaryPreviousMonthButtonPart = "PART_PrimaryPreviousMonthButton"; - public const string PrimaryHeaderButtonPart = "PART_PrimaryHeaderButton"; - public const string PrimaryNextMonthButtonPart = "PART_PrimaryNextMonthButton"; - public const string PrimaryNextButtonPart = "PART_PrimaryNextButton"; - - public const string SecondaryPreviousButtonPart = "PART_SecondaryPreviousButton"; - public const string SecondaryPreviousMonthButtonPart = "PART_SecondaryPreviousMonthButton"; - public const string SecondaryHeaderButtonPart = "PART_SecondaryHeaderButton"; - public const string SecondaryNextMonthButtonPart = "PART_SecondaryNextMonthButton"; - public const string SecondaryNextButtonPart = "PART_SecondaryNextButton"; - - public RangeCalendarItemTheme() - : base(typeof(RangeCalendarItem)) - { - } - - protected override IControlTemplate BuildControlTemplate() - { - return new FuncControlTemplate((calendarItem, scope) => - { - var frame = new Border - { - Name = ItemFramePart - }; - - var rootLayout = new DockPanel - { - Name = ItemRootLayoutPart, - LastChildFill = true - }; - BuildHeader(rootLayout, scope); - BuildContentView(rootLayout, scope); - - BuildDayTitleTemplate(calendarItem); - frame.Child = rootLayout; - - return frame; - }); - } - - private void BuildDayTitleTemplate(RangeCalendarItem calendarItem) - { - calendarItem.DayTitleTemplate = new DayTitleTemplate(); - } - - protected virtual void BuildHeader(DockPanel layout, INameScope scope) - { - var headerLayout = new UniformGrid - { - Name = HeaderLayoutPart, - Columns = 2 - }; - - headerLayout.RegisterInNameScope(scope); - BuildPrimaryHeaderItem(headerLayout, scope); - BuildSecondaryHeaderItem(headerLayout, scope); - - DockPanel.SetDock(headerLayout, Dock.Top); - layout.Children.Add(headerLayout); - } - - private void BuildPrimaryHeaderItem(UniformGrid layout, INameScope scope) - { - var headerLayout = new Grid - { - ColumnDefinitions = new ColumnDefinitions - { - new(GridLength.Auto), - new(GridLength.Auto), - new(GridLength.Star), - new(GridLength.Auto), - new(GridLength.Auto) - } - }; - - var previousButton = BuildPreviousButton(PrimaryPreviousButtonPart); - previousButton.RegisterInNameScope(scope); - Grid.SetColumn(previousButton, 0); - headerLayout.Children.Add(previousButton); - - var previousMonthButton = BuildPreviousMonthButton(PrimaryPreviousMonthButtonPart); - CreateTemplateParentBinding(previousMonthButton, Visual.IsVisibleProperty, - RangeCalendarItem.IsMonthViewModeProperty); - previousMonthButton.RegisterInNameScope(scope); - Grid.SetColumn(previousMonthButton, 1); - headerLayout.Children.Add(previousMonthButton); - - var primaryHeaderButton = new HeadTextButton - { - Name = PrimaryHeaderButtonPart - }; - Grid.SetColumn(primaryHeaderButton, 2); - primaryHeaderButton.RegisterInNameScope(scope); - headerLayout.Children.Add(primaryHeaderButton); - - var nextMonthButton = BuildNextMonthButton(PrimaryNextMonthButtonPart); - nextMonthButton.IsVisible = false; - nextMonthButton.RegisterInNameScope(scope); - Grid.SetColumn(nextMonthButton, 3); - headerLayout.Children.Add(nextMonthButton); - - var nextButton = BuildNextButton(PrimaryNextButtonPart); - CreateTemplateParentBinding(nextButton, Visual.IsVisibleProperty, RangeCalendarItem.IsMonthViewModeProperty, - BindingMode.Default, - BoolConverters.Not); - nextButton.RegisterInNameScope(scope); - Grid.SetColumn(nextButton, 4); - headerLayout.Children.Add(nextButton); - - layout.Children.Add(headerLayout); - } - - private void BuildSecondaryHeaderItem(UniformGrid layout, INameScope scope) - { - var headerLayout = new Grid - { - ColumnDefinitions = new ColumnDefinitions - { - new(GridLength.Auto), - new(GridLength.Auto), - new(GridLength.Star), - new(GridLength.Auto), - new(GridLength.Auto) - } - }; - - CreateTemplateParentBinding(headerLayout, Visual.IsVisibleProperty, RangeCalendarItem.IsMonthViewModeProperty); - - TokenResourceBinder.CreateTokenBinding(headerLayout, Layoutable.MarginProperty, - DatePickerTokenResourceKey.RangeCalendarSpacing, BindingPriority.Template, - v => - { - if (v is double dval) - { - return new Thickness(dval, 0, 0, 0); - } - - return new Thickness(); - }); - - // 原则上这两个按钮不需要,但是可能后面会用到 - - var previousButton = BuildPreviousButton(SecondaryPreviousButtonPart); - previousButton.RegisterInNameScope(scope); - previousButton.IsVisible = false; - Grid.SetColumn(previousButton, 0); - headerLayout.Children.Add(previousButton); - - var previousMonthButton = BuildPreviousMonthButton(SecondaryPreviousMonthButtonPart); - previousMonthButton.RegisterInNameScope(scope); - previousMonthButton.IsVisible = false; - Grid.SetColumn(previousMonthButton, 1); - headerLayout.Children.Add(previousMonthButton); - - var secondaryHeaderButton = new HeadTextButton - { - Name = SecondaryHeaderButtonPart - }; - Grid.SetColumn(secondaryHeaderButton, 2); - secondaryHeaderButton.RegisterInNameScope(scope); - headerLayout.Children.Add(secondaryHeaderButton); - - var nextMonthButton = BuildNextMonthButton(SecondaryNextMonthButtonPart); - CreateTemplateParentBinding(nextMonthButton, Visual.IsVisibleProperty, - RangeCalendarItem.IsMonthViewModeProperty); - nextMonthButton.RegisterInNameScope(scope); - Grid.SetColumn(nextMonthButton, 3); - headerLayout.Children.Add(nextMonthButton); - - var nextButton = BuildNextButton(SecondaryNextButtonPart); - CreateTemplateParentBinding(nextButton, Visual.IsVisibleProperty, RangeCalendarItem.IsMonthViewModeProperty); - nextButton.RegisterInNameScope(scope); - Grid.SetColumn(nextButton, 4); - headerLayout.Children.Add(nextButton); - - layout.Children.Add(headerLayout); - } - - protected virtual IconButton BuildPreviousButton(string name) - { - var previousButtonIcon = new PathIcon - { - Kind = "DoubleLeftOutlined" - }; - TokenResourceBinder.CreateGlobalTokenBinding(previousButtonIcon, PathIcon.NormalFilledBrushProperty, - GlobalTokenResourceKey.ColorTextDescription); - TokenResourceBinder.CreateGlobalTokenBinding(previousButtonIcon, PathIcon.ActiveFilledBrushProperty, - GlobalTokenResourceKey.ColorText); - TokenResourceBinder.CreateGlobalTokenBinding(previousButtonIcon, PathIcon.SelectedFilledBrushProperty, - GlobalTokenResourceKey.ColorText); - - var previousButton = new IconButton - { - Name = name, - Icon = previousButtonIcon - }; - - TokenResourceBinder.CreateGlobalTokenBinding(previousButton, IconButton.IconWidthProperty, - GlobalTokenResourceKey.IconSizeSM); - TokenResourceBinder.CreateGlobalTokenBinding(previousButton, IconButton.IconHeightProperty, - GlobalTokenResourceKey.IconSizeSM); - return previousButton; - } - - protected virtual IconButton BuildPreviousMonthButton(string name) - { - var previousMonthButtonIcon = new PathIcon - { - Kind = "LeftOutlined" - }; - TokenResourceBinder.CreateGlobalTokenBinding(previousMonthButtonIcon, PathIcon.NormalFilledBrushProperty, - GlobalTokenResourceKey.ColorTextDescription); - TokenResourceBinder.CreateGlobalTokenBinding(previousMonthButtonIcon, PathIcon.ActiveFilledBrushProperty, - GlobalTokenResourceKey.ColorText); - TokenResourceBinder.CreateGlobalTokenBinding(previousMonthButtonIcon, PathIcon.SelectedFilledBrushProperty, - GlobalTokenResourceKey.ColorText); - - var previousMonthButton = new IconButton - { - Name = name, - Icon = previousMonthButtonIcon - }; - - TokenResourceBinder.CreateGlobalTokenBinding(previousMonthButton, IconButton.IconWidthProperty, - GlobalTokenResourceKey.IconSizeSM); - TokenResourceBinder.CreateGlobalTokenBinding(previousMonthButton, IconButton.IconHeightProperty, - GlobalTokenResourceKey.IconSizeSM); - return previousMonthButton; - } - - protected virtual IconButton BuildNextButton(string name) - { - var nextButtonIcon = new PathIcon - { - Kind = "DoubleRightOutlined" - }; - TokenResourceBinder.CreateGlobalTokenBinding(nextButtonIcon, PathIcon.NormalFilledBrushProperty, - GlobalTokenResourceKey.ColorTextDescription); - TokenResourceBinder.CreateGlobalTokenBinding(nextButtonIcon, PathIcon.ActiveFilledBrushProperty, - GlobalTokenResourceKey.ColorText); - TokenResourceBinder.CreateGlobalTokenBinding(nextButtonIcon, PathIcon.SelectedFilledBrushProperty, - GlobalTokenResourceKey.ColorText); - - var nextButton = new IconButton - { - Name = name, - Icon = nextButtonIcon - }; - TokenResourceBinder.CreateGlobalTokenBinding(nextButton, IconButton.IconWidthProperty, - GlobalTokenResourceKey.IconSizeSM); - TokenResourceBinder.CreateGlobalTokenBinding(nextButton, IconButton.IconHeightProperty, - GlobalTokenResourceKey.IconSizeSM); - return nextButton; - } - - protected virtual IconButton BuildNextMonthButton(string name) - { - var nextMonthButtonIcon = new PathIcon - { - Kind = "RightOutlined" - }; - TokenResourceBinder.CreateGlobalTokenBinding(nextMonthButtonIcon, PathIcon.NormalFilledBrushProperty, - GlobalTokenResourceKey.ColorTextDescription); - TokenResourceBinder.CreateGlobalTokenBinding(nextMonthButtonIcon, PathIcon.ActiveFilledBrushProperty, - GlobalTokenResourceKey.ColorText); - TokenResourceBinder.CreateGlobalTokenBinding(nextMonthButtonIcon, PathIcon.SelectedFilledBrushProperty, - GlobalTokenResourceKey.ColorText); - var nextMonthButton = new IconButton - { - Name = name, - Icon = nextMonthButtonIcon - }; - TokenResourceBinder.CreateGlobalTokenBinding(nextMonthButton, IconButton.IconWidthProperty, - GlobalTokenResourceKey.IconSizeSM); - TokenResourceBinder.CreateGlobalTokenBinding(nextMonthButton, IconButton.IconHeightProperty, - GlobalTokenResourceKey.IconSizeSM); - return nextMonthButton; - } - - private void BuildContentView(DockPanel layout, INameScope scope) - { - var monthView = new UniformGrid - { - Name = MonthViewPart, - Columns = 2, - IsVisible = false - }; - - var primaryMonthView = BuildMonthViewItem(PrimaryMonthViewPart); - primaryMonthView.RegisterInNameScope(scope); - monthView.Children.Add(primaryMonthView); - - var secondaryMonthView = BuildMonthViewItem(SecondaryMonthViewPart); - secondaryMonthView.RegisterInNameScope(scope); - monthView.Children.Add(secondaryMonthView); - - TokenResourceBinder.CreateTokenBinding(secondaryMonthView, Layoutable.MarginProperty, - DatePickerTokenResourceKey.RangeCalendarSpacing, BindingPriority.Template, - v => - { - if (v is double dval) - { - return new Thickness(dval, 0, 0, 0); - } - - return new Thickness(); - }); - - BindUtils.RelayBind(monthView, Visual.IsVisibleProperty, primaryMonthView, Visual.IsVisibleProperty); - BindUtils.RelayBind(monthView, Visual.IsVisibleProperty, secondaryMonthView, Visual.IsVisibleProperty); - - monthView.RegisterInNameScope(scope); - layout.Children.Add(monthView); - - var yearView = new Grid - { - Name = YearViewPart, - IsVisible = false, - RowDefinitions = new RowDefinitions - { - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star) - }, - ColumnDefinitions = new ColumnDefinitions - { - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star) - } - }; - yearView.RegisterInNameScope(scope); - layout.Children.Add(yearView); - } - - private Grid BuildMonthViewItem(string name) - { - var dayTitleRowDef = new RowDefinition(); - TokenResourceBinder.CreateTokenBinding(dayTitleRowDef, RowDefinition.HeightProperty, - DatePickerTokenResourceKey.DayTitleHeight); - var monthView = new Grid - { - Name = name, - HorizontalAlignment = HorizontalAlignment.Stretch, - IsVisible = false, - RowDefinitions = new RowDefinitions - { - dayTitleRowDef, - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star) - }, - ColumnDefinitions = new ColumnDefinitions - { - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star), - new(GridLength.Star) - } - }; - return monthView; - } - - protected override void BuildStyles() - { - var commonStyle = new Style(selector => selector.Nesting()); - - var headerLayoutStyle = new Style(selector => selector.Nesting().Template().Name(HeaderLayoutPart)); - headerLayoutStyle.Add(Layoutable.MarginProperty, DatePickerTokenResourceKey.HeaderMargin); - - commonStyle.Add(headerLayoutStyle); - - Add(commonStyle); - } -} \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarTheme.cs b/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarTheme.cs index 4dc2a3d..b502ebf 100644 --- a/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarTheme.cs +++ b/src/AtomUI.Controls/DatePicker/CalendarView/RangeCalendarTheme.cs @@ -1,74 +1,31 @@ -using AtomUI.Theme; -using AtomUI.Theme.Data; -using AtomUI.Theme.Styling; -using AtomUI.Utils; +using AtomUI.Theme.Styling; using Avalonia.Controls; -using Avalonia.Controls.Primitives; using Avalonia.Controls.Templates; using Avalonia.Layout; -using Avalonia.Styling; namespace AtomUI.Controls.CalendarView; [ControlThemeProvider] -internal class RangeCalendarTheme : BaseControlTheme +internal class RangeCalendarTheme : CalendarTheme { - public const string RootPart = "PART_Root"; - public const string CalendarItemPart = "PART_CalendarItem"; - public const string FramePart = "PART_Frame"; - public RangeCalendarTheme() - : base(typeof(RangeCalendar)) + : this(typeof(RangeCalendar)) { } - protected override IControlTemplate BuildControlTemplate() + public RangeCalendarTheme(Type targetType) : base(targetType) { - return new FuncControlTemplate((rangeCalendar, scope) => + } + + protected override CalendarItem BuildCalendarItem(INameScope scope) + { + var calendarItem = new RangeCalendarItem { - var frame = new Border - { - Name = FramePart - }; + Name = CalendarItemPart, + HorizontalAlignment = HorizontalAlignment.Stretch + }; - CreateTemplateParentBinding(frame, Border.BorderBrushProperty, TemplatedControl.BorderBrushProperty); - CreateTemplateParentBinding(frame, Border.BorderThicknessProperty, - TemplatedControl.BorderThicknessProperty); - CreateTemplateParentBinding(frame, Border.CornerRadiusProperty, TemplatedControl.CornerRadiusProperty); - CreateTemplateParentBinding(frame, Border.BackgroundProperty, TemplatedControl.BackgroundProperty); - CreateTemplateParentBinding(frame, Decorator.PaddingProperty, TemplatedControl.PaddingProperty); - - var rootLayout = new Panel - { - Name = RootPart, - ClipToBounds = true - }; - TokenResourceBinder.CreateTokenBinding(rootLayout, StackPanel.SpacingProperty, - DatePickerTokenResourceKey.RangeCalendarSpacing); - rootLayout.RegisterInNameScope(scope); - - var calendarItem = new RangeCalendarItem - { - Name = CalendarItemPart, - HorizontalAlignment = HorizontalAlignment.Stretch - }; - - calendarItem.RegisterInNameScope(scope); - rootLayout.Children.Add(calendarItem); - - frame.Child = rootLayout; - - return frame; - }); - } - - protected override void BuildStyles() - { - var commonStyle = new Style(selector => selector.Nesting()); - commonStyle.Add(TemplatedControl.BorderBrushProperty, GlobalTokenResourceKey.ColorBorder); - commonStyle.Add(TemplatedControl.CornerRadiusProperty, GlobalTokenResourceKey.BorderRadius); - commonStyle.Add(TemplatedControl.BackgroundProperty, GlobalTokenResourceKey.ColorBgContainer); - commonStyle.Add(TemplatedControl.PaddingProperty, DatePickerTokenResourceKey.PanelContentPadding); - Add(commonStyle); + calendarItem.RegisterInNameScope(scope); + return calendarItem; } } \ No newline at end of file diff --git a/src/AtomUI.Controls/DatePicker/DatePicker.cs b/src/AtomUI.Controls/DatePicker/DatePicker.cs index bca25e3..80f955b 100644 --- a/src/AtomUI.Controls/DatePicker/DatePicker.cs +++ b/src/AtomUI.Controls/DatePicker/DatePicker.cs @@ -26,7 +26,7 @@ public class DatePicker : InfoPickerInput AvaloniaProperty.Register(nameof(Format)); public static readonly StyledProperty IsShowTimeProperty = - AvaloniaProperty.Register(nameof(IsShowTime)); + AvaloniaProperty.Register(nameof(IsShowTime), false); public static readonly StyledProperty IsNeedConfirmProperty = AvaloniaProperty.Register(nameof(IsNeedConfirm)); @@ -124,7 +124,7 @@ public class DatePicker : InfoPickerInput return format; } - public string FormatDateTime(DateTime? dateTime) + protected string FormatDateTime(DateTime? dateTime) { if (dateTime is null) { @@ -208,9 +208,9 @@ public class DatePicker : InfoPickerInput private void HandleHoverDateTimeChanged(object? sender, DateSelectedEventArgs args) { - if (args.Value.HasValue) + if (args.Date.HasValue) { - Text = FormatDateTime(args.Value); + Text = FormatDateTime(args.Date); } else { @@ -226,9 +226,7 @@ public class DatePicker : InfoPickerInput private void ClearHoverSelectedInfo() { - DateTime? targetValue = default; - targetValue = SelectedDateTime; - Text = FormatDateTime(targetValue); + Text = FormatDateTime(SelectedDateTime); } protected override void OnApplyTemplate(TemplateAppliedEventArgs e) diff --git a/src/AtomUI.Controls/DatePicker/DatePickerPresenter.cs b/src/AtomUI.Controls/DatePicker/DatePickerPresenter.cs index a677c63..3f1a86b 100644 --- a/src/AtomUI.Controls/DatePicker/DatePickerPresenter.cs +++ b/src/AtomUI.Controls/DatePicker/DatePickerPresenter.cs @@ -112,12 +112,12 @@ internal class DatePickerPresenter : PickerPresenterBase #endregion - private Button? _nowButton; - private Button? _todayButton; - private Button? _confirmButton; - private PickerCalendar? _calendarView; - private CompositeDisposable? _compositeDisposable; - private TimeView? _timeView; + protected Button? _nowButton; + protected Button? _todayButton; + protected Button? _confirmButton; + protected PickerCalendar? _calendarView; + protected CompositeDisposable? _compositeDisposable; + protected TimeView? _timeView; protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e) { @@ -129,7 +129,7 @@ internal class DatePickerPresenter : PickerPresenterBase { _compositeDisposable.Add(PickerCalendar.IsPointerInMonthViewProperty.Changed.Subscribe(args => { - ChoosingStatueChanged?.Invoke(this, new ChoosingStatusEventArgs(args.GetNewValue())); + EmitChoosingStatueChanged(args.GetNewValue()); })); } @@ -137,7 +137,7 @@ internal class DatePickerPresenter : PickerPresenterBase { _compositeDisposable.Add(TimeView.IsPointerInSelectorProperty.Changed.Subscribe(args => { - ChoosingStatueChanged?.Invoke(this, new ChoosingStatusEventArgs(args.GetNewValue())); + EmitChoosingStatueChanged(args.GetNewValue()); })); SyncTimeViewTimeValue(); } @@ -161,10 +161,15 @@ internal class DatePickerPresenter : PickerPresenterBase } else if (change.Property == SelectedDateTimeProperty) { - if (_confirmButton is not null) - { - _confirmButton.IsEnabled = SelectedDateTime is not null; - } + SetupConfirmButtonEnableStatus(); + } + } + + protected virtual void SetupConfirmButtonEnableStatus() + { + if (_confirmButton is not null) + { + _confirmButton.IsEnabled = SelectedDateTime is not null; } } @@ -175,7 +180,7 @@ internal class DatePickerPresenter : PickerPresenterBase _todayButton = e.NameScope.Get