mirror of
https://github.com/DarthAffe/RGBSyncPlus
synced 2025-12-12 17:08: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