62 Commits
Author SHA1 Message Date
Stone_Red 7755ece3cd Merge pull request #10 from Stone-Red-Code/develop
Develop
2025-12-09 00:05:39 +01:00
Stone_Red b380e35189 Update version 2025-12-09 00:05:27 +01:00
Stone_Red 3fcda8e64e Add per plugin theme override 2025-12-08 20:37:01 +01:00
Stone_Red 0bc7033196 Fix some issues with the new theme support 2025-12-08 20:11:12 +01:00
Stone_Red 10fe4c773b Add better theme support 2025-11-04 19:00:32 +01:00
Stone_Red 13ed2f6a22 Merge pull request #9 from Stone-Red-Code/develop
Update auto start step in README.md
2025-07-07 11:41:15 +02:00
Stone_Red b7139a8821 Update auto start step in README.md 2025-07-07 11:41:01 +02:00
Stone_Red 302ff3aa05 Merge pull request #8 from Stone-Red-Code/develop
Develop
2025-07-05 17:42:00 +02:00
Stone_Red d285bdc489 Update version 2025-07-05 17:39:07 +02:00
Stone_Red 0a64184c32 Fix plugin manager crash when opening it 2025-05-17 15:45:43 +02:00
Stone_Red 2df00fbeeb Properly remove the plugin window from the lists in the main window when an exception occurs 2025-02-26 20:22:42 +01:00
Stone_Red 088f51410a Send plugin windows to front when edit mode enabled and to back when disabled 2025-02-26 19:28:42 +01:00
Stone_Red 70d08aa4c3 Set WindowState of main window to Minimized when closing 2025-02-25 23:04:44 +01:00
Stone_Red af9aa60bd9 Rename ModEntry UserControl to PluginEntry 2025-02-25 23:03:14 +01:00
Stone_Red 695cb867ee Add autostart checkbox 2025-02-25 19:20:02 +01:00
Stone_Red 376176460b Update modio.net library links in README.md 2025-02-25 03:09:35 +01:00
Stone_Red 327b79d69c Remove Extended.Wpf.Toolkit from thrid party licenses section in README.md 2025-02-25 03:04:43 +01:00
Stone_Red c74bc60209 Add login/logout button to plugin manger to sync subscriptions 2025-02-24 22:02:58 +01:00
Stone_Red 930da5d679 Correctly update .csproj file when creating new plugin 2025-02-23 15:53:41 +01:00
Stone_Red ffd92d2259 Add create new plugin button to plugin manager 2025-02-23 15:32:56 +01:00
Stone_Red 6100f444a8 Center dialogs on parent window 2025-02-23 15:32:25 +01:00
Stone_Red ead20d1279 Change GetLanguageDictionary method to LanguageDictionary property 2024-12-30 16:54:04 +01:00
Stone_Red b638eff451 Add missing translations 2024-12-28 23:16:23 +01:00
Stone_Red 793dcbad38 Small fixes 2024-12-28 16:40:06 +01:00
Stone_Red c2474e6425 Plugin manager layout improvments 2024-12-05 15:00:48 +01:00
Stone_Red cbeaaee88e Standardize README 2024-12-03 00:43:51 +01:00
Stone_Red 92c13c5ed0 Change app name from "Desktop Magic" to "DesktopMagic" and some QOL improvments 2024-12-03 00:16:37 +01:00
Stone_Red 26e979af79 Standardize default plugin setting names 2024-12-03 00:16:37 +01:00
Stone_Red 29619dbdda Rename download plugins to browse plugins in README.md 2024-11-30 00:38:56 +01:00
Stone_Red bc11832f9f Add right click actions to tray icon 2024-11-29 18:40:00 +01:00
Stone_Red f8f06a9e2c Improve plugin window performance by not constantly updating properties of UI elements 2024-11-29 17:55:33 +01:00
Stone_Red 35d64ef2c3 Don't unnecessarily redraw time plugin bitmap every second 2024-11-29 17:55:33 +01:00
Stone_Red 3b9d49e8da Update README.md 2024-11-29 00:57:02 +01:00
Stone_Red aada1b8807 Add Microsoft Store link and fix twitter/x link 2024-11-28 17:47:36 +01:00
Stone_Red 9abfb9cb66 Merge pull request #7 from Stone-Red-Code/main
Readme updates
2024-11-18 23:00:21 +01:00
Stone_Red ce1c181b14 Add MsixPackaging project 2024-11-16 14:36:04 +01:00
Stone_Red e6be5c011b Replace deprecated Modio library with alternative library 2024-11-15 19:55:12 +01:00
Stone_Red c6e858764f Remove unnecessary files 2024-11-15 19:53:19 +01:00
Stone_Red f684cdb051 Show error when failing to delete plugin files 2024-11-15 19:41:34 +01:00
Stone_Red 3993e6d612 Fix multiple warnings 2024-11-15 19:41:16 +01:00
Stone_Red 8e187f91fa Update README.md 2024-10-31 13:19:28 +01:00
Stone_Red 566bcee426 Update README.md 2024-10-30 21:51:00 +01:00
Stone_Red 038074cd87 Update README.md 2024-10-30 21:50:22 +01:00
Stone_Red 7e1736696d Rename BuiltInWindowElements to BuiltInPlugins 2024-10-26 14:43:14 +02:00
Stone_Red e545f27461 Replace Xceed.Wpf.Toolkit.IntegerUpDown with MaterialDesignThemes.Wpf.NumericUpDown 2024-10-26 00:25:53 +02:00
Stone_Red d458feca1e Add DesktopMagicPluginAPI.xml to .gitignore 2024-10-25 23:28:52 +02:00
Stone_Red f899fd3e9b Merge branch 'main' into develop 2024-10-25 23:22:23 +02:00
Stone_Red c3b867ff67 Merge pull request #6 from dylanrenwick/main
Updated documentation file path to be relative to project
2024-10-25 23:19:29 +02:00
drenwick 1fe59e6338 Updated documentation file path to be relative to project 2024-10-25 15:10:58 -04:00
Stone_Red 242f6a8388 Merge pull request #4 from Stone-Red-Code/develop
Develop
2024-05-01 18:22:10 +02:00
Stone_Red f7f75a4580 Fix Installer.iss 2024-05-01 18:21:23 +02:00
Stone_Red 475623f333 Change file version 2024-05-01 18:20:08 +02:00
Stone_Red aa1733e0c6 Update libraries 2024-05-01 17:41:27 +02:00
Stone_Red 5804bade47 Fix plugin dependencies not getting loaded 2024-05-01 15:51:19 +02:00
Stone_Red ca9f426bba Fix null warning 2024-05-01 15:26:14 +02:00
Stone_Red 4cd8c51592 Make installed plugins panel scrollable 2024-05-01 15:23:53 +02:00
Stone_Red d4cd384ce4 Merge pull request #3 from Stone-Red-Code/develop
Develop
2024-02-22 09:58:24 +01:00
Stone_Red 414f84a024 Update installer 2024-02-22 09:57:41 +01:00
Stone_Red 3c732117d3 Remove auto update 2024-02-22 09:50:30 +01:00
Stone_Red 9a75cbd8e7 Fix or disable multiple warnings 2024-02-22 09:34:01 +01:00
Stone_Red 536890a5e4 Update twitter link in README.md to always show the latest updates 2024-01-03 12:24:13 +01:00
Stone_Red 975831eb18 Add "Follow the development" section to readme 2024-01-02 16:38:38 +01:00
112 changed files with 2035 additions and 768 deletions
+3
View File
@@ -6,6 +6,9 @@
bin/
obj/
# Project-specific files
/src/DesktopMagicPluginAPI/DesktopMagicPluginAPI.xml
# User-specific files
*.rsuser
*.suo
+17 -10
View File
@@ -1,18 +1,25 @@
# DesktopMagic
![DesktopMagic](https://socialify.git.ci/Stone-Red-Code/DesktopMagic/image?description=1&descriptionEditable=DesktopMagic%20allows%20you%20to%20improve%20the%20looks%20of%20your%20desktop!&forks=1&issues=1&logo=https%3A%2F%2Fgithub.com%2Fuser-attachments%2Fassets%2F34f3c473-a29a-4d71-9ec0-1387b04ad2c5&name=1&pattern=Formal%20Invitation&pulls=1&stargazers=1&theme=Auto)
> DesktopMagic allows you to improve the looks of your Windows desktop!\
> You can add useful elements to your desktop like a clock, an audio visualizer or even your own plugins using mod.io!
> You can add useful widgets to your desktop like a clock, an audio visualizer or even your own plugins using mod.io!
- [Releases](https://github.com/Stone-Red-Code/DesktopMagic/releases)
- [Download plugins](https://mod.io/g/desktopmagic)
- [Browse plugins](https://mod.io/g/desktopmagic)
- [Plugin creation guide](https://mod.io/g/desktopmagic/r/plugin-creation-guide)
- [Licence](https://github.com/Stone-Red-Code/DesktopMagic/blob/main/LICENSE)
## Setup
## Usage
1. Download one of the [releases](https://github.com/Stone-Red-Code/DesktopMagic/releases).
1. Execute the `DesktopMagic-Installer.exe` file.
1. (Optional) Put a shortcut to the `DesktopMagic.exe` file in the install directory into the `shell:startup` directory.
1. Download & install the latest release
- Microsoft Store: [Store Page](https://www.microsoft.com/store/productId/9NPV8F9K1CWM?ocid=pdpshare)
- GitHub: [Releases](https://github.com/Stone-Red-Code/DesktopMagic/releases)
1. Start the app and select the widgets you want to see on your desktop.
1. (Optional) Check "Launch on startup" so DesktopMagic automatically starts when you log in.
1. Check the "Edit" Checkbox to move the widgets.
1. Open the plugin manager to install third-party plugins.
## Follow the development
[![Twitter(X)](http://img.shields.io/badge/Twitter-black.svg?&logo=x&style=for-the-badge&logoColor=white)](https://x.com/search?q=from%3A%40StoneRedCode%20%23DesktopMagic)
## Preview
@@ -20,8 +27,8 @@
![Screenshot 2023-12-31 164853](https://github.com/Stone-Red-Code/DesktopMagic/assets/56473591/22de55d2-dde3-43a5-b77b-c773a7697e8c)
## Third party licenses
- [BusyIndicator](https://github.com/moh3ngolshani/BusyIndicator) - [MIT](https://github.com/Moh3nGolshani/BusyIndicator/blob/master/LICENSE)
- [Extended.Wpf.Toolkit](https://github.com/xceedsoftware/wpftoolkit) - [XCEED SOFTWARE COMMUNITY LICENSE AGREEMENT](https://github.com/xceedsoftware/wpftoolkit/blob/master/license.md)
- [Material Design In XAML Toolkit](https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit) - [MIT](https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/master/LICENSE)
- [Modio.NET](https://github.com/thetestgame/modio.net) - [Apache-2.0](https://github.com/thetestgame/Modio.NET/blob/main/LICENSE-APACHE), [MIT](https://github.com/thetestgame/Modio.NET/blob/main/LICENSE-MIT)
- [Modio.NET](https://github.com/nickelc/modio.net) - [Apache-2.0](https://github.com/nickelc/modio.net/blob/master/LICENSE-APACHE), [MIT](https://github.com/nickelc/modio.net/blob/master/LICENSE-MIT)
- [NAudio](https://github.com/naudio/NAudio) - [MIT](https://github.com/naudio/NAudio/blob/master/license.txt)
Binary file not shown.
+1 -1
View File
@@ -4,7 +4,7 @@
#expr Exec('cmd.exe /C ', 'dotnet build -o "' + SourcePath + '\publish" -c Release ' + SourcePath + '..\src\DesktopMagic\')
#define MyAppName "DesktopMagic"
#define MyAppVersion GetVersionNumbersString("/publish/DesktopMagic.exe")
#define MyAppVersion GetStringFileInfo("/publish/DesktopMagic.exe","ProductVersion")
#define MyAppPublisher "Stone_Red"
#define MyAppExeName "DesktopMagic.exe"
+92 -4
View File
@@ -9,24 +9,112 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesktopMagic.Api", "Desktop
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DesktopMagic.PluginTest", "DesktopMagicPlugin.Test\DesktopMagic.PluginTest.csproj", "{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}"
EndProject
Project("{C7167F0D-BC9F-4E6E-AFE1-012C56B48DB5}") = "MsixPackaging", "MsixPackaging\MsixPackaging.wapproj", "{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM = Debug|ARM
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM = Release|ARM
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|Any CPU.Build.0 = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|Any CPU.ActiveCfg = Debug|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|Any CPU.Build.0 = Debug|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|ARM.Build.0 = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|ARM64.Build.0 = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|x64.ActiveCfg = Debug|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|x64.Build.0 = Debug|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|x86.ActiveCfg = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Debug|x86.Build.0 = Debug|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|Any CPU.ActiveCfg = Release|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|Any CPU.Build.0 = Release|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|ARM.ActiveCfg = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|ARM.Build.0 = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|ARM64.ActiveCfg = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|ARM64.Build.0 = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|x64.ActiveCfg = Release|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|x64.Build.0 = Release|x64
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|x86.ActiveCfg = Release|Any CPU
{B56B4CCC-CF92-4C05-9DEA-57666D81889A}.Release|x86.Build.0 = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|ARM.ActiveCfg = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|ARM.Build.0 = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|ARM64.Build.0 = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|x64.ActiveCfg = Debug|x64
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|x64.Build.0 = Debug|x64
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|x86.ActiveCfg = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Debug|x86.Build.0 = Debug|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|Any CPU.Build.0 = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|ARM.ActiveCfg = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|ARM.Build.0 = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|ARM64.ActiveCfg = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|ARM64.Build.0 = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|x64.ActiveCfg = Release|x64
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|x64.Build.0 = Release|x64
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|x86.ActiveCfg = Release|Any CPU
{9D193A10-3E8E-447F-89F1-4B316C2EE37D}.Release|x86.Build.0 = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|ARM.ActiveCfg = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|ARM.Build.0 = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|ARM64.Build.0 = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|x64.ActiveCfg = Debug|x64
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|x64.Build.0 = Debug|x64
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|x86.ActiveCfg = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Debug|x86.Build.0 = Debug|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|Any CPU.Build.0 = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|ARM.ActiveCfg = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|ARM.Build.0 = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|ARM64.ActiveCfg = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|ARM64.Build.0 = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|x64.ActiveCfg = Release|x64
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|x64.Build.0 = Release|x64
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|x86.ActiveCfg = Release|Any CPU
{EF8407AB-28AE-4B5E-AC2E-D4C4A575FBC7}.Release|x86.Build.0 = Release|Any CPU
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM.ActiveCfg = Debug|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM.Build.0 = Debug|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM.Deploy.0 = Debug|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM64.ActiveCfg = Debug|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM64.Build.0 = Debug|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|ARM64.Deploy.0 = Debug|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x64.ActiveCfg = Debug|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x64.Build.0 = Debug|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x64.Deploy.0 = Debug|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x86.ActiveCfg = Debug|x86
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x86.Build.0 = Debug|x86
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Debug|x86.Deploy.0 = Debug|x86
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|Any CPU.ActiveCfg = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|Any CPU.Build.0 = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|Any CPU.Deploy.0 = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM.ActiveCfg = Release|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM.Build.0 = Release|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM.Deploy.0 = Release|ARM
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM64.ActiveCfg = Release|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM64.Build.0 = Release|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|ARM64.Deploy.0 = Release|ARM64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x64.ActiveCfg = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x64.Build.0 = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x64.Deploy.0 = Release|x64
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x86.ActiveCfg = Release|x86
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x86.Build.0 = Release|x86
{CC2850EF-1451-4D0C-9474-4CBEBB28A2C8}.Release|x86.Deploy.0 = Release|x86
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
+3 -1
View File
@@ -8,8 +8,10 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Resources\Strings\StringResources.en.xaml" />
<materialDesign:BundledTheme BaseTheme="Light" PrimaryColor="Grey" SecondaryColor="LightBlue" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesign3.Defaults.xaml" />
<ResourceDictionary Source="pack://application:,,,/BusyIndicator;component/Theme/Default.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ObsoleteBrushes.xaml" />
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.ObsoleteStyles.xaml" />
<ResourceDictionary Source="Resources\Images\ImageResources.xaml" />
</ResourceDictionary.MergedDictionaries>
<Thickness x:Key="DefaultMargin" Top="6" Left="6" Right="6" Bottom ="6"></Thickness>
+98 -98
View File
@@ -1,8 +1,4 @@
global using Stone_Red_Utilities.Logging;
using AlwaysUpToDate;
using Stone_Red_C_Sharp_Utilities.Logging;
using CuteUtils.Logging;
using System;
using System.IO;
@@ -18,58 +14,107 @@ public partial class App : Application
{
public const string AppGuid = "{{61FE5CE9-47C3-4255-A1F4-5BCF4ACA0879}";
public const string AppName = "Desktop Magic";
private readonly string logFilePath;
#if DEBUG
private readonly Updater updater = new Updater(TimeSpan.FromDays(1), "https://raw.githubusercontent.com/Stone-Red-Code/DesktopMagic/develop/update/updateInfo.json");
#else
private readonly Updater updater = new Updater(TimeSpan.FromDays(1), "https://raw.githubusercontent.com/Stone-Red-Code/DesktopMagic/main/update/updateInfo.json");
#endif
public const string AppName = "DesktopMagic";
// This is the previous name of the application, used to migrate the application data folder
private const string PreviousAppName = "Desktop Magic";
private static readonly string logFilePath = Path.Combine(ApplicationDataPath, $"{AppName}.log");
private readonly Thread? eventThread;
private readonly EventWaitHandle eventWaitHandle;
public static string ApplicationDataPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "StoneRed", AppName);
private readonly Logger logger = new Logger();
public static string ApplicationDataPath { get; } = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "StoneRed", AppName);
public static string PluginsPath => Path.Combine(ApplicationDataPath, "Plugins");
public static Logger Logger => ((App)Current).logger;
public static Logger Logger { get; } = new Logger()
{
Config = new()
{
FatalConfig = new OutputConfig()
{
ConsoleColor = ConsoleColor.DarkRed,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
ErrorConfig = new OutputConfig()
{
ConsoleColor = ConsoleColor.Red,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
WarnConfig = new OutputConfig()
{
ConsoleColor = ConsoleColor.Yellow,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
InfoConfig = new OutputConfig()
{
ConsoleColor = ConsoleColor.White,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
DebugConfig = new OutputConfig()
{
ConsoleColor = ConsoleColor.Gray,
LogTarget = LogTarget.DebugConsole,
},
FormatConfig = new FormatConfig()
{
DebugConsoleFormat = $"> {{{LogFormatType.DateTime}:HH:mm:ss}} | {{{LogFormatType.LogSeverity},-5}} | {{{LogFormatType.Message}}}\nat {{{LogFormatType.LineNumber}}} | {{{LogFormatType.FilePath}}}"
}
}
};
public static ResourceDictionary LanguageDictionary
{
get
{
ResourceDictionary dict = [];
string currentCulture = Thread.CurrentThread.CurrentUICulture.ToString();
if (currentCulture.Contains("de"))
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.de.xaml", UriKind.Relative);
}
else
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.en.xaml", UriKind.Relative);
}
return dict;
}
}
private static string PreviousApplicationDataPath => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "StoneRed", PreviousAppName);
public App()
{
logFilePath = ApplicationDataPath + "\\log.log";
// Setup global event handler
eventWaitHandle = new EventWaitHandle(false, EventResetMode.AutoReset, AppGuid, out bool createdNew);
//check if creating new was successful
// Check if creating new was successful
if (!createdNew)
{
Setup(false);
Logger.Log("Shutting down because other instance already running.", "Setup", LogSeverity.Warn);
//Shutdown Application
Logger.LogWarn("Shutting down because other instance already running.", source: "Setup");
// Shutdown Application
_ = eventWaitHandle.Set();
Current.Shutdown();
}
else
{
eventThread = new Thread(
() =>
eventThread = new Thread(() =>
{
while (eventWaitHandle.WaitOne())
{
while (eventWaitHandle.WaitOne())
{
_ = Current.Dispatcher.BeginInvoke(
() => ((MainWindow)Current.MainWindow).RestoreWindow());
}
});
_ = Current.Dispatcher.BeginInvoke(() => ((MainWindow)Current.MainWindow).RestoreWindow());
}
});
eventThread.Start();
Setup(true);
Exit += CloseHandler;
updater.ProgressChanged += Updater_ProgressChanged;
updater.OnException += Updater_OnException;
updater.NoUpdateAvailible += Updater_NoUpdateAvailible;
updater.UpdateAvailible += Updater_UpdateAvailible;
updater.Start();
}
}
@@ -79,78 +124,39 @@ public partial class App : Application
eventThread?.Interrupt();
}
private void Updater_UpdateAvailible(string version, string additionalInformation)
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
updater.Update();
Exception exception = (Exception)e.ExceptionObject;
Logger.LogFatal(exception + (e.IsTerminating ? "\t Process terminating!" : ""), source: exception.Source ?? "Unknown");
}
private void Updater_NoUpdateAvailible()
{
Logger.Log("No update available", "Updater");
}
private void Updater_OnException(Exception exception)
{
Logger.Log(exception.ToString(), "Updater");
}
private void Updater_ProgressChanged(long? totalFileSize, long totalBytesDownloaded, double? progressPercentage)
{
Logger.Log($"Downloading: {progressPercentage}% {totalBytesDownloaded}/{totalFileSize}", "Updater");
}
private void Setup(bool clearLogFile)
private static void Setup(bool clearLogFile)
{
AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
Logger.Config = new LogConfig()
{
FatalConfig = new OutputConfig()
{
Color = ConsoleColor.DarkRed,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
ErrorConfig = new OutputConfig()
{
Color = ConsoleColor.Red,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
WarnConfig = new OutputConfig()
{
Color = ConsoleColor.Yellow,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
InfoConfig = new OutputConfig()
{
Color = ConsoleColor.White,
LogTarget = LogTarget.DebugConsole | LogTarget.File,
FilePath = logFilePath
},
DebugConfig = new OutputConfig()
{
Color = ConsoleColor.Gray,
LogTarget = LogTarget.DebugConsole,
},
FormatConfig = new FormatConfig()
{
DebugConsoleFormat = $"> {{{LogFormatType.DateTime}:HH:mm:ss}} | {{{LogFormatType.LogSeverity},-5}} | {{{LogFormatType.Message}}}\nat {{{LogFormatType.LineNumber}}} | {{{LogFormatType.FilePath}}}"
}
};
try
{
if (Directory.Exists(PreviousApplicationDataPath) && !Directory.Exists(ApplicationDataPath))
{
Directory.Move(PreviousApplicationDataPath, ApplicationDataPath);
Logger.LogInfo("Migrated ApplicationData folder", source: "Setup");
}
if (!Directory.Exists(ApplicationDataPath))
{
_ = Directory.CreateDirectory(ApplicationDataPath);
Logger.LogInfo("Created ApplicationData folder", source: "Setup");
}
if (!Directory.Exists(PluginsPath))
{
_ = Directory.CreateDirectory(PluginsPath);
Logger.LogInfo("Created Plugins folder", source: "Setup");
}
Logger.Log("Created ApplicationData Folder", "Main");
}
catch (Exception ex)
{
_ = MessageBox.Show(ex.ToString());
_ = MessageBox.Show(ex.ToString(), AppName, MessageBoxButton.OK, MessageBoxImage.Error);
Logger.Log(ex.Message, "Setup", LogSeverity.Error);
}
@@ -159,12 +165,6 @@ public partial class App : Application
Logger.ClearLogFile(LogSeverity.Info);
}
Logger.Log("Log setup complete", "Setup");
}
private void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
Exception exception = (Exception)e.ExceptionObject;
Logger.Log(exception + (e.IsTerminating ? "\t Process terminating!" : ""), exception.Source, LogSeverity.Fatal);
Logger.LogInfo("Setup complete", source: "Setup");
}
}
@@ -7,7 +7,7 @@ using System.Drawing.Text;
using SettingAttribute = DesktopMagic.Api.Settings.SettingAttribute;
namespace DesktopMagic.BuiltInWindowElements;
namespace DesktopMagic.BuiltInPlugins;
internal class CpuMonitorPlugin : Plugin
{
@@ -5,22 +5,22 @@ using System;
using System.Drawing;
using System.Drawing.Text;
namespace DesktopMagic.BuiltInWindowElements;
namespace DesktopMagic.BuiltInPlugins;
internal class DatePlugin : Plugin
{
[Setting("short-date", "Short date")]
private readonly CheckBox shortDatecheckBox = new CheckBox(true);
private readonly CheckBox shortDateCheckBox = new CheckBox(true);
private DateTime oldDateTime = DateTime.MinValue;
private Color oldColor = Color.White;
private string oldFont = string.Empty;
private bool oldShortDatecheckBoxValue;
private bool oldShortDateCheckBoxValue;
public override int UpdateInterval => 1000;
public override Bitmap? Main()
{
if (oldDateTime.Date == DateTime.Now.Date && oldColor == Application.Theme.PrimaryColor && oldFont == Application.Theme.Font && oldShortDatecheckBoxValue == shortDatecheckBox.Value)
if (oldDateTime.Date == DateTime.Now.Date && oldColor == Application.Theme.PrimaryColor && oldFont == Application.Theme.Font && oldShortDateCheckBoxValue == shortDateCheckBox.Value)
{
return null;
}
@@ -28,9 +28,9 @@ internal class DatePlugin : Plugin
oldDateTime = DateTime.Now;
oldColor = Application.Theme.PrimaryColor;
oldFont = Application.Theme.Font;
oldShortDatecheckBoxValue = shortDatecheckBox.Value;
oldShortDateCheckBoxValue = shortDateCheckBox.Value;
string date = shortDatecheckBox.Value ? DateTime.Now.ToShortDateString() : DateTime.Now.ToLongDateString();
string date = shortDateCheckBox.Value ? DateTime.Now.ToShortDateString() : DateTime.Now.ToLongDateString();
Font font = new Font(Application.Theme.Font, 200);
@@ -9,7 +9,7 @@ using System.Collections.Generic;
using System.Drawing;
using System.Linq;
namespace DesktopMagic.BuiltInWindowElements;
namespace DesktopMagic.BuiltInPlugins;
internal class MusicVisualizerPlugin : Plugin
{
@@ -272,7 +272,7 @@ internal class MusicVisualizerPlugin : Plugin
}
catch (Exception ex)
{
App.Logger.Log(ex.Message, "Music Visualizer", LogSeverity.Error);
App.Logger.LogError(ex.Message, source: "Music Visualizer");
}
}
@@ -5,19 +5,33 @@ using System;
using System.Drawing;
using System.Drawing.Text;
namespace DesktopMagic.BuiltInWindowElements;
namespace DesktopMagic.BuiltInPlugins;
internal class TimePlugin : Plugin
{
[Setting("display-seconds", "Display Seconds")]
[Setting("display-seconds", "Show Seconds")]
private readonly CheckBox displaySecondsCheckBox = new CheckBox(true);
private string oldTime = string.Empty;
private Color oldColor = Color.White;
private string oldFont = string.Empty;
private bool oldDisplaySecondsCheckBoxValue;
public override int UpdateInterval => 1000;
public override Bitmap Main()
public override Bitmap? Main()
{
string time = displaySecondsCheckBox.Value ? DateTime.Now.ToLongTimeString() : DateTime.Now.ToShortTimeString();
if (oldTime == time && oldColor == Application.Theme.PrimaryColor && oldFont == Application.Theme.Font && oldDisplaySecondsCheckBoxValue == displaySecondsCheckBox.Value)
{
return null;
}
oldTime = time;
oldColor = Application.Theme.PrimaryColor;
oldFont = Application.Theme.Font;
oldDisplaySecondsCheckBoxValue = displaySecondsCheckBox.Value;
Font font = new Font(Application.Theme.Font, 200);
Bitmap bmp = new Bitmap(1, 1);
@@ -1,4 +1,5 @@
using DesktopMagic.Settings;
using DesktopMagic.Helpers;
using DesktopMagic.Settings;
using System.ComponentModel;
using System.Runtime.CompilerServices;
@@ -32,6 +33,23 @@ internal class MainWindowDataContext : INotifyPropertyChanged
}
}
public bool IsAutoStartEnabled
{
get => StartupManager.IsAutoStartEnabled();
set
{
if (value)
{
_ = StartupManager.EnableAutoStart();
}
else
{
_ = StartupManager.DisableAutoStart();
}
OnPropertyChanged();
}
}
public static DesktopMagicSettings GetSettings()
{
return settings;
@@ -1,14 +1,18 @@
using DesktopMagic.Plugins;
using DesktopMagic.Helpers;
using DesktopMagic.Plugins;
using MaterialDesignThemes.Wpf;
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
namespace DesktopMagic.DataContexts;
internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand command, bool installed = false) : INotifyPropertyChanged
internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand command, PluginEntryDataContext.Mode mode, string? path = null) : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
@@ -18,18 +22,38 @@ internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand co
public string? Description => pluginMetadata.Description;
public string Author => pluginMetadata.Author ?? (string)App.LanguageDictionary["unknown"];
public string? Version => pluginMetadata.Version ?? (string)App.LanguageDictionary["unknown"];
public string? Logo => pluginMetadata.IconUri?.ToString();
public DateTime? FormattedDateAdded => pluginMetadata.Added;
public DateTime? FormattedDateUpdated => pluginMetadata.Updated;
public DateTime? DateAdded => pluginMetadata.Added;
public DateTime? DateUpdated => pluginMetadata.Updated;
public uint Id => pluginMetadata.Id;
public string? Path => path;
public bool IsLocalPlugin => string.IsNullOrWhiteSpace(pluginMetadata.ProfileUri?.ToString());
public ICommand Command => command;
public Visibility InstallButtonVisibility => installed ? Visibility.Collapsed : Visibility.Visible;
public ButtonData InstallUninstallButtonData => new(mode == Mode.Install ? PackIconKind.Download : PackIconKind.Remove, GetInstallUninstallButtonText(), true, Command);
public Visibility RemoveButtonVisibility => installed ? Visibility.Visible : Visibility.Collapsed;
public ButtonData OpenButtonData
{
get
{
if (string.IsNullOrWhiteSpace(pluginMetadata.ProfileUri?.ToString()))
{
return new(PackIconKind.FolderOutline, (string)App.LanguageDictionary["folder"], path is not null, new CommandHandler(() => Process.Start("explorer.exe", path!)));
}
else
{
return new(PackIconKind.ExternalLink, "mod.io", true, new CommandHandler(OpenModIoPage));
}
}
}
public bool IsVisible
{
@@ -44,8 +68,37 @@ internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand co
public Visibility Visibility => IsVisible ? Visibility.Visible : Visibility.Collapsed;
private void OpenModIoPage()
{
ProcessStartInfo psi = new ProcessStartInfo
{
UseShellExecute = true,
FileName = pluginMetadata.ProfileUri?.ToString() ?? path
};
_ = Process.Start(psi);
}
private string GetInstallUninstallButtonText()
{
return mode switch
{
Mode.Install => (string)App.LanguageDictionary["install"],
Mode.Uninstall => (string)App.LanguageDictionary["uninstall"],
_ => throw new NotImplementedException()
};
}
private void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public record ButtonData(PackIconKind IconKind, string Text, bool IsEnabled, ICommand Command);
public enum Mode
{
Install,
Uninstall
}
}
@@ -12,6 +12,7 @@ internal class PluginManagerDataContext : INotifyPropertyChanged
private string installedPluginsSearchText = string.Empty;
private bool isLoading = true;
private bool isSearching;
private bool isAuthenticated = false;
public ObservableCollection<PluginEntryDataContext> AllPlugins { get; } = [];
public ObservableCollection<PluginEntryDataContext> InstalledPlugins { get; } = [];
@@ -58,6 +59,19 @@ internal class PluginManagerDataContext : INotifyPropertyChanged
}
}
public bool IsAuthenticated
{
get => isAuthenticated;
set
{
isAuthenticated = value;
OnPropertyChanged();
OnPropertyChanged(nameof(LoginButtonText));
}
}
public string LoginButtonText => isAuthenticated ? (string)App.LanguageDictionary["logout"] : (string)App.LanguageDictionary["login"];
protected void OnPropertyChanged([CallerMemberName] string? name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+64 -52
View File
@@ -1,61 +1,73 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<UseWPF>true</UseWPF>
<RootNamespace>DesktopMagic</RootNamespace>
<ApplicationIcon>icon.ico</ApplicationIcon>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<Authors>Stone_Red</Authors>
<Version>1.0.0.0</Version>
<PackageProjectUrl>https://github.com/Stone-Red-Code/DesktopMagic</PackageProjectUrl>
<RepositoryUrl>https://github.com/Stone-Red-Code/DesktopMagic</RepositoryUrl>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<FileVersion>1.0.0.0</FileVersion>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<OutputType>WinExe</OutputType>
<UseWPF>true</UseWPF>
<RootNamespace>DesktopMagic</RootNamespace>
<ApplicationIcon>icon.ico</ApplicationIcon>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<Authors>Stone_Red</Authors>
<Version>1.2.0.0</Version>
<PackageProjectUrl>https://github.com/Stone-Red-Code/DesktopMagic</PackageProjectUrl>
<RepositoryUrl>https://github.com/Stone-Red-Code/DesktopMagic</RepositoryUrl>
<AssemblyVersion>1.2.0.0</AssemblyVersion>
<FileVersion>1.2.0.0</FileVersion>
<TargetFramework>net8.0-windows7.0</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier>
<Nullable>enable</Nullable>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<None Remove="icon.ico" />
<None Remove="icons8_volunteering_26_85L_icon.ico" />
<None Remove="icon_Dark.ico" />
<None Remove="Resources\Images\modio-cog-blue.png" />
<None Remove="Resources\Images\modio-logo-bluedark.png" />
</ItemGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<ItemGroup>
<Resource Include="Resources\Images\modio-cog-blue.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
</ItemGroup>
<ItemGroup>
<None Remove="icon.ico" />
<None Remove="icons8_volunteering_26_85L_icon.ico" />
<None Remove="icon_Dark.ico" />
<None Remove="Resources\Images\modio-cog-blue.png" />
<None Remove="Resources\Images\modio-logo-bluedark.png" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="AlwaysUpToDate" Version="1.0.0.4" />
<PackageReference Include="BusyIndicators" Version="2.1.2" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="4.5.1" />
<PackageReference Include="MaterialDesignThemes" Version="4.9.0" />
<PackageReference Include="Modio.NET" Version="1.1.1" />
<PackageReference Include="NAudio" Version="2.2.1" />
<PackageReference Include="Stone_Red-C-Sharp-Utilities" Version="1.0.3.2" />
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Images\modio-cog-blue.png">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</Resource>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DesktopMagicPluginAPI\DesktopMagic.Api.csproj" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="BusyIndicators" Version="2.1.2" />
<PackageReference Include="CuteUtils" Version="1.0.0" />
<PackageReference Include="Interop.IWshRuntimeLibrary" Version="1.0.1" />
<PackageReference Include="MaterialDesignThemes" Version="5.1.0" />
<PackageReference Include="Modio" Version="1.0.0" />
<PackageReference Include="NAudio" Version="2.2.1" />
<PackageReference Include="System.Management" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<Resource Include="icon_Dark.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="icon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Images\modio-logo-bluedark.png" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\DesktopMagicPluginAPI\DesktopMagic.Api.csproj" />
</ItemGroup>
<ItemGroup>
<Resource Include="icon_Dark.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="icon.ico">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Resource>
<Resource Include="Resources\Images\modio-logo-bluedark.png" />
</ItemGroup>
<ItemGroup>
<None Update="AutoStart.ps1">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>
+4 -3
View File
@@ -8,10 +8,11 @@
mc:Ignorable="d"
ResizeMode="NoResize"
Title="ColorDialog"
WindowStartupLocation="CenterOwner"
SizeToContent="WidthAndHeight">
<Grid>
<StackPanel Margin="15">
<Label x:Name="label" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<Label x:Name="label" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" />
<DockPanel>
<Label Content="A:" Width="20" />
@@ -41,8 +42,8 @@
</TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
<Button x:Name="okButton" Content="{DynamicResource ok }" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Top" Width="100" Click="OkButton_Click" Cursor="Hand"/>
<Button x:Name="cancelButton" Content="{DynamicResource cancel }" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="100" Click="CancelButton_Click"/>
<Button x:Name="okButton" Content="{DynamicResource ok }" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Top" Width="100" Click="OkButton_Click" Cursor="Hand" />
<Button x:Name="cancelButton" Content="{DynamicResource cancel }" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="100" Click="CancelButton_Click" />
</StackPanel>
</StackPanel>
</Grid>
+5 -21
View File
@@ -1,7 +1,5 @@
using DesktopMagic.Helpers;
using System;
using System.Threading;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
@@ -17,12 +15,14 @@ public partial class ColorDialog : Window
public Brush ResultBrush { get; private set; } = Brushes.Transparent;
public ColorDialog(string content, System.Drawing.Color defaultColor, string title = "ColorDialog")
public ColorDialog(string content, System.Drawing.Color defaultColor, string title = App.AppName)
{
InitializeComponent();
Resources.MergedDictionaries.Add(App.LanguageDictionary);
label.Content = content;
Title = title;
SetLanguageDictionary();
alphaSlider.Value = defaultColor.A;
redSlider.Value = defaultColor.R;
@@ -97,7 +97,7 @@ public partial class ColorDialog : Window
private void SetColorText()
{
if (alphaSlider.Value == 255)
if ((int)alphaSlider.Value == 255)
{
colorHexTextBox.Text = "#";
}
@@ -108,20 +108,4 @@ public partial class ColorDialog : Window
colorHexTextBox.Text += ((int)redSlider.Value).ToString("X2") + ((int)greenSlider.Value).ToString("X2") + ((int)blueSlider.Value).ToString("X2");
}
private void SetLanguageDictionary()
{
ResourceDictionary dict = [];
string currentCulture = Thread.CurrentThread.CurrentCulture.ToString();
if (currentCulture.Contains("de"))
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.de.xaml", UriKind.Relative);
}
else
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.en.xaml", UriKind.Relative);
}
Resources.MergedDictionaries.Add(dict);
}
}
+5 -4
View File
@@ -7,14 +7,15 @@
mc:Ignorable="d"
Title="InputDialog"
ResizeMode="NoResize"
WindowStartupLocation="CenterOwner"
SizeToContent="WidthAndHeight">
<Grid>
<StackPanel VerticalAlignment="Center" HorizontalAlignment="Center" Margin="15">
<Label x:Name="label" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="280" VerticalContentAlignment="Center"/>
<Label x:Name="label" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" />
<TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="280" VerticalContentAlignment="Center" />
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
<Button x:Name="okButton" Content="{DynamicResource ok }" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Top" Width="100" Click="OkButton_Click" Cursor="Hand"/>
<Button x:Name="cancelButton" Content="{DynamicResource cancel }" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="100" Click="CancelButton_Click"/>
<Button x:Name="okButton" Content="{DynamicResource ok }" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Top" Width="100" Click="OkButton_Click" Cursor="Hand" />
<Button x:Name="cancelButton" Content="{DynamicResource cancel }" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="100" Click="CancelButton_Click" />
</StackPanel>
</StackPanel>
</Grid>
+5 -21
View File
@@ -1,6 +1,4 @@
using System;
using System.Threading;
using System.Windows;
using System.Windows;
namespace DesktopMagic.Dialogs;
@@ -12,12 +10,14 @@ public partial class InputDialog : Window
set => textBox.Text = value;
}
public InputDialog(string content, string title = "InputDialog")
public InputDialog(string content, string title = App.AppName)
{
InitializeComponent();
Resources.MergedDictionaries.Add(App.LanguageDictionary);
label.Content = content;
Title = title;
SetLanguageDictionary();
}
private void OkButton_Click(object sender, RoutedEventArgs e)
@@ -29,20 +29,4 @@ public partial class InputDialog : Window
{
DialogResult = false;
}
private void SetLanguageDictionary()
{
ResourceDictionary dict = [];
string currentCulture = Thread.CurrentThread.CurrentCulture.ToString();
if (currentCulture.Contains("de"))
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.de.xaml", UriKind.Relative);
}
else
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.en.xaml", UriKind.Relative);
}
Resources.MergedDictionaries.Add(dict);
}
}
+76
View File
@@ -0,0 +1,76 @@
<Window x:Class="DesktopMagic.Dialogs.ThemeDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:DesktopMagic.Dialogs"
mc:Ignorable="d"
ResizeMode="NoResize"
Title="ThemeDialog"
WindowStartupLocation="CenterOwner"
SizeToContent="WidthAndHeight">
<Grid>
<StackPanel Margin="15">
<Label x:Name="label" Content="Label" HorizontalAlignment="Left" VerticalAlignment="Top" />
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Margin="{StaticResource DefaultMargin}" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="Display Font: " Grid.Column="0" Grid.Row="0" VerticalAlignment="Center" Loaded="TextBlock_Loaded"/>
<ComboBox x:Name="fontComboBox" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Top" SelectionChanged="FontComboBox_SelectionChanged" Margin="0,0,0,5" />
<TextBlock Text="Corner Radius: " Grid.Column="0" Grid.Row="1" VerticalAlignment="Center"></TextBlock>
<TextBox x:Name="cornerRadiusTextBox" Grid.Column="1" Grid.Row="1" TextChanged="CornerRadiusTextBox_TextChanged" materialDesign:HintAssist.Hint="Enter a number">
<materialDesign:TextFieldAssist.CharacterCounterStyle>
<Style TargetType="TextBlock" />
</materialDesign:TextFieldAssist.CharacterCounterStyle>
</TextBox>
<TextBlock Text="Margin: " Grid.Column="0" Grid.Row="3" VerticalAlignment="Center"></TextBlock>
<TextBox x:Name="marginTextBox" Grid.Column="1" Grid.Row="3" TextChanged="MarginTextBox_TextChanged" materialDesign:HintAssist.Hint="Enter a number">
<materialDesign:TextFieldAssist.CharacterCounterStyle>
<Style TargetType="TextBlock" />
</materialDesign:TextFieldAssist.CharacterCounterStyle>
</TextBox>
</Grid>
<StackPanel Grid.Column="1" Margin="{StaticResource DefaultMargin}" HorizontalAlignment="Stretch">
<DockPanel Margin="0,0,0,5">
<Border CornerRadius="1" BorderThickness="1.5" BorderBrush="Gray" Height="23" Width="23" Margin="0,0,5,0">
<Rectangle x:Name="primaryColorRechtangle" Fill="White" />
</Border>
<Button Content="Change Primary Color" Height="23" FontSize="12" FontWeight="Regular" Click="ChangePrimaryColorButton_Click" />
</DockPanel>
<DockPanel Margin="0,0,0,5">
<Border CornerRadius="1" BorderThickness="1.5" BorderBrush="Gray" Height="23" Width="23" Margin="0,0,5,0">
<Rectangle x:Name="secondaryColorRechtangle" Fill="White" />
</Border>
<Button Content="Change Secondary Color" Height="23" FontSize="12" FontWeight="Regular" Click="ChangeSecondaryColorButton_Click" />
</DockPanel>
<DockPanel>
<Border CornerRadius="1" BorderThickness="1.5" BorderBrush="Gray" Height="23" Width="23" Margin="0,0,5,0">
<Rectangle x:Name="backgroundColorRechtangle" Fill="White" />
</Border>
<Button Content="Change Background Color" Height="23" FontSize="12" FontWeight="Regular" Click="ChangeBackgroundColorButton_Click" />
</DockPanel>
</StackPanel>
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
<Button x:Name="okButton" Content="{DynamicResource ok }" HorizontalAlignment="Left" Margin="0,0,10,0" VerticalAlignment="Top" Width="100" Click="OkButton_Click" Cursor="Hand" />
<Button x:Name="cancelButton" Content="{DynamicResource cancel }" HorizontalAlignment="Left" Margin="0,0,0,0" VerticalAlignment="Top" Width="100" Click="CancelButton_Click" />
</StackPanel>
</StackPanel>
</Grid>
</Window>
@@ -0,0 +1,143 @@
using DesktopMagic.Helpers;
using DesktopMagic.Plugins;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace DesktopMagic.Dialogs;
/// <summary>
/// Interaction logic for ColorDialog.xaml
/// </summary>
public partial class ThemeDialog : Window
{
private readonly Theme theme;
public ThemeDialog(string content, Theme theme, string title = App.AppName)
{
this.theme = theme;
InitializeComponent();
Resources.MergedDictionaries.Add(App.LanguageDictionary);
cornerRadiusTextBox.Text = theme.CornerRadius.ToString();
marginTextBox.Text = theme.Margin.ToString();
primaryColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(theme.PrimaryColor));
secondaryColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(theme.SecondaryColor));
backgroundColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(theme.BackgroundColor));
label.Content = content;
Title = title;
}
private void OkButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
}
private void TextBlock_Loaded(object sender, RoutedEventArgs e)
{
int index = 0;
foreach (FontFamily ff in Fonts.SystemFontFamilies)
{
ComboBoxItem comboBoxItem = new()
{
FontFamily = ff,
Content = ff.ToString()
};
_ = fontComboBox.Items.Add(comboBoxItem);
if (ff.ToString() == theme.Font)
{
fontComboBox.SelectedIndex = index;
}
index++;
}
if (fontComboBox.SelectedIndex == -1)
{
fontComboBox.SelectedIndex = 0;
}
}
private void FontComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
theme.Font = fontComboBox.SelectedValue.ToString()!.Replace("System.Windows.Controls.ComboBoxItem: ", "");
}
private void ChangePrimaryColorButton_Click(object sender, RoutedEventArgs e)
{
ColorDialog colorDialog = new ColorDialog("Set Primary Color", theme.PrimaryColor)
{
Owner = this
};
if (colorDialog.ShowDialog() == true)
{
theme.PrimaryColor = colorDialog.ResultColor;
primaryColorRechtangle.Fill = colorDialog.ResultBrush;
}
}
private void ChangeSecondaryColorButton_Click(object sender, RoutedEventArgs e)
{
ColorDialog colorDialog = new ColorDialog("Set Secondary Color", theme.SecondaryColor)
{
Owner = this
};
if (colorDialog.ShowDialog() == true)
{
theme.SecondaryColor = colorDialog.ResultColor;
secondaryColorRechtangle.Fill = colorDialog.ResultBrush;
}
}
private void ChangeBackgroundColorButton_Click(object sender, RoutedEventArgs e)
{
ColorDialog colorDialog = new ColorDialog("Set Background Color", theme.BackgroundColor)
{
Owner = this
};
if (colorDialog.ShowDialog() == true)
{
theme.BackgroundColor = colorDialog.ResultColor;
backgroundColorRechtangle.Fill = colorDialog.ResultBrush;
}
}
private void CornerRadiusTextBox_TextChanged(object? sender, TextChangedEventArgs? e)
{
bool success = int.TryParse(cornerRadiusTextBox.Text, out int cornerRadius);
if (success)
{
cornerRadiusTextBox.Foreground = Brushes.Black;
theme.CornerRadius = cornerRadius;
}
else
{
cornerRadiusTextBox.Foreground = Brushes.Red;
}
}
private void MarginTextBox_TextChanged(object? sender, TextChangedEventArgs? e)
{
bool success = int.TryParse(marginTextBox.Text, out int margin);
if (success)
{
marginTextBox.Foreground = Brushes.Black;
theme.Margin = margin;
}
else
{
marginTextBox.Foreground = Brushes.Red;
}
}
}
+4
View File
@@ -8,3 +8,7 @@ using System.Diagnostics.CodeAnalysis;
[assembly: SuppressMessage("Interoperability", "CA1416:Validate platform compatibility", Justification = "Windows only application")]
[assembly: SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "No need to")]
[assembly: SuppressMessage("Minor Code Smell", "S1075:URIs should not be hardcoded", Justification = "<Pending>")]
[assembly: SuppressMessage("Critical Code Smell", "S2696:Instance members should not write to \"static\" fields", Justification = "<Pending>", Scope = "member", Target = "~P:DesktopMagic.DataContexts.MainWindowDataContext.Settings")]
[assembly: SuppressMessage("Major Code Smell", "S3885:\"Assembly.Load\" should be used", Justification = "Assembly.Load does not load dependencies", Scope = "member", Target = "~M:DesktopMagic.PluginWindow.ExecuteSource")]
[assembly: SuppressMessage("Minor Code Smell", "S2325:Methods and properties that don't access instance data should be static", Justification = "<Pending>", Scope = "member", Target = "~M:DesktopMagic.MainWindow.OpenPluginsFolderButton_Click(System.Object,System.Windows.RoutedEventArgs)")]
[assembly: SuppressMessage("Minor Code Smell", "S2325:Methods and properties that don't access instance data should be static", Justification = "<Pending>", Scope = "member", Target = "~M:DesktopMagic.MainWindow.ScrollViewer_PreviewMouseWheel(System.Object,System.Windows.Input.MouseWheelEventArgs)")]
+93
View File
@@ -0,0 +1,93 @@
using System;
using System.IO;
using System.Runtime.InteropServices;
using System.Text;
namespace DesktopMagic.Helpers;
internal static class FileUtilities
{
public static bool ExistsOnPath(string fileName)
{
return GetFullPath(fileName) is not null;
}
public static string? GetFullPath(string fileName)
{
if (File.Exists(fileName))
{
return Path.GetFullPath(fileName);
}
string? values = Environment.GetEnvironmentVariable("PATH");
if (string.IsNullOrEmpty(values))
{
return null;
}
foreach (string path in values.Split(Path.PathSeparator))
{
string fullPath = Path.Combine(path, fileName);
if (File.Exists(fullPath))
{
return fullPath;
}
}
return null;
}
public static bool HasAssociatedProgram(string extension)
{
return GetAssociatedProgram(extension) is not null;
}
public static string? GetAssociatedProgram(string extension)
{
uint pcchOut = 0;
_ = AssocQueryString(AssocF.Verify, AssocStr.Executable, extension, null, null, ref pcchOut);
StringBuilder pszOut = new StringBuilder((int)pcchOut);
_ = AssocQueryString(AssocF.Verify, AssocStr.Executable, extension, null, pszOut, ref pcchOut);
if (File.Exists(pszOut.ToString()))
{
return pszOut.ToString();
}
return null;
}
[DllImport("Shlwapi.dll", SetLastError = true, CharSet = CharSet.Unicode)]
private static extern uint AssocQueryString(AssocF flags, AssocStr str, string pszAssoc, string? pszExtra, [Out] StringBuilder? pszOut, [In][Out] ref uint pcchOut);
[Flags]
public enum AssocF
{
Init_NoRemapCLSID = 0x1,
Init_ByExeName = 0x2,
Open_ByExeName = 0x2,
Init_DefaultToStar = 0x4,
Init_DefaultToFolder = 0x8,
NoUserSettings = 0x10,
NoTruncate = 0x20,
Verify = 0x40,
RemapRunDll = 0x80,
NoFixUps = 0x100,
IgnoreBaseClass = 0x200
}
public enum AssocStr
{
Command = 1,
Executable,
FriendlyDocName,
FriendlyAppName,
NoOpen,
ShellNewValue,
DDECommand,
DDEIfExec,
DDEApplication,
DDETopic
}
}
+1 -1
View File
@@ -47,7 +47,7 @@ internal class SampleAggregator
}
}
private bool IsPowerOfTwo(int x)
private static bool IsPowerOfTwo(int x)
{
return (x & (x - 1)) == 0;
}
@@ -127,19 +127,22 @@ internal class SettingElementGenerator(ComboBox optionsComboBox)
}
else if (settingElement.Input is DesktopMagic.Api.Settings.IntegerUpDown eIntegerUpDown)
{
Xceed.Wpf.Toolkit.IntegerUpDown integerUpDown = new()
MaterialDesignThemes.Wpf.NumericUpDown numericUpDown = new()
{
Value = eIntegerUpDown.Value,
Minimum = eIntegerUpDown.Minimum,
Maximum = eIntegerUpDown.Maximum,
IncreaseContent = new Label() { Content = "+" },
DecreaseContent = new Label() { Content = "" },
VerticalAlignment = VerticalAlignment.Center,
HorizontalAlignment = HorizontalAlignment.Stretch
HorizontalAlignment = HorizontalAlignment.Stretch,
AllowChangeOnScroll = true
};
integerUpDown.ValueChanged += (_s, _e) =>
numericUpDown.ValueChanged += (_s, _e) =>
{
try
{
eIntegerUpDown.Value = integerUpDown.Value.GetValueOrDefault();
eIntegerUpDown.Value = numericUpDown.Value;
}
catch (Exception ex)
{
@@ -148,12 +151,12 @@ internal class SettingElementGenerator(ComboBox optionsComboBox)
};
eIntegerUpDown.OnValueChanged += () =>
{
integerUpDown.Dispatcher.Invoke(() =>
numericUpDown.Dispatcher.Invoke(() =>
{
integerUpDown.Value = eIntegerUpDown.Value;
numericUpDown.Value = eIntegerUpDown.Value;
});
};
_ = dockPanel.Children.Add(integerUpDown);
_ = dockPanel.Children.Add(numericUpDown);
}
else if (settingElement.Input is DesktopMagic.Api.Settings.Slider eSlider)
{
@@ -203,7 +206,8 @@ internal class SettingElementGenerator(ComboBox optionsComboBox)
{
try
{
eComboBox.Value = comboBox.SelectedItem.ToString() ?? string.Empty;
comboBox.SelectedItem ??= eComboBox.Value;
eComboBox.Value = comboBox.SelectedItem?.ToString() ?? eComboBox.Value;
}
catch (Exception ex)
{
@@ -222,7 +226,7 @@ internal class SettingElementGenerator(ComboBox optionsComboBox)
private void DisplayException(string message)
{
App.Logger.Log(message, "PluginInput");
App.Logger.LogInfo(message, source: "PluginInput");
_ = MessageBox.Show("File execution error:\n" + message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
int index = MainWindow.WindowNames.IndexOf(optionsComboBox.SelectedItem.ToString() ?? string.Empty);
@@ -0,0 +1,82 @@
using IWshRuntimeLibrary;
using System;
using System.IO;
using System.Reflection;
using System.Windows;
namespace DesktopMagic.Helpers;
public enum AutoStartStatus
{
Success = 0,
InvalidParameters = 1,
AlreadyEnabled = 2,
AlreadyDisabled = 3,
UnexpectedError = 4
}
public static class StartupManager
{
private static readonly string appPath = Path.ChangeExtension(Assembly.GetEntryAssembly()?.Location ?? throw new InvalidOperationException("Failed to get the application path."), ".exe");
private static readonly string startupFolder = Environment.GetFolderPath(Environment.SpecialFolder.Startup);
private static readonly string shortcutPath = Path.Combine(startupFolder, Path.GetFileNameWithoutExtension(appPath) + ".lnk");
public static bool IsAutoStartEnabled()
{
return System.IO.File.Exists(shortcutPath);
}
public static AutoStartStatus EnableAutoStart()
{
if (IsAutoStartEnabled())
{
return AutoStartStatus.AlreadyEnabled;
}
try
{
WshShell shell = new WshShell();
IWshShortcut shortcut = (IWshShortcut)shell.CreateShortcut(shortcutPath);
shortcut.TargetPath = appPath;
shortcut.WorkingDirectory = Path.GetDirectoryName(appPath);
shortcut.Save();
return AutoStartStatus.Success;
}
catch
{
return AutoStartStatus.UnexpectedError;
}
}
public static AutoStartStatus DisableAutoStart()
{
if (!IsAutoStartEnabled())
{
return AutoStartStatus.AlreadyDisabled;
}
try
{
System.IO.File.Delete(shortcutPath);
return AutoStartStatus.Success;
}
catch
{
return AutoStartStatus.UnexpectedError;
}
}
public static void ToggleAutoStart()
{
AutoStartStatus status = IsAutoStartEnabled() ? DisableAutoStart() : EnableAutoStart();
_ = status switch
{
AutoStartStatus.Success => MessageBox.Show("Auto-start setting changed successfully."),
AutoStartStatus.AlreadyEnabled => MessageBox.Show("Auto-start is already enabled."),
AutoStartStatus.AlreadyDisabled => MessageBox.Show("Auto-start is already disabled."),
_ => MessageBox.Show("Failed to change auto-start setting."),
};
}
}
+1 -1
View File
@@ -1,7 +1,7 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
#pragma warning disable
namespace DesktopMagic.Helpers;
internal class W32
+1 -1
View File
@@ -3,7 +3,7 @@ using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Interop;
using System.Windows.Shapes;
#pragma warning disable
namespace DesktopMagic
{
using static NativeMethods;
+59 -56
View File
@@ -20,12 +20,11 @@
MinHeight="520"
MinWidth="570"
WindowState="Minimized"
StateChanged="Window_StateChanged"
Loaded="Window_Loaded">
<busyIndicator:BusyMask x:Name="BusyIndicator" IsBusy="{Binding IsLoading}" IndicatorType="Cogs" BusyContent="Please wait..." BusyContentMargin="0,20,0,0" IsBusyAtStartup="False">
<Grid>
<TextBlock TextWrapping="Wrap" Text="0" VerticalAlignment="Top" FontFamily="Comic Sans MS" Loaded="TextBlock_Loaded" Foreground="Transparent" />
<TextBlock TextWrapping="Wrap" Text="0" VerticalAlignment="Top" FontFamily="Comic Sans MS" Foreground="Transparent" />
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
@@ -39,7 +38,7 @@
<DockPanel Margin="0,0,2.5,0">
<Grid DockPanel.Dock="Top">
<Rectangle Grid.Row="1" Fill="#FFECECEC" Height="24" />
<CheckBox x:Name="EditCheckBox" VerticalAlignment="Center" Grid.Row="1" Content="{DynamicResource edit}" Click="EditCheckBox_Click" Foreground="Black" BorderBrush="#FF323232" Style="{StaticResource MaterialDesignDarkCheckBox}" IsChecked="True" />
<CheckBox x:Name="editCheckBox" VerticalAlignment="Center" Grid.Row="1" Content="{DynamicResource editLayout}" Click="EditCheckBox_Click" Foreground="Black" BorderBrush="#FF323232" Style="{StaticResource MaterialDesignDarkCheckBox}" IsChecked="True" />
</Grid>
<ScrollViewer Background="#FFBBBBBB" PreviewMouseWheel="ScrollViewer_PreviewMouseWheel">
<ItemsControl ItemsSource="{Binding Settings.CurrentLayout.Plugins}">
@@ -76,53 +75,26 @@
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Margin="{StaticResource DefaultMargin}" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<TextBlock Text="Display Font: " Grid.Column="0" Grid.Row="0" VerticalAlignment="Center"></TextBlock>
<ComboBox x:Name="fontComboBox" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Stretch" VerticalAlignment="Top" SelectionChanged="FontComboBox_SelectionChanged" Margin="0,0,0,5" />
<TextBlock Text="Corner Radius: " Grid.Column="0" Grid.Row="1" VerticalAlignment="Center"></TextBlock>
<TextBox x:Name="cornerRadiusTextBox" Grid.Column="1" Grid.Row="1" TextChanged="CornerRadiusTextBox_TextChanged" materialDesign:HintAssist.Hint="Enter a number">
<materialDesign:TextFieldAssist.CharacterCounterStyle>
<Style TargetType="TextBlock" />
</materialDesign:TextFieldAssist.CharacterCounterStyle>
</TextBox>
<TextBlock Text="Margin: " Grid.Column="0" Grid.Row="3" VerticalAlignment="Center"></TextBlock>
<TextBox x:Name="marginTextBox" Grid.Column="1" Grid.Row="3" TextChanged="MarginTextBox_TextChanged" materialDesign:HintAssist.Hint="Enter a number">
<materialDesign:TextFieldAssist.CharacterCounterStyle>
<Style TargetType="TextBlock" />
</materialDesign:TextFieldAssist.CharacterCounterStyle>
</TextBox>
</Grid>
<StackPanel Grid.Column="1" Margin="{StaticResource DefaultMargin}" HorizontalAlignment="Stretch">
<DockPanel Margin="0,0,0,5">
<Border CornerRadius="1" BorderThickness="1.5" BorderBrush="Gray" Height="23" Width="23" Margin="0,0,5,0">
<Rectangle x:Name="primaryColorRechtangle" Fill="White" />
</Border>
<Button Content="Change Primary Color" Height="23" FontSize="12" FontWeight="Regular" Click="ChangePrimaryColorButton_Click" />
</DockPanel>
<DockPanel Margin="0,0,0,5">
<Border CornerRadius="1" BorderThickness="1.5" BorderBrush="Gray" Height="23" Width="23" Margin="0,0,5,0">
<Rectangle x:Name="secondaryColorRechtangle" Fill="White" />
</Border>
<Button Content="Change Secondary Color" Height="23" FontSize="12" FontWeight="Regular" Click="ChangeSecondaryColorButton_Click" />
</DockPanel>
<DockPanel>
<Border CornerRadius="1" BorderThickness="1.5" BorderBrush="Gray" Height="23" Width="23" Margin="0,0,5,0">
<Rectangle x:Name="backgroundColorRechtangle" Fill="White" />
</Border>
<Button Content="Change Background Color" Height="23" FontSize="12" FontWeight="Regular" Click="ChangeBackgroundColorButton_Click" />
</DockPanel>
<ListBox x:Name="themesListBox" Grid.Row="0" Grid.ColumnSpan="1" Margin="{StaticResource DefaultMargin}" ItemsSource="{Binding Settings.Themes}" DisplayMemberPath="Name" SelectedValue="{Binding Settings.CurrentLayout.CurrentThemeName}" SelectedValuePath="Name" />
<StackPanel Grid.Row="0" Grid.Column="1" VerticalAlignment="Center" Margin="{StaticResource DefaultMargin}">
<Button x:Name="addThemeButton" Margin="0,0,0,5" HorizontalAlignment="Stretch" Click="AddThemeButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Add" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource newTheme}" />
</StackPanel>
</Button>
<Button x:Name="deleteThemeButton" Margin="0,0,0,5" HorizontalAlignment="Stretch" Click="DeleteThemeButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="DeleteOutline" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource deleteTheme}" />
</StackPanel>
</Button>
<Button x:Name="changeThemeButton" Margin="0,0,0,5" HorizontalAlignment="Stretch" Click="ChangeThemeButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="PaletteOutline" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource changeTheme}" />
</StackPanel>
</Button>
</StackPanel>
<Grid Grid.Row="1" Grid.ColumnSpan="2" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
@@ -134,16 +106,47 @@
<Rectangle Fill="#FFC5C5C5" Stroke="#FFC5C5C5" Grid.ColumnSpan="3" />
<StackPanel Margin="{StaticResource DefaultMargin}" VerticalAlignment="Bottom">
<ComboBox x:Name="layoutsComboBox" ItemsSource="{Binding Settings.Layouts}" DisplayMemberPath="Name" SelectedValue="{Binding Settings.CurrentLayoutName}" SelectedValuePath="Name" HorizontalAlignment="Left" Margin="0,0,0,5" Width="170" Height="20" SelectionChanged="LayoutsComboBox_SelectionChanged" />
<Button x:Name="newLayoutButton" Content="{DynamicResource newLayout}" Margin="0,0,0,5" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="170" Click="NewLayoutButton_Click" FontWeight="Regular" />
<Button x:Name="removeLayoutButton" Content="{DynamicResource deleteLayout}" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="170" Click="RemoveLayoutButton_Click" FontWeight="Regular" />
<Button x:Name="newLayoutButton" Margin="0,0,0,5" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="170" Click="NewLayoutButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Add" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource newLayout}" />
</StackPanel>
</Button>
<Button x:Name="removeLayoutButton" HorizontalAlignment="Left" VerticalAlignment="Bottom" Width="170" Click="RemoveLayoutButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="DeleteOutline" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource deleteLayout}" />
</StackPanel>
</Button>
</StackPanel>
<StackPanel Grid.Column="1" Margin="{StaticResource DefaultMargin}" VerticalAlignment="Bottom">
<Button x:Name="updatePluginsButton" Content="{DynamicResource updatePlugins}" Margin="0,0,0,5" HorizontalAlignment="Center" Width="170" Click="UpdatePluginsButton_Click" FontWeight="Regular" />
<Button x:Name="githubButton" Content="GitHub" HorizontalAlignment="Center" Width="170" Click="GitHubButton_Click" FontWeight="Regular" Cursor="Hand" />
<Button x:Name="updatePluginsButton" Margin="0,0,0,5" HorizontalAlignment="Center" Width="170" Click="UpdatePluginsButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Reload" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource updatePlugins}" />
</StackPanel>
</Button>
<Button x:Name="githubButton" HorizontalAlignment="Center" Width="170" Click="GitHubButton_Click" FontWeight="Regular" Cursor="Hand">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Github" Margin="0 0 10 0" />
<TextBlock Text="GitHub" />
</StackPanel>
</Button>
</StackPanel>
<StackPanel Grid.Column="2" Margin="{StaticResource DefaultMargin}" VerticalAlignment="Bottom">
<Button x:Name="downloadPluginsButton" Content="{DynamicResource pluginManager}" Margin="0,0,0,5" HorizontalAlignment="Right" Width="170" Click="PluginManagerButton_Click" FontWeight="Regular" Cursor="Hand" />
<Button x:Name="openPluginsFolderButton" Content="{DynamicResource openPluginsFolder}" HorizontalAlignment="Right" Width="170" Click="OpenPluginsFolderButton_Click" FontWeight="Regular" />
<CheckBox x:Name="autoStartCheckBox" Content="{DynamicResource autoStart}" Foreground="Black" BorderBrush="#FF323232" Margin="0,0,0,5" Width="170" Height="20" Style="{StaticResource MaterialDesignDarkCheckBox}" IsChecked="{Binding IsAutoStartEnabled}" />
<Button x:Name="downloadPluginsButton" Margin="0,0,0,5" HorizontalAlignment="Right" Width="170" Click="PluginManagerButton_Click" FontWeight="Regular" Cursor="Hand">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="ExtensionOutline" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource pluginManager}" />
</StackPanel>
</Button>
<Button x:Name="openPluginsFolderButton" HorizontalAlignment="Right" Width="170" Click="OpenPluginsFolderButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="FolderOutline" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource pluginsFolder}" />
</StackPanel>
</Button>
</StackPanel>
</Grid>
</Grid>
+149 -203
View File
@@ -1,4 +1,4 @@
using DesktopMagic.BuiltInWindowElements;
using DesktopMagic.BuiltInPlugins;
using DesktopMagic.DataContexts;
using DesktopMagic.Dialogs;
using DesktopMagic.Helpers;
@@ -10,13 +10,9 @@ using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace DesktopMagic
{
@@ -28,17 +24,16 @@ namespace DesktopMagic
private readonly Dictionary<PluginMetadata, Type> builtInPlugins = new()
{
{new("Music Visualizer", 1), typeof(MusicVisualizerPlugin)},
{new("Time",2), typeof(TimePlugin)},
{new("Date",3), typeof(DatePlugin)},
{new("Cpu Usage", 4), typeof(CpuMonitorPlugin)}
{new((string)App.LanguageDictionary["musicVisualizer"], 1), typeof(MusicVisualizerPlugin)},
{new((string)App.LanguageDictionary["time"],2), typeof(TimePlugin)},
{new((string)App.LanguageDictionary["date"],3), typeof(DatePlugin)},
{new((string)App.LanguageDictionary["cpuUsage"], 4), typeof(CpuMonitorPlugin)}
};
private bool loaded = false;
private bool blockWindowsClosing = true;
public static List<PluginWindow> Windows { get; } = [];
public static List<string> WindowNames { get; } = [];
internal static bool EditMode { get; set; } = false;
private DesktopMagicSettings Settings
{
@@ -53,24 +48,35 @@ namespace DesktopMagic
try
{
Stream iconStream = Application.GetResourceStream(new Uri("pack://application:,,,/DesktopMagic;component/icon.ico")).Stream;
notifyIcon.Click += TaskbarIcon_TrayLeftClick;
notifyIcon.MouseClick += NotifyIcon_MouseClick;
notifyIcon.Visible = true;
notifyIcon.Text = App.AppName;
notifyIcon.Icon = new System.Drawing.Icon(iconStream);
notifyIcon.ContextMenuStrip = new System.Windows.Forms.ContextMenuStrip()
{
Items =
{
new System.Windows.Forms.ToolStripMenuItem((string)App.LanguageDictionary["open"], null, (s, e) => RestoreWindow()),
new System.Windows.Forms.ToolStripMenuItem((string)App.LanguageDictionary["toggleEditMode"], null, (s, e) => { editCheckBox.IsChecked = !editCheckBox.IsChecked; EditCheckBox_Click(null, null); }),
new System.Windows.Forms.ToolStripMenuItem((string)App.LanguageDictionary["pluginManager"], null, (s, e) => PluginManagerButton_Click(null!, null!)),
new System.Windows.Forms.ToolStripMenuItem("GitHub", null, (s, e) => GitHubButton_Click(null!, null!)),
new System.Windows.Forms.ToolStripMenuItem((string)App.LanguageDictionary["quit"], null, (s, e) => Quit()),
}
};
InitializeComponent();
SetLanguageDictionary();
Resources.MergedDictionaries.Add(App.LanguageDictionary);
#if DEBUG
Title = $"{App.AppName} - Dev {Assembly.GetExecutingAssembly().GetName().Version}";
Title = $"{App.AppName} - Dev {System.Windows.Forms.Application.ProductVersion}";
#else
Title = $"{App.AppName} - {Assembly.GetExecutingAssembly().GetName().Version}";
Title = $"{App.AppName} - {System.Windows.Forms.Application.ProductVersion}";
#endif
}
catch (Exception ex)
{
_ = MessageBox.Show(ex.ToString());
_ = MessageBox.Show(ex.ToString(), App.AppName, MessageBoxButton.OK, MessageBoxImage.Error);
}
}
@@ -82,28 +88,22 @@ namespace DesktopMagic
{
try
{
if (!Directory.Exists(App.ApplicationDataPath + "\\Plugins"))
{
_ = Directory.CreateDirectory(App.ApplicationDataPath + "\\Plugins");
}
App.Logger.Log("Created Plugins Folder", "Main");
//Write To Log File and Load Elements
App.Logger.Log("Loading Plugin names", "Main");
App.Logger.LogInfo("Loading Plugin names", source: "Main");
LoadPlugins();
App.Logger.Log("Loading Layout names", "Main");
App.Logger.LogInfo("Loading Layout names", source: "Main");
LoadSettings();
App.Logger.Log("Loading Layout", "Main");
App.Logger.LogInfo("Loading Layout", source: "Main");
LoadLayout();
loaded = true;
App.Logger.Log("Window Loaded", "Main");
App.Logger.LogInfo("Window Loaded", source: "Main");
}
catch (Exception ex)
{
App.Logger.Log(ex.Message, "Main", LogSeverity.Error);
_ = MessageBox.Show(ex.ToString());
App.Logger.LogError(ex.Message, source: "Main");
_ = MessageBox.Show(ex.ToString(), App.AppName, MessageBoxButton.OK, MessageBoxImage.Error);
}
}
@@ -117,22 +117,20 @@ namespace DesktopMagic
plugins.Add(buildInPlugin.Id, new(buildInPlugin, string.Empty));
}
string pluginsPath = App.ApplicationDataPath + "\\Plugins";
foreach (string directory in Directory.GetDirectories(pluginsPath))
foreach (string directory in Directory.GetDirectories(App.PluginsPath))
{
string? pluginDllPath = Directory.GetFiles(directory, "main.dll").FirstOrDefault();
string? pluginMetadataPath = Directory.GetFiles(directory, "metadata.json").FirstOrDefault();
if (pluginDllPath is null)
{
App.Logger.Log($"Plugin \"{directory}\" has no \"main.dll\"", "Main", LogSeverity.Error);
App.Logger.LogError($"Plugin \"{directory}\" has no \"main.dll\"", source: "Main");
continue;
}
if (pluginMetadataPath is null)
{
App.Logger.Log($"Plugin \"{directory}\" has no \"metadata.json\"", "Main", LogSeverity.Warn);
App.Logger.LogWarn($"Plugin \"{directory}\" has no \"metadata.json\"", source: "Main");
continue;
}
@@ -140,13 +138,13 @@ namespace DesktopMagic
if (pluginMetadata is null)
{
App.Logger.Log($"Plugin \"{directory}\" has no valid \"metadata.json\"", "Main", LogSeverity.Error);
App.Logger.LogError($"Plugin \"{directory}\" has no valid \"metadata.json\"", source: "Main");
continue;
}
if (plugins.ContainsKey(pluginMetadata.Id))
{
App.Logger.Log($"Plugin \"{directory}\" has the same id as another plugin", "Main", LogSeverity.Error);
App.Logger.LogError($"Plugin \"{directory}\" has the same id as another plugin", source: "Main");
continue;
}
@@ -161,7 +159,11 @@ namespace DesktopMagic
private void EditCheckBox_Click(object? sender, RoutedEventArgs? e)
{
EditMode = EditCheckBox.IsChecked == true;
foreach (PluginWindow window in Windows)
{
window.SetEditMode(editCheckBox.IsChecked == true);
}
SaveSettings();
}
@@ -204,7 +206,7 @@ namespace DesktopMagic
}
catch (Exception ex)
{
App.Logger.Log(ex.Message, "Main", LogSeverity.Error);
App.Logger.LogError(ex.Message, source: "Main");
}
}
return;
@@ -241,31 +243,26 @@ namespace DesktopMagic
window.PluginLoaded -= onPluginLoaded;
});
};
window.OnExit += () =>
{
Windows.Remove(window);
WindowNames.Remove(window.Title);
blockWindowsClosing = false;
window.Close();
blockWindowsClosing = true;
pluginSettings.Enabled = false;
};
window.PluginLoaded += onPluginLoaded;
window.ShowInTaskbar = false;
window.Show();
window.ContentRendered += DisplayWindow_ContentRendered;
window.SetEditMode(editCheckBox.IsChecked == true);
window.Closing += DisplayWindow_Closing;
Windows.Add(window);
WindowNames.Add(window.Title);
}
private void DisplayWindow_ContentRendered(object? sender, EventArgs e)
{
if (sender is not Window window)
{
return;
}
WindowPos.SendWpfWindowBack(window);
WindowPos.SendWpfWindowBack(window);
}
private void DisplayWindow_Closing(object? sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel = blockWindowsClosing;
@@ -273,9 +270,18 @@ namespace DesktopMagic
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
MessageBoxResult msbRes = MessageBox.Show((string)FindResource("wantToCloseProgram"), App.AppName, MessageBoxButton.YesNo);
e.Cancel = msbRes != MessageBoxResult.Yes;
SaveSettings();
if (blockWindowsClosing)
{
e.Cancel = true;
editCheckBox.IsChecked = false;
EditCheckBox_Click(null, null);
ShowInTaskbar = false;
WindowState = WindowState.Minimized;
Visibility = Visibility.Collapsed;
}
}
private void Window_Closed(object sender, EventArgs e)
@@ -289,29 +295,53 @@ namespace DesktopMagic
Environment.Exit(0);
}
private void Window_StateChanged(object? sender, EventArgs? e)
{
if (WindowState == WindowState.Minimized)
{
EditCheckBox.IsChecked = false;
EditCheckBox_Click(null, null);
ShowInTaskbar = false;
Visibility = Visibility.Collapsed;
foreach (Window item in Windows)
{
WindowPos.SendWpfWindowBack(item);
WindowPos.SendWpfWindowBack(item);
}
}
}
#endregion Windows
#region Options
private void FontComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
private void AddThemeButton_Click(object sender, RoutedEventArgs e)
{
Settings.CurrentLayout.Theme.Font = fontComboBox.SelectedValue.ToString()!.Replace("System.Windows.Controls.ComboBoxItem: ", "");
InputDialog inputDialog = new((string)FindResource("enterThemeName"))
{
Owner = this
};
if (inputDialog.ShowDialog() == true)
{
if (Settings.Themes.Any(l => l.Name.Trim() == inputDialog.ResponseText.Trim()))
{
_ = MessageBox.Show((string)FindResource("themeAlreadyExists"), App.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
Settings.Themes.Add(new Theme(inputDialog.ResponseText.Trim()));
Settings.CurrentLayout.CurrentThemeName = inputDialog.ResponseText.Trim();
SaveSettings();
}
}
private void DeleteThemeButton_Click(object sender, RoutedEventArgs e)
{
if (Settings.Themes.Count <= 1)
{
_ = MessageBox.Show((string)FindResource("cannotDeleteLastTheme"), App.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
Settings.Themes.Remove((Theme)themesListBox.SelectedItem);
SaveSettings();
}
private void ChangeThemeButton_Click(object sender, RoutedEventArgs e)
{
Theme theme = themesListBox.SelectedItem as Theme ?? Settings.CurrentLayout.Theme;
ThemeDialog themeDialog = new(theme.Name, theme, App.AppName)
{
Owner = this
};
themeDialog.ShowDialog();
}
private void OptionsComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -371,86 +401,22 @@ namespace DesktopMagic
}
}
private void TextBlock_Loaded(object sender, RoutedEventArgs e)
private void Quit()
{
int index = 0;
foreach (FontFamily ff in Fonts.SystemFontFamilies)
{
ComboBoxItem comboBoxItem = new()
{
FontFamily = ff,
Content = ff.ToString()
};
_ = fontComboBox.Items.Add(comboBoxItem);
if (ff.ToString() == Settings.CurrentLayout.Theme.Font)
{
fontComboBox.SelectedIndex = index;
}
index++;
}
if (fontComboBox.SelectedIndex == -1)
{
fontComboBox.SelectedIndex = 0;
}
blockWindowsClosing = false;
Close();
}
private void ChangePrimaryColorButton_Click(object sender, RoutedEventArgs e)
private void OpenPluginsFolderButton_Click(object sender, RoutedEventArgs e)
{
ColorDialog colorDialog = new ColorDialog("Set Primary Color", Settings.CurrentLayout.Theme.PrimaryColor);
if (colorDialog.ShowDialog() == true)
{
Settings.CurrentLayout.Theme.PrimaryColor = colorDialog.ResultColor;
primaryColorRechtangle.Fill = colorDialog.ResultBrush;
}
_ = Process.Start("explorer.exe", App.PluginsPath);
}
private void ChangeSecondaryColorButton_Click(object sender, RoutedEventArgs e)
private void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
ColorDialog colorDialog = new ColorDialog("Set Secondary Color", Settings.CurrentLayout.Theme.SecondaryColor);
if (colorDialog.ShowDialog() == true)
{
Settings.CurrentLayout.Theme.SecondaryColor = colorDialog.ResultColor;
secondaryColorRechtangle.Fill = colorDialog.ResultBrush;
}
}
private void ChangeBackgroundColorButton_Click(object sender, RoutedEventArgs e)
{
ColorDialog colorDialog = new ColorDialog("Set Background Color", Settings.CurrentLayout.Theme.BackgroundColor);
if (colorDialog.ShowDialog() == true)
{
Settings.CurrentLayout.Theme.BackgroundColor = colorDialog.ResultColor;
backgroundColorRechtangle.Fill = colorDialog.ResultBrush;
}
}
private void CornerRadiusTextBox_TextChanged(object? sender, TextChangedEventArgs? e)
{
bool success = int.TryParse(cornerRadiusTextBox.Text, out int cornerRadius);
if (success)
{
cornerRadiusTextBox.Foreground = Brushes.Black;
Settings.CurrentLayout.Theme.CornerRadius = cornerRadius;
}
else
{
cornerRadiusTextBox.Foreground = Brushes.Red;
}
}
private void MarginTextBox_TextChanged(object? sender, TextChangedEventArgs? e)
{
bool success = int.TryParse(marginTextBox.Text, out int margin);
if (success)
{
marginTextBox.Foreground = Brushes.Black;
Settings.CurrentLayout.Theme.Margin = margin;
}
else
{
marginTextBox.Foreground = Brushes.Red;
}
ScrollViewer scv = (ScrollViewer)sender;
scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
e.Handled = true;
}
#region Layout
@@ -474,12 +440,16 @@ namespace DesktopMagic
private void NewLayoutButton_Click(object sender, RoutedEventArgs e)
{
InputDialog inputDialog = new((string)FindResource("enterLayoutName"));
InputDialog inputDialog = new((string)FindResource("enterLayoutName"))
{
Owner = this
};
if (inputDialog.ShowDialog() == true)
{
if (Settings.Layouts.Any(l => l.Name.Trim() == inputDialog.ResponseText.Trim()))
{
_ = MessageBox.Show((string)FindResource("layoutAlreadyExists"));
_ = MessageBox.Show((string)FindResource("layoutAlreadyExists"), App.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
@@ -491,6 +461,12 @@ namespace DesktopMagic
private void RemoveLayoutButton_Click(object sender, RoutedEventArgs e)
{
if (Settings.Layouts.Count <= 1)
{
_ = MessageBox.Show((string)FindResource("cannotDeleteLastLayout"), App.AppName, MessageBoxButton.OK, MessageBoxImage.Warning);
return;
}
Settings.Layouts.Remove(Settings.CurrentLayout);
SaveSettings();
}
@@ -510,49 +486,41 @@ namespace DesktopMagic
{
if (!File.Exists(Path.Combine(App.ApplicationDataPath, "settings.json")))
{
Settings = new DesktopMagicSettings()
{
Layouts =
[
new Layout((string)FindResource("default"))
]
};
Settings = new DesktopMagicSettings();
Settings.Layouts.Add(new Layout((string)FindResource("default")));
Settings.Themes.Add(new Theme((string)FindResource("default")));
return;
}
string json = File.ReadAllText(Path.Combine(App.ApplicationDataPath, "settings.json"));
Settings = JsonSerializer.Deserialize<DesktopMagicSettings>(json, jsonSettingsOptions) ?? new DesktopMagicSettings()
Settings = JsonSerializer.Deserialize<DesktopMagicSettings>(json, jsonSettingsOptions) ?? new DesktopMagicSettings();
if(Settings.Layouts.Count == 0)
{
Layouts =
[
new Layout((string)FindResource("default"))
]
};
Settings.Layouts.Add(new Layout((string)FindResource("default")));
}
if (Settings.Themes.Count == 0)
{
Settings.Themes.Add(new Theme((string)FindResource("default")));
}
}
private void LoadLayout(bool minimize = true)
{
mainWindowDataContext.IsLoading = true;
cornerRadiusTextBox.Text = Settings.CurrentLayout.Theme.CornerRadius.ToString();
marginTextBox.Text = Settings.CurrentLayout.Theme.Margin.ToString();
blockWindowsClosing = false;
primaryColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(Settings.CurrentLayout.Theme.PrimaryColor));
secondaryColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(Settings.CurrentLayout.Theme.SecondaryColor));
backgroundColorRechtangle.Fill = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(Settings.CurrentLayout.Theme.BackgroundColor));
CornerRadiusTextBox_TextChanged(null, null);
MarginTextBox_TextChanged(null, null);
foreach (Window window in Windows)
{
window.Close();
}
EditCheckBox.IsChecked = false;
EditMode = false;
editCheckBox.IsChecked = false;
EditCheckBox_Click(null, null);
blockWindowsClosing = true;
Windows.Clear();
WindowNames.Clear();
@@ -599,14 +567,13 @@ namespace DesktopMagic
if (!showWindow && minimize)
{
WindowState = WindowState.Minimized;
Window_StateChanged(null, null);
Close();
}
else
{
WindowState = WindowState.Normal;
Window_StateChanged(null, null);
RestoreWindow();
}
mainWindowDataContext.IsLoading = false;
}
@@ -618,21 +585,12 @@ namespace DesktopMagic
LoadLayout(false);
}
private void OpenPluginsFolderButton_Click(object sender, RoutedEventArgs e)
private void NotifyIcon_MouseClick(object? sender, System.Windows.Forms.MouseEventArgs e)
{
_ = Process.Start("explorer.exe", App.ApplicationDataPath + "\\Plugins");
}
private void ScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
ScrollViewer scv = (ScrollViewer)sender;
scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
e.Handled = true;
}
private void TaskbarIcon_TrayLeftClick(object? sender, EventArgs e)
{
RestoreWindow();
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
RestoreWindow();
}
}
private void GitHubButton_Click(object sender, RoutedEventArgs e)
@@ -648,26 +606,14 @@ namespace DesktopMagic
private void PluginManagerButton_Click(object sender, RoutedEventArgs e)
{
PluginManager pluginManager = new PluginManager();
PluginManager pluginManager = new PluginManager
{
Owner = this
};
pluginManager.ShowDialog();
LoadPlugins();
LoadLayout(false);
}
private void SetLanguageDictionary()
{
ResourceDictionary dict = [];
string currentCulture = Thread.CurrentThread.CurrentUICulture.ToString();
if (currentCulture.Contains("de"))
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.de.xaml", UriKind.Relative);
}
else
{
dict.Source = new Uri("..\\Resources\\Strings\\StringResources.en.xaml", UriKind.Relative);
}
Resources.MergedDictionaries.Add(dict);
LoadLayout(Visibility != Visibility.Visible);
}
}
-43
View File
@@ -1,43 +0,0 @@
<UserControl x:Class="DesktopMagic.Plugins.ModEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:DesktopMagic.Plugins"
xmlns:dataContext="clr-namespace:DesktopMagic.DataContexts"
d:DataContext="{d:DesignInstance Type=dataContext:PluginEntryDataContext}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{DynamicResource MaterialDesignFont}"
Visibility="{Binding Visibility}">
<Grid Background="White" Margin="10">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border HorizontalAlignment="Left" Width="100" Height="100" BorderThickness="1" BorderBrush="LightGray">
<Image Source="{Binding Logo, FallbackValue={StaticResource ModioCogBlue}, TargetNullValue={StaticResource ModioCogBlue}}" Width="100" Height="100" />
</Border>
<StackPanel Grid.Column="1" HorizontalAlignment="Stretch">
<Label Content="{Binding FormattedDateAdded}" HorizontalAlignment="Center" ContentStringFormat="Added: {0}" />
<Label Content="{Binding FormattedDateUpdated}" HorizontalAlignment="Center" ContentStringFormat="Updated: {0}" />
<Button Command="{Binding Command}" Visibility="{Binding InstallButtonVisibility}" HorizontalAlignment="Stretch" Margin="10" Content="Install" />
<Button Command="{Binding Command}" Visibility="{Binding RemoveButtonVisibility}" HorizontalAlignment="Stretch" Margin="10" Content="Remove" />
</StackPanel>
<StackPanel Grid.Row="1" Grid.ColumnSpan="2">
<Label Content="{Binding Name}" FontSize="20" />
<TextBlock Text="{Binding Description}" TextWrapping="Wrap" />
</StackPanel>
</Grid>
</UserControl>
+1 -1
View File
@@ -9,7 +9,7 @@ internal class PluginData(PluginWindow window, PluginSettings pluginSettings) :
{
private readonly PluginWindow window = window;
public ITheme Theme { get; } = pluginSettings.Theme;
public ITheme Theme => pluginSettings.Theme;
public Size WindowSize => new Size((int)window.ActualWidth, (int)window.ActualHeight);
+63
View File
@@ -0,0 +1,63 @@
<UserControl x:Class="DesktopMagic.Plugins.ModEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:local="clr-namespace:DesktopMagic.Plugins"
xmlns:dataContext="clr-namespace:DesktopMagic.DataContexts"
d:DataContext="{d:DesignInstance Type=dataContext:PluginEntryDataContext}"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Background="{DynamicResource MaterialDesignPaper}"
FontFamily="{DynamicResource MaterialDesignFont}"
Visibility="{Binding Visibility}">
<Grid Background="White" Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="auto" />
<RowDefinition Height="3*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border HorizontalAlignment="Center" Margin="10" Width="100" Height="100" BorderThickness="1" BorderBrush="LightGray">
<Image Source="{Binding Logo, FallbackValue={StaticResource ModioCogBlue}, TargetNullValue={StaticResource ModioCogBlue}}" Width="100" Height="100" />
</Border>
<StackPanel Grid.Column="1" VerticalAlignment="Center">
<Label Content="{Binding Author}" HorizontalAlignment="Center" ContentStringFormat="{DynamicResource authorFormat}" />
<Label Content="{Binding DateAdded}" HorizontalAlignment="Center" ContentStringFormat="{DynamicResource addedFormat}" />
<Label Content="{Binding DateUpdated}" HorizontalAlignment="Center" ContentStringFormat="{DynamicResource updatedFormat}" />
<Label Content="{Binding Version}" HorizontalAlignment="Center" ContentStringFormat="{DynamicResource versionFormat}" />
</StackPanel>
<Grid Grid.Row="1" Grid.ColumnSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Command="{Binding InstallUninstallButtonData.Command}" IsEnabled="{Binding InstallUninstallButtonData.IsEnabled}" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="10 5 5 0">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="{Binding InstallUninstallButtonData.IconKind}" Margin="0 0 10 0" />
<TextBlock Text="{Binding InstallUninstallButtonData.Text}" />
</StackPanel>
</Button>
<Button Grid.Column="1" Command="{Binding OpenButtonData.Command}" IsEnabled="{Binding OpenButtonData.IsEnabled}" VerticalAlignment="Bottom" HorizontalAlignment="Stretch" Margin="5 5 10 0">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="{Binding OpenButtonData.IconKind}" Margin="0 0 10 0" />
<TextBlock Text="{Binding OpenButtonData.Text}" />
</StackPanel>
</Button>
</Grid>
<StackPanel Grid.Row="2" Grid.ColumnSpan="2" Margin="10">
<Label Content="{Binding Name}" FontSize="20" Padding="0" />
<TextBlock Text="{Binding Description}" TextWrapping="Wrap" />
</StackPanel>
</Grid>
</UserControl>
@@ -1,6 +1,7 @@
using System.Windows.Controls;
namespace DesktopMagic.Plugins;
/// <summary>
/// Interaction logic for ModEntry.xaml
/// </summary>
+45 -29
View File
@@ -9,7 +9,7 @@
xmlns:dataContexts="clr-namespace:DesktopMagic.DataContexts"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=dataContexts:PluginManagerDataContext}"
Title="PluginManager"
Title="{DynamicResource pluginManager}"
Height="450"
Width="800"
MinHeight="520"
@@ -31,7 +31,7 @@
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Label Content="All plugins" FontSize="20" />
<Label Content="{DynamicResource allPlugins}" FontSize="20" />
<TextBox Grid.Row="1" Text="{Binding AllPluginsSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="AllPluginsSearchTextBox_TextChanged" materialDesign:HintAssist.Hint="Search..." materialDesign:TextFieldAssist.HasLeadingIcon="True" materialDesign:TextFieldAssist.LeadingIcon="Search" />
@@ -52,7 +52,7 @@
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Text="No plugins found!" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<TextBlock Text="No plugins found!" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center" />
</ControlTemplate>
</Setter.Value>
</Setter>
@@ -64,37 +64,53 @@
</ScrollViewer>
</busyIndicator:BusyMask>
<Label Grid.Column="1" Content="Installed plugins" FontSize="20" />
<Label Grid.Column="1" Content="{DynamicResource installedPlugins}" FontSize="20" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding InstalledPluginsSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="InstalledPluginsSearchTextBox_TextChanged" materialDesign:HintAssist.Hint="Search..." materialDesign:TextFieldAssist.HasLeadingIcon="True" materialDesign:TextFieldAssist.LeadingIcon="Search" />
<ItemsControl Grid.Row="2" Grid.Column="1" ItemsSource="{Binding InstalledPlugins}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="LightGray" BorderThickness="1">
<local:ModEntry />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Style>
<Style TargetType="ItemsControl">
<Style.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Text="No plugins found!" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ItemsControl.Style>
</ItemsControl>
<ScrollViewer Grid.Row="2" Grid.Column="1" VerticalScrollBarVisibility="Auto">
<ItemsControl ItemsSource="{Binding InstalledPlugins}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="LightGray" BorderThickness="1">
<local:ModEntry />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
<ItemsControl.Style>
<Style TargetType="ItemsControl">
<Style.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<TextBlock Text="No plugins found!" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
</ItemsControl.Style>
</ItemsControl>
</ScrollViewer>
<Border Grid.Row="3" Grid.ColumnSpan="2" Padding="0 5 0 0" BorderThickness="0 2 0 0" BorderBrush="DarkGray">
<Image Source="{StaticResource ModioLogoBlueDark}" Cursor="Hand" Height="30" MouseUp="Image_MouseUp" HorizontalAlignment="Left" />
<DockPanel>
<Image Source="{StaticResource ModioLogoBlueDark}" Cursor="Hand" Height="30" MouseUp="Image_MouseUp" HorizontalAlignment="Left" />
<Button DockPanel.Dock="Right" HorizontalAlignment="Right" Click="LogInButton_Click">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Login" Margin="0 0 10 0" />
<TextBlock Text="{Binding LoginButtonText}" />
</StackPanel>
</Button>
<Button DockPanel.Dock="Right" HorizontalAlignment="Right" Margin="0 0 10 0" Click="CreatePluginButton_Click">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Add" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource createNewPlugin}" />
</StackPanel>
</Button>
</DockPanel>
</Border>
</Grid>
</busyIndicator:BusyMask>
+338 -18
View File
@@ -1,22 +1,26 @@
using DesktopMagic.DataContexts;
using DesktopMagic.Dialogs;
using DesktopMagic.Helpers;
using Modio.NET;
using Modio.NET.Filters;
using Modio.NET.Models;
using Modio;
using Modio.Filters;
using Modio.Models;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Net.Http;
using System.Text.Json;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Threading;
using System.Xml.Linq;
using File = System.IO.File;
using Path = System.IO.Path;
@@ -28,20 +32,36 @@ namespace DesktopMagic.Plugins;
/// </summary>
public partial class PluginManager : Window
{
private const int modIoGameId = 5665;
private readonly Client client = new Client(new Credentials("88e6ea774c3a502b06114e7fee0829ac"));
private const int ModIoGameId = 5665;
private const string ModIoApiKey = "88e6ea774c3a502b06114e7fee0829ac";
private readonly HttpClient httpClient = new();
private readonly PluginManagerDataContext pluginManagerDataContext = new();
private readonly string pluginsPath = Path.Combine(App.ApplicationDataPath, "Plugins");
private readonly string pluginDevelopmentPath = Path.Combine(App.ApplicationDataPath, "PluginDevelopment");
private readonly DispatcherTimer searchTimer = new()
{
Interval = TimeSpan.FromMilliseconds(300),
};
private Client modIoClient;
public PluginManager()
{
Resources.MergedDictionaries.Add(App.LanguageDictionary);
string? modIoAccessToken = MainWindowDataContext.GetSettings().ModIoAccessToken;
if (modIoAccessToken is null)
{
modIoClient = new Client(new Credentials(ModIoApiKey));
}
else
{
modIoClient = new Client(new Credentials(ModIoApiKey, modIoAccessToken));
pluginManagerDataContext.IsAuthenticated = true;
}
InitializeComponent();
DataContext = pluginManagerDataContext;
@@ -52,20 +72,33 @@ public partial class PluginManager : Window
};
}
public void Remove(string pluginPath, uint? id)
public async Task Remove(string pluginPath, uint id)
{
pluginManagerDataContext.IsLoading = true;
PluginEntryDataContext? pluginEntryDataContext = pluginManagerDataContext.InstalledPlugins.FirstOrDefault(p => p.Id == id);
if (Directory.Exists(pluginPath))
{
try
{
Directory.Delete(pluginPath, true);
}
catch (Exception ex)
{
_ = MessageBox.Show(ex.Message, "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
App.Logger.LogError(ex.Message, source: "PluginManager");
}
}
if (pluginEntryDataContext is not null)
{
_ = pluginManagerDataContext.InstalledPlugins.Remove(pluginEntryDataContext);
}
if (Directory.Exists(pluginPath))
if (pluginManagerDataContext.IsAuthenticated)
{
Directory.Delete(pluginPath, true);
await modIoClient.Games[ModIoGameId].Mods.Unsubscribe(id);
}
pluginManagerDataContext.IsLoading = false;
@@ -85,18 +118,18 @@ public partial class PluginManager : Window
continue;
}
PluginMetadata? pluginMetadata = JsonSerializer.Deserialize<PluginMetadata>(File.ReadAllText(pluginMetadataPath));
PluginMetadata? pluginMetadata = JsonSerializer.Deserialize<PluginMetadata>(await File.ReadAllTextAsync(pluginMetadataPath));
if (pluginMetadata is not null)
{
pluginManagerDataContext.InstalledPlugins.Add(new PluginEntryDataContext(pluginMetadata, new CommandHandler(() => Remove(pluginPath, pluginMetadata.Id)), true));
pluginManagerDataContext.InstalledPlugins.Add(new PluginEntryDataContext(pluginMetadata, new CommandHandler(async () => await Remove(pluginPath, pluginMetadata.Id)), PluginEntryDataContext.Mode.Uninstall, pluginPath));
_ = pluginIds.Add(pluginMetadata.Id);
}
}
Filter filter = ModFilter.Popular.Desc().Limit(100);
IAsyncEnumerable<Mod> mods = client.Games[modIoGameId].Mods.Search(filter).ToEnumerableAsync();
IAsyncEnumerable<Mod> mods = modIoClient.Games[ModIoGameId].Mods.Search(filter).ToEnumerable();
await foreach (Mod mod in mods)
{
if (pluginIds.Contains(mod.Id))
@@ -104,9 +137,11 @@ public partial class PluginManager : Window
continue;
}
pluginManagerDataContext.AllPlugins.Add(new PluginEntryDataContext(new(mod), new CommandHandler(async () => await Install(mod))));
pluginManagerDataContext.AllPlugins.Add(new PluginEntryDataContext(new(mod), new CommandHandler(async () => await Install(mod)), PluginEntryDataContext.Mode.Install));
}
await SyncPlugins();
pluginManagerDataContext.IsLoading = false;
}
@@ -115,6 +150,9 @@ public partial class PluginManager : Window
e.Cancel = pluginManagerDataContext.IsLoading;
}
[GeneratedRegex(@"[^a-zA-Z0-9]")]
private static partial Regex IdentifierNameRegex();
private async Task Install(Mod mod)
{
pluginManagerDataContext.IsLoading = true;
@@ -141,13 +179,13 @@ public partial class PluginManager : Window
}
string pluginMetadataPath = Path.Combine(pluginPath, "metadata.json");
File.WriteAllText(pluginMetadataPath, JsonSerializer.Serialize(new PluginMetadata(mod)));
await File.WriteAllTextAsync(pluginMetadataPath, JsonSerializer.Serialize(new PluginMetadata(mod)));
File.Delete(zipFilePath);
if (!File.Exists(Path.Combine(pluginPath, "main.dll")))
{
Remove(pluginPath, mod.Id);
_ = Remove(pluginPath, mod.Id);
pluginManagerDataContext.IsLoading = false;
_ = MessageBox.Show("The plugin you are trying to install does not contain a \"main.dll\" file. Please contact the plugin author.", "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
return;
@@ -160,7 +198,12 @@ public partial class PluginManager : Window
_ = pluginManagerDataContext.AllPlugins.Remove(pluginEntryDataContext);
}
pluginManagerDataContext.InstalledPlugins.Add(new PluginEntryDataContext(new PluginMetadata(mod), new CommandHandler(() => Remove(pluginPath, mod.Id)), true));
if (pluginManagerDataContext.IsAuthenticated)
{
await modIoClient.Games[ModIoGameId].Mods.Subscribe(mod.Id);
}
pluginManagerDataContext.InstalledPlugins.Add(new PluginEntryDataContext(new PluginMetadata(mod), new CommandHandler(async () => await Remove(pluginPath, mod.Id)), PluginEntryDataContext.Mode.Uninstall, pluginPath));
pluginManagerDataContext.IsLoading = false;
}
@@ -212,7 +255,7 @@ public partial class PluginManager : Window
Filter filter = ModFilter.Name.Like($"{searchString}").And(ModFilter.Popular.Desc()).Limit(100);
IAsyncEnumerable<Mod> mods = client.Games[modIoGameId].Mods.Search(filter).ToEnumerableAsync();
IAsyncEnumerable<Mod> mods = modIoClient.Games[ModIoGameId].Mods.Search(filter).ToEnumerable();
await foreach (Mod mod in mods)
{
if (pluginManagerDataContext.InstalledPlugins.Any(p => p.Id == mod.Id))
@@ -220,9 +263,286 @@ public partial class PluginManager : Window
continue;
}
pluginManagerDataContext.AllPlugins.Add(new PluginEntryDataContext(new(mod), new CommandHandler(async () => await Install(mod))));
pluginManagerDataContext.AllPlugins.Add(new PluginEntryDataContext(new(mod), new CommandHandler(async () => await Install(mod)), PluginEntryDataContext.Mode.Install));
}
pluginManagerDataContext.IsSearching = false;
}
private void CreatePluginButton_Click(object sender, RoutedEventArgs e)
{
try
{
CreateNewPlugin();
}
catch (Exception ex)
{
App.Logger.LogError(ex.Message, source: "PluginManager");
_ = MessageBox.Show(ex.Message, "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
}
}
private void CreateNewPlugin()
{
if (!FileUtilities.ExistsOnPath("dotnet.exe"))
{
_ = MessageBox.Show("The .NET SDK is required to create a plugin. Please install it and try again.", "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
string pluginGuid = Guid.NewGuid().ToString();
string pluginPath = Path.Combine(pluginsPath, pluginGuid);
uint pluginId = (uint)Random.Shared.Next(1000, 9999);
InputDialog inputDialog = new((string)FindResource("enterPluginName"), "Plugin Manager")
{
Owner = this,
};
if (inputDialog.ShowDialog() != true)
{
return;
}
string pluginName = inputDialog.ResponseText;
string pluginSafeName = pluginName.ToLower().Replace("_", " ");
TextInfo info = CultureInfo.CurrentCulture.TextInfo;
pluginSafeName = info.ToTitleCase(pluginSafeName);
pluginSafeName = IdentifierNameRegex().Replace(pluginSafeName, "");
if (!Directory.Exists(pluginDevelopmentPath))
{
_ = Directory.CreateDirectory(pluginDevelopmentPath);
}
string pluginProjectPath = Path.Combine(pluginDevelopmentPath, pluginSafeName);
if (Directory.Exists(pluginProjectPath))
{
_ = MessageBox.Show("A plugin with the same name already exists. Please choose a different name.", "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
PluginMetadata pluginMetadata = new(pluginName, pluginId);
_ = Directory.CreateDirectory(pluginPath);
_ = Directory.CreateDirectory(pluginProjectPath);
string pluginMetadataPath = Path.Combine(pluginPath, "metadata.json");
File.WriteAllText(pluginMetadataPath, JsonSerializer.Serialize(pluginMetadata));
string cmd = $"new classlib -n {pluginSafeName} -o {pluginProjectPath} -f net8.0 --target-framework-override net8.0-windows7";
Process process = Process.Start("dotnet", cmd);
process.WaitForExit();
// Install the required NuGet packages
process = Process.Start("dotnet", $"add {pluginProjectPath} package DesktopMagic.Api");
process.WaitForExit();
File.Move(Path.Combine(pluginProjectPath, "Class1.cs"), Path.Combine(pluginProjectPath, $"{pluginSafeName}.cs"));
string code = $@"using DesktopMagic.Api;
using System.Drawing;
namespace {pluginSafeName};
public class {pluginSafeName}Plugin : Plugin
{{
public override Bitmap Main()
{{
Bitmap bmp = new Bitmap(2000, 1000);
using (Graphics g = Graphics.FromImage(bmp))
{{
g.Clear(Application.Theme.PrimaryColor); // Set the background color to the color specified in the DesktopMagic application.
g.DrawString(""Hello World"", new Font(Application.Theme.Font, 100), Brushes.Black, new PointF(0, 0)); // Draw ""Hello World"" to the image.
}}
bmp.SetResolution(300, 300); // Set DPI to avoid scaling issues.
return bmp; // Return the image.
}}
}}
";
// Update the .csproj file
string csprojPath = Path.Combine(pluginProjectPath, $"{pluginSafeName}.csproj");
File.WriteAllText(Path.Combine(pluginProjectPath, $"{pluginSafeName}.cs"), code);
XDocument doc = XDocument.Load(csprojPath);
XElement? propertyGroup = doc.Root?.Element("PropertyGroup");
if (propertyGroup is not null)
{
XElement? outputPathElement = propertyGroup.Element("OutputPath");
if (outputPathElement is not null)
{
outputPathElement.Value = pluginPath;
}
else
{
propertyGroup.Add(new XElement("OutputPath", pluginPath));
}
XElement? appendTargetFrameworkToOutputPathElement = propertyGroup.Element("AppendTargetFrameworkToOutputPath");
if (appendTargetFrameworkToOutputPathElement is not null)
{
appendTargetFrameworkToOutputPathElement.Value = "false";
}
else
{
propertyGroup.Add(new XElement("AppendTargetFrameworkToOutputPath", "false"));
}
XElement? targetNameElement = propertyGroup.Element("TargetName");
if (targetNameElement is not null)
{
targetNameElement.Value = "main";
}
else
{
propertyGroup.Add(new XElement("TargetName", "main"));
}
doc.Save(csprojPath);
}
else
{
_ = MessageBox.Show("PropertyGroup element not found in .csproj", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
return;
}
// Open the project in the default IDE
string? associatedProgram = FileUtilities.GetAssociatedProgram(".csproj");
if (associatedProgram is null)
{
_ = Process.Start("explorer.exe", pluginProjectPath);
return;
}
ProcessStartInfo psi = new ProcessStartInfo
{
FileName = associatedProgram,
Arguments = csprojPath,
};
_ = Process.Start(psi);
}
private async void LogInButton_Click(object sender, RoutedEventArgs e)
{
if (pluginManagerDataContext.IsAuthenticated)
{
MainWindowDataContext.GetSettings().ModIoAccessToken = null;
pluginManagerDataContext.IsAuthenticated = false;
return;
}
try
{
InputDialog inputDialog = new((string)FindResource("enterModIoEmail"), "Plugin Manager")
{
Owner = this,
};
if (inputDialog.ShowDialog() != true)
{
return;
}
await modIoClient.Auth.RequestCode(ModIoApiKey, inputDialog.ResponseText);
inputDialog = new((string)FindResource("enterModIoAccessToken"), "Plugin Manager")
{
Owner = this,
};
if (inputDialog.ShowDialog() != true)
{
return;
}
pluginManagerDataContext.IsLoading = true;
AccessToken accessToken = await modIoClient.Auth.SecurityCode(ModIoApiKey, inputDialog.ResponseText);
if (accessToken.Value is not null)
{
modIoClient = new Client(new Credentials(ModIoApiKey, accessToken.Value));
}
MainWindowDataContext.GetSettings().ModIoAccessToken = accessToken.Value;
pluginManagerDataContext.IsAuthenticated = true;
foreach (PluginEntryDataContext plugin in pluginManagerDataContext.InstalledPlugins)
{
if (!plugin.IsLocalPlugin)
{
try
{
await modIoClient.Games[ModIoGameId].Mods.Subscribe(plugin.Id);
}
catch (Exception ex)
{
App.Logger.LogError(ex.Message, source: "PluginManager");
}
}
}
await SyncPlugins();
}
catch (Exception ex)
{
App.Logger.LogError(ex.Message, source: "PluginManager");
_ = MessageBox.Show(ex.Message, "Plugin Manager", MessageBoxButton.OK, MessageBoxImage.Error);
}
pluginManagerDataContext.IsLoading = false;
}
private async Task SyncPlugins()
{
if (!pluginManagerDataContext.IsAuthenticated)
{
return;
}
IReadOnlyList<Mod> mods = await modIoClient.User.GetSubscriptions(ModFilter.GameId.Eq(ModIoGameId)).ToList();
List<PluginEntryDataContext> pluginsToRemove = [];
foreach (PluginEntryDataContext plugin in pluginManagerDataContext.InstalledPlugins)
{
if (!plugin.IsLocalPlugin && !mods.Any(m => m.Id == plugin.Id))
{
pluginsToRemove.Add(plugin);
}
}
foreach (PluginEntryDataContext plugin in pluginsToRemove)
{
if (plugin.Path is null)
{
continue;
}
await Remove(plugin.Path, plugin.Id);
}
IEnumerable<Mod> notInstalledMods = mods.Where(m => !pluginManagerDataContext.InstalledPlugins.Any(p => p.Id == m.Id));
foreach (Mod mod in notInstalledMods)
{
await Install(mod);
}
}
}
+8 -2
View File
@@ -1,4 +1,4 @@
using Modio.NET.Models;
using Modio.Models;
using System;
using System.Text.Json.Serialization;
@@ -7,7 +7,7 @@ namespace DesktopMagic.Plugins;
public class PluginMetadata
{
public string Name { get; set; }
public string Name { get; set; } = string.Empty;
public uint Id { get; set; }
@@ -15,12 +15,16 @@ public class PluginMetadata
public Uri? IconUri { get; set; }
public Uri? ProfileUri { get; set; }
public DateTime? Added { get; set; }
public DateTime? Updated { get; set; }
public string? Description { get; set; }
public string? Summary { get; set; }
public string? Version { get; set; }
public PluginMetadata(Mod mod)
@@ -29,9 +33,11 @@ public class PluginMetadata
Id = mod.Id;
Author = mod.SubmittedBy?.Username;
IconUri = mod.Logo?.Thumb320x180;
ProfileUri = mod.ProfileUrl;
Added = DateTimeOffset.FromUnixTimeSeconds(mod.DateAdded).DateTime;
Updated = DateTimeOffset.FromUnixTimeSeconds(mod.DateUpdated).DateTime;
Description = mod.DescriptionPlaintext;
Summary = mod.Summary;
Version = mod.Modfile?.Version;
}
+2 -2
View File
@@ -17,8 +17,8 @@
<Grid>
<Rectangle x:Name="panel" Fill="#4CBAFFEF" Stroke="White" Margin="0,0,0,0" Visibility="Collapsed" />
<Border x:Name="border" />
<Viewbox x:Name="viewBox" StretchDirection="Both" Stretch="Uniform">
<Border SizeChanged="Border_SizeChanged" x:Name="border" />
<Viewbox SizeChanged="ViewBox_SizeChanged" x:Name="viewBox" StretchDirection="Both" Stretch="Uniform">
<Viewbox.Clip>
<RectangleGeometry x:Name="rectangleGeometry" RadiusX="{Binding ElementName=border, Path=CornerRadius.TopLeft}" RadiusY="{Binding ElementName=border, Path=CornerRadius.TopLeft}" />
</Viewbox.Clip>
+118 -74
View File
@@ -1,6 +1,7 @@
using DesktopMagic.Api;
using DesktopMagic.Api.Drawing;
using DesktopMagic.Api.Settings;
using DesktopMagic.DataContexts;
using DesktopMagic.Helpers;
using DesktopMagic.Plugins;
using DesktopMagic.Settings;
@@ -28,14 +29,13 @@ public partial class PluginWindow : Window
public event Action? OnExit;
private readonly PluginSettings settings;
private readonly System.Timers.Timer? updateTimer;
private Thread? pluginThread;
private System.Timers.Timer? valueTimer;
private System.Timers.Timer? updateTimer;
private Plugin? pluginClassInstance;
public bool IsRunning { get; private set; } = true;
public PluginMetadata PluginMetadata { get; private set; }
public string? PluginFolderPath { get; private set; }
public string PluginFolderPath { get; private set; }
public PluginWindow(PluginMetadata pluginMetadata, PluginSettings settings, string pluginFolderPath)
{
@@ -51,16 +51,23 @@ public partial class PluginWindow : Window
WindowStyle = WindowStyle.ToolWindow,
ShowInTaskbar = false
};
w.Show();
Owner = w;
w.Hide();
updateTimer = new System.Timers.Timer
WindowInteropHelper helper = new WindowInteropHelper(w);
_ = helper.EnsureHandle();
Owner = w;
settings.PropertyChanged += (e, s) =>
{
Interval = 100
if (s.PropertyName == nameof(PluginSettings.CurrentThemeName))
{
settings.Theme.PropertyChanged += (se, ev) =>
{
ThemeChanged();
};
ThemeChanged();
}
};
updateTimer.Elapsed += UpdateTimer_Elapsed;
updateTimer.Start();
PluginMetadata = pluginMetadata;
this.settings = settings;
@@ -80,7 +87,8 @@ public partial class PluginWindow : Window
public void UpdatePluginWindow()
{
ValueTimer_Elapsed(valueTimer, null);
Dispatcher.Invoke(ThemeChanged);
UpdateTimer_Elapsed(updateTimer, null);
}
public void Exit()
@@ -93,6 +101,32 @@ public partial class PluginWindow : Window
});
}
public void SetEditMode(bool enabled)
{
if (enabled)
{
Topmost = true;
panel.Visibility = Visibility.Visible;
imageBorder.BorderThickness = new Thickness(3);
image.Margin = new(-3);
WindowPos.SetIsLocked(this, false);
tileBar.CaptionHeight = tileBar.CaptionHeight = ActualHeight - 10 < 0 ? 0 : ActualHeight - 10;
ResizeMode = ResizeMode.CanResize;
}
else
{
Topmost = false;
panel.Visibility = Visibility.Collapsed;
imageBorder.BorderThickness = new Thickness(0);
image.Margin = new Thickness(0);
WindowPos.SendWpfWindowBack(this);
WindowPos.SendWpfWindowBack(this);
WindowPos.SetIsLocked(this, true);
tileBar.CaptionHeight = 0;
ResizeMode = ResizeMode.NoResize;
}
}
protected override void OnSourceInitialized(EventArgs e)
{
base.OnSourceInitialized(e);
@@ -121,62 +155,25 @@ public partial class PluginWindow : Window
private void Window_ContentRendered(object? sender, EventArgs e)
{
App.Logger.Log($"\"{PluginMetadata.Name}\" - Starting plugin thread", "Plugin");
App.Logger.LogInfo($"\"{PluginMetadata.Name}\" - Starting plugin thread", source: "Plugin");
pluginThread = new Thread(LoadPlugin);
pluginThread.Start();
}
private void UpdateTimer_Elapsed(object? sender, ElapsedEventArgs e)
private void ThemeChanged()
{
Dispatcher.Invoke(() =>
{
if (MainWindow.EditMode)
{
panel.Visibility = Visibility.Visible;
imageBorder.BorderThickness = new Thickness(3);
image.Margin = new(-3);
WindowPos.SetIsLocked(this, false);
tileBar.CaptionHeight = tileBar.CaptionHeight = ActualHeight - 10 < 0 ? 0 : ActualHeight - 10;
ResizeMode = ResizeMode.CanResize;
}
else
{
panel.Visibility = Visibility.Collapsed;
imageBorder.BorderThickness = new Thickness(0);
image.Margin = new Thickness(0);
WindowPos.SetIsLocked(this, true);
tileBar.CaptionHeight = 0;
ResizeMode = ResizeMode.NoResize;
}
if (!IsRunning)
{
(sender as System.Timers.Timer)?.Stop();
}
else
{
viewBox.Margin = new Thickness(settings.Theme.Margin);
border.Width = viewBox.ActualWidth + (settings.Theme.Margin * 2);
border.Height = viewBox.ActualHeight + (settings.Theme.Margin * 2);
rectangleGeometry.Rect = new Rect(-settings.Theme.Margin, -settings.Theme.Margin, border.ActualWidth, border.ActualHeight);
border.Background = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(settings.Theme.BackgroundColor));
border.CornerRadius = new CornerRadius(settings.Theme.CornerRadius);
}
});
if (!IsRunning)
{
updateTimer?.Stop();
}
viewBox.Margin = new Thickness(settings.Theme.Margin);
border.Background = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(settings.Theme.BackgroundColor));
border.CornerRadius = new CornerRadius(settings.Theme.CornerRadius);
}
private void LoadPlugin()
{
App.Logger.Log($"\"{PluginMetadata.Name}\" - Loading plugin", "Plugin");
App.Logger.LogInfo($"\"{PluginMetadata.Name}\" - Loading plugin", source: "Plugin");
if (pluginClassInstance is null && !File.Exists($"{PluginFolderPath}\\main.dll"))
{
App.Logger.Log($"\"{PluginMetadata.Name}\" - File \"main.dll\" does not exist", "Plugin", LogSeverity.Error);
App.Logger.LogError($"\"{PluginMetadata.Name}\" - File \"main.dll\" does not exist", source: "Plugin");
_ = MessageBox.Show("File \"main.dll\" does not exist!", $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit();
@@ -189,7 +186,7 @@ public partial class PluginWindow : Window
}
catch (Exception ex)
{
App.Logger.Log($"\"{PluginMetadata.Name}\" - {ex}", "Plugin", LogSeverity.Error);
App.Logger.LogError($"\"{PluginMetadata.Name}\" - {ex}", source: "Plugin");
_ = MessageBox.Show("File execution error:\n" + ex, $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit();
return;
@@ -202,13 +199,12 @@ public partial class PluginWindow : Window
object? instance = pluginClassInstance;
if (instance is null)
{
byte[] assemblyBytes = File.ReadAllBytes($"{PluginFolderPath}\\main.dll");
Assembly dll = Assembly.Load(assemblyBytes);
Assembly dll = Assembly.LoadFrom($"{PluginFolderPath}\\main.dll");
Type? instanceType = Array.Find(dll.GetTypes(), type => type.GetTypeInfo().BaseType == typeof(Plugin));
if (instanceType is null)
{
App.Logger.Log($"\"{PluginMetadata.Name}\" - The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", "Plugin", LogSeverity.Error);
App.Logger.LogError($"\"{PluginMetadata.Name}\" - The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", source: "Plugin");
_ = MessageBox.Show($"The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit();
@@ -224,7 +220,7 @@ public partial class PluginWindow : Window
}
else
{
App.Logger.Log($"\"{PluginMetadata.Name}\" - The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", "Plugin", LogSeverity.Error);
App.Logger.LogError($"\"{PluginMetadata.Name}\" - The \"Plugin\" class could not be found! It has to inherit from \"{typeof(Plugin).FullName}\"", source: "Plugin");
_ = MessageBox.Show($"The \"Plugin\" class has to inherit from \"{typeof(Plugin).FullName}\"", $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit();
return;
@@ -233,19 +229,19 @@ public partial class PluginWindow : Window
LoadOptions(pluginClassInstance);
BindDefaultSettings(pluginClassInstance);
valueTimer = new System.Timers.Timer
updateTimer = new System.Timers.Timer
{
Interval = 1000
};
valueTimer.Elapsed += ValueTimer_Elapsed;
updateTimer.Elapsed += UpdateTimer_Elapsed;
pluginClassInstance.Start();
UpdatePluginWindow();
if (pluginClassInstance.UpdateInterval > 0)
{
valueTimer.Interval = pluginClassInstance.UpdateInterval;
valueTimer.Start();
updateTimer.Interval = pluginClassInstance.UpdateInterval;
updateTimer.Start();
}
}
@@ -255,37 +251,74 @@ public partial class PluginWindow : Window
{
SetHorizontalAlignment();
SetVerticalAlignment();
SetThemeOverride();
SetThemeOverrideItems();
pluginClassInstance.horizontalAlignment.OnValueChanged += SetHorizontalAlignment;
pluginClassInstance.verticalAlignment.OnValueChanged += SetVerticalAlignment;
pluginClassInstance.themeOverride.OnValueChanged += SetThemeOverride;
DesktopMagicSettings desktopMagicSettings = MainWindowDataContext.GetSettings();
desktopMagicSettings.Themes.CollectionChanged += (s, e) => SetThemeOverrideItems();
});
void SetVerticalAlignment()
{
viewBox.VerticalAlignment = pluginClassInstance.verticalAlignment.Value switch
VerticalAlignment verticalAlignment = pluginClassInstance.verticalAlignment.Value switch
{
"Top" => VerticalAlignment.Top,
"Center" => VerticalAlignment.Center,
"Bottom" => VerticalAlignment.Bottom,
_ => VerticalAlignment.Center
};
viewBox.VerticalAlignment = verticalAlignment;
border.VerticalAlignment = verticalAlignment;
}
void SetHorizontalAlignment()
{
viewBox.HorizontalAlignment = pluginClassInstance.horizontalAlignment.Value switch
HorizontalAlignment horizontalAlignment = pluginClassInstance.horizontalAlignment.Value switch
{
"Left" => HorizontalAlignment.Left,
"Center" => HorizontalAlignment.Center,
"Right" => HorizontalAlignment.Right,
_ => HorizontalAlignment.Center
};
viewBox.HorizontalAlignment = horizontalAlignment;
border.HorizontalAlignment = horizontalAlignment;
}
void SetThemeOverride()
{
if (pluginClassInstance.themeOverride.Value == "<None>")
{
settings.CurrentThemeName = null;
}
else
{
settings.CurrentThemeName = pluginClassInstance.themeOverride.Value;
}
}
void SetThemeOverrideItems()
{
DesktopMagicSettings desktopMagicSettings = MainWindowDataContext.GetSettings();
pluginClassInstance.themeOverride.Items.Clear();
pluginClassInstance.themeOverride.Items.Add("<None>");
foreach (Theme theme in desktopMagicSettings.Themes)
{
pluginClassInstance.themeOverride.Items.Add(theme.Name);
}
}
}
private void LoadOptions(object instance)
{
App.Logger.Log($"\"{PluginMetadata.Name}\" - Loading plugin options", "Plugin");
App.Logger.LogInfo($"\"{PluginMetadata.Name}\" - Loading plugin options", source: "Plugin");
try
{
@@ -323,13 +356,13 @@ public partial class PluginWindow : Window
catch (Exception ex)
{
IsRunning = false;
App.Logger.Log($"\"{PluginMetadata.Name}\" - {ex}", "Plugin", LogSeverity.Error);
App.Logger.LogError($"\"{PluginMetadata.Name}\" - {ex}", source: "Plugin");
_ = MessageBox.Show("File execution error:\n" + ex, $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit();
}
}
private void ValueTimer_Elapsed(object? sender, ElapsedEventArgs? e)
private void UpdateTimer_Elapsed(object? sender, ElapsedEventArgs? e)
{
try
{
@@ -339,11 +372,11 @@ public partial class PluginWindow : Window
if (pluginClassInstance.UpdateInterval > 0)
{
valueTimer!.Interval = pluginClassInstance.UpdateInterval;
updateTimer!.Interval = pluginClassInstance.UpdateInterval;
}
else
{
valueTimer!.Stop();
updateTimer!.Stop();
}
if (result is not null)
@@ -368,7 +401,7 @@ public partial class PluginWindow : Window
catch (Exception ex)
{
IsRunning = false;
App.Logger.Log($"\"{PluginMetadata.Name}\" - {ex}", "Plugin", LogSeverity.Error);
App.Logger.LogError($"\"{PluginMetadata.Name}\" - {ex}", source: "Plugin");
_ = MessageBox.Show("File execution error:\n" + ex, $"Error \"{PluginMetadata.Name}\"", MessageBoxButton.OK, MessageBoxImage.Error);
Exit();
return;
@@ -376,13 +409,24 @@ public partial class PluginWindow : Window
if (!IsRunning)
{
valueTimer!.Stop();
updateTimer!.Stop();
}
}
private void Border_SizeChanged(object sender, SizeChangedEventArgs e)
{
rectangleGeometry.Rect = new Rect(-settings.Theme.Margin, -settings.Theme.Margin, e.NewSize.Width, e.NewSize.Height);
}
private void ViewBox_SizeChanged(object sender, SizeChangedEventArgs e)
{
border.Width = e.NewSize.Width + (settings.Theme.Margin * 2);
border.Height = e.NewSize.Height + (settings.Theme.Margin * 2);
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
App.Logger.Log($"\"{PluginMetadata.Name}\" - Stopping plugin", "Plugin");
App.Logger.LogInfo($"\"{PluginMetadata.Name}\" - Stopping plugin", source: "Plugin");
IsRunning = false;
pluginClassInstance?.Stop();
}
+12 -2
View File
@@ -11,17 +11,27 @@ using Color = System.Drawing.Color;
namespace DesktopMagic.Plugins;
public class Theme : ITheme, INotifyPropertyChanged
public class Theme(string name) : ITheme, INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private Color primaryColor = Color.White;
private Color secondaryColor = Color.White;
private Color secondaryColor = Color.LightGray;
private Color backgroundColor = Color.Transparent;
private string font = "Segoe UI";
private int cornerRadius;
private int margin;
public string Name
{
get => name;
set
{
name = value;
OnPropertyChanged();
}
}
public Color PrimaryColor
{
get => primaryColor;
@@ -5,29 +5,51 @@
<system:String x:Key="lineMode">Linie</system:String>
<system:String x:Key="mirrorMode">Spiegeln</system:String>
<system:String x:Key="folder">Ordner</system:String>
<system:String x:Key="autoStart">Starten beim Hochfahren</system:String>
<system:String x:Key="unknown">Unbekannt</system:String>
<system:String x:Key="open">Öffnen</system:String>
<system:String x:Key="quit">Schließen</system:String>
<system:String x:Key="login">Einloggen</system:String>
<system:String x:Key="logout">Ausloggen</system:String>
<system:String x:Key="enterModIoEmail">Mod.io Account E-Mail eingeben</system:String>
<system:String x:Key="enterModIoAccessToken">Geben Sie Ihren mod.io Sicherheitscode ein</system:String>
<system:String x:Key="toggleEditMode">Bearbeitungsmodus umschalten</system:String>
<system:String x:Key="allPlugins">Alle Plugins</system:String>
<system:String x:Key="installedPlugins">Installierte Plugins</system:String>
<system:String x:Key="updatePlugins">Neu Laden</system:String>
<system:String x:Key="openPluginsFolder">Plugins Ordner Öffnen</system:String>
<system:String x:Key="pluginManager">Plugin Manager</system:String>
<system:String x:Key="pluginsFolder">Plugins Ordner</system:String>
<system:String x:Key="pluginManager">Plugins Manager</system:String>
<system:String x:Key="createNewPlugin">Neues Plugin erstellen</system:String>
<system:String x:Key="enterPluginName">Pluginnamen eingeben</system:String>
<system:String x:Key="color">Farbe:</system:String>
<system:String x:Key="default">Standard</system:String>
<system:String x:Key="wantToCloseProgram">Wollen sie das Programm wirklich schließen?</system:String>
<system:String x:Key="noOptions">Keine Optionen!</system:String>
<system:String x:Key="edit">Bearbeiten</system:String>
<system:String x:Key="editLayout">Layout Bearbeiten</system:String>
<system:String x:Key="time">Uhrzeit</system:String>
<system:String x:Key="date">Datum</system:String>
<system:String x:Key="cpuUsage">CPU Auslastung</system:String>
<system:String x:Key="googleCalendar">Google Kalender</system:String>
<system:String x:Key="musicVisualizer">Musik Visualizer</system:String>
<system:String x:Key="musicVisualizerOptions">Musik Visualizer Einstellungen:</system:String>
<system:String x:Key="musicVisualizer">Musik Visualisierer</system:String>
<system:String x:Key="amplifier">Signalverstärkung:</system:String>
<system:String x:Key="newLayout">Neues Layout</system:String>
<system:String x:Key="deleteLayout">Layout Löschen</system:String>
<system:String x:Key="newTheme">Neues Theme</system:String>
<system:String x:Key="deleteTheme">Theme Löschen</system:String>
<system:String x:Key="changeTheme">Theme Ändern</system:String>
<system:String x:Key="ok">Ok</system:String>
<system:String x:Key="cancel">Abbrechen</system:String>
<system:String x:Key="enterLayoutName">Layoutnamen eingeben:</system:String>
<system:String x:Key="layoutAlreadyExists">Layout existiert bereits!</system:String>
<system:String x:Key="enterThemeName">Themenamen eingeben:</system:String>
<system:String x:Key="themeAlreadyExists">Theme existiert bereits!</system:String>
<system:String x:Key="install">Installieren</system:String>
<system:String x:Key="uninstall">Deinstallieren</system:String>
<system:String x:Key="remove">Entfernen</system:String>
<system:String x:Key="authorFormat">Author: {0}</system:String>
<system:String x:Key="addedFormat">Erstellt: {0}</system:String>
<system:String x:Key="updatedFormat">Aktualisiert: {0}</system:String>
<system:String x:Key="versionFormat">Version: {0}</system:String>
<col:ArrayList x:Key="musicVisualizerOptionsComboboxItems">
<system:String>Unten</system:String>
<system:String>Mitte</system:String>
@@ -5,29 +5,53 @@
<system:String x:Key="lineMode">Line</system:String>
<system:String x:Key="mirrorMode">Mirror</system:String>
<system:String x:Key="folder">Folder</system:String>
<system:String x:Key="autoStart">Launch on startup</system:String>
<system:String x:Key="unknown">Unknown</system:String>
<system:String x:Key="open">Open</system:String>
<system:String x:Key="quit">Quit</system:String>
<system:String x:Key="login">Log In</system:String>
<system:String x:Key="logout">Log Out</system:String>
<system:String x:Key="enterModIoEmail">Enter your mod.io account E-mail</system:String>
<system:String x:Key="enterModIoAccessToken">Enter your mod.io security code</system:String>
<system:String x:Key="toggleEditMode">Toggle Edit Mode</system:String>
<system:String x:Key="allPlugins">All Plugins</system:String>
<system:String x:Key="installedPlugins">Installed Plugins</system:String>
<system:String x:Key="updatePlugins">Reload</system:String>
<system:String x:Key="openPluginsFolder">Open Plugins Folder</system:String>
<system:String x:Key="pluginManager">Plugin Manager</system:String>
<system:String x:Key="pluginsFolder">Plugins Folder</system:String>
<system:String x:Key="pluginManager">Plugins Manager</system:String>
<system:String x:Key="createNewPlugin">Create New Plugin</system:String>
<system:String x:Key="enterPluginName">Enter plugin name</system:String>
<system:String x:Key="color">Color:</system:String>
<system:String x:Key="default">Default</system:String>
<system:String x:Key="wantToCloseProgram">Do you really want to close the program?</system:String>
<system:String x:Key="noOptions">No Options!</system:String>
<system:String x:Key="edit">Edit</system:String>
<system:String x:Key="editLayout">Edit Layout</system:String>
<system:String x:Key="time">Time</system:String>
<system:String x:Key="date">Date</system:String>
<system:String x:Key="cpuUsage">CPU Usage</system:String>
<system:String x:Key="googleCalendar">Google Calendar</system:String>
<system:String x:Key="musicVisualizer">Music Visualizer</system:String>
<system:String x:Key="musicVisualizerOptions">Music Visualizer Options:</system:String>
<system:String x:Key="amplifier">Signal Amplification:</system:String>
<system:String x:Key="newLayout">New Layout</system:String>
<system:String x:Key="deleteLayout">Delete Layout</system:String>
<system:String x:Key="newTheme">New Theme</system:String>
<system:String x:Key="deleteTheme">Delete Theme</system:String>
<system:String x:Key="changeTheme">Change Theme</system:String>
<system:String x:Key="ok">Ok</system:String>
<system:String x:Key="cancel">Cancel</system:String>
<system:String x:Key="enterLayoutName">Enter layout name</system:String>
<system:String x:Key="layoutAlreadyExists">Layout already exists!</system:String>
<system:String x:Key="cannotDeleteLastLayout">Can't delete last layout!</system:String>
<system:String x:Key="enterThemeName">Enter theme name</system:String>
<system:String x:Key="themeAlreadyExists">Theme already exists!</system:String>
<system:String x:Key="cannotDeleteLastTheme">Can't delete last theme!</system:String>
<system:String x:Key="install">Install</system:String>
<system:String x:Key="uninstall">Uninstall</system:String>
<system:String x:Key="remove">Remove</system:String>
<system:String x:Key="authorFormat">Author: {0}</system:String>
<system:String x:Key="addedFormat">Added: {0}</system:String>
<system:String x:Key="updatedFormat">Updated: {0}</system:String>
<system:String x:Key="versionFormat">Version: {0}</system:String>
<col:ArrayList x:Key="musicVisualizerOptionsComboboxItems">
<system:String>Bottom</system:String>
<system:String>Middle</system:String>
@@ -1,4 +1,6 @@
using System.Collections.ObjectModel;
using DesktopMagic.Plugins;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
@@ -11,14 +13,28 @@ internal class DesktopMagicSettings : INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged;
private ObservableCollection<Layout> layouts = [];
private ObservableCollection<Theme> themes = [];
private string? currentLayoutName;
public ObservableCollection<Theme> Themes
{
get => themes;
init
{
themes = value;
themes.CollectionChanged += (s, e) => CurrentLayout.UpdateTheme();
OnPropertyChanged();
}
}
public ObservableCollection<Layout> Layouts
{
get => layouts;
set
{
layouts = value;
layouts.CollectionChanged += (s, e) => OnPropertyChanged(nameof(CurrentLayout));
layouts.CollectionChanged += (s, e) => OnPropertyChanged(nameof(CurrentLayoutName));
OnPropertyChanged();
}
}
@@ -37,6 +53,16 @@ internal class DesktopMagicSettings : INotifyPropertyChanged
}
}
public string? ModIoAccessToken { get; set; }
public DesktopMagicSettings()
{
themes.CollectionChanged += (s, e) => CurrentLayout.UpdateTheme();
layouts.CollectionChanged += (s, e) => OnPropertyChanged(nameof(CurrentLayout));
layouts.CollectionChanged += (s, e) => OnPropertyChanged(nameof(CurrentLayoutName));
}
protected void OnPropertyChanged([CallerMemberName] string? name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
+33 -6
View File
@@ -1,9 +1,11 @@
using DesktopMagic.Plugins;
using DesktopMagic.DataContexts;
using DesktopMagic.Plugins;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;
namespace DesktopMagic.Settings;
@@ -12,16 +14,29 @@ internal class Layout(string name) : INotifyPropertyChanged
public event PropertyChangedEventHandler? PropertyChanged;
private string name = name;
private Theme theme = new Theme();
private string? currentThemeName = null;
private Dictionary<uint, PluginSettings> plugins = [];
[JsonIgnore]
public Theme Theme
{
get => theme;
get
{
DesktopMagicSettings settings = MainWindowDataContext.GetSettings();
return settings.Themes.FirstOrDefault(theme => theme.Name == currentThemeName) ?? settings.Themes.FirstOrDefault() ?? new Theme("ERROR");
}
}
public string? CurrentThemeName
{
get => Theme.Name;
set
{
theme = value;
OnPropertyChanged();
if (currentThemeName != value)
{
currentThemeName = value;
UpdateTheme();
}
}
}
@@ -47,7 +62,19 @@ internal class Layout(string name) : INotifyPropertyChanged
public void UpdatePlugins()
{
Plugins = Plugins.ToDictionary();
plugins = plugins.ToDictionary();
OnPropertyChanged(nameof(Plugins));
}
public void UpdateTheme()
{
OnPropertyChanged(nameof(Theme));
OnPropertyChanged(nameof(CurrentThemeName));
foreach (PluginSettings pluginSettings in plugins.Values)
{
pluginSettings.UpdateTheme();
}
}
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
+32 -4
View File
@@ -3,6 +3,7 @@ using DesktopMagic.Plugins;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text.Json.Serialization;
using System.Windows;
@@ -13,19 +14,40 @@ public class PluginSettings : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private readonly Theme? theme;
private string? currentThemeName;
private List<SettingElement> settings = [];
private bool enabled = false;
private Point position = new Point(100, 100);
private Point size = new Point(300, 300);
[JsonIgnore]
public Theme Theme => theme is null ? MainWindowDataContext.GetSettings().CurrentLayout.Theme : theme;
// Only for internal use to show the name of the plugin in the main window
[JsonIgnore]
public string Name { get; set; } = string.Empty;
[JsonIgnore]
public Theme Theme
{
get
{
DesktopMagicSettings settings = MainWindowDataContext.GetSettings();
return settings.Themes.FirstOrDefault(t => t.Name == currentThemeName) ?? settings.CurrentLayout.Theme;
}
}
public string? CurrentThemeName
{
get => currentThemeName;
set
{
if (currentThemeName != value)
{
currentThemeName = value;
OnPropertyChanged();
OnPropertyChanged(nameof(Theme));
}
}
}
public List<SettingElement> Settings
{
get => settings;
@@ -78,6 +100,12 @@ public class PluginSettings : INotifyPropertyChanged
}
}
public void UpdateTheme()
{
OnPropertyChanged(nameof(Theme));
OnPropertyChanged(nameof(CurrentThemeName));
}
protected void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
@@ -3,6 +3,7 @@
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
<OutputType>Library</OutputType>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<ItemGroup>
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework>
@@ -12,25 +12,34 @@
<PackageProjectUrl></PackageProjectUrl>
<FileVersion>0.0.0.5</FileVersion>
<Nullable>enable</Nullable>
<Platforms>AnyCPU;x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<DocumentationFile>C:\Users\David\Programmieren\DesktopMagic\src\DesktopMagicPluginAPI\DesktopMagicPluginAPI.xml</DocumentationFile>
<DocumentationFile>$([System.IO.Path]::Combine($(MSBuildProjectDirectory), "DesktopMagicPluginAPI.xml"))</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<DocumentationFile>$([System.IO.Path]::Combine($(MSBuildProjectDirectory), "DesktopMagicPluginAPI.xml"))</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<DocumentationFile>C:\Users\David\Programmieren\DesktopMagic\src\DesktopMagicPluginAPI\DesktopMagicPluginAPI.xml</DocumentationFile>
<DocumentationFile>$([System.IO.Path]::Combine($(MSBuildProjectDirectory), "DesktopMagicPluginAPI.xml"))</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<DocumentationFile>$([System.IO.Path]::Combine($(MSBuildProjectDirectory), "DesktopMagicPluginAPI.xml"))</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Pack>True</Pack>
<PackagePath>\</PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="8.0.0" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\LICENSE">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
</Project>
@@ -1,4 +1,5 @@
using System.Collections.Generic;
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Drawing;
@@ -6,14 +7,21 @@ namespace DesktopMagic.Api.Drawing;
internal class FontComparer : IEqualityComparer<Font>
{
public bool Equals(Font font1, Font font2)
private const float Tolerance = 0.01f;
public bool Equals(Font? font1, Font? font2)
{
if (font1 is null || font2 is null)
{
return false;
}
if (font1.Name != font2.Name)
{
return false;
}
if (font1.SizeInPoints != font2.SizeInPoints)
if (Math.Abs(font1.SizeInPoints - font2.SizeInPoints) > Tolerance)
{
return false;
}
-21
View File
@@ -1,21 +0,0 @@
MIT License
Copyright (c) 2021 Stone_Red
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+6 -3
View File
@@ -11,16 +11,19 @@ namespace DesktopMagic.Api;
/// </summary>
public abstract class Plugin
{
[Setting("horizontalAlignment", "Horizontal Alignment", -999)]
[Setting("desktopmagic-horizontal-alignment", "Horizontal Alignment", -999)]
internal ComboBox horizontalAlignment = new ComboBox("Center", "Left", "Right");
[Setting("verticalAlignment", "Vertical Alignment", -998)]
[Setting("desktopmagic-vertical-alignment", "Vertical Alignment", -998)]
internal ComboBox verticalAlignment = new ComboBox("Center", "Top", "Bottom");
[Setting("theme-override", "Theme Override", -997)]
internal ComboBox themeOverride = new ComboBox("<None>");
private IPluginData application = null!;
/// <summary>
/// Informations about the main application.
/// Information about the main application.
/// </summary>
public IPluginData Application
{
+2 -2
View File
@@ -10,9 +10,9 @@ public class Button : Setting
/// <summary>
/// Occurs when the button gets clicked.
/// </summary>
public event Action OnClick;
public event Action? OnClick;
private string _value;
private string _value = string.Empty;
/// <summary>
/// Gets or sets the text caption displayed in the <see cref="Button"/> element.
+1 -1
View File
@@ -5,7 +5,7 @@
/// </summary>
public class Label : Setting
{
private string _value;
private string _value = string.Empty;
/// <summary>
/// Gets or sets the text associated with this <see cref="Label"/>.
@@ -1,4 +1,5 @@
using System;
using System.Diagnostics.CodeAnalysis;
namespace DesktopMagic.Api.Settings;
@@ -22,6 +23,7 @@ public sealed class Slider : Setting
/// <summary>
/// Gets or sets the value assigned to the <see cref="Slider"/> element.
/// </summary>
[SuppressMessage("Major Bug", "S1244:Floating point numbers should not be tested for equality", Justification = "Not applicable here since we want to detect changes in the value.")]
public double Value
{
get => _value;
@@ -5,7 +5,7 @@
/// </summary>
public class TextBox : Setting
{
private string _value;
private string _value = string.Empty;
/// <summary>
/// Gets or sets the text associated with this <see cref="TextBox"/>.
-20
View File
@@ -1,20 +0,0 @@
{"message":"No project detected for extracting metadata.","source":"MetadataCommand.ExtractMetadata","date_time":"2022-03-23T17:27:09.2932822Z","message_severity":"warning","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.1.1.3"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\ukjrz4sg.zci'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.3"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\dwwldwwa.bzu'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.4"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\t3fz202q.zli'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.5"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\i2420sau.kem'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.6"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\cb1eimph.z3j'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.7"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\1055nvuh.cur'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.8"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\1dkzedxu.fnm'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.803282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.9"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\nkzrssns.lck'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.8042823Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.10"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\lwogcavo.5da'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.8042823Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.11"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\puc5uwdx.h5d'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.8042823Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.12"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\v12lrk4s.ngm'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.805282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.13"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\0hscybzu.ob2'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.805282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.14"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\rphd3j2r.zjr'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-23T17:27:10.805282Z","message_severity":"error","code":"FatalError","correlation_id":"05F9403E-48D7-4391-A021-24959EE7708C.15"}
{"message":"No project detected for extracting metadata.","source":"MetadataCommand.ExtractMetadata","date_time":"2022-03-24T12:36:07.32842Z","message_severity":"warning","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.1.1.3"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\puc5uwdx.h5d'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-24T12:36:18.2594668Z","message_severity":"error","code":"FatalError","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.3"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\lwogcavo.5da'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-24T12:36:18.2604591Z","message_severity":"error","code":"FatalError","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.4"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\v12lrk4s.ngm'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-24T12:36:18.2604591Z","message_severity":"error","code":"FatalError","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.5"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\t3fz202q.zli'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-24T12:36:18.2604591Z","message_severity":"error","code":"FatalError","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.6"}
{"message":"System.IO.DirectoryNotFoundException: Could not find a part of the path 'C:\\Users\\David\\Programmieren\\DesktopMagic\\src\\DesktopMagicPluginAPI\\obj\\.cache\\build\\dwcg0axe.jl4\\0hscybzu.ob2'.\r\n at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)\r\n at System.IO.File.InternalCopy(String sourceFileName, String destFileName, Boolean overwrite, Boolean checkHost)\r\n at Microsoft.DocAsCode.Common.RealFileWriter.Copy(PathMapping sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.FileAbstractLayer.Copy(RelativePath sourceFileName, RelativePath destFileName)\r\n at Microsoft.DocAsCode.Common.ManifestFileHelper.<>c__DisplayClass8_0.<Dereference>b__4(OutputFileInfo ofi)\r\n at System.Threading.Tasks.Parallel.<>c__DisplayClass42_0`2.<PartitionerForEachWorker>b__1()\r\n at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)\r\n at System.Threading.Tasks.Task.<>c__DisplayClass176_0.<ExecuteSelfReplicating>b__0(Object <p0>)","date_time":"2022-03-24T12:36:18.2604591Z","message_severity":"error","code":"FatalError","correlation_id":"831032FA-9498-4B91-8F87-6478A11BD9B2.7"}
Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 864 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 606 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Some files were not shown because too many files have changed in this diff Show More