1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Added dark mode 🦇

This commit is contained in:
Robert 2019-12-06 17:34:06 +01:00
parent 8430f28fa7
commit 8f3d2f1ff5
12 changed files with 207 additions and 33 deletions

View File

@ -67,35 +67,38 @@ namespace Artemis.Core.Models.Profile
if (RenderPath == null) if (RenderPath == null)
return; return;
canvas.Save(); // TODO Just lock the whole thing, this is asking for deadlock
lock (_renderBitmap) lock (_renderBitmap)
{ {
foreach (var layerElement in LayerElements) lock (LayerElements)
layerElement.RenderPreProcess(surface, canvas);
_renderCanvas.Clear();
foreach (var layerElement in LayerElements)
layerElement.Render(surface, _renderCanvas);
var baseShader = SKShader.CreateBitmap(_renderBitmap, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, SKMatrix.MakeTranslation(RenderRectangle.Left, RenderRectangle.Top));
foreach (var layerElement in LayerElements)
{ {
var newBaseShader = layerElement.RenderPostProcess(surface, _renderBitmap, baseShader); canvas.Save();
if (newBaseShader == null) foreach (var layerElement in LayerElements)
continue; layerElement.RenderPreProcess(surface, canvas);
// Dispose the old base shader if the layer element provided a new one _renderCanvas.Clear();
if (!ReferenceEquals(baseShader, newBaseShader)) foreach (var layerElement in LayerElements)
baseShader.Dispose(); layerElement.Render(surface, _renderCanvas);
baseShader = newBaseShader; var baseShader = SKShader.CreateBitmap(_renderBitmap, SKShaderTileMode.Repeat, SKShaderTileMode.Repeat, SKMatrix.MakeTranslation(RenderRectangle.Left, RenderRectangle.Top));
foreach (var layerElement in LayerElements)
{
var newBaseShader = layerElement.RenderPostProcess(surface, _renderBitmap, baseShader);
if (newBaseShader == null)
continue;
// Dispose the old base shader if the layer element provided a new one
if (!ReferenceEquals(baseShader, newBaseShader))
baseShader.Dispose();
baseShader = newBaseShader;
}
canvas.ClipPath(RenderPath);
canvas.DrawRect(RenderRectangle, new SKPaint {Shader = baseShader, FilterQuality = SKFilterQuality.Low});
baseShader.Dispose();
canvas.Restore();
} }
canvas.ClipPath(RenderPath);
canvas.DrawRect(RenderRectangle, new SKPaint {Shader = baseShader, FilterQuality = SKFilterQuality.Low});
baseShader.Dispose();
canvas.Restore();
} }
} }
@ -162,12 +165,18 @@ namespace Artemis.Core.Models.Profile
internal void AddLayerElement(LayerElement layerElement) internal void AddLayerElement(LayerElement layerElement)
{ {
_layerElements.Add(layerElement); lock (LayerElements)
{
_layerElements.Add(layerElement);
}
} }
internal void RemoveLayerElement(LayerElement layerElement) internal void RemoveLayerElement(LayerElement layerElement)
{ {
_layerElements.Remove(layerElement); lock (LayerElements)
{
_layerElements.Remove(layerElement);
}
} }
internal void PopulateLeds(ArtemisSurface surface) internal void PopulateLeds(ArtemisSurface surface)

View File

@ -77,7 +77,8 @@ namespace Artemis.Core.Services.Storage
public void ActivateProfile(ProfileModule module, Profile profile) public void ActivateProfile(ProfileModule module, Profile profile)
{ {
module.ChangeActiveProfile(profile, _surfaceService.ActiveSurface); module.ChangeActiveProfile(profile, _surfaceService.ActiveSurface);
InstantiateProfileLayerElements(profile); if (profile != null)
InstantiateProfileLayerElements(profile);
} }
public void DeleteProfile(Profile profile) public void DeleteProfile(Profile profile)

View File

@ -139,6 +139,7 @@
<Reference Include="System.ComponentModel.DataAnnotations" /> <Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" /> <Reference Include="System.Configuration" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL"> <Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath> <HintPath>..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference> </Reference>
@ -170,6 +171,9 @@
<SubType>Designer</SubType> <SubType>Designer</SubType>
</ApplicationDefinition> </ApplicationDefinition>
<Compile Include="Bootstrapper.cs" /> <Compile Include="Bootstrapper.cs" />
<Compile Include="Controls\ColorPicker\ColorPickerView.xaml.cs">
<DependentUpon>ColorPickerView.xaml</DependentUpon>
</Compile>
<Compile Include="Converters\ColorToDrawingColorConverter.cs" /> <Compile Include="Converters\ColorToDrawingColorConverter.cs" />
<Compile Include="Converters\ColorToSolidColorBrushConverter.cs" /> <Compile Include="Converters\ColorToSolidColorBrushConverter.cs" />
<Compile Include="Converters\EnumToCollectionConverter.cs" /> <Compile Include="Converters\EnumToCollectionConverter.cs" />
@ -177,11 +181,13 @@
<Compile Include="Converters\NullToImageConverter.cs" /> <Compile Include="Converters\NullToImageConverter.cs" />
<Compile Include="Converters\NullToVisibilityConverter.cs" /> <Compile Include="Converters\NullToVisibilityConverter.cs" />
<Compile Include="Events\MainWindowFocusChangedEvent.cs" /> <Compile Include="Events\MainWindowFocusChangedEvent.cs" />
<Compile Include="Events\WindowsThemeEventArgs.cs" />
<Compile Include="Screens\GradientEditor\GradientEditorViewModel.cs" /> <Compile Include="Screens\GradientEditor\GradientEditorViewModel.cs" />
<Compile Include="Screens\Module\ProfileEditor\LayerElements\Dialogs\AddLayerElementViewModel.cs" /> <Compile Include="Screens\Module\ProfileEditor\LayerElements\Dialogs\AddLayerElementViewModel.cs" />
<Compile Include="Services\Interfaces\IProfileEditorService.cs" /> <Compile Include="Services\Interfaces\IProfileEditorService.cs" />
<Compile Include="Services\ProfileEditorService.cs" /> <Compile Include="Services\ProfileEditorService.cs" />
<Compile Include="Utilities\BindableSelectedItemBehavior.cs" /> <Compile Include="Utilities\BindableSelectedItemBehavior.cs" />
<Compile Include="Utilities\ThemeWatcher.cs" />
<Compile Include="Utilities\TriggerTracing.cs" /> <Compile Include="Utilities\TriggerTracing.cs" />
<Compile Include="Exceptions\ArtemisCoreException.cs" /> <Compile Include="Exceptions\ArtemisCoreException.cs" />
<Compile Include="Extensions\RgbColorExtensions.cs" /> <Compile Include="Extensions\RgbColorExtensions.cs" />
@ -247,6 +253,10 @@
<SubType>Code</SubType> <SubType>Code</SubType>
</Compile> </Compile>
<Compile Include="Screens\Settings\SettingsViewModel.cs" /> <Compile Include="Screens\Settings\SettingsViewModel.cs" />
<Page Include="Controls\ColorPicker\ColorPickerView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="ResourceDictionaries\Scrollbar.xaml"> <Page Include="ResourceDictionaries\Scrollbar.xaml">
<SubType>Designer</SubType> <SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator> <Generator>MSBuild:Compile</Generator>

View File

@ -0,0 +1,13 @@
<UserControl x:Class="Artemis.UI.Controls.ColorPicker.ColorPickerView"
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:local="clr-namespace:Artemis.UI.Controls.ColorPicker"
xmlns:wpf="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
</Grid>
</UserControl>

View File

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Artemis.UI.Controls.ColorPicker
{
/// <summary>
/// Interaction logic for ColorPickerView.xaml
/// </summary>
public partial class ColorPickerView : UserControl
{
public ColorPickerView()
{
InitializeComponent();
}
}
}

View File

@ -0,0 +1,15 @@
using System;
using Artemis.UI.Utilities;
namespace Artemis.UI.Events
{
public class WindowsThemeEventArgs : EventArgs
{
public WindowsThemeEventArgs(ThemeWatcher.WindowsTheme theme)
{
Theme = theme;
}
public ThemeWatcher.WindowsTheme Theme { get; set; }
}
}

View File

@ -6,6 +6,7 @@
xmlns:s="https://github.com/canton7/Stylet" xmlns:s="https://github.com/canton7/Stylet"
xmlns:converters="clr-namespace:Artemis.UI.Converters" xmlns:converters="clr-namespace:Artemis.UI.Converters"
xmlns:visualization="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization" xmlns:visualization="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance {x:Type visualization:ProfileDeviceViewModel}}" d:DataContext="{d:DesignInstance {x:Type visualization:ProfileDeviceViewModel}}"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
@ -20,7 +21,9 @@
</Grid.LayoutTransform> </Grid.LayoutTransform>
<!-- Device image with fallback --> <!-- Device image with fallback -->
<Image Source="{Binding Device.RgbDevice.DeviceInfo.Image, Converter={StaticResource NullToImageConverter}}" VerticalAlignment="Top" HorizontalAlignment="Left" /> <Border Effect="{StaticResource MaterialDesignShadowDepth3}" VerticalAlignment="Top" HorizontalAlignment="Left" >
<Image Source="{Binding Device.RgbDevice.DeviceInfo.Image, Converter={StaticResource NullToImageConverter}}"/>
</Border>
<Rectangle Fill="{DynamicResource ControlBackgroundBrush}" <Rectangle Fill="{DynamicResource ControlBackgroundBrush}"
Stroke="{DynamicResource ControlBorderBrush}" Stroke="{DynamicResource ControlBorderBrush}"

View File

@ -51,7 +51,7 @@
<Grid.Background> <Grid.Background>
<VisualBrush TileMode="Tile" Stretch="Uniform" Viewport="{Binding PanZoomViewModel.BackgroundViewport}" ViewportUnits="Absolute"> <VisualBrush TileMode="Tile" Stretch="Uniform" Viewport="{Binding PanZoomViewModel.BackgroundViewport}" ViewportUnits="Absolute">
<VisualBrush.Visual> <VisualBrush.Visual>
<Grid Width="20" Height="20"> <Grid Width="25" Height="25">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition /> <RowDefinition />
<RowDefinition /> <RowDefinition />
@ -60,10 +60,10 @@
<ColumnDefinition /> <ColumnDefinition />
<ColumnDefinition /> <ColumnDefinition />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<Rectangle Grid.Row="0" Grid.Column="0" Fill="LightGray" /> <Rectangle Grid.Row="0" Grid.Column="0" Fill="{DynamicResource MaterialDesignPaper}" />
<Rectangle Grid.Row="0" Grid.Column="1" /> <Rectangle Grid.Row="0" Grid.Column="1" />
<Rectangle Grid.Row="1" Grid.Column="0" /> <Rectangle Grid.Row="1" Grid.Column="0" />
<Rectangle Grid.Row="1" Grid.Column="1" Fill="LightGray" /> <Rectangle Grid.Row="1" Grid.Column="1" Fill="{DynamicResource MaterialDesignPaper}" />
</Grid> </Grid>
</VisualBrush.Visual> </VisualBrush.Visual>
</VisualBrush> </VisualBrush>

View File

@ -12,7 +12,11 @@
Icon="/Artemis.UI;component/Resources/logo-512.png" Icon="/Artemis.UI;component/Resources/logo-512.png"
Title="Artemis" Title="Artemis"
GlowBrush="{DynamicResource AccentColorBrush}" GlowBrush="{DynamicResource AccentColorBrush}"
FontFamily="{StaticResource DefaultFont}" TextElement.Foreground="{DynamicResource MaterialDesignBody}"
Background="{DynamicResource MaterialDesignPaper}"
TextElement.FontWeight="Medium"
TextElement.FontSize="14"
FontFamily="pack://application:,,,/MaterialDesignThemes.Wpf;component/Resources/Roboto/#Roboto"
SaveWindowPosition="True" SaveWindowPosition="True"
UseLayoutRounding="True" UseLayoutRounding="True"
Deactivated="{s:Action WindowDeactivated}" Deactivated="{s:Action WindowDeactivated}"

View File

@ -13,6 +13,8 @@ using Artemis.UI.Screens.News;
using Artemis.UI.Screens.Settings; using Artemis.UI.Screens.Settings;
using Artemis.UI.Screens.SurfaceEditor; using Artemis.UI.Screens.SurfaceEditor;
using Artemis.UI.Screens.Workshop; using Artemis.UI.Screens.Workshop;
using Artemis.UI.Utilities;
using MaterialDesignThemes.Wpf;
using Stylet; using Stylet;
namespace Artemis.UI.Screens namespace Artemis.UI.Screens
@ -47,6 +49,19 @@ namespace Artemis.UI.Screens
_pluginService.PluginDisabled += PluginServiceOnPluginDisabled; _pluginService.PluginDisabled += PluginServiceOnPluginDisabled;
PropertyChanged += OnSelectedModuleChanged; PropertyChanged += OnSelectedModuleChanged;
PropertyChanged += OnSelectedPageChanged; PropertyChanged += OnSelectedPageChanged;
var themeWatcher = new ThemeWatcher();
themeWatcher.ThemeChanged += (sender, args) => ApplyWindowsTheme(args.Theme);
ApplyWindowsTheme(themeWatcher.GetWindowsTheme());
}
private void ApplyWindowsTheme(ThemeWatcher.WindowsTheme windowsTheme)
{
var paletteHelper = new PaletteHelper();
var theme = paletteHelper.GetTheme();
theme.SetBaseTheme(windowsTheme == ThemeWatcher.WindowsTheme.Dark ? Theme.Dark : Theme.Light);
paletteHelper.SetTheme(theme);
} }
public IObservableCollection<Core.Plugins.Abstract.Module> Modules { get; set; } public IObservableCollection<Core.Plugins.Abstract.Module> Modules { get; set; }

View File

@ -8,6 +8,6 @@
mc:Ignorable="d" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"> d:DesignHeight="450" d:DesignWidth="800">
<Grid> <Grid>
<TextBlock>Work work!</TextBlock> <TextBlock Style="{DynamicResource MaterialDesignBody1TextBlock}">Work work!</TextBlock>
</Grid> </Grid>
</UserControl> </UserControl>

View File

@ -0,0 +1,76 @@
using System;
using System.Globalization;
using System.Management;
using System.Security.Principal;
using Artemis.UI.Events;
using Microsoft.Win32;
namespace Artemis.UI.Utilities
{
public class ThemeWatcher
{
public ThemeWatcher()
{
WatchTheme();
}
public enum WindowsTheme
{
Light,
Dark
}
private const string RegistryKeyPath = @"Software\Microsoft\Windows\CurrentVersion\Themes\Personalize";
private const string RegistryValueName = "AppsUseLightTheme";
public void WatchTheme()
{
var currentUser = WindowsIdentity.GetCurrent();
var query = string.Format(
CultureInfo.InvariantCulture,
@"SELECT * FROM RegistryValueChangeEvent WHERE Hive = 'HKEY_USERS' AND KeyPath = '{0}\\{1}' AND ValueName = '{2}'",
currentUser.User.Value,
RegistryKeyPath.Replace(@"\", @"\\"),
RegistryValueName);
try
{
var watcher = new ManagementEventWatcher(query);
watcher.EventArrived += (sender, args) =>
{
var newWindowsTheme = GetWindowsTheme();
OnThemeChanged(new WindowsThemeEventArgs(newWindowsTheme));
};
// Start listening for events
watcher.Start();
}
catch (Exception)
{
// This can fail on Windows 7
}
}
public WindowsTheme GetWindowsTheme()
{
using (var key = Registry.CurrentUser.OpenSubKey(RegistryKeyPath))
{
var registryValueObject = key?.GetValue(RegistryValueName);
if (registryValueObject == null) return WindowsTheme.Light;
var registryValue = (int) registryValueObject;
return registryValue > 0 ? WindowsTheme.Light : WindowsTheme.Dark;
}
}
public event EventHandler<WindowsThemeEventArgs> ThemeChanged;
protected virtual void OnThemeChanged(WindowsThemeEventArgs e)
{
ThemeChanged?.Invoke(this, e);
}
}
}