├── .gitignore
├── LICENSE
├── README.md
└── RGBSync+
├── App.config
├── App.xaml
├── App.xaml.cs
├── ApplicationManager.cs
├── Attached
├── SliderValue.cs
└── SliderValueAdorner.cs
├── Brushes
└── SyncBrush.cs
├── Configuration
├── AbstractConfiguration.cs
├── ColorSerializer.cs
├── IConfiguration.cs
├── Legacy
│ └── ConfigurationUpdates.cs
└── Settings.cs
├── Controls
├── BlurredDecorationWindow.cs
├── ColorSelector.cs
├── Form.cs
├── GradientEditor.cs
└── ImageButton.cs
├── Converter
├── BoolToVisibilityConverter.cs
├── EqualsToBoolConverter.cs
├── NullToVisibilityConverter.cs
├── ScrollOffsetToOpacityMaskConverter.cs
└── ScrollOffsetToVisibilityConverter.cs
├── Helper
├── ActionCommand.cs
├── ExceptionExtension.cs
├── MathHelper.cs
└── RGBNetExtension.cs
├── Model
├── SyncGroup.cs
└── SyncLed.cs
├── NuGet.Config
├── Properties
├── AssemblyInfo.cs
├── Resources.Designer.cs
├── Resources.resx
├── Settings.Designer.cs
└── Settings.settings
├── RGBSync+.csproj
├── RGBSync+.sln
├── Resources
├── RGBSync+.xaml
├── argebee.ico
├── arrow_down.png
├── arrow_up.png
├── background.png
├── close.png
├── font.ttf
├── minimize.png
└── navigation.ttf
├── Styles
├── BlurredDecorationWindow.xaml
├── Button.xaml
├── CachedResourceDictionary.cs
├── ColorSelector.xaml
├── ComboBox.xaml
├── Form.xaml
├── FrameworkElement.xaml
├── GradientEditor.xaml
├── GroupBox.xaml
├── ImageButton.xaml
├── ListBox.xaml
├── Navigation.xaml
├── Slider.xaml
├── TextBox.xaml
├── Theme.xaml
└── ToolTip.xaml
└── UI
├── ConfigurationViewModel.cs
├── ConfigurationWindow.xaml
└── ConfigurationWindow.xaml.cs
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 | ##
4 | ## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
5 |
6 | # User-specific files
7 | *.suo
8 | *.user
9 | *.userosscache
10 | *.sln.docstates
11 |
12 | # User-specific files (MonoDevelop/Xamarin Studio)
13 | *.userprefs
14 |
15 | # Build results
16 | [Dd]ebug/
17 | [Dd]ebugPublic/
18 | [Rr]elease/
19 | [Rr]eleases/
20 | x64/
21 | x86/
22 | bld/
23 | [Bb]in/
24 | [Oo]bj/
25 | [Ll]og/
26 |
27 | # Visual Studio 2015/2017 cache/options directory
28 | .vs/
29 | # Uncomment if you have tasks that create the project's static files in wwwroot
30 | #wwwroot/
31 |
32 | # Visual Studio 2017 auto generated files
33 | Generated\ Files/
34 |
35 | # MSTest test Results
36 | [Tt]est[Rr]esult*/
37 | [Bb]uild[Ll]og.*
38 |
39 | # NUNIT
40 | *.VisualState.xml
41 | TestResult.xml
42 |
43 | # Build Results of an ATL Project
44 | [Dd]ebugPS/
45 | [Rr]eleasePS/
46 | dlldata.c
47 |
48 | # Benchmark Results
49 | BenchmarkDotNet.Artifacts/
50 |
51 | # .NET Core
52 | project.lock.json
53 | project.fragment.lock.json
54 | artifacts/
55 | **/Properties/launchSettings.json
56 |
57 | # StyleCop
58 | StyleCopReport.xml
59 |
60 | # Files built by Visual Studio
61 | *_i.c
62 | *_p.c
63 | *_i.h
64 | *.ilk
65 | *.meta
66 | *.obj
67 | *.iobj
68 | *.pch
69 | *.pdb
70 | *.ipdb
71 | *.pgc
72 | *.pgd
73 | *.rsp
74 | *.sbr
75 | *.tlb
76 | *.tli
77 | *.tlh
78 | *.tmp
79 | *.tmp_proj
80 | *.log
81 | *.vspscc
82 | *.vssscc
83 | .builds
84 | *.pidb
85 | *.svclog
86 | *.scc
87 |
88 | # Chutzpah Test files
89 | _Chutzpah*
90 |
91 | # Visual C++ cache files
92 | ipch/
93 | *.aps
94 | *.ncb
95 | *.opendb
96 | *.opensdf
97 | *.sdf
98 | *.cachefile
99 | *.VC.db
100 | *.VC.VC.opendb
101 |
102 | # Visual Studio profiler
103 | *.psess
104 | *.vsp
105 | *.vspx
106 | *.sap
107 |
108 | # Visual Studio Trace Files
109 | *.e2e
110 |
111 | # TFS 2012 Local Workspace
112 | $tf/
113 |
114 | # Guidance Automation Toolkit
115 | *.gpState
116 |
117 | # ReSharper is a .NET coding add-in
118 | _ReSharper*/
119 | *.[Rr]e[Ss]harper
120 | *.DotSettings.user
121 |
122 | # JustCode is a .NET coding add-in
123 | .JustCode
124 |
125 | # TeamCity is a build add-in
126 | _TeamCity*
127 |
128 | # DotCover is a Code Coverage Tool
129 | *.dotCover
130 |
131 | # AxoCover is a Code Coverage Tool
132 | .axoCover/*
133 | !.axoCover/settings.json
134 |
135 | # Visual Studio code coverage results
136 | *.coverage
137 | *.coveragexml
138 |
139 | # NCrunch
140 | _NCrunch_*
141 | .*crunch*.local.xml
142 | nCrunchTemp_*
143 |
144 | # MightyMoose
145 | *.mm.*
146 | AutoTest.Net/
147 |
148 | # Web workbench (sass)
149 | .sass-cache/
150 |
151 | # Installshield output folder
152 | [Ee]xpress/
153 |
154 | # DocProject is a documentation generator add-in
155 | DocProject/buildhelp/
156 | DocProject/Help/*.HxT
157 | DocProject/Help/*.HxC
158 | DocProject/Help/*.hhc
159 | DocProject/Help/*.hhk
160 | DocProject/Help/*.hhp
161 | DocProject/Help/Html2
162 | DocProject/Help/html
163 |
164 | # Click-Once directory
165 | publish/
166 |
167 | # Publish Web Output
168 | *.[Pp]ublish.xml
169 | *.azurePubxml
170 | # Note: Comment the next line if you want to checkin your web deploy settings,
171 | # but database connection strings (with potential passwords) will be unencrypted
172 | *.pubxml
173 | *.publishproj
174 |
175 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
176 | # checkin your Azure Web App publish settings, but sensitive information contained
177 | # in these scripts will be unencrypted
178 | PublishScripts/
179 |
180 | # NuGet Packages
181 | *.nupkg
182 | # The packages folder can be ignored because of Package Restore
183 | **/[Pp]ackages/*
184 | # except build/, which is used as an MSBuild target.
185 | !**/[Pp]ackages/build/
186 | # Uncomment if necessary however generally it will be regenerated when needed
187 | #!**/[Pp]ackages/repositories.config
188 | # NuGet v3's project.json files produces more ignorable files
189 | *.nuget.props
190 | *.nuget.targets
191 |
192 | # Microsoft Azure Build Output
193 | csx/
194 | *.build.csdef
195 |
196 | # Microsoft Azure Emulator
197 | ecf/
198 | rcf/
199 |
200 | # Windows Store app package directories and files
201 | AppPackages/
202 | BundleArtifacts/
203 | Package.StoreAssociation.xml
204 | _pkginfo.txt
205 | *.appx
206 |
207 | # Visual Studio cache files
208 | # files ending in .cache can be ignored
209 | *.[Cc]ache
210 | # but keep track of directories ending in .cache
211 | !*.[Cc]ache/
212 |
213 | # Others
214 | ClientBin/
215 | ~$*
216 | *~
217 | *.dbmdl
218 | *.dbproj.schemaview
219 | *.jfm
220 | *.pfx
221 | *.publishsettings
222 | orleans.codegen.cs
223 |
224 | # Including strong name files can present a security risk
225 | # (https://github.com/github/gitignore/pull/2483#issue-259490424)
226 | #*.snk
227 |
228 | # Since there are multiple workflows, uncomment next line to ignore bower_components
229 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
230 | #bower_components/
231 |
232 | # RIA/Silverlight projects
233 | Generated_Code/
234 |
235 | # Backup & report files from converting an old project file
236 | # to a newer Visual Studio version. Backup files are not needed,
237 | # because we have git ;-)
238 | _UpgradeReport_Files/
239 | Backup*/
240 | UpgradeLog*.XML
241 | UpgradeLog*.htm
242 | ServiceFabricBackup/
243 | *.rptproj.bak
244 |
245 | # SQL Server files
246 | *.mdf
247 | *.ldf
248 | *.ndf
249 |
250 | # Business Intelligence projects
251 | *.rdl.data
252 | *.bim.layout
253 | *.bim_*.settings
254 | *.rptproj.rsuser
255 |
256 | # Microsoft Fakes
257 | FakesAssemblies/
258 |
259 | # GhostDoc plugin setting file
260 | *.GhostDoc.xml
261 |
262 | # Node.js Tools for Visual Studio
263 | .ntvs_analysis.dat
264 | node_modules/
265 |
266 | # Visual Studio 6 build log
267 | *.plg
268 |
269 | # Visual Studio 6 workspace options file
270 | *.opt
271 |
272 | # Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
273 | *.vbw
274 |
275 | # Visual Studio LightSwitch build output
276 | **/*.HTMLClient/GeneratedArtifacts
277 | **/*.DesktopClient/GeneratedArtifacts
278 | **/*.DesktopClient/ModelManifest.xml
279 | **/*.Server/GeneratedArtifacts
280 | **/*.Server/ModelManifest.xml
281 | _Pvt_Extensions
282 |
283 | # Paket dependency manager
284 | .paket/paket.exe
285 | paket-files/
286 |
287 | # FAKE - F# Make
288 | .fake/
289 |
290 | # JetBrains Rider
291 | .idea/
292 | *.sln.iml
293 |
294 | # CodeRush
295 | .cr/
296 |
297 | # Python Tools for Visual Studio (PTVS)
298 | __pycache__/
299 | *.pyc
300 |
301 | # Cake - Uncomment if you are using it
302 | # tools/**
303 | # !tools/packages.config
304 |
305 | # Tabs Studio
306 | *.tss
307 |
308 | # Telerik's JustMock configuration file
309 | *.jmconfig
310 |
311 | # BizTalk build output
312 | *.btp.cs
313 | *.btm.cs
314 | *.odx.cs
315 | *.xsd.cs
316 |
317 | # OpenCover UI analysis results
318 | OpenCover/
319 |
320 | # Azure Stream Analytics local run output
321 | ASALocalRun/
322 |
323 | # MSBuild Binary and Structured Log
324 | *.binlog
325 |
326 | # NVidia Nsight GPU debugger configuration file
327 | *.nvuser
328 |
329 | # MFractors (Xamarin productivity tool) working folder
330 | .mfractor/
331 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | Since [RGB.NET](https://github.com/DarthAffe/RGB.NET) no longer supports reading colors from devices, syncing is no longer possible and this example no longer needed.
2 |
3 | If you're looking for a software to control RGB-devices of different brands together consider checking out [Artemis](https://github.com/Artemis-RGB/Artemis).
4 |
5 | # RGBSyncPlus
6 | Tool to syncronize RGB devices
7 |
8 | If you've issues with the configuration window not opening when clicking the Tray-Icon you can disable Tray-Minimization by changing ```"MinimizeToTray":true``` to ```"MinimizeToTray":false``` in _Settings.json_ in the installation directory. (If this entry isn't already included delete the file and start/close the program once.)
9 |
--------------------------------------------------------------------------------
/RGBSync+/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/RGBSync+/App.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/RGBSync+/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.IO;
3 | using System.Windows;
4 | using System.Windows.Controls;
5 | using Hardcodet.Wpf.TaskbarNotification;
6 | using Newtonsoft.Json;
7 | using RGBSyncPlus.Configuration;
8 | using RGBSyncPlus.Configuration.Legacy;
9 | using RGBSyncPlus.Helper;
10 |
11 | namespace RGBSyncPlus
12 | {
13 | public partial class App : Application
14 | {
15 | #region Constants
16 |
17 | private const string PATH_SETTINGS = "Settings.json";
18 |
19 | #endregion
20 |
21 | #region Properties & Fields
22 |
23 | private TaskbarIcon _taskbarIcon;
24 |
25 | #endregion
26 |
27 | #region Methods
28 |
29 | protected override void OnStartup(StartupEventArgs e)
30 | {
31 | base.OnStartup(e);
32 |
33 | try
34 | {
35 | ToolTipService.ShowDurationProperty.OverrideMetadata(typeof(DependencyObject), new FrameworkPropertyMetadata(int.MaxValue));
36 |
37 | _taskbarIcon = (TaskbarIcon)FindResource("TaskbarIcon");
38 | _taskbarIcon.DoubleClickCommand = ApplicationManager.Instance.OpenConfigurationCommand;
39 |
40 | Settings settings = null;
41 | try { settings = JsonConvert.DeserializeObject(File.ReadAllText(PATH_SETTINGS), new ColorSerializer()); }
42 | catch (Exception ex)
43 | {
44 | Console.WriteLine(ex.Message);
45 | /* File doesn't exist or is corrupt - just create a new one. */
46 | }
47 |
48 | if (settings == null)
49 | {
50 | settings = new Settings { Version = Settings.CURRENT_VERSION };
51 | _taskbarIcon.ShowBalloonTip("RGBSync+ is starting in the tray!", "Click on the icon to open the configuration.", BalloonIcon.Info);
52 | }
53 | else if (settings.Version != Settings.CURRENT_VERSION)
54 | ConfigurationUpdates.PerformOn(settings);
55 |
56 | ApplicationManager.Instance.Settings = settings;
57 | ApplicationManager.Instance.Initialize();
58 |
59 | if (!settings.MinimizeToTray) //HACK DarthAffe 02.12.2018: Workaround to create the window
60 | {
61 | ApplicationManager.Instance.OpenConfigurationCommand.Execute(null);
62 | ApplicationManager.Instance.HideConfigurationCommand.Execute(null);
63 | }
64 | }
65 | catch (Exception ex)
66 | {
67 | 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");
68 | 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+.");
69 |
70 | try { ApplicationManager.Instance.ExitCommand.Execute(null); }
71 | catch { Environment.Exit(0); }
72 | }
73 | }
74 |
75 | protected override void OnExit(ExitEventArgs e)
76 | {
77 | base.OnExit(e);
78 |
79 | File.WriteAllText(PATH_SETTINGS, JsonConvert.SerializeObject(ApplicationManager.Instance.Settings, new ColorSerializer()));
80 | }
81 |
82 | #endregion
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/RGBSync+/ApplicationManager.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Collections.Specialized;
4 | using System.IO;
5 | using System.Linq;
6 | using System.Reflection;
7 | using System.Windows;
8 | using RGB.NET.Core;
9 | using RGB.NET.Groups;
10 | using RGBSyncPlus.Brushes;
11 | using RGBSyncPlus.Configuration;
12 | using RGBSyncPlus.Helper;
13 | using RGBSyncPlus.Model;
14 | using RGBSyncPlus.UI;
15 |
16 | namespace RGBSyncPlus
17 | {
18 | public class ApplicationManager
19 | {
20 | #region Constants
21 |
22 | private const string DEVICEPROVIDER_DIRECTORY = "DeviceProvider";
23 |
24 | #endregion
25 |
26 | #region Properties & Fields
27 |
28 | public static ApplicationManager Instance { get; } = new ApplicationManager();
29 |
30 | private ConfigurationWindow _configurationWindow;
31 |
32 | public Settings Settings { get; set; }
33 | public TimerUpdateTrigger UpdateTrigger { get; private set; }
34 |
35 | #endregion
36 |
37 | #region Commands
38 |
39 | private ActionCommand _openConfiguration;
40 | public ActionCommand OpenConfigurationCommand => _openConfiguration ?? (_openConfiguration = new ActionCommand(OpenConfiguration));
41 |
42 | private ActionCommand _hideConfiguration;
43 | public ActionCommand HideConfigurationCommand => _hideConfiguration ?? (_hideConfiguration = new ActionCommand(HideConfiguration));
44 |
45 | private ActionCommand _exitCommand;
46 | public ActionCommand ExitCommand => _exitCommand ?? (_exitCommand = new ActionCommand(Exit));
47 |
48 | #endregion
49 |
50 | #region Constructors
51 |
52 | private ApplicationManager() { }
53 |
54 | #endregion
55 |
56 | #region Methods
57 |
58 | public void Initialize()
59 | {
60 | RGBSurface surface = RGBSurface.Instance;
61 | LoadDeviceProviders();
62 | surface.AlignDevices();
63 |
64 | foreach (IRGBDevice device in surface.Devices)
65 | device.UpdateMode = DeviceUpdateMode.Sync | DeviceUpdateMode.SyncBack;
66 |
67 | UpdateTrigger = new TimerUpdateTrigger { UpdateFrequency = 1.0 / MathHelper.Clamp(Settings.UpdateRate, 1, 100) };
68 | surface.RegisterUpdateTrigger(UpdateTrigger);
69 | UpdateTrigger.Start();
70 |
71 | foreach (SyncGroup syncGroup in Settings.SyncGroups)
72 | RegisterSyncGroup(syncGroup);
73 | }
74 |
75 | private void LoadDeviceProviders()
76 | {
77 | string deviceProvierDir = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) ?? string.Empty, DEVICEPROVIDER_DIRECTORY);
78 | if (!Directory.Exists(deviceProvierDir)) return;
79 |
80 | foreach (string file in Directory.GetFiles(deviceProvierDir, "*.dll"))
81 | {
82 | try
83 | {
84 | Assembly assembly = Assembly.LoadFrom(file);
85 | foreach (Type loaderType in assembly.GetTypes().Where(t => !t.IsAbstract && !t.IsInterface && t.IsClass
86 | && typeof(IRGBDeviceProviderLoader).IsAssignableFrom(t)))
87 | {
88 | if (Activator.CreateInstance(loaderType) is IRGBDeviceProviderLoader deviceProviderLoader)
89 | {
90 | //TODO DarthAffe 03.06.2018: Support Initialization
91 | if (deviceProviderLoader.RequiresInitialization) continue;
92 |
93 | RGBSurface.Instance.LoadDevices(deviceProviderLoader);
94 | }
95 | }
96 | }
97 | catch { /* #sadprogrammer */ }
98 | }
99 | }
100 |
101 | public void AddSyncGroup(SyncGroup syncGroup)
102 | {
103 | Settings.SyncGroups.Add(syncGroup);
104 | RegisterSyncGroup(syncGroup);
105 | }
106 |
107 | private void RegisterSyncGroup(SyncGroup syncGroup)
108 | {
109 | syncGroup.LedGroup = new ListLedGroup(syncGroup.Leds.GetLeds()) { Brush = new SyncBrush(syncGroup) };
110 | syncGroup.LedsChangedEventHandler = (sender, args) => UpdateLedGroup(syncGroup.LedGroup, args);
111 | syncGroup.Leds.CollectionChanged += syncGroup.LedsChangedEventHandler;
112 | }
113 |
114 | public void RemoveSyncGroup(SyncGroup syncGroup)
115 | {
116 | Settings.SyncGroups.Remove(syncGroup);
117 | syncGroup.Leds.CollectionChanged -= syncGroup.LedsChangedEventHandler;
118 | syncGroup.LedGroup.Detach();
119 | syncGroup.LedGroup = null;
120 | }
121 |
122 | private void UpdateLedGroup(ListLedGroup group, NotifyCollectionChangedEventArgs args)
123 | {
124 | if (args.Action == NotifyCollectionChangedAction.Reset)
125 | {
126 | List leds = group.GetLeds().ToList();
127 | group.RemoveLeds(leds);
128 | }
129 | else
130 | {
131 | if (args.NewItems != null)
132 | group.AddLeds(args.NewItems.Cast().GetLeds());
133 |
134 | if (args.OldItems != null)
135 | group.RemoveLeds(args.OldItems.Cast().GetLeds());
136 | }
137 | }
138 |
139 | private void HideConfiguration()
140 | {
141 | if (Settings.MinimizeToTray)
142 | {
143 | if (_configurationWindow.IsVisible)
144 | _configurationWindow.Hide();
145 | }
146 | else
147 | _configurationWindow.WindowState = WindowState.Minimized;
148 | }
149 |
150 | private void OpenConfiguration()
151 | {
152 | if (_configurationWindow == null) _configurationWindow = new ConfigurationWindow();
153 |
154 | if (!_configurationWindow.IsVisible)
155 | _configurationWindow.Show();
156 |
157 | if (_configurationWindow.WindowState == WindowState.Minimized)
158 | _configurationWindow.WindowState = WindowState.Normal;
159 | }
160 |
161 | private void Exit()
162 | {
163 | try { RGBSurface.Instance?.Dispose(); } catch { /* well, we're shuting down anyway ... */ }
164 | Application.Current.Shutdown();
165 | }
166 |
167 | #endregion
168 | }
169 | }
170 |
--------------------------------------------------------------------------------
/RGBSync+/Attached/SliderValue.cs:
--------------------------------------------------------------------------------
1 | using System.Linq;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 | using System.Windows.Documents;
5 | using System.Windows.Input;
6 | using System.Windows.Media;
7 |
8 | namespace RGBSyncPlus.Attached
9 | {
10 | public static class SliderValue
11 | {
12 | #region Properties & Fields
13 | // ReSharper disable InconsistentNaming
14 |
15 | public static readonly DependencyProperty UnitProperty = DependencyProperty.RegisterAttached(
16 | "Unit", typeof(string), typeof(SliderValue), new PropertyMetadata(default(string)));
17 |
18 | public static void SetUnit(DependencyObject element, string value) => element.SetValue(UnitProperty, value);
19 | public static string GetUnit(DependencyObject element) => (string)element.GetValue(UnitProperty);
20 |
21 | public static readonly DependencyProperty IsShownProperty = DependencyProperty.RegisterAttached(
22 | "IsShown", typeof(bool), typeof(SliderValue), new PropertyMetadata(default(bool), IsShownChanged));
23 |
24 | public static void SetIsShown(DependencyObject element, bool value) => element.SetValue(IsShownProperty, value);
25 | public static bool GetIsShown(DependencyObject element) => (bool)element.GetValue(IsShownProperty);
26 |
27 | public static readonly DependencyProperty BorderBrushProperty = DependencyProperty.RegisterAttached(
28 | "BorderBrush", typeof(Brush), typeof(SliderValue), new PropertyMetadata(default(Brush)));
29 |
30 | public static void SetBorderBrush(DependencyObject element, Brush value) => element.SetValue(BorderBrushProperty, value);
31 | public static Brush GetBorderBrush(DependencyObject element) => (Brush)element.GetValue(BorderBrushProperty);
32 |
33 | public static readonly DependencyProperty BackgroundProperty = DependencyProperty.RegisterAttached(
34 | "Background", typeof(Brush), typeof(SliderValue), new PropertyMetadata(default(Brush)));
35 |
36 | public static void SetBackground(DependencyObject element, Brush value) => element.SetValue(BackgroundProperty, value);
37 | public static Brush GetBackground(DependencyObject element) => (Brush)element.GetValue(BackgroundProperty);
38 |
39 | public static readonly DependencyProperty ForegroundProperty = DependencyProperty.RegisterAttached(
40 | "Foreground", typeof(Brush), typeof(SliderValue), new PropertyMetadata(default(Brush)));
41 |
42 | public static void SetForeground(DependencyObject element, Brush value) => element.SetValue(ForegroundProperty, value);
43 | public static Brush GetForeground(DependencyObject element) => (Brush)element.GetValue(ForegroundProperty);
44 |
45 | public static readonly DependencyProperty FontProperty = DependencyProperty.RegisterAttached(
46 | "Font", typeof(FontFamily), typeof(SliderValue), new PropertyMetadata(default(FontFamily)));
47 |
48 | public static void SetFont(DependencyObject element, FontFamily value) => element.SetValue(FontProperty, value);
49 | public static FontFamily GetFont(DependencyObject element) => (FontFamily)element.GetValue(FontProperty);
50 |
51 | public static readonly DependencyProperty FontSizeProperty = DependencyProperty.RegisterAttached(
52 | "FontSize", typeof(double), typeof(SliderValue), new PropertyMetadata(default(double)));
53 |
54 | public static void SetFontSize(DependencyObject element, double value) => element.SetValue(FontSizeProperty, value);
55 | public static double GetFontSize(DependencyObject element) => (double)element.GetValue(FontSizeProperty);
56 |
57 | // ReSharper enable InconsistentNaming
58 | #endregion
59 |
60 | #region Methods
61 |
62 | private static void IsShownChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
63 | {
64 | if (!(dependencyObject is Slider slider)) return;
65 |
66 | if (dependencyPropertyChangedEventArgs.NewValue as bool? == true)
67 | {
68 | slider.MouseEnter += SliderOnMouseEnter;
69 | slider.MouseLeave += SliderOnMouseLeave;
70 | }
71 | else
72 | {
73 | slider.MouseEnter -= SliderOnMouseEnter;
74 | slider.MouseLeave -= SliderOnMouseLeave;
75 | RemoveAdorner(slider);
76 | }
77 | }
78 |
79 | private static void SliderOnMouseEnter(object sender, MouseEventArgs mouseEventArgs)
80 | {
81 | if (!(sender is Slider slider)) return;
82 | AdornerLayer.GetAdornerLayer(slider)?.Add(new SliderValueAdorner(slider, GetUnit(slider))
83 | {
84 | BorderBrush = GetBorderBrush(slider),
85 | Background = GetBackground(slider),
86 | Foreground = GetForeground(slider),
87 | Font = GetFont(slider),
88 | FontSize = GetFontSize(slider)
89 | });
90 | }
91 |
92 | private static void SliderOnMouseLeave(object sender, MouseEventArgs mouseEventArgs)
93 | {
94 | if (!(sender is Slider slider)) return;
95 | RemoveAdorner(slider);
96 | }
97 |
98 | private static void RemoveAdorner(Slider slider)
99 | {
100 | AdornerLayer adornerLayer = AdornerLayer.GetAdornerLayer(slider);
101 | Adorner adorner = adornerLayer?.GetAdorners(slider)?.FirstOrDefault(x => x is SliderValueAdorner);
102 | if (adorner != null)
103 | {
104 | adornerLayer.Remove(adorner);
105 | (adorner as SliderValueAdorner)?.Cleanup();
106 | }
107 | }
108 |
109 | #endregion
110 | }
111 | }
112 |
--------------------------------------------------------------------------------
/RGBSync+/Attached/SliderValueAdorner.cs:
--------------------------------------------------------------------------------
1 | using System.Globalization;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 | using System.Windows.Controls.Primitives;
5 | using System.Windows.Media;
6 | using Point = System.Windows.Point;
7 |
8 | namespace RGBSyncPlus.Attached
9 | {
10 | public class SliderValueAdorner : System.Windows.Documents.Adorner
11 | {
12 | #region Properties & Fields
13 |
14 | private readonly string _unit;
15 | private readonly Slider _slider;
16 | private readonly Thumb _thumb;
17 | private readonly RepeatButton _decreaseRepeatButton;
18 |
19 | public Brush BorderBrush { get; set; } = System.Windows.Media.Brushes.Black;
20 | public Brush Background { get; set; } = System.Windows.Media.Brushes.Black;
21 | public Brush Foreground { get; set; } = System.Windows.Media.Brushes.White;
22 | public FontFamily Font { get; set; } = new FontFamily("Verdana");
23 | public double FontSize { get; set; } = 14;
24 |
25 | #endregion
26 |
27 | #region Constructors
28 |
29 | public SliderValueAdorner(UIElement adornedElement, string unit)
30 | : base(adornedElement)
31 | {
32 | this._unit = unit;
33 |
34 | _slider = (Slider)adornedElement;
35 | Track track = (Track)_slider.Template.FindName("PART_Track", _slider);
36 |
37 | _thumb = track.Thumb;
38 | _decreaseRepeatButton = track.DecreaseRepeatButton;
39 | _decreaseRepeatButton.SizeChanged += OnButtonSizeChanged;
40 | }
41 |
42 | #endregion
43 |
44 | #region Methods
45 |
46 | public void Cleanup()
47 | {
48 | _decreaseRepeatButton.SizeChanged -= OnButtonSizeChanged;
49 | }
50 |
51 | private void OnButtonSizeChanged(object sender, SizeChangedEventArgs sizeChangedEventArgs) => InvalidateVisual();
52 |
53 | protected override void OnRender(DrawingContext drawingContext)
54 | {
55 | double offset = _decreaseRepeatButton.ActualWidth + (_thumb.ActualWidth / 2.0);
56 |
57 | FormattedText text = new FormattedText(GetText(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight, new Typeface(Font, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal), FontSize, Foreground);
58 | Geometry border = CreateBorder(offset, text.Width, text.Height);
59 |
60 | drawingContext.DrawGeometry(Background, new Pen(BorderBrush, 1), border);
61 | drawingContext.DrawText(text, new Point(offset - (text.Width / 2.0), -26));
62 | }
63 |
64 | private string GetText()
65 | {
66 | string valueText = _slider.Value.ToString();
67 | if (!string.IsNullOrWhiteSpace(_unit))
68 | valueText += " " + _unit;
69 |
70 | return valueText;
71 | }
72 |
73 | private Geometry CreateBorder(double offset, double width, double height)
74 | {
75 | double halfWidth = width / 2.0;
76 |
77 | PathGeometry borderGeometry = new PathGeometry();
78 | PathFigure border = new PathFigure
79 | {
80 | StartPoint = new Point(offset, 0),
81 | IsClosed = true,
82 | IsFilled = true
83 | };
84 |
85 | border.Segments.Add(new LineSegment(new Point(offset + 4, -6), true));
86 | border.Segments.Add(new LineSegment(new Point(offset + 4 + halfWidth, -6), true));
87 | border.Segments.Add(new LineSegment(new Point(offset + 4 + halfWidth, -10 - height), true));
88 | border.Segments.Add(new LineSegment(new Point(offset - 4 - halfWidth, -10 - height), true));
89 | border.Segments.Add(new LineSegment(new Point(offset - 4 - halfWidth, -6), true));
90 | border.Segments.Add(new LineSegment(new Point(offset - 4, -6), true));
91 |
92 | borderGeometry.Figures.Add(border);
93 |
94 | return borderGeometry;
95 | }
96 |
97 | #endregion
98 | }
99 | }
100 |
--------------------------------------------------------------------------------
/RGBSync+/Brushes/SyncBrush.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 | using RGB.NET.Core;
3 | using RGBSyncPlus.Helper;
4 | using RGBSyncPlus.Model;
5 |
6 | namespace RGBSyncPlus.Brushes
7 | {
8 | public class SyncBrush : AbstractBrush
9 | {
10 | #region Properties & Fields
11 |
12 | private readonly SyncGroup _syncGroup;
13 |
14 | private Led _syncLed;
15 |
16 | #endregion
17 |
18 | #region Constructors
19 |
20 | public SyncBrush(SyncGroup syncGroup)
21 | {
22 | this._syncGroup = syncGroup;
23 |
24 | syncGroup.PropertyChanged += SyncGroupOnPropertyChanged;
25 | _syncLed = syncGroup.SyncLed?.GetLed();
26 | }
27 |
28 | #endregion
29 |
30 | #region Methods
31 |
32 | private void SyncGroupOnPropertyChanged(object sender, PropertyChangedEventArgs e)
33 | {
34 | if (e.PropertyName == nameof(SyncGroup.SyncLed))
35 | _syncLed = _syncGroup.SyncLed?.GetLed();
36 | }
37 |
38 | protected override Color GetColorAtPoint(Rectangle rectangle, BrushRenderTarget renderTarget)
39 | {
40 | if(_syncLed == null)
41 | _syncLed = _syncGroup.SyncLed?.GetLed();
42 |
43 | if (renderTarget.Led == _syncLed)
44 | return Color.Transparent;
45 |
46 | return _syncLed?.Color ?? Color.Transparent;
47 | }
48 |
49 | #endregion
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/RGBSync+/Configuration/AbstractConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.ComponentModel;
3 | using System.Runtime.CompilerServices;
4 | using RGB.NET.Core;
5 |
6 | namespace RGBSyncPlus.Configuration
7 | {
8 | public class AbstractConfiguration : AbstractBindable, IConfiguration, INotifyPropertyChanged
9 | {
10 | #region Methods
11 |
12 | protected override bool SetProperty(ref T storage, T value, [CallerMemberName] string propertyName = null)
13 | {
14 | if ((typeof(T) == typeof(double)) || (typeof(T) == typeof(float)))
15 | {
16 | if (Math.Abs((double)(object)storage - (double)(object)value) < 0.000001) return false;
17 | }
18 | else
19 | {
20 | if (Equals(storage, value)) return false;
21 | }
22 |
23 | storage = value;
24 | // ReSharper disable once ExplicitCallerInfoArgument
25 | OnPropertyChanged(propertyName);
26 | return true;
27 | }
28 |
29 | #endregion
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/RGBSync+/Configuration/ColorSerializer.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using Newtonsoft.Json;
3 | using Newtonsoft.Json.Linq;
4 | using RGB.NET.Core;
5 |
6 | namespace RGBSyncPlus.Configuration
7 | {
8 | public class ColorSerializer : JsonConverter
9 | {
10 | #region Methods
11 |
12 | public override bool CanConvert(Type objectType) => objectType == typeof(Color);
13 |
14 | public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
15 | {
16 | if (!(value is Color color)) return;
17 |
18 | writer.WriteStartObject();
19 | writer.WritePropertyName("A");
20 | writer.WriteValue(color.A);
21 | writer.WritePropertyName("R");
22 | writer.WriteValue(color.R);
23 | writer.WritePropertyName("G");
24 | writer.WriteValue(color.G);
25 | writer.WritePropertyName("B");
26 | writer.WriteValue(color.B);
27 | writer.WriteEndObject();
28 | }
29 |
30 | public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
31 | {
32 | JObject jsonObject = JObject.Load(reader);
33 | return new Color(jsonObject.Property("A").Value.ToObject(),
34 | jsonObject.Property("R").Value.ToObject(),
35 | jsonObject.Property("G").Value.ToObject(),
36 | jsonObject.Property("B").Value.ToObject());
37 | }
38 |
39 | #endregion
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/RGBSync+/Configuration/IConfiguration.cs:
--------------------------------------------------------------------------------
1 | using System.ComponentModel;
2 |
3 | namespace RGBSyncPlus.Configuration
4 | {
5 | public interface IConfiguration : INotifyPropertyChanged
6 | { }
7 | }
8 |
--------------------------------------------------------------------------------
/RGBSync+/Configuration/Legacy/ConfigurationUpdates.cs:
--------------------------------------------------------------------------------
1 | namespace RGBSyncPlus.Configuration.Legacy
2 | {
3 | public static class ConfigurationUpdates
4 | {
5 | #region Methods
6 |
7 | public static void PerformOn(Settings settings)
8 | { }
9 |
10 | #endregion
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/RGBSync+/Configuration/Settings.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using RGBSyncPlus.Model;
3 |
4 | namespace RGBSyncPlus.Configuration
5 | {
6 | public class Settings
7 | {
8 | #region Constants
9 |
10 | public const int CURRENT_VERSION = 1;
11 |
12 | #endregion
13 |
14 | #region Properties & Fields
15 |
16 | public int Version { get; set; } = 0;
17 |
18 | public double UpdateRate { get; set; } = 30.0;
19 |
20 | public bool MinimizeToTray { get; set; } = true;
21 |
22 | public List SyncGroups { get; set; } = new List();
23 |
24 | #endregion
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/RGBSync+/Controls/BlurredDecorationWindow.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Controls;
3 | using System.Windows.Input;
4 | using System.Windows.Media;
5 |
6 | namespace RGBSyncPlus.Controls
7 | {
8 | [TemplatePart(Name = "PART_Decoration", Type = typeof(FrameworkElement))]
9 | [TemplatePart(Name = "PART_Content", Type = typeof(FrameworkElement))]
10 | [TemplatePart(Name = "PART_CloseButton", Type = typeof(Button))]
11 | [TemplatePart(Name = "PART_MinimizeButton", Type = typeof(Button))]
12 | [TemplatePart(Name = "PART_IconButton", Type = typeof(Button))]
13 | public class BlurredDecorationWindow : Window
14 | {
15 | #region DependencyProperties
16 | // ReSharper disable InconsistentNaming
17 |
18 | public static readonly DependencyProperty BackgroundImageProperty = DependencyProperty.Register(
19 | "BackgroundImage", typeof(ImageSource), typeof(BlurredDecorationWindow), new PropertyMetadata(default(ImageSource)));
20 |
21 | public ImageSource BackgroundImage
22 | {
23 | get => (ImageSource)GetValue(BackgroundImageProperty);
24 | set => SetValue(BackgroundImageProperty, value);
25 | }
26 |
27 | public static readonly DependencyProperty DecorationHeightProperty = DependencyProperty.Register(
28 | "DecorationHeight", typeof(double), typeof(BlurredDecorationWindow), new PropertyMetadata(20.0));
29 |
30 | public double DecorationHeight
31 | {
32 | get => (double)GetValue(DecorationHeightProperty);
33 | set => SetValue(DecorationHeightProperty, value);
34 | }
35 |
36 | public static readonly DependencyProperty IconToolTipProperty = DependencyProperty.Register(
37 | "IconToolTip", typeof(string), typeof(BlurredDecorationWindow), new PropertyMetadata(default(string)));
38 |
39 | public string IconToolTip
40 | {
41 | get => (string)GetValue(IconToolTipProperty);
42 | set => SetValue(IconToolTipProperty, value);
43 | }
44 |
45 | public static readonly DependencyProperty IconCommandProperty = DependencyProperty.Register(
46 | "IconCommand", typeof(ICommand), typeof(BlurredDecorationWindow), new PropertyMetadata(default(ICommand)));
47 |
48 | public ICommand IconCommand
49 | {
50 | get => (ICommand)GetValue(IconCommandProperty);
51 | set => SetValue(IconCommandProperty, value);
52 | }
53 |
54 | // ReSharper restore InconsistentNaming
55 | #endregion
56 |
57 | #region Constructors
58 |
59 | static BlurredDecorationWindow()
60 | {
61 | DefaultStyleKeyProperty.OverrideMetadata(typeof(BlurredDecorationWindow), new FrameworkPropertyMetadata(typeof(BlurredDecorationWindow)));
62 | }
63 |
64 | #endregion
65 |
66 | #region Methods
67 |
68 | public override void OnApplyTemplate()
69 | {
70 | base.OnApplyTemplate();
71 |
72 | if (GetTemplateChild("PART_Decoration") is FrameworkElement decoration)
73 | decoration.MouseLeftButtonDown += (sender, args) => DragMove();
74 |
75 | if (GetTemplateChild("PART_CloseButton") is Button closeButton)
76 | closeButton.Click += (sender, args) => ApplicationManager.Instance.ExitCommand.Execute(null);
77 |
78 | if (GetTemplateChild("PART_MinimizeButton") is Button minimizeButton)
79 | minimizeButton.Click += (sender, args) => ApplicationManager.Instance.HideConfigurationCommand.Execute(null); //HACK DarthAffe 02.12.2018: This is a really dirty hack - hopefully this will never get more than one window ...
80 |
81 | if (GetTemplateChild("PART_IconButton") is Button iconButton)
82 | iconButton.Click += (sender, args) => IconCommand?.Execute(null);
83 | }
84 |
85 | #endregion
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/RGBSync+/Controls/Form.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows;
3 | using System.Windows.Controls;
4 |
5 | namespace RGBSyncPlus.Controls
6 | {
7 | public class Form : Panel
8 | {
9 | #region DependencyProperties
10 | // ReSharper disable InconsistentNaming
11 |
12 | public static readonly DependencyProperty RowHeightProperty = DependencyProperty.Register("RowHeight", typeof(double), typeof(Form),
13 | new FrameworkPropertyMetadata(24.0, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
14 |
15 | public double RowHeight
16 | {
17 | get => (double)GetValue(RowHeightProperty);
18 | set
19 | {
20 | if (value < 0) throw new ArgumentOutOfRangeException(nameof(RowHeight), "Row height can't be negative");
21 | SetValue(RowHeightProperty, value);
22 | }
23 | }
24 |
25 | public static readonly DependencyProperty LabelWidthProperty = DependencyProperty.Register("LabelWidth", typeof(double), typeof(Form),
26 | new FrameworkPropertyMetadata(100.0, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
27 |
28 | public double LabelWidth
29 | {
30 | get => (double)GetValue(LabelWidthProperty);
31 | set
32 | {
33 | if (value < 0) throw new ArgumentOutOfRangeException(nameof(RowHeight), "Label width can't be negative");
34 | SetValue(LabelWidthProperty, value);
35 | }
36 | }
37 |
38 | public static readonly DependencyProperty ElementSpacingProperty = DependencyProperty.Register("ElementSpacing", typeof(double), typeof(Form),
39 | new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
40 |
41 | public double ElementSpacing
42 | {
43 | get => (double)GetValue(ElementSpacingProperty);
44 | set => SetValue(ElementSpacingProperty, value);
45 | }
46 |
47 | public static readonly DependencyProperty RowSpacingProperty = DependencyProperty.Register("RowSpacing", typeof(double), typeof(Form),
48 | new FrameworkPropertyMetadata(default(double), FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
49 |
50 | public double RowSpacing
51 | {
52 | get => (double)GetValue(RowSpacingProperty);
53 | set => SetValue(RowSpacingProperty, value);
54 | }
55 |
56 | // ReSharper restore InconsistentNaming
57 | #endregion
58 |
59 | #region AttachedProperties
60 | // ReSharper disable InconsistentNaming
61 |
62 | public static readonly DependencyProperty IsLabelProperty = DependencyProperty.RegisterAttached("IsLabel", typeof(bool), typeof(Form),
63 | new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
64 |
65 | public static void SetIsLabel(UIElement element, bool value) => element.SetValue(IsLabelProperty, value);
66 | public static bool GetIsLabel(UIElement element) => (bool)element.GetValue(IsLabelProperty);
67 |
68 | public static readonly DependencyProperty LineBreaksProperty = DependencyProperty.RegisterAttached("LineBreaks", typeof(int), typeof(Form),
69 | new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
70 |
71 | public static void SetLineBreaks(UIElement element, int value) => element.SetValue(LineBreaksProperty, value);
72 | public static int GetLineBreaks(UIElement element) => (int)element.GetValue(LineBreaksProperty);
73 |
74 | public static readonly DependencyProperty RowSpanProperty = DependencyProperty.RegisterAttached("RowSpan", typeof(int), typeof(Form),
75 | new FrameworkPropertyMetadata(1, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
76 |
77 | public static void SetRowSpan(DependencyObject element, int value) => element.SetValue(RowSpanProperty, value);
78 | public static int GetRowSpan(DependencyObject element) => (int)element.GetValue(RowSpanProperty);
79 |
80 | public static readonly DependencyProperty FillProperty = DependencyProperty.RegisterAttached("Fill", typeof(bool), typeof(Form),
81 | new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsArrange | FrameworkPropertyMetadataOptions.AffectsMeasure));
82 |
83 | public static void SetFill(DependencyObject element, bool value) => element.SetValue(FillProperty, value);
84 | public static bool GetFill(DependencyObject element) => (bool)element.GetValue(FillProperty);
85 |
86 | // ReSharper restore InconsistentNaming
87 | #endregion
88 |
89 | #region Methods
90 |
91 | protected override Size MeasureOverride(Size availableSize)
92 | {
93 | if (InternalChildren.Count == 0) return new Size(0, 0);
94 |
95 | FormLayout layout = new FormLayout(RowHeight, LabelWidth, ElementSpacing, RowSpacing);
96 |
97 | foreach (UIElement child in InternalChildren)
98 | {
99 | child.Measure(availableSize);
100 | layout.AddElement(child, 0);
101 | }
102 |
103 | return new Size(layout.Width, layout.Height);
104 | }
105 |
106 | protected override Size ArrangeOverride(Size finalSize)
107 | {
108 | if (InternalChildren.Count == 0) return new Size(0, 0);
109 |
110 | FormLayout layout = new FormLayout(RowHeight, LabelWidth, ElementSpacing, RowSpacing);
111 |
112 | foreach (UIElement child in InternalChildren)
113 | child.Arrange(layout.AddElement(child, finalSize.Width));
114 |
115 | return new Size(finalSize.Width, layout.Height);
116 | }
117 |
118 | #endregion
119 |
120 | #region Data
121 |
122 | private class FormLayout
123 | {
124 | #region Properties & Fields
125 |
126 | private readonly double _rowHeight;
127 | private readonly double _labelWidth;
128 | private readonly double _elementSpacing;
129 | private readonly double _rowSpacing;
130 |
131 | private double _currentRowWidth;
132 |
133 | private int _newRows = 0;
134 | private int _rows = -1;
135 | private double _currentMaxWidth;
136 | public double Width => Math.Max((Math.Max(_currentMaxWidth, _currentRowWidth) - _elementSpacing), 0);
137 | public double Height => ((_rows + 1) * _rowHeight) + (_rows * _rowSpacing);
138 |
139 | #endregion
140 |
141 | #region Constructors
142 |
143 | public FormLayout(double rowHeight, double labelWidth, double elementSpacing, double rowSpacing)
144 | {
145 | this._rowHeight = rowHeight;
146 | this._labelWidth = labelWidth;
147 | this._elementSpacing = elementSpacing;
148 | this._rowSpacing = rowSpacing;
149 | }
150 |
151 | #endregion
152 |
153 | #region Methods
154 |
155 | public Rect AddElement(UIElement element, double targetWidth)
156 | {
157 | bool isLabel = GetIsLabel(element);
158 | int lineBreaks = GetLineBreaks(element);
159 | int rowSpan = GetRowSpan(element);
160 |
161 | double elementWidth = isLabel ? _labelWidth : element.DesiredSize.Width;
162 | double height = _rowHeight;
163 |
164 | if (_newRows > 0)
165 | {
166 | AddLineBreaks(_newRows);
167 | _newRows = 0;
168 | }
169 |
170 | if (lineBreaks > 0) AddLineBreaks(lineBreaks);
171 | else if (isLabel) AddLineBreaks(1);
172 | else if (_rows < 0) _rows = 0;
173 |
174 | if (!isLabel && (_currentRowWidth < _labelWidth))
175 | _currentRowWidth = _labelWidth + _elementSpacing;
176 |
177 | if (rowSpan > 1)
178 | {
179 | height = (rowSpan * _rowHeight) + ((rowSpan - 1) * _rowSpacing);
180 | _newRows = Math.Max(_newRows, rowSpan - 1);
181 | }
182 |
183 | if (element is FrameworkElement fe)
184 | fe.MaxHeight = height;
185 |
186 | double width = elementWidth;
187 | if ((targetWidth >= 1) && GetFill(element))
188 | width = targetWidth - _currentRowWidth;
189 |
190 | Rect rect = new Rect(new Point(_currentRowWidth, (_rows * _rowHeight) + (_rows * _rowSpacing)), new Size(width, height));
191 |
192 | _currentRowWidth += width + _elementSpacing;
193 |
194 | return rect;
195 | }
196 |
197 | private void AddLineBreaks(int count)
198 | {
199 | if (count <= 0) return;
200 |
201 | _currentMaxWidth = Math.Max(_currentMaxWidth, _currentRowWidth);
202 |
203 | _currentRowWidth = 0;
204 | _rows += count;
205 | }
206 |
207 | #endregion
208 | }
209 |
210 | #endregion
211 | }
212 | }
213 |
--------------------------------------------------------------------------------
/RGBSync+/Controls/ImageButton.cs:
--------------------------------------------------------------------------------
1 | using System.Windows;
2 | using System.Windows.Controls;
3 | using System.Windows.Media;
4 |
5 | namespace RGBSyncPlus.Controls
6 | {
7 | public class ImageButton : Button
8 | {
9 | #region Properties & Fields
10 | // ReSharper disable InconsistentNaming
11 |
12 | public static readonly DependencyProperty ImageProperty = DependencyProperty.Register(
13 | "Image", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
14 |
15 | public ImageSource Image
16 | {
17 | get => (ImageSource)GetValue(ImageProperty);
18 | set => SetValue(ImageProperty, value);
19 | }
20 |
21 | public static readonly DependencyProperty HoverImageProperty = DependencyProperty.Register(
22 | "HoverImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
23 |
24 | public ImageSource HoverImage
25 | {
26 | get => (ImageSource)GetValue(HoverImageProperty);
27 | set => SetValue(HoverImageProperty, value);
28 | }
29 |
30 | public static readonly DependencyProperty PressedImageProperty = DependencyProperty.Register(
31 | "PressedImage", typeof(ImageSource), typeof(ImageButton), new PropertyMetadata(default(ImageSource)));
32 |
33 | public ImageSource PressedImage
34 | {
35 | get => (ImageSource)GetValue(PressedImageProperty);
36 | set => SetValue(PressedImageProperty, value);
37 | }
38 |
39 | // ReSharper restore InconsistentNaming
40 | #endregion
41 |
42 | #region Constructors
43 |
44 | static ImageButton()
45 | {
46 | DefaultStyleKeyProperty.OverrideMetadata(typeof(ImageButton), new FrameworkPropertyMetadata(typeof(ImageButton)));
47 | }
48 |
49 | #endregion
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/RGBSync+/Converter/BoolToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace RGBSyncPlus.Converter
7 | {
8 | [ValueConversion(typeof(bool), typeof(Visibility))]
9 | public class BoolToVisibilityConverter : IValueConverter
10 | {
11 | #region Methods
12 |
13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
14 | => (value as bool?) == true ? Visibility.Visible
15 | : (string.Equals(parameter?.ToString(), "true", StringComparison.OrdinalIgnoreCase) ? Visibility.Hidden : Visibility.Collapsed);
16 |
17 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => value as Visibility? == Visibility.Visible;
18 |
19 | #endregion
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/RGBSync+/Converter/EqualsToBoolConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows.Data;
4 |
5 | namespace RGBSyncPlus.Converter
6 | {
7 | [ValueConversion(typeof(object), typeof(bool))]
8 | public class EqualsToBoolConverter : IValueConverter
9 | {
10 | #region Methods
11 |
12 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture) => Equals(value, parameter);
13 |
14 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
15 |
16 | #endregion
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/RGBSync+/Converter/NullToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace RGBSyncPlus.Converter
7 | {
8 | [ValueConversion(typeof(object), typeof(Visibility))]
9 | public class NullToVisibilityConverter : IValueConverter
10 | {
11 | #region Methods
12 |
13 | public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
14 | => (value == null) == (string.Equals(parameter?.ToString(), "true", StringComparison.OrdinalIgnoreCase)) ? Visibility.Visible : Visibility.Hidden;
15 |
16 | public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => throw new NotSupportedException();
17 |
18 | #endregion
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/RGBSync+/Converter/ScrollOffsetToOpacityMaskConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 | using System.Windows.Media;
6 |
7 | namespace RGBSyncPlus.Converter
8 | {
9 | public class ScrollOffsetToOpacityMaskConverter : IMultiValueConverter
10 | {
11 | #region Constants
12 |
13 | private static readonly Color TRANSPARENT = Color.FromArgb(0, 0, 0, 0);
14 | private static readonly Color OPAQUE = Color.FromArgb(255, 0, 0, 0);
15 |
16 | #endregion
17 |
18 | #region Methods
19 |
20 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
21 | {
22 | double offset = double.Parse(values[0].ToString());
23 | double maxHeight = double.Parse(values[1].ToString());
24 | double height = double.Parse(values[2].ToString());
25 |
26 | double transparencyHeight = double.Parse(parameter.ToString());
27 | double transparencyFactor = (transparencyHeight - 6) / height;
28 | double transparencyFadeFactor = (transparencyHeight + 4) / height;
29 |
30 | bool top = !(Math.Abs(offset) < float.Epsilon);
31 | bool bot = !(Math.Abs(offset - maxHeight) < float.Epsilon);
32 |
33 | if (!top && !bot) return new SolidColorBrush(OPAQUE);
34 |
35 | GradientStopCollection gradientStops = new GradientStopCollection();
36 | if (top)
37 | {
38 | gradientStops.Add(new GradientStop(TRANSPARENT, 0.0));
39 | gradientStops.Add(new GradientStop(TRANSPARENT, transparencyFactor));
40 | gradientStops.Add(new GradientStop(OPAQUE, transparencyFadeFactor));
41 | }
42 | else
43 | gradientStops.Add(new GradientStop(OPAQUE, 0.0));
44 |
45 | if (bot)
46 | {
47 | gradientStops.Add(new GradientStop(OPAQUE, 1.0 - transparencyFadeFactor));
48 | gradientStops.Add(new GradientStop(TRANSPARENT, 1.0 - transparencyFactor));
49 | gradientStops.Add(new GradientStop(TRANSPARENT, 1.0));
50 | }
51 | else
52 | gradientStops.Add(new GradientStop(OPAQUE, 1.0));
53 |
54 | return new LinearGradientBrush(gradientStops, new Point(0.5, 0.0), new Point(0.5, 1.0));
55 | }
56 |
57 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotSupportedException();
58 |
59 | #endregion
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/RGBSync+/Converter/ScrollOffsetToVisibilityConverter.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Globalization;
3 | using System.Windows;
4 | using System.Windows.Data;
5 |
6 | namespace RGBSyncPlus.Converter
7 | {
8 | // Based on: http://stackoverflow.com/a/28679767
9 | public class ScrollOffsetToVisibilityConverter : IMultiValueConverter
10 | {
11 | #region Methods
12 |
13 | public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
14 | {
15 | bool top = "top".Equals(parameter?.ToString(), StringComparison.OrdinalIgnoreCase);
16 |
17 | double offset = double.Parse(values[0].ToString());
18 | double maxHeight = double.Parse(values[1].ToString());
19 |
20 | return (top && Math.Abs(offset) < float.Epsilon) || (!top && Math.Abs(offset - maxHeight) < float.Epsilon)
21 | ? Visibility.Collapsed
22 | : Visibility.Visible;
23 | }
24 |
25 | public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) => throw new NotSupportedException();
26 |
27 | #endregion
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/RGBSync+/Helper/ActionCommand.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Windows.Input;
3 |
4 | namespace RGBSyncPlus.Helper
5 | {
6 | public class ActionCommand : ICommand
7 | {
8 | #region Properties & Fields
9 |
10 | private readonly Func _canExecute;
11 | private readonly Action _command;
12 |
13 | #endregion
14 |
15 | #region Events
16 |
17 | public event EventHandler CanExecuteChanged;
18 |
19 | #endregion
20 |
21 | #region Constructors
22 |
23 | public ActionCommand(Action command, Func canExecute = null)
24 | {
25 | this._command = command;
26 | this._canExecute = canExecute;
27 | }
28 |
29 | #endregion
30 |
31 | #region Methods
32 |
33 | public bool CanExecute(object parameter) => _canExecute?.Invoke() ?? true;
34 |
35 | public void Execute(object parameter) => _command?.Invoke();
36 |
37 | public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, new EventArgs());
38 |
39 | #endregion
40 | }
41 |
42 | public class ActionCommand : ICommand
43 | {
44 | #region Properties & Fields
45 |
46 | private readonly Func _canExecute;
47 | private readonly Action _command;
48 |
49 | #endregion
50 |
51 | #region Events
52 |
53 | public event EventHandler CanExecuteChanged;
54 |
55 | #endregion
56 |
57 | #region Constructors
58 |
59 | public ActionCommand(Action command, Func canExecute = null)
60 | {
61 | this._command = command;
62 | this._canExecute = canExecute;
63 | }
64 |
65 | #endregion
66 |
67 | #region Methods
68 |
69 | public bool CanExecute(object parameter) => _canExecute?.Invoke((T)parameter) ?? true;
70 |
71 | public void Execute(object parameter) => _command?.Invoke((T)parameter);
72 |
73 | public void RaiseCanExecuteChanged() => CanExecuteChanged?.Invoke(this, new EventArgs());
74 |
75 | #endregion
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/RGBSync+/Helper/ExceptionExtension.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace RGBSyncPlus.Helper
4 | {
5 | public static class ExceptionExtension
6 | {
7 | #region Methods
8 |
9 | public static string GetFullMessage(this Exception ex, string message = "")
10 | {
11 | if (ex == null) return string.Empty;
12 |
13 | message += ex.Message;
14 |
15 | if (ex.InnerException != null)
16 | message += "\r\nInnerException: " + GetFullMessage(ex.InnerException);
17 |
18 | return message;
19 | }
20 |
21 | #endregion
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/RGBSync+/Helper/MathHelper.cs:
--------------------------------------------------------------------------------
1 | using System;
2 |
3 | namespace RGBSyncPlus.Helper
4 | {
5 | public static class MathHelper
6 | {
7 | #region Methods
8 |
9 | public static double Clamp(double value, double min, double max) => Math.Max(min, Math.Min(max, value));
10 | public static float Clamp(float value, float min, float max) => (float)Clamp((double)value, min, max);
11 | public static int Clamp(int value, int min, int max) => Math.Max(min, Math.Min(max, value));
12 |
13 | #endregion
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/RGBSync+/Helper/RGBNetExtension.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.Generic;
2 | using System.Linq;
3 | using RGB.NET.Core;
4 | using RGBSyncPlus.Model;
5 |
6 | namespace RGBSyncPlus.Helper
7 | {
8 | public static class RGBNetExtension
9 | {
10 | public static string GetDeviceName(this IRGBDevice device) => $"{device.DeviceInfo.DeviceName} ({device.DeviceInfo.DeviceType})";
11 |
12 | public static IEnumerable GetLeds(this IEnumerable syncLeds)
13 | => syncLeds.Select(GetLed).Where(led => led != null);
14 |
15 | public static Led GetLed(this SyncLed syncLed)
16 | {
17 | if (syncLed == null) return null;
18 | return RGBSurface.Instance.Leds.FirstOrDefault(l => (l.Id == syncLed.LedId) && (l.Device.GetDeviceName() == syncLed.Device));
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/RGBSync+/Model/SyncGroup.cs:
--------------------------------------------------------------------------------
1 | using System.Collections.ObjectModel;
2 | using System.Collections.Specialized;
3 | using Newtonsoft.Json;
4 | using RGB.NET.Core;
5 | using RGB.NET.Groups;
6 |
7 | namespace RGBSyncPlus.Model
8 | {
9 | public class SyncGroup : AbstractBindable
10 | {
11 | #region Properties & Fields
12 |
13 | public string DisplayName => string.IsNullOrWhiteSpace(Name) ? "(unnamed)" : Name;
14 |
15 | private string _name;
16 | public string Name
17 | {
18 | get => _name;
19 | set
20 | {
21 | if (SetProperty(ref _name, value))
22 | OnPropertyChanged(nameof(DisplayName));
23 | }
24 | }
25 |
26 | private SyncLed _syncLed;
27 | public SyncLed SyncLed
28 | {
29 | get => _syncLed;
30 | set => SetProperty(ref _syncLed, value);
31 | }
32 |
33 | private ObservableCollection _leds = new ObservableCollection();
34 | public ObservableCollection Leds
35 | {
36 | get => _leds;
37 | set => SetProperty(ref _leds, value);
38 | }
39 |
40 | [JsonIgnore]
41 | public ListLedGroup LedGroup { get; set; }
42 |
43 | [JsonIgnore]
44 | public NotifyCollectionChangedEventHandler LedsChangedEventHandler { get; set; }
45 |
46 | #endregion
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/RGBSync+/Model/SyncLed.cs:
--------------------------------------------------------------------------------
1 | using Newtonsoft.Json;
2 | using RGB.NET.Core;
3 | using RGBSyncPlus.Helper;
4 |
5 | namespace RGBSyncPlus.Model
6 | {
7 | public class SyncLed : AbstractBindable
8 | {
9 | #region Properties & Fields
10 |
11 | private string _device;
12 | public string Device
13 | {
14 | get => _device;
15 | set => SetProperty(ref _device, value);
16 | }
17 |
18 | private LedId _ledId;
19 | public LedId LedId
20 | {
21 | get => _ledId;
22 | set => SetProperty(ref _ledId, value);
23 | }
24 |
25 | private Led _led;
26 | [JsonIgnore]
27 | public Led Led
28 | {
29 | get => _led;
30 | set => SetProperty(ref _led, value);
31 | }
32 |
33 | #endregion
34 |
35 | #region Constructors
36 |
37 | public SyncLed()
38 | { }
39 |
40 | public SyncLed(string device, LedId ledId)
41 | {
42 | this.Device = device;
43 | this.LedId = ledId;
44 | }
45 |
46 | public SyncLed(Led led)
47 | {
48 | this.Device = led.Device.GetDeviceName();
49 | this.LedId = led.Id;
50 | this.Led = led;
51 | }
52 |
53 | #endregion
54 |
55 | #region Methods
56 |
57 | protected bool Equals(SyncLed other) => string.Equals(_device, other._device) && (_ledId == other._ledId);
58 |
59 | public override bool Equals(object obj)
60 | {
61 | if (ReferenceEquals(null, obj)) return false;
62 | if (ReferenceEquals(this, obj)) return true;
63 | if (obj.GetType() != this.GetType()) return false;
64 | return Equals((SyncLed)obj);
65 | }
66 |
67 | public override int GetHashCode()
68 | {
69 | unchecked
70 | {
71 | return ((_device != null ? _device.GetHashCode() : 0) * 397) ^ (int)_ledId;
72 | }
73 | }
74 |
75 | public static bool operator ==(SyncLed left, SyncLed right) => Equals(left, right);
76 | public static bool operator !=(SyncLed left, SyncLed right) => !Equals(left, right);
77 |
78 | #endregion
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/RGBSync+/NuGet.Config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/RGBSync+/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Resources;
3 | using System.Runtime.CompilerServices;
4 | using System.Runtime.InteropServices;
5 | using System.Windows;
6 |
7 | // General Information about an assembly is controlled through the following
8 | // set of attributes. Change these attribute values to modify the information
9 | // associated with an assembly.
10 | [assembly: AssemblyTitle("RGBSync+")]
11 | [assembly: AssemblyDescription("")]
12 | [assembly: AssemblyConfiguration("")]
13 | [assembly: AssemblyCompany("")]
14 | [assembly: AssemblyProduct("RGBSync+")]
15 | [assembly: AssemblyCopyright("Copyright © 2018")]
16 | [assembly: AssemblyTrademark("")]
17 | [assembly: AssemblyCulture("")]
18 |
19 | // Setting ComVisible to false makes the types in this assembly not visible
20 | // to COM components. If you need to access a type in this assembly from
21 | // COM, set the ComVisible attribute to true on that type.
22 | [assembly: ComVisible(false)]
23 |
24 | //In order to begin building localizable applications, set
25 | //CultureYouAreCodingWith in your .csproj file
26 | //inside a . For example, if you are using US english
27 | //in your source files, set the to en-US. Then uncomment
28 | //the NeutralResourceLanguage attribute below. Update the "en-US" in
29 | //the line below to match the UICulture setting in the project file.
30 |
31 | //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
32 |
33 |
34 | [assembly: ThemeInfo(
35 | ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
36 | //(used if a resource is not found in the page,
37 | // or application resource dictionaries)
38 | ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
39 | //(used if a resource is not found in the page,
40 | // app, or any theme specific resource dictionaries)
41 | )]
42 |
43 |
44 | // Version information for an assembly consists of the following four values:
45 | //
46 | // Major Version
47 | // Minor Version
48 | // Build Number
49 | // Revision
50 | //
51 | // You can specify all the values or you can default the Build and Revision Numbers
52 | // by using the '*' as shown below:
53 | // [assembly: AssemblyVersion("1.0.*")]
54 | [assembly: AssemblyVersion("1.0.0.3")]
55 | [assembly: AssemblyFileVersion("1.0.0.3")]
56 |
--------------------------------------------------------------------------------
/RGBSync+/Properties/Resources.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace RGBSyncPlus.Properties {
12 | using System;
13 |
14 |
15 | ///
16 | /// A strongly-typed resource class, for looking up localized strings, etc.
17 | ///
18 | // This class was auto-generated by the StronglyTypedResourceBuilder
19 | // class via a tool like ResGen or Visual Studio.
20 | // To add or remove a member, edit your .ResX file then rerun ResGen
21 | // with the /str option, or rebuild your VS project.
22 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0")]
23 | [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
24 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
25 | internal class Resources {
26 |
27 | private static global::System.Resources.ResourceManager resourceMan;
28 |
29 | private static global::System.Globalization.CultureInfo resourceCulture;
30 |
31 | [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
32 | internal Resources() {
33 | }
34 |
35 | ///
36 | /// Returns the cached ResourceManager instance used by this class.
37 | ///
38 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
39 | internal static global::System.Resources.ResourceManager ResourceManager {
40 | get {
41 | if (object.ReferenceEquals(resourceMan, null)) {
42 | global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("RGBSyncPlus.Properties.Resources", typeof(Resources).Assembly);
43 | resourceMan = temp;
44 | }
45 | return resourceMan;
46 | }
47 | }
48 |
49 | ///
50 | /// Overrides the current thread's CurrentUICulture property for all
51 | /// resource lookups using this strongly typed resource class.
52 | ///
53 | [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
54 | internal static global::System.Globalization.CultureInfo Culture {
55 | get {
56 | return resourceCulture;
57 | }
58 | set {
59 | resourceCulture = value;
60 | }
61 | }
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/RGBSync+/Properties/Resources.resx:
--------------------------------------------------------------------------------
1 |
2 |
3 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 | text/microsoft-resx
107 |
108 |
109 | 2.0
110 |
111 |
112 | System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
113 |
114 |
115 | System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
116 |
117 |
--------------------------------------------------------------------------------
/RGBSync+/Properties/Settings.Designer.cs:
--------------------------------------------------------------------------------
1 | //------------------------------------------------------------------------------
2 | //
3 | // This code was generated by a tool.
4 | // Runtime Version:4.0.30319.42000
5 | //
6 | // Changes to this file may cause incorrect behavior and will be lost if
7 | // the code is regenerated.
8 | //
9 | //------------------------------------------------------------------------------
10 |
11 | namespace RGBSyncPlus.Properties {
12 |
13 |
14 | [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
15 | [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "15.7.0.0")]
16 | internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
17 |
18 | private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
19 |
20 | public static Settings Default {
21 | get {
22 | return defaultInstance;
23 | }
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/RGBSync+/Properties/Settings.settings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/RGBSync+/RGBSync+.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Debug
6 | AnyCPU
7 | {C6BF4357-07D9-496B-9630-A26568D30723}
8 | WinExe
9 | RGBSyncPlus
10 | RGBSync+
11 | v4.5
12 | 512
13 | {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
14 | 4
15 |
16 |
17 | x86
18 | true
19 | full
20 | false
21 | ..\bin\
22 | DEBUG;TRACE
23 | prompt
24 | 4
25 |
26 |
27 | x86
28 | pdbonly
29 | true
30 | ..\bin\
31 | TRACE
32 | prompt
33 | 4
34 |
35 |
36 | RGBSyncPlus.App
37 |
38 |
39 | Resources\argebee.ico
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | 4.0
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 | MSBuild:Compile
61 | Designer
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 | ConfigurationWindow.xaml
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | App.xaml
95 | Code
96 |
97 |
98 | MSBuild:Compile
99 | Designer
100 |
101 |
102 | MSBuild:Compile
103 | Designer
104 |
105 |
106 | MSBuild:Compile
107 | Designer
108 |
109 |
110 | MSBuild:Compile
111 | Designer
112 |
113 |
114 | MSBuild:Compile
115 | Designer
116 |
117 |
118 | MSBuild:Compile
119 | Designer
120 |
121 |
122 | MSBuild:Compile
123 | Designer
124 |
125 |
126 | MSBuild:Compile
127 | Designer
128 |
129 |
130 | MSBuild:Compile
131 | Designer
132 |
133 |
134 | MSBuild:Compile
135 | Designer
136 |
137 |
138 | MSBuild:Compile
139 | Designer
140 |
141 |
142 | MSBuild:Compile
143 | Designer
144 |
145 |
146 | MSBuild:Compile
147 | Designer
148 |
149 |
150 | MSBuild:Compile
151 | Designer
152 |
153 |
154 | MSBuild:Compile
155 | Designer
156 |
157 |
158 | MSBuild:Compile
159 | Designer
160 |
161 |
162 | MSBuild:Compile
163 | Designer
164 |
165 |
166 |
167 |
168 | Code
169 |
170 |
171 | True
172 | True
173 | Resources.resx
174 |
175 |
176 | True
177 | Settings.settings
178 | True
179 |
180 |
181 | ResXFileCodeGenerator
182 | Resources.Designer.cs
183 |
184 |
185 | SettingsSingleFileGenerator
186 | Settings.Designer.cs
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 | 1.1.0
197 |
198 |
199 | 1.0.8
200 |
201 |
202 | 12.0.1
203 |
204 |
205 | 0.1.23
206 |
207 |
208 | 0.1.23
209 |
210 |
211 | 0.1.23
212 |
213 |
214 | 0.1.23
215 |
216 |
217 | 4.5.0
218 |
219 |
220 | 1.0.0
221 |
222 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
--------------------------------------------------------------------------------
/RGBSync+/RGBSync+.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.27703.2018
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RGBSync+", "RGBSync+.csproj", "{C6BF4357-07D9-496B-9630-A26568D30723}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {C6BF4357-07D9-496B-9630-A26568D30723}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {C6BF4357-07D9-496B-9630-A26568D30723}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {C6BF4357-07D9-496B-9630-A26568D30723}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {C6BF4357-07D9-496B-9630-A26568D30723}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {3AD1163D-9F77-43AB-A3BA-38C1B9CCBA87}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/RGBSync+/Resources/RGBSync+.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/RGBSync+/Resources/argebee.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarthAffe/RGBSyncPlus/6ea97964cc6444e545906aea74e9813adb3994a1/RGBSync+/Resources/argebee.ico
--------------------------------------------------------------------------------
/RGBSync+/Resources/arrow_down.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarthAffe/RGBSyncPlus/6ea97964cc6444e545906aea74e9813adb3994a1/RGBSync+/Resources/arrow_down.png
--------------------------------------------------------------------------------
/RGBSync+/Resources/arrow_up.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarthAffe/RGBSyncPlus/6ea97964cc6444e545906aea74e9813adb3994a1/RGBSync+/Resources/arrow_up.png
--------------------------------------------------------------------------------
/RGBSync+/Resources/background.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarthAffe/RGBSyncPlus/6ea97964cc6444e545906aea74e9813adb3994a1/RGBSync+/Resources/background.png
--------------------------------------------------------------------------------
/RGBSync+/Resources/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarthAffe/RGBSyncPlus/6ea97964cc6444e545906aea74e9813adb3994a1/RGBSync+/Resources/close.png
--------------------------------------------------------------------------------
/RGBSync+/Resources/font.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarthAffe/RGBSyncPlus/6ea97964cc6444e545906aea74e9813adb3994a1/RGBSync+/Resources/font.ttf
--------------------------------------------------------------------------------
/RGBSync+/Resources/minimize.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarthAffe/RGBSyncPlus/6ea97964cc6444e545906aea74e9813adb3994a1/RGBSync+/Resources/minimize.png
--------------------------------------------------------------------------------
/RGBSync+/Resources/navigation.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/DarthAffe/RGBSyncPlus/6ea97964cc6444e545906aea74e9813adb3994a1/RGBSync+/Resources/navigation.ttf
--------------------------------------------------------------------------------
/RGBSync+/Styles/BlurredDecorationWindow.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
20 |
21 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/Button.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/CachedResourceDictionary.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Windows;
5 |
6 | namespace RGBSyncPlus.Styles
7 | {
8 | public class CachedResourceDictionary : ResourceDictionary
9 | {
10 | #region Properties & Fields
11 |
12 | // ReSharper disable InconsistentNaming
13 | private static readonly List _cachedDictionaries = new List();
14 | private static readonly ResourceDictionary _innerDictionary = new ResourceDictionary();
15 | // ReSharper restore
16 |
17 | public new Uri Source
18 | {
19 | get => null;
20 | set
21 | {
22 | lock (_innerDictionary)
23 | {
24 | UpdateCache(value);
25 |
26 | MergedDictionaries.Clear();
27 | MergedDictionaries.Add(_innerDictionary);
28 | }
29 | }
30 | }
31 |
32 | #endregion
33 |
34 | #region Methods
35 |
36 | private static void UpdateCache(Uri source)
37 | {
38 | string uriPath = source.OriginalString;
39 | if (_cachedDictionaries.Contains(uriPath)) return;
40 |
41 | _cachedDictionaries.Add(uriPath);
42 |
43 | ResourceDictionary newDictionary = new ResourceDictionary { Source = new Uri(uriPath, source.IsAbsoluteUri ? UriKind.Absolute : UriKind.Relative) };
44 | CopyDictionaryEntries(newDictionary, _innerDictionary);
45 | }
46 |
47 | private static void CopyDictionaryEntries(IDictionary source, IDictionary target)
48 | {
49 | foreach (object key in source.Keys)
50 | if (!target.Contains(key))
51 | target.Add(key, source[key]);
52 | }
53 |
54 | #endregion
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/ColorSelector.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
10 |
11 |
13 |
14 |
15 |
16 |
20 |
21 |
23 |
24 |
25 |
26 |
31 |
32 |
36 |
37 |
57 |
58 |
111 |
112 |
303 |
304 |
305 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/ComboBox.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
32 |
33 |
35 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
71 |
74 |
75 |
76 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/Form.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
19 |
20 |
46 |
47 |
55 |
56 |
79 |
80 |
97 |
98 |
99 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/FrameworkElement.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/GradientEditor.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
42 |
43 |
91 |
92 |
93 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/GroupBox.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/ImageButton.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
68 |
69 |
105 |
106 |
114 |
115 |
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/ListBox.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
147 |
148 |
162 |
163 |
164 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/Navigation.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
98 |
99 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/Slider.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/TextBox.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
43 |
44 |
45 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/Theme.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 | #FFDCDCDC
7 | #FF2A2A2A
8 | #B82A2A2A
9 | #111111
10 | #B8111111
11 | #60111111
12 | #50000000
13 | #FFE135
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | #60111111
53 | #B8111111
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 | 40
69 |
70 |
71 |
72 | 14
73 | 14
74 | 22
75 |
76 |
--------------------------------------------------------------------------------
/RGBSync+/Styles/ToolTip.xaml:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
29 |
30 |
31 |
--------------------------------------------------------------------------------
/RGBSync+/UI/ConfigurationViewModel.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections;
3 | using System.Collections.Generic;
4 | using System.Collections.ObjectModel;
5 | using System.ComponentModel;
6 | using System.Diagnostics;
7 | using System.Linq;
8 | using System.Reflection;
9 | using System.Windows;
10 | using System.Windows.Data;
11 | using GongSolutions.Wpf.DragDrop;
12 | using RGB.NET.Core;
13 | using RGBSyncPlus.Helper;
14 | using RGBSyncPlus.Model;
15 |
16 | namespace RGBSyncPlus.UI
17 | {
18 | public sealed class ConfigurationViewModel : AbstractBindable, IDropTarget
19 | {
20 | #region Properties & Fields
21 |
22 | public Version Version => Assembly.GetEntryAssembly().GetName().Version;
23 |
24 | public double UpdateRate
25 | {
26 | get => 1.0 / ApplicationManager.Instance.UpdateTrigger.UpdateFrequency;
27 | set
28 | {
29 | double val = MathHelper.Clamp(value, 1, 100);
30 | ApplicationManager.Instance.Settings.UpdateRate = val;
31 | ApplicationManager.Instance.UpdateTrigger.UpdateFrequency = 1.0 / val;
32 | OnPropertyChanged();
33 | }
34 | }
35 |
36 | private ObservableCollection _syncGroups;
37 | public ObservableCollection SyncGroups
38 | {
39 | get => _syncGroups;
40 | set => SetProperty(ref _syncGroups, value);
41 | }
42 |
43 | private SyncGroup _selectedSyncGroup;
44 | public SyncGroup SelectedSyncGroup
45 | {
46 | get => _selectedSyncGroup;
47 | set
48 | {
49 | if (SetProperty(ref _selectedSyncGroup, value))
50 | UpdateLedLists();
51 | }
52 | }
53 |
54 | private ListCollectionView _availableSyncLeds;
55 | public ListCollectionView AvailableSyncLeds
56 | {
57 | get => _availableSyncLeds;
58 | set => SetProperty(ref _availableSyncLeds, value);
59 | }
60 |
61 | private ListCollectionView _availableLeds;
62 | public ListCollectionView AvailableLeds
63 | {
64 | get => _availableLeds;
65 | set => SetProperty(ref _availableLeds, value);
66 | }
67 |
68 | private ListCollectionView _synchronizedLeds;
69 | public ListCollectionView SynchronizedLeds
70 | {
71 | get => _synchronizedLeds;
72 | set => SetProperty(ref _synchronizedLeds, value);
73 | }
74 |
75 | #endregion
76 |
77 | #region Commands
78 |
79 | private ActionCommand _openHomepageCommand;
80 | public ActionCommand OpenHomepageCommand => _openHomepageCommand ?? (_openHomepageCommand = new ActionCommand(OpenHomepage));
81 |
82 | private ActionCommand _addSyncGroupCommand;
83 | public ActionCommand AddSyncGroupCommand => _addSyncGroupCommand ?? (_addSyncGroupCommand = new ActionCommand(AddSyncGroup));
84 |
85 | private ActionCommand _removeSyncGroupCommand;
86 | public ActionCommand RemoveSyncGroupCommand => _removeSyncGroupCommand ?? (_removeSyncGroupCommand = new ActionCommand(RemoveSyncGroup));
87 |
88 | #endregion
89 |
90 | #region Constructors
91 |
92 | public ConfigurationViewModel()
93 | {
94 | SyncGroups = new ObservableCollection(ApplicationManager.Instance.Settings.SyncGroups);
95 |
96 | AvailableSyncLeds = GetGroupedLedList(RGBSurface.Instance.Leds.Where(x => x.Device.DeviceInfo.SupportsSyncBack));
97 | OnPropertyChanged(nameof(AvailableSyncLeds));
98 | }
99 |
100 | #endregion
101 |
102 | #region Methods
103 |
104 | private ListCollectionView GetGroupedLedList(IEnumerable leds) => GetGroupedLedList(leds.Select(led => new SyncLed(led)).ToList());
105 |
106 | private ListCollectionView GetGroupedLedList(IList syncLeds)
107 | {
108 | ListCollectionView collectionView = new ListCollectionView(syncLeds);
109 | collectionView.GroupDescriptions.Add(new PropertyGroupDescription(nameof(SyncLed.Device)));
110 | collectionView.SortDescriptions.Add(new SortDescription(nameof(SyncLed.Device), ListSortDirection.Ascending));
111 | collectionView.SortDescriptions.Add(new SortDescription(nameof(SyncLed.LedId), ListSortDirection.Ascending));
112 | collectionView.Refresh();
113 | return collectionView;
114 | }
115 |
116 | private void UpdateLedLists()
117 | {
118 | SynchronizedLeds = GetGroupedLedList(SelectedSyncGroup.Leds);
119 | OnPropertyChanged(nameof(SynchronizedLeds));
120 |
121 | AvailableLeds = GetGroupedLedList(RGBSurface.Instance.Leds.Where(led => !SelectedSyncGroup.Leds.Any(sc => (sc.LedId == led.Id) && (sc.Device == led.Device.GetDeviceName()))));
122 | OnPropertyChanged(nameof(AvailableLeds));
123 | }
124 |
125 | private void OpenHomepage() => Process.Start("https://github.com/DarthAffe/RGBSyncPlus");
126 |
127 | private void AddSyncGroup()
128 | {
129 | SyncGroup syncGroup = new SyncGroup();
130 | SyncGroups.Add(syncGroup);
131 | ApplicationManager.Instance.AddSyncGroup(syncGroup);
132 | }
133 |
134 | private void RemoveSyncGroup(SyncGroup syncGroup)
135 | {
136 | if (syncGroup == null) return;
137 |
138 | if (MessageBox.Show($"Are you sure that you want to delete the group '{syncGroup.DisplayName}'", "Remove Sync-Group", MessageBoxButton.YesNo) == MessageBoxResult.No)
139 | return;
140 |
141 | SyncGroups.Remove(syncGroup);
142 | ApplicationManager.Instance.RemoveSyncGroup(syncGroup);
143 | }
144 |
145 | void IDropTarget.DragOver(IDropInfo dropInfo)
146 | {
147 | if ((dropInfo.Data is SyncLed || dropInfo.Data is IEnumerable) && (dropInfo.TargetCollection is ListCollectionView))
148 | {
149 | dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;
150 | dropInfo.Effects = DragDropEffects.Copy;
151 | }
152 | }
153 |
154 | void IDropTarget.Drop(IDropInfo dropInfo)
155 | {
156 | if (!(dropInfo.TargetCollection is ListCollectionView targetList)) return;
157 |
158 | //HACK DarthAffe 04.06.2018: Super ugly hack - I've no idea how to do this correctly ...
159 | ListCollectionView sourceList = targetList == AvailableLeds ? SynchronizedLeds : AvailableLeds;
160 |
161 | if (dropInfo.Data is SyncLed syncLed)
162 | {
163 | targetList.AddNewItem(syncLed);
164 | sourceList.Remove(syncLed);
165 |
166 | targetList.CommitNew();
167 | sourceList.CommitEdit();
168 | }
169 | else if (dropInfo.Data is IEnumerable syncLeds)
170 | {
171 | foreach (SyncLed led in syncLeds)
172 | {
173 | targetList.AddNewItem(led);
174 | sourceList.Remove(led);
175 | }
176 | targetList.CommitNew();
177 | sourceList.CommitEdit();
178 | }
179 | }
180 |
181 | #endregion
182 | }
183 | }
184 |
--------------------------------------------------------------------------------
/RGBSync+/UI/ConfigurationWindow.xaml:
--------------------------------------------------------------------------------
1 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
43 |
44 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
88 |
90 |
91 |
93 |
96 |
97 |
98 |
99 |
100 |
103 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
156 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
176 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
216 |
217 |
218 |
220 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
--------------------------------------------------------------------------------
/RGBSync+/UI/ConfigurationWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using RGBSyncPlus.Controls;
3 |
4 | namespace RGBSyncPlus.UI
5 | {
6 | public partial class ConfigurationWindow : BlurredDecorationWindow
7 | {
8 | public ConfigurationWindow() => InitializeComponent();
9 |
10 | //DarthAffe 07.02.2018: This prevents the applicaiton from not shutting down and crashing afterwards if 'close' is selected in the taskbar-context-menu
11 | private void ConfigurationWindow_OnClosed(object sender, EventArgs e)
12 | {
13 | ApplicationManager.Instance.ExitCommand.Execute(null);
14 | }
15 | }
16 | }
17 |
--------------------------------------------------------------------------------