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,9 +67,12 @@ namespace Artemis.Core.Models.Profile
if (RenderPath == null)
return;
canvas.Save();
// TODO Just lock the whole thing, this is asking for deadlock
lock (_renderBitmap)
{
lock (LayerElements)
{
canvas.Save();
foreach (var layerElement in LayerElements)
layerElement.RenderPreProcess(surface, canvas);
@ -94,10 +97,10 @@ namespace Artemis.Core.Models.Profile
canvas.ClipPath(RenderPath);
canvas.DrawRect(RenderRectangle, new SKPaint {Shader = baseShader, FilterQuality = SKFilterQuality.Low});
baseShader.Dispose();
canvas.Restore();
}
}
}
internal override void ApplyToEntity()
{
@ -161,14 +164,20 @@ namespace Artemis.Core.Models.Profile
}
internal void AddLayerElement(LayerElement layerElement)
{
lock (LayerElements)
{
_layerElements.Add(layerElement);
}
}
internal void RemoveLayerElement(LayerElement layerElement)
{
lock (LayerElements)
{
_layerElements.Remove(layerElement);
}
}
internal void PopulateLeds(ArtemisSurface surface)
{

View File

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

View File

@ -139,6 +139,7 @@
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Configuration" />
<Reference Include="System.Drawing" />
<Reference Include="System.Management" />
<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>
</Reference>
@ -170,6 +171,9 @@
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Bootstrapper.cs" />
<Compile Include="Controls\ColorPicker\ColorPickerView.xaml.cs">
<DependentUpon>ColorPickerView.xaml</DependentUpon>
</Compile>
<Compile Include="Converters\ColorToDrawingColorConverter.cs" />
<Compile Include="Converters\ColorToSolidColorBrushConverter.cs" />
<Compile Include="Converters\EnumToCollectionConverter.cs" />
@ -177,11 +181,13 @@
<Compile Include="Converters\NullToImageConverter.cs" />
<Compile Include="Converters\NullToVisibilityConverter.cs" />
<Compile Include="Events\MainWindowFocusChangedEvent.cs" />
<Compile Include="Events\WindowsThemeEventArgs.cs" />
<Compile Include="Screens\GradientEditor\GradientEditorViewModel.cs" />
<Compile Include="Screens\Module\ProfileEditor\LayerElements\Dialogs\AddLayerElementViewModel.cs" />
<Compile Include="Services\Interfaces\IProfileEditorService.cs" />
<Compile Include="Services\ProfileEditorService.cs" />
<Compile Include="Utilities\BindableSelectedItemBehavior.cs" />
<Compile Include="Utilities\ThemeWatcher.cs" />
<Compile Include="Utilities\TriggerTracing.cs" />
<Compile Include="Exceptions\ArtemisCoreException.cs" />
<Compile Include="Extensions\RgbColorExtensions.cs" />
@ -247,6 +253,10 @@
<SubType>Code</SubType>
</Compile>
<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">
<SubType>Designer</SubType>
<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:converters="clr-namespace:Artemis.UI.Converters"
xmlns:visualization="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance {x:Type visualization:ProfileDeviceViewModel}}"
d:DesignHeight="450" d:DesignWidth="800">
@ -20,7 +21,9 @@
</Grid.LayoutTransform>
<!-- 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}"
Stroke="{DynamicResource ControlBorderBrush}"

View File

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

View File

@ -12,7 +12,11 @@
Icon="/Artemis.UI;component/Resources/logo-512.png"
Title="Artemis"
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"
UseLayoutRounding="True"
Deactivated="{s:Action WindowDeactivated}"

View File

@ -13,6 +13,8 @@ using Artemis.UI.Screens.News;
using Artemis.UI.Screens.Settings;
using Artemis.UI.Screens.SurfaceEditor;
using Artemis.UI.Screens.Workshop;
using Artemis.UI.Utilities;
using MaterialDesignThemes.Wpf;
using Stylet;
namespace Artemis.UI.Screens
@ -47,6 +49,19 @@ namespace Artemis.UI.Screens
_pluginService.PluginDisabled += PluginServiceOnPluginDisabled;
PropertyChanged += OnSelectedModuleChanged;
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; }

View File

@ -8,6 +8,6 @@
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBlock>Work work!</TextBlock>
<TextBlock Style="{DynamicResource MaterialDesignBody1TextBlock}">Work work!</TextBlock>
</Grid>
</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);
}
}
}