├── .editorconfig ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ ├── bug_report.yaml │ └── feature_request.yaml ├── PULL_REQUEST_TEMPLATE.md └── dependabot.yml ├── .gitignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── FUNDING.yml ├── LICENSE ├── Logo ├── MicaWPFLogo - 128x128.png ├── MicaWPFLogo - 178x178.png └── MicaWPFLogo - 80x56.png ├── MicaWPF.sln ├── README.md ├── ReadmeNuget.md ├── SECURITY.md ├── azure-pipelines.yml ├── azure ├── build.yml └── deploy.yml ├── src ├── MicaWPF.Core │ ├── Animations │ │ └── BrushAnimation.cs │ ├── AssemblyInfo.cs │ ├── Controls │ │ ├── GradientBorder.cs │ │ ├── IButton.cs │ │ └── MicaWindow │ │ │ ├── IMicaWindow.cs │ │ │ ├── MicaWindowActionHandler.cs │ │ │ ├── MicaWindowBase.cs │ │ │ ├── MicaWindowInteropHandler.cs │ │ │ ├── MicaWindowProperty.cs │ │ │ └── MicaWindowStyle.cs │ ├── Converters │ │ ├── BrushToColorConverter.cs │ │ ├── DialogScrollViewerHeightConverter.cs │ │ ├── IconNotEmptyConverter.cs │ │ ├── IsNullConverter.cs │ │ ├── ObjectToSymbolConverter.cs │ │ ├── ProgressThicknessConverter.cs │ │ └── TextToAsteriskConverter.cs │ ├── Enums │ │ ├── AccentBrushType.cs │ │ ├── BackdropType.cs │ │ ├── ContentDialogButton.cs │ │ ├── ContentDialogResult.cs │ │ ├── ElementPosition.cs │ │ ├── RevealMode.cs │ │ ├── TitleBarType.cs │ │ └── WindowsTheme.cs │ ├── Events │ │ ├── ISubscription.cs │ │ ├── IWeakEvent.cs │ │ ├── Subscription.cs │ │ └── WeakEvent.cs │ ├── Extensions │ │ ├── ColorExtension.cs │ │ ├── DependencyObjectExtension.cs │ │ ├── FluentSystemIconsExtension.cs │ │ ├── FrameworkElementExtension.cs │ │ ├── MathExtension.cs │ │ └── WindowExtension.cs │ ├── Helpers │ │ ├── ColorHelper.cs │ │ ├── DesignTimeHelper.cs │ │ ├── DpiHelper.cs │ │ ├── HSVColorHelper.cs │ │ ├── MathHelper.cs │ │ ├── OsHelper.cs │ │ ├── PtrHelper.cs │ │ ├── ServiceLocatorHelper.cs │ │ ├── SnapLayoutHelper.cs │ │ ├── StaticHelper.cs │ │ ├── WindowHelper.cs │ │ ├── WindowsAccentHelper.cs │ │ └── WindowsThemeHelper.cs │ ├── Interop │ │ ├── InteropMethods.cs │ │ └── InteropValues.cs │ ├── MicaWPF.Core.csproj │ ├── Models │ │ ├── AccentColors.cs │ │ ├── BackdropEnabledWindow.cs │ │ ├── EventIdentifier.cs │ │ └── Glyph.cs │ ├── ReadmeNuget.md │ ├── Services │ │ ├── AccentColorService.cs │ │ ├── IAccentColorService.cs │ │ ├── IThemeDictionaryService.cs │ │ ├── IThemeService.cs │ │ ├── MicaWPFServiceUtility.cs │ │ ├── ThemeDictionaryService.cs │ │ └── ThemeService.cs │ ├── Styles │ │ ├── Assets │ │ │ └── Accent.xaml │ │ ├── Controls │ │ │ ├── Dark │ │ │ │ └── GradientBorder.xaml │ │ │ └── Light │ │ │ │ └── GradientBorder.xaml │ │ ├── MicaWindow.xaml │ │ ├── ThemeDictionaryBase.cs │ │ └── Themes │ │ │ ├── MicaDark.xaml │ │ │ └── MicaLight.xaml │ └── Symbols │ │ └── FluentSystemIcons.cs ├── MicaWPF.Demo │ ├── MicaWPF.Demo.sln │ ├── MicaWPF.Demo │ │ ├── App.xaml │ │ ├── App.xaml.cs │ │ ├── AssemblyInfo.cs │ │ ├── MainWindow.xaml │ │ ├── MainWindow.xaml.cs │ │ └── MicaWPF.Demo.csproj │ └── README.md ├── MicaWPF.DependencyInjection │ ├── Helpers │ │ └── DependencyInjectionHelper.cs │ ├── MicaWPF.DependencyInjection.csproj │ ├── Options │ │ └── MicaWPFOptions.cs │ └── Services │ │ ├── AccentColorServiceDI.cs │ │ └── ThemeServiceDI.cs ├── MicaWPF.Lite │ ├── AssemblyInfo.cs │ ├── Controls │ │ └── MicaWindow.cs │ ├── MicaWPF.Lite.csproj │ └── Styles │ │ ├── ControlsDictionary.cs │ │ ├── MicaWPF.Lite.xaml │ │ └── ThemeDictionary.cs └── MicaWPF │ ├── AssemblyInfo.cs │ ├── Controls │ ├── AnimatedScrollBar.cs │ ├── AnimatedScrollViewer.cs │ ├── Arc.cs │ ├── Button.cs │ ├── ColumnDefinitionExtended.cs │ ├── Frame.cs │ ├── MenuListViewItem.cs │ ├── MicaWindow.cs │ ├── PasswordBox.cs │ ├── ProgressRing.cs │ ├── RichSelectableLabel.cs │ ├── SelectableLabel.cs │ ├── SymbolIcon.cs │ ├── TextBox.cs │ └── ToggleSwitch.cs │ ├── Dialogs │ ├── ContentDialog.cs │ ├── DefaultContentDialog.xaml │ ├── DefaultContentDialog.xaml.cs │ ├── DefaultDialogWindow.xaml │ ├── DefaultDialogWindow.xaml.cs │ └── IContentDialog.cs │ ├── Fonts │ ├── FluentSystemIcons-Filled.ttf │ ├── FluentSystemIcons-Regular.ttf │ └── SegUIVar.ttf │ ├── Helpers │ ├── WinRTHelper.cs │ └── WindowsAccentHelperWinRT.cs │ ├── MicaWPF.csproj │ ├── ReadmeNuget.md │ ├── Services │ └── AccentColorServiceWinRT.cs │ └── Styles │ ├── Assets │ └── Fonts.xaml │ ├── Controls │ ├── AnimatedScrollBar.xaml │ ├── AnimatedScrollViewer.xaml │ ├── Button.xaml │ ├── ComboBox.xaml │ ├── ContextMenu.xaml │ ├── DataGrid.xaml │ ├── Expander.xaml │ ├── FocusVisualStyle.xaml │ ├── Label.xaml │ ├── ListView.xaml │ ├── MenuListViewItem.xaml │ ├── PasswordBox.xaml │ ├── ProgressBar.xaml │ ├── ProgressRing.xaml │ ├── RichSelectableLabel.xaml │ ├── RichTextBox.xaml │ ├── ScrollBar.xaml │ ├── ScrollViewer.xaml │ ├── SelectableLabel.xaml │ ├── SymbolIcon.xaml │ ├── TextBox.xaml │ ├── ToggleSwitch.xaml │ ├── Tooltip.xaml │ └── VisualStates │ │ ├── Common_Animations.xaml │ │ ├── Dark │ │ └── Button.xaml │ │ └── Light │ │ └── Button.xaml │ ├── ControlsDictionary.cs │ ├── MicaWPF.xaml │ ├── ThemeDictionary.cs │ └── Themes │ ├── MicaDark.xaml │ └── MicaLight.xaml └── stylecop.json /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.yaml: -------------------------------------------------------------------------------- 1 | name: Bug Report 2 | description: File a bug report 3 | title: "[Bug]: " 4 | labels: ["bug", "Needs-Triage"] 5 | assignees: 6 | - Simnico99 7 | body: 8 | - type: textarea 9 | validations: 10 | required: true 11 | attributes: 12 | label: Describe the bug 13 | description: Please enter a short, clear description of the bug. 14 | - type: textarea 15 | validations: 16 | required: true 17 | attributes: 18 | label: Steps to reproduce the bug 19 | description: Please provide any required setup and steps to reproduce the behavior. 20 | placeholder: | 21 | 1. Go to '...' 22 | 2. Click on '....' 23 | - type: textarea 24 | attributes: 25 | label: Expected behavior 26 | description: Please provide a description of what you expected to happen 27 | - type: textarea 28 | attributes: 29 | label: Screenshots 30 | description: If applicable, add screenshots here to help explain your problem 31 | - type: dropdown 32 | validations: 33 | required: true 34 | attributes: 35 | label: Windows version 36 | description: Which Windows versions did you see the issue on? 37 | multiple: true 38 | options: 39 | - "Insider Build (xxxxx)" 40 | - "Windows 11 version 23H2 (22631, 2023 Update)" 41 | - "Windows 11 version 22H2 (22621, 2022 Update)" 42 | - "Windows 11 version 21H2 (22000)" 43 | - "Windows 10 version 22H2 (19045, 2022 Update)" 44 | - "Windows 10 version 21H2 (19044, November 2021 Update)" 45 | - "Windows 10 version 21H1 (19043, May 2021 Update)" 46 | - "Windows 10 version 20H2 (19042, October 2020 Update)" 47 | - "Windows 10 version 2004 (19041, May 2020 Update)" 48 | - "Windows 10 version 1909 (18363, November 2019 Update)" 49 | - "Windows 10 version 1903 (18362, May 2019 Update)" 50 | - "Windows 10 version 1809 (17763, October 2018 Update)" 51 | - "Other (Please add the version in additionnal context.)" 52 | - type: dropdown 53 | validations: 54 | required: true 55 | attributes: 56 | label: .Net Version 57 | description: Which Version of .Net are you using? 58 | multiple: true 59 | options: 60 | - ".Net Framework 4.6.x" 61 | - ".Net Framework 4.7.x" 62 | - ".Net Framework 4.8.x" 63 | - ".NET Standard 1.x" 64 | - ".NET Standard 2.x" 65 | - ".NET Core 1.x" 66 | - ".NET Core 2.x" 67 | - ".NET Core 3.x" 68 | - ".NET 5.x" 69 | - ".NET 6.x" 70 | - ".NET 7.x" 71 | - ".NET 8.x" 72 | - "Other (Please add the version in additionnal context.)" 73 | - type: dropdown 74 | validations: 75 | required: true 76 | attributes: 77 | label: .MicaWPF Version 78 | description: Which version lite or not of MicaWPF you are using? 79 | multiple: true 80 | options: 81 | - "MicaWPF" 82 | - "MicaWPF.Lite" 83 | - type: textarea 84 | attributes: 85 | label: Additional context 86 | description: Enter any other applicable info here 87 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.yaml: -------------------------------------------------------------------------------- 1 | name: Feature request 2 | description: Suggest an idea for this project 3 | title: "[Feature Request]: " 4 | labels: ["enhancement", "Needs-Triage"] 5 | assignees: 6 | - Simnico99 7 | body: 8 | - type: textarea 9 | validations: 10 | required: true 11 | attributes: 12 | label: Describe the solution you'd like 13 | description: A clear and concise description of what you want to happen. 14 | - type: textarea 15 | attributes: 16 | label: Is your feature request related to a problem? Please describe. 17 | description: A clear and concise description of what the problem is. Ex. I'm always frustrated when 18 | - type: textarea 19 | attributes: 20 | label: Describe alternatives you've considered 21 | description: A clear and concise description of any alternative solutions or features you've considered. 22 | - type: textarea 23 | attributes: 24 | label: Additional context 25 | description: Enter any other applicable info here. 26 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | # Description 2 | 3 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change. 4 | 5 | Fixes # (issue) 6 | 7 | ## Type of change 8 | 9 | Please delete options that are not relevant. 10 | 11 | - [ ] Bug fix (non-breaking change which fixes an issue) 12 | - [ ] New feature (non-breaking change which adds functionality) 13 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) 14 | - [ ] This change requires a documentation update 15 | 16 | # How Has This Been Tested? 17 | 18 | Please describe the tests that you ran to verify your changes. Provide instructions so we can reproduce. Please also list any relevant details for your test configuration. 19 | - [ ] Test A 20 | - [ ] Test B 21 | 22 | # Checklist: 23 | 24 | - [ ] My code follows the style guidelines of this project 25 | - [ ] I have performed a self-review of my own code 26 | - [ ] I have commented my code, particularly in hard-to-understand areas 27 | - [ ] I have made corresponding changes to the documentation 28 | - [ ] My changes generate no new warnings 29 | - [ ] I have added tests that prove my fix is effective or that my feature works 30 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "nuget" 4 | directories: 5 | - "/src/MicaWPF" 6 | - "/src/MicaWPF.Core" 7 | - "/src/MicaWPF.Lite" 8 | - "/src/MicaWPF.DependencyInjection" 9 | schedule: 10 | interval: "daily" 11 | reviewers: 12 | - "Simnico99" 13 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Contributions are what make the open source community such an amazing place to be learn, inspire, and create. Any contributions you make are **greatly appreciated**. 4 | 5 | 1. Fork the Project 6 | 2. Create your Feature Branch (`git checkout -b feature/AmazingFeature`) 7 | 3. Commit your Changes (`git commit -m 'Add some AmazingFeature'`) 8 | 4. Push to the Branch (`git push origin feature/AmazingFeature`) 9 | 5. Open a Pull Request 10 | -------------------------------------------------------------------------------- /FUNDING.yml: -------------------------------------------------------------------------------- 1 | github: [Simnico99] 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Simnico99 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Logo/MicaWPFLogo - 128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Simnico99/MicaWPF/eac144580274d06161c354442fa1c07784ae05e4/Logo/MicaWPFLogo - 128x128.png -------------------------------------------------------------------------------- /Logo/MicaWPFLogo - 178x178.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Simnico99/MicaWPF/eac144580274d06161c354442fa1c07784ae05e4/Logo/MicaWPFLogo - 178x178.png -------------------------------------------------------------------------------- /Logo/MicaWPFLogo - 80x56.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Simnico99/MicaWPF/eac144580274d06161c354442fa1c07784ae05e4/Logo/MicaWPFLogo - 80x56.png -------------------------------------------------------------------------------- /ReadmeNuget.md: -------------------------------------------------------------------------------- 1 | https://github.com/Simnico99/MicaWPF -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Supported Versions 4 | 5 | We release patches for security vulnerabilities. Which versions are eligible for receiving such patches depends on the CVSS v3.0 Rating: 6 | 7 | | Version | Supported | 8 | | ------- | ------------------ | 9 | | 6.x.x | :white_check_mark: | 10 | 11 | ## Reporting a Vulnerability 12 | Go to the security tab and click on the report security vulnerability button. 13 | -------------------------------------------------------------------------------- /azure-pipelines.yml: -------------------------------------------------------------------------------- 1 | # .NET Desktop 2 | # Build and run tests for .NET Desktop or Windows classic desktop solutions. 3 | # Add steps that publish symbols, save build artifacts, and more: 4 | # https://docs.microsoft.com/azure/devops/pipelines/apps/windows/dot-net 5 | 6 | trigger: 7 | tags: 8 | include: 9 | - "*" 10 | branches: 11 | include: 12 | - "*" 13 | 14 | variables: 15 | solution: '**/*.sln' 16 | buildPlatform: 'Any CPU' 17 | buildConfiguration: 'Release' 18 | buildNumber: $[ variables['Build.BuildNumber'] ] 19 | buildTag: $[ startsWith(variables['Build.SourceBranch'], 'refs/tags') ] 20 | 21 | jobs: 22 | - job: "Windows_Build" 23 | pool: 24 | vmImage: 'windows-2022' 25 | condition: | 26 | not( 27 | or ( 28 | eq(variables['Build.SourceBranch'], 'refs/heads/main'), 29 | eq(variables['buildTag'], True) 30 | ) 31 | ) 32 | steps: 33 | - template: azure/build.yml 34 | 35 | - job: "Windows_deploy" 36 | pool: 37 | vmImage: "windows-2022" 38 | condition: | 39 | and ( 40 | succeeded(), 41 | or ( 42 | eq(variables['Build.SourceBranch'], 'refs/heads/main'), 43 | eq(variables['buildTag'], True) 44 | ) 45 | ) 46 | steps: 47 | - template: azure/build.yml 48 | - template: azure/deploy.yml 49 | -------------------------------------------------------------------------------- /azure/build.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - pwsh: | 3 | $url = "https://azuresearch-usnc.nuget.org/query?q=MicaWPF&prerelease=false" 4 | $packageInfo = Invoke-RestMethod -Uri $url -Headers @{Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"} 5 | Write-Host "Pipeline = $($packageInfo | ConvertTo-Json -Depth 100)" 6 | $versionList; 7 | foreach ($versionlocal in $packageInfo.data.versions) 8 | { 9 | $versionList += [version[]]$versionlocal.version 10 | } 11 | $sortedVersions = $versionList | Sort-Object -Descending | foreach {$_.ToString()} 12 | $version = $sortedVersions[0] 13 | Write-Host $version 14 | $productVersionBeta = “$version.$(Build.BuildId)-Beta” 15 | Write-Host "##vso[task.setvariable variable=packageVersion]$productVersionBeta" 16 | Write-Host $productVersionBeta 17 | displayName: "Computing alpha version" 18 | condition: eq(variables['buildTag'], False) 19 | 20 | - pwsh: | 21 | $tags = git tag --sort=-creatordate 22 | [string] $tag = $tags[0] 23 | Write-Host "##vso[task.setvariable variable=packageVersion]$tag" 24 | Write-Host $tag 25 | displayName: "Computing release version" 26 | condition: eq(variables['buildTag'], True) 27 | 28 | - task: NuGetToolInstaller@1 29 | displayName: 'Installing Nuget 6.x' 30 | inputs: 31 | versionSpec: '6.x' 32 | 33 | - pwsh: | 34 | Write-Host Downloading .Net Framework 4.8.1 35 | Start-BitsTransfer -Source 'https://go.microsoft.com/fwlink/?linkid=2203306' -Destination "C:\Net4.8.1.exe" 36 | Write-Host Installing .Net Framework 4.8.1 37 | Start-Process "C:\Net4.8.1.exe" -ArgumentList "/q", "/norestart", "/install" -wait 38 | Write-Host Installed .Net Framework 4.8.1 39 | displayName: "Use .Net Framework 4.8.1" 40 | 41 | - task: UseDotNet@2 42 | displayName: 'Use .Net Core 3.1.x' 43 | inputs: 44 | packageType: 'sdk' 45 | version: '3.1.x' 46 | includePreviewVersions: false 47 | 48 | - task: UseDotNet@2 49 | displayName: 'Use .Net 6.0.x' 50 | inputs: 51 | packageType: 'sdk' 52 | version: '6.0.x' 53 | includePreviewVersions: false 54 | 55 | - task: UseDotNet@2 56 | displayName: 'Use .Net 7.0.x' 57 | inputs: 58 | packageType: 'sdk' 59 | version: '7.0.x' 60 | includePreviewVersions: false 61 | 62 | - task: UseDotNet@2 63 | displayName: 'Use .Net 8.0.x' 64 | inputs: 65 | packageType: 'sdk' 66 | version: '8.0.x' 67 | includePreviewVersions: false 68 | 69 | - task: UseDotNet@2 70 | displayName: 'Use .Net 9.0.x' 71 | inputs: 72 | packageType: 'sdk' 73 | version: '9.0.x' 74 | includePreviewVersions: false 75 | 76 | - task: DotNetCoreCLI@2 77 | displayName: .Net Restore 78 | inputs: 79 | command: 'restore' 80 | projects: '**\*!(Demo).csproj' 81 | 82 | - task: DotNetCoreCLI@2 83 | displayName: .Net Build 84 | inputs: 85 | command: 'build' 86 | configuration: Release 87 | projects: '**\*!(Demo).csproj' 88 | arguments: --no-restore -c release -p:FileVersionRevision=$(packageVersion) -p:ContinuousIntegrationBuild=true 89 | versioningScheme: byEnvVar 90 | versionEnvVar: '$(packageVersion)' -------------------------------------------------------------------------------- /azure/deploy.yml: -------------------------------------------------------------------------------- 1 | steps: 2 | - task: NuGetCommand@2 3 | displayName: Push to NuGet 4 | condition: and(succeeded(), eq(variables['buildTag'], true)) 5 | inputs: 6 | command: 'push' 7 | packagesToPush: '**/+(MicaWPF)*.nupkg;!**/*.symbols.nupkg;' 8 | nuGetFeedType: 'external' 9 | publishFeedCredentials: 'NugetConnection' -------------------------------------------------------------------------------- /src/MicaWPF.Core/Animations/BrushAnimation.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using System.Windows.Media; 7 | using System.Windows.Media.Animation; 8 | using MicaWPF.Core.Helpers; 9 | 10 | namespace MicaWPF.Core.Animations; 11 | 12 | /// 13 | /// Interpolation animation between 2 brushes. 14 | /// 15 | public sealed class BrushAnimation : AnimationTimeline 16 | { 17 | public static readonly DependencyProperty FromProperty = DependencyProperty.Register("From", typeof(Brush), typeof(BrushAnimation)); 18 | public static readonly DependencyProperty ToProperty = DependencyProperty.Register("To", typeof(Brush), typeof(BrushAnimation)); 19 | 20 | /// 21 | /// Gets or sets brush to start the animation from. 22 | /// 23 | public Brush From 24 | { 25 | get => (Brush)GetValue(FromProperty); 26 | set => SetValue(FromProperty, value); 27 | } 28 | 29 | /// 30 | /// Gets or sets brush to end the animation to. 31 | /// 32 | public Brush To 33 | { 34 | get => (Brush)GetValue(ToProperty); 35 | set => SetValue(ToProperty, value); 36 | } 37 | 38 | public override Type TargetPropertyType => typeof(Brush); 39 | 40 | public override object GetCurrentValue(object defaultOriginValue, object defaultDestinationValue, AnimationClock animationClock) 41 | { 42 | return GetCurrentValue((Brush)defaultOriginValue, (Brush)defaultDestinationValue, animationClock); 43 | } 44 | 45 | /// 46 | /// Gets the current value of the animation. 47 | /// 48 | /// Origin brush. 49 | /// Destination brush. 50 | /// Animation Clock. 51 | /// The value this animation believes should be the current value for the property. 52 | public object GetCurrentValue(Brush defaultOriginValue, Brush defaultDestinationValue, AnimationClock animationClock) 53 | { 54 | if (!animationClock.CurrentProgress.HasValue) 55 | { 56 | return Brushes.Transparent; 57 | } 58 | 59 | defaultOriginValue = From ?? defaultOriginValue; 60 | defaultDestinationValue = To ?? defaultDestinationValue; 61 | 62 | if (animationClock.CurrentProgress.Value == 0) 63 | { 64 | return defaultOriginValue; 65 | } 66 | 67 | if (animationClock.CurrentProgress.Value == 1) 68 | { 69 | return defaultDestinationValue; 70 | } 71 | 72 | var colorOriginValue = ((SolidColorBrush)defaultOriginValue).Color; 73 | var colorDestinationValue = ((SolidColorBrush)defaultDestinationValue).Color; 74 | 75 | return new SolidColorBrush(ColorHelper.InterpolateBetween(colorOriginValue, colorDestinationValue, animationClock.CurrentProgress.Value)); 76 | } 77 | 78 | protected override Freezable CreateInstanceCore() 79 | { 80 | return new BrushAnimation(); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | 7 | [assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)] -------------------------------------------------------------------------------- /src/MicaWPF.Core/Controls/GradientBorder.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.ComponentModel; 6 | using System.Windows; 7 | using System.Windows.Controls; 8 | using System.Windows.Media; 9 | 10 | namespace MicaWPF.Core.Controls; 11 | 12 | /// 13 | /// A border that has a gradient based on the current theme. 14 | /// 15 | [ToolboxItem(true)] 16 | public class GradientBorder : UserControl 17 | { 18 | public static readonly DependencyProperty BottomBorderBrushProperty = DependencyProperty.Register(nameof(BottomBorderBrush), typeof(Brush), typeof(GradientBorder)); 19 | public static readonly DependencyProperty TopBorderBrushProperty = DependencyProperty.Register(nameof(TopBorderBrush), typeof(Brush), typeof(GradientBorder)); 20 | public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register(nameof(CornerRadius), typeof(CornerRadius), typeof(GradientBorder)); 21 | 22 | public Brush? TopBorderBrush 23 | { 24 | get => (Brush)GetValue(BottomBorderBrushProperty); 25 | set => SetValue(BottomBorderBrushProperty, value); 26 | } 27 | 28 | public Brush? BottomBorderBrush 29 | { 30 | get => (Brush)GetValue(BottomBorderBrushProperty); 31 | set => SetValue(BottomBorderBrushProperty, value); 32 | } 33 | 34 | public CornerRadius? CornerRadius 35 | { 36 | get => (CornerRadius)GetValue(BottomBorderBrushProperty); 37 | set => SetValue(BottomBorderBrushProperty, value); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Controls/IButton.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using MicaWPF.Core.Symbols; 7 | 8 | namespace MicaWPF.Core.Controls; 9 | 10 | /// 11 | /// Represents the contract for a button control in a Fluent UI, defining properties for customizing its appearance. 12 | /// 13 | public interface IButton 14 | { 15 | /// 16 | /// Gets or sets the CornerRadius of the button. This determines the roundness of the button's corners. 17 | /// 18 | CornerRadius CornerRadius { get; set; } 19 | 20 | /// 21 | /// Gets or sets the icon of the button from the FluentSystemIcons.Regular set. 22 | /// This icon will be displayed inside the button. 23 | /// 24 | FluentSystemIcons.Regular Icon { get; set; } 25 | 26 | /// 27 | /// Gets or sets a value indicating whether the icon of the button is filled. 28 | /// When set to true, the icon will be displayed as filled; otherwise, it will be displayed as outlined. 29 | /// 30 | bool IconFilled { get; set; } 31 | } 32 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Controls/MicaWindow/IMicaWindow.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using System.Windows.Shell; 7 | using MicaWPF.Core.Enums; 8 | 9 | namespace MicaWPF.Core.Controls.MicaWindow; 10 | 11 | /// 12 | /// Defines the interface for a Mica-styled Window in WPF, which allows customization of the window's appearance and behavior. 13 | /// 14 | public interface IMicaWindow 15 | { 16 | /// 17 | /// Gets or sets a value indicating whether the title color of the window changes when the window becomes inactive. 18 | /// 19 | /// A boolean value indicating whether the window's title color changes when inactive. 20 | bool ChangeTitleColorWhenInactive { get; set; } 21 | 22 | /// 23 | /// Gets or sets the content of the title bar of the window. 24 | /// This allows for customization of the title bar with any UI elements. 25 | /// 26 | /// The UIElement that represents the content of the title bar. 27 | UIElement TitleBarContent { get; set; } 28 | 29 | /// 30 | /// Gets or sets the height of the title bar of the window. 31 | /// 32 | /// An integer value representing the height of the title bar in device-independent units (1/96th inch per unit). 33 | int TitleBarHeight { get; set; } 34 | 35 | /// 36 | /// Gets or sets a value indicating whether the accent color should be applied to the title bar and the border of the window. 37 | /// 38 | /// A boolean value indicating whether the accent color is used on the title bar and the border of the window. 39 | bool UseAccentOnTitleBarAndBorder { get; set; } 40 | 41 | /// 42 | /// Gets or sets the current backdrop type of the window. 43 | /// 44 | BackdropType SystemBackdropType { get; set; } 45 | 46 | /// 47 | /// Gets or sets the title bar type of the window (WinUI or Win32). 48 | /// 49 | TitleBarType TitleBarType { get; set; } 50 | 51 | /// 52 | /// Gets or sets a custom WindowChrom for the MicaWindow. 53 | /// 54 | WindowChrome CustomWindowChrome { get; set; } 55 | 56 | /// 57 | /// Ends the initialization of a window that is created using markup. This method is called by the markup parser. 58 | /// 59 | void EndInit(); 60 | 61 | /// 62 | /// Builds the current template's visual tree if necessary, and returns a value that indicates whether the visual tree was rebuilt by this call. 63 | /// 64 | void OnApplyTemplate(); 65 | } 66 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Controls/MicaWindow/MicaWindowActionHandler.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using System.Windows.Input; 7 | 8 | namespace MicaWPF.Core.Controls.MicaWindow; 9 | 10 | public class MicaWindowActionHandler : MicaWindowInteropHandler 11 | { 12 | public MicaWindowActionHandler() 13 | : base() 14 | { 15 | _ = CommandBindings.Add(new CommandBinding(SystemCommands.CloseWindowCommand, OnCloseWindow)); 16 | _ = CommandBindings.Add(new CommandBinding(SystemCommands.MaximizeWindowCommand, OnMaximizeWindow, OnCanResizeWindow)); 17 | _ = CommandBindings.Add(new CommandBinding(SystemCommands.MinimizeWindowCommand, OnMinimizeWindow, OnCanMinimizeWindow)); 18 | _ = CommandBindings.Add(new CommandBinding(SystemCommands.RestoreWindowCommand, OnRestoreWindow, OnCanResizeWindow)); 19 | } 20 | 21 | private void OnCanResizeWindow(object target, CanExecuteRoutedEventArgs e) 22 | { 23 | e.CanExecute = ResizeMode is ResizeMode.CanResize or ResizeMode.CanResizeWithGrip; 24 | } 25 | 26 | private void OnCanMinimizeWindow(object target, CanExecuteRoutedEventArgs e) 27 | { 28 | e.CanExecute = ResizeMode != ResizeMode.NoResize; 29 | } 30 | 31 | private void OnCloseWindow(object target, ExecutedRoutedEventArgs e) 32 | { 33 | SystemCommands.CloseWindow(this); 34 | } 35 | 36 | private void OnMaximizeWindow(object target, ExecutedRoutedEventArgs e) 37 | { 38 | SystemCommands.MaximizeWindow(this); 39 | } 40 | 41 | private void OnMinimizeWindow(object target, ExecutedRoutedEventArgs e) 42 | { 43 | SystemCommands.MinimizeWindow(this); 44 | } 45 | 46 | private void OnRestoreWindow(object target, ExecutedRoutedEventArgs e) 47 | { 48 | SystemCommands.RestoreWindow(this); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Controls/MicaWindow/MicaWindowBase.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using System.Windows.Shell; 7 | using MicaWPF.Core.Extensions; 8 | 9 | namespace MicaWPF.Core.Controls.MicaWindow; 10 | 11 | public class MicaWindowBase : MicaWindowActionHandler, IMicaWindow 12 | { 13 | public MicaWindowBase() 14 | : base() 15 | { 16 | CustomWindowChrome.CaptionHeight = TitleBarHeight - 7; 17 | CustomWindowChrome.CornerRadius = new CornerRadius(8); 18 | CustomWindowChrome.GlassFrameThickness = new Thickness(-1); 19 | WindowChrome.SetWindowChrome(this, CustomWindowChrome); 20 | } 21 | 22 | public override void OnApplyTemplate() 23 | { 24 | ButtonMax = GetTemplateChild(_buttonMaxName) as System.Windows.Controls.Button; 25 | ButtonRestore = GetTemplateChild(_buttonRestoreName) as System.Windows.Controls.Button; 26 | 27 | base.OnApplyTemplate(); 28 | } 29 | 30 | public override void EndInit() 31 | { 32 | AddPadding(WindowState); 33 | ApplyResizeBorderThickness(WindowState); 34 | 35 | base.EndInit(); 36 | } 37 | 38 | protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e) 39 | { 40 | if (e.Property.Name is nameof(WindowState)) 41 | { 42 | AddPadding((WindowState)e.NewValue); 43 | ApplyResizeBorderThickness((WindowState)e.NewValue); 44 | } 45 | 46 | if (e.Property.Name is nameof(IsActive)) 47 | { 48 | this.UpdateBorderColor(); 49 | } 50 | 51 | base.OnPropertyChanged(e); 52 | } 53 | 54 | protected override void OnSourceInitialized(EventArgs e) 55 | { 56 | base.OnSourceInitialized(e); 57 | this.EnableBackdrop(SystemBackdropType); 58 | this.UpdateBorderColor(); 59 | } 60 | 61 | private void AddPadding(WindowState windowsState) 62 | { 63 | MarginMaximized = windowsState == WindowState.Maximized ? new Thickness(6) : new Thickness(0); 64 | } 65 | 66 | private void ApplyResizeBorderThickness(WindowState windowsState) 67 | { 68 | if (windowsState == WindowState.Maximized || ResizeMode == ResizeMode.NoResize) 69 | { 70 | CustomWindowChrome.ResizeBorderThickness = new Thickness(0); 71 | } 72 | else 73 | { 74 | CustomWindowChrome.ResizeBorderThickness = new Thickness(6); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Controls/MicaWindow/MicaWindowProperty.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using System.Windows.Media; 7 | using System.Windows.Shell; 8 | using MicaWPF.Core.Enums; 9 | using MicaWPF.Core.Services; 10 | 11 | namespace MicaWPF.Core.Controls.MicaWindow; 12 | 13 | public class MicaWindowProperty : MicaWindowStyle 14 | { 15 | public static readonly DependencyProperty CustomWindowChromeProperty = DependencyProperty.Register(nameof(CustomWindowChrome), typeof(WindowChrome), typeof(MicaWindowStyle)); 16 | public static readonly DependencyProperty TitleBarContentProperty = DependencyProperty.Register(nameof(TitleBarContent), typeof(UIElement), typeof(MicaWindowStyle)); 17 | public static readonly DependencyProperty UseAccentOnTitleBarAndBorderProperty = DependencyProperty.Register(nameof(UseAccentOnTitleBarAndBorder), typeof(bool), typeof(MicaWindowStyle), new UIPropertyMetadata(MicaWPFServiceUtility.HasBeenInitialized && MicaWPFServiceUtility.AccentColorService.IsTitleBarAndWindowsBorderColored)); 18 | public static readonly DependencyProperty ChangeTitleColorWhenInactiveProperty = DependencyProperty.Register(nameof(ChangeTitleColorWhenInactive), typeof(bool), typeof(MicaWindowStyle), new UIPropertyMetadata(true)); 19 | public static readonly DependencyProperty TitleBarHeightProperty = DependencyProperty.Register(nameof(TitleBarHeight), typeof(int), typeof(MicaWindowStyle), new UIPropertyMetadata(34)); 20 | public static readonly DependencyProperty TitleBarTypeProperty = DependencyProperty.Register(nameof(TitleBarType), typeof(TitleBarType), typeof(MicaWindowStyle), new UIPropertyMetadata(TitleBarType.WinUI)); 21 | public static readonly DependencyProperty TitleBarBrushProperty = DependencyProperty.Register(nameof(TitleBarBrush), typeof(Brush), typeof(MicaWindowStyle)); 22 | public static readonly DependencyProperty MarginMaximizedProperty = DependencyProperty.Register(nameof(MarginMaximized), typeof(Thickness), typeof(MicaWindowStyle)); 23 | 24 | public MicaWindowProperty() 25 | : base() 26 | { 27 | CustomWindowChrome = new WindowChrome(); 28 | } 29 | 30 | public BackdropType SystemBackdropType { get; set; } = BackdropType.Mica; 31 | 32 | public int TitleBarHeight 33 | { 34 | get => (int)GetValue(TitleBarHeightProperty); 35 | set => SetValue(TitleBarHeightProperty, value); 36 | } 37 | 38 | public bool UseAccentOnTitleBarAndBorder 39 | { 40 | get => (bool)GetValue(UseAccentOnTitleBarAndBorderProperty); 41 | set => SetValue(UseAccentOnTitleBarAndBorderProperty, value); 42 | } 43 | 44 | public TitleBarType TitleBarType 45 | { 46 | get => (TitleBarType)GetValue(TitleBarTypeProperty); 47 | set => SetValue(TitleBarTypeProperty, value); 48 | } 49 | 50 | public bool ChangeTitleColorWhenInactive 51 | { 52 | get => (bool)GetValue(MarginMaximizedProperty); 53 | set => SetValue(MarginMaximizedProperty, value); 54 | } 55 | 56 | public UIElement TitleBarContent 57 | { 58 | get => (UIElement)GetValue(TitleBarContentProperty); 59 | set => SetValue(TitleBarContentProperty, value); 60 | } 61 | 62 | public Brush TitleBarBrush 63 | { 64 | get => (Brush)GetValue(TitleBarBrushProperty); 65 | set => SetValue(TitleBarBrushProperty, value); 66 | } 67 | 68 | public WindowChrome CustomWindowChrome 69 | { 70 | get => (WindowChrome)GetValue(CustomWindowChromeProperty); 71 | set => SetValue(CustomWindowChromeProperty, value); 72 | } 73 | 74 | /// 75 | /// Gets or sets if the margin maximized. 76 | /// 77 | internal Thickness? MarginMaximized 78 | { 79 | get => (Thickness)GetValue(MarginMaximizedProperty); 80 | set => SetValue(MarginMaximizedProperty, value); 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Controls/MicaWindow/MicaWindowStyle.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using MicaWPF.Core.Helpers; 7 | 8 | namespace MicaWPF.Core.Controls.MicaWindow; 9 | 10 | public class MicaWindowStyle : Window 11 | { 12 | static MicaWindowStyle() 13 | { 14 | if (OsHelper.IsWindows11_OrGreater) 15 | { 16 | DefaultStyleKeyProperty.OverrideMetadata(typeof(MicaWindowStyle), new FrameworkPropertyMetadata(typeof(MicaWindowStyle))); 17 | } 18 | } 19 | 20 | public MicaWindowStyle() 21 | { 22 | var myResourceDictionary = new ResourceDictionary 23 | { 24 | Source = new Uri($"MicaWPF.Core;component/Styles/MicaWindow.xaml", UriKind.RelativeOrAbsolute), 25 | }; 26 | 27 | Style = OsHelper.IsWindows11_OrGreater 28 | ? myResourceDictionary[$"MicaWPF.Core.Styles.Default.MicaWindow.Windows11"] as Style 29 | : myResourceDictionary[$"MicaWPF.Core.Styles.Default.MicaWindow.Windows10"] as Style; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Converters/BrushToColorConverter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Globalization; 6 | using System.Windows.Data; 7 | using System.Windows.Media; 8 | 9 | namespace MicaWPF.Core.Converters; 10 | 11 | public sealed class BrushToColorConverter : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 14 | { 15 | if (value is SolidColorBrush brush) 16 | { 17 | return Color.FromArgb((byte)(brush.Opacity * brush.Color.A), brush.Color.R, brush.Color.G, brush.Color.B); 18 | } 19 | 20 | if (value is Color) 21 | { 22 | return value; 23 | } 24 | 25 | // We draw red to visibly see an invalid bind in the UI. 26 | return new Color { A = 255, R = 255, G = 0, B = 0 }; 27 | } 28 | 29 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 30 | { 31 | throw new NotImplementedException(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Converters/DialogScrollViewerHeightConverter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows.Data; 6 | 7 | namespace MicaWPF.Core.Converters; 8 | 9 | public sealed class DialogScrollViewerHeightConverter : IValueConverter 10 | { 11 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 12 | { 13 | return value is double height ? height - 100 : (object)500; 14 | } 15 | 16 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 17 | { 18 | throw new NotImplementedException(); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Converters/IconNotEmptyConverter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows.Data; 6 | using MicaWPF.Core.Symbols; 7 | 8 | namespace MicaWPF.Core.Converters; 9 | 10 | public sealed class IconNotEmptyConverter : IValueConverter 11 | { 12 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 13 | { 14 | return value is FluentSystemIcons.Regular icon ? icon != FluentSystemIcons.Regular.Empty : (object)false; 15 | } 16 | 17 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 18 | { 19 | throw new NotImplementedException(); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Converters/IsNullConverter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows.Data; 6 | 7 | namespace MicaWPF.Core.Converters; 8 | 9 | /// 10 | /// Null to bool. 11 | /// 12 | public sealed class IsNullConverter : IValueConverter 13 | { 14 | public object? Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 15 | { 16 | return (value != null && value.ToString() == string.Empty) || value is null; 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Converters/ObjectToSymbolConverter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows.Data; 6 | using MicaWPF.Core.Extensions; 7 | using MicaWPF.Core.Symbols; 8 | 9 | namespace MicaWPF.Core.Converters; 10 | 11 | public sealed class ObjectToSymbolConverter : IValueConverter 12 | { 13 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 14 | { 15 | return value is FluentSystemIcons.Regular symbol 16 | ? symbol 17 | : value is FluentSystemIcons.Filled symbolFilled ? symbolFilled.Swap() : (object)FluentSystemIcons.Regular.Empty; 18 | } 19 | 20 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 21 | { 22 | throw new NotImplementedException(); 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Converters/ProgressThicknessConverter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows.Data; 6 | 7 | namespace MicaWPF.Core.Converters; 8 | 9 | /// 10 | /// Converts the current double to a thickness value for the . 11 | /// 12 | public sealed class ProgressThicknessConverter : IValueConverter 13 | { 14 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 15 | { 16 | return value is double height ? height / 11 : (object)12.0d; 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Converters/TextToAsteriskConverter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows.Data; 6 | 7 | namespace MicaWPF.Core.Converters; 8 | 9 | /// 10 | /// Converts the current text to asterisks. 11 | /// 12 | public sealed class TextToAsteriskConverter : IValueConverter 13 | { 14 | public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 15 | { 16 | return new string('*', value?.ToString()?.Length ?? 0); 17 | } 18 | 19 | public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 20 | { 21 | throw new NotImplementedException(); 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Enums/AccentBrushType.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Enums; 6 | 7 | /// 8 | /// The type of accent brush. 9 | /// 10 | public enum AccentBrushType 11 | { 12 | Primary, 13 | Secondary, 14 | Tertiary, 15 | Quaternary, 16 | } 17 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Enums/BackdropType.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Enums; 6 | 7 | /// 8 | /// The type of backdrop used by a Window. 9 | /// 10 | public enum BackdropType 11 | { 12 | None = 1, 13 | Mica = 2, 14 | Acrylic = 3, 15 | Tabbed = 4, 16 | } 17 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Enums/ContentDialogButton.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Enums; 6 | 7 | /// 8 | /// The button that must be colored on the content dialog. 9 | /// 10 | public enum ContentDialogButton 11 | { 12 | Primary, 13 | Secondary, 14 | Close, 15 | } 16 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Enums/ContentDialogResult.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Enums; 6 | 7 | /// 8 | /// Results of a Content Dialog. 9 | /// 10 | public enum ContentDialogResult 11 | { 12 | PrimaryButton, 13 | SecondaryButton, 14 | TertiaryButton, 15 | Empty, 16 | } 17 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Enums/ElementPosition.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Enums; 6 | 7 | /// 8 | /// Element position. 9 | /// 10 | public enum ElementPosition 11 | { 12 | Left, 13 | Right, 14 | } 15 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Enums/RevealMode.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Enums; 6 | 7 | /// 8 | /// Is the password visible or not. 9 | /// 10 | public enum RevealMode 11 | { 12 | Hidden, 13 | Visible, 14 | } 15 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Enums/TitleBarType.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Enums; 6 | 7 | /// 8 | /// The type of title bar. 9 | /// 10 | public enum TitleBarType 11 | { 12 | Win32, 13 | WinUI, 14 | } 15 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Enums/WindowsTheme.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Enums; 6 | 7 | /// 8 | /// The theme used by Windows. 9 | /// 10 | public enum WindowsTheme 11 | { 12 | Light, 13 | Dark, 14 | Auto, 15 | } 16 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Events/ISubscription.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Events; 6 | 7 | /// 8 | /// A IWeakEvent subscription. 9 | /// 10 | public interface ISubscription 11 | { 12 | /// 13 | /// Dispose the Subsription. 14 | /// 15 | void Dispose(); 16 | } 17 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Events/IWeakEvent.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace MicaWPF.Core.Events; 8 | 9 | /// 10 | /// Represents a weak event that is less prone to memory leaks. 11 | /// 12 | /// The type of the argument that will be passed to the . 13 | public interface IWeakEvent 14 | { 15 | /// 16 | /// Asynchronously publishes the specified data to all subscribers. 17 | /// 18 | /// The data to publish. 19 | /// If set to true, this method will not complete until all event handlers have been invoked. Default is false. 20 | /// A that can be awaited until all event handlers have completed. 21 | ConfiguredTaskAwaitable PublishAsync(T data, bool awaitAllCalls = false); 22 | 23 | /// 24 | /// Publishes the specified data to all subscribers. 25 | /// 26 | /// The data to publish. 27 | void Publish(T data); 28 | 29 | /// 30 | /// Subscribes the specified action to this event. 31 | /// 32 | /// The action to be executed when the event is published. 33 | /// An which can be used to unsubscribe the action from the event. 34 | ISubscription Subscribe(Action action); 35 | } -------------------------------------------------------------------------------- /src/MicaWPF.Core/Events/Subscription.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Events; 6 | 7 | /// 8 | /// The action to perform when this subscription is disposed. 9 | /// 10 | internal sealed class Subscription : ISubscription 11 | { 12 | private readonly Action _removeMethod; 13 | 14 | /// 15 | /// Initializes a new instance of the class. 16 | /// 17 | /// The action to perform when this subscription is disposed. 18 | public Subscription(Action removeMethod) 19 | { 20 | _removeMethod = removeMethod; 21 | } 22 | 23 | /// 24 | public void Dispose() 25 | { 26 | if (_removeMethod is not null) 27 | { 28 | _removeMethod(); 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Events/WeakEvent.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace MicaWPF.Core.Events; 8 | 9 | /// 10 | /// Represents a weak event that is less prone to memory leaks. 11 | /// 12 | /// The type of the argument that will be passed to the . 13 | internal sealed class WeakEvent : IWeakEvent 14 | { 15 | #if NET9_0_OR_GREATER 16 | private readonly Lock _locker = new(); 17 | #else 18 | private readonly object _locker = new(); 19 | #endif 20 | 21 | private readonly List<(Type EventType, Delegate MethodToCall)> _eventRegistrations = []; 22 | 23 | /// 24 | public ISubscription Subscribe(Action action) 25 | { 26 | if (action is null) 27 | { 28 | #if NET5_0_OR_GREATER 29 | ArgumentNullException.ThrowIfNull(action); 30 | #else 31 | if (action is null) 32 | { 33 | throw new ArgumentNullException(nameof(action)); 34 | } 35 | #endif 36 | } 37 | 38 | _eventRegistrations.Add((typeof(T), action)); 39 | 40 | return new Subscription(() => 41 | { 42 | lock (_locker) 43 | { 44 | _ = _eventRegistrations.Remove((typeof(T), action)); 45 | } 46 | }); 47 | } 48 | 49 | /// 50 | public ConfiguredTaskAwaitable PublishAsync(T data, bool configureAwait = false) 51 | { 52 | return Task.Run(() => 53 | { 54 | lock (_locker) 55 | { 56 | foreach (var (eventType, methodToCall) in _eventRegistrations) 57 | { 58 | if (eventType == typeof(T)) 59 | { 60 | ((Action)methodToCall)(data); 61 | } 62 | } 63 | } 64 | }).ConfigureAwait(configureAwait); 65 | } 66 | 67 | /// 68 | public void Publish(T data) 69 | { 70 | _ = Task.Run(() => 71 | { 72 | lock (_locker) 73 | { 74 | foreach (var (eventType, methodToCall) in _eventRegistrations) 75 | { 76 | if (eventType == typeof(T)) 77 | { 78 | ((Action)methodToCall)(data); 79 | } 80 | } 81 | } 82 | }); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Extensions/ColorExtension.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows.Media; 6 | 7 | namespace MicaWPF.Core.Extensions; 8 | 9 | /// 10 | /// Extensions for . 11 | /// 12 | public static class ColorExtensions 13 | { 14 | /// 15 | /// Creates a from a . 16 | /// 17 | /// Input color. 18 | /// The converted color brush. 19 | public static SolidColorBrush ToBrush(this Color color) 20 | { 21 | return new SolidColorBrush(color); 22 | } 23 | 24 | /// 25 | /// Creates a from a with defined brush opacity. 26 | /// 27 | /// Input color. 28 | /// Degree of opacity. 29 | /// The converted color brush. 30 | public static SolidColorBrush ToBrush(this Color color, double opacity) 31 | { 32 | return new SolidColorBrush { Color = color, Opacity = opacity }; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Extensions/DependencyObjectExtension.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using System.Windows.Controls; 7 | using System.Windows.Media; 8 | 9 | namespace MicaWPF.Core.Extensions; 10 | 11 | /// 12 | /// Extensions for . 13 | /// 14 | public static class DependencyObjectExtension 15 | { 16 | /// 17 | /// Get all objects of a certain type in a (Visual only). 18 | /// 19 | /// 20 | /// A of the type of object specified. 21 | /// 22 | public static IEnumerable FindVisualChildren(this DependencyObject depObj) 23 | where T : DependencyObject 24 | { 25 | if (depObj == null) 26 | { 27 | yield break; 28 | } 29 | 30 | for (var i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++) 31 | { 32 | var child = VisualTreeHelper.GetChild(depObj, i); 33 | 34 | if (child is T t) 35 | { 36 | yield return t; 37 | } 38 | 39 | foreach (var childOfChild in FindVisualChildren(child)) 40 | { 41 | yield return childOfChild; 42 | } 43 | } 44 | } 45 | 46 | /// 47 | /// Get all objects of a certain type in a (Logical only). 48 | /// 49 | /// 50 | /// A of the type of object specified. 51 | /// 52 | public static IEnumerable FindLogicalChildren(this DependencyObject depObj) 53 | where T : DependencyObject 54 | { 55 | if (depObj != null) 56 | { 57 | foreach (var rawChild in LogicalTreeHelper.GetChildren(depObj)) 58 | { 59 | if (rawChild is not null) 60 | { 61 | if (rawChild is DependencyObject child) 62 | { 63 | if (child is T t) 64 | { 65 | yield return t; 66 | } 67 | 68 | foreach (var childOfChild in FindLogicalChildren(child)) 69 | { 70 | yield return childOfChild; 71 | } 72 | } 73 | } 74 | } 75 | } 76 | } 77 | 78 | /// 79 | /// Refresh the style of logical and visual children in a . 80 | /// 81 | public static void RefreshChildrenStyle(this DependencyObject depObj) 82 | { 83 | foreach (var element in depObj.FindLogicalChildren()) 84 | { 85 | if (element is Frame) 86 | { 87 | element.RefreshChildrenStyle(); 88 | } 89 | 90 | element.RefreshStyle(); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Extensions/FluentSystemIconsExtension.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using MicaWPF.Core.Models; 6 | using MicaWPF.Core.Symbols; 7 | 8 | namespace MicaWPF.Core.Extensions; 9 | 10 | /// 11 | /// Provides extension methods to work with Fluent System Icons. 12 | /// 13 | public static class FluentSystemIconsExtension 14 | { 15 | /// 16 | /// Converts a regular icon to a filled icon. 17 | /// 18 | /// The regular icon to convert. 19 | /// A filled icon. 20 | public static FluentSystemIcons.Filled Swap(this FluentSystemIcons.Regular icon) 21 | { 22 | return Glyph.ParseFilled(icon.ToString()); 23 | } 24 | 25 | /// 26 | /// Converts a filled icon to a regular icon. 27 | /// 28 | /// The filled icon to convert. 29 | /// A regular icon. 30 | public static FluentSystemIcons.Regular Swap(this FluentSystemIcons.Filled icon) 31 | { 32 | return Glyph.Parse(icon.ToString()); 33 | } 34 | 35 | /// 36 | /// Gets the glyph character for a regular icon. 37 | /// 38 | /// The regular icon. 39 | /// The glyph character. 40 | public static char GetGlyph(this FluentSystemIcons.Regular icon) 41 | { 42 | return ToChar(icon); 43 | } 44 | 45 | /// 46 | /// Gets the glyph character for a filled icon. 47 | /// 48 | /// The filled icon. 49 | /// The glyph character. 50 | public static char GetGlyph(this FluentSystemIcons.Filled icon) 51 | { 52 | return ToChar(icon); 53 | } 54 | 55 | /// 56 | /// Gets the glyph character as a string for a regular icon. 57 | /// 58 | /// The regular icon. 59 | /// The glyph character as a string. 60 | public static string GetString(this FluentSystemIcons.Regular icon) 61 | { 62 | return icon.GetGlyph().ToString(); 63 | } 64 | 65 | /// 66 | /// Gets the glyph character as a string for a filled icon. 67 | /// 68 | /// The filled icon. 69 | /// The glyph character as a string. 70 | public static string GetString(this FluentSystemIcons.Filled icon) 71 | { 72 | return icon.GetGlyph().ToString(); 73 | } 74 | 75 | private static char ToChar(FluentSystemIcons.Regular icon) 76 | { 77 | return Convert.ToChar(icon); 78 | } 79 | 80 | private static char ToChar(FluentSystemIcons.Filled icon) 81 | { 82 | return Convert.ToChar(icon); 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Extensions/FrameworkElementExtension.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | 7 | namespace MicaWPF.Core.Extensions; 8 | 9 | /// 10 | /// Extensions of . 11 | /// 12 | public static class FrameworkElementExtension 13 | { 14 | /// 15 | /// Refresh the style of the current element. 16 | /// 17 | public static void RefreshStyle(this FrameworkElement element) 18 | { 19 | lock (element) 20 | { 21 | var savedStyle = element.Style; 22 | element.Style = new(); 23 | 24 | element.UpdateDefaultStyle(); 25 | 26 | element.Style = savedStyle; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Extensions/MathExtension.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Extensions; 6 | 7 | /// 8 | /// Extensions of Int,Doubles,Etc... 9 | /// 10 | public static class MathExtension 11 | { 12 | /// 13 | /// Clamp the value to a minimum and maxmimum value. 14 | /// 15 | /// The clamped result. 16 | public static T Clamp(this T val, T min, T max) 17 | where T : struct, IComparable, IFormattable, IConvertible, IComparable, IEquatable 18 | { 19 | return val.CompareTo(min) < 0 ? min : val.CompareTo(max) > 0 ? max : val; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Extensions/WindowExtension.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using MicaWPF.Core.Enums; 7 | using MicaWPF.Core.Services; 8 | 9 | namespace MicaWPF.Core.Extensions; 10 | 11 | /// 12 | /// Extensions of and . 13 | /// 14 | public static class WindowExtension 15 | { 16 | /// 17 | /// Refresh the content of the entire . 18 | /// 19 | public static async Task RefreshContentAsync(this Window window) 20 | { 21 | await Application.Current.Dispatcher.InvokeAsync(() => window.RefreshChildrenStyle()); 22 | } 23 | 24 | /// 25 | /// Enable the backdrop on a . 26 | /// 27 | public static void EnableBackdrop(this Window window, BackdropType backdropType = BackdropType.Mica) 28 | { 29 | MicaWPFServiceUtility.ThemeService.EnableBackdrop(window, backdropType); 30 | } 31 | 32 | public static void UpdateBorderColor(this Window window) 33 | { 34 | MicaWPFServiceUtility.AccentColorService.IsTitleBarAndBorderAccentEnabled(window, MicaWPFServiceUtility.AccentColorService.IsTitleBarAndWindowsBorderColored); 35 | } 36 | } -------------------------------------------------------------------------------- /src/MicaWPF.Core/Helpers/ColorHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows.Media; 6 | 7 | namespace MicaWPF.Core.Helpers; 8 | 9 | /// 10 | /// An helper class to help with . 11 | /// 12 | public static class ColorHelper 13 | { 14 | private static readonly ComponentSelector _alphaSelector = color => color.A; 15 | private static readonly ComponentSelector _redSelector = color => color.R; 16 | private static readonly ComponentSelector _greenSelector = color => color.G; 17 | private static readonly ComponentSelector _blueSelector = color => color.B; 18 | 19 | private delegate byte ComponentSelector(Color color); 20 | 21 | /// 22 | /// Will interpolate between 2 colors. 23 | /// 24 | /// The interpolated . 25 | /// If lambda value is not between 0 or 1. 26 | public static Color InterpolateBetween( 27 | Color endPoint1, 28 | Color endPoint2, 29 | double lambda) 30 | { 31 | if (lambda is < 0 or > 1) 32 | { 33 | throw new ArgumentOutOfRangeException(nameof(lambda)); 34 | } 35 | 36 | var color = Color.FromArgb( 37 | InterpolateComponent(endPoint1, endPoint2, lambda, _alphaSelector), 38 | InterpolateComponent(endPoint1, endPoint2, lambda, _redSelector), 39 | InterpolateComponent(endPoint1, endPoint2, lambda, _greenSelector), 40 | InterpolateComponent(endPoint1, endPoint2, lambda, _blueSelector)); 41 | 42 | return color; 43 | } 44 | 45 | private static byte InterpolateComponent( 46 | Color endPoint1, 47 | Color endPoint2, 48 | double lambda, 49 | ComponentSelector selector) 50 | { 51 | return (byte)(selector(endPoint1) + ((selector(endPoint2) - selector(endPoint1)) * lambda)); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Helpers/DesignTimeHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.ComponentModel; 6 | using System.Windows; 7 | 8 | namespace MicaWPF.Core.Helpers; 9 | 10 | public static class DesignTimeHelper 11 | { 12 | public static bool IsDesignMode { get; } = DesignerProperties.GetIsInDesignMode(new DependencyObject()); 13 | } 14 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Helpers/HSVColorHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows.Media; 6 | 7 | namespace MicaWPF.Core.Helpers; 8 | 9 | /// 10 | /// An helper class to manipulate HSV Colors. 11 | /// 12 | public static class HSVColorHelper 13 | { 14 | /// 15 | /// Gets the entire color spectrum. 16 | /// 17 | /// The entire color. 18 | public static Color[] GetSpectrum() 19 | { 20 | var rgbs = new Color[360]; 21 | 22 | for (var h = 0; h < 360; h++) 23 | { 24 | rgbs[h] = RGBFromHSV(h, 1f, 1f); 25 | } 26 | 27 | return rgbs; 28 | } 29 | 30 | /// 31 | /// Gets the current hue spectrum from the saturation and value. 32 | /// 33 | /// Colors between the provided staturation and the provided value. 34 | public static Color[] HueSpectrum(double saturation, double value) 35 | { 36 | var rgbs = new Color[7]; 37 | 38 | for (var h = 0; h < 7; h++) 39 | { 40 | rgbs[h] = RGBFromHSV(h * 60, saturation, value); 41 | } 42 | 43 | return rgbs; 44 | } 45 | 46 | /// 47 | /// Convert HSV to RGB . 48 | /// 49 | /// Converted HSV color to RGB. 50 | public static Color RGBFromHSV(double h, double s, double v) 51 | { 52 | if (h > 360 || h < 0 || s > 1 || s < 0 || v > 1 || v < 0) 53 | { 54 | return Color.FromRgb(0, 0, 0); 55 | } 56 | 57 | var c = v * s; 58 | var x = c * (1 - Math.Abs(((h / 60) % 2) - 1)); 59 | var m = v - c; 60 | 61 | double r = 0, g = 0, b = 0; 62 | 63 | switch (h) 64 | { 65 | case < 60: 66 | r = c; 67 | g = x; 68 | break; 69 | case < 120: 70 | r = x; 71 | g = c; 72 | break; 73 | case < 180: 74 | g = c; 75 | b = x; 76 | break; 77 | case < 240: 78 | g = x; 79 | b = c; 80 | break; 81 | case < 300: 82 | r = x; 83 | b = c; 84 | break; 85 | case <= 360: 86 | r = c; 87 | b = x; 88 | break; 89 | } 90 | 91 | return Color.FromRgb((byte)((r + m) * 255), (byte)((g + m) * 255), (byte)((b + m) * 255)); 92 | } 93 | 94 | /// 95 | /// Convert a given to a HSV color (hue, saturation, value). 96 | /// 97 | /// The to convert. 98 | /// The hue [0°..360°], saturation [0..1] and value [0..1] of the converted color. 99 | public static (double Hue, double Saturation, double Value) ConvertToHSVColor(System.Drawing.Color color) 100 | { 101 | var min = Math.Min(Math.Min(color.R, color.G), color.B) / 255d; 102 | var max = Math.Max(Math.Max(color.R, color.G), color.B) / 255d; 103 | 104 | return (color.GetHue(), max == 0d ? 0d : (max - min) / max, max); 105 | } 106 | } 107 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Helpers/MathHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Helpers; 6 | 7 | /// 8 | /// Provides helper methods for mathematical operations. 9 | /// 10 | public static class MathHelper 11 | { 12 | /// 13 | /// Determines whether two specified double-precision floating-point numbers are close to each other, considering the values very small differences. 14 | /// 15 | /// The first double-precision floating-point number. 16 | /// The second double-precision floating-point number. 17 | /// true if the value of value1 is approximately equal to the value of value2; otherwise, false. 18 | public static bool AreClose(double value1, double value2) 19 | { 20 | return value1 == value2 || IsVerySmall(value1 - value2); 21 | } 22 | 23 | /// 24 | /// Determines whether the specified double-precision floating-point number is very small (less than 1E-06). 25 | /// 26 | /// The double-precision floating-point number. 27 | /// true if the value of the number is less than 1E-06; otherwise, false. 28 | public static bool IsVerySmall(double value) 29 | { 30 | return Math.Abs(value) < 1E-06; 31 | } 32 | 33 | /// 34 | /// Determines whether the first specified double-precision floating-point number is greater than the second specified double-precision floating-point number. 35 | /// 36 | /// The first double-precision floating-point number. 37 | /// The second double-precision floating-point number. 38 | /// true if the value of value1 is greater than the value of value2 and they are not approximately equal; otherwise, false. 39 | public static bool GreaterThan(double value1, double value2) 40 | { 41 | return value1 > value2 && !AreClose(value1, value2); 42 | } 43 | 44 | /// 45 | /// Determines whether the first specified double-precision floating-point number is less than the second specified double-precision floating-point number. 46 | /// 47 | /// The first double-precision floating-point number. 48 | /// The second double-precision floating-point number. 49 | /// true if the value of value1 is less than the value of value2 and they are not approximately equal; otherwise, false. 50 | public static bool LessThan(double value1, double value2) 51 | { 52 | return value1 < value2 && !AreClose(value1, value2); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Helpers/PtrHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Runtime.CompilerServices; 6 | 7 | namespace MicaWPF.Core.Helpers; 8 | 9 | #if NET7_0_OR_GREATER 10 | /// 11 | /// Provides helper methods and properties for working with native integers (nint). 12 | /// 13 | public static class PtrHelper 14 | { 15 | /// 16 | /// Gets the zero value for an IntPtr. 17 | /// 18 | public static nint Zero { get; } = nint.Zero; 19 | 20 | /// 21 | /// Creates a new native integer initialized to a specified value. 22 | /// 23 | /// The value to initialize the native integer with. 24 | /// A native integer initialized to the specified value. 25 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 26 | public static nint Create(int value) 27 | { 28 | return new nint(value); 29 | } 30 | } 31 | #else 32 | /// 33 | /// Provides helper methods and properties for working with IntPtr. 34 | /// 35 | public static class PtrHelper 36 | { 37 | /// 38 | /// Gets the zero value for an IntPtr. 39 | /// 40 | public static IntPtr Zero { get; } = IntPtr.Zero; 41 | 42 | /// 43 | /// Creates a new IntPtr initialized to a specified value. 44 | /// 45 | /// The value to initialize the IntPtr with. 46 | /// An IntPtr initialized to the specified value. 47 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 48 | public static IntPtr Create(int value) 49 | { 50 | return new IntPtr(value); 51 | } 52 | 53 | /// 54 | /// Converts the value of this instance to a 32-bit signed integer. 55 | /// 56 | /// The native integer to convert. 57 | /// A 32-bit signed integer equal to the value of this instance. 58 | [MethodImpl(MethodImplOptions.AggressiveInlining)] 59 | public static int ToInt32(this nint nintPtr) 60 | { 61 | var ptr = (IntPtr)nintPtr; 62 | return ptr.ToInt32(); 63 | } 64 | } 65 | 66 | #endif 67 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Helpers/ServiceLocatorHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Reflection; 6 | 7 | namespace MicaWPF.Core.Helpers; 8 | 9 | /// 10 | /// Provides utility methods to locate and instantiate services. 11 | /// 12 | internal static class ServiceLocatorHelper 13 | { 14 | private static readonly Assembly[] _assemblies = AppDomain.CurrentDomain.GetAssemblies(); 15 | 16 | /// 17 | /// Returns the namespace for the current MicaWPF assembly if lite is used or not. 18 | /// 19 | /// The current namespace. 20 | public static string GetNamespace() 21 | { 22 | return _assemblies.Any(x => x.GetName().Name == "MicaWPF") ? "MicaWPF" : "MicaWPF.Core"; 23 | } 24 | 25 | /// 26 | /// Attempts to locate and instantiate a service of the given type. 27 | /// 28 | /// The type of service to locate. 29 | /// The service instance. 30 | /// Thrown when the service cannot be found in any assembly. 31 | public static T GetService() 32 | where T : class 33 | { 34 | var serviceType = typeof(T); 35 | 36 | // Simplified assembly search with pattern matching 37 | var currentAssembly = _assemblies.FirstOrDefault(x => x.GetName().Name is "MicaWPF" or "MicaWPF.Lite"); 38 | 39 | if (currentAssembly?.GetName().Name == "MicaWPF.Lite") 40 | { 41 | currentAssembly = _assemblies.FirstOrDefault(x => x.GetName().Name is "MicaWPF.Core"); 42 | } 43 | 44 | if (currentAssembly is not null) 45 | { 46 | var instance = GetInstanceFromAssembly(currentAssembly, serviceType); 47 | if (instance is not null) 48 | { 49 | return instance; 50 | } 51 | } 52 | 53 | // Utilizing the 'Assembly.GetAssembly' method directly 54 | var fallbackAssembly = Assembly.GetAssembly(typeof(ServiceLocatorHelper)); 55 | var fallbackInstance = fallbackAssembly is not null ? GetInstanceFromAssembly(fallbackAssembly, serviceType) : null; 56 | 57 | return fallbackInstance ?? throw new InvalidOperationException($"{serviceType} wasn't found in any assembly."); 58 | } 59 | 60 | /// 61 | /// Attempts to create an instance of a specific type from the specified assembly. 62 | /// 63 | /// The type of instance to create. 64 | /// The assembly to create the instance from. 65 | /// The type of service. 66 | /// The created instance or null if it couldn't be created. 67 | private static T? GetInstanceFromAssembly(Assembly assembly, Type serviceType) 68 | where T : class 69 | { 70 | var typeInAssembly = assembly.GetTypes().FirstOrDefault(t => serviceType.IsAssignableFrom(t) && !t.IsInterface); 71 | 72 | return typeInAssembly is not null ? Activator.CreateInstance(typeInAssembly) as T : null; 73 | } 74 | } -------------------------------------------------------------------------------- /src/MicaWPF.Core/Helpers/SnapLayoutHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using Microsoft.Win32; 6 | 7 | namespace MicaWPF.Core.Helpers; 8 | 9 | /// 10 | /// Provides a helper method to determine if the Windows snap layout feature is enabled. 11 | /// 12 | public static class SnapLayoutHelper 13 | { 14 | private const string _registryKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced"; 15 | private const string _registryValueName = "EnableSnapAssistFlyout"; 16 | 17 | /// 18 | /// Determines whether the Windows snap layout feature is enabled. 19 | /// This is determined by checking a specific registry value. 20 | /// 21 | /// A boolean value indicating whether the Windows snap layout feature is enabled. 22 | public static bool IsSnapLayoutEnabled() 23 | { 24 | using var key = Registry.CurrentUser.OpenSubKey(_registryKeyPath); 25 | var registryValueObject = key?.GetValue(_registryValueName); 26 | 27 | if (registryValueObject == null) 28 | { 29 | return true; 30 | } 31 | 32 | var registryValue = (int)registryValueObject; 33 | 34 | return registryValue > 0; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Helpers/StaticHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Helpers; 6 | 7 | /// 8 | /// Provides a helper class for static methods. 9 | /// 10 | internal static class StaticHelper 11 | { 12 | /// 13 | /// Initializes a reference type with a specified . 14 | /// 15 | /// The type of the objects to initialize. 16 | /// The value to use for initialization. 17 | /// The reference to initialize. 18 | /// Thrown when the cache parameter is already initialized. 19 | public static void Init(T value, ref T cache) 20 | { 21 | if (cache is not null) 22 | { 23 | throw new InvalidOperationException("Cannot set the value more than once."); 24 | } 25 | 26 | cache = value; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Helpers/WindowHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using MicaWPF.Core.Extensions; 7 | 8 | namespace MicaWPF.Core.Helpers; 9 | 10 | public static class WindowHelper 11 | { 12 | /// 13 | /// Refreshes the contents of all the windows in the application asynchronously. 14 | /// 15 | public static async Task RefreshAllWindowsContentsAsync() 16 | { 17 | _ = await Application.Current.Dispatcher.InvokeAsync(async () => 18 | { 19 | foreach (var windowObj in Application.Current.Windows) 20 | { 21 | if (windowObj is Window window and not null) 22 | { 23 | await window.RefreshContentAsync(); 24 | } 25 | } 26 | }); 27 | } 28 | 29 | /// 30 | /// Refreshes the contents of all the windows in the application. 31 | /// 35 | { 36 | foreach (var windowObj in Application.Current.Windows) 37 | { 38 | if (windowObj is Window window and not null) 39 | { 40 | await window.RefreshContentAsync(); 41 | } 42 | } 43 | }); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Helpers/WindowsThemeHelper.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using MicaWPF.Core.Enums; 6 | using MicaWPF.Core.Services; 7 | using Microsoft.Win32; 8 | 9 | namespace MicaWPF.Core.Helpers; 10 | 11 | public static class WindowsThemeHelper 12 | { 13 | private const string _registryKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize"; 14 | private const string _registryValueName = "AppsUseLightTheme"; 15 | 16 | /// 17 | /// Gets the dark theme resource Uri. 18 | /// 19 | public static Uri DarkUri { get; } = new Uri($"pack://application:,,,/{MicaWPFServiceUtility.CurrentNamespace};component/Styles/Themes/MicaDark.xaml"); 20 | 21 | /// 22 | /// Gets the light theme resource Uri. 23 | /// 24 | public static Uri LightUri { get; } = new Uri($"pack://application:,,,/{MicaWPFServiceUtility.CurrentNamespace};component/Styles/Themes/MicaLight.xaml"); 25 | 26 | /// 27 | /// Gets the Windows theme (light or dark) from the registry. 28 | /// 29 | /// The current Windows theme (light or dark). 30 | public static WindowsTheme GetCurrentWindowsTheme() 31 | { 32 | using var key = Registry.CurrentUser.OpenSubKey(_registryKeyPath); 33 | var registryValueObject = key?.GetValue(_registryValueName); 34 | 35 | if (registryValueObject == null) 36 | { 37 | return WindowsTheme.Light; 38 | } 39 | 40 | var registryValue = (int)registryValueObject; 41 | 42 | return registryValue > 0 ? WindowsTheme.Light : WindowsTheme.Dark; 43 | } 44 | 45 | /// 46 | /// Converts a Windows theme (light or dark) to a resource theme. 47 | /// 48 | /// The Windows theme to convert. 49 | /// The corresponding resource theme URI. 50 | public static Uri WindowsThemeToResourceTheme(WindowsTheme windowsTheme) 51 | { 52 | return windowsTheme == WindowsTheme.Dark 53 | ? DarkUri 54 | : LightUri; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/MicaWPF.Core.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net461;net47;net48;net481;netcoreapp3.1;net6.0-windows;net7.0-windows;net8.0-windows;net9.0-windows 5 | 7.0 6 | true 7 | Copyright (c) 2021 Simnico99 8 | https://github.com/Simnico99/MicaWPF 9 | git 10 | MicaWPF;WPF;Mica;WinUI;wpfui;UI;windows;controls;custom;modern;xaml;toolkit;color;dark;theme;Simnico99;net6;net5;net;fluent;acrylic 11 | True 12 | enable 13 | https://github.com/Simnico99/MicaWPF 14 | en 15 | latest 16 | enable 17 | MIT 18 | True 19 | MicaWPFLogo - 128x128.png 20 | Simnico99 21 | Core library of MicaWPF and MicaWPF.Lite 22 | ReadmeNuget.md 23 | true 24 | true 25 | true 26 | snupkg 27 | true 28 | true 29 | NETSDK1138 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | \ 39 | True 40 | 41 | 42 | True 43 | \ 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | all 54 | runtime; build; native; contentfiles; analyzers; buildtransitive 55 | 56 | 57 | all 58 | runtime; build; native; contentfiles; analyzers; buildtransitive 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | True 70 | \ 71 | 72 | 73 | 74 | 75 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Models/AccentColors.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows.Media; 6 | 7 | namespace MicaWPF.Core.Models; 8 | 9 | /// 10 | /// Represents a set of accent colors. 11 | /// 12 | public readonly struct AccentColors 13 | { 14 | /// 15 | /// Initializes a new instance of the struct. 16 | /// 17 | /// The system accent color. 18 | /// The light 1 system accent color. 19 | /// The light 2 system accent color. 20 | /// The light 3 system accent color. 21 | /// The dark 1 system accent color. 22 | /// The dark 2 system accent color. 23 | /// The dark 3 system accent color. 24 | /// A value indicating whether this is a fallback color set. 25 | public AccentColors(Color systemAccentColor, Color systemAccentColorLight1, Color systemAccentColorLight2, Color systemAccentColorLight3, Color systemAccentColorDark1, Color systemAccentColorDark2, Color systemAccentColorDark3, bool isFallBack = false) 26 | { 27 | SystemAccentColor = systemAccentColor; 28 | SystemAccentColorLight1 = systemAccentColorLight1; 29 | SystemAccentColorLight2 = systemAccentColorLight2; 30 | SystemAccentColorLight3 = systemAccentColorLight3; 31 | SystemAccentColorDark1 = systemAccentColorDark1; 32 | SystemAccentColorDark2 = systemAccentColorDark2; 33 | SystemAccentColorDark3 = systemAccentColorDark3; 34 | IsFallBack = isFallBack; 35 | } 36 | 37 | /// 38 | /// Gets the system accent color. 39 | /// 40 | public Color SystemAccentColor { get; } 41 | 42 | /// 43 | /// Gets the light 1 system accent color. 44 | /// 45 | public Color SystemAccentColorLight1 { get; } 46 | 47 | /// 48 | /// Gets the light 2 system accent color. 49 | /// 50 | public Color SystemAccentColorLight2 { get; } 51 | 52 | /// 53 | /// Gets the light 3 system accent color. 54 | /// 55 | public Color SystemAccentColorLight3 { get; } 56 | 57 | /// 58 | /// Gets the dark 1 system accent color. 59 | /// 60 | public Color SystemAccentColorDark1 { get; } 61 | 62 | /// 63 | /// Gets the dark 2 system accent color. 64 | /// 65 | public Color SystemAccentColorDark2 { get; } 66 | 67 | /// 68 | /// Gets the dark 3 system accent color. 69 | /// 70 | public Color SystemAccentColorDark3 { get; } 71 | 72 | /// 73 | /// Gets a value indicating whether this is a fallback color set. 74 | /// 75 | public bool IsFallBack { get; } 76 | } -------------------------------------------------------------------------------- /src/MicaWPF.Core/Models/BackdropEnabledWindow.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using MicaWPF.Core.Enums; 7 | 8 | namespace MicaWPF.Core.Models; 9 | 10 | /// 11 | /// Represents a readonly struct that contains information about a window and its backdrop type. 12 | /// 13 | public readonly struct BackdropEnabledWindow 14 | { 15 | /// 16 | /// Initializes a new instance of the struct. 17 | /// 18 | /// The Window associated with this BackdropEnabledWindow instance. 19 | /// The BackdropType associated with this BackdropEnabledWindow instance. 20 | public BackdropEnabledWindow(Window window, BackdropType backdropType) 21 | { 22 | Window = window; 23 | BackdropType = backdropType; 24 | } 25 | 26 | /// 27 | /// Gets the Window associated with this BackdropEnabledWindow instance. 28 | /// 29 | public Window Window { get; } 30 | 31 | /// 32 | /// Gets the BackdropType associated with this BackdropEnabledWindow instance. 33 | /// 34 | public BackdropType BackdropType { get; } 35 | } 36 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Models/EventIdentifier.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | namespace MicaWPF.Core.Models; 6 | 7 | /// 8 | /// Represents an event identifier with a unique timestamp-based value. 9 | /// 10 | public sealed class EventIdentifier 11 | { 12 | /// 13 | /// Gets the current event identifier value. 14 | /// 15 | public long Current { get; internal set; } = 0; 16 | 17 | /// 18 | /// Updates the event identifier and returns the updated value. 19 | /// The updated value is based on the current date and time. 20 | /// 21 | /// The updated event identifier value. 22 | public long GetNext() 23 | { 24 | UpdateIdentifier(); 25 | 26 | return Current; 27 | } 28 | 29 | /// 30 | /// Checks if the provided identifier is equal to the current identifier. 31 | /// 32 | /// The identifier to compare with the current identifier. 33 | /// True if the provided identifier is equal to the current identifier; otherwise, false. 34 | public bool IsEqual(long storedId) 35 | { 36 | return Current == storedId; 37 | } 38 | 39 | /// 40 | /// Updates the event identifier with the current timestamp in Unix format. 41 | /// 42 | private void UpdateIdentifier() 43 | { 44 | Current = DateTime.Now.Subtract(new DateTime(1970, 1, 1)).Ticks / (TimeSpan.TicksPerMillisecond / 1000); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Models/Glyph.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using MicaWPF.Core.Symbols; 6 | 7 | namespace MicaWPF.Core.Models; 8 | 9 | /// 10 | /// A static helper class to parse instances into . 11 | /// 12 | public static class Glyph 13 | { 14 | public const FluentSystemIcons.Regular DefaultIcon = FluentSystemIcons.Regular.Heart28; 15 | public const FluentSystemIcons.Filled DefaultFilledIcon = FluentSystemIcons.Filled.Heart28; 16 | 17 | /// 18 | /// Parses a string into a icon. 19 | /// If the string is null or empty, a default icon is returned. 20 | /// 21 | /// The string representation of a FluentSystemIcons.Regular enum value. 22 | /// The parsed icon. If the input string is null or empty, a default icon is returned. 23 | public static FluentSystemIcons.Regular Parse(string name) 24 | { 25 | #if NET9_0_OR_GREATER 26 | return string.IsNullOrEmpty(name) ? DefaultIcon : Enum.Parse(name); 27 | #else 28 | return string.IsNullOrEmpty(name) ? DefaultIcon : (FluentSystemIcons.Regular)Enum.Parse(typeof(FluentSystemIcons.Regular), name); 29 | #endif 30 | } 31 | 32 | /// 33 | /// Parses a string into a icon. 34 | /// If the string is null or empty, a default icon is returned. 35 | /// 36 | /// The string representation of a FluentSystemIcons.Filled enum value. 37 | /// The parsed icon. If the input string is null or empty, a default icon is returned. 38 | public static FluentSystemIcons.Filled ParseFilled(string name) 39 | { 40 | #if NET9_0_OR_GREATER 41 | return string.IsNullOrEmpty(name) ? DefaultFilledIcon : Enum.Parse(name); 42 | #else 43 | return string.IsNullOrEmpty(name) ? DefaultFilledIcon : (FluentSystemIcons.Filled)Enum.Parse(typeof(FluentSystemIcons.Filled), name); 44 | #endif 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/ReadmeNuget.md: -------------------------------------------------------------------------------- 1 | https://github.com/Simnico99/MicaWPF -------------------------------------------------------------------------------- /src/MicaWPF.Core/Services/IAccentColorService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using System.Windows.Media; 7 | using MicaWPF.Core.Events; 8 | using MicaWPF.Core.Helpers; 9 | using MicaWPF.Core.Models; 10 | 11 | namespace MicaWPF.Core.Services; 12 | 13 | /// 14 | /// Service that manages the accent colors of the application. 15 | /// 16 | public interface IAccentColorService 17 | { 18 | /// 19 | /// Gets contains the currently used WindowsAccentHelper. 20 | /// 21 | WindowsAccentHelper WindowsAccentHelper 22 | { 23 | get; 24 | } 25 | 26 | /// 27 | /// Gets event that is raised when the accent colors are changed. 28 | /// 29 | IWeakEvent AccentColorChanged 30 | { 31 | get; 32 | } 33 | 34 | /// 35 | /// Gets contains information about the current accent colors. 36 | /// 37 | AccentColors AccentColors 38 | { 39 | get; 40 | } 41 | 42 | /// 43 | /// Gets a value indicating whether indicates if the accent colors were updated from Windows. 44 | /// 45 | bool AccentColorsUpdateFromWindows 46 | { 47 | get; 48 | } 49 | 50 | /// 51 | /// Gets or sets a value indicating whether indicates if the title bar and borders are accent aware. 52 | /// 53 | bool IsTitleBarAndBorderAccentAware 54 | { 55 | get; set; 56 | } 57 | 58 | /// 59 | /// Gets a value indicating whether indicates if the title bar and windows borders are colored. 60 | /// 61 | bool IsTitleBarAndWindowsBorderColored 62 | { 63 | get; 64 | } 65 | 66 | /// 67 | /// Refreshes the accent colors used in the application. 68 | /// If `AccentColorsUpdateFromWindows` is set to true, the accent colors will be updated from Windows. 69 | /// Otherwise, the accent colors will be updated to the system accent color. 70 | /// This is automatically done when the theme change. 71 | /// 72 | void RefreshAccentsColors(); 73 | 74 | /// 75 | /// Updates the accent colors with the given color. 76 | /// 77 | /// The color to use as the system accent color. 78 | void UpdateAccentsColors(Color systemAccent); 79 | 80 | /// 81 | /// Updates the accent colors with the system accent color obtained from Windows. 82 | /// 83 | void UpdateAccentsColorsFromWindows(); 84 | 85 | /// 86 | /// Add border and titlebar accent color. 87 | /// 88 | /// The window to apply it to. 89 | /// Is the accent color enabled 90 | void IsTitleBarAndBorderAccentEnabled(Window window, bool isEnabled); 91 | } -------------------------------------------------------------------------------- /src/MicaWPF.Core/Services/IThemeDictionaryService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.ComponentModel; 6 | using MicaWPF.Core.Enums; 7 | 8 | namespace MicaWPF.Core.Services; 9 | 10 | /// 11 | /// Service that manages the theme dictionnaries from MicaWPF.Core. 12 | /// 13 | public interface IThemeDictionaryService 14 | { 15 | /// 16 | /// Event that is raised when the `ThemeSource` property is changed. 17 | /// 18 | event PropertyChangedEventHandler? PropertyChanged; 19 | 20 | /// 21 | /// Gets or sets the source of the current theme. 22 | /// 23 | Uri? ThemeSource { get; set; } 24 | 25 | /// 26 | /// Sets the source of the current theme. 27 | /// 28 | /// The source of the theme to set. 29 | void SetThemeSource(Uri source); 30 | 31 | /// 32 | /// Force the current theme source to reload. 33 | /// 34 | void RefreshThemeSource(); 35 | 36 | /// 37 | /// Gets the current theme from the loaded resource dictionnary. 38 | /// 39 | /// The current ap theme. 40 | WindowsTheme GetCurrentResourcesTheme(); 41 | } -------------------------------------------------------------------------------- /src/MicaWPF.Core/Services/IThemeService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.Windows; 6 | using MicaWPF.Core.Enums; 7 | using MicaWPF.Core.Events; 8 | using MicaWPF.Core.Models; 9 | 10 | namespace MicaWPF.Core.Services; 11 | 12 | /// 13 | /// Service that manages the theme of the application. 14 | /// 15 | public interface IThemeService 16 | { 17 | /// 18 | /// Gets contains information about the current theme. 19 | /// 20 | WindowsTheme CurrentTheme { get; } 21 | 22 | /// 23 | /// Gets a value indicating whether indicates if the service is aware of windows theme changes. 24 | /// 25 | bool IsThemeAware { get; } 26 | 27 | /// 28 | /// Gets list of windows that have Mica enabled. 29 | /// 30 | List BackdropEnabledWindows { get; } 31 | 32 | /// 33 | /// Gets event that is raised when the theme is changed. 34 | /// 35 | IWeakEvent ThemeChanged { get; } 36 | 37 | /// 38 | /// Set the current accent color service. 39 | /// 40 | /// Accent color service to use. 41 | void SetAccentColorService(IAccentColorService accentColorService); 42 | 43 | /// 44 | /// Changes the current theme. 45 | /// 46 | /// The theme to switch to. Default is `WindowsTheme.Auto`. 47 | /// The newly set theme. 48 | WindowsTheme ChangeTheme(WindowsTheme windowsTheme = WindowsTheme.Auto); 49 | 50 | /// 51 | /// Enables the backdrop on the given window with the specified type. 52 | /// 53 | /// The window to enable the backdrop on. 54 | /// The type of backdrop to enable. Default is `BackdropType.Mica`. 55 | void EnableBackdrop(Window window, BackdropType micaType = BackdropType.Mica); 56 | } -------------------------------------------------------------------------------- /src/MicaWPF.Core/Services/MicaWPFServiceUtility.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using MicaWPF.Core.Helpers; 6 | 7 | namespace MicaWPF.Core.Services; 8 | 9 | /// 10 | /// Controls and manages the services in the MicaWPF framework. 11 | /// 12 | public sealed class MicaWPFServiceUtility 13 | { 14 | private static IAccentColorService? _accentColorService; 15 | private static IThemeService? _themeService; 16 | private static IThemeDictionaryService? _themeDictionaryService; 17 | private static string? _currentNamespace; 18 | 19 | static MicaWPFServiceUtility() 20 | { 21 | // Warning the order is very important. 22 | try 23 | { 24 | _currentNamespace ??= ServiceLocatorHelper.GetNamespace(); 25 | _themeDictionaryService ??= ServiceLocatorHelper.GetService(); 26 | _themeService ??= ServiceLocatorHelper.GetService(); 27 | _accentColorService ??= ServiceLocatorHelper.GetService(); 28 | HasBeenInitialized = true; 29 | } 30 | catch 31 | { 32 | HasBeenInitialized = false; 33 | } 34 | } 35 | 36 | public static bool HasBeenInitialized 37 | { 38 | get; 39 | } 40 | 41 | /// 42 | /// Gets or sets the Accent Color Service instance (WARNING: Sets should be done on application start). 43 | /// 44 | public static IAccentColorService AccentColorService 45 | { 46 | get => _accentColorService ?? throw new ArgumentNullException("Value is not initialized yet."); 47 | set => StaticHelper.Init(value, ref _accentColorService); 48 | } 49 | 50 | /// 51 | /// Gets or sets the Theme Service instance (WARNING: Sets should be done on application start). 52 | /// 53 | public static IThemeService ThemeService 54 | { 55 | get => _themeService ?? throw new ArgumentNullException("Value is not initialized yet."); 56 | set => StaticHelper.Init(value, ref _themeService); 57 | } 58 | 59 | /// 60 | /// Gets or sets the Theme Dictionary Service instance (WARNING: Sets should be done on application start). 61 | /// 62 | public static IThemeDictionaryService ThemeDictionaryService 63 | { 64 | get => _themeDictionaryService ?? throw new ArgumentNullException("Value is not initialized yet."); 65 | set => StaticHelper.Init(value, ref _themeDictionaryService); 66 | } 67 | 68 | /// 69 | /// Gets or sets the current namespace string (WARNING: Sets should be done on application start). 70 | /// 71 | public static string CurrentNamespace 72 | { 73 | get => _currentNamespace ?? throw new ArgumentNullException("Value is not initialized yet."); 74 | set => StaticHelper.Init(value, ref _currentNamespace); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Services/ThemeDictionaryService.cs: -------------------------------------------------------------------------------- 1 | // 2 | // This software is distributed under the MIT license and its code is open-source and free for use, modification, and distribution. 3 | // 4 | 5 | using System.ComponentModel; 6 | using System.Runtime.CompilerServices; 7 | using System.Windows; 8 | using MicaWPF.Core.Enums; 9 | using MicaWPF.Core.Helpers; 10 | using MicaWPF.Core.Styles; 11 | 12 | namespace MicaWPF.Core.Services; 13 | 14 | /// 15 | /// Service that manages the theme dictionnaries from MicaWPF. 16 | /// 17 | public class ThemeDictionaryService : INotifyPropertyChanged, IThemeDictionaryService 18 | { 19 | private static Uri? _currentThemeSource; 20 | 21 | public event PropertyChangedEventHandler? PropertyChanged; 22 | 23 | public Uri? ThemeSource 24 | { 25 | get => _currentThemeSource; 26 | set 27 | { 28 | if (value != null) 29 | { 30 | SetThemeSource(value); 31 | OnPropertyChanged(); 32 | } 33 | } 34 | } 35 | 36 | public void SetThemeSource(Uri source) 37 | { 38 | lock (source) 39 | { 40 | _currentThemeSource = source; 41 | 42 | var oldThemes = GetThemeResourceDictionary(); 43 | var dictionaries = Application.Current.Resources.MergedDictionaries; 44 | 45 | WindowHelper.RefreshAllWindowsContents(); 46 | 47 | dictionaries.Add(new ResourceDictionary 48 | { 49 | Source = source, 50 | }); 51 | 52 | foreach (var oldTheme in oldThemes) 53 | { 54 | _ = dictionaries.Remove(oldTheme); 55 | } 56 | } 57 | } 58 | 59 | public WindowsTheme GetCurrentResourcesTheme() 60 | { 61 | var dictionnaries = Application.Current.Resources.MergedDictionaries; 62 | foreach (var dictionary in dictionnaries) 63 | { 64 | if (dictionary is not ThemeDictionaryBase themeDictionary) 65 | { 66 | continue; 67 | } 68 | 69 | return themeDictionary.Theme; 70 | } 71 | 72 | return WindowsTheme.Auto; 73 | } 74 | 75 | public void RefreshThemeSource() 76 | { 77 | if (_currentThemeSource is not null) 78 | { 79 | SetThemeSource(_currentThemeSource); 80 | OnPropertyChanged(); 81 | } 82 | } 83 | 84 | private static List GetThemeResourceDictionary() 85 | { 86 | var list = new List(); 87 | foreach (var dictionary in Application.Current.Resources.MergedDictionaries) 88 | { 89 | if (dictionary.GetType().Name == "ThemeDictionary") 90 | { 91 | list.Add(dictionary); 92 | } 93 | } 94 | 95 | return list; 96 | } 97 | 98 | private void OnPropertyChanged([CallerMemberName] string propertyName = "") 99 | { 100 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 101 | } 102 | } -------------------------------------------------------------------------------- /src/MicaWPF.Core/Styles/Assets/Accent.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | #559ce4 5 | #80b9ee 6 | #add8ff 7 | 8 | 9 | 10 | #91C5F0 11 | #60AFEE 12 | #3091E2 13 | #2D78D6 14 | #1F5AA2 15 | #113D70 16 | #0C2F56 17 | 18 | -------------------------------------------------------------------------------- /src/MicaWPF.Core/Styles/Controls/Dark/GradientBorder.xaml: -------------------------------------------------------------------------------- 1 |  5 | 6 | 34 | 35 | 64 | 65 | 34 | 35 | 64 | 65 | 62 | 63 | 49 | 50 | 18 | 19 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /src/MicaWPF/Styles/Controls/ListView.xaml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 57 | 58 | 60 | 61 | 24 | 25 | 54 | 55 | 25 | 26 | 41 | 42 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 |