20 Commits
Author SHA1 Message Date
Stone_Red 7604acf115 Merge pull request #16 from Stone-Red-Code/develop
Version 1.3.1.0
2026-02-07 00:09:58 +01:00
Stone_Red 8c97f6b56a Update version and installer 2026-02-07 00:09:04 +01:00
Stone_Red 01a1d109ff Add weekend color override settings to DatePlugin 2026-02-07 00:00:44 +01:00
Stone_Red d2f123e0f5 Make sure underscore is properly escaped 2026-02-06 23:45:34 +01:00
Stone_Red f217574022 Add FPS limit setting and throttle Main() calls in MusicVisualizerPlugin 2026-01-23 21:53:54 +01:00
Stone_Red 1e9c74af52 Optimize bitmap rendering in PluginWindow 2026-01-23 21:13:40 +01:00
Stone_Red 2853d49dd9 Add rotation setting to plugins 2026-01-23 20:35:15 +01:00
Stone_Red 4133f61a5c Add customizable date format options 2026-01-23 00:33:46 +01:00
Stone_Red e3056a398a Update default and post-load info messages for GIF plugin 2026-01-22 17:54:23 +01:00
Stone_Red cd0bcad181 Add submenu options for bug reporting and feature requests via GitHub or email 2026-01-22 17:53:20 +01:00
Stone_Red fec26069be Make sure date plugin updates when settings change 2026-01-22 15:29:35 +01:00
Stone_Red f84dd20eb9 Update NuGet packages 2026-01-22 15:29:35 +01:00
Stone_Red 9581cc185c Replace all Buttons with icons with ui:Button 2026-01-22 15:29:35 +01:00
Stone_Red a438ab5475 Add Documentation navigation item with click handler linking to GitHub 2026-01-22 15:29:35 +01:00
Stone_Red 1b496db094 Replace TextBox with FileSelector for gif-path plugin setting 2026-01-22 15:29:35 +01:00
Stone_Red 3dce9ab59a Add CreatePluginDialog for plugin creation and update search boxes with icons 2026-01-22 15:29:35 +01:00
Stone_Red a85e57ad58 Fix titles of dialogs 2026-01-22 15:29:34 +01:00
Stone_Red 1cafc01cd7 Merge pull request #13 from Stone-Red-Code/develop
Update README
2026-01-22 00:10:14 +01:00
Stone_Red d319b32263 Update third party licenses in README.md 2026-01-22 00:09:26 +01:00
Stone_Red ca83e5585f Replace old screenshots with new ones
Updated preview images in README with new screenshots.
2026-01-22 00:08:01 +01:00
29 changed files with 407 additions and 130 deletions
+3 -3
View File
@@ -23,12 +23,12 @@
## Preview ## Preview
![Screenshot 2023-12-31 164947](https://github.com/Stone-Red-Code/DesktopMagic/assets/56473591/191ac76f-264d-4e9f-8979-7a13b2a1cd12) ![Screenshot 2026-01-22 000348](https://github.com/user-attachments/assets/4617330d-4c4b-4509-80d7-9f6db413e84f)
![Screenshot 2023-12-31 164853](https://github.com/Stone-Red-Code/DesktopMagic/assets/56473591/22de55d2-dde3-43a5-b77b-c773a7697e8c) ![Screenshot 2026-01-22 000434](https://github.com/user-attachments/assets/aebeca87-b305-40a4-a942-d78fce0e9e97)
## Third party licenses ## Third party licenses
- [BusyIndicator](https://github.com/moh3ngolshani/BusyIndicator) - [MIT](https://github.com/Moh3nGolshani/BusyIndicator/blob/master/LICENSE) - [BusyIndicator](https://github.com/moh3ngolshani/BusyIndicator) - [MIT](https://github.com/Moh3nGolshani/BusyIndicator/blob/master/LICENSE)
- [Material Design In XAML Toolkit](https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit) - [MIT](https://github.com/MaterialDesignInXAML/MaterialDesignInXamlToolkit/blob/master/LICENSE) - [WPF UI](https://github.com/lepoco/wpfui) - [MIT](https://github.com/lepoco/wpfui/blob/main/LICENSE.md)
- [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) - [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) - [NAudio](https://github.com/naudio/NAudio) - [MIT](https://github.com/naudio/NAudio/blob/master/license.txt)
Binary file not shown.
+116 -6
View File
@@ -4,13 +4,34 @@ using DesktopMagic.Api.Settings;
using System; using System;
using System.Drawing; using System.Drawing;
using System.Drawing.Text; using System.Drawing.Text;
using System.Globalization;
using System.Linq;
using System.Text.RegularExpressions;
namespace DesktopMagic.BuiltInPlugins; namespace DesktopMagic.BuiltInPlugins;
internal class DatePlugin : Plugin internal partial class DatePlugin : Plugin
{ {
[Setting("short-date", "Short date")] [Setting("week-day-style", "Week Day Style")]
private readonly CheckBox shortDateCheckBox = new CheckBox(true); public ComboBox weekDayStyleComboBox = new ComboBox([.. Enum.GetValues<WeekdayStyle>().Select(e => e.ToString())]);
[Setting("day-style", "Day Style")]
public ComboBox dayStyleComboBox = new ComboBox([.. Enum.GetValues<DayStyle>().Select(e => e.ToString())]);
[Setting("month-style", "Month Style")]
public ComboBox monthStyleComboBox = new ComboBox([.. Enum.GetValues<MonthStyle>().Select(e => e.ToString())]);
[Setting("year-style", "Year Style")]
public ComboBox yearStyleComboBox = new ComboBox([.. Enum.GetValues<YearStyle>().Select(e => e.ToString())]);
[Setting("use-date-separators", "Use Date Separators")]
public CheckBox useDateSeparators = new CheckBox(true);
[Setting("use-color-override-for-weekend", "Use Color Override For Weekend")]
public CheckBox useColorOverrideForWeekend = new CheckBox(false);
[Setting("weekend-color-override", "Weekend Color Override")]
public ColorPicker weekendColorOverride = new ColorPicker(Color.Red);
private DateTime oldDateTime = DateTime.MinValue; private DateTime oldDateTime = DateTime.MinValue;
private bool themeChanged = false; private bool themeChanged = false;
@@ -27,7 +48,68 @@ internal class DatePlugin : Plugin
oldDateTime = DateTime.Now; oldDateTime = DateTime.Now;
themeChanged = false; themeChanged = false;
string date = shortDateCheckBox.Value ? DateTime.Now.ToShortDateString() : DateTime.Now.ToLongDateString(); CultureInfo culture = CultureInfo.CurrentCulture;
DateTime dateTime = DateTime.Now;
DateTimeFormatInfo dtf = culture.DateTimeFormat;
string pattern = dtf.LongDatePattern;
WeekdayStyle weekdayStyle = Enum.Parse<WeekdayStyle>(weekDayStyleComboBox.Value);
DayStyle dayStyle = Enum.Parse<DayStyle>(dayStyleComboBox.Value);
MonthStyle monthStyle = Enum.Parse<MonthStyle>(monthStyleComboBox.Value);
YearStyle yearStyle = Enum.Parse<YearStyle>(yearStyleComboBox.Value);
// Weekday: ddd, dddd
pattern = WeekdayRegex().Replace(pattern, weekdayStyle switch
{
WeekdayStyle.Long => "dddd",
WeekdayStyle.Short => "ddd",
_ => ""
});
// Day: d, dd
pattern = DayRegex().Replace(pattern, dayStyle switch
{
DayStyle.Numeric => "dd",
_ => ""
});
// Month: M, MM, MMM, MMMM
pattern = MonthRegex().Replace(pattern, monthStyle switch
{
MonthStyle.Long => "MMMM",
MonthStyle.Short => "MMM",
MonthStyle.Numeric => "MM",
_ => ""
});
// Year: yy, yyyy
pattern = YearRegex().Replace(pattern, yearStyle switch
{
YearStyle.FourDigit => "yyyy",
YearStyle.TwoDigit => "yy",
_ => ""
});
// Clean up leftover punctuation/spacing
pattern = CleanupRegex().Replace(pattern, " ").Trim();
if (string.IsNullOrWhiteSpace(pattern))
{
pattern = dtf.LongDatePattern;
}
string date = dateTime.ToString(pattern, culture);
if (useDateSeparators.Value)
{
date = DateSeparatorsRegex().Replace(date, dtf.DateSeparator);
}
Color color = useColorOverrideForWeekend.Value && (dateTime.DayOfWeek == DayOfWeek.Saturday || dateTime.DayOfWeek == DayOfWeek.Sunday)
? weekendColorOverride.Value
: Application.Theme.PrimaryColor;
using Font font = new Font(Application.Theme.Font, 200); using Font font = new Font(Application.Theme.Font, 200);
@@ -42,7 +124,7 @@ internal class DatePlugin : Plugin
bmp.SetResolution(100, 100); bmp.SetResolution(100, 100);
using Graphics gr = Graphics.FromImage(bmp); using Graphics gr = Graphics.FromImage(bmp);
using SolidBrush brush = new SolidBrush(Application.Theme.PrimaryColor); using SolidBrush brush = new SolidBrush(color);
gr.TextRenderingHint = TextRenderingHint.AntiAlias; gr.TextRenderingHint = TextRenderingHint.AntiAlias;
gr.DrawString(date, font, brush, 0, 0); gr.DrawString(date, font, brush, 0, 0);
@@ -54,4 +136,32 @@ internal class DatePlugin : Plugin
{ {
themeChanged = true; themeChanged = true;
} }
}
public override void OnSettingsChanged()
{
themeChanged = true;
}
[GeneratedRegex(@"d{3,4}")]
private static partial Regex WeekdayRegex();
[GeneratedRegex(@"\b(?<!d)d{1,2}\b")]
private static partial Regex DayRegex();
[GeneratedRegex(@"M{1,4}")]
private static partial Regex MonthRegex();
[GeneratedRegex(@"y{2,4}")]
private static partial Regex YearRegex();
[GeneratedRegex(@"[\s,./\-]+")]
private static partial Regex CleanupRegex();
[GeneratedRegex(@"(?<=\d)\s+(?=\d)")]
private static partial Regex DateSeparatorsRegex();
public enum WeekdayStyle { None, Short, Long }
public enum DayStyle { None, Numeric }
public enum MonthStyle { None, Numeric, Short, Long }
public enum YearStyle { None, TwoDigit, FourDigit }
}
@@ -20,6 +20,11 @@ internal class MusicVisualizerPlugin : Plugin
private readonly Bitmap output = new Bitmap(880, 300); private readonly Bitmap output = new Bitmap(880, 300);
private readonly System.Diagnostics.Stopwatch frameStopwatch = System.Diagnostics.Stopwatch.StartNew();
[Setting("fps-limit", "FPS Limit")]
private readonly IntegerUpDown fpsLimit = new IntegerUpDown(1, 144, 60);
[Setting("mirror", "Mirror")] [Setting("mirror", "Mirror")]
private readonly CheckBox mirrorMode = new CheckBox(false); private readonly CheckBox mirrorMode = new CheckBox(false);
@@ -51,8 +56,16 @@ internal class MusicVisualizerPlugin : Plugin
waveIn.StartRecording(); waveIn.StartRecording();
} }
public override Bitmap Main() public override Bitmap? Main()
{ {
double msPerFrame = 1000.0 / Math.Max(1, fpsLimit.Value);
if (frameStopwatch.Elapsed.TotalMilliseconds < msPerFrame)
{
return null; // Exit early if we haven't reached the time threshold
}
frameStopwatch.Restart(); // Reset timer for the next frame
return output; return output;
} }
@@ -9,6 +9,8 @@ using System.Runtime.CompilerServices;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
using Wpf.Ui.Controls;
namespace DesktopMagic.DataContexts; namespace DesktopMagic.DataContexts;
internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand command, PluginEntryDataContext.Mode mode, string? path = null, string? csprojPath = null) : INotifyPropertyChanged internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand command, PluginEntryDataContext.Mode mode, string? path = null, string? csprojPath = null) : INotifyPropertyChanged
@@ -38,7 +40,20 @@ internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand co
public ICommand Command => command; public ICommand Command => command;
public ButtonData InstallUninstallButtonData => new(mode == Mode.Install ? "Download24" : "Delete24", GetInstallUninstallButtonText(), true, Command); public ButtonData InstallUninstallButtonData
{
get
{
if (mode == Mode.Install)
{
return new(new SymbolIcon(SymbolRegular.ArrowDownload24), GetInstallUninstallButtonText(), true, Command);
}
else
{
return new(new SymbolIcon(SymbolRegular.Delete24), GetInstallUninstallButtonText(), true, Command);
}
}
}
public ButtonData OpenButtonData public ButtonData OpenButtonData
{ {
@@ -46,15 +61,15 @@ internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand co
{ {
if (File.Exists(csprojPath)) if (File.Exists(csprojPath))
{ {
return new("Code24", "IDE", true, new CommandHandler(OpenCsprojInIDE)); return new(new SymbolIcon(SymbolRegular.Code24), "IDE", true, new CommandHandler(OpenCsprojInIDE));
} }
else if (string.IsNullOrWhiteSpace(pluginMetadata.ProfileUri?.ToString())) else if (string.IsNullOrWhiteSpace(pluginMetadata.ProfileUri?.ToString()))
{ {
return new("Folder24", (string)App.LanguageDictionary["folder"], path is not null, new CommandHandler(() => Process.Start("explorer.exe", path!))); return new(new SymbolIcon(SymbolRegular.Folder24), (string)App.LanguageDictionary["folder"], path is not null, new CommandHandler(() => Process.Start("explorer.exe", path!)));
} }
else else
{ {
return new("Open24", "mod.io", true, new CommandHandler(OpenModIoPage)); return new(new SymbolIcon(SymbolRegular.Open24), "mod.io", true, new CommandHandler(OpenModIoPage));
} }
} }
} }
@@ -126,7 +141,7 @@ internal class PluginEntryDataContext(PluginMetadata pluginMetadata, ICommand co
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
} }
public record ButtonData(string Icon, string Text, bool IsEnabled, ICommand Command); public record ButtonData(SymbolIcon Icon, string Text, bool IsEnabled, ICommand Command);
public enum Mode public enum Mode
{ {
+8 -8
View File
@@ -7,14 +7,15 @@
<ApplicationIcon>icon.ico</ApplicationIcon> <ApplicationIcon>icon.ico</ApplicationIcon>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent> <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
<Authors>Stone_Red</Authors> <Authors>Stone_Red</Authors>
<Version>1.3.0.0</Version> <Version>1.3.1.0</Version>
<PackageProjectUrl>https://github.com/Stone-Red-Code/DesktopMagic</PackageProjectUrl> <PackageProjectUrl>https://github.com/Stone-Red-Code/DesktopMagic</PackageProjectUrl>
<RepositoryUrl>https://github.com/Stone-Red-Code/DesktopMagic</RepositoryUrl> <RepositoryUrl>https://github.com/Stone-Red-Code/DesktopMagic</RepositoryUrl>
<AssemblyVersion>1.3.0.0</AssemblyVersion> <AssemblyVersion>1.3.1.0</AssemblyVersion>
<FileVersion>1.3.0.0</FileVersion> <FileVersion>1.3.1.0</FileVersion>
<TargetFramework>net8.0-windows7.0</TargetFramework> <TargetFramework>net8.0-windows7.0</TargetFramework>
<RuntimeIdentifier>win-x64</RuntimeIdentifier> <RuntimeIdentifier>win-x64</RuntimeIdentifier>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion> <IncludeSourceRevisionInInformationalVersion>false</IncludeSourceRevisionInInformationalVersion>
<Platforms>AnyCPU;x64</Platforms> <Platforms>AnyCPU;x64</Platforms>
</PropertyGroup> </PropertyGroup>
@@ -43,16 +44,15 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="BusyIndicators" Version="2.1.2" /> <PackageReference Include="BusyIndicators" Version="2.1.3" />
<PackageReference Include="CuteUtils" Version="1.0.0" /> <PackageReference Include="CuteUtils" Version="1.0.0" />
<PackageReference Include="Interop.IWshRuntimeLibrary" Version="1.0.1" /> <PackageReference Include="Interop.IWshRuntimeLibrary" Version="1.0.1" />
<PackageReference Include="MaterialDesignThemes" Version="5.1.0" /> <PackageReference Include="Microsoft.Web.WebView2" Version="1.0.3650.58" />
<PackageReference Include="Microsoft.Web.WebView2" Version="1.0.2592.51" />
<PackageReference Include="Modio" Version="1.0.0" /> <PackageReference Include="Modio" Version="1.0.0" />
<PackageReference Include="NAudio" Version="2.2.1" /> <PackageReference Include="NAudio" Version="2.2.1" />
<PackageReference Include="System.Management" Version="8.0.0" /> <PackageReference Include="System.Management" Version="8.0.0" />
<PackageReference Include="WPF-UI" Version="4.1.0" /> <PackageReference Include="WPF-UI" Version="4.2.0" />
<PackageReference Include="WPF-UI.Tray" Version="4.1.0" /> <PackageReference Include="WPF-UI.Tray" Version="4.2.0" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
+1 -1
View File
@@ -28,7 +28,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ui:TitleBar ShowMinimize="False" ShowMaximize="False"> <ui:TitleBar x:Name="titleBar" ShowMinimize="False" ShowMaximize="False">
<ui:TitleBar.Icon> <ui:TitleBar.Icon>
<ui:ImageIcon Source="{StaticResource Icon}" /> <ui:ImageIcon Source="{StaticResource Icon}" />
</ui:TitleBar.Icon> </ui:TitleBar.Icon>
@@ -24,6 +24,7 @@ public partial class ColorDialog : FluentWindow
Resources.MergedDictionaries.Add(App.LanguageDictionary); Resources.MergedDictionaries.Add(App.LanguageDictionary);
label.Content = content; label.Content = content;
titleBar.Title = title;
Title = title; Title = title;
alphaSlider.Value = defaultColor.A; alphaSlider.Value = defaultColor.A;
@@ -0,0 +1,55 @@
<ui:FluentWindow x:Class="DesktopMagic.Dialogs.CreatePluginDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ui="http://schemas.lepo.co/wpfui/2022/xaml"
xmlns:tray="http://schemas.lepo.co/wpfui/2022/xaml/tray"
xmlns:pages="clr-namespace:DesktopMagic.Pages"
xmlns:plugins="clr-namespace:DesktopMagic.Plugins"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dataContext="clr-namespace:DesktopMagic.DataContexts"
d:DataContext="{d:DesignInstance Type=dataContext:MainWindowDataContext}"
ui:Design.Background="{DynamicResource ApplicationBackgroundBrush}"
ui:Design.Foreground="{DynamicResource TextFillColorPrimaryBrush}"
Foreground="{DynamicResource TextFillColorPrimaryBrush}"
WindowCornerPreference="Round"
WindowBackdropType="Tabbed"
Height="230"
Width="300"
MinHeight="160"
MinWidth="300"
WindowStartupLocation="CenterOwner"
ExtendsContentIntoTitleBar="True">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ui:TitleBar Title="Create New Plugin" ShowMinimize="False" ShowMaximize="False">
<ui:TitleBar.Icon>
<ui:ImageIcon Source="{StaticResource Icon}" />
</ui:TitleBar.Icon>
</ui:TitleBar>
<StackPanel Grid.Row="1" Margin="{StaticResource DefaultMargin}" Orientation="Horizontal" HorizontalAlignment="Center">
<ui:TextBlock TextWrapping="Wrap" VerticalAlignment="Center" Foreground="{DynamicResource TextFillColorSecondaryBrush}">
Please check out the
</ui:TextBlock>
<ui:HyperlinkButton Padding="0" Content=" Plugin Creation Guide" VerticalAlignment="Center" VerticalContentAlignment="Center" NavigateUri="https://mod.io/g/desktopmagic/r/plugin-creation-guide/" />
</StackPanel>
<StackPanel Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="15">
<Label Content="{DynamicResource enterPluginName}" HorizontalAlignment="Left" VerticalAlignment="Top" />
<ui:TextBox x:Name="textBox" HorizontalAlignment="Stretch" Margin="5" TextWrapping="Wrap" VerticalAlignment="Top" VerticalContentAlignment="Center" />
</StackPanel>
<StackPanel Grid.Row="3" Orientation="Horizontal" HorizontalAlignment="Right" Margin="5">
<Button x:Name="okButton" Content="{DynamicResource ok }" HorizontalAlignment="Left" Margin="0 0 5 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>
</Grid>
</ui:FluentWindow>
@@ -0,0 +1,29 @@
using System.Windows;
namespace DesktopMagic.Dialogs;
public partial class CreatePluginDialog : Wpf.Ui.Controls.FluentWindow
{
public string ResponseText
{
get => textBox.Text;
set => textBox.Text = value;
}
public CreatePluginDialog()
{
InitializeComponent();
Resources.MergedDictionaries.Add(App.LanguageDictionary);
}
private void OkButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = true;
}
private void CancelButton_Click(object sender, RoutedEventArgs e)
{
DialogResult = false;
}
}
+1 -1
View File
@@ -28,7 +28,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ui:TitleBar ShowMinimize="False" ShowMaximize="False"> <ui:TitleBar x:Name="titleBar" ShowMinimize="False" ShowMaximize="False">
<ui:TitleBar.Icon> <ui:TitleBar.Icon>
<ui:ImageIcon Source="{StaticResource Icon}" /> <ui:ImageIcon Source="{StaticResource Icon}" />
</ui:TitleBar.Icon> </ui:TitleBar.Icon>
@@ -17,6 +17,7 @@ public partial class InputDialog : Wpf.Ui.Controls.FluentWindow
Resources.MergedDictionaries.Add(App.LanguageDictionary); Resources.MergedDictionaries.Add(App.LanguageDictionary);
label.Content = content; label.Content = content;
titleBar.Title = title;
Title = title; Title = title;
} }
+1 -1
View File
@@ -28,7 +28,7 @@
<RowDefinition Height="Auto" /> <RowDefinition Height="Auto" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<ui:TitleBar ShowMinimize="False" ShowMaximize="False"> <ui:TitleBar x:Name="titleBar" ShowMinimize="False" ShowMaximize="False">
<ui:TitleBar.Icon> <ui:TitleBar.Icon>
<ui:ImageIcon Source="{StaticResource Icon}" /> <ui:ImageIcon Source="{StaticResource Icon}" />
</ui:TitleBar.Icon> </ui:TitleBar.Icon>
@@ -29,6 +29,7 @@ public partial class ThemeDialog : Wpf.Ui.Controls.FluentWindow
backgroundColorRechtangle.Background = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(theme.BackgroundColor)); backgroundColorRechtangle.Background = new SolidColorBrush(MultiColorConverter.ConvertToMediaColor(theme.BackgroundColor));
label.Content = content; label.Content = content;
titleBar.Title = title;
Title = title; Title = title;
} }
+32 -6
View File
@@ -73,15 +73,44 @@
</ui:NavigationView.MenuItems> </ui:NavigationView.MenuItems>
<ui:NavigationView.FooterMenuItems> <ui:NavigationView.FooterMenuItems>
<ui:NavigationViewItem Content="{DynamicResource requestFeature}" Click="ReportBugNavigationViewItem_Click"> <ui:NavigationViewItem Content="Documentation" Click="DocumentationNavigationViewItem_Click">
<ui:NavigationViewItem.Icon>
<ui:SymbolIcon Symbol="LightbulbFilament24"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="{DynamicResource requestFeature}">
<ui:NavigationViewItem.Icon> <ui:NavigationViewItem.Icon>
<ui:SymbolIcon Symbol="ChatHelp24"/> <ui:SymbolIcon Symbol="ChatHelp24"/>
</ui:NavigationViewItem.Icon> </ui:NavigationViewItem.Icon>
<ui:NavigationViewItem.MenuItems>
<ui:NavigationViewItem Content="GitHub" Click="RequestFeatureNavigationViewItem_Click">
<ui:NavigationViewItem.Icon>
<ui:SymbolIcon Symbol="Globe24"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="{DynamicResource email}" Click="RequestFeatureEmailNavigationViewItem_Click">
<ui:NavigationViewItem.Icon>
<ui:SymbolIcon Symbol="Mail24"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
</ui:NavigationViewItem.MenuItems>
</ui:NavigationViewItem> </ui:NavigationViewItem>
<ui:NavigationViewItem Content="{DynamicResource reportBug}" Click="ReportBugNavigationViewItem_Click"> <ui:NavigationViewItem Content="{DynamicResource reportBug}">
<ui:NavigationViewItem.Icon> <ui:NavigationViewItem.Icon>
<ui:SymbolIcon Symbol="Bug24"/> <ui:SymbolIcon Symbol="Bug24"/>
</ui:NavigationViewItem.Icon> </ui:NavigationViewItem.Icon>
<ui:NavigationViewItem.MenuItems>
<ui:NavigationViewItem Content="GitHub" Click="ReportBugNavigationViewItem_Click">
<ui:NavigationViewItem.Icon>
<ui:SymbolIcon Symbol="Globe24"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
<ui:NavigationViewItem Content="{DynamicResource email}" Click="ReportBugEmailNavigationViewItem_Click">
<ui:NavigationViewItem.Icon>
<ui:SymbolIcon Symbol="Mail24"/>
</ui:NavigationViewItem.Icon>
</ui:NavigationViewItem>
</ui:NavigationViewItem.MenuItems>
</ui:NavigationViewItem> </ui:NavigationViewItem>
</ui:NavigationView.FooterMenuItems> </ui:NavigationView.FooterMenuItems>
</ui:NavigationView> </ui:NavigationView>
@@ -94,10 +123,7 @@
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Column="0"> <ui:HyperlinkButton FontWeight="Bold" Content="{DynamicResource developedBy}" NavigateUri="https://me.stone-red.net"/>
<ui:HyperlinkButton FontWeight="Bold" Content="{DynamicResource developedBy}" NavigateUri="https://me.stone-red.net"/>
</StackPanel>
<ui:ToggleSwitch x:Name="autoStartCheckBox" Style="{StaticResource ToggleSwitchContentLeftStyle}" Grid.Column="2" Margin="0 0 5 0" Content="{DynamicResource autoStart}" IsChecked="{Binding IsAutoStartEnabled}" VerticalAlignment="Center"/> <ui:ToggleSwitch x:Name="autoStartCheckBox" Style="{StaticResource ToggleSwitchContentLeftStyle}" Grid.Column="2" Margin="0 0 5 0" Content="{DynamicResource autoStart}" IsChecked="{Binding IsAutoStartEnabled}" VerticalAlignment="Center"/>
</Grid> </Grid>
</Border> </Border>
+36
View File
@@ -14,6 +14,7 @@ public partial class MainWindow : FluentWindow
private readonly Manager _manager = Manager.Instance; private readonly Manager _manager = Manager.Instance;
private readonly MainWindowDataContext _mainWindowDataContext = new(); private readonly MainWindowDataContext _mainWindowDataContext = new();
[Obsolete]
public MainWindow() public MainWindow()
{ {
SystemThemeWatcher.Watch(this); SystemThemeWatcher.Watch(this);
@@ -123,6 +124,18 @@ public partial class MainWindow : FluentWindow
_ = Process.Start(psi); _ = Process.Start(psi);
} }
private void ReportBugEmailNavigationViewItem_Click(object sender, RoutedEventArgs e)
{
string uri = "mailto:[email protected]";
ProcessStartInfo psi = new()
{
UseShellExecute = true,
FileName = uri
};
_ = Process.Start(psi);
}
private void RequestFeatureNavigationViewItem_Click(object sender, RoutedEventArgs e) private void RequestFeatureNavigationViewItem_Click(object sender, RoutedEventArgs e)
{ {
string uri = "https://github.com/Stone-Red-Code/DesktopMagic/issues/new?template=feature_request.md"; string uri = "https://github.com/Stone-Red-Code/DesktopMagic/issues/new?template=feature_request.md";
@@ -134,6 +147,29 @@ public partial class MainWindow : FluentWindow
_ = Process.Start(psi); _ = Process.Start(psi);
} }
private void RequestFeatureEmailNavigationViewItem_Click(object sender, RoutedEventArgs e)
{
string uri = "mailto:[email protected]";
ProcessStartInfo psi = new()
{
UseShellExecute = true,
FileName = uri
};
_ = Process.Start(psi);
}
private void DocumentationNavigationViewItem_Click(object sender, RoutedEventArgs e)
{
string uri = "https://github.com/Stone-Red-Code/DesktopMagic";
ProcessStartInfo psi = new()
{
UseShellExecute = true,
FileName = uri
};
_ = Process.Start(psi);
}
private void NotifyIcon_LeftClick(Wpf.Ui.Tray.Controls.NotifyIcon sender, RoutedEventArgs e) private void NotifyIcon_LeftClick(Wpf.Ui.Tray.Controls.NotifyIcon sender, RoutedEventArgs e)
{ {
RestoreWindow(); RestoreWindow();
+2 -12
View File
@@ -71,18 +71,8 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ComboBox x:Name="layoutsComboBox" ItemsSource="{Binding Settings.Layouts}" DisplayMemberPath="Name" SelectedValue="{Binding Settings.CurrentLayoutName}" SelectedValuePath="Name" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Padding="4" SelectionChanged="LayoutsComboBox_SelectionChanged" /> <ComboBox x:Name="layoutsComboBox" ItemsSource="{Binding Settings.Layouts}" DisplayMemberPath="Name" SelectedValue="{Binding Settings.CurrentLayoutName}" SelectedValuePath="Name" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Padding="4" SelectionChanged="LayoutsComboBox_SelectionChanged" />
<Button x:Name="newLayoutButton" Grid.Column="2" HorizontalAlignment="Stretch" Click="NewLayoutButton_Click" FontWeight="Regular"> <ui:Button x:Name="newLayoutButton" Content="{DynamicResource newLayout}" Grid.Column="2" Icon="{ui:SymbolIcon Add24}" HorizontalAlignment="Stretch" Click="NewLayoutButton_Click" FontWeight="Regular"/>
<StackPanel Orientation="Horizontal"> <ui:Button x:Name="removeLayoutButton" Content="{DynamicResource deleteLayout}" Icon="{ui:SymbolIcon Delete24}" Grid.Column="4" HorizontalAlignment="Stretch" Click="RemoveLayoutButton_Click" FontWeight="Regular"/>
<ui:SymbolIcon Symbol="Add24" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource newLayout}" />
</StackPanel>
</Button>
<Button x:Name="removeLayoutButton" Grid.Column="4" HorizontalAlignment="Stretch" Click="RemoveLayoutButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Delete24" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource deleteLayout}" />
</StackPanel>
</Button>
</Grid> </Grid>
</ui:Card> </ui:Card>
</Grid> </Grid>
+5 -18
View File
@@ -25,12 +25,9 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<TextBlock Margin="8" VerticalAlignment="Center" FontWeight="SemiBold" Text="{Binding Name, Mode=OneWay}" /> <TextBlock Margin="8" VerticalAlignment="Center" FontWeight="SemiBold" Text="{Binding Name, Mode=OneWay}" />
<StackPanel Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal" Margin="{StaticResource DefaultMargin}"> <StackPanel Grid.Column="1" VerticalAlignment="Center" Orientation="Horizontal" Margin="{StaticResource DefaultMargin}">
<Button x:Name="editThemeButton" HorizontalAlignment="Stretch" Click="EditThemeButton_Click" FontWeight="Regular" Tag="{Binding}"> <ui:Button x:Name="editThemeButton" Content="{DynamicResource editTheme}" Icon="{ui:SymbolIcon Color24}" HorizontalAlignment="Stretch" Click="EditThemeButton_Click" FontWeight="Regular" Tag="{Binding}">
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Color24" Margin="0 0 10 0" /> </ui:Button>
<TextBlock Text="{DynamicResource editTheme}" />
</StackPanel>
</Button>
</StackPanel> </StackPanel>
</Grid> </Grid>
</DataTemplate> </DataTemplate>
@@ -47,18 +44,8 @@
<ColumnDefinition Width="0.5*" /> <ColumnDefinition Width="0.5*" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Button x:Name="newThemeButton" Grid.Column="2" HorizontalAlignment="Stretch" Click="AddThemeButton_Click" FontWeight="Regular"> <ui:Button x:Name="newThemeButton" Content="{DynamicResource newTheme}" Icon="{ui:SymbolIcon Add24}" Grid.Column="2" HorizontalAlignment="Stretch" Click="AddThemeButton_Click" FontWeight="Regular"/>
<StackPanel Orientation="Horizontal"> <ui:Button x:Name="deleteThemeButton" Content="{DynamicResource deleteTheme}" Icon="{ui:SymbolIcon Delete24}" Grid.Column="4" HorizontalAlignment="Stretch" Click="DeleteThemeButton_Click" FontWeight="Regular"/>
<ui:SymbolIcon Symbol="Add24" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource newTheme}" />
</StackPanel>
</Button>
<Button x:Name="deleteThemeButton" Grid.Column="4" HorizontalAlignment="Stretch" Click="DeleteThemeButton_Click" FontWeight="Regular">
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="Delete24" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource deleteTheme}" />
</StackPanel>
</Button>
</Grid> </Grid>
</ui:Card> </ui:Card>
</Grid> </Grid>
+2 -12
View File
@@ -40,18 +40,8 @@
<ColumnDefinition /> <ColumnDefinition />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Button Grid.Column="0" Command="{Binding InstallUninstallButtonData.Command}" IsEnabled="{Binding InstallUninstallButtonData.IsEnabled}" VerticalAlignment="Bottom" HorizontalAlignment="Stretch"> <ui:Button Content="{Binding InstallUninstallButtonData.Text}" Icon="{Binding InstallUninstallButtonData.Icon}" Grid.Column="0" Command="{Binding InstallUninstallButtonData.Command}" IsEnabled="{Binding InstallUninstallButtonData.IsEnabled}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
<StackPanel Orientation="Horizontal"> <ui:Button Content="{Binding OpenButtonData.Text}" Icon="{Binding OpenButtonData.Icon}" Grid.Column="1" Command="{Binding OpenButtonData.Command}" IsEnabled="{Binding OpenButtonData.IsEnabled}" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="5 0 5 0"/>
<ui:SymbolIcon Symbol="Delete24" 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 0 5 0">
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="{Binding OpenButtonData.Icon}" Margin="0 0 10 0" />
<TextBlock Text="{Binding OpenButtonData.Text}" />
</StackPanel>
</Button>
</Grid> </Grid>
<StackPanel Grid.Row="2" Grid.ColumnSpan="2" Margin="5"> <StackPanel Grid.Row="2" Grid.ColumnSpan="2" Margin="5">
+7 -22
View File
@@ -14,7 +14,7 @@
ScrollViewer.CanContentScroll="False" ScrollViewer.CanContentScroll="False"
Title="{DynamicResource pluginManager}"> Title="{DynamicResource pluginManager}">
<busyIndicator:BusyMask x:Name="BusyIndicator" IsBusy="{Binding IsLoading}" IndicatorType="Cogs" BusyContent="Please wait..." BusyContentMargin="0,20,0,0" IsBusyAtStartup="False" Foreground="{DynamicResource TextFillColorPrimaryBrush}" Background="{DynamicResource ControlStrokeColorDefaultBrush}"> <busyIndicator:BusyMask x:Name="BusyIndicator" IsBusy="{Binding IsLoading}" IndicatorType="ThreeDots" BusyContent="Please wait..." BusyContentMargin="0,20,0,0" Foreground="{DynamicResource TextFillColorPrimaryBrush}" Background="{DynamicResource ControlStrokeColorDefaultBrush}">
<Grid Margin="{StaticResource DefaultMargin}"> <Grid Margin="{StaticResource DefaultMargin}">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="auto" /> <RowDefinition Height="auto" />
@@ -36,12 +36,12 @@
<ColumnDefinition /> <ColumnDefinition />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<ui:TextBox Grid.Column="0" Text="{Binding AllPluginsSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="AllPluginsSearchTextBox_TextChanged" PlaceholderText="{DynamicResource searchAllPlugins}" /> <ui:TextBox Grid.Column="0" Text="{Binding AllPluginsSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="AllPluginsSearchTextBox_TextChanged" PlaceholderText="{DynamicResource searchAllPlugins}" Icon="{ui:SymbolIcon Search24}" IconPlacement="Right" />
<ui:TextBox Grid.Column="2" Text="{Binding InstalledPluginsSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="InstalledPluginsSearchTextBox_TextChanged" PlaceholderText="{DynamicResource searchInstalledPlugins}" /> <ui:TextBox Grid.Column="2" Text="{Binding InstalledPluginsSearchText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" TextChanged="InstalledPluginsSearchTextBox_TextChanged" PlaceholderText="{DynamicResource searchInstalledPlugins}" Icon="{ui:SymbolIcon Search24}" IconPlacement="Right" />
</Grid> </Grid>
</ui:Card> </ui:Card>
<busyIndicator:BusyMask Grid.Row="2" IsBusy="{Binding IsSearching}" IndicatorType="Ring" BusyContent="Searching..." BusyContentMargin="0,50,0,0" IsBusyAtStartup="False" Foreground="{DynamicResource TextFillColorPrimaryBrush}" Background="{DynamicResource ControlStrokeColorDefaultBrush}"> <busyIndicator:BusyMask Grid.Row="2" IsBusy="{Binding IsSearching}" IndicatorType="ThreeDots" BusyContent="Searching..." BusyContentMargin="0,50,0,0" Foreground="{DynamicResource TextFillColorPrimaryBrush}" Background="{DynamicResource ControlStrokeColorDefaultBrush}">
<ScrollViewer VerticalScrollBarVisibility="Auto" VerticalAlignment="Stretch" Padding="0" VerticalContentAlignment="Top" Margin="0 0 2.5 0"> <ScrollViewer VerticalScrollBarVisibility="Auto" VerticalAlignment="Stretch" Padding="0" VerticalContentAlignment="Top" Margin="0 0 2.5 0">
<ItemsControl ItemsSource="{Binding AllPlugins}"> <ItemsControl ItemsSource="{Binding AllPlugins}">
<ItemsControl.ItemTemplate> <ItemsControl.ItemTemplate>
@@ -106,24 +106,9 @@
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Image Source="{Binding ModIoIcon}" Cursor="Hand" Height="30" MouseUp="Image_MouseUp" HorizontalAlignment="Left" /> <Image Source="{Binding ModIoIcon}" Cursor="Hand" Height="30" MouseUp="Image_MouseUp" HorizontalAlignment="Left" />
<Button Grid.Column="2" HorizontalAlignment="Stretch" Click="CreatePluginButton_Click"> <ui:Button Content="{DynamicResource createNewPlugin}" Icon="{ui:SymbolIcon Add24}" Grid.Column="2" HorizontalAlignment="Stretch" Click="CreatePluginButton_Click"/>
<StackPanel Orientation="Horizontal"> <ui:Button Content="{DynamicResource reloadPlugins}" Icon="{ui:SymbolIcon ArrowClockwise24}" Grid.Column="4" HorizontalAlignment="Stretch" Click="ReloadPluginsButton_Click"/>
<ui:SymbolIcon Symbol="Add24" Margin="0 0 10 0" /> <ui:Button Content="{Binding LoginButtonText}" Icon="{ui:SymbolIcon PersonKey20}" Grid.Column="6" HorizontalAlignment="Stretch" Click="LogInButton_Click"/>
<TextBlock Text="{DynamicResource createNewPlugin}" />
</StackPanel>
</Button>
<Button Grid.Column="4" HorizontalAlignment="Stretch" Click="ReloadPluginsButton_Click">
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="ArrowClockwise24" Margin="0 0 10 0" />
<TextBlock Text="{DynamicResource reloadPlugins}" />
</StackPanel>
</Button>
<Button Grid.Column="6" HorizontalAlignment="Stretch" Click="LogInButton_Click">
<StackPanel Orientation="Horizontal">
<ui:SymbolIcon Symbol="PersonKey20" Margin="0 0 10 0" />
<TextBlock Text="{Binding LoginButtonText}" />
</StackPanel>
</Button>
</Grid> </Grid>
</ui:Card> </ui:Card>
</Grid> </Grid>
@@ -440,7 +440,7 @@ public partial class PluginManager : Page
string pluginPath = Path.Combine(pluginsPath, pluginGuid); string pluginPath = Path.Combine(pluginsPath, pluginGuid);
uint pluginId = (uint)Random.Shared.Next(1000, 9999); uint pluginId = (uint)Random.Shared.Next(1000, 9999);
InputDialog inputDialog = new((string)FindResource("enterPluginName"), "Plugin Manager") CreatePluginDialog inputDialog = new()
{ {
Owner = Window.GetWindow(this), Owner = Window.GetWindow(this),
}; };
+1 -1
View File
@@ -16,7 +16,7 @@
Closing="Window_Closing" Closing="Window_Closing"
ContentRendered="Window_ContentRendered" ContentRendered="Window_ContentRendered"
x:Name="window"> x:Name="window">
<busyIndicator:BusyMask x:Name="busyMask" IsBusyAtStartup="True" Background="Transparent" BusyContent="" BusyContentMargin="-5" IndicatorType="Cogs"> <busyIndicator:BusyMask x:Name="busyMask" IsBusy="True" Background="Transparent" BusyContent="" BusyContentMargin="-5" IndicatorType="Cogs">
<Grid> <Grid>
<Rectangle x:Name="panel" Fill="#4CBAFFEF" Stroke="White" Margin="0,0,0,0" Visibility="Collapsed" /> <Rectangle x:Name="panel" Fill="#4CBAFFEF" Stroke="White" Margin="0,0,0,0" Visibility="Collapsed" />
+57 -24
View File
@@ -42,6 +42,9 @@ public partial class PluginWindow : Window, IPluginWindow
private System.Timers.Timer? reloadDebounceTimer; private System.Timers.Timer? reloadDebounceTimer;
private bool isReloading = false; private bool isReloading = false;
private WriteableBitmap? writeableBitmap;
private BitmapScalingMode lastBitmapScalingMode = BitmapScalingMode.Unspecified;
public bool IsRunning { get; private set; } = true; public bool IsRunning { get; private set; } = true;
public PluginMetadata PluginMetadata { get; private set; } public PluginMetadata PluginMetadata { get; private set; }
public string PluginFolderPath { get; private set; } public string PluginFolderPath { get; private set; }
@@ -241,21 +244,21 @@ public partial class PluginWindow : Window, IPluginWindow
assemblyLoadContext = CreateAssemblyLoadContext(); assemblyLoadContext = CreateAssemblyLoadContext();
// Show busy indicator // Show busy indicator
await Dispatcher.InvokeAsync(() => busyMask.IsBusy = true); _ = await Dispatcher.InvokeAsync(() => busyMask.IsBusy = true);
// Reload the plugin // Reload the plugin
await ExecuteSource(); await ExecuteSource();
// Hide busy indicator // Hide busy indicator
await Dispatcher.InvokeAsync(() => busyMask.IsBusy = false); _ = await Dispatcher.InvokeAsync(() => busyMask.IsBusy = false);
App.Logger.LogInfo($"\"{PluginMetadata.Name}\" - Plugin reloaded successfully", source: "Plugin"); App.Logger.LogInfo($"\"{PluginMetadata.Name}\" - Plugin reloaded successfully", source: "Plugin");
} }
catch (Exception ex) catch (Exception ex)
{ {
App.Logger.LogError($"\"{PluginMetadata.Name}\" - Failed to reload plugin: {ex}", source: "Plugin"); App.Logger.LogError($"\"{PluginMetadata.Name}\" - Failed to reload plugin: {ex}", source: "Plugin");
await Dispatcher.InvokeAsync(async () => _ = await Dispatcher.InvokeAsync(async () =>
{ {
Wpf.Ui.Controls.MessageBox messageBox = new Wpf.Ui.Controls.MessageBox Wpf.Ui.Controls.MessageBox messageBox = new Wpf.Ui.Controls.MessageBox
{ {
@@ -337,22 +340,52 @@ public partial class PluginWindow : Window, IPluginWindow
WindowPos.GetWindowLong(helper.Handle, WindowPos.GWL_EXSTYLE) | WindowPos.WS_EX_NOACTIVATE); WindowPos.GetWindowLong(helper.Handle, WindowPos.GWL_EXSTYLE) | WindowPos.WS_EX_NOACTIVATE);
} }
private static BitmapSource BitmapToImageSource(Bitmap bitmap) private void UpdateImageFromBitmap(Bitmap bitmap, BitmapScalingMode scalingMode)
{ {
BitmapData bitmapData = bitmap.LockBits( BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
new Rectangle(0, 0, bitmap.Width, bitmap.Height),
ImageLockMode.ReadOnly, bitmap.PixelFormat);
BitmapSource bitmapSource = BitmapSource.Create( try
bitmapData.Width, bitmapData.Height, {
bitmap.HorizontalResolution, bitmap.VerticalResolution, Dispatcher.Invoke(() =>
PixelFormats.Bgra32, null, {
bitmapData.Scan0, bitmapData.Stride * bitmapData.Height, bitmapData.Stride); if (lastBitmapScalingMode != scalingMode)
{
RenderOptions.SetBitmapScalingMode(image, scalingMode);
lastBitmapScalingMode = scalingMode;
}
bitmap.UnlockBits(bitmapData); if (writeableBitmap == null || writeableBitmap.PixelWidth != bitmapData.Width || writeableBitmap.PixelHeight != bitmapData.Height)
{
writeableBitmap = new WriteableBitmap(
bitmapData.Width, bitmapData.Height,
bitmap.HorizontalResolution, bitmap.VerticalResolution,
PixelFormats.Bgra32, null);
image.Source = writeableBitmap;
}
bitmapSource.Freeze(); writeableBitmap.Lock();
return bitmapSource; try
{
unsafe
{
Buffer.MemoryCopy(
bitmapData.Scan0.ToPointer(),
writeableBitmap.BackBuffer.ToPointer(),
writeableBitmap.BackBufferStride * writeableBitmap.PixelHeight,
bitmapData.Stride * bitmapData.Height);
}
writeableBitmap.AddDirtyRect(new Int32Rect(0, 0, bitmapData.Width, bitmapData.Height));
}
finally
{
writeableBitmap.Unlock();
}
});
}
finally
{
bitmap.UnlockBits(bitmapData);
}
} }
private void Window_ContentRendered(object? sender, EventArgs e) private void Window_ContentRendered(object? sender, EventArgs e)
@@ -525,11 +558,13 @@ public partial class PluginWindow : Window, IPluginWindow
{ {
SetHorizontalAlignment(); SetHorizontalAlignment();
SetVerticalAlignment(); SetVerticalAlignment();
SetRotation();
SetThemeOverride(); SetThemeOverride();
SetThemeOverrideItems(); SetThemeOverrideItems();
pluginClassInstance.horizontalAlignment.OnValueChanged += SetHorizontalAlignment; pluginClassInstance.horizontalAlignment.OnValueChanged += SetHorizontalAlignment;
pluginClassInstance.verticalAlignment.OnValueChanged += SetVerticalAlignment; pluginClassInstance.verticalAlignment.OnValueChanged += SetVerticalAlignment;
pluginClassInstance.rotation.OnValueChanged += SetRotation;
pluginClassInstance.themeOverride.OnValueChanged += SetThemeOverride; pluginClassInstance.themeOverride.OnValueChanged += SetThemeOverride;
DesktopMagicSettings desktopMagicSettings = MainWindowDataContext.GetSettings(); DesktopMagicSettings desktopMagicSettings = MainWindowDataContext.GetSettings();
@@ -564,6 +599,11 @@ public partial class PluginWindow : Window, IPluginWindow
border.HorizontalAlignment = horizontalAlignment; border.HorizontalAlignment = horizontalAlignment;
} }
void SetRotation()
{
image.LayoutTransform = new RotateTransform(pluginClassInstance.rotation.Value);
}
void SetThemeOverride() void SetThemeOverride()
{ {
if (pluginClassInstance.themeOverride.Value == "<None>") if (pluginClassInstance.themeOverride.Value == "<None>")
@@ -819,14 +859,7 @@ public partial class PluginWindow : Window, IPluginWindow
_ => BitmapScalingMode.Unspecified _ => BitmapScalingMode.Unspecified
}; };
// Update Image UpdateImageFromBitmap(result, renderOptions);
BitmapSource frozenSource = BitmapToImageSource(result);
_ = Dispatcher.BeginInvoke(() =>
{
RenderOptions.SetBitmapScalingMode(image, renderOptions);
image.Source = frozenSource;
});
} }
} }
} }
@@ -18,7 +18,7 @@
ContentRendered="Window_ContentRendered" ContentRendered="Window_ContentRendered"
x:Name="window"> x:Name="window">
<busyIndicator:BusyMask x:Name="busyMask" IsBusyAtStartup="True" Background="Transparent" BusyContent="" BusyContentMargin="-5" IndicatorType="Cogs"> <busyIndicator:BusyMask x:Name="busyMask" IsBusy="True" Background="Transparent" BusyContent="" BusyContentMargin="-5" IndicatorType="Cogs">
<Grid> <Grid>
<Rectangle x:Name="panel" Fill="#4CBAFFEF" Stroke="White" Margin="0,0,0,0" Visibility="Collapsed" /> <Rectangle x:Name="panel" Fill="#4CBAFFEF" Stroke="White" Margin="0,0,0,0" Visibility="Collapsed" />
@@ -3,9 +3,10 @@
xmlns:col="clr-namespace:System.Collections;assembly=mscorlib" xmlns:col="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:system="clr-namespace:System;assembly=mscorlib"> xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="developedBy">Entwickelt von Stone_Red</system:String> <system:String x:Key="developedBy">Entwickelt von Stone__Red</system:String>
<system:String x:Key="reportBug">Bug Melden</system:String> <system:String x:Key="reportBug">Bug Melden</system:String>
<system:String x:Key="requestFeature">Feature Anfragen</system:String> <system:String x:Key="requestFeature">Feature Anfragen</system:String>
<system:String x:Key="email">E-Mail</system:String>
<system:String x:Key="lineMode">Linie</system:String> <system:String x:Key="lineMode">Linie</system:String>
<system:String x:Key="mirrorMode">Spiegeln</system:String> <system:String x:Key="mirrorMode">Spiegeln</system:String>
<system:String x:Key="folder">Ordner</system:String> <system:String x:Key="folder">Ordner</system:String>
@@ -3,9 +3,10 @@
xmlns:col="clr-namespace:System.Collections;assembly=mscorlib" xmlns:col="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:system="clr-namespace:System;assembly=mscorlib"> xmlns:system="clr-namespace:System;assembly=mscorlib">
<system:String x:Key="developedBy">Developed by Stone_Red</system:String> <system:String x:Key="developedBy">Developed by Stone__Red</system:String>
<system:String x:Key="reportBug">Report Bug</system:String> <system:String x:Key="reportBug">Report Bug</system:String>
<system:String x:Key="requestFeature">Request Feature</system:String> <system:String x:Key="requestFeature">Request Feature</system:String>
<system:String x:Key="email">Email</system:String>
<system:String x:Key="lineMode">Line</system:String> <system:String x:Key="lineMode">Line</system:String>
<system:String x:Key="mirrorMode">Mirror</system:String> <system:String x:Key="mirrorMode">Mirror</system:String>
<system:String x:Key="folder">Folder</system:String> <system:String x:Key="folder">Folder</system:String>
+3 -3
View File
@@ -14,10 +14,10 @@ namespace DesktopMagic.PluginTest;
public class GifPlugin : Plugin public class GifPlugin : Plugin
{ {
[Setting("gif-path", "GIF path")] [Setting("gif-path", "GIF path")]
private readonly TextBox input = new TextBox(""); private readonly FileSelector input = new FileSelector();
[Setting("info")] [Setting("info")]
private readonly Label info = new Label(""); private readonly Label info = new Label("Select a GIF file to load.");
private readonly List<Bitmap> bitmaps = []; private readonly List<Bitmap> bitmaps = [];
@@ -92,7 +92,7 @@ public class GifPlugin : Plugin
info.Value = $"Loading frame {i + 1} of {gif.GetFrameCount(FrameDimension.Time)}"; info.Value = $"Loading frame {i + 1} of {gif.GetFrameCount(FrameDimension.Time)}";
} }
info.Value = string.Empty; info.Value = $"Loaded {bitmaps.Count} frames.";
} }
else else
{ {
+4 -1
View File
@@ -23,7 +23,10 @@ public abstract class Plugin
[Setting("desktopmagic-vertical-alignment", "Vertical Alignment", -998)] [Setting("desktopmagic-vertical-alignment", "Vertical Alignment", -998)]
internal ComboBox verticalAlignment = new ComboBox("Center", "Top", "Bottom"); internal ComboBox verticalAlignment = new ComboBox("Center", "Top", "Bottom");
[Setting("theme-override", "Theme Override", -997)] [Setting("rotation", "Rotation", -997)]
internal IntegerUpDown rotation = new IntegerUpDown(-360, 360, 0);
[Setting("theme-override", "Theme Override", -996)]
internal ComboBox themeOverride = new ComboBox("<None>"); internal ComboBox themeOverride = new ComboBox("<None>");
private IPluginData application = null!; private IPluginData application = null!;
+1 -1
View File
@@ -9,7 +9,7 @@
<Identity <Identity
Name="StoneRed.DesktopMagic" Name="StoneRed.DesktopMagic"
Publisher="CN=6D1FD759-1951-428A-9B03-964461C7DBF5" Publisher="CN=6D1FD759-1951-428A-9B03-964461C7DBF5"
Version="1.3.0.0" /> Version="1.3.1.0" />
<Properties> <Properties>
<DisplayName>Desktop Magic</DisplayName> <DisplayName>Desktop Magic</DisplayName>