Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ site/
Thumbs.db
*.lscache
/plugin-out
/.cr
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,17 @@ Notes:

---

## v1.2.3.0 - Minor Release

### Features / Improvements

- Added a `Touch Strip Text` toggle for `Adaptive Dial` so the dial title can be shown or hidden on the Stream Deck+ touch strip.

### Bug Fixes

- Reworked the Adaptive Dial feedback layouts to remove the default grey bottom-right bar.
- Increased the usable icon area and balanced the captioned layout so the icon no longer looks cramped next to the touch-strip text.

## v1.2.2.1 - Build Release

### Internal / Refactor
Expand Down
63 changes: 63 additions & 0 deletions PluginCore/ActionKeys/SCDialActionBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@ namespace SCStreamDeck.ActionKeys;
/// </summary>
public abstract class SCDialActionBase : EncoderBase
{
private const string DefaultDialTitle = "Adaptive Dial";
private const string DialLayoutNoCaption = "Layouts/adaptiveDial.json";
private const string DialLayoutWithCaption = "Layouts/adaptiveDial.caption.json";

private string _customDialTitle = DefaultDialTitle;
private string? _activeDialLayout;

[ExcludeFromCodeCoverage]
protected SCDialActionBase(SDConnection connection, InitialPayload payload) : base(connection, payload)
{
Expand All @@ -39,6 +46,7 @@ protected SCDialActionBase(SDConnection connection, InitialPayload payload) : ba
InitializationService.KeybindingsStateChanged += OnKeybindingsStateChanged;
PluginLocaleService.LocaleChanged += OnPluginLocaleChanged;
Connection.OnPropertyInspectorDidAppear += OnPropertyInspectorDidAppear;
Connection.OnTitleParametersDidChange += OnTitleParametersDidChange;
Connection.OnSendToPlugin += OnSendToPlugin;

TryMigrateFunctionSettingsIfPossible();
Expand All @@ -47,6 +55,8 @@ protected SCDialActionBase(SDConnection connection, InitialPayload payload) : ba
{
SendPropertyInspectorUpdate();
}

SendDialTextUpdate();
}

private InitializationService InitializationService { get; }
Expand Down Expand Up @@ -99,6 +109,7 @@ public override void OnTick()
public override void Dispose()
{
Connection.OnPropertyInspectorDidAppear -= OnPropertyInspectorDidAppear;
Connection.OnTitleParametersDidChange -= OnTitleParametersDidChange;
Connection.OnSendToPlugin -= OnSendToPlugin;
InitializationService.KeybindingsStateChanged -= OnKeybindingsStateChanged;
PluginLocaleService.LocaleChanged -= OnPluginLocaleChanged;
Expand All @@ -116,10 +127,44 @@ public override void ReceivedSettings(ReceivedSettingsPayload payload)
}

TryMigrateFunctionSettingsIfPossible();
SendDialTextUpdate();
}

private void SendPropertyInspectorUpdate() => _ = SendPropertyInspectorUpdateAsync();

private void SendDialTextUpdate() => _ = UpdateDialTextAsync();

private async Task UpdateDialTextAsync()
{
try
{
bool showText = Settings.ShowTouchText;
string targetLayout = showText ? DialLayoutWithCaption : DialLayoutNoCaption;

if (!string.Equals(_activeDialLayout, targetLayout, StringComparison.Ordinal))
{
await Connection.SetFeedbackLayoutAsync(targetLayout).ConfigureAwait(false);
_activeDialLayout = targetLayout;
}

string caption = showText ? BuildTouchStripText() : string.Empty;

await Connection.SetFeedbackAsync(new JObject
{
["caption"] = caption
}).ConfigureAwait(false);
}
catch (Exception ex)
{
Log.Err($"[{GetType().Name}] Failed to update dial text: {ex.Message}", ex);
}
}

private string BuildTouchStripText()
{
return string.IsNullOrWhiteSpace(_customDialTitle) ? DefaultDialTitle : _customDialTitle;
}

private async Task SendPropertyInspectorUpdateAsync()
{
PluginLocaleResolution pluginLocale = await GetPluginLocaleResolutionAsync().ConfigureAwait(false);
Expand Down Expand Up @@ -171,10 +216,28 @@ private async Task<PluginLocaleResolution> GetPluginLocaleResolutionAsync()
private void OnPropertyInspectorDidAppear(object? sender, SDEventReceivedEventArgs<PropertyInspectorDidAppear> e) =>
SendPropertyInspectorUpdate();

private void OnTitleParametersDidChange(object? sender, SDEventReceivedEventArgs<TitleParametersDidChange> e)
{
try
{
string? incomingTitle = e.Event?.Payload?.Title;
_customDialTitle = string.IsNullOrWhiteSpace(incomingTitle)
? DefaultDialTitle
: incomingTitle.Trim();

SendDialTextUpdate();
}
catch (Exception ex)
{
Log.Err($"[{GetType().Name}] Failed to process title update: {ex.Message}", ex);
}
}

private void OnKeybindingsStateChanged()
{
TryMigrateFunctionSettingsIfPossible();
SendPropertyInspectorUpdate();
SendDialTextUpdate();
}

private void OnPluginLocaleChanged() => SendPropertyInspectorUpdate();
Expand Down
3 changes: 3 additions & 0 deletions PluginCore/ActionKeys/Settings/DialSettings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,7 @@ public sealed class DialSettings

[JsonProperty(PropertyName = "clickSoundPath")]
public string? ClickSoundPath { get; set; }

[JsonProperty(PropertyName = "showTouchText")]
public bool ShowTouchText { get; set; } = false;
}
26 changes: 26 additions & 0 deletions PluginCore/Layouts/adaptiveDial.caption.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"id": "scsd-adaptive-dial-caption",
"items": [
{
"key": "background",
"type": "pixmap",
"rect": [0, 0, 200, 100],
"zOrder": 0,
"value": ""
},
{
"key": "icon",
"type": "pixmap",
"rect": [64, 0, 72, 72],
"zOrder": 1,
"value": ""
},
{
"key": "caption",
"type": "text",
"rect": [8, 78, 184, 20],
"zOrder": 2,
"value": ""
}
]
}
19 changes: 19 additions & 0 deletions PluginCore/Layouts/adaptiveDial.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"id": "scsd-adaptive-dial",
"items": [
{
"key": "background",
"type": "pixmap",
"rect": [0, 0, 200, 100],
"zOrder": 0,
"value": ""
},
{
"key": "icon",
"type": "pixmap",
"rect": [50, 0, 100, 100],
"zOrder": 1,
"value": ""
}
]
}
3 changes: 3 additions & 0 deletions PluginCore/PluginCore.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,9 @@
<Content Include="PropertyInspector\**\*.*" Exclude="PropertyInspector\**\src\**\*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Include="Layouts\**\*.*">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>

<Target Name="BuildPropertyInspectorAssets" BeforeTargets="CopyFilesToOutputDirectory">
Expand Down
11 changes: 11 additions & 0 deletions PluginCore/PropertyInspector/Dials/AdaptiveDial.html
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,17 @@
<div class="pi-file-picker" data-accept=".wav,.mp3" id="audioFilePicker"></div>
</div>
</div>

<div class="pi-section">
<div class="pi-picker-row">
<div class="pi-picker-label">Touch Strip Text</div>
<label class="checkable-container">
<input id="showTouchTextToggle" type="checkbox">
<span class="checkable-symbol" role="checkbox"></span>
<span class="checkable-text">Show</span>
</label>
</div>
</div>
</div>
</div>
</body>
Expand Down
2 changes: 1 addition & 1 deletion PluginCore/PropertyInspector/js/pi-dial-action.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions PluginCore/PropertyInspector/js/src/pi-dial-action.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,39 @@
settingsKey: 'clickSoundPath'
});

const showTouchTextToggle = document.getElementById('showTouchTextToggle');
function toBoolean(value, defaultValue = true) {
if (typeof value === 'boolean') {
return value;
}

if (typeof value === 'string') {
const normalized = value.trim().toLowerCase();
if (normalized === 'false' || normalized === '0' || normalized === 'off' || normalized === 'no') {
return false;
}

if (normalized === 'true' || normalized === '1' || normalized === 'on' || normalized === 'yes') {
return true;
}
}

return defaultValue;
}

const [getShowTouchText, setShowTouchText] = globalThis.SDPIComponents.useSettings(
'showTouchText',
(value) => {
if (showTouchTextToggle) {
showTouchTextToggle.checked = toBoolean(value, true);
}
}
);

showTouchTextToggle?.addEventListener('change', () => {
setShowTouchText(showTouchTextToggle.checked);
});

function flattenFunctionsData(groups) {
const flatten = SCPI?.functionPicker?.flattenFunctionsData;
if (typeof flatten !== 'function') {
Expand Down Expand Up @@ -218,6 +251,11 @@
});

SCPI?.util?.onDocumentReady?.(() => {
if (showTouchTextToggle) {
const current = getShowTouchText();
showTouchTextToggle.checked = toBoolean(current, true);
}

slotStates.forEach((slot) => {
const savedValue = slot.getValue();
slot.currentValue = savedValue || '';
Expand Down
2 changes: 1 addition & 1 deletion PluginCore/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"Encoder"
],
"Encoder": {
"layout": "$B1",
"layout": "Layouts/adaptiveDial.json",
"TriggerDescription": {
"Rotate": "Execute left or right function",
"Push": "Execute push function"
Expand Down
4 changes: 2 additions & 2 deletions Tests/Tests.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@

<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.15.8" />
<PackageReference Include="coverlet.collector" Version="10.0.0">
<PackageReference Include="coverlet.collector" Version="10.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
<PackageReference Include="FluentAssertions" Version="8.10.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.5.1" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="18.6.0" />
<PackageReference Include="Moq" Version="4.20.72" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="ReportGenerator" Version="5.5.10" />
Expand Down
Loading