Skip to content

Commit

Permalink
Add support for SD+
Browse files Browse the repository at this point in the history
With the release of SD+ you now have control over dials and touchscreen
on top of the usual buttons. Support adds a few new events received and
sent and new configuration objects like Encoder and Layout.
  • Loading branch information
rdohms committed Mar 21, 2023
1 parent 0289df8 commit da3a27b
Show file tree
Hide file tree
Showing 5 changed files with 440 additions and 0 deletions.
35 changes: 35 additions & 0 deletions src/Action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { ActionEvents } from "./events";
import { State, StateProps } from "./State";
import { Target } from "./Target";
import type { Plugin } from "./Plugin";
import { Encoder } from "./Encoder";

/**
* The Action must match a few files:
Expand Down Expand Up @@ -90,6 +91,8 @@ export class Action<
*/
public device = "";

public encoder: Encoder = undefined as unknown as Encoder;

constructor(params: {
name: string;
inspectorName?: string;
Expand Down Expand Up @@ -129,6 +132,8 @@ export class Action<
this.hasMultiActionSupport === false,
this.hasMultiActionSupport,
],
["Controllers", this.encoder !== undefined, ["KeyPad", "Encoder"]],
["Encoder", this.encoder !== undefined, this.encoder.toManifest()],
];

optionals.forEach(([prop, condition, value]) => {
Expand Down Expand Up @@ -406,4 +411,34 @@ export class Action<
payload: { profile },
});
}

/**
* Send event to dynamically change properties of the SD+ touch display
* @param {Record<string, unknown>} payload Key/Value pairs of properties to
* change
* @return {void}
*/
public setFeedback(payload: Record<string, unknown>) {
this.send({
event: "setFeedback",
context: this.context,
payload,
});
}

/**
* Send an event to dynamically change the layout of a SD+ touch display
* @param {string} layout Internal `id` of built-in layout or path to json
* file that contains a custom layout
* @return {void}
*/
public setFeedbackLayout(layout: string) {
this.send({
event: "setFeedbackLayout",
context: this.context,
payload: {
layout,
},
});
}
}
122 changes: 122 additions & 0 deletions src/Encoder.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
/**
* The encoder is used to configure the dial and display segment on an SD+.
* It is completely optional.
*/
export class Encoder {
/**
* Default background for the touch display slot
* @type {string}
*/
public background?: string;

/**
* Default icon for the Property Inspector, dial stack and layout. Falls back
* to the Action List Icon
*
* @type {string}
*/
public icon?: string;

/**
* Either a built-in layout (string) or a path to a JSON file that describes
* a custom layout. Can be changed with `setFeedbackLayout` event.
* @see Layout
* @type {string}
*/
public layout?: string;

/**
* The color used as the background of the Dial Stack
* @type {string}
*/
public stackColor?: string;

/**
* Part of TriggerDescription. Describes the action performed on rotation of
* the dial
* @type {string}
*/
public onRotateDescription?: string;

/**
* Part of TriggerDescription. Describes the action performed on pressing of
* the dial
* @type {string}
*/
public onPushDescription?: string;

/**
* Part of TriggerDescription. Describes the action performed on touching the
* display pad
* @type {string}
*/
public onTouchDescription?: string;

/**
* Part of TriggerDescription. Describes the action performed on long pressing
* the display pad
* @type {string}
*/
public onLongTouchDescription?: string;

public toManifest(): Record<string, unknown> {
const snippet: Record<string, unknown> = {
background: this.background,
Icon: this.icon,
layout: this.layout,
StackColor: this.stackColor,
TriggerDescription: {
Rotate: this.onRotateDescription,
Push: this.onPushDescription,
Touch: this.onTouchDescription,
LongTouch: this.onLongTouchDescription,
},
};

const optionals: [string, unknown, unknown][] = [
["background", this.background, this.background],
["Icon", this.icon, this.icon],
["layout", this.layout, this.layout],
["StackColor", this.stackColor, this.stackColor],
["StackColor", this.stackColor, this.stackColor],
[
"TriggerDescription",
this.onRotateDescription ||
this.onPushDescription ||
this.onTouchDescription ||
this.onLongTouchDescription,
this.buildTriggerDescription(),
],
];

this.evaluateOptionalValues(optionals, snippet);
return snippet;
}

private buildTriggerDescription() {
const snippet: Record<string, unknown> = {};

const optionals: [string, unknown, unknown][] = [
["Rotate", this.onRotateDescription, this.onRotateDescription],
["Push", this.onPushDescription, this.onPushDescription],
["Touch", this.onTouchDescription, this.onTouchDescription],
["LongTouch", this.onLongTouchDescription, this.onLongTouchDescription],
];

this.evaluateOptionalValues(optionals, snippet);
return snippet;
}

private evaluateOptionalValues(
optionals: [string, unknown, unknown][],
object: Record<string, unknown>,
): Record<string, unknown> {
optionals.forEach(([prop, condition, value]) => {
if (condition) {
object[prop] = value;
}
});

return object;
}
}
Loading

0 comments on commit da3a27b

Please sign in to comment.