Skip to content

Commit 678d096

Browse files
committed
Enable wallpaper sink to set individual wallpapers per screen
1 parent 03a63af commit 678d096

16 files changed

+315
-49
lines changed

AllMyLights.Test/Connectors/WallpaperSinkTest.cs

+43-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
using System.Collections.Generic;
12
using System.IO;
23
using AllMyLights.Connectors.Sinks.Wallpaper;
3-
using AllMyLights.Models.OpenRGB;
44
using AllMyLights.Platforms;
55
using Moq;
6+
using Newtonsoft.Json.Linq;
67
using NUnit.Framework;
78

89
namespace AllMyLights.Test
@@ -23,6 +24,26 @@ public void Should_set_background()
2324
desktopMock.Verify();
2425
}
2526

27+
[Test]
28+
public void Should_set_background_per_screen()
29+
{
30+
var input = JObject.Parse(@"{""0"": ""C:\\absolute\\path\\batman.jpg"", ""1"": ""C:\\absolute\\path\\joker.jpg""}");
31+
32+
var expectedFilePathByScreen = new Dictionary<int, string>()
33+
{
34+
{ 0, @"C:\absolute\path\batman.jpg" },
35+
{ 1, @"C:\absolute\path\joker.jpg" },
36+
};
37+
38+
var desktopMock = new Mock<IDesktop>();
39+
desktopMock.Setup(it => it.SetBackgrounds(expectedFilePathByScreen)).Verifiable();
40+
41+
var sink = new WallpaperSink(new WallpaperSinkOptions(), desktopMock.Object);
42+
sink.Consume(input);
43+
44+
desktopMock.Verify();
45+
}
46+
2647
[Test]
2748
public void Should_do_nothing_on_receiving_the_same_value_twice()
2849
{
@@ -58,5 +79,26 @@ public void Should_prepend_configured_directory_to_relative_paths()
5879

5980
desktopMock.Verify(it => it.SetBackground(expected));
6081
}
82+
83+
[Test]
84+
public void Should_prepend_configured_directory_to_relative_paths_for_each_display()
85+
{
86+
var input = JObject.Parse(@"{""0"": ""relative\\path\\batman.jpg"", ""1"": ""relative\\path\\alfred.jpg""}");
87+
88+
var expectedFilePathByScreen = new Dictionary<int, string>()
89+
{
90+
{ 0, @"D:\wayne\enterprises\relative\path\batman.jpg" },
91+
{ 1, @"D:\wayne\enterprises\relative\path\alfred.jpg" },
92+
};
93+
94+
var desktopMock = new Mock<IDesktop>();
95+
desktopMock.Setup(it => it.SetBackgrounds(expectedFilePathByScreen)).Verifiable();
96+
97+
var relativeTo = @"D:\wayne\enterprises";
98+
var sink = new WallpaperSink(new WallpaperSinkOptions() { RelativeTo = relativeTo }, desktopMock.Object);
99+
sink.Consume(input);
100+
101+
desktopMock.Verify();
102+
}
61103
}
62104
}

AllMyLights.Test/Transformations/MappingTransformationTest.cs

+21-8
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using AllMyLights.Transformations;
77
using AllMyLights.Transformations.Mapping;
88
using Microsoft.Reactive.Testing;
9+
using Newtonsoft.Json.Linq;
910
using NUnit.Framework;
1011

1112
namespace AllMyLights.Test
@@ -22,6 +23,18 @@ public void Should_match_simple_string()
2223
.Verify();
2324
}
2425

26+
[Test]
27+
public void Should_match_simple_string_and_return_object()
28+
{
29+
var to = new JObject();
30+
31+
new Validator()
32+
.AddMapping("red", to)
33+
.StartWith("red")
34+
.ExpectOutput(to)
35+
.Verify();
36+
}
37+
2538
[Test]
2639
public void Should_match_regex_and_replace_substitutions()
2740
{
@@ -61,7 +74,7 @@ private class Validator
6174
};
6275

6376
private string Input { get; set; }
64-
private string Output { get; set; }
77+
private object Output { get; set; }
6578
private bool ShouldReturnEmpty { get; set; } = false;
6679

6780
public Validator StartWith(string input)
@@ -70,12 +83,12 @@ public Validator StartWith(string input)
7083
return this;
7184
}
7285

73-
public Validator AddMapping(string match, string substitute)
86+
public Validator AddMapping(string match, object to)
7487
{
7588
Options.Mappings.Add(new MappingTransformationOptions.Mapping()
7689
{
7790
From = match,
78-
To = substitute
91+
To = to
7992
});
8093
return this;
8194
}
@@ -86,7 +99,7 @@ public Validator FailOnMiss()
8699
return this;
87100
}
88101

89-
public Validator ExpectOutput(string output)
102+
public Validator ExpectOutput(object output)
90103
{
91104
Output = output;
92105
return this;
@@ -115,16 +128,16 @@ public void Verify()
115128
if (ShouldReturnEmpty)
116129
{
117130

118-
var expected = new Recorded<Notification<string>>[] {
119-
OnCompleted<string>(10)
131+
var expected = new Recorded<Notification<object>>[] {
132+
OnCompleted<object>(10)
120133
};
121134
ReactiveAssert.AreElementsEqual(expected, actual.Messages);
122135
}
123136
else
124137
{
125-
var expected = new Recorded<Notification<string>>[] {
138+
var expected = new Recorded<Notification<object>>[] {
126139
OnNext(10, Output),
127-
OnCompleted<string>(10)
140+
OnCompleted<object>(10)
128141
};
129142
ReactiveAssert.AreElementsEqual(expected, actual.Messages);
130143
}

AllMyLights/Connectors/ConnectorFactory.cs

-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
using AllMyLights.Connectors.Sources.Mqtt;
1212
using AllMyLights.Connectors.Sources.OpenRGB;
1313
using AllMyLights.Extensions;
14-
using AllMyLights.Models.OpenRGB;
1514
using AllMyLights.Platforms;
1615
using MQTTnet;
1716
using MQTTnet.Extensions.ManagedClient;

AllMyLights/Connectors/Sinks/SinkOptions.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
using System.Runtime.Serialization;
22
using AllMyLights.Connectors.Sinks.Chroma;
33
using AllMyLights.Connectors.Sinks.OpenRGB;
4+
using AllMyLights.Connectors.Sinks.Wallpaper;
45
using AllMyLights.JsonConverters;
5-
using AllMyLights.Models.OpenRGB;
66
using Newtonsoft.Json;
77

88
namespace AllMyLights.Connectors.Sinks

AllMyLights/Connectors/Sinks/Wallpaper/WallpaperSink.cs

+39-11
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.IO;
34
using System.Linq;
45
using System.Reactive.Linq;
5-
using AllMyLights.Models.OpenRGB;
6+
using AllMyLights.Extensions;
67
using AllMyLights.Platforms;
8+
using Newtonsoft.Json;
9+
using Newtonsoft.Json.Linq;
710
using NLog;
811

912
namespace AllMyLights.Connectors.Sinks.Wallpaper
@@ -22,27 +25,52 @@ public WallpaperSink(WallpaperSinkOptions options, IDesktop desktop): base(optio
2225
{
2326
Desktop = desktop;
2427
RelativeTo = options.RelativeTo;
25-
Next.DistinctUntilChanged().Subscribe((value) =>
28+
Next.DistinctUntilChanged().Subscribe((raw) =>
2629
{
27-
if(value is string)
30+
Logger.Debug(@$"{ToString()} received value {raw})");
31+
32+
if (raw is string value)
2833
{
29-
Logger.Debug(@$"{nameof(WallpaperSink)} received value {value}. Applying background. {(!string.IsNullOrEmpty(RelativeTo) ? $"Relative to: {RelativeTo}" : "")}");
30-
Desktop.SetBackground(PrependRelativeTo(value as string));
31-
} else
34+
Logger.Debug($"Applying background. {RelativeTo?.Let((it) => $"Relative to: {it}") ?? ""}");
35+
Desktop.SetBackground(PrependRelativeTo(value));
36+
return;
37+
}
38+
39+
40+
if (raw is JObject mapping)
3241
{
33-
Logger.Error($"Received value {value} cannot be consumed by {nameof(WallpaperSink)}");
42+
try
43+
{
44+
Logger.Debug("Assuming that received value is mapping of file path to display name.");
45+
var filePathByScreen = mapping.ToObject<Dictionary<int, string>>()
46+
.ToDictionary(pair => pair.Key, pair => PrependRelativeTo(pair.Value));
47+
48+
Logger.Debug(() => $"Activating the following wallpapers: {JsonConvert.SerializeObject(filePathByScreen)}");
49+
Desktop.SetBackgrounds(filePathByScreen);
50+
}
51+
catch(JsonReaderException e)
52+
{
53+
Logger.Error($"The provided mapping is invalid: {e.Message}");
54+
}
55+
catch(Exception e)
56+
{
57+
Logger.Error(e.Message);
58+
}
59+
return;
3460
}
61+
62+
63+
64+
Logger.Error($"Received value {raw} cannot be consumed by {nameof(WallpaperSink)}");
3565
});
3666
}
3767

3868
public override object GetInfo()
3969
{
40-
if (string.IsNullOrEmpty(RelativeTo)) return null;
41-
4270
try
4371
{
44-
string[] files = Directory.GetFiles(RelativeTo);
45-
return $"Available file names under specified directory {RelativeTo}: {string.Join(", ", files.Select((it) => Path.GetFileName(it)))}";
72+
string[] files = !string.IsNullOrEmpty(RelativeTo) ? Directory.GetFiles(RelativeTo) : null;
73+
return new WallpaperSinkInfo(RelativeTo, files, Desktop.GetScreens());
4674
}
4775
catch(Exception e)
4876
{
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
using System.Collections.Generic;
2+
using Newtonsoft.Json;
3+
4+
namespace AllMyLights.Connectors.Sinks.Wallpaper
5+
{
6+
public struct WallpaperSinkInfo
7+
{
8+
public WallpaperSinkInfo(
9+
string relativeTo,
10+
IEnumerable<string> imageFiles,
11+
IEnumerable<int> screens)
12+
{
13+
RelativeTo = relativeTo;
14+
ImageFiles = imageFiles;
15+
Screens = screens;
16+
}
17+
18+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
19+
public string RelativeTo { get; }
20+
21+
22+
[JsonProperty(NullValueHandling = NullValueHandling.Ignore, PropertyName = "Available file names under specified directory")]
23+
public IEnumerable<string> ImageFiles { get; }
24+
public IEnumerable<int> Screens { get; }
25+
}
26+
}

AllMyLights/Connectors/Sinks/Wallpaper/WallpaperSinkOptions.cs

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
using AllMyLights.Connectors.Sinks;
2-
3-
namespace AllMyLights.Models.OpenRGB
1+
namespace AllMyLights.Connectors.Sinks.Wallpaper
42
{
53
public class WallpaperSinkOptions: SinkOptions
64
{

AllMyLights/Extensions/Objects.cs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Text;
4+
5+
namespace AllMyLights.Extensions
6+
{
7+
public static class Objects
8+
{
9+
public static R Let<T, R>(this T self, Func<T, R> block)
10+
{
11+
return block(self);
12+
}
13+
}
14+
}

AllMyLights/Platforms/Desktop.cs

+4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Runtime.InteropServices;
34
using AllMyLights.Platforms.Windows;
45
using NLog;
@@ -19,6 +20,9 @@ public static Desktop GetPlatformInstance()
1920
return null;
2021
}
2122

23+
public abstract IEnumerable<int> GetScreens();
24+
2225
public abstract void SetBackground(string filePath);
26+
public abstract void SetBackgrounds(Dictionary<int, string> filePathByScreen);
2327
}
2428
}

AllMyLights/Platforms/IDesktop.cs

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
1-
namespace AllMyLights.Platforms
1+
using System.Collections.Generic;
2+
3+
namespace AllMyLights.Platforms
24
{
35
public interface IDesktop
46
{
57
void SetBackground(string filePath);
8+
void SetBackgrounds(Dictionary<int, string> filePathByScreen);
9+
IEnumerable<int> GetScreens();
610
}
711
}

0 commit comments

Comments
 (0)