-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #133 from pre-martin/feature/flags-with-custom-images
Flags with custom images
- Loading branch information
Showing
43 changed files
with
1,144 additions
and
166 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
namespace StreamDeckSimHub.Plugin.Actions; | ||
|
||
/// <summary> | ||
/// Settings for Flags Action, which are set in the Stream Deck UI. | ||
/// </summary> | ||
public class FlagsSettings | ||
{ | ||
public string NoFlag { get; set; } = "flags/flag-none.svg"; | ||
public string BlackFlag { get; set; } = "flags/flag-black.svg"; | ||
public string BlueFlag { get; set; } = "flags/flag-blue.svg"; | ||
public string CheckeredFlag { get; set; } = "flags/flag-checkered.svg"; | ||
public string GreenFlag { get; set; } = "flags/flag-green.svg"; | ||
public string OrangeFlag { get; set; } = "flags/flag-orange.svg"; | ||
public string WhiteFlag { get; set; } = "flags/flag-white.svg"; | ||
public string YellowFlag { get; set; } = "flags/flag-yellow.svg"; | ||
public string YellowFlagSec1 { get; set; } = "flags/flag-yellow-s1.png"; | ||
public string YellowFlagSec2 { get; set; } = "flags/flag-yellow-s2.png"; | ||
public string YellowFlagSec3 { get; set; } = "flags/flag-yellow-s3.png"; | ||
|
||
public override string ToString() | ||
{ | ||
return | ||
$"No: {NoFlag}, Black: {BlackFlag}, Blue: {BlueFlag}, Checkered: {CheckeredFlag}, Green: {GreenFlag}, Orange: {OrangeFlag}, White: {WhiteFlag}, Yellow: {YellowFlag}, YellowFlagSec1: {YellowFlagSec1}, YellowFlagSec2: {YellowFlagSec2}, YellowFlagSec3: {YellowFlagSec3}"; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,8 @@ | |
<PackageReference Include="NLog" Version="5.3.3" /> | ||
<PackageReference Include="NLog.Extensions.Logging" Version="5.3.10" /> | ||
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="2.1.4" /> | ||
<PackageReference Include="Svg.Skia" Version="2.0.0.1" /> | ||
<PackageReference Include="TestableIO.System.IO.Abstractions.Wrappers" Version="21.0.29" /> | ||
<Reference Include="SharpDeck"> | ||
<HintPath>..\lib\SharpDeck.dll</HintPath> | ||
</Reference> | ||
|
@@ -83,6 +85,12 @@ | |
<None Update="pi\js\dial.js"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="pi\flags.html"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="pi\js\flags.js"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\actions\dial.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
|
@@ -146,25 +154,10 @@ | |
<None Update="images\icons\dial.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\icons\flag-black.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\icons\flag-blue.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\icons\flag-checkered.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\icons\flag-green.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\icons\flag-orange.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\icons\flag-white.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\icons\flag-yellow.svg"> | ||
<None Update="images\icons\undefined.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\icons\input.png"> | ||
|
@@ -215,6 +208,48 @@ | |
<None Update="pi\react\react.production.min.js"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-black.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-blue.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-checkered.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-green.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-none.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-orange.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-white.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-yellow.svg"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-yellow-s1.png"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-yellow-s2.png"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\flag-yellow-s3.png"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\[email protected]"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\[email protected]"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
<None Update="images\custom\flags\[email protected]"> | ||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> | ||
</None> | ||
</ItemGroup> | ||
|
||
<ItemGroup Label="streamdeck-javascript-sdk"> | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,85 @@ | ||
// Copyright (C) 2024 Martin Renner | ||
// LGPL-3.0-or-later (see file COPYING and COPYING.LESSER) | ||
|
||
using System.IO.Abstractions; | ||
using System.Text.RegularExpressions; | ||
using NLog; | ||
using SixLabors.ImageSharp; | ||
|
||
namespace StreamDeckSimHub.Plugin.Tools; | ||
|
||
public class ImageManager(IFileSystem fileSystem, ImageUtils imageUtils) | ||
{ | ||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger(); | ||
private static readonly string[] SupportedExtensions = [".svg", ".png", ".jpg", ".jpeg", ".gif"]; | ||
private readonly IDirectoryInfo _customImagesDirectory = fileSystem.DirectoryInfo.New(Path.Combine("images", "custom")); | ||
|
||
/// <summary> | ||
/// Returns an array with all custom images. The images are returned with their relative path inside | ||
/// the "custom images" directory. Images with quality suffix in their name ("@2x") are excluded from the list. | ||
/// </summary> | ||
public string[] ListCustomImages() | ||
{ | ||
var imageQualityRegex = new Regex(@"@\dx\."); // "[email protected]", "[email protected]", ... | ||
try | ||
{ | ||
var fn = _customImagesDirectory.FullName; | ||
return _customImagesDirectory.GetFiles("*.*", SearchOption.AllDirectories) | ||
.Where(fileInfo => SupportedExtensions.Contains(fileInfo.Extension.ToLowerInvariant())) | ||
.Select(fileInfo => fileInfo.FullName[(fn.Length + 1)..]) | ||
.Select(fileName => imageQualityRegex.Replace(fileName, ".")) | ||
.Select(fileName => fileName.Replace(@"\", "/")) | ||
.ToList() | ||
.Distinct() | ||
.OrderBy(fileName => fileName.Count(c => c == '/') + fileName) | ||
.ToArray(); | ||
} | ||
catch (Exception e) | ||
{ | ||
Logger.Error($"Could not load custom images: {e.Message}"); | ||
return []; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Returns an image from the "custom image" folder. | ||
/// </summary> | ||
/// <param name="relativePath">The relative path inside the "custom images" folder</param> | ||
/// <param name="sdKeyInfo">Information about the specific Stream Deck key or dial</param> | ||
/// <returns>The image in encoded form, or a default error image, if it could not be loaded.</returns> | ||
public Image GetCustomImage(string relativePath, StreamDeckKeyInfo sdKeyInfo) | ||
{ | ||
relativePath = relativePath.Replace('/', Path.DirectorySeparatorChar); | ||
if (Path.GetExtension(relativePath).Equals(".svg", StringComparison.InvariantCultureIgnoreCase)) | ||
{ | ||
// No quality suffix for SVG files. | ||
var fn = Path.Combine(_customImagesDirectory.FullName, relativePath); | ||
return imageUtils.FromSvgFile(fn, sdKeyInfo); | ||
} | ||
|
||
var newName = FindResolutionForKeyInfo(_customImagesDirectory.FullName, relativePath, sdKeyInfo); | ||
var newFn = Path.Combine(_customImagesDirectory.FullName, newName); | ||
try | ||
{ | ||
using var stream = fileSystem.File.OpenRead(newFn); | ||
return Image.Load(stream); | ||
} | ||
catch (Exception e) | ||
{ | ||
Logger.Warn($"Could not load custom image '{newFn}': {e.Message}"); | ||
return imageUtils.GetErrorImage(sdKeyInfo); | ||
} | ||
} | ||
|
||
private string FindResolutionForKeyInfo(string baseDir, string relativePath, StreamDeckKeyInfo sdKeyInfo) | ||
{ | ||
if (sdKeyInfo.IsHighRes) | ||
{ | ||
var extension = Path.GetExtension(relativePath); | ||
var hqFile = relativePath[..relativePath.LastIndexOf('.')] + "@2x" + extension; | ||
if (fileSystem.File.Exists(Path.Combine(baseDir, hqFile))) return hqFile; | ||
} | ||
|
||
return relativePath; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.