mirror of
https://github.com/DarthAffe/RGBSyncPlus
synced 2025-12-13 09:28:31 +00:00
Initial implementation
This commit is contained in:
parent
278e22020e
commit
fd662dcf34
6
RGBSync+/App.config
Normal file
6
RGBSync+/App.config
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8" ?>
|
||||||
|
<configuration>
|
||||||
|
<startup>
|
||||||
|
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
|
||||||
|
</startup>
|
||||||
|
</configuration>
|
||||||
26
RGBSync+/App.xaml
Normal file
26
RGBSync+/App.xaml
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
<Application x:Class="RGBSyncPlus.App"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:tb="http://www.hardcodet.net/taskbar"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles"
|
||||||
|
xmlns:rgbSyncPlus="clr-namespace:RGBSyncPlus">
|
||||||
|
<Application.Resources>
|
||||||
|
<ResourceDictionary>
|
||||||
|
<ResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Resources/RGBSync+.xaml" />
|
||||||
|
</ResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<tb:TaskbarIcon x:Key="TaskbarIcon"
|
||||||
|
IconSource="Resources/argebee.ico"
|
||||||
|
ToolTip="Keyboard Audio-Visualizer"
|
||||||
|
MenuActivation="RightClick">
|
||||||
|
<tb:TaskbarIcon.ContextMenu>
|
||||||
|
<ContextMenu>
|
||||||
|
<MenuItem Header="Open Configuration" Command="{Binding Source={x:Static rgbSyncPlus:ApplicationManager.Instance}, Path=OpenConfigurationCommand}" />
|
||||||
|
<MenuItem Header="Exit" Command="{Binding Source={x:Static rgbSyncPlus:ApplicationManager.Instance}, Path=ExitCommand}" />
|
||||||
|
</ContextMenu>
|
||||||
|
</tb:TaskbarIcon.ContextMenu>
|
||||||
|
</tb:TaskbarIcon>
|
||||||
|
</ResourceDictionary>
|
||||||
|
</Application.Resources>
|
||||||
|
</Application>
|
||||||
78
RGBSync+/App.xaml.cs
Normal file
78
RGBSync+/App.xaml.cs
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using Hardcodet.Wpf.TaskbarNotification;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using RGBSyncPlus.Configuration;
|
||||||
|
using RGBSyncPlus.Configuration.Legacy;
|
||||||
|
using RGBSyncPlus.Helper;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus
|
||||||
|
{
|
||||||
|
public partial class App : Application
|
||||||
|
{
|
||||||
|
#region Constants
|
||||||
|
|
||||||
|
private const string PATH_SETTINGS = "Settings.json";
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private TaskbarIcon _taskbarIcon;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
protected override void OnStartup(StartupEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnStartup(e);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
ToolTipService.ShowDurationProperty.OverrideMetadata(typeof(DependencyObject), new FrameworkPropertyMetadata(int.MaxValue));
|
||||||
|
|
||||||
|
_taskbarIcon = (TaskbarIcon)FindResource("TaskbarIcon");
|
||||||
|
_taskbarIcon.DoubleClickCommand = ApplicationManager.Instance.OpenConfigurationCommand;
|
||||||
|
|
||||||
|
Settings settings = null;
|
||||||
|
try { settings = JsonConvert.DeserializeObject<Settings>(File.ReadAllText(PATH_SETTINGS), new ColorSerializer()); }
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
Console.WriteLine(ex.Message);
|
||||||
|
/* File doesn't exist or is corrupt - just create a new one. */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (settings == null)
|
||||||
|
{
|
||||||
|
settings = new Settings { Version = Settings.CURRENT_VERSION };
|
||||||
|
_taskbarIcon.ShowBalloonTip("RGBSync+ is starting in the tray!", "Click on the icon to open the configuration.", BalloonIcon.Info);
|
||||||
|
}
|
||||||
|
else if (settings.Version != Settings.CURRENT_VERSION)
|
||||||
|
ConfigurationUpdates.PerformOn(settings);
|
||||||
|
|
||||||
|
ApplicationManager.Instance.Settings = settings;
|
||||||
|
ApplicationManager.Instance.Initialize();
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
File.WriteAllText("error.log", $"[{DateTime.Now:G}] Exception!\r\n\r\nMessage:\r\n{ex.GetFullMessage()}\r\n\r\nStackTrace:\r\n{ex.StackTrace}\r\n\r\n");
|
||||||
|
MessageBox.Show("An error occured while starting RGBSync+.\r\nMore information can be found in the error.log file in the application directory.", "Can't start RGBSync+.");
|
||||||
|
|
||||||
|
try { ApplicationManager.Instance.ExitCommand.Execute(null); }
|
||||||
|
catch { Environment.Exit(0); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnExit(ExitEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnExit(e);
|
||||||
|
|
||||||
|
File.WriteAllText(PATH_SETTINGS, JsonConvert.SerializeObject(ApplicationManager.Instance.Settings, new ColorSerializer()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
150
RGBSync+/ApplicationManager.cs
Normal file
150
RGBSync+/ApplicationManager.cs
Normal file
@ -0,0 +1,150 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Windows;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
using RGB.NET.Groups;
|
||||||
|
using RGBSyncPlus.Brushes;
|
||||||
|
using RGBSyncPlus.Configuration;
|
||||||
|
using RGBSyncPlus.Helper;
|
||||||
|
using RGBSyncPlus.Model;
|
||||||
|
using RGBSyncPlus.UI;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus
|
||||||
|
{
|
||||||
|
public class ApplicationManager
|
||||||
|
{
|
||||||
|
#region Constants
|
||||||
|
|
||||||
|
private const string DEVICEPROVIDER_DIRECTORY = "DeviceProvider";
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
public static ApplicationManager Instance { get; } = new ApplicationManager();
|
||||||
|
|
||||||
|
private ConfigurationWindow _configurationWindow;
|
||||||
|
|
||||||
|
public Settings Settings { get; set; }
|
||||||
|
public TimerUpdateTrigger UpdateTrigger { get; private set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Commands
|
||||||
|
|
||||||
|
private ActionCommand _openConfiguration;
|
||||||
|
public ActionCommand OpenConfigurationCommand => _openConfiguration ?? (_openConfiguration = new ActionCommand(OpenConfiguration));
|
||||||
|
|
||||||
|
private ActionCommand _exitCommand;
|
||||||
|
public ActionCommand ExitCommand => _exitCommand ?? (_exitCommand = new ActionCommand(Exit));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
private ApplicationManager() { }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public void Initialize()
|
||||||
|
{
|
||||||
|
RGBSurface surface = RGBSurface.Instance;
|
||||||
|
LoadDeviceProviders();
|
||||||
|
surface.AlignDevices();
|
||||||
|
|
||||||
|
foreach (IRGBDevice device in surface.Devices)
|
||||||
|
device.UpdateMode = DeviceUpdateMode.Sync | DeviceUpdateMode.SyncBack;
|
||||||
|
|
||||||
|
UpdateTrigger = new TimerUpdateTrigger { UpdateFrequency = 1.0 / MathHelper.Clamp(Settings.UpdateRate, 1, 100) };
|
||||||
|
surface.RegisterUpdateTrigger(UpdateTrigger);
|
||||||
|
UpdateTrigger.Start();
|
||||||
|
|
||||||
|
foreach (SyncGroup syncGroup in Settings.SyncGroups)
|
||||||
|
RegisterSyncGroup(syncGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LoadDeviceProviders()
|
||||||
|
{
|
||||||
|
string deviceProvierDir = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) ?? string.Empty, DEVICEPROVIDER_DIRECTORY);
|
||||||
|
if (!Directory.Exists(deviceProvierDir)) return;
|
||||||
|
|
||||||
|
foreach (string file in Directory.GetFiles(deviceProvierDir, "*.dll"))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Assembly assembly = Assembly.LoadFrom(file);
|
||||||
|
foreach (Type loaderType in assembly.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && t.IsClass
|
||||||
|
&& typeof(IRGBDeviceProviderLoader).IsAssignableFrom(t)))
|
||||||
|
{
|
||||||
|
if (Activator.CreateInstance(loaderType) is IRGBDeviceProviderLoader deviceProviderLoader)
|
||||||
|
{
|
||||||
|
//TODO DarthAffe 03.06.2018: Support Initialization
|
||||||
|
if (deviceProviderLoader.RequiresInitialization) continue;
|
||||||
|
|
||||||
|
RGBSurface.Instance.LoadDevices(deviceProviderLoader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch { /* #sadprogrammer */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void AddSyncGroup(SyncGroup syncGroup)
|
||||||
|
{
|
||||||
|
Settings.SyncGroups.Add(syncGroup);
|
||||||
|
RegisterSyncGroup(syncGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterSyncGroup(SyncGroup syncGroup)
|
||||||
|
{
|
||||||
|
syncGroup.LedGroup = new ListLedGroup(syncGroup.Leds.GetLeds()) { Brush = new SyncBrush(syncGroup) };
|
||||||
|
syncGroup.LedsChangedEventHandler = (sender, args) => UpdateLedGroup(syncGroup.LedGroup, args);
|
||||||
|
syncGroup.Leds.CollectionChanged += syncGroup.LedsChangedEventHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void RemoveSyncGroup(SyncGroup syncGroup)
|
||||||
|
{
|
||||||
|
Settings.SyncGroups.Remove(syncGroup);
|
||||||
|
syncGroup.Leds.CollectionChanged -= syncGroup.LedsChangedEventHandler;
|
||||||
|
syncGroup.LedGroup.Detach();
|
||||||
|
syncGroup.LedGroup = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLedGroup(ListLedGroup group, NotifyCollectionChangedEventArgs args)
|
||||||
|
{
|
||||||
|
if (args.Action == NotifyCollectionChangedAction.Reset)
|
||||||
|
{
|
||||||
|
List<Led> leds = group.GetLeds().ToList();
|
||||||
|
group.RemoveLeds(leds);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (args.NewItems != null)
|
||||||
|
group.AddLeds(args.NewItems.Cast<SyncLed>().GetLeds());
|
||||||
|
|
||||||
|
if (args.OldItems != null)
|
||||||
|
group.RemoveLeds(args.OldItems.Cast<SyncLed>().GetLeds());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenConfiguration()
|
||||||
|
{
|
||||||
|
if (_configurationWindow == null) _configurationWindow = new ConfigurationWindow();
|
||||||
|
_configurationWindow.Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Exit()
|
||||||
|
{
|
||||||
|
try { RGBSurface.Instance?.Dispose(); } catch { /* well, we're shuting down anyway ... */ }
|
||||||
|
Application.Current.Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
111
RGBSync+/Attached/SliderValue.cs
Normal file
111
RGBSync+/Attached/SliderValue.cs
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
using System.Linq;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Attached
|
||||||
|
{
|
||||||
|
public static class SliderValue
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
public static readonly DependencyProperty UnitProperty = DependencyProperty.RegisterAttached(
|
||||||
|
"Unit", typeof(string), typeof(SliderValue), new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
public static void SetUnit(DependencyObject element, string value) => element.SetValue(UnitProperty, value);
|
||||||
|
public static string GetUnit(DependencyObject element) => (string)element.GetValue(UnitProperty);
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IsShownProperty = DependencyProperty.RegisterAttached(
|
||||||
|
"IsShown", typeof(bool), typeof(SliderValue), new PropertyMetadata(default(bool), IsShownChanged));
|
||||||
|
|
||||||
|
public static void SetIsShown(DependencyObject element, bool value) => element.SetValue(IsShownProperty, value);
|
||||||
|
public static bool GetIsShown(DependencyObject element) => (bool)element.GetValue(IsShownProperty);
|
||||||
|
|
||||||
|
public static readonly DependencyProperty BorderBrushProperty = DependencyProperty.RegisterAttached(
|
||||||
|
"BorderBrush", typeof(Brush), typeof(SliderValue), new PropertyMetadata(default(Brush)));
|
||||||
|
|
||||||
|
public static void SetBorderBrush(DependencyObject element, Brush value) => element.SetValue(BorderBrushProperty, value);
|
||||||
|
public static Brush GetBorderBrush(DependencyObject element) => (Brush)element.GetValue(BorderBrushProperty);
|
||||||
|
|
||||||
|
public static readonly DependencyProperty BackgroundProperty = DependencyProperty.RegisterAttached(
|
||||||
|
"Background", typeof(Brush), typeof(SliderValue), new PropertyMetadata(default(Brush)));
|
||||||
|
|
||||||
|
public static void SetBackground(DependencyObject element, Brush value) => element.SetValue(BackgroundProperty, value);
|
||||||
|
public static Brush GetBackground(DependencyObject element) => (Brush)element.GetValue(BackgroundProperty);
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ForegroundProperty = DependencyProperty.RegisterAttached(
|
||||||
|
"Foreground", typeof(Brush), typeof(SliderValue), new PropertyMetadata(default(Brush)));
|
||||||
|
|
||||||
|
public static void SetForeground(DependencyObject element, Brush value) => element.SetValue(ForegroundProperty, value);
|
||||||
|
public static Brush GetForeground(DependencyObject element) => (Brush)element.GetValue(ForegroundProperty);
|
||||||
|
|
||||||
|
public static readonly DependencyProperty FontProperty = DependencyProperty.RegisterAttached(
|
||||||
|
"Font", typeof(FontFamily), typeof(SliderValue), new PropertyMetadata(default(FontFamily)));
|
||||||
|
|
||||||
|
public static void SetFont(DependencyObject element, FontFamily value) => element.SetValue(FontProperty, value);
|
||||||
|
public static FontFamily GetFont(DependencyObject element) => (FontFamily)element.GetValue(FontProperty);
|
||||||
|
|
||||||
|
public static readonly DependencyProperty FontSizeProperty = DependencyProperty.RegisterAttached(
|
||||||
|
"FontSize", typeof(double), typeof(SliderValue), new PropertyMetadata(default(double)));
|
||||||
|
|
||||||
|
public static void SetFontSize(DependencyObject element, double value) => element.SetValue(FontSizeProperty, value);
|
||||||
|
public static double GetFontSize(DependencyObject element) => (double)element.GetValue(FontSizeProperty);
|
||||||
|
|
||||||
|
// ReSharper enable InconsistentNaming
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
private static void IsShownChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (!(dependencyObject is Slider slider)) return;
|
||||||
|
|
||||||
|
if (dependencyPropertyChangedEventArgs.NewValue as bool? == true)
|
||||||
|
{
|
||||||
|
slider.MouseEnter += SliderOnMouseEnter;
|
||||||
|
slider.MouseLeave += SliderOnMouseLeave;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
slider.MouseEnter -= SliderOnMouseEnter;
|
||||||
|
slider.MouseLeave -= SliderOnMouseLeave;
|
||||||
|
RemoveAdorner(slider);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SliderOnMouseEnter(object sender, MouseEventArgs mouseEventArgs)
|
||||||
|
{
|
||||||
|
if (!(sender is Slider slider)) return;
|
||||||
|
AdornerLayer.GetAdornerLayer(slider)?.Add(new SliderValueAdorner(slider, GetUnit(slider))
|
||||||
|
{
|
||||||
|
BorderBrush = GetBorderBrush(slider),
|
||||||
|
Background = GetBackground(slider),
|
||||||
|
Foreground = GetForeground(slider),
|
||||||
|
Font = GetFont(slider),
|
||||||
|
FontSize = GetFontSize(slider)
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SliderOnMouseLeave(object sender, MouseEventArgs mouseEventArgs)
|
||||||
|
{
|
||||||
|
if (!(sender is Slider slider)) return;
|
||||||
|
RemoveAdorner(slider);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void RemoveAdorner(Slider slider)
|
||||||
|
{
|
||||||
|
AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(slider);
|
||||||
|
Adorner adorner = adornerLayer?.GetAdorners(slider)?.FirstOrDefault(x => x is SliderValueAdorner);
|
||||||
|
if (adorner != null)
|
||||||
|
{
|
||||||
|
adornerLayer.Remove(adorner);
|
||||||
|
(adorner as SliderValueAdorner)?.Cleanup();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
99
RGBSync+/Attached/SliderValueAdorner.cs
Normal file
99
RGBSync+/Attached/SliderValueAdorner.cs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Controls.Primitives;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using Point = System.Windows.Point;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Attached
|
||||||
|
{
|
||||||
|
public class SliderValueAdorner : System.Windows.Documents.Adorner
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private readonly string _unit;
|
||||||
|
private readonly Slider _slider;
|
||||||
|
private readonly Thumb _thumb;
|
||||||
|
private readonly RepeatButton _decreaseRepeatButton;
|
||||||
|
|
||||||
|
public Brush BorderBrush { get; set; } = System.Windows.Media.Brushes.Black;
|
||||||
|
public Brush Background { get; set; } = System.Windows.Media.Brushes.Black;
|
||||||
|
public Brush Foreground { get; set; } = System.Windows.Media.Brushes.White;
|
||||||
|
public FontFamily Font { get; set; } = new FontFamily("Verdana");
|
||||||
|
public double FontSize { get; set; } = 14;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public SliderValueAdorner(UIElement adornedElement, string unit)
|
||||||
|
: base(adornedElement)
|
||||||
|
{
|
||||||
|
this._unit = unit;
|
||||||
|
|
||||||
|
_slider = (Slider)adornedElement;
|
||||||
|
Track track = (Track)_slider.Template.FindName("PART_Track", _slider);
|
||||||
|
|
||||||
|
_thumb = track.Thumb;
|
||||||
|
_decreaseRepeatButton = track.DecreaseRepeatButton;
|
||||||
|
_decreaseRepeatButton.SizeChanged += OnButtonSizeChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public void Cleanup()
|
||||||
|
{
|
||||||
|
_decreaseRepeatButton.SizeChanged -= OnButtonSizeChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnButtonSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs) => InvalidateVisual();
|
||||||
|
|
||||||
|
protected override void OnRender(DrawingContext drawingContext)
|
||||||
|
{
|
||||||
|
double offset = _decreaseRepeatButton.ActualWidth + (_thumb.ActualWidth / 2.0);
|
||||||
|
|
||||||
|
FormattedText text = new FormattedText(GetText(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface(Font, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal), FontSize, Foreground);
|
||||||
|
Geometry border = CreateBorder(offset, text.Width, text.Height);
|
||||||
|
|
||||||
|
drawingContext.DrawGeometry(Background, new Pen(BorderBrush, 1), border);
|
||||||
|
drawingContext.DrawText(text, new Point(offset - (text.Width / 2.0), -26));
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetText()
|
||||||
|
{
|
||||||
|
string valueText = _slider.Value.ToString();
|
||||||
|
if (!string.IsNullOrWhiteSpace(_unit))
|
||||||
|
valueText += " " + _unit;
|
||||||
|
|
||||||
|
return valueText;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Geometry CreateBorder(double offset, double width, double height)
|
||||||
|
{
|
||||||
|
double halfWidth = width / 2.0;
|
||||||
|
|
||||||
|
PathGeometry borderGeometry = new PathGeometry();
|
||||||
|
PathFigure border = new PathFigure
|
||||||
|
{
|
||||||
|
StartPoint = new Point(offset, 0),
|
||||||
|
IsClosed = true,
|
||||||
|
IsFilled = true
|
||||||
|
};
|
||||||
|
|
||||||
|
border.Segments.Add(new LineSegment(new Point(offset + 4, -6), true));
|
||||||
|
border.Segments.Add(new LineSegment(new Point(offset + 4 + halfWidth, -6), true));
|
||||||
|
border.Segments.Add(new LineSegment(new Point(offset + 4 + halfWidth, -10 - height), true));
|
||||||
|
border.Segments.Add(new LineSegment(new Point(offset - 4 - halfWidth, -10 - height), true));
|
||||||
|
border.Segments.Add(new LineSegment(new Point(offset - 4 - halfWidth, -6), true));
|
||||||
|
border.Segments.Add(new LineSegment(new Point(offset - 4, -6), true));
|
||||||
|
|
||||||
|
borderGeometry.Figures.Add(border);
|
||||||
|
|
||||||
|
return borderGeometry;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
48
RGBSync+/Brushes/SyncBrush.cs
Normal file
48
RGBSync+/Brushes/SyncBrush.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
using RGBSyncPlus.Helper;
|
||||||
|
using RGBSyncPlus.Model;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Brushes
|
||||||
|
{
|
||||||
|
public class SyncBrush : AbstractBrush
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private readonly SyncGroup _syncGroup;
|
||||||
|
|
||||||
|
private Led _syncLed;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public SyncBrush(SyncGroup syncGroup)
|
||||||
|
{
|
||||||
|
this._syncGroup = syncGroup;
|
||||||
|
|
||||||
|
syncGroup.PropertyChanged += SyncGroupOnPropertyChanged;
|
||||||
|
_syncLed = syncGroup.SyncLed?.GetLed();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
private void SyncGroupOnPropertyChanged(object sender, PropertyChangedEventArgs e)
|
||||||
|
{
|
||||||
|
if (e.PropertyName == nameof(SyncGroup.SyncLed))
|
||||||
|
_syncLed = _syncGroup.SyncLed?.GetLed();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget)
|
||||||
|
{
|
||||||
|
if (renderTarget.Led == _syncLed)
|
||||||
|
return Color.Transparent;
|
||||||
|
|
||||||
|
return _syncLed?.Color ?? Color.Transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
31
RGBSync+/Configuration/AbstractConfiguration.cs
Normal file
31
RGBSync+/Configuration/AbstractConfiguration.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using System;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Configuration
|
||||||
|
{
|
||||||
|
public class AbstractConfiguration : AbstractBindable, IConfiguration, INotifyPropertyChanged
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
protected override bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
|
||||||
|
{
|
||||||
|
if ((typeof(T) == typeof(double)) || (typeof(T) == typeof(float)))
|
||||||
|
{
|
||||||
|
if (Math.Abs((double)(object)storage - (double)(object)value) < 0.000001) return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (Equals(storage, value)) return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
storage = value;
|
||||||
|
// ReSharper disable once ExplicitCallerInfoArgument
|
||||||
|
OnPropertyChanged(propertyName);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
41
RGBSync+/Configuration/ColorSerializer.cs
Normal file
41
RGBSync+/Configuration/ColorSerializer.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Linq;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Configuration
|
||||||
|
{
|
||||||
|
public class ColorSerializer : JsonConverter
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public override bool CanConvert(Type objectType) => objectType == typeof(Color);
|
||||||
|
|
||||||
|
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
if (!(value is Color color)) return;
|
||||||
|
|
||||||
|
writer.WriteStartObject();
|
||||||
|
writer.WritePropertyName("A");
|
||||||
|
writer.WriteValue(color.A);
|
||||||
|
writer.WritePropertyName("R");
|
||||||
|
writer.WriteValue(color.R);
|
||||||
|
writer.WritePropertyName("G");
|
||||||
|
writer.WriteValue(color.G);
|
||||||
|
writer.WritePropertyName("B");
|
||||||
|
writer.WriteValue(color.B);
|
||||||
|
writer.WriteEndObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||||
|
{
|
||||||
|
JObject jsonObject = JObject.Load(reader);
|
||||||
|
return new Color(jsonObject.Property("A").Value.ToObject<byte>(),
|
||||||
|
jsonObject.Property("R").Value.ToObject<byte>(),
|
||||||
|
jsonObject.Property("G").Value.ToObject<byte>(),
|
||||||
|
jsonObject.Property("B").Value.ToObject<byte>());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
7
RGBSync+/Configuration/IConfiguration.cs
Normal file
7
RGBSync+/Configuration/IConfiguration.cs
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
using System.ComponentModel;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Configuration
|
||||||
|
{
|
||||||
|
public interface IConfiguration : INotifyPropertyChanged
|
||||||
|
{ }
|
||||||
|
}
|
||||||
12
RGBSync+/Configuration/Legacy/ConfigurationUpdates.cs
Normal file
12
RGBSync+/Configuration/Legacy/ConfigurationUpdates.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
namespace RGBSyncPlus.Configuration.Legacy
|
||||||
|
{
|
||||||
|
public static class ConfigurationUpdates
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public static void PerformOn(Settings settings)
|
||||||
|
{ }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
24
RGBSync+/Configuration/Settings.cs
Normal file
24
RGBSync+/Configuration/Settings.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using RGBSyncPlus.Model;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Configuration
|
||||||
|
{
|
||||||
|
public class Settings
|
||||||
|
{
|
||||||
|
#region Constants
|
||||||
|
|
||||||
|
public const int CURRENT_VERSION = 1;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
public int Version { get; set; } = 0;
|
||||||
|
|
||||||
|
public double UpdateRate { get; set; } = 30.0;
|
||||||
|
|
||||||
|
public List<SyncGroup> SyncGroups { get; set; } = new List<SyncGroup>();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
87
RGBSync+/Controls/BlurredDecorationWindow.cs
Normal file
87
RGBSync+/Controls/BlurredDecorationWindow.cs
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Controls
|
||||||
|
{
|
||||||
|
[TemplatePart(Name = "PART_Decoration", Type = typeof(FrameworkElement))]
|
||||||
|
[TemplatePart(Name = "PART_Content", Type = typeof(FrameworkElement))]
|
||||||
|
[TemplatePart(Name = "PART_CloseButton", Type = typeof(Button))]
|
||||||
|
[TemplatePart(Name = "PART_MinimizeButton", Type = typeof(Button))]
|
||||||
|
[TemplatePart(Name = "PART_IconButton", Type = typeof(Button))]
|
||||||
|
public class BlurredDecorationWindow : Window
|
||||||
|
{
|
||||||
|
#region DependencyProperties
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
public static readonly DependencyProperty BackgroundImageProperty = DependencyProperty.Register(
|
||||||
|
"BackgroundImage", typeof(ImageSource), typeof(BlurredDecorationWindow), new PropertyMetadata(default(ImageSource)));
|
||||||
|
|
||||||
|
public ImageSource BackgroundImage
|
||||||
|
{
|
||||||
|
get => (ImageSource)GetValue(BackgroundImageProperty);
|
||||||
|
set => SetValue(BackgroundImageProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty DecorationHeightProperty = DependencyProperty.Register(
|
||||||
|
"DecorationHeight", typeof(double), typeof(BlurredDecorationWindow), new PropertyMetadata(20.0));
|
||||||
|
|
||||||
|
public double DecorationHeight
|
||||||
|
{
|
||||||
|
get => (double)GetValue(DecorationHeightProperty);
|
||||||
|
set => SetValue(DecorationHeightProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IconToolTipProperty = DependencyProperty.Register(
|
||||||
|
"IconToolTip", typeof(string), typeof(BlurredDecorationWindow), new PropertyMetadata(default(string)));
|
||||||
|
|
||||||
|
public string IconToolTip
|
||||||
|
{
|
||||||
|
get => (string)GetValue(IconToolTipProperty);
|
||||||
|
set => SetValue(IconToolTipProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IconCommandProperty = DependencyProperty.Register(
|
||||||
|
"IconCommand", typeof(ICommand), typeof(BlurredDecorationWindow), new PropertyMetadata(default(ICommand)));
|
||||||
|
|
||||||
|
public ICommand IconCommand
|
||||||
|
{
|
||||||
|
get => (ICommand)GetValue(IconCommandProperty);
|
||||||
|
set => SetValue(IconCommandProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper restore InconsistentNaming
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
static BlurredDecorationWindow()
|
||||||
|
{
|
||||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(BlurredDecorationWindow), new FrameworkPropertyMetadata(typeof(BlurredDecorationWindow)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
base.OnApplyTemplate();
|
||||||
|
|
||||||
|
if (GetTemplateChild("PART_Decoration") is FrameworkElement decoration)
|
||||||
|
decoration.MouseLeftButtonDown += (sender, args) => DragMove();
|
||||||
|
|
||||||
|
if (GetTemplateChild("PART_CloseButton") is Button closeButton)
|
||||||
|
closeButton.Click += (sender, args) => ApplicationManager.Instance.ExitCommand.Execute(null);
|
||||||
|
|
||||||
|
if (GetTemplateChild("PART_MinimizeButton") is Button minimizeButton)
|
||||||
|
minimizeButton.Click += (sender, args) => Hide();
|
||||||
|
|
||||||
|
if (GetTemplateChild("PART_IconButton") is Button iconButton)
|
||||||
|
iconButton.Click += (sender, args) => IconCommand?.Execute(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
483
RGBSync+/Controls/ColorSelector.cs
Normal file
483
RGBSync+/Controls/ColorSelector.cs
Normal file
@ -0,0 +1,483 @@
|
|||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using System.Windows.Shapes;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
using Color = RGB.NET.Core.Color;
|
||||||
|
using Point = System.Windows.Point;
|
||||||
|
using Rectangle = System.Windows.Shapes.Rectangle;
|
||||||
|
using WpfColor = System.Windows.Media.Color;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Controls
|
||||||
|
{
|
||||||
|
[TemplatePart(Name = "PART_Selector", Type = typeof(Panel))]
|
||||||
|
[TemplatePart(Name = "PART_SliderAlpha", Type = typeof(Slider))]
|
||||||
|
[TemplatePart(Name = "PART_SliderRed", Type = typeof(Slider))]
|
||||||
|
[TemplatePart(Name = "PART_SliderGreen", Type = typeof(Slider))]
|
||||||
|
[TemplatePart(Name = "PART_SliderBlue", Type = typeof(Slider))]
|
||||||
|
[TemplatePart(Name = "PART_SliderHue", Type = typeof(Slider))]
|
||||||
|
[TemplatePart(Name = "PART_SliderSaturation", Type = typeof(Slider))]
|
||||||
|
[TemplatePart(Name = "PART_SliderValue", Type = typeof(Slider))]
|
||||||
|
[TemplatePart(Name = "PART_Preview", Type = typeof(Rectangle))]
|
||||||
|
public class ColorSelector : Control
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private bool _ignorePropertyChanged;
|
||||||
|
private bool _dragSelector;
|
||||||
|
|
||||||
|
private byte _a;
|
||||||
|
private byte _r;
|
||||||
|
private byte _g;
|
||||||
|
private byte _b;
|
||||||
|
private double _hue;
|
||||||
|
private double _saturation;
|
||||||
|
private double _value;
|
||||||
|
|
||||||
|
private Panel _selector;
|
||||||
|
private Rectangle _selectorColor;
|
||||||
|
private Grid _selectorGrip;
|
||||||
|
private Slider _sliderAlpha;
|
||||||
|
private Slider _sliderRed;
|
||||||
|
private Slider _sliderGreen;
|
||||||
|
private Slider _sliderBlue;
|
||||||
|
private Slider _sliderHue;
|
||||||
|
private Slider _sliderSaturation;
|
||||||
|
private Slider _sliderValue;
|
||||||
|
private Rectangle _preview;
|
||||||
|
|
||||||
|
private SolidColorBrush _previewBrush;
|
||||||
|
private SolidColorBrush _selectorBrush;
|
||||||
|
private LinearGradientBrush _alphaBrush;
|
||||||
|
private LinearGradientBrush _redBrush;
|
||||||
|
private LinearGradientBrush _greenBrush;
|
||||||
|
private LinearGradientBrush _blueBrush;
|
||||||
|
private LinearGradientBrush _hueBrush;
|
||||||
|
private LinearGradientBrush _saturationBrush;
|
||||||
|
private LinearGradientBrush _valueBrush;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region DependencyProperties
|
||||||
|
|
||||||
|
public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register(
|
||||||
|
"SelectedColor", typeof(Color), typeof(ColorSelector), new FrameworkPropertyMetadata(new Color(255, 0, 0),
|
||||||
|
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
|
||||||
|
SelectedColorChanged));
|
||||||
|
|
||||||
|
public Color SelectedColor
|
||||||
|
{
|
||||||
|
get => (Color)GetValue(SelectedColorProperty);
|
||||||
|
set => SetValue(SelectedColorProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
if ((_selector = GetTemplateChild("PART_Selector") as Panel) != null)
|
||||||
|
{
|
||||||
|
_selectorBrush = new SolidColorBrush();
|
||||||
|
_selectorColor = new Rectangle
|
||||||
|
{
|
||||||
|
VerticalAlignment = VerticalAlignment.Stretch,
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||||
|
SnapsToDevicePixels = true,
|
||||||
|
StrokeThickness = 0,
|
||||||
|
Fill = _selectorBrush
|
||||||
|
};
|
||||||
|
_selector.Children.Add(_selectorColor);
|
||||||
|
|
||||||
|
Rectangle selectorWhite = new Rectangle
|
||||||
|
{
|
||||||
|
VerticalAlignment = VerticalAlignment.Stretch,
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||||
|
SnapsToDevicePixels = true,
|
||||||
|
StrokeThickness = 0,
|
||||||
|
Fill = new LinearGradientBrush(WpfColor.FromRgb(255, 255, 255), WpfColor.FromArgb(0, 255, 255, 255), new Point(0, 0.5), new Point(1, 0.5))
|
||||||
|
};
|
||||||
|
_selector.Children.Add(selectorWhite);
|
||||||
|
|
||||||
|
Rectangle selectorBlack = new Rectangle
|
||||||
|
{
|
||||||
|
VerticalAlignment = VerticalAlignment.Stretch,
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Stretch,
|
||||||
|
SnapsToDevicePixels = true,
|
||||||
|
StrokeThickness = 0,
|
||||||
|
Fill = new LinearGradientBrush(WpfColor.FromRgb(0, 0, 0), WpfColor.FromArgb(0, 0, 0, 0), new Point(0.5, 1), new Point(0.5, 0))
|
||||||
|
};
|
||||||
|
_selector.Children.Add(selectorBlack);
|
||||||
|
|
||||||
|
_selectorGrip = new Grid
|
||||||
|
{
|
||||||
|
VerticalAlignment = VerticalAlignment.Bottom,
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Left,
|
||||||
|
SnapsToDevicePixels = true
|
||||||
|
};
|
||||||
|
_selectorGrip.Children.Add(new Ellipse
|
||||||
|
{
|
||||||
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
SnapsToDevicePixels = true,
|
||||||
|
Stroke = new SolidColorBrush(WpfColor.FromRgb(0, 0, 0)),
|
||||||
|
StrokeThickness = 2,
|
||||||
|
Fill = null,
|
||||||
|
Width = 12,
|
||||||
|
Height = 12
|
||||||
|
});
|
||||||
|
_selectorGrip.Children.Add(new Ellipse
|
||||||
|
{
|
||||||
|
VerticalAlignment = VerticalAlignment.Center,
|
||||||
|
HorizontalAlignment = HorizontalAlignment.Center,
|
||||||
|
SnapsToDevicePixels = true,
|
||||||
|
Stroke = new SolidColorBrush(WpfColor.FromRgb(255, 255, 255)),
|
||||||
|
StrokeThickness = 1,
|
||||||
|
Fill = null,
|
||||||
|
Width = 10,
|
||||||
|
Height = 10
|
||||||
|
});
|
||||||
|
_selector.Children.Add(_selectorGrip);
|
||||||
|
|
||||||
|
_selector.SizeChanged += (sender, args) => UpdateSelector();
|
||||||
|
_selector.MouseLeftButtonDown += (sender, args) =>
|
||||||
|
{
|
||||||
|
_dragSelector = true;
|
||||||
|
UpdateSelectorValue(args.GetPosition(_selector));
|
||||||
|
};
|
||||||
|
_selector.MouseEnter += (sender, args) =>
|
||||||
|
{
|
||||||
|
if (args.LeftButton == MouseButtonState.Pressed)
|
||||||
|
{
|
||||||
|
_dragSelector = true;
|
||||||
|
UpdateSelectorValue(args.GetPosition(_selector));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
_selector.MouseLeftButtonUp += (sender, args) => _dragSelector = false;
|
||||||
|
_selector.MouseLeave += (sender, args) => _dragSelector = false;
|
||||||
|
_selector.MouseMove += (sender, args) => UpdateSelectorValue(args.GetPosition(_selector));
|
||||||
|
_selector.ClipToBounds = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_sliderAlpha = GetTemplateChild("PART_SliderAlpha") as Slider) != null)
|
||||||
|
{
|
||||||
|
_alphaBrush = new LinearGradientBrush(new GradientStopCollection(new[] { new GradientStop(new WpfColor(), 0),
|
||||||
|
new GradientStop(new WpfColor(), 1) }));
|
||||||
|
_sliderAlpha.Background = _alphaBrush;
|
||||||
|
_sliderAlpha.ValueChanged += AChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_sliderRed = GetTemplateChild("PART_SliderRed") as Slider) != null)
|
||||||
|
{
|
||||||
|
_redBrush = new LinearGradientBrush(new GradientStopCollection(new[] { new GradientStop(new WpfColor(), 0),
|
||||||
|
new GradientStop(new WpfColor(), 1) }));
|
||||||
|
_sliderRed.Background = _redBrush;
|
||||||
|
_sliderRed.ValueChanged += RChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_sliderGreen = GetTemplateChild("PART_SliderGreen") as Slider) != null)
|
||||||
|
{
|
||||||
|
_greenBrush = new LinearGradientBrush(new GradientStopCollection(new[] { new GradientStop(new WpfColor(), 0),
|
||||||
|
new GradientStop(new WpfColor(), 1) }));
|
||||||
|
_sliderGreen.Background = _greenBrush;
|
||||||
|
_sliderGreen.ValueChanged += GChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_sliderBlue = GetTemplateChild("PART_SliderBlue") as Slider) != null)
|
||||||
|
{
|
||||||
|
_blueBrush = new LinearGradientBrush(new GradientStopCollection(new[] { new GradientStop(new WpfColor(), 0),
|
||||||
|
new GradientStop(new WpfColor(), 1) }));
|
||||||
|
_sliderBlue.Background = _blueBrush;
|
||||||
|
_sliderBlue.ValueChanged += BChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_sliderHue = GetTemplateChild("PART_SliderHue") as Slider) != null)
|
||||||
|
{
|
||||||
|
_hueBrush = new LinearGradientBrush(new GradientStopCollection(new[] { new GradientStop(new WpfColor(), 0),
|
||||||
|
new GradientStop(new WpfColor(), 1.0 / 6.0),
|
||||||
|
new GradientStop(new WpfColor(), 2.0 / 6.0),
|
||||||
|
new GradientStop(new WpfColor(), 3.0 / 6.0),
|
||||||
|
new GradientStop(new WpfColor(), 4.0 / 6.0),
|
||||||
|
new GradientStop(new WpfColor(), 5.0 / 6.0),
|
||||||
|
new GradientStop(new WpfColor(), 1) }));
|
||||||
|
_sliderHue.Background = _hueBrush;
|
||||||
|
_sliderHue.ValueChanged += HueChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_sliderSaturation = GetTemplateChild("PART_SliderSaturation") as Slider) != null)
|
||||||
|
{
|
||||||
|
_saturationBrush = new LinearGradientBrush(new GradientStopCollection(new[] { new GradientStop(new WpfColor(), 0),
|
||||||
|
new GradientStop(new WpfColor(), 1) }));
|
||||||
|
_sliderSaturation.Background = _saturationBrush;
|
||||||
|
_sliderSaturation.ValueChanged += SaturationChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_sliderValue = GetTemplateChild("PART_SliderValue") as Slider) != null)
|
||||||
|
{
|
||||||
|
_valueBrush = new LinearGradientBrush(new GradientStopCollection(new[] { new GradientStop(new WpfColor(), 0),
|
||||||
|
new GradientStop(new WpfColor(), 1) }));
|
||||||
|
_sliderValue.Background = _valueBrush;
|
||||||
|
_sliderValue.ValueChanged += ValueChanged;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_preview = GetTemplateChild("PART_Preview") as Rectangle) != null)
|
||||||
|
{
|
||||||
|
_previewBrush = new SolidColorBrush();
|
||||||
|
_preview.Fill = _previewBrush;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetColor(SelectedColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SelectedColorChanged(DependencyObject dependencyObject,
|
||||||
|
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (!(dependencyObject is ColorSelector cs) || !(dependencyPropertyChangedEventArgs.NewValue is Color color)) return;
|
||||||
|
cs.SetColor(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetColor(Color color)
|
||||||
|
{
|
||||||
|
if (_ignorePropertyChanged) return;
|
||||||
|
|
||||||
|
SetA(color);
|
||||||
|
SetRGB(color);
|
||||||
|
SetHSV(color);
|
||||||
|
|
||||||
|
UpdateSelector();
|
||||||
|
UpdateUIColors();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AChanged(object sender, RoutedPropertyChangedEventArgs<double> routedPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (_ignorePropertyChanged) return;
|
||||||
|
|
||||||
|
_a = (byte)routedPropertyChangedEventArgs.NewValue.Clamp(0, byte.MaxValue);
|
||||||
|
Color color = new Color(_a, _r, _g, _b);
|
||||||
|
UpdateSelectedColor(color);
|
||||||
|
UpdateUIColors();
|
||||||
|
UpdateSelector();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RChanged(object sender, RoutedPropertyChangedEventArgs<double> routedPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (_ignorePropertyChanged) return;
|
||||||
|
|
||||||
|
_r = (byte)routedPropertyChangedEventArgs.NewValue.Clamp(0, byte.MaxValue);
|
||||||
|
RGBChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GChanged(object sender, RoutedPropertyChangedEventArgs<double> routedPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (_ignorePropertyChanged) return;
|
||||||
|
|
||||||
|
_g = (byte)routedPropertyChangedEventArgs.NewValue.Clamp(0, byte.MaxValue);
|
||||||
|
RGBChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void BChanged(object sender, RoutedPropertyChangedEventArgs<double> routedPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (_ignorePropertyChanged) return;
|
||||||
|
|
||||||
|
_b = (byte)routedPropertyChangedEventArgs.NewValue.Clamp(0, byte.MaxValue);
|
||||||
|
RGBChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RGBChanged()
|
||||||
|
{
|
||||||
|
Color color = new Color(_a, _r, _g, _b);
|
||||||
|
UpdateSelectedColor(color);
|
||||||
|
SetHSV(color);
|
||||||
|
UpdateUIColors();
|
||||||
|
UpdateSelector();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HueChanged(object sender, RoutedPropertyChangedEventArgs<double> routedPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (_ignorePropertyChanged) return;
|
||||||
|
|
||||||
|
_hue = routedPropertyChangedEventArgs.NewValue.Clamp(0, 360);
|
||||||
|
HSVChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SaturationChanged(object sender, RoutedPropertyChangedEventArgs<double> routedPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (_ignorePropertyChanged) return;
|
||||||
|
|
||||||
|
_saturation = routedPropertyChangedEventArgs.NewValue.Clamp(0, 1);
|
||||||
|
HSVChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> routedPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (_ignorePropertyChanged) return;
|
||||||
|
|
||||||
|
_value = routedPropertyChangedEventArgs.NewValue.Clamp(0, 1);
|
||||||
|
HSVChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HSVChanged()
|
||||||
|
{
|
||||||
|
Color color = Color.FromHSV(_a, _hue, _saturation, _value);
|
||||||
|
UpdateSelectedColor(color);
|
||||||
|
SetRGB(color);
|
||||||
|
UpdateUIColors();
|
||||||
|
UpdateSelector();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetA(Color color)
|
||||||
|
{
|
||||||
|
_ignorePropertyChanged = true;
|
||||||
|
|
||||||
|
_a = color.A;
|
||||||
|
if (_sliderAlpha != null)
|
||||||
|
_sliderAlpha.Value = _a;
|
||||||
|
|
||||||
|
_ignorePropertyChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetRGB(Color color)
|
||||||
|
{
|
||||||
|
_ignorePropertyChanged = true;
|
||||||
|
|
||||||
|
_r = color.R;
|
||||||
|
if (_sliderRed != null)
|
||||||
|
_sliderRed.Value = _r;
|
||||||
|
|
||||||
|
_g = color.G;
|
||||||
|
if (_sliderGreen != null)
|
||||||
|
_sliderGreen.Value = _g;
|
||||||
|
|
||||||
|
_b = color.B;
|
||||||
|
if (_sliderBlue != null)
|
||||||
|
_sliderBlue.Value = _b;
|
||||||
|
|
||||||
|
_ignorePropertyChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetHSV(Color color)
|
||||||
|
{
|
||||||
|
_ignorePropertyChanged = true;
|
||||||
|
|
||||||
|
_hue = color.Hue;
|
||||||
|
if (_sliderHue != null)
|
||||||
|
_sliderHue.Value = _hue;
|
||||||
|
|
||||||
|
_saturation = color.Saturation;
|
||||||
|
if (_sliderSaturation != null)
|
||||||
|
_sliderSaturation.Value = _saturation;
|
||||||
|
|
||||||
|
_value = color.Value;
|
||||||
|
if (_sliderValue != null)
|
||||||
|
_sliderValue.Value = _value;
|
||||||
|
|
||||||
|
_ignorePropertyChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSelectedColor(Color color)
|
||||||
|
{
|
||||||
|
_ignorePropertyChanged = true;
|
||||||
|
|
||||||
|
SelectedColor = color;
|
||||||
|
|
||||||
|
_ignorePropertyChanged = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSelector()
|
||||||
|
{
|
||||||
|
if (_selector == null) return;
|
||||||
|
|
||||||
|
double selectorX = (_selector.ActualWidth * _saturation) - (_selectorGrip.ActualWidth / 2);
|
||||||
|
double selectorY = (_selector.ActualHeight * _value) - (_selectorGrip.ActualHeight / 2);
|
||||||
|
if (!double.IsNaN(selectorX) && !double.IsNaN(selectorY))
|
||||||
|
_selectorGrip.Margin = new Thickness(selectorX, 0, 0, selectorY);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateSelectorValue(Point mouseLocation)
|
||||||
|
{
|
||||||
|
if (!_dragSelector) return;
|
||||||
|
|
||||||
|
double saturation = mouseLocation.X / _selector.ActualWidth;
|
||||||
|
double value = 1 - (mouseLocation.Y / _selector.ActualHeight);
|
||||||
|
if (!double.IsNaN(saturation) && !double.IsNaN(value))
|
||||||
|
{
|
||||||
|
_saturation = saturation;
|
||||||
|
_value = value;
|
||||||
|
HSVChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateUIColors()
|
||||||
|
{
|
||||||
|
Color hueColor = Color.FromHSV(_hue, 1, 1);
|
||||||
|
|
||||||
|
if (_previewBrush != null)
|
||||||
|
_previewBrush.Color = WpfColor.FromArgb(_a, _r, _g, _b);
|
||||||
|
|
||||||
|
if (_selectorBrush != null)
|
||||||
|
_selectorBrush.Color = WpfColor.FromRgb(hueColor.R, hueColor.G, hueColor.B);
|
||||||
|
|
||||||
|
if (_alphaBrush != null)
|
||||||
|
{
|
||||||
|
_alphaBrush.GradientStops[0].Color = WpfColor.FromArgb(0, _r, _g, _b);
|
||||||
|
_alphaBrush.GradientStops[1].Color = WpfColor.FromArgb(255, _r, _g, _b);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_redBrush != null)
|
||||||
|
{
|
||||||
|
_redBrush.GradientStops[0].Color = WpfColor.FromArgb(_a, 0, _g, _b);
|
||||||
|
_redBrush.GradientStops[1].Color = WpfColor.FromArgb(_a, 255, _g, _b);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_greenBrush != null)
|
||||||
|
{
|
||||||
|
_greenBrush.GradientStops[0].Color = WpfColor.FromArgb(_a, _r, 0, _b);
|
||||||
|
_greenBrush.GradientStops[1].Color = WpfColor.FromArgb(_a, _r, 255, _b);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_blueBrush != null)
|
||||||
|
{
|
||||||
|
_blueBrush.GradientStops[0].Color = WpfColor.FromArgb(_a, _r, _g, 0);
|
||||||
|
_blueBrush.GradientStops[1].Color = WpfColor.FromArgb(_a, _r, _g, 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_hueBrush != null)
|
||||||
|
{
|
||||||
|
Color referenceColor1 = Color.FromHSV(0, _saturation, _value);
|
||||||
|
Color referenceColor2 = Color.FromHSV(60, _saturation, _value);
|
||||||
|
Color referenceColor3 = Color.FromHSV(120, _saturation, _value);
|
||||||
|
Color referenceColor4 = Color.FromHSV(180, _saturation, _value);
|
||||||
|
Color referenceColor5 = Color.FromHSV(240, _saturation, _value);
|
||||||
|
Color referenceColor6 = Color.FromHSV(300, _saturation, _value);
|
||||||
|
|
||||||
|
_hueBrush.GradientStops[0].Color = WpfColor.FromArgb(_a, referenceColor1.R, referenceColor1.G, referenceColor1.B);
|
||||||
|
_hueBrush.GradientStops[1].Color = WpfColor.FromArgb(_a, referenceColor2.R, referenceColor2.G, referenceColor2.B);
|
||||||
|
_hueBrush.GradientStops[2].Color = WpfColor.FromArgb(_a, referenceColor3.R, referenceColor3.G, referenceColor3.B);
|
||||||
|
_hueBrush.GradientStops[3].Color = WpfColor.FromArgb(_a, referenceColor4.R, referenceColor4.G, referenceColor4.B);
|
||||||
|
_hueBrush.GradientStops[4].Color = WpfColor.FromArgb(_a, referenceColor5.R, referenceColor5.G, referenceColor5.B);
|
||||||
|
_hueBrush.GradientStops[5].Color = WpfColor.FromArgb(_a, referenceColor6.R, referenceColor6.G, referenceColor6.B);
|
||||||
|
_hueBrush.GradientStops[6].Color = WpfColor.FromArgb(_a, referenceColor1.R, referenceColor1.G, referenceColor1.B);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_saturationBrush != null)
|
||||||
|
{
|
||||||
|
Color referenceColor = Color.FromHSV(_hue, 1, _value);
|
||||||
|
|
||||||
|
_saturationBrush.GradientStops[0].Color = WpfColor.FromArgb(_a, 255, 255, 255);
|
||||||
|
_saturationBrush.GradientStops[1].Color = WpfColor.FromArgb(_a, referenceColor.R, referenceColor.G, referenceColor.B);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_valueBrush != null)
|
||||||
|
{
|
||||||
|
Color referenceColor = Color.FromHSV(_hue, _saturation, 1);
|
||||||
|
|
||||||
|
_valueBrush.GradientStops[0].Color = WpfColor.FromArgb(_a, 0, 0, 0);
|
||||||
|
_valueBrush.GradientStops[1].Color = WpfColor.FromArgb(_a, referenceColor.R, referenceColor.G, referenceColor.B);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
212
RGBSync+/Controls/Form.cs
Normal file
212
RGBSync+/Controls/Form.cs
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Controls
|
||||||
|
{
|
||||||
|
public class Form : Panel
|
||||||
|
{
|
||||||
|
#region DependencyProperties
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
public static readonly DependencyProperty RowHeightProperty = DependencyProperty.Register("RowHeight", typeof(double), typeof(Form),
|
||||||
|
new FrameworkPropertyMetadata(24.0, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||||
|
|
||||||
|
public double RowHeight
|
||||||
|
{
|
||||||
|
get => (double)GetValue(RowHeightProperty);
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < 0) throw new ArgumentOutOfRangeException(nameof(RowHeight), "Row height can't be negative");
|
||||||
|
SetValue(RowHeightProperty, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty LabelWidthProperty = DependencyProperty.Register("LabelWidth", typeof(double), typeof(Form),
|
||||||
|
new FrameworkPropertyMetadata(100.0, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||||
|
|
||||||
|
public double LabelWidth
|
||||||
|
{
|
||||||
|
get => (double)GetValue(LabelWidthProperty);
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value < 0) throw new ArgumentOutOfRangeException(nameof(RowHeight), "Label width can't be negative");
|
||||||
|
SetValue(LabelWidthProperty, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ElementSpacingProperty = DependencyProperty.Register("ElementSpacing", typeof(double), typeof(Form),
|
||||||
|
new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||||
|
|
||||||
|
public double ElementSpacing
|
||||||
|
{
|
||||||
|
get => (double)GetValue(ElementSpacingProperty);
|
||||||
|
set => SetValue(ElementSpacingProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty RowSpacingProperty = DependencyProperty.Register("RowSpacing", typeof(double), typeof(Form),
|
||||||
|
new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||||
|
|
||||||
|
public double RowSpacing
|
||||||
|
{
|
||||||
|
get => (double)GetValue(RowSpacingProperty);
|
||||||
|
set => SetValue(RowSpacingProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper restore InconsistentNaming
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region AttachedProperties
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IsLabelProperty = DependencyProperty.RegisterAttached("IsLabel", typeof(bool), typeof(Form),
|
||||||
|
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||||
|
|
||||||
|
public static void SetIsLabel(UIElement element, bool value) => element.SetValue(IsLabelProperty, value);
|
||||||
|
public static bool GetIsLabel(UIElement element) => (bool)element.GetValue(IsLabelProperty);
|
||||||
|
|
||||||
|
public static readonly DependencyProperty LineBreaksProperty = DependencyProperty.RegisterAttached("LineBreaks", typeof(int), typeof(Form),
|
||||||
|
new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||||
|
|
||||||
|
public static void SetLineBreaks(UIElement element, int value) => element.SetValue(LineBreaksProperty, value);
|
||||||
|
public static int GetLineBreaks(UIElement element) => (int)element.GetValue(LineBreaksProperty);
|
||||||
|
|
||||||
|
public static readonly DependencyProperty RowSpanProperty = DependencyProperty.RegisterAttached("RowSpan", typeof(int), typeof(Form),
|
||||||
|
new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||||
|
|
||||||
|
public static void SetRowSpan(DependencyObject element, int value) => element.SetValue(RowSpanProperty, value);
|
||||||
|
public static int GetRowSpan(DependencyObject element) => (int)element.GetValue(RowSpanProperty);
|
||||||
|
|
||||||
|
public static readonly DependencyProperty FillProperty = DependencyProperty.RegisterAttached("Fill", typeof(bool), typeof(Form),
|
||||||
|
new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
|
||||||
|
|
||||||
|
public static void SetFill(DependencyObject element, bool value) => element.SetValue(FillProperty, value);
|
||||||
|
public static bool GetFill(DependencyObject element) => (bool)element.GetValue(FillProperty);
|
||||||
|
|
||||||
|
// ReSharper restore InconsistentNaming
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
protected override Size MeasureOverride(Size availableSize)
|
||||||
|
{
|
||||||
|
if (InternalChildren.Count == 0) return new Size(0, 0);
|
||||||
|
|
||||||
|
FormLayout layout = new FormLayout(RowHeight, LabelWidth, ElementSpacing, RowSpacing);
|
||||||
|
|
||||||
|
foreach (UIElement child in InternalChildren)
|
||||||
|
{
|
||||||
|
child.Measure(availableSize);
|
||||||
|
layout.AddElement(child, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new Size(layout.Width, layout.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Size ArrangeOverride(Size finalSize)
|
||||||
|
{
|
||||||
|
if (InternalChildren.Count == 0) return new Size(0, 0);
|
||||||
|
|
||||||
|
FormLayout layout = new FormLayout(RowHeight, LabelWidth, ElementSpacing, RowSpacing);
|
||||||
|
|
||||||
|
foreach (UIElement child in InternalChildren)
|
||||||
|
child.Arrange(layout.AddElement(child, finalSize.Width));
|
||||||
|
|
||||||
|
return new Size(finalSize.Width, layout.Height);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Data
|
||||||
|
|
||||||
|
private class FormLayout
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private readonly double _rowHeight;
|
||||||
|
private readonly double _labelWidth;
|
||||||
|
private readonly double _elementSpacing;
|
||||||
|
private readonly double _rowSpacing;
|
||||||
|
|
||||||
|
private double _currentRowWidth;
|
||||||
|
|
||||||
|
private int _newRows = 0;
|
||||||
|
private int _rows = -1;
|
||||||
|
private double _currentMaxWidth;
|
||||||
|
public double Width => Math.Max((Math.Max(_currentMaxWidth, _currentRowWidth) - _elementSpacing), 0);
|
||||||
|
public double Height => ((_rows + 1) * _rowHeight) + (_rows * _rowSpacing);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public FormLayout(double rowHeight, double labelWidth, double elementSpacing, double rowSpacing)
|
||||||
|
{
|
||||||
|
this._rowHeight = rowHeight;
|
||||||
|
this._labelWidth = labelWidth;
|
||||||
|
this._elementSpacing = elementSpacing;
|
||||||
|
this._rowSpacing = rowSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public Rect AddElement(UIElement element, double targetWidth)
|
||||||
|
{
|
||||||
|
bool isLabel = GetIsLabel(element);
|
||||||
|
int lineBreaks = GetLineBreaks(element);
|
||||||
|
int rowSpan = GetRowSpan(element);
|
||||||
|
|
||||||
|
double elementWidth = isLabel ? _labelWidth : element.DesiredSize.Width;
|
||||||
|
double height = _rowHeight;
|
||||||
|
|
||||||
|
if (_newRows > 0)
|
||||||
|
{
|
||||||
|
AddLineBreaks(_newRows);
|
||||||
|
_newRows = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (lineBreaks > 0) AddLineBreaks(lineBreaks);
|
||||||
|
else if (isLabel) AddLineBreaks(1);
|
||||||
|
else if (_rows < 0) _rows = 0;
|
||||||
|
|
||||||
|
if (!isLabel && (_currentRowWidth < _labelWidth))
|
||||||
|
_currentRowWidth = _labelWidth + _elementSpacing;
|
||||||
|
|
||||||
|
if (rowSpan > 1)
|
||||||
|
{
|
||||||
|
height = (rowSpan * _rowHeight) + ((rowSpan - 1) * _rowSpacing);
|
||||||
|
_newRows = Math.Max(_newRows, rowSpan - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (element is FrameworkElement fe)
|
||||||
|
fe.MaxHeight = height;
|
||||||
|
|
||||||
|
double width = elementWidth;
|
||||||
|
if ((targetWidth >= 1) && GetFill(element))
|
||||||
|
width = targetWidth - _currentRowWidth;
|
||||||
|
|
||||||
|
Rect rect = new Rect(new Point(_currentRowWidth, (_rows * _rowHeight) + (_rows * _rowSpacing)), new Size(width, height));
|
||||||
|
|
||||||
|
_currentRowWidth += width + _elementSpacing;
|
||||||
|
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddLineBreaks(int count)
|
||||||
|
{
|
||||||
|
if (count <= 0) return;
|
||||||
|
|
||||||
|
_currentMaxWidth = Math.Max(_currentMaxWidth, _currentRowWidth);
|
||||||
|
|
||||||
|
_currentRowWidth = 0;
|
||||||
|
_rows += count;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
424
RGBSync+/Controls/GradientEditor.cs
Normal file
424
RGBSync+/Controls/GradientEditor.cs
Normal file
@ -0,0 +1,424 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Documents;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Media;
|
||||||
|
using RGB.NET.Brushes.Gradients;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
using Color = System.Windows.Media.Color;
|
||||||
|
using Point = System.Windows.Point;
|
||||||
|
using Size = System.Windows.Size;
|
||||||
|
using Rectangle = System.Windows.Shapes.Rectangle;
|
||||||
|
using GradientStop = RGB.NET.Brushes.Gradients.GradientStop;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Controls
|
||||||
|
{
|
||||||
|
[TemplatePart(Name = "PART_Gradient", Type = typeof(Canvas))]
|
||||||
|
[TemplatePart(Name = "PART_Stops", Type = typeof(Canvas))]
|
||||||
|
public class GradientEditor : Control
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private Canvas _gradientContainer;
|
||||||
|
private Canvas _stopContainer;
|
||||||
|
private readonly List<Rectangle> _previewRectangles = new List<Rectangle>();
|
||||||
|
private readonly Dictionary<GradientStop, ContentControl> _stops = new Dictionary<GradientStop, ContentControl>();
|
||||||
|
private ContentControl _draggingStop;
|
||||||
|
private AdornerLayer _adornerLayer;
|
||||||
|
private ColorPickerAdorner _adorner;
|
||||||
|
private Window _window;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region DepdencyProperties
|
||||||
|
|
||||||
|
public static readonly DependencyProperty GradientProperty = DependencyProperty.Register(
|
||||||
|
"Gradient", typeof(LinearGradient), typeof(GradientEditor), new FrameworkPropertyMetadata(null,
|
||||||
|
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
|
||||||
|
OnGradientChanged));
|
||||||
|
|
||||||
|
public LinearGradient Gradient
|
||||||
|
{
|
||||||
|
get => (LinearGradient)GetValue(GradientProperty);
|
||||||
|
set => SetValue(GradientProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty GradientStopStyleProperty = DependencyProperty.Register(
|
||||||
|
"GradientStopStyle", typeof(Style), typeof(GradientEditor), new PropertyMetadata(default(Style)));
|
||||||
|
|
||||||
|
public Style GradientStopStyle
|
||||||
|
{
|
||||||
|
get => (Style)GetValue(GradientStopStyleProperty);
|
||||||
|
set => SetValue(GradientStopStyleProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty SelectedStopProperty = DependencyProperty.Register(
|
||||||
|
"SelectedStop", typeof(GradientStop), typeof(GradientEditor), new PropertyMetadata(default(GradientStop), SelectedStopChanged));
|
||||||
|
|
||||||
|
public GradientStop SelectedStop
|
||||||
|
{
|
||||||
|
get => (GradientStop)GetValue(SelectedStopProperty);
|
||||||
|
set => SetValue(SelectedStopProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ColorSelectorTemplateProperty = DependencyProperty.Register(
|
||||||
|
"ColorSelectorTemplate", typeof(DataTemplate), typeof(GradientEditor), new PropertyMetadata(default(DataTemplate)));
|
||||||
|
|
||||||
|
public DataTemplate ColorSelectorTemplate
|
||||||
|
{
|
||||||
|
get => (DataTemplate)GetValue(ColorSelectorTemplateProperty);
|
||||||
|
set => SetValue(ColorSelectorTemplateProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty CanAddOrDeleteStopsProperty = DependencyProperty.Register(
|
||||||
|
"CanAddOrDeleteStops", typeof(bool), typeof(GradientEditor), new PropertyMetadata(true));
|
||||||
|
|
||||||
|
public bool CanAddOrDeleteStops
|
||||||
|
{
|
||||||
|
get => (bool)GetValue(CanAddOrDeleteStopsProperty);
|
||||||
|
set => SetValue(CanAddOrDeleteStopsProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region AttachedProperties
|
||||||
|
|
||||||
|
public static readonly DependencyProperty IsSelectedProperty = DependencyProperty.RegisterAttached(
|
||||||
|
"IsSelected", typeof(bool), typeof(GradientEditor), new PropertyMetadata(default(bool)));
|
||||||
|
|
||||||
|
public static void SetIsSelected(DependencyObject element, bool value) => element.SetValue(IsSelectedProperty, value);
|
||||||
|
public static bool GetIsSelected(DependencyObject element) => (bool)element.GetValue(IsSelectedProperty);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public GradientEditor()
|
||||||
|
{
|
||||||
|
if (Gradient == null)
|
||||||
|
Gradient = new LinearGradient();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public override void OnApplyTemplate()
|
||||||
|
{
|
||||||
|
if ((_gradientContainer = GetTemplateChild("PART_Gradient") as Canvas) != null)
|
||||||
|
{
|
||||||
|
_gradientContainer.SizeChanged += (sender, args) => UpdateGradientPreview();
|
||||||
|
_gradientContainer.MouseDown += GradientContainerOnMouseDown;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((_stopContainer = GetTemplateChild("PART_Stops") as Canvas) != null)
|
||||||
|
_stopContainer.SizeChanged += (sender, args) => UpdateGradientStops();
|
||||||
|
|
||||||
|
_adornerLayer = AdornerLayer.GetAdornerLayer(this);
|
||||||
|
_window = Window.GetWindow(this);
|
||||||
|
if (_window != null)
|
||||||
|
{
|
||||||
|
_window.PreviewMouseDown += WindowMouseDown;
|
||||||
|
_window.PreviewKeyDown += (sender, args) =>
|
||||||
|
{
|
||||||
|
if (args.Key == Key.Escape)
|
||||||
|
SelectedStop = null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
UpdateGradientPreview();
|
||||||
|
UpdateGradientStops();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateGradientPreview()
|
||||||
|
{
|
||||||
|
if ((_gradientContainer == null) || (Gradient == null)) return;
|
||||||
|
|
||||||
|
List<GradientStop> gradientStops = Gradient.GradientStops.OrderBy(x => x.Offset).ToList();
|
||||||
|
if (gradientStops.Count == 0)
|
||||||
|
UpdatePreviewRectangleCount(gradientStops.Count);
|
||||||
|
else if (gradientStops.Count == 1)
|
||||||
|
{
|
||||||
|
UpdatePreviewRectangleCount(gradientStops.Count);
|
||||||
|
GradientStop firstStop = gradientStops[0];
|
||||||
|
UpdatePreviewRectangle(_previewRectangles[0], _gradientContainer.ActualWidth, _gradientContainer.ActualHeight, 0, 1, firstStop.Color, firstStop.Color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UpdatePreviewRectangleCount(gradientStops.Count + 1);
|
||||||
|
|
||||||
|
GradientStop firstStop = gradientStops[0];
|
||||||
|
UpdatePreviewRectangle(_previewRectangles[0], _gradientContainer.ActualWidth, _gradientContainer.ActualHeight, 0, firstStop.Offset, firstStop.Color, firstStop.Color);
|
||||||
|
for (int i = 0; i < (gradientStops.Count - 1); i++)
|
||||||
|
{
|
||||||
|
GradientStop stop = gradientStops[i];
|
||||||
|
GradientStop nextStop = gradientStops[i + 1];
|
||||||
|
Rectangle rect = _previewRectangles[i + 1];
|
||||||
|
UpdatePreviewRectangle(rect, _gradientContainer.ActualWidth, _gradientContainer.ActualHeight, stop.Offset, nextStop.Offset, stop.Color, nextStop.Color);
|
||||||
|
}
|
||||||
|
GradientStop lastStop = gradientStops[gradientStops.Count - 1];
|
||||||
|
UpdatePreviewRectangle(_previewRectangles[_previewRectangles.Count - 1], _gradientContainer.ActualWidth, _gradientContainer.ActualHeight, lastStop.Offset, 1, lastStop.Color, lastStop.Color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePreviewRectangle(Rectangle rect, double referenceWidth, double referenceHeight, double from, double to,
|
||||||
|
RGB.NET.Core.Color startColor, RGB.NET.Core.Color endColor)
|
||||||
|
{
|
||||||
|
rect.Fill = new LinearGradientBrush(Color.FromArgb(startColor.A, startColor.R, startColor.G, startColor.B),
|
||||||
|
Color.FromArgb(endColor.A, endColor.R, endColor.G, endColor.B),
|
||||||
|
new Point(0, 0.5), new Point(1, 0.5));
|
||||||
|
|
||||||
|
//DarthAffe 09.02.2018: Forced rounding to prevent render issues on resize
|
||||||
|
Canvas.SetLeft(rect, Math.Floor(referenceWidth * from.Clamp(0, 1)));
|
||||||
|
rect.Width = Math.Ceiling(referenceWidth * (to.Clamp(0, 1) - from.Clamp(0, 1)));
|
||||||
|
|
||||||
|
Canvas.SetTop(rect, 0);
|
||||||
|
rect.Height = referenceHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdatePreviewRectangleCount(int gradientCount)
|
||||||
|
{
|
||||||
|
int countDiff = gradientCount - _previewRectangles.Count;
|
||||||
|
if (countDiff > 0)
|
||||||
|
for (int i = 0; i < countDiff; i++)
|
||||||
|
{
|
||||||
|
Rectangle rect = new Rectangle { VerticalAlignment = VerticalAlignment.Stretch };
|
||||||
|
_previewRectangles.Add(rect);
|
||||||
|
_gradientContainer.Children.Add(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (countDiff < 0)
|
||||||
|
for (int i = 0; i < Math.Abs(countDiff); i++)
|
||||||
|
{
|
||||||
|
int index = _previewRectangles.Count - i - 1;
|
||||||
|
Rectangle rect = _previewRectangles[index];
|
||||||
|
_previewRectangles.RemoveAt(index);
|
||||||
|
_gradientContainer.Children.Remove(rect);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateGradientStops()
|
||||||
|
{
|
||||||
|
if (Gradient == null) return;
|
||||||
|
|
||||||
|
List<GradientStop> gradientStops = Gradient.GradientStops.OrderBy(x => x.Offset).ToList();
|
||||||
|
UpdateGradientStopsCount(gradientStops);
|
||||||
|
foreach (GradientStop stop in gradientStops)
|
||||||
|
UpdateGradientStop(_stops[stop], _stopContainer.ActualWidth, _stopContainer.ActualHeight, stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateGradientStop(ContentControl control, double referenceWidth, double referenceHeight, GradientStop stop)
|
||||||
|
{
|
||||||
|
control.Background = new SolidColorBrush(Color.FromArgb(stop.Color.A, stop.Color.R, stop.Color.G, stop.Color.B));
|
||||||
|
|
||||||
|
Canvas.SetLeft(control, (referenceWidth * stop.Offset.Clamp(0, 1)) - (control.Width / 2.0));
|
||||||
|
|
||||||
|
Canvas.SetTop(control, 0);
|
||||||
|
control.Height = referenceHeight;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateGradientStopsCount(List<GradientStop> gradientStops)
|
||||||
|
{
|
||||||
|
foreach (GradientStop stop in gradientStops)
|
||||||
|
{
|
||||||
|
if (!_stops.ContainsKey(stop))
|
||||||
|
{
|
||||||
|
ContentControl control = new ContentControl
|
||||||
|
{
|
||||||
|
VerticalAlignment = VerticalAlignment.Stretch,
|
||||||
|
Style = GradientStopStyle,
|
||||||
|
Content = stop
|
||||||
|
};
|
||||||
|
control.MouseDown += GradientStopOnMouseDown;
|
||||||
|
_stops.Add(stop, control);
|
||||||
|
_stopContainer.Children.Add(control);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<GradientStop> stopsToRemove = new List<GradientStop>();
|
||||||
|
foreach (KeyValuePair<GradientStop, ContentControl> stopPair in _stops)
|
||||||
|
if (!gradientStops.Contains(stopPair.Key))
|
||||||
|
{
|
||||||
|
ContentControl control = stopPair.Value;
|
||||||
|
control.MouseDown -= GradientStopOnMouseDown;
|
||||||
|
stopsToRemove.Add(stopPair.Key);
|
||||||
|
_stopContainer.Children.Remove(control);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (GradientStop stop in stopsToRemove)
|
||||||
|
_stops.Remove(stop);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AttachGradient(AbstractGradient gradient) => gradient.GradientChanged += GradientChanged;
|
||||||
|
private void DetachGradient(AbstractGradient gradient) => gradient.GradientChanged -= GradientChanged;
|
||||||
|
|
||||||
|
private void GradientChanged(object o, EventArgs eventArgs)
|
||||||
|
{
|
||||||
|
UpdateGradientPreview();
|
||||||
|
UpdateGradientStops();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void OnGradientChanged(DependencyObject dependencyObject,
|
||||||
|
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (!(dependencyObject is GradientEditor ge)) return;
|
||||||
|
|
||||||
|
if (dependencyPropertyChangedEventArgs.OldValue is AbstractGradient oldGradient)
|
||||||
|
ge.DetachGradient(oldGradient);
|
||||||
|
|
||||||
|
if (dependencyPropertyChangedEventArgs.NewValue is AbstractGradient newGradient)
|
||||||
|
ge.AttachGradient(newGradient);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GradientContainerOnMouseDown(object o, MouseButtonEventArgs mouseButtonEventArgs)
|
||||||
|
{
|
||||||
|
if ((mouseButtonEventArgs.ChangedButton != MouseButton.Left) || (Gradient == null) || !CanAddOrDeleteStops) return;
|
||||||
|
|
||||||
|
double offset = mouseButtonEventArgs.GetPosition(_gradientContainer).X / _gradientContainer.ActualWidth;
|
||||||
|
RGB.NET.Core.Color color = Gradient.GetColor(offset);
|
||||||
|
GradientStop newStop = new GradientStop(offset, color);
|
||||||
|
Gradient.GradientStops.Add(newStop);
|
||||||
|
SelectedStop = newStop;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void GradientStopOnMouseDown(object o, MouseButtonEventArgs mouseButtonEventArgs)
|
||||||
|
{
|
||||||
|
if (!((o as ContentControl)?.Content is GradientStop stop) || (Gradient == null)) return;
|
||||||
|
|
||||||
|
if (mouseButtonEventArgs.ChangedButton == MouseButton.Right)
|
||||||
|
{
|
||||||
|
if (CanAddOrDeleteStops)
|
||||||
|
Gradient.GradientStops.Remove(stop);
|
||||||
|
}
|
||||||
|
else if (mouseButtonEventArgs.ChangedButton == MouseButton.Left)
|
||||||
|
{
|
||||||
|
SelectedStop = stop;
|
||||||
|
_draggingStop = (ContentControl)o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseMove(MouseEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnMouseMove(e);
|
||||||
|
|
||||||
|
if (_draggingStop?.Content is GradientStop stop)
|
||||||
|
{
|
||||||
|
double location = e.GetPosition(_gradientContainer).X;
|
||||||
|
stop.Offset = (location / _gradientContainer.ActualWidth).Clamp(0, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseLeave(MouseEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnMouseLeave(e);
|
||||||
|
|
||||||
|
_draggingStop = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
|
||||||
|
{
|
||||||
|
base.OnMouseLeftButtonUp(e);
|
||||||
|
|
||||||
|
_draggingStop = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void SelectedStopChanged(DependencyObject dependencyObject,
|
||||||
|
DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
|
||||||
|
{
|
||||||
|
if (!(dependencyObject is GradientEditor gradientEditor)) return;
|
||||||
|
|
||||||
|
if (gradientEditor._adorner != null)
|
||||||
|
gradientEditor._adornerLayer.Remove(gradientEditor._adorner);
|
||||||
|
|
||||||
|
if (dependencyPropertyChangedEventArgs.OldValue is GradientStop oldStop)
|
||||||
|
{
|
||||||
|
if (gradientEditor._stops.TryGetValue(oldStop, out ContentControl oldcontrol))
|
||||||
|
SetIsSelected(oldcontrol, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dependencyPropertyChangedEventArgs.NewValue is GradientStop stop)
|
||||||
|
{
|
||||||
|
ContentControl stopContainer = gradientEditor._stops[stop];
|
||||||
|
SetIsSelected(stopContainer, true);
|
||||||
|
|
||||||
|
if (gradientEditor._adornerLayer != null)
|
||||||
|
{
|
||||||
|
ContentControl contentControl = new ContentControl
|
||||||
|
{
|
||||||
|
ContentTemplate = gradientEditor.ColorSelectorTemplate,
|
||||||
|
Content = stop
|
||||||
|
};
|
||||||
|
|
||||||
|
ColorPickerAdorner adorner = new ColorPickerAdorner(stopContainer, contentControl);
|
||||||
|
gradientEditor._adorner = adorner;
|
||||||
|
gradientEditor._adornerLayer.Add(adorner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WindowMouseDown(object o, MouseButtonEventArgs mouseButtonEventArgs)
|
||||||
|
{
|
||||||
|
if ((_adorner != null) && (VisualTreeHelper.HitTest(_adorner, mouseButtonEventArgs.GetPosition(_adorner)) == null))
|
||||||
|
SelectedStop = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ColorPickerAdorner : Adorner
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private readonly VisualCollection _visualChildren;
|
||||||
|
private readonly FrameworkElement _colorSelector;
|
||||||
|
protected override int VisualChildrenCount => 1;
|
||||||
|
protected override Visual GetVisualChild(int index) => _colorSelector;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public ColorPickerAdorner(UIElement adornedElement, FrameworkElement colorSelector)
|
||||||
|
: base(adornedElement)
|
||||||
|
{
|
||||||
|
this._colorSelector = colorSelector;
|
||||||
|
|
||||||
|
_visualChildren = new VisualCollection(this) { colorSelector };
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
protected override Size ArrangeOverride(Size finalSize)
|
||||||
|
{
|
||||||
|
Window referenceWindow = Window.GetWindow(AdornedElement);
|
||||||
|
Point referenceLocation = AdornedElement.TranslatePoint(new Point(0, 0), referenceWindow);
|
||||||
|
|
||||||
|
double referenceWidth = ((FrameworkElement)AdornedElement).ActualWidth / 2.0;
|
||||||
|
double referenceHeight = ((FrameworkElement)AdornedElement).Height;
|
||||||
|
double referenceX = referenceLocation.X + referenceWidth;
|
||||||
|
double halfWidth = finalSize.Width / 2.0;
|
||||||
|
double maxOffset = referenceWindow.Width - halfWidth;
|
||||||
|
|
||||||
|
double offset = (referenceX < halfWidth ? referenceX
|
||||||
|
: (((referenceX + (referenceWidth * 2)) > maxOffset)
|
||||||
|
? halfWidth - ((maxOffset - referenceX) - (referenceWidth * 2))
|
||||||
|
: halfWidth));
|
||||||
|
|
||||||
|
_colorSelector.Arrange(new Rect(new Point(referenceWidth - offset, referenceHeight), finalSize));
|
||||||
|
return _colorSelector.RenderSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Size MeasureOverride(Size constraint)
|
||||||
|
{
|
||||||
|
_colorSelector.Measure(constraint);
|
||||||
|
return _colorSelector.DesiredSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
51
RGBSync+/Controls/ImageButton.cs
Normal file
51
RGBSync+/Controls/ImageButton.cs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Controls
|
||||||
|
{
|
||||||
|
public class ImageButton : Button
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
|
||||||
|
public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(
|
||||||
|
"Image", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
|
||||||
|
|
||||||
|
public ImageSource Image
|
||||||
|
{
|
||||||
|
get => (ImageSource)GetValue(ImageProperty);
|
||||||
|
set => SetValue(ImageProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty HoverImageProperty = DependencyProperty.Register(
|
||||||
|
"HoverImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
|
||||||
|
|
||||||
|
public ImageSource HoverImage
|
||||||
|
{
|
||||||
|
get => (ImageSource)GetValue(HoverImageProperty);
|
||||||
|
set => SetValue(HoverImageProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static readonly DependencyProperty PressedImageProperty = DependencyProperty.Register(
|
||||||
|
"PressedImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
|
||||||
|
|
||||||
|
public ImageSource PressedImage
|
||||||
|
{
|
||||||
|
get => (ImageSource)GetValue(PressedImageProperty);
|
||||||
|
set => SetValue(PressedImageProperty, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ReSharper restore InconsistentNaming
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
static ImageButton()
|
||||||
|
{
|
||||||
|
DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
21
RGBSync+/Converter/BoolToVisibilityConverter.cs
Normal file
21
RGBSync+/Converter/BoolToVisibilityConverter.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Converter
|
||||||
|
{
|
||||||
|
[ValueConversion(typeof(bool), typeof(Visibility))]
|
||||||
|
public class BoolToVisibilityConverter : IValueConverter
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
=> (value as bool?) == true ? Visibility.Visible
|
||||||
|
: (string.Equals(parameter?.ToString(), "true", StringComparison.OrdinalIgnoreCase) ? Visibility.Hidden : Visibility.Collapsed);
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => value as Visibility? == Visibility.Visible;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
18
RGBSync+/Converter/EqualsToBoolConverter.cs
Normal file
18
RGBSync+/Converter/EqualsToBoolConverter.cs
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Converter
|
||||||
|
{
|
||||||
|
[ValueConversion(typeof(object), typeof(bool))]
|
||||||
|
public class EqualsToBoolConverter : IValueConverter
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => Equals(value, parameter);
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
20
RGBSync+/Converter/NullToVisibilityConverter.cs
Normal file
20
RGBSync+/Converter/NullToVisibilityConverter.cs
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Converter
|
||||||
|
{
|
||||||
|
[ValueConversion(typeof(object), typeof(Visibility))]
|
||||||
|
public class NullToVisibilityConverter : IValueConverter
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
=> (value == null) == (string.Equals(parameter?.ToString(), "true", StringComparison.OrdinalIgnoreCase)) ? Visibility.Visible : Visibility.Hidden;
|
||||||
|
|
||||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
61
RGBSync+/Converter/ScrollOffsetToOpacityMaskConverter.cs
Normal file
61
RGBSync+/Converter/ScrollOffsetToOpacityMaskConverter.cs
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using System.Windows.Media;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Converter
|
||||||
|
{
|
||||||
|
public class ScrollOffsetToOpacityMaskConverter : IMultiValueConverter
|
||||||
|
{
|
||||||
|
#region Constants
|
||||||
|
|
||||||
|
private static readonly Color TRANSPARENT = Color.FromArgb(0, 0, 0, 0);
|
||||||
|
private static readonly Color OPAQUE = Color.FromArgb(255, 0, 0, 0);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
double offset = double.Parse(values[0].ToString());
|
||||||
|
double maxHeight = double.Parse(values[1].ToString());
|
||||||
|
double height = double.Parse(values[2].ToString());
|
||||||
|
|
||||||
|
double transparencyHeight = double.Parse(parameter.ToString());
|
||||||
|
double transparencyFactor = (transparencyHeight - 6) / height;
|
||||||
|
double transparencyFadeFactor = (transparencyHeight + 4) / height;
|
||||||
|
|
||||||
|
bool top = !(Math.Abs(offset) < float.Epsilon);
|
||||||
|
bool bot = !(Math.Abs(offset - maxHeight) < float.Epsilon);
|
||||||
|
|
||||||
|
if (!top && !bot) return new SolidColorBrush(OPAQUE);
|
||||||
|
|
||||||
|
GradientStopCollection gradientStops = new GradientStopCollection();
|
||||||
|
if (top)
|
||||||
|
{
|
||||||
|
gradientStops.Add(new GradientStop(TRANSPARENT, 0.0));
|
||||||
|
gradientStops.Add(new GradientStop(TRANSPARENT, transparencyFactor));
|
||||||
|
gradientStops.Add(new GradientStop(OPAQUE, transparencyFadeFactor));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gradientStops.Add(new GradientStop(OPAQUE, 0.0));
|
||||||
|
|
||||||
|
if (bot)
|
||||||
|
{
|
||||||
|
gradientStops.Add(new GradientStop(OPAQUE, 1.0 - transparencyFadeFactor));
|
||||||
|
gradientStops.Add(new GradientStop(TRANSPARENT, 1.0 - transparencyFactor));
|
||||||
|
gradientStops.Add(new GradientStop(TRANSPARENT, 1.0));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
gradientStops.Add(new GradientStop(OPAQUE, 1.0));
|
||||||
|
|
||||||
|
return new LinearGradientBrush(gradientStops, new Point(0.5, 0.0), new Point(0.5, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotSupportedException();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
29
RGBSync+/Converter/ScrollOffsetToVisibilityConverter.cs
Normal file
29
RGBSync+/Converter/ScrollOffsetToVisibilityConverter.cs
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Data;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Converter
|
||||||
|
{
|
||||||
|
// Based on: http://stackoverflow.com/a/28679767
|
||||||
|
public class ScrollOffsetToVisibilityConverter : IMultiValueConverter
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
|
bool top = "top".Equals(parameter?.ToString(), StringComparison.OrdinalIgnoreCase);
|
||||||
|
|
||||||
|
double offset = double.Parse(values[0].ToString());
|
||||||
|
double maxHeight = double.Parse(values[1].ToString());
|
||||||
|
|
||||||
|
return (top && Math.Abs(offset) < float.Epsilon) || (!top && Math.Abs(offset - maxHeight) < float.Epsilon)
|
||||||
|
? Visibility.Collapsed
|
||||||
|
: Visibility.Visible;
|
||||||
|
}
|
||||||
|
|
||||||
|
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotSupportedException();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
77
RGBSync+/Helper/ActionCommand.cs
Normal file
77
RGBSync+/Helper/ActionCommand.cs
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Helper
|
||||||
|
{
|
||||||
|
public class ActionCommand : ICommand
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private readonly Func<bool> _canExecute;
|
||||||
|
private readonly Action _command;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
|
||||||
|
public event EventHandler CanExecuteChanged;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public ActionCommand(Action command, Func<bool> canExecute = null)
|
||||||
|
{
|
||||||
|
this._command = command;
|
||||||
|
this._canExecute = canExecute;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;
|
||||||
|
|
||||||
|
public void Execute(object parameter) => _command?.Invoke();
|
||||||
|
|
||||||
|
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, new EventArgs());
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ActionCommand<T> : ICommand
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private readonly Func<T, bool> _canExecute;
|
||||||
|
private readonly Action<T> _command;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events
|
||||||
|
|
||||||
|
public event EventHandler CanExecuteChanged;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public ActionCommand(Action<T> command, Func<T, bool> canExecute = null)
|
||||||
|
{
|
||||||
|
this._command = command;
|
||||||
|
this._canExecute = canExecute;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public bool CanExecute(object parameter) => _canExecute?.Invoke((T)parameter) ?? true;
|
||||||
|
|
||||||
|
public void Execute(object parameter) => _command?.Invoke((T)parameter);
|
||||||
|
|
||||||
|
public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, new EventArgs());
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
23
RGBSync+/Helper/ExceptionExtension.cs
Normal file
23
RGBSync+/Helper/ExceptionExtension.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Helper
|
||||||
|
{
|
||||||
|
public static class ExceptionExtension
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public static string GetFullMessage(this Exception ex, string message = "")
|
||||||
|
{
|
||||||
|
if (ex == null) return string.Empty;
|
||||||
|
|
||||||
|
message += ex.Message;
|
||||||
|
|
||||||
|
if (ex.InnerException != null)
|
||||||
|
message += "\r\nInnerException: " + GetFullMessage(ex.InnerException);
|
||||||
|
|
||||||
|
return message;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
15
RGBSync+/Helper/MathHelper.cs
Normal file
15
RGBSync+/Helper/MathHelper.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Helper
|
||||||
|
{
|
||||||
|
public static class MathHelper
|
||||||
|
{
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
public static double Clamp(double value, double min, double max) => Math.Max(min, Math.Min(max, value));
|
||||||
|
public static float Clamp(float value, float min, float max) => (float)Clamp((double)value, min, max);
|
||||||
|
public static int Clamp(int value, int min, int max) => Math.Max(min, Math.Min(max, value));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
21
RGBSync+/Helper/RGBNetExtension.cs
Normal file
21
RGBSync+/Helper/RGBNetExtension.cs
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
using RGBSyncPlus.Model;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Helper
|
||||||
|
{
|
||||||
|
public static class RGBNetExtension
|
||||||
|
{
|
||||||
|
public static string GetDeviceName(this IRGBDevice device) => $"{device.DeviceInfo.Manufacturer} {device.DeviceInfo.Model} ({device.DeviceInfo.DeviceType})";
|
||||||
|
|
||||||
|
public static IEnumerable<Led> GetLeds(this IEnumerable<SyncLed> syncLeds)
|
||||||
|
=> syncLeds.Select(GetLed).Where(led => led != null);
|
||||||
|
|
||||||
|
public static Led GetLed(this SyncLed syncLed)
|
||||||
|
{
|
||||||
|
if (syncLed == null) return null;
|
||||||
|
return RGBSurface.Instance.Leds.FirstOrDefault(l => (l.Id == syncLed.LedId) && (l.Device.GetDeviceName() == syncLed.Device));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
48
RGBSync+/Model/SyncGroup.cs
Normal file
48
RGBSync+/Model/SyncGroup.cs
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.Collections.Specialized;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
using RGB.NET.Groups;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Model
|
||||||
|
{
|
||||||
|
public class SyncGroup : AbstractBindable
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
public string DisplayName => string.IsNullOrWhiteSpace(Name) ? "(unnamed)" : Name;
|
||||||
|
|
||||||
|
private string _name;
|
||||||
|
public string Name
|
||||||
|
{
|
||||||
|
get => _name;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _name, value))
|
||||||
|
OnPropertyChanged(nameof(DisplayName));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private SyncLed _syncLed;
|
||||||
|
public SyncLed SyncLed
|
||||||
|
{
|
||||||
|
get => _syncLed;
|
||||||
|
set => SetProperty(ref _syncLed, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObservableCollection<SyncLed> _leds = new ObservableCollection<SyncLed>();
|
||||||
|
public ObservableCollection<SyncLed> Leds
|
||||||
|
{
|
||||||
|
get => _leds;
|
||||||
|
set => SetProperty(ref _leds, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public ListLedGroup LedGroup { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public NotifyCollectionChangedEventHandler LedsChangedEventHandler { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
80
RGBSync+/Model/SyncLed.cs
Normal file
80
RGBSync+/Model/SyncLed.cs
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
using Newtonsoft.Json;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
using RGBSyncPlus.Helper;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Model
|
||||||
|
{
|
||||||
|
public class SyncLed : AbstractBindable
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
private string _device;
|
||||||
|
public string Device
|
||||||
|
{
|
||||||
|
get => _device;
|
||||||
|
set => SetProperty(ref _device, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private LedId _ledId;
|
||||||
|
public LedId LedId
|
||||||
|
{
|
||||||
|
get => _ledId;
|
||||||
|
set => SetProperty(ref _ledId, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Led _led;
|
||||||
|
[JsonIgnore]
|
||||||
|
public Led Led
|
||||||
|
{
|
||||||
|
get => _led;
|
||||||
|
set => SetProperty(ref _led, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public SyncLed()
|
||||||
|
{ }
|
||||||
|
|
||||||
|
public SyncLed(string device, LedId ledId)
|
||||||
|
{
|
||||||
|
this.Device = device;
|
||||||
|
this.LedId = ledId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SyncLed(Led led)
|
||||||
|
{
|
||||||
|
this.Device = led.Device.GetDeviceName();
|
||||||
|
this.LedId = led.Id;
|
||||||
|
this.Led = led;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
protected bool Equals(SyncLed other) => string.Equals(_device, other._device) && (_ledId == other._ledId);
|
||||||
|
|
||||||
|
public override bool Equals(object obj)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(null, obj)) return false;
|
||||||
|
if (ReferenceEquals(this, obj)) return true;
|
||||||
|
if (obj.GetType() != this.GetType()) return false;
|
||||||
|
return Equals((SyncLed)obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override int GetHashCode()
|
||||||
|
{
|
||||||
|
unchecked
|
||||||
|
{
|
||||||
|
return ((_device != null ? _device.GetHashCode() : 0) * 397) ^ (int)_ledId;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator ==(SyncLed left, SyncLed right) => Equals(left, right);
|
||||||
|
public static bool operator !=(SyncLed left, SyncLed right) => !Equals(left, right);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
55
RGBSync+/Properties/AssemblyInfo.cs
Normal file
55
RGBSync+/Properties/AssemblyInfo.cs
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Resources;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("RGBSync+")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("RGBSync+")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2018")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
//In order to begin building localizable applications, set
|
||||||
|
//<UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
|
||||||
|
//inside a <PropertyGroup>. For example, if you are using US english
|
||||||
|
//in your source files, set the <UICulture> to en-US. Then uncomment
|
||||||
|
//the NeutralResourceLanguage attribute below. Update the "en-US" in
|
||||||
|
//the line below to match the UICulture setting in the project file.
|
||||||
|
|
||||||
|
//[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
|
||||||
|
|
||||||
|
|
||||||
|
[assembly: ThemeInfo(
|
||||||
|
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||||
|
//(used if a resource is not found in the page,
|
||||||
|
// or application resource dictionaries)
|
||||||
|
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||||
|
//(used if a resource is not found in the page,
|
||||||
|
// app, or any theme specific resource dictionaries)
|
||||||
|
)]
|
||||||
|
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
63
RGBSync+/Properties/Resources.Designer.cs
generated
Normal file
63
RGBSync+/Properties/Resources.Designer.cs
generated
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Properties {
|
||||||
|
using System;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// A strongly-typed resource class, for looking up localized strings, etc.
|
||||||
|
/// </summary>
|
||||||
|
// This class was auto-generated by the StronglyTypedResourceBuilder
|
||||||
|
// class via a tool like ResGen or Visual Studio.
|
||||||
|
// To add or remove a member, edit your .ResX file then rerun ResGen
|
||||||
|
// with the /str option, or rebuild your VS project.
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
internal class Resources {
|
||||||
|
|
||||||
|
private static global::System.Resources.ResourceManager resourceMan;
|
||||||
|
|
||||||
|
private static global::System.Globalization.CultureInfo resourceCulture;
|
||||||
|
|
||||||
|
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
|
||||||
|
internal Resources() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the cached ResourceManager instance used by this class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Resources.ResourceManager ResourceManager {
|
||||||
|
get {
|
||||||
|
if (object.ReferenceEquals(resourceMan, null)) {
|
||||||
|
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RGBSyncPlus.Properties.Resources", typeof(Resources).Assembly);
|
||||||
|
resourceMan = temp;
|
||||||
|
}
|
||||||
|
return resourceMan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Overrides the current thread's CurrentUICulture property for all
|
||||||
|
/// resource lookups using this strongly typed resource class.
|
||||||
|
/// </summary>
|
||||||
|
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
|
||||||
|
internal static global::System.Globalization.CultureInfo Culture {
|
||||||
|
get {
|
||||||
|
return resourceCulture;
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
resourceCulture = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
117
RGBSync+/Properties/Resources.resx
Normal file
117
RGBSync+/Properties/Resources.resx
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||||
|
<xsd:element name="root" msdata:IsDataSet="true">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:choice maxOccurs="unbounded">
|
||||||
|
<xsd:element name="metadata">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="assembly">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:attribute name="alias" type="xsd:string" />
|
||||||
|
<xsd:attribute name="name" type="xsd:string" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="data">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||||
|
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||||
|
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
<xsd:element name="resheader">
|
||||||
|
<xsd:complexType>
|
||||||
|
<xsd:sequence>
|
||||||
|
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||||
|
</xsd:sequence>
|
||||||
|
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:choice>
|
||||||
|
</xsd:complexType>
|
||||||
|
</xsd:element>
|
||||||
|
</xsd:schema>
|
||||||
|
<resheader name="resmimetype">
|
||||||
|
<value>text/microsoft-resx</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="version">
|
||||||
|
<value>2.0</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="reader">
|
||||||
|
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
<resheader name="writer">
|
||||||
|
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||||
|
</resheader>
|
||||||
|
</root>
|
||||||
26
RGBSync+/Properties/Settings.Designer.cs
generated
Normal file
26
RGBSync+/Properties/Settings.Designer.cs
generated
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
// <auto-generated>
|
||||||
|
// This code was generated by a tool.
|
||||||
|
// Runtime Version:4.0.30319.42000
|
||||||
|
//
|
||||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||||
|
// the code is regenerated.
|
||||||
|
// </auto-generated>
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Properties {
|
||||||
|
|
||||||
|
|
||||||
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
|
||||||
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
|
|
||||||
|
public static Settings Default {
|
||||||
|
get {
|
||||||
|
return defaultInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
RGBSync+/Properties/Settings.settings
Normal file
7
RGBSync+/Properties/Settings.settings
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||||
|
<Profiles>
|
||||||
|
<Profile Name="(Default)" />
|
||||||
|
</Profiles>
|
||||||
|
<Settings />
|
||||||
|
</SettingsFile>
|
||||||
236
RGBSync+/RGBSync+.csproj
Normal file
236
RGBSync+/RGBSync+.csproj
Normal file
@ -0,0 +1,236 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{C6BF4357-07D9-496B-9630-A26568D30723}</ProjectGuid>
|
||||||
|
<OutputType>WinExe</OutputType>
|
||||||
|
<RootNamespace>RGBSyncPlus</RootNamespace>
|
||||||
|
<AssemblyName>RGBSync+</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>..\bin\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<PlatformTarget>x86</PlatformTarget>
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>..\bin\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<StartupObject>RGBSyncPlus.App</StartupObject>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup>
|
||||||
|
<ApplicationIcon>Resources\argebee.ico</ApplicationIcon>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Drawing" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xaml">
|
||||||
|
<RequiredTargetFramework>4.0</RequiredTargetFramework>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="WindowsBase" />
|
||||||
|
<Reference Include="PresentationCore" />
|
||||||
|
<Reference Include="PresentationFramework" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ApplicationDefinition Include="App.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</ApplicationDefinition>
|
||||||
|
<Compile Include="ApplicationManager.cs" />
|
||||||
|
<Compile Include="Attached\SliderValue.cs" />
|
||||||
|
<Compile Include="Attached\SliderValueAdorner.cs" />
|
||||||
|
<Compile Include="Brushes\SyncBrush.cs" />
|
||||||
|
<Compile Include="Configuration\AbstractConfiguration.cs" />
|
||||||
|
<Compile Include="Configuration\ColorSerializer.cs" />
|
||||||
|
<Compile Include="Configuration\IConfiguration.cs" />
|
||||||
|
<Compile Include="Configuration\Legacy\ConfigurationUpdates.cs" />
|
||||||
|
<Compile Include="Configuration\Settings.cs" />
|
||||||
|
<Compile Include="Converter\NullToVisibilityConverter.cs" />
|
||||||
|
<Compile Include="Converter\ScrollOffsetToOpacityMaskConverter.cs" />
|
||||||
|
<Compile Include="Converter\ScrollOffsetToVisibilityConverter.cs" />
|
||||||
|
<Compile Include="Helper\ActionCommand.cs" />
|
||||||
|
<Compile Include="Helper\RGBNetExtension.cs" />
|
||||||
|
<Compile Include="Helper\ExceptionExtension.cs" />
|
||||||
|
<Compile Include="Helper\MathHelper.cs" />
|
||||||
|
<Compile Include="Model\SyncGroup.cs" />
|
||||||
|
<Compile Include="Model\SyncLed.cs" />
|
||||||
|
<Compile Include="UI\ConfigurationViewModel.cs" />
|
||||||
|
<Compile Include="UI\ConfigurationWindow.xaml.cs">
|
||||||
|
<DependentUpon>ConfigurationWindow.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Controls\BlurredDecorationWindow.cs" />
|
||||||
|
<Compile Include="Controls\ColorSelector.cs" />
|
||||||
|
<Compile Include="Controls\Form.cs" />
|
||||||
|
<Compile Include="Controls\GradientEditor.cs" />
|
||||||
|
<Compile Include="Controls\ImageButton.cs" />
|
||||||
|
<Compile Include="Converter\BoolToVisibilityConverter.cs" />
|
||||||
|
<Compile Include="Converter\EqualsToBoolConverter.cs" />
|
||||||
|
<Compile Include="Styles\CachedResourceDictionary.cs" />
|
||||||
|
<Compile Include="App.xaml.cs">
|
||||||
|
<DependentUpon>App.xaml</DependentUpon>
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Page Include="Styles\TextBox.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\ListBox.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="UI\ConfigurationWindow.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Resources\RGBSync+.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\BlurredDecorationWindow.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\Button.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\ColorSelector.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\ComboBox.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\Form.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\FrameworkElement.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\GradientEditor.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\GroupBox.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\ImageButton.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\Navigation.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\Slider.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\Theme.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
<Page Include="Styles\ToolTip.xaml">
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
</Page>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Properties\Resources.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DesignTime>True</DesignTime>
|
||||||
|
<DependentUpon>Resources.resx</DependentUpon>
|
||||||
|
</Compile>
|
||||||
|
<Compile Include="Properties\Settings.Designer.cs">
|
||||||
|
<AutoGen>True</AutoGen>
|
||||||
|
<DependentUpon>Settings.settings</DependentUpon>
|
||||||
|
<DesignTimeSharedInput>True</DesignTimeSharedInput>
|
||||||
|
</Compile>
|
||||||
|
<EmbeddedResource Include="Properties\Resources.resx">
|
||||||
|
<Generator>ResXFileCodeGenerator</Generator>
|
||||||
|
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
|
||||||
|
</EmbeddedResource>
|
||||||
|
<None Include="Properties\Settings.settings">
|
||||||
|
<Generator>SettingsSingleFileGenerator</Generator>
|
||||||
|
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
|
||||||
|
</None>
|
||||||
|
<Resource Include="Resources\font.ttf" />
|
||||||
|
<Resource Include="Resources\navigation.ttf" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<None Include="App.config" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="gong-wpf-dragdrop">
|
||||||
|
<Version>1.1.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Hardcodet.NotifyIcon.Wpf">
|
||||||
|
<Version>1.0.8</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="Newtonsoft.Json">
|
||||||
|
<Version>11.0.2</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="RGB.NET.Brushes">
|
||||||
|
<Version>0.0.1.54</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="RGB.NET.Core">
|
||||||
|
<Version>0.0.1.54</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="RGB.NET.Decorators">
|
||||||
|
<Version>0.0.1.54</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="RGB.NET.Groups">
|
||||||
|
<Version>0.0.1.54</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="System.ValueTuple">
|
||||||
|
<Version>4.5.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
<PackageReference Include="WPFTransitionals">
|
||||||
|
<Version>1.0.0</Version>
|
||||||
|
</PackageReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Resource Include="Resources\argebee.ico" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Resource Include="Resources\background.png" />
|
||||||
|
<Resource Include="Resources\close.png" />
|
||||||
|
<Resource Include="Resources\minimize.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Resource Include="Resources\arrow_down.png" />
|
||||||
|
<Resource Include="Resources\arrow_up.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
25
RGBSync+/RGBSync+.sln
Normal file
25
RGBSync+/RGBSync+.sln
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio 15
|
||||||
|
VisualStudioVersion = 15.0.27703.2018
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RGBSync+", "RGBSync+.csproj", "{C6BF4357-07D9-496B-9630-A26568D30723}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{C6BF4357-07D9-496B-9630-A26568D30723}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C6BF4357-07D9-496B-9630-A26568D30723}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C6BF4357-07D9-496B-9630-A26568D30723}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C6BF4357-07D9-496B-9630-A26568D30723}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {3AD1163D-9F77-43AB-A3BA-38C1B9CCBA87}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
42
RGBSync+/Resources/RGBSync+.xaml
Normal file
42
RGBSync+/Resources/RGBSync+.xaml
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:ui="clr-namespace:RGBSyncPlus.UI"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles"
|
||||||
|
xmlns:controls="clr-namespace:RGBSyncPlus.Controls"
|
||||||
|
xmlns:converter="clr-namespace:RGBSyncPlus.Converter">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/BlurredDecorationWindow.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/ImageButton.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Form.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/GroupBox.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/ToolTip.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/ComboBox.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Button.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/ListBox.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Slider.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/TextBox.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/ColorSelector.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/GradientEditor.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<converter:EqualsToBoolConverter x:Key="EqualsToBoolConverter" />
|
||||||
|
<converter:BoolToVisibilityConverter x:Key="BoolToVisibilityConverter" />
|
||||||
|
<converter:NullToVisibilityConverter x:Key="NullToVisibilityConverter" />
|
||||||
|
|
||||||
|
<Style TargetType="{x:Type controls:BlurredDecorationWindow}" BasedOn="{StaticResource StyleBlurredDecorationWindow}" />
|
||||||
|
<Style TargetType="{x:Type ui:ConfigurationWindow}" BasedOn="{StaticResource StyleBlurredDecorationWindow}" />
|
||||||
|
<Style TargetType="{x:Type controls:ImageButton}" BasedOn="{StaticResource StyleImageButton}" />
|
||||||
|
<Style TargetType="{x:Type controls:Form}" BasedOn="{StaticResource StyleForm}" />
|
||||||
|
<Style TargetType="GroupBox" BasedOn="{StaticResource StyleGroupBoxBox}" />
|
||||||
|
<Style TargetType="ToolTip" BasedOn="{StaticResource StyleToolTip}" />
|
||||||
|
<Style TargetType="ComboBox" BasedOn="{StaticResource StyleComboBox}" />
|
||||||
|
<Style TargetType="Button" BasedOn="{StaticResource StyleButton}" />
|
||||||
|
<Style TargetType="ListBox" BasedOn="{StaticResource StyleListBox}" />
|
||||||
|
<Style TargetType="Slider" BasedOn="{StaticResource StyleSlider}" />
|
||||||
|
<Style TargetType="TextBox" BasedOn="{StaticResource StyleTextBox}" />
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
BIN
RGBSync+/Resources/argebee.ico
Normal file
BIN
RGBSync+/Resources/argebee.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 39 KiB |
BIN
RGBSync+/Resources/arrow_down.png
Normal file
BIN
RGBSync+/Resources/arrow_down.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
BIN
RGBSync+/Resources/arrow_up.png
Normal file
BIN
RGBSync+/Resources/arrow_up.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.9 KiB |
BIN
RGBSync+/Resources/background.png
Normal file
BIN
RGBSync+/Resources/background.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 273 KiB |
BIN
RGBSync+/Resources/close.png
Normal file
BIN
RGBSync+/Resources/close.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.7 KiB |
BIN
RGBSync+/Resources/font.ttf
Normal file
BIN
RGBSync+/Resources/font.ttf
Normal file
Binary file not shown.
BIN
RGBSync+/Resources/minimize.png
Normal file
BIN
RGBSync+/Resources/minimize.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
BIN
RGBSync+/Resources/navigation.ttf
Normal file
BIN
RGBSync+/Resources/navigation.ttf
Normal file
Binary file not shown.
126
RGBSync+/Styles/BlurredDecorationWindow.xaml
Normal file
126
RGBSync+/Styles/BlurredDecorationWindow.xaml
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="clr-namespace:RGBSyncPlus.Controls"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/ImageButton.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Theme.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Style x:Key="StyleImageButtonWindow"
|
||||||
|
BasedOn="{StaticResource StyleImageButtonWithOpacity}"
|
||||||
|
TargetType="{x:Type controls:ImageButton}">
|
||||||
|
<Setter Property="Padding" Value="4" />
|
||||||
|
<Setter Property="Margin" Value="4" />
|
||||||
|
<Setter Property="VerticalAlignment" Value="Top" />
|
||||||
|
<Setter Property="Width" Value="24" />
|
||||||
|
<Setter Property="Height" Value="24" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleBlurredDecorationWindow"
|
||||||
|
TargetType="{x:Type controls:BlurredDecorationWindow}">
|
||||||
|
<Setter Property="WindowStyle" Value="None" />
|
||||||
|
<Setter Property="ResizeMode" Value="CanResize" />
|
||||||
|
<Setter Property="AllowsTransparency" Value="True" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="VerticalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="BorderThickness" Value="1,0,1,1" />
|
||||||
|
<Setter Property="DecorationHeight" Value="80" />
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource BrushWindowBorder}" />
|
||||||
|
<Setter Property="Background" Value="{StaticResource BrushWindowBackground}" />
|
||||||
|
<Setter Property="BackgroundImage" Value="pack://application:,,,/Resources/background.png" />
|
||||||
|
<Setter Property="MinWidth" Value="256" />
|
||||||
|
<Setter Property="MinHeight" Value="144" />
|
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource FontSizeDefault}" />
|
||||||
|
<Setter Property="FontFamily" Value="pack://application:,,,/Resources/#Cinzel" />
|
||||||
|
|
||||||
|
<Setter Property="WindowChrome.WindowChrome">
|
||||||
|
<Setter.Value>
|
||||||
|
<WindowChrome CaptionHeight="0" ResizeBorderThickness="5" />
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type controls:BlurredDecorationWindow}">
|
||||||
|
<Grid Background="{TemplateBinding Background}">
|
||||||
|
<Grid Margin="-12,-12,-12,0">
|
||||||
|
<Viewbox HorizontalAlignment="Center" Stretch="UniformToFill">
|
||||||
|
<Image Source="{TemplateBinding BackgroundImage}" />
|
||||||
|
</Viewbox>
|
||||||
|
|
||||||
|
<Border Name="BlurImage">
|
||||||
|
<Border.OpacityMask>
|
||||||
|
<VisualBrush TileMode="None" Stretch="None" AlignmentX="Center" AlignmentY="Center">
|
||||||
|
<VisualBrush.Visual>
|
||||||
|
<Grid Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=Border}}"
|
||||||
|
Height="{Binding ActualHeight, RelativeSource={RelativeSource AncestorType=Border}}">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="12" />
|
||||||
|
<RowDefinition Height="92" />
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<Rectangle Fill="Black" Grid.Row="0" Grid.RowSpan="2" />
|
||||||
|
<Rectangle Fill="Transparent" Grid.Row="2" />
|
||||||
|
</Grid>
|
||||||
|
</VisualBrush.Visual>
|
||||||
|
</VisualBrush>
|
||||||
|
</Border.OpacityMask>
|
||||||
|
|
||||||
|
<Border.Effect>
|
||||||
|
<BlurEffect Radius="30" />
|
||||||
|
</Border.Effect>
|
||||||
|
|
||||||
|
<Viewbox HorizontalAlignment="Center" Stretch="UniformToFill">
|
||||||
|
<Image Source="{TemplateBinding BackgroundImage}" VerticalAlignment="Center" HorizontalAlignment="Center" />
|
||||||
|
</Viewbox>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Border BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}">
|
||||||
|
<DockPanel LastChildFill="True">
|
||||||
|
<Border x:Name="PART_Decoration"
|
||||||
|
DockPanel.Dock="Top"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Height="{TemplateBinding DecorationHeight}"
|
||||||
|
Background="{TemplateBinding BorderBrush}">
|
||||||
|
<DockPanel HorizontalAlignment="Stretch" Margin="4" LastChildFill="False">
|
||||||
|
<controls:ImageButton x:Name="PART_CloseButton"
|
||||||
|
DockPanel.Dock="Right"
|
||||||
|
Style="{StaticResource StyleImageButtonWindow}"
|
||||||
|
Image="pack://application:,,,/Resources/close.png"
|
||||||
|
ToolTip="Close" />
|
||||||
|
|
||||||
|
<controls:ImageButton x:Name="PART_MinimizeButton"
|
||||||
|
DockPanel.Dock="Right"
|
||||||
|
Style="{StaticResource StyleImageButtonWindow}"
|
||||||
|
Image="pack://application:,,,/Resources/minimize.png"
|
||||||
|
ToolTip="Minimize" />
|
||||||
|
|
||||||
|
<controls:ImageButton x:Name="PART_IconButton"
|
||||||
|
DockPanel.Dock="Left"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Margin="8"
|
||||||
|
Style="{StaticResource StyleImageButtonWithOpacity}"
|
||||||
|
Image="{TemplateBinding Icon}"
|
||||||
|
ToolTip="https://github.com/DarthAffe/RGBSyncPlus" />
|
||||||
|
</DockPanel>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<ContentPresenter x:Name="PART_Content" />
|
||||||
|
</DockPanel>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
41
RGBSync+/Styles/Button.xaml
Normal file
41
RGBSync+/Styles/Button.xaml
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/FrameworkElement.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Theme.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Style x:Key="StyleButton"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="Button">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource BrushButtonForeground}" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource FontSizeDefault}" />
|
||||||
|
<Setter Property="FontFamily" Value="pack://application:,,,/Resources/#Cinzel" />
|
||||||
|
<Setter Property="Background" Value="{StaticResource BrushButtonBackground}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource BrushButtonBorder}" />
|
||||||
|
<Setter Property="BorderThickness" Value="2" />
|
||||||
|
<Setter Property="Padding" Value="4,2" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="Button">
|
||||||
|
<Border BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
Background="{TemplateBinding Background}">
|
||||||
|
<ContentPresenter Margin="{TemplateBinding Padding}" />
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="Background" Value="{StaticResource BrushButtonHover}" />
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
56
RGBSync+/Styles/CachedResourceDictionary.cs
Normal file
56
RGBSync+/Styles/CachedResourceDictionary.cs
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Windows;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.Styles
|
||||||
|
{
|
||||||
|
public class CachedResourceDictionary : ResourceDictionary
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
// ReSharper disable InconsistentNaming
|
||||||
|
private static readonly List<string> _cachedDictionaries = new List<string>();
|
||||||
|
private static readonly ResourceDictionary _innerDictionary = new ResourceDictionary();
|
||||||
|
// ReSharper restore
|
||||||
|
|
||||||
|
public new Uri Source
|
||||||
|
{
|
||||||
|
get => null;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
lock (_innerDictionary)
|
||||||
|
{
|
||||||
|
UpdateCache(value);
|
||||||
|
|
||||||
|
MergedDictionaries.Clear();
|
||||||
|
MergedDictionaries.Add(_innerDictionary);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
private static void UpdateCache(Uri source)
|
||||||
|
{
|
||||||
|
string uriPath = source.OriginalString;
|
||||||
|
if (_cachedDictionaries.Contains(uriPath)) return;
|
||||||
|
|
||||||
|
_cachedDictionaries.Add(uriPath);
|
||||||
|
|
||||||
|
ResourceDictionary newDictionary = new ResourceDictionary { Source = new Uri(uriPath, source.IsAbsoluteUri ? UriKind.Absolute : UriKind.Relative) };
|
||||||
|
CopyDictionaryEntries(newDictionary, _innerDictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void CopyDictionaryEntries(IDictionary source, IDictionary target)
|
||||||
|
{
|
||||||
|
foreach (object key in source.Keys)
|
||||||
|
if (!target.Contains(key))
|
||||||
|
target.Add(key, source[key]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
305
RGBSync+/Styles/ColorSelector.xaml
Normal file
305
RGBSync+/Styles/ColorSelector.xaml
Normal file
@ -0,0 +1,305 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="clr-namespace:RGBSyncPlus.Controls"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles">
|
||||||
|
|
||||||
|
<DrawingBrush x:Key="BrushChessboard"
|
||||||
|
TileMode="Tile"
|
||||||
|
Viewport="0,0,16,16"
|
||||||
|
ViewportUnits="Absolute">
|
||||||
|
<DrawingBrush.Drawing>
|
||||||
|
<GeometryDrawing Brush="#FF808080"
|
||||||
|
Geometry="M5,5 L0,5 0,10 5,10 5,5 10,5 10,0 5,0 Z"/>
|
||||||
|
</DrawingBrush.Drawing>
|
||||||
|
</DrawingBrush>
|
||||||
|
|
||||||
|
<DrawingBrush x:Key="BrushChessboardSmall"
|
||||||
|
TileMode="Tile"
|
||||||
|
Viewport="0,0,8,8"
|
||||||
|
ViewportUnits="Absolute">
|
||||||
|
<DrawingBrush.Drawing>
|
||||||
|
<GeometryDrawing Brush="#FF808080"
|
||||||
|
Geometry="M5,5 L0,5 0,10 5,10 5,5 10,5 10,0 5,0 Z"/>
|
||||||
|
</DrawingBrush.Drawing>
|
||||||
|
</DrawingBrush>
|
||||||
|
|
||||||
|
<Style x:Key="StyleSliderLabel"
|
||||||
|
TargetType="TextBlock">
|
||||||
|
<Setter Property="TextAlignment" Value="Right" />
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleSliderValue"
|
||||||
|
TargetType="TextBlock">
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleThumbSlider"
|
||||||
|
TargetType="Thumb">
|
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||||
|
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||||
|
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="Height" Value="NaN" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="Thumb">
|
||||||
|
<Border VerticalAlignment="Stretch"
|
||||||
|
Width="4"
|
||||||
|
SnapsToDevicePixels="True"
|
||||||
|
Opacity="0.66"
|
||||||
|
BorderThickness="1"
|
||||||
|
Background="#FFFFFFFF"
|
||||||
|
BorderBrush="#FF000000" />
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleSlider"
|
||||||
|
TargetType="Slider">
|
||||||
|
|
||||||
|
<Setter Property="Focusable" Value="False" />
|
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||||
|
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||||
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
|
<Setter Property="BorderBrush" Value="#FF000000" />
|
||||||
|
<Setter Property="IsMoveToPointEnabled" Value="True" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="Slider">
|
||||||
|
<Border SnapsToDevicePixels="True"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
Background="#FFFFFFFF">
|
||||||
|
<Border Margin="1"
|
||||||
|
SnapsToDevicePixels="True"
|
||||||
|
Background="{StaticResource BrushChessboardSmall}">
|
||||||
|
<Border SnapsToDevicePixels="True"
|
||||||
|
Background="{TemplateBinding Background}">
|
||||||
|
<Grid x:Name="GridTrackParent" SnapsToDevicePixels="True">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="Auto" MinHeight="{TemplateBinding MinHeight}" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Track x:Name="PART_Track"
|
||||||
|
Grid.Row="1"
|
||||||
|
Width="{Binding ActualWidth, ElementName=GridTrackParent}"
|
||||||
|
Height="{Binding ActualHeight, ElementName=GridTrackParent}">
|
||||||
|
<Track.DecreaseRepeatButton>
|
||||||
|
<RepeatButton Visibility="Hidden" Command="Slider.DecreaseLarge" />
|
||||||
|
</Track.DecreaseRepeatButton>
|
||||||
|
|
||||||
|
<Track.Thumb>
|
||||||
|
<Thumb Style="{StaticResource StyleThumbSlider}" />
|
||||||
|
</Track.Thumb>
|
||||||
|
|
||||||
|
<Track.IncreaseRepeatButton>
|
||||||
|
<RepeatButton Visibility="Hidden" Command="Slider.IncreaseLarge" />
|
||||||
|
</Track.IncreaseRepeatButton>
|
||||||
|
</Track>
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
</Border>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleColorSelector"
|
||||||
|
TargetType="{x:Type controls:ColorSelector}">
|
||||||
|
|
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||||
|
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
<Setter Property="Width" Value="504" />
|
||||||
|
<Setter Property="Height" Value="232" />
|
||||||
|
<Setter Property="FontSize" Value="13" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type controls:ColorSelector}">
|
||||||
|
<Border BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
Background="{TemplateBinding Background}">
|
||||||
|
<DockPanel Margin="{TemplateBinding Padding}">
|
||||||
|
<Border DockPanel.Dock="Left"
|
||||||
|
SnapsToDevicePixels="True"
|
||||||
|
Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="#FF000000"
|
||||||
|
Background="#FFFFFFFF">
|
||||||
|
<Grid x:Name="PART_Selector"
|
||||||
|
Margin="1"
|
||||||
|
SnapsToDevicePixels="True" />
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Slider DockPanel.Dock="Left"
|
||||||
|
Margin="8,0"
|
||||||
|
Height="24"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Style="{StaticResource StyleSlider}"
|
||||||
|
Background="{Binding Background, ElementName=PART_SliderHue}"
|
||||||
|
Minimum="{Binding Minimum, ElementName=PART_SliderHue}"
|
||||||
|
Maximum="{Binding Maximum, ElementName=PART_SliderHue}"
|
||||||
|
Value="{Binding Value, ElementName=PART_SliderHue}">
|
||||||
|
<Slider.LayoutTransform>
|
||||||
|
<RotateTransform CenterX="0.5" CenterY="0.5" Angle="90" />
|
||||||
|
</Slider.LayoutTransform>
|
||||||
|
</Slider>
|
||||||
|
|
||||||
|
<DockPanel>
|
||||||
|
<Grid DockPanel.Dock="Bottom">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="12" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="8" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="8" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="12" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="8" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
<RowDefinition Height="8" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="4" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="4" />
|
||||||
|
<ColumnDefinition Width="28" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="0" Grid.Column="0"
|
||||||
|
Style="{StaticResource StyleSliderLabel}"
|
||||||
|
Text="Alpha:" />
|
||||||
|
<Slider x:Name="PART_SliderAlpha"
|
||||||
|
Grid.Row="0" Grid.Column="2"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Style="{StaticResource StyleSlider}"
|
||||||
|
Minimum="0"
|
||||||
|
Maximum="255" />
|
||||||
|
<TextBlock Grid.Row="0" Grid.Column="4"
|
||||||
|
Style="{StaticResource StyleSliderValue}"
|
||||||
|
Text="{Binding Value, ElementName=PART_SliderAlpha, StringFormat=##0}" />
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="2" Grid.Column="0"
|
||||||
|
Style="{StaticResource StyleSliderLabel}"
|
||||||
|
Text="Hue:" />
|
||||||
|
<Slider x:Name="PART_SliderHue"
|
||||||
|
Grid.Row="2" Grid.Column="2"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Style="{StaticResource StyleSlider}"
|
||||||
|
IsSnapToTickEnabled="False"
|
||||||
|
Minimum="0"
|
||||||
|
Maximum="360" />
|
||||||
|
<TextBlock Grid.Row="2" Grid.Column="4"
|
||||||
|
Style="{StaticResource StyleSliderValue}"
|
||||||
|
Text="{Binding Value, ElementName=PART_SliderHue, StringFormat=##0}" />
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="4" Grid.Column="0"
|
||||||
|
Style="{StaticResource StyleSliderLabel}"
|
||||||
|
Text="Sat:" />
|
||||||
|
<Slider x:Name="PART_SliderSaturation"
|
||||||
|
Grid.Row="4" Grid.Column="2"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Style="{StaticResource StyleSlider}"
|
||||||
|
IsSnapToTickEnabled="False"
|
||||||
|
Minimum="0"
|
||||||
|
Maximum="1" />
|
||||||
|
<TextBlock Grid.Row="4" Grid.Column="4"
|
||||||
|
Style="{StaticResource StyleSliderValue}"
|
||||||
|
Text="{Binding Value, ElementName=PART_SliderSaturation, StringFormat=0.00}" />
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="6" Grid.Column="0"
|
||||||
|
Style="{StaticResource StyleSliderLabel}"
|
||||||
|
Text="Value:" />
|
||||||
|
<Slider x:Name="PART_SliderValue"
|
||||||
|
Grid.Row="6" Grid.Column="2"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Style="{StaticResource StyleSlider}"
|
||||||
|
IsSnapToTickEnabled="False"
|
||||||
|
Minimum="0"
|
||||||
|
Maximum="1" />
|
||||||
|
<TextBlock Grid.Row="6" Grid.Column="4"
|
||||||
|
Style="{StaticResource StyleSliderValue}"
|
||||||
|
Text="{Binding Value, ElementName=PART_SliderValue, StringFormat=0.00}" />
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="8" Grid.Column="0"
|
||||||
|
Style="{StaticResource StyleSliderLabel}"
|
||||||
|
Text="Red:" />
|
||||||
|
<Slider x:Name="PART_SliderRed"
|
||||||
|
Grid.Row="8" Grid.Column="2"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Style="{StaticResource StyleSlider}"
|
||||||
|
TickFrequency="1"
|
||||||
|
IsSnapToTickEnabled="True"
|
||||||
|
Minimum="0"
|
||||||
|
Maximum="255" />
|
||||||
|
<TextBlock Grid.Row="8" Grid.Column="4"
|
||||||
|
Style="{StaticResource StyleSliderValue}"
|
||||||
|
Text="{Binding Value, ElementName=PART_SliderRed, StringFormat=000}" />
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="10" Grid.Column="0"
|
||||||
|
Style="{StaticResource StyleSliderLabel}"
|
||||||
|
Text="Green:" />
|
||||||
|
<Slider x:Name="PART_SliderGreen"
|
||||||
|
Grid.Row="10" Grid.Column="2"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Style="{StaticResource StyleSlider}"
|
||||||
|
TickFrequency="1"
|
||||||
|
IsSnapToTickEnabled="True"
|
||||||
|
Minimum="0"
|
||||||
|
Maximum="255" />
|
||||||
|
<TextBlock Grid.Row="10" Grid.Column="4"
|
||||||
|
Style="{StaticResource StyleSliderValue}"
|
||||||
|
Text="{Binding Value, ElementName=PART_SliderGreen, StringFormat=000}" />
|
||||||
|
|
||||||
|
<TextBlock Grid.Row="12" Grid.Column="0"
|
||||||
|
Style="{StaticResource StyleSliderLabel}"
|
||||||
|
Text="Blue:" />
|
||||||
|
<Slider x:Name="PART_SliderBlue"
|
||||||
|
Grid.Row="12" Grid.Column="2"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
Style="{StaticResource StyleSlider}"
|
||||||
|
TickFrequency="1"
|
||||||
|
IsSnapToTickEnabled="True"
|
||||||
|
Minimum="0"
|
||||||
|
Maximum="255" />
|
||||||
|
<TextBlock Grid.Row="12" Grid.Column="4"
|
||||||
|
Style="{StaticResource StyleSliderValue}"
|
||||||
|
Text="{Binding Value, ElementName=PART_SliderBlue, StringFormat=000}" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<Border HorizontalAlignment="Stretch"
|
||||||
|
Margin="0,0,0,4"
|
||||||
|
SnapsToDevicePixels="True"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="#FF000000"
|
||||||
|
Background="#FFFFFFFF">
|
||||||
|
<Border Margin="1"
|
||||||
|
SnapsToDevicePixels="True"
|
||||||
|
Background="{StaticResource BrushChessboard}">
|
||||||
|
<Rectangle x:Name="PART_Preview"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
SnapsToDevicePixels="True" />
|
||||||
|
</Border>
|
||||||
|
</Border>
|
||||||
|
</DockPanel>
|
||||||
|
</DockPanel>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="{x:Type controls:ColorSelector}" BasedOn="{StaticResource StyleColorSelector}" />
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
144
RGBSync+/Styles/ComboBox.xaml
Normal file
144
RGBSync+/Styles/ComboBox.xaml
Normal file
@ -0,0 +1,144 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/FrameworkElement.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Theme.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Style x:Key="StyleComboBoxItem"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="{x:Type ComboBoxItem}">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource BrushComboBoxForeground}"/>
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type ComboBoxItem}">
|
||||||
|
<Border Name="Border"
|
||||||
|
Padding="2"
|
||||||
|
SnapsToDevicePixels="true">
|
||||||
|
<ContentPresenter />
|
||||||
|
</Border>
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsHighlighted" Value="true">
|
||||||
|
<Setter TargetName="Border" Property="Background" Value="{StaticResource BrushComboBoxHover}"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<ControlTemplate x:Key="ComboBoxToggleButton"
|
||||||
|
TargetType="{x:Type ToggleButton}">
|
||||||
|
<Border x:Name="Border"
|
||||||
|
CornerRadius="0"
|
||||||
|
Background="{StaticResource BrushComboBoxBackground}"
|
||||||
|
BorderBrush="{StaticResource BrushComboBoxBorder}"
|
||||||
|
BorderThickness="1">
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition />
|
||||||
|
<ColumnDefinition Width="20" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Border Grid.Column="0"
|
||||||
|
CornerRadius="0"
|
||||||
|
Margin="1"
|
||||||
|
Background="Transparent"
|
||||||
|
BorderBrush="{StaticResource BrushComboBoxBorder}"
|
||||||
|
BorderThickness="0,0,1,0" />
|
||||||
|
|
||||||
|
<Path x:Name="Arrow"
|
||||||
|
Grid.Column="1"
|
||||||
|
Fill="{StaticResource BrushComboBoxForeground}"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
Data="M0,0 L0,2 L4,6 L8,2 L8,0 L4,4 z" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="ToggleButton.IsMouseOver" Value="true">
|
||||||
|
<Setter TargetName="Border" Property="Background" Value="{StaticResource BrushComboBoxHover}" />
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
|
||||||
|
<ControlTemplate x:Key="ComboBoxTextBox"
|
||||||
|
TargetType="{x:Type TextBox}">
|
||||||
|
<Border x:Name="PART_ContentHost"
|
||||||
|
Focusable="False"
|
||||||
|
Background="{TemplateBinding Background}" />
|
||||||
|
</ControlTemplate>
|
||||||
|
|
||||||
|
<Style x:Key="StyleComboBox"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="{x:Type ComboBox}" >
|
||||||
|
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto"/>
|
||||||
|
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto"/>
|
||||||
|
<Setter Property="ScrollViewer.CanContentScroll" Value="true"/>
|
||||||
|
<Setter Property="MinWidth" Value="120"/>
|
||||||
|
<Setter Property="MinHeight" Value="20"/>
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource BrushComboBoxForeground}"/>
|
||||||
|
<Setter Property="ItemContainerStyle" Value="{StaticResource StyleComboBoxItem}" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type ComboBox}">
|
||||||
|
<Grid>
|
||||||
|
<ToggleButton Name="ToggleButton"
|
||||||
|
Template="{StaticResource ComboBoxToggleButton}"
|
||||||
|
Focusable="False"
|
||||||
|
IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
|
||||||
|
ClickMode="Press">
|
||||||
|
</ToggleButton>
|
||||||
|
<ContentPresenter Name="ContentSite" IsHitTestVisible="False" Content="{TemplateBinding SelectionBoxItem}"
|
||||||
|
ContentTemplate="{TemplateBinding SelectionBoxItemTemplate}"
|
||||||
|
ContentTemplateSelector="{TemplateBinding ItemTemplateSelector}"
|
||||||
|
Margin="6,3,26,3"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Left" />
|
||||||
|
<Popup Name="Popup"
|
||||||
|
Placement="Bottom"
|
||||||
|
IsOpen="{TemplateBinding IsDropDownOpen}"
|
||||||
|
AllowsTransparency="True"
|
||||||
|
Focusable="False"
|
||||||
|
PopupAnimation="Slide">
|
||||||
|
|
||||||
|
<Grid Name="DropDown"
|
||||||
|
SnapsToDevicePixels="True"
|
||||||
|
MinWidth="{TemplateBinding ActualWidth}"
|
||||||
|
MaxHeight="{TemplateBinding MaxDropDownHeight}">
|
||||||
|
<Border x:Name="DropDownBorder"
|
||||||
|
Background="{StaticResource BrushComboBoxBackgroundPopup}"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{StaticResource BrushComboBoxBorder}"/>
|
||||||
|
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True">
|
||||||
|
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" />
|
||||||
|
</ScrollViewer>
|
||||||
|
</Grid>
|
||||||
|
</Popup>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="HasItems" Value="False">
|
||||||
|
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsGrouping" Value="True">
|
||||||
|
<Setter Property="ScrollViewer.CanContentScroll" Value="False"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="True">
|
||||||
|
<Setter TargetName="DropDownBorder" Property="CornerRadius" Value="0"/>
|
||||||
|
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
99
RGBSync+/Styles/Form.xaml
Normal file
99
RGBSync+/Styles/Form.xaml
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles"
|
||||||
|
xmlns:controls="clr-namespace:RGBSyncPlus.Controls">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/FrameworkElement.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Style x:Key="StyleForm"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="{x:Type controls:Form}">
|
||||||
|
<Setter Property="VerticalAlignment" Value="Top" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="LabelWidth" Value="112" />
|
||||||
|
<Setter Property="ElementSpacing" Value="8" />
|
||||||
|
<Setter Property="RowSpacing" Value="8" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleLabelForm"
|
||||||
|
TargetType="Label">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource BrushForeground}" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource FontSizeDefault}" />
|
||||||
|
<Setter Property="FontWeight" Value="Bold" />
|
||||||
|
<Setter Property="FontFamily" Value="pack://application:,,,/Resources/#Cinzel" />
|
||||||
|
<Setter Property="VerticalContentAlignment" Value="Center" />
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Right" />
|
||||||
|
|
||||||
|
<!-- DarthAffe 04.08.2017: Quite a botch, but it works ... -->
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="Label">
|
||||||
|
<TextBlock HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
|
||||||
|
VerticalAlignment="{TemplateBinding VerticalAlignment}"
|
||||||
|
FontFamily="{TemplateBinding FontFamily}"
|
||||||
|
FontSize="{TemplateBinding FontSize}"
|
||||||
|
FontStyle="{TemplateBinding FontStyle}"
|
||||||
|
FontWeight="{TemplateBinding FontWeight}"
|
||||||
|
Foreground="{TemplateBinding Foreground}"
|
||||||
|
Text="{TemplateBinding Content}" />
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleTextBlockForm"
|
||||||
|
TargetType="TextBlock">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource BrushForeground}" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource FontSizeDefault}" />
|
||||||
|
<Setter Property="FontFamily" Value="pack://application:,,,/Resources/#Cinzel" />
|
||||||
|
<Setter Property="VerticalAlignment" Value="Center" />
|
||||||
|
<Setter Property="TextAlignment" Value="Left" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleListBoxItemForm"
|
||||||
|
TargetType="ListBoxItem">
|
||||||
|
<Setter Property="MinWidth" Value="0" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="VerticalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="Padding" Value="0,2" />
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="ListBoxItem">
|
||||||
|
<Border x:Name="Border"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}">
|
||||||
|
<ContentPresenter Margin="{TemplateBinding Padding}"
|
||||||
|
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
|
||||||
|
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" />
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleListBoxForm"
|
||||||
|
TargetType="ListBox">
|
||||||
|
<Setter Property="Focusable" Value="False" />
|
||||||
|
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled" />
|
||||||
|
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
|
||||||
|
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
|
||||||
|
<Setter Property="MinHeight" Value="0" />
|
||||||
|
<Setter Property="MinWidth" Value="0" />
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="VerticalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="VerticalAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
|
<Setter Property="ItemContainerStyle" Value="{StaticResource StyleListBoxItemForm}" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
13
RGBSync+/Styles/FrameworkElement.xaml
Normal file
13
RGBSync+/Styles/FrameworkElement.xaml
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles">
|
||||||
|
|
||||||
|
<Style x:Key="StyleFrameworkElement" TargetType="FrameworkElement">
|
||||||
|
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||||
|
<Setter Property="UseLayoutRounding" Value="True" />
|
||||||
|
<Setter Property="Validation.ErrorTemplate" Value="{x:Null}" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
93
RGBSync+/Styles/GradientEditor.xaml
Normal file
93
RGBSync+/Styles/GradientEditor.xaml
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:controls="clr-namespace:RGBSyncPlus.Controls"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/ColorSelector.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Style x:Key="StyleGradientStop"
|
||||||
|
TargetType="ContentControl">
|
||||||
|
|
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||||
|
<Setter Property="Width" Value="12" />
|
||||||
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
|
<Setter Property="BorderBrush" Value="#FFFFFFFF" />
|
||||||
|
|
||||||
|
<Setter Property="ContentTemplate">
|
||||||
|
<Setter.Value>
|
||||||
|
<DataTemplate DataType="{x:Type GradientStop}">
|
||||||
|
<Grid>
|
||||||
|
<Path Stretch="Fill"
|
||||||
|
Data="M 0.5,0 L 0,0.25 L 0,1 L 1,1 L 1,0.25 Z"
|
||||||
|
StrokeThickness="0"
|
||||||
|
Fill="{StaticResource BrushChessboardSmall}" />
|
||||||
|
<Path Stretch="Fill"
|
||||||
|
Data="M 0.5,0 L 0,0.25 L 0,1 L 1,1 L 1,0.25 Z"
|
||||||
|
Stroke="{Binding BorderBrush, RelativeSource={RelativeSource AncestorType=ContentControl}}"
|
||||||
|
StrokeThickness="{Binding BorderThickness, RelativeSource={RelativeSource AncestorType=ContentControl}}"
|
||||||
|
Fill="{Binding Background, RelativeSource={RelativeSource AncestorType=ContentControl}}" />
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<DataTrigger Binding="{Binding (controls:GradientEditor.IsSelected), RelativeSource={RelativeSource Self}}" Value="True">
|
||||||
|
<Setter Property="BorderBrush" Value="#FF808080" />
|
||||||
|
</DataTrigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleGradientEditor"
|
||||||
|
TargetType="{x:Type controls:GradientEditor}">
|
||||||
|
|
||||||
|
<Setter Property="SnapsToDevicePixels" Value="True" />
|
||||||
|
<Setter Property="OverridesDefaultStyle" Value="True" />
|
||||||
|
<Setter Property="Height" Value="60" />
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
|
<Setter Property="GradientStopStyle" Value="{StaticResource StyleGradientStop}" />
|
||||||
|
|
||||||
|
<Setter Property="ColorSelectorTemplate">
|
||||||
|
<Setter.Value>
|
||||||
|
<DataTemplate DataType="{x:Type GradientStop}">
|
||||||
|
<GroupBox>
|
||||||
|
<controls:ColorSelector Foreground="#FFFFFFFF" SelectedColor="{Binding Color}" />
|
||||||
|
</GroupBox>
|
||||||
|
</DataTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type controls:GradientEditor}">
|
||||||
|
<Border BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
Background="{TemplateBinding Background}">
|
||||||
|
|
||||||
|
<DockPanel>
|
||||||
|
<Border DockPanel.Dock="Bottom"
|
||||||
|
Height="16">
|
||||||
|
<Canvas x:Name="PART_Stops"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Background="Transparent" />
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border Background="{StaticResource BrushChessboard}">
|
||||||
|
<Canvas x:Name="PART_Gradient"
|
||||||
|
VerticalAlignment="Stretch"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Background="Transparent" />
|
||||||
|
</Border>
|
||||||
|
</DockPanel>
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
<Style TargetType="{x:Type controls:GradientEditor}" BasedOn="{StaticResource StyleGradientEditor}" />
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
35
RGBSync+/Styles/GroupBox.xaml
Normal file
35
RGBSync+/Styles/GroupBox.xaml
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/FrameworkElement.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Theme.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Style x:Key="StyleGroupBoxBox"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="GroupBox">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource BrushForeground}" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource FontSizeDefault}" />
|
||||||
|
<Setter Property="FontFamily" Value="pack://application:,,,/Resources/#Cinzel" />
|
||||||
|
<Setter Property="Background" Value="{StaticResource BrushBoxBackground}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource BrushBoxBorder}" />
|
||||||
|
<Setter Property="BorderThickness" Value="2" />
|
||||||
|
<Setter Property="Padding" Value="6,8" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="GroupBox">
|
||||||
|
<Border BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
Background="{TemplateBinding Background}">
|
||||||
|
<ContentPresenter Margin="{TemplateBinding Padding}" />
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
119
RGBSync+/Styles/ImageButton.xaml
Normal file
119
RGBSync+/Styles/ImageButton.xaml
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:buttons="clr-namespace:RGBSyncPlus.Controls"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/FrameworkElement.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Style x:Key="StyleImageButton"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="{x:Type buttons:ImageButton}">
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type buttons:ImageButton}">
|
||||||
|
<Grid Background="Transparent">
|
||||||
|
<Image x:Name="ImageNormal" Margin="{TemplateBinding Padding}"
|
||||||
|
Source="{TemplateBinding Image}" Stretch="Uniform" />
|
||||||
|
<Image x:Name="ImageHover" Margin="{TemplateBinding Padding}"
|
||||||
|
Opacity="0"
|
||||||
|
Source="{TemplateBinding HoverImage}" Stretch="Uniform" />
|
||||||
|
<Image x:Name="ImagePressed" Margin="{TemplateBinding Padding}"
|
||||||
|
Opacity="0"
|
||||||
|
Source="{TemplateBinding PressedImage}" Stretch="Uniform" />
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard TargetName="ImageHover">
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1.0" Duration="0:0:0.150" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard TargetName="ImageHover">
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.250" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsPressed" Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard TargetName="ImagePressed">
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1.0" Duration="0:0:0.150" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard TargetName="ImagePressed">
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.250" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleImageButtonWithOpacity"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="{x:Type buttons:ImageButton}">
|
||||||
|
<Setter Property="Opacity" Value="0.66" />
|
||||||
|
<Setter Property="Padding" Value="0" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type buttons:ImageButton}">
|
||||||
|
<Grid Background="Transparent">
|
||||||
|
<Image x:Name="ImageNormal" Margin="{TemplateBinding Padding}"
|
||||||
|
Source="{TemplateBinding Image}" Stretch="Uniform" />
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1.0" Duration="0:0:0.150" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:0.250" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleImageButtonMenu"
|
||||||
|
BasedOn="{StaticResource StyleImageButton}"
|
||||||
|
TargetType="{x:Type buttons:ImageButton}">
|
||||||
|
<Setter Property="Width" Value="180" />
|
||||||
|
<Setter Property="Height" Value="90" />
|
||||||
|
<Setter Property="Margin" Value="0,16" />
|
||||||
|
<Setter Property="HorizontalAlignment" Value="Center" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
164
RGBSync+/Styles/ListBox.xaml
Normal file
164
RGBSync+/Styles/ListBox.xaml
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles"
|
||||||
|
xmlns:converter="clr-namespace:RGBSyncPlus.Converter">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/FrameworkElement.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Theme.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<converter:ScrollOffsetToOpacityMaskConverter x:Key="ScrollOffsetToOpacityMaskConverter" />
|
||||||
|
<converter:ScrollOffsetToVisibilityConverter x:Key="ScrollOffsetToVisibilityConverter" />
|
||||||
|
|
||||||
|
<Style x:Key="ListBoxScrollViewButtonStyle" TargetType="RepeatButton">
|
||||||
|
<Style.Setters>
|
||||||
|
<Setter Property="Background" Value="{StaticResource BrushListBoxScrollButtonBackground}"></Setter>
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="RepeatButton">
|
||||||
|
<Border x:Name="ButtonBorder"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Width="80"
|
||||||
|
Height="30"
|
||||||
|
BorderThickness="1"
|
||||||
|
BorderBrush="{StaticResource BrushListBoxScrollButtonBorder}"
|
||||||
|
Background="{TemplateBinding Background}">
|
||||||
|
|
||||||
|
<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" />
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style.Setters>
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="Background" Value="{StaticResource BrushListBoxScrollButtonBackgroundHover}" />
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<ControlTemplate x:Key="ListBoxTemplate" TargetType="ListBox">
|
||||||
|
<Grid>
|
||||||
|
<ScrollViewer x:Name="ScrollViewer" CanContentScroll="False" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Hidden">
|
||||||
|
<ScrollViewer.OpacityMask>
|
||||||
|
<MultiBinding Converter="{StaticResource ScrollOffsetToOpacityMaskConverter}" ConverterParameter="30">
|
||||||
|
<Binding ElementName="ScrollViewer" Path="VerticalOffset" />
|
||||||
|
<Binding ElementName="ScrollViewer" Path="ScrollableHeight" />
|
||||||
|
<Binding ElementName="ScrollViewer" Path="ActualHeight" />
|
||||||
|
</MultiBinding>
|
||||||
|
</ScrollViewer.OpacityMask>
|
||||||
|
|
||||||
|
<ItemsPresenter />
|
||||||
|
</ScrollViewer>
|
||||||
|
|
||||||
|
<DockPanel LastChildFill="False">
|
||||||
|
<RepeatButton DockPanel.Dock="Top" Style="{StaticResource ListBoxScrollViewButtonStyle}"
|
||||||
|
Command="{x:Static ScrollBar.LineUpCommand}" CommandTarget="{Binding ElementName=ScrollViewer}">
|
||||||
|
<RepeatButton.Visibility>
|
||||||
|
<MultiBinding Converter="{StaticResource ScrollOffsetToVisibilityConverter}" ConverterParameter="Top">
|
||||||
|
<Binding ElementName="ScrollViewer" Path="VerticalOffset"/>
|
||||||
|
<Binding ElementName="ScrollViewer" Path="ScrollableHeight"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</RepeatButton.Visibility>
|
||||||
|
<RepeatButton.Content>
|
||||||
|
<Image Source="/RGBSync+;component/Resources/arrow_up.png" Stretch="Uniform" />
|
||||||
|
</RepeatButton.Content>
|
||||||
|
</RepeatButton>
|
||||||
|
<RepeatButton DockPanel.Dock="Bottom" Style="{StaticResource ListBoxScrollViewButtonStyle}"
|
||||||
|
Command="{x:Static ScrollBar.LineDownCommand}" CommandTarget="{Binding ElementName=ScrollViewer}">
|
||||||
|
<RepeatButton.Visibility>
|
||||||
|
<MultiBinding Converter="{StaticResource ScrollOffsetToVisibilityConverter}" ConverterParameter="Bottom">
|
||||||
|
<Binding ElementName="ScrollViewer" Path="VerticalOffset"/>
|
||||||
|
<Binding ElementName="ScrollViewer" Path="ScrollableHeight"/>
|
||||||
|
</MultiBinding>
|
||||||
|
</RepeatButton.Visibility>
|
||||||
|
<RepeatButton.Content>
|
||||||
|
<Image Source="/RGBSync+;component/Resources/arrow_down.png" Stretch="Uniform" />
|
||||||
|
</RepeatButton.Content>
|
||||||
|
</RepeatButton>
|
||||||
|
</DockPanel>
|
||||||
|
</Grid>
|
||||||
|
</ControlTemplate>
|
||||||
|
|
||||||
|
<Style x:Key="StyleListBoxItemContainer"
|
||||||
|
TargetType="{x:Type ListBoxItem}">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="ListBoxItem">
|
||||||
|
<Border x:Name="ItemBorder"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
BorderThickness="0"
|
||||||
|
BorderBrush="Transparent"
|
||||||
|
Background="{StaticResource BrushListBoxItemBackground}">
|
||||||
|
<ContentPresenter />
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<ColorAnimation Storyboard.TargetName="ItemBorder"
|
||||||
|
Storyboard.TargetProperty="Background.Color"
|
||||||
|
To="{StaticResource ColorListBoxItemBackgroundHover}"
|
||||||
|
Duration="0:0:0.2" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<ColorAnimation Storyboard.TargetName="ItemBorder"
|
||||||
|
Storyboard.TargetProperty="Background.Color"
|
||||||
|
Duration="0:0:0.25" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsSelected" Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<ColorAnimation Storyboard.TargetName="ItemBorder"
|
||||||
|
Storyboard.TargetProperty="Background.Color"
|
||||||
|
To="{StaticResource ColorListBoxItemBackgroundSelected}"
|
||||||
|
Duration="0:0:0.2" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard>
|
||||||
|
<ColorAnimation Storyboard.TargetName="ItemBorder"
|
||||||
|
Storyboard.TargetProperty="Background.Color"
|
||||||
|
Duration="0:0:0.25" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleListBox"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="ListBox">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource BrushButtonForeground}" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource FontSizeDefault}" />
|
||||||
|
<Setter Property="FontFamily" Value="pack://application:,,,/Resources/#Cinzel" />
|
||||||
|
<Setter Property="Background" Value="{StaticResource BrushButtonBackground}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource BrushButtonBorder}" />
|
||||||
|
<Setter Property="BorderThickness" Value="2" />
|
||||||
|
<Setter Property="Padding" Value="4,2" />
|
||||||
|
|
||||||
|
<Setter Property="ItemContainerStyle" Value="{StaticResource StyleListBoxItemContainer}" />
|
||||||
|
<Setter Property="Template" Value="{StaticResource ListBoxTemplate}" />
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
181
RGBSync+/Styles/Navigation.xaml
Normal file
181
RGBSync+/Styles/Navigation.xaml
Normal file
@ -0,0 +1,181 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles"
|
||||||
|
xmlns:controls="clr-namespace:Transitionals.Controls;assembly=Transitionals"
|
||||||
|
xmlns:transitions="clr-namespace:Transitionals.Transitions;assembly=Transitionals">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/FrameworkElement.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Theme.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<transitions:FadeTransition x:Key="TransitionFade" Duration="0:0:0.200" />
|
||||||
|
|
||||||
|
<Style x:Key="StyleTabControlNavigation"
|
||||||
|
TargetType="TabControl">
|
||||||
|
|
||||||
|
<Setter Property="BorderThickness" Value="0" />
|
||||||
|
<Setter Property="Background" Value="Transparent" />
|
||||||
|
<Setter Property="Margin" Value="0,-72,0,0" />
|
||||||
|
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
|
||||||
|
<Setter Property="VerticalContentAlignment" Value="Stretch" />
|
||||||
|
|
||||||
|
<!-- DarthAffe 04.08.2017: The TabControl is a shitty one to style - if unused parts are removed it throws exceptions ... -->
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="TabControl">
|
||||||
|
<Grid ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition x:Name="ColumnDefinition0" />
|
||||||
|
<ColumnDefinition x:Name="ColumnDefinition1" Width="0" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition x:Name="RowDefinition0" Height="Auto" />
|
||||||
|
<RowDefinition x:Name="RowDefinition1" Height="*" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<TabPanel x:Name="HeaderPanel"
|
||||||
|
Grid.Row="0"
|
||||||
|
Grid.Column="0"
|
||||||
|
Margin="82,2,2,0"
|
||||||
|
Panel.ZIndex="1"
|
||||||
|
IsItemsHost="true"
|
||||||
|
KeyboardNavigation.TabIndex="1" />
|
||||||
|
<Border x:Name="ContentPanel"
|
||||||
|
Grid.Column="0"
|
||||||
|
Grid.Row="1"
|
||||||
|
Margin="4"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
Background="{TemplateBinding Background}"
|
||||||
|
KeyboardNavigation.DirectionalNavigation="Contained"
|
||||||
|
KeyboardNavigation.TabIndex="2"
|
||||||
|
KeyboardNavigation.TabNavigation="Local">
|
||||||
|
<controls:TransitionElement x:Name="PART_SelectedContentHost"
|
||||||
|
Margin="{TemplateBinding Padding}"
|
||||||
|
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
|
||||||
|
Transition="{StaticResource TransitionFade}"
|
||||||
|
Content="{TemplateBinding SelectedContent}" />
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="TabStripPlacement" Value="Bottom">
|
||||||
|
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="1" />
|
||||||
|
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0" />
|
||||||
|
<Setter Property="Height" TargetName="RowDefinition0" Value="*" />
|
||||||
|
<Setter Property="Height" TargetName="RowDefinition1" Value="Auto" />
|
||||||
|
<Setter Property="Margin" TargetName="HeaderPanel" Value="2,0,2,2" />
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="TabStripPlacement" Value="Left">
|
||||||
|
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0" />
|
||||||
|
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0" />
|
||||||
|
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="0" />
|
||||||
|
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="1" />
|
||||||
|
<Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto" />
|
||||||
|
<Setter Property="Width" TargetName="ColumnDefinition1" Value="*" />
|
||||||
|
<Setter Property="Height" TargetName="RowDefinition0" Value="*" />
|
||||||
|
<Setter Property="Height" TargetName="RowDefinition1" Value="0" />
|
||||||
|
<Setter Property="Margin" TargetName="HeaderPanel" Value="2,2,0,2" />
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="TabStripPlacement" Value="Right">
|
||||||
|
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0" />
|
||||||
|
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0" />
|
||||||
|
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="1" />
|
||||||
|
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="0" />
|
||||||
|
<Setter Property="Width" TargetName="ColumnDefinition0" Value="*" />
|
||||||
|
<Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto" />
|
||||||
|
<Setter Property="Height" TargetName="RowDefinition0" Value="*" />
|
||||||
|
<Setter Property="Height" TargetName="RowDefinition1" Value="0" />
|
||||||
|
<Setter Property="Margin" TargetName="HeaderPanel" Value="0,2,2,2" />
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsEnabled" Value="false">
|
||||||
|
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
<Style x:Key="StyleTabItemNavigation"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="TabItem">
|
||||||
|
|
||||||
|
<Setter Property="Height" Value="72" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource FontSizeNavigation}" />
|
||||||
|
<Setter Property="FontFamily" Value="pack://application:,,,/Resources/#Cinzel Decorative" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="TabItem">
|
||||||
|
<Border Margin="8,0"
|
||||||
|
Padding="4"
|
||||||
|
IsHitTestVisible="True"
|
||||||
|
BorderThickness="0"
|
||||||
|
Background="Transparent">
|
||||||
|
<Grid>
|
||||||
|
<TextBlock x:Name="TxtBlurred"
|
||||||
|
VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
FontWeight="Black"
|
||||||
|
Opacity="0"
|
||||||
|
Foreground="{StaticResource BrushNavigationItemBlur}"
|
||||||
|
Text="{TemplateBinding Header}">
|
||||||
|
<TextBlock.Effect>
|
||||||
|
<BlurEffect Radius="{StaticResource DoubleNavigationBlurRadius}" />
|
||||||
|
</TextBlock.Effect>
|
||||||
|
</TextBlock>
|
||||||
|
<TextBlock VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Foreground="{StaticResource BrushNavigationItem}"
|
||||||
|
Text="{TemplateBinding Header}" />
|
||||||
|
</Grid>
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<!--<DataTrigger Binding="{Binding RelativeSource={RelativeSource PreviousData}}" Value="{x:Null}">
|
||||||
|
<Setter Property="Margin" Value="80,0,0,0" />
|
||||||
|
</DataTrigger>-->
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard TargetName="TxtBlurred">
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.5" Duration="0:0:0.150" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard TargetName="TxtBlurred">
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:0.250" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsSelected" Value="True">
|
||||||
|
<Trigger.EnterActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard TargetName="TxtBlurred">
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1.0" Duration="0:0:0.150" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.EnterActions>
|
||||||
|
<Trigger.ExitActions>
|
||||||
|
<BeginStoryboard>
|
||||||
|
<Storyboard TargetName="TxtBlurred">
|
||||||
|
<DoubleAnimation Storyboard.TargetProperty="Opacity" Duration="0:0:0.250" />
|
||||||
|
</Storyboard>
|
||||||
|
</BeginStoryboard>
|
||||||
|
</Trigger.ExitActions>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
<Style BasedOn="{StaticResource StyleTabItemNavigation}" TargetType="TabItem" />
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
31
RGBSync+/Styles/Slider.xaml
Normal file
31
RGBSync+/Styles/Slider.xaml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles"
|
||||||
|
xmlns:attached="clr-namespace:RGBSyncPlus.Attached">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Theme.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Style x:Key="StyleSlider"
|
||||||
|
BasedOn="{StaticResource {x:Type Slider}}"
|
||||||
|
TargetType="Slider">
|
||||||
|
|
||||||
|
<!-- ReSharper disable Xaml.RedundantStyledValue - -->
|
||||||
|
<Setter Property="attached:SliderValue.IsShown" Value="True" />
|
||||||
|
<Setter Property="attached:SliderValue.Background" Value="{StaticResource BrushTooltipBackground}" />
|
||||||
|
<Setter Property="attached:SliderValue.BorderBrush" Value="{StaticResource BrushTooltipBorder}" />
|
||||||
|
<Setter Property="attached:SliderValue.Foreground" Value="{StaticResource BrushTooltipForeground}" />
|
||||||
|
<Setter Property="attached:SliderValue.FontSize" Value="{StaticResource FontSizeTooltip}" />
|
||||||
|
<Setter Property="attached:SliderValue.Font" Value="pack://application:,,,/Resources/#Cinzel" />
|
||||||
|
<!-- ReSharper restore Xaml.RedundantStyledValue -->
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsEnabled" Value="False">
|
||||||
|
<Setter Property="Opacity" Value="0.2" />
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
45
RGBSync+/Styles/TextBox.xaml
Normal file
45
RGBSync+/Styles/TextBox.xaml
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/FrameworkElement.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Theme.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Style x:Key="StyleTextBox"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="TextBox">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource BrushTextBoxForeground}" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource FontSizeDefault}" />
|
||||||
|
<Setter Property="FontFamily" Value="pack://application:,,,/Resources/#Cinzel" />
|
||||||
|
<Setter Property="Background" Value="{StaticResource BrushTextBoxBackground}" />
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource BrushTextBoxBorder}" />
|
||||||
|
<Setter Property="BorderThickness" Value="1" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type TextBoxBase}">
|
||||||
|
<Border Name="Border"
|
||||||
|
Padding="2"
|
||||||
|
BorderThickness="{TemplateBinding BorderThickness}"
|
||||||
|
BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
Background="{TemplateBinding Background}">
|
||||||
|
<ScrollViewer x:Name="PART_ContentHost" />
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
|
||||||
|
<Style.Triggers>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource BrushTextBoxBorderHover}" />
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsFocused" Value="True">
|
||||||
|
<Setter Property="BorderBrush" Value="{StaticResource BrushTextBoxBorderFocused}" />
|
||||||
|
</Trigger>
|
||||||
|
</Style.Triggers>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
75
RGBSync+/Styles/Theme.xaml
Normal file
75
RGBSync+/Styles/Theme.xaml
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:sys="clr-namespace:System;assembly=mscorlib"
|
||||||
|
xmlns:presentationOptions="http://schemas.microsoft.com/winfx/2006/xaml/presentation/options">
|
||||||
|
<!-- ### Colors ### -->
|
||||||
|
<Color x:Key="ColorGainsboro">#FFDCDCDC</Color>
|
||||||
|
<Color x:Key="ColorBuckinghamGray">#FF2A2A2A</Color>
|
||||||
|
<Color x:Key="ColorBuckinghamGrayTransparent">#B82A2A2A</Color>
|
||||||
|
<Color x:Key="ColorJetBlack">#111111</Color>
|
||||||
|
<Color x:Key="ColorJetBlackTransparent">#B8111111</Color>
|
||||||
|
<Color x:Key="ColorJetBlackSuperTransparent">#60111111</Color>
|
||||||
|
<Color x:Key="ColorBlackTransparent">#50000000</Color>
|
||||||
|
<Color x:Key="ColorBananaYellow">#FFE135</Color>
|
||||||
|
|
||||||
|
<!-- ### Brushes ### -->
|
||||||
|
<SolidColorBrush x:Key="BrushBackground" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlack}" />
|
||||||
|
<SolidColorBrush x:Key="BrushForeground" presentationOptions:Freeze="True" Color="{StaticResource ColorGainsboro}" />
|
||||||
|
|
||||||
|
<!-- Window -->
|
||||||
|
<SolidColorBrush x:Key="BrushWindowBorder" presentationOptions:Freeze="True" Color="{StaticResource ColorBlackTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushWindowBackground" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlack}" />
|
||||||
|
|
||||||
|
<!-- Box -->
|
||||||
|
<SolidColorBrush x:Key="BrushBoxBorder" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushBoxBackground" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackSuperTransparent}" />
|
||||||
|
|
||||||
|
<!-- ToolTip -->
|
||||||
|
<SolidColorBrush x:Key="BrushTooltipForeground" presentationOptions:Freeze="True" Color="{StaticResource ColorGainsboro}" />
|
||||||
|
<SolidColorBrush x:Key="BrushTooltipBorder" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlack}" />
|
||||||
|
<SolidColorBrush x:Key="BrushTooltipBackground" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackTransparent}" />
|
||||||
|
|
||||||
|
<!-- ComboBox -->
|
||||||
|
<SolidColorBrush x:Key="BrushComboBoxForeground" presentationOptions:Freeze="True" Color="{StaticResource ColorGainsboro}" />
|
||||||
|
<SolidColorBrush x:Key="BrushComboBoxBackground" presentationOptions:Freeze="True" Color="{StaticResource ColorBuckinghamGrayTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushComboBoxBackgroundPopup" presentationOptions:Freeze="True" Color="{StaticResource ColorBuckinghamGray}" />
|
||||||
|
<SolidColorBrush x:Key="BrushComboBoxBorder" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushComboBoxHover" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlack}" />
|
||||||
|
<SolidColorBrush x:Key="BrushComboBoxBackgroundGroupHeader" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackSuperTransparent}" />
|
||||||
|
|
||||||
|
<!-- Button -->
|
||||||
|
<SolidColorBrush x:Key="BrushButtonForeground" presentationOptions:Freeze="True" Color="{StaticResource ColorGainsboro}" />
|
||||||
|
<SolidColorBrush x:Key="BrushButtonBackground" presentationOptions:Freeze="True" Color="{StaticResource ColorBuckinghamGrayTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushButtonBorder" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushButtonHover" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlack}" />
|
||||||
|
|
||||||
|
<!-- ListBox -->
|
||||||
|
<SolidColorBrush x:Key="BrushListBoxForeground" presentationOptions:Freeze="True" Color="{StaticResource ColorGainsboro}" />
|
||||||
|
<SolidColorBrush x:Key="BrushListBoxScrollButtonBackground" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackSuperTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushListBoxScrollButtonBackgroundHover" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushListBoxScrollButtonBorder" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushListBoxItemBackground" presentationOptions:Freeze="True" Color="#00111111" />
|
||||||
|
<Color x:Key="ColorListBoxItemBackgroundHover">#60111111</Color>
|
||||||
|
<Color x:Key="ColorListBoxItemBackgroundSelected">#B8111111</Color>
|
||||||
|
|
||||||
|
<!-- TextBox -->
|
||||||
|
<SolidColorBrush x:Key="BrushTextBoxForeground" presentationOptions:Freeze="True" Color="{StaticResource ColorGainsboro}" />
|
||||||
|
<SolidColorBrush x:Key="BrushTextBoxBackground" presentationOptions:Freeze="True" Color="{StaticResource ColorBuckinghamGrayTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushTextBoxBorder" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlackTransparent}" />
|
||||||
|
<SolidColorBrush x:Key="BrushTextBoxBorderHover" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlack}" />
|
||||||
|
<SolidColorBrush x:Key="BrushTextBoxBorderFocused" presentationOptions:Freeze="True" Color="{StaticResource ColorJetBlack}" />
|
||||||
|
|
||||||
|
<!-- Navigation -->
|
||||||
|
<SolidColorBrush x:Key="BrushNavigationItem" presentationOptions:Freeze="True" Color="{StaticResource ColorGainsboro}" />
|
||||||
|
<SolidColorBrush x:Key="BrushNavigationItemBlur" presentationOptions:Freeze="True" Color="{StaticResource ColorBananaYellow}" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ### Border'n'stuff ### -->
|
||||||
|
<sys:Double x:Key="DoubleNavigationBlurRadius">40</sys:Double>
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ### Fonts ### -->
|
||||||
|
<sys:Double x:Key="FontSizeDefault">14</sys:Double>
|
||||||
|
<sys:Double x:Key="FontSizeTooltip">14</sys:Double>
|
||||||
|
<sys:Double x:Key="FontSizeNavigation">22</sys:Double>
|
||||||
|
</ResourceDictionary>
|
||||||
31
RGBSync+/Styles/ToolTip.xaml
Normal file
31
RGBSync+/Styles/ToolTip.xaml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<styles:CachedResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles">
|
||||||
|
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/FrameworkElement.xaml" />
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Theme.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
|
||||||
|
<Style x:Key="StyleToolTip"
|
||||||
|
BasedOn="{StaticResource StyleFrameworkElement}"
|
||||||
|
TargetType="{x:Type ToolTip}">
|
||||||
|
<Setter Property="Foreground" Value="{StaticResource BrushTooltipForeground}" />
|
||||||
|
<Setter Property="FontSize" Value="{StaticResource FontSizeTooltip}" />
|
||||||
|
<Setter Property="FontFamily" Value="pack://application:,,,/Resources/#Cinzel" />
|
||||||
|
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="{x:Type ToolTip}">
|
||||||
|
<Border BorderThickness="1"
|
||||||
|
BorderBrush="{StaticResource BrushTooltipBorder}"
|
||||||
|
Background="{StaticResource BrushTooltipBackground}">
|
||||||
|
<ContentPresenter Margin="6,4" />
|
||||||
|
</Border>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
</Style>
|
||||||
|
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
|
||||||
183
RGBSync+/UI/ConfigurationViewModel.cs
Normal file
183
RGBSync+/UI/ConfigurationViewModel.cs
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.ObjectModel;
|
||||||
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Data;
|
||||||
|
using GongSolutions.Wpf.DragDrop;
|
||||||
|
using RGB.NET.Core;
|
||||||
|
using RGBSyncPlus.Helper;
|
||||||
|
using RGBSyncPlus.Model;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.UI
|
||||||
|
{
|
||||||
|
public sealed class ConfigurationViewModel : AbstractBindable, IDropTarget
|
||||||
|
{
|
||||||
|
#region Properties & Fields
|
||||||
|
|
||||||
|
public Version Version => Assembly.GetEntryAssembly().GetName().Version;
|
||||||
|
|
||||||
|
public double UpdateRate
|
||||||
|
{
|
||||||
|
get => 1.0 / ApplicationManager.Instance.UpdateTrigger.UpdateFrequency;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
double val = MathHelper.Clamp(value, 1, 100);
|
||||||
|
ApplicationManager.Instance.Settings.UpdateRate = val;
|
||||||
|
ApplicationManager.Instance.UpdateTrigger.UpdateFrequency = 1.0 / val;
|
||||||
|
OnPropertyChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ObservableCollection<SyncGroup> _syncGroups;
|
||||||
|
public ObservableCollection<SyncGroup> SyncGroups
|
||||||
|
{
|
||||||
|
get => _syncGroups;
|
||||||
|
set => SetProperty(ref _syncGroups, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private SyncGroup _selectedSyncGroup;
|
||||||
|
public SyncGroup SelectedSyncGroup
|
||||||
|
{
|
||||||
|
get => _selectedSyncGroup;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (SetProperty(ref _selectedSyncGroup, value))
|
||||||
|
UpdateLedLists();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private ListCollectionView _availableSyncLeds;
|
||||||
|
public ListCollectionView AvailableSyncLeds
|
||||||
|
{
|
||||||
|
get => _availableSyncLeds;
|
||||||
|
set => SetProperty(ref _availableSyncLeds, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ListCollectionView _availableLeds;
|
||||||
|
public ListCollectionView AvailableLeds
|
||||||
|
{
|
||||||
|
get => _availableLeds;
|
||||||
|
set => SetProperty(ref _availableLeds, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private ListCollectionView _synchronizedLeds;
|
||||||
|
public ListCollectionView SynchronizedLeds
|
||||||
|
{
|
||||||
|
get => _synchronizedLeds;
|
||||||
|
set => SetProperty(ref _synchronizedLeds, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Commands
|
||||||
|
|
||||||
|
private ActionCommand _openHomepageCommand;
|
||||||
|
public ActionCommand OpenHomepageCommand => _openHomepageCommand ?? (_openHomepageCommand = new ActionCommand(OpenHomepage));
|
||||||
|
|
||||||
|
private ActionCommand _addSyncGroupCommand;
|
||||||
|
public ActionCommand AddSyncGroupCommand => _addSyncGroupCommand ?? (_addSyncGroupCommand = new ActionCommand(AddSyncGroup));
|
||||||
|
|
||||||
|
private ActionCommand<SyncGroup> _removeSyncGroupCommand;
|
||||||
|
public ActionCommand<SyncGroup> RemoveSyncGroupCommand => _removeSyncGroupCommand ?? (_removeSyncGroupCommand = new ActionCommand<SyncGroup>(RemoveSyncGroup));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public ConfigurationViewModel()
|
||||||
|
{
|
||||||
|
SyncGroups = new ObservableCollection<SyncGroup>(ApplicationManager.Instance.Settings.SyncGroups);
|
||||||
|
|
||||||
|
AvailableSyncLeds = GetGroupedLedList(RGBSurface.Instance.Leds.Where(x => x.Device.DeviceInfo.SupportsSyncBack));
|
||||||
|
OnPropertyChanged(nameof(AvailableSyncLeds));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Methods
|
||||||
|
|
||||||
|
private ListCollectionView GetGroupedLedList(IEnumerable<Led> leds) => GetGroupedLedList(leds.Select(led => new SyncLed(led)).ToList());
|
||||||
|
|
||||||
|
private ListCollectionView GetGroupedLedList(IList syncLeds)
|
||||||
|
{
|
||||||
|
ListCollectionView collectionView = new ListCollectionView(syncLeds);
|
||||||
|
collectionView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(SyncLed.Device)));
|
||||||
|
collectionView.SortDescriptions.Add(new SortDescription(nameof(SyncLed.Device), ListSortDirection.Ascending));
|
||||||
|
collectionView.SortDescriptions.Add(new SortDescription(nameof(SyncLed.LedId), ListSortDirection.Ascending));
|
||||||
|
collectionView.Refresh();
|
||||||
|
return collectionView;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateLedLists()
|
||||||
|
{
|
||||||
|
SynchronizedLeds = GetGroupedLedList(SelectedSyncGroup.Leds);
|
||||||
|
OnPropertyChanged(nameof(SynchronizedLeds));
|
||||||
|
|
||||||
|
AvailableLeds = GetGroupedLedList(RGBSurface.Instance.Leds.Where(led => !SelectedSyncGroup.Leds.Any(sc => (sc.LedId == led.Id) && (sc.Device == led.Device.GetDeviceName()))));
|
||||||
|
OnPropertyChanged(nameof(AvailableLeds));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OpenHomepage() => Process.Start("https://github.com/DarthAffe/RGBSyncPlus");
|
||||||
|
|
||||||
|
private void AddSyncGroup()
|
||||||
|
{
|
||||||
|
SyncGroup syncGroup = new SyncGroup();
|
||||||
|
SyncGroups.Add(syncGroup);
|
||||||
|
ApplicationManager.Instance.AddSyncGroup(syncGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveSyncGroup(SyncGroup syncGroup)
|
||||||
|
{
|
||||||
|
if (syncGroup == null) return;
|
||||||
|
|
||||||
|
if (MessageBox.Show($"Are you sure that you want to delete the group '{syncGroup.DisplayName}'", "Remove Sync-Group", MessageBoxButton.YesNo) == MessageBoxResult.No)
|
||||||
|
return;
|
||||||
|
|
||||||
|
SyncGroups.Remove(syncGroup);
|
||||||
|
ApplicationManager.Instance.RemoveSyncGroup(syncGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IDropTarget.DragOver(IDropInfo dropInfo)
|
||||||
|
{
|
||||||
|
if ((dropInfo.Data is SyncLed || dropInfo.Data is IEnumerable<SyncLed>) && (dropInfo.TargetCollection is ListCollectionView))
|
||||||
|
{
|
||||||
|
dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;
|
||||||
|
dropInfo.Effects = DragDropEffects.Copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void IDropTarget.Drop(IDropInfo dropInfo)
|
||||||
|
{
|
||||||
|
if (!(dropInfo.TargetCollection is ListCollectionView targetList)) return;
|
||||||
|
|
||||||
|
//HACK DarthAffe 04.06.2018: Super ugly hack - I've no idea how to do this correctly ...
|
||||||
|
ListCollectionView sourceList = targetList == AvailableLeds ? SynchronizedLeds : AvailableLeds;
|
||||||
|
|
||||||
|
if (dropInfo.Data is SyncLed syncLed)
|
||||||
|
{
|
||||||
|
targetList.AddNewItem(syncLed);
|
||||||
|
sourceList.Remove(syncLed);
|
||||||
|
|
||||||
|
targetList.CommitNew();
|
||||||
|
sourceList.CommitEdit();
|
||||||
|
}
|
||||||
|
else if (dropInfo.Data is IEnumerable<SyncLed> syncLeds)
|
||||||
|
{
|
||||||
|
foreach (SyncLed led in syncLeds)
|
||||||
|
{
|
||||||
|
targetList.AddNewItem(led);
|
||||||
|
sourceList.Remove(led);
|
||||||
|
}
|
||||||
|
targetList.CommitNew();
|
||||||
|
sourceList.CommitEdit();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
250
RGBSync+/UI/ConfigurationWindow.xaml
Normal file
250
RGBSync+/UI/ConfigurationWindow.xaml
Normal file
@ -0,0 +1,250 @@
|
|||||||
|
<controls:BlurredDecorationWindow x:Class="RGBSyncPlus.UI.ConfigurationWindow"
|
||||||
|
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:core="clr-namespace:RGB.NET.Core;assembly=RGB.NET.Core"
|
||||||
|
xmlns:ui="clr-namespace:RGBSyncPlus.UI"
|
||||||
|
xmlns:controls="clr-namespace:RGBSyncPlus.Controls"
|
||||||
|
xmlns:styles="clr-namespace:RGBSyncPlus.Styles"
|
||||||
|
xmlns:attached="clr-namespace:RGBSyncPlus.Attached"
|
||||||
|
xmlns:helper="clr-namespace:RGBSyncPlus.Helper"
|
||||||
|
xmlns:dd="urn:gong-wpf-dragdrop"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Title="RGBSync+ # Configuration"
|
||||||
|
Icon="pack://application:,,,/RGBSync+;component/Resources/argebee.ico"
|
||||||
|
IconCommand="{Binding OpenHomepageCommand}"
|
||||||
|
Width="1280" Height="720"
|
||||||
|
Closed="ConfigurationWindow_OnClosed">
|
||||||
|
|
||||||
|
<controls:BlurredDecorationWindow.Resources>
|
||||||
|
<styles:CachedResourceDictionary>
|
||||||
|
<styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
<styles:CachedResourceDictionary Source="/RGBSync+;component/Styles/Navigation.xaml" />
|
||||||
|
</styles:CachedResourceDictionary.MergedDictionaries>
|
||||||
|
</styles:CachedResourceDictionary>
|
||||||
|
</controls:BlurredDecorationWindow.Resources>
|
||||||
|
|
||||||
|
<controls:BlurredDecorationWindow.DataContext>
|
||||||
|
<ui:ConfigurationViewModel />
|
||||||
|
</controls:BlurredDecorationWindow.DataContext>
|
||||||
|
|
||||||
|
<TabControl Style="{StaticResource StyleTabControlNavigation}">
|
||||||
|
<TabItem Header="Sync-Groups">
|
||||||
|
<AdornerDecorator>
|
||||||
|
<DockPanel LastChildFill="True">
|
||||||
|
<GroupBox DockPanel.Dock="Left" Width="260">
|
||||||
|
<DockPanel VerticalAlignment="Top">
|
||||||
|
<Button DockPanel.Dock="Bottom"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="8"
|
||||||
|
Content="New Sync-Group"
|
||||||
|
Command="{Binding AddSyncGroupCommand}" />
|
||||||
|
|
||||||
|
<ListBox ItemsSource="{Binding SyncGroups}"
|
||||||
|
SelectedItem="{Binding SelectedSyncGroup}">
|
||||||
|
<ListBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Grid>
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="Auto" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Button Width="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"
|
||||||
|
ToolTip="Remove"
|
||||||
|
Command="{Binding DataContext.RemoveSyncGroupCommand, RelativeSource={RelativeSource AncestorType={x:Type controls:BlurredDecorationWindow}}}"
|
||||||
|
CommandParameter="{Binding DataContext, RelativeSource={RelativeSource AncestorType=ListBoxItem}}">
|
||||||
|
<Image Source="/RGBSync+;component/Resources/close.png" />
|
||||||
|
</Button>
|
||||||
|
<TextBlock Grid.Column="1" Margin="4" Text="{Binding DisplayName}" />
|
||||||
|
</Grid>
|
||||||
|
</DataTemplate>
|
||||||
|
</ListBox.ItemTemplate>
|
||||||
|
</ListBox>
|
||||||
|
</DockPanel>
|
||||||
|
</GroupBox>
|
||||||
|
|
||||||
|
<DockPanel Margin="8,0,0,0">
|
||||||
|
<GroupBox DockPanel.Dock="Top">
|
||||||
|
<Grid>
|
||||||
|
<Border HorizontalAlignment="Center"
|
||||||
|
VerticalAlignment="Top"
|
||||||
|
Margin="16"
|
||||||
|
Visibility="{Binding SelectedSyncGroup, Converter={StaticResource NullToVisibilityConverter}, ConverterParameter=True}">
|
||||||
|
<TextBlock Text="No Sync-Group selected ..." />
|
||||||
|
</Border>
|
||||||
|
|
||||||
|
<Border Visibility="{Binding SelectedSyncGroup, Converter={StaticResource NullToVisibilityConverter}}">
|
||||||
|
<Border.Resources>
|
||||||
|
<Style BasedOn="{StaticResource StyleLabelForm}" TargetType="Label" />
|
||||||
|
<Style BasedOn="{StaticResource StyleTextBlockForm}" TargetType="TextBlock" />
|
||||||
|
</Border.Resources>
|
||||||
|
|
||||||
|
<controls:Form DockPanel.Dock="Top">
|
||||||
|
<Label controls:Form.IsLabel="True"
|
||||||
|
Content="Name:" />
|
||||||
|
<TextBox controls:Form.Fill="True"
|
||||||
|
Text="{Binding SelectedSyncGroup.Name, UpdateSourceTrigger=PropertyChanged}" />
|
||||||
|
|
||||||
|
<Label controls:Form.IsLabel="True"
|
||||||
|
Content="Sync-LED:" />
|
||||||
|
<ComboBox controls:Form.Fill="True"
|
||||||
|
ItemsSource="{Binding AvailableSyncLeds}"
|
||||||
|
SelectedItem="{Binding SelectedSyncGroup.SyncLed}">
|
||||||
|
<ComboBox.GroupStyle>
|
||||||
|
<GroupStyle>
|
||||||
|
<GroupStyle.HeaderTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<Border VerticalAlignment="Stretch"
|
||||||
|
HorizontalAlignment="Stretch"
|
||||||
|
Background="{StaticResource BrushComboBoxBackgroundGroupHeader}">
|
||||||
|
<TextBlock VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Text="{Binding Name}" />
|
||||||
|
</Border>
|
||||||
|
</DataTemplate>
|
||||||
|
</GroupStyle.HeaderTemplate>
|
||||||
|
</GroupStyle>
|
||||||
|
</ComboBox.GroupStyle>
|
||||||
|
<ComboBox.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Text="{Binding LedId}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</ComboBox.ItemTemplate>
|
||||||
|
</ComboBox>
|
||||||
|
</controls:Form>
|
||||||
|
</Border>
|
||||||
|
</Grid>
|
||||||
|
</GroupBox>
|
||||||
|
|
||||||
|
<Grid Margin="0,8,0,0"
|
||||||
|
Visibility="{Binding SelectedSyncGroup, Converter={StaticResource NullToVisibilityConverter}}">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="8" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<Grid.Resources>
|
||||||
|
<GroupStyle x:Key="StyleListBoxGroup">
|
||||||
|
<GroupStyle.HeaderTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock VerticalAlignment="Center"
|
||||||
|
HorizontalAlignment="Left"
|
||||||
|
Margin="0,8,0,0"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Text="{Binding Name}" />
|
||||||
|
</DataTemplate>
|
||||||
|
</GroupStyle.HeaderTemplate>
|
||||||
|
</GroupStyle>
|
||||||
|
|
||||||
|
<DataTemplate x:Key="DataTemplateListBoxItem">
|
||||||
|
<TextBlock Text="{Binding LedId}"/>
|
||||||
|
</DataTemplate>
|
||||||
|
</Grid.Resources>
|
||||||
|
|
||||||
|
<GroupBox Grid.Column="0">
|
||||||
|
<DockPanel>
|
||||||
|
<TextBlock DockPanel.Dock="Top"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="0,0,0,8"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Text="Available LEDS" />
|
||||||
|
<ListBox SelectionMode="Extended"
|
||||||
|
dd:DragDrop.IsDragSource="True"
|
||||||
|
dd:DragDrop.IsDropTarget="True"
|
||||||
|
dd:DragDrop.DropHandler="{Binding}"
|
||||||
|
ItemTemplate="{StaticResource DataTemplateListBoxItem}"
|
||||||
|
ItemsSource="{Binding AvailableLeds}">
|
||||||
|
<ListBox.GroupStyle>
|
||||||
|
<StaticResource ResourceKey="StyleListBoxGroup" />
|
||||||
|
</ListBox.GroupStyle>
|
||||||
|
</ListBox>
|
||||||
|
</DockPanel>
|
||||||
|
</GroupBox>
|
||||||
|
|
||||||
|
<GroupBox Grid.Column="2">
|
||||||
|
<DockPanel>
|
||||||
|
<TextBlock DockPanel.Dock="Top"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="0,0,0,8"
|
||||||
|
FontWeight="Bold"
|
||||||
|
Text="Synchronized LEDS" />
|
||||||
|
<ListBox SelectionMode="Extended"
|
||||||
|
dd:DragDrop.IsDragSource="True"
|
||||||
|
dd:DragDrop.IsDropTarget="True"
|
||||||
|
dd:DragDrop.DropHandler="{Binding}"
|
||||||
|
ItemTemplate="{StaticResource DataTemplateListBoxItem}"
|
||||||
|
ItemsSource="{Binding SynchronizedLeds}">
|
||||||
|
<ListBox.GroupStyle>
|
||||||
|
<StaticResource ResourceKey="StyleListBoxGroup" />
|
||||||
|
</ListBox.GroupStyle>
|
||||||
|
</ListBox>
|
||||||
|
</DockPanel>
|
||||||
|
</GroupBox>
|
||||||
|
</Grid>
|
||||||
|
</DockPanel>
|
||||||
|
</DockPanel>
|
||||||
|
</AdornerDecorator>
|
||||||
|
</TabItem>
|
||||||
|
|
||||||
|
<TabItem Header="Settings">
|
||||||
|
<AdornerDecorator>
|
||||||
|
<GroupBox VerticalAlignment="Top">
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<Grid>
|
||||||
|
<Grid.Resources>
|
||||||
|
<Style BasedOn="{StaticResource StyleLabelForm}" TargetType="Label" />
|
||||||
|
<Style BasedOn="{StaticResource StyleTextBlockForm}" TargetType="TextBlock" />
|
||||||
|
<Style BasedOn="{StaticResource StyleListBoxForm}" TargetType="ListBox" />
|
||||||
|
</Grid.Resources>
|
||||||
|
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="8" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
<ColumnDefinition Width="8" />
|
||||||
|
<ColumnDefinition Width="*" />
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
|
||||||
|
<controls:Form Grid.Column="0">
|
||||||
|
<Label controls:Form.IsLabel="True"
|
||||||
|
Content="Version:" />
|
||||||
|
<TextBlock Text="{Binding Version}" />
|
||||||
|
|
||||||
|
<Label controls:Form.IsLabel="True"
|
||||||
|
Content="Update-Rate" />
|
||||||
|
<Slider Minimum="1" Maximum="100" controls:Form.Fill="True" IsSnapToTickEnabled="True" TickFrequency="1" TickPlacement="BottomRight"
|
||||||
|
Value="{Binding UpdateRate}"
|
||||||
|
attached:SliderValue.Unit="UPS"
|
||||||
|
ToolTip="Defines how fast the data is updated.
Low values can reduce CPU-usage but might cause stuttering." />
|
||||||
|
|
||||||
|
<Label controls:Form.LineBreaks="1" controls:Form.IsLabel="True" Content="Devices:" />
|
||||||
|
</controls:Form>
|
||||||
|
</Grid>
|
||||||
|
|
||||||
|
<ItemsControl VerticalAlignment="Top" HorizontalAlignment="Left" Margin="120,-22,0,0" ItemsSource="{Binding Source={x:Static core:RGBSurface.Instance}, Path=Devices}">
|
||||||
|
<ItemsControl.ItemTemplate>
|
||||||
|
<DataTemplate>
|
||||||
|
<TextBlock Style="{StaticResource StyleTextBlockForm}">
|
||||||
|
<TextBlock.Text>
|
||||||
|
<MultiBinding StringFormat="> {0} {1} ({2})">
|
||||||
|
<Binding Path="DeviceInfo.Manufacturer" />
|
||||||
|
<Binding Path="DeviceInfo.Model" />
|
||||||
|
<Binding Path="DeviceInfo.DeviceType" />
|
||||||
|
</MultiBinding>
|
||||||
|
</TextBlock.Text>
|
||||||
|
</TextBlock>
|
||||||
|
</DataTemplate>
|
||||||
|
</ItemsControl.ItemTemplate>
|
||||||
|
</ItemsControl>
|
||||||
|
</StackPanel>
|
||||||
|
</GroupBox>
|
||||||
|
</AdornerDecorator>
|
||||||
|
</TabItem>
|
||||||
|
</TabControl>
|
||||||
|
|
||||||
|
</controls:BlurredDecorationWindow>
|
||||||
16
RGBSync+/UI/ConfigurationWindow.xaml.cs
Normal file
16
RGBSync+/UI/ConfigurationWindow.xaml.cs
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
using System;
|
||||||
|
using RGBSyncPlus.Controls;
|
||||||
|
|
||||||
|
namespace RGBSyncPlus.UI
|
||||||
|
{
|
||||||
|
public partial class ConfigurationWindow : BlurredDecorationWindow
|
||||||
|
{
|
||||||
|
public ConfigurationWindow() => InitializeComponent();
|
||||||
|
|
||||||
|
//DarthAffe 07.02.2018: This prevents the applicaiton from not shutting down and crashing afterwards if 'close' is selected in the taskbar-context-menu
|
||||||
|
private void ConfigurationWindow_OnClosed(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
ApplicationManager.Instance.ExitCommand.Execute(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user