...
 
Commits (6)
  • Wouter's avatar
    Fix plugin build on Windows · 2f7cd3ec
    Wouter authored
    Needs a separate .cmd file to flip the return code from
    DistributionTool. Doing it all straight from CMake doesn't seem to work
    very well.
    2f7cd3ec
  • Wouter's avatar
    Some license clarifications · ece99edc
    Wouter authored
    ece99edc
  • Wouter's avatar
    Remove some unused sample files · 6b164e80
    Wouter authored
    6b164e80
  • Wouter's avatar
    Various example cleanups and minor fixes · da824edb
    Wouter authored
    - Lots of template comments removed
    - Changed to 'oninput' change event for the property inspector
    - Implemented (empty) action configuration showing/hiding mechanism in
    property inspector
    - Implemented core localization using localize (and similar) attributes
    - Length labels (which count characters up to max length) must have
    'length-label' class (so we can use labels properly)
    - Allow saving empty values from PI back to the app
    da824edb
  • Wouter's avatar
    Add cheat action · dac83a96
    Wouter authored
    dac83a96
  • Wouter's avatar
    Define action category for all actions · 19641be0
    Wouter authored
    Moves them out of the "Custom" group in Stream Deck, into a "The Sims 4"
    group
    19641be0
......@@ -47,14 +47,14 @@ add_streamdeck_plugin(net.simply-life.sims4streamdeck
action/images/motherlode@2x.png
action/images/emote-plumbob.png
action/images/emote-plumbob@2x.png
action/images/cheat.png
action/images/cheat@2x.png
propertyinspector/css/caret.svg
propertyinspector/css/check.png
propertyinspector/css/elg_calendar.svg
propertyinspector/css/elg_calendar_inv.svg
propertyinspector/css/g_d8d8d8.svg
propertyinspector/css/rcheck.svg
propertyinspector/css/sdpi.css
propertyinspector/css/sims4streamdeck.css
propertyinspector/js/common.js
propertyinspector/js/common_pi.js
......
......@@ -22,3 +22,10 @@ The above copyright notice and this permission notice shall be included in all c
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================
All assets (graphics etc) in the `action` subdirectory:
Copyright 2019 Rosana Kooymans
Redistribution of these assets without explicit permission is prohibited.
......@@ -4,3 +4,22 @@ This plugin allows controlling The Sims 4 from your Stream Deck. Using the Remot
the game, this allows you to add buttons for cheats and other things - without even having to bring
up the cheat bar or messing around with key sequences.
# License and Credits
All custom parts are licensed under GPLv3. See the LICENSE file for details.
Some files are based on the Stream Deck SDK template plugin. To these files, the following license
applies:
```
The MIT License
Copyright 2018 Corsair Memory, Inc
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
```
......@@ -4,6 +4,10 @@ $SD.on('connected', (jsonObj) => connected(jsonObj));
function connected(jsn) {
$SD.on('net.simply-life.sims4streamdeck.motherlode.keyUp', (jsonObj) => motherlode.onKeyUp(jsonObj));
$SD.on('net.simply-life.sims4streamdeck.cheat.willAppear', (jsonObj) => cheat.onWillAppear(jsonObj));
$SD.on('net.simply-life.sims4streamdeck.cheat.didReceiveSettings', (jsonObj) => cheat.onDidReceiveSettings(jsonObj));
$SD.on('net.simply-life.sims4streamdeck.cheat.keyUp', (jsonObj) => cheat.onKeyUp(jsonObj));
};
function sims4_get_request(path, params) {
......@@ -22,9 +26,29 @@ function sims4_get_request(path, params) {
* Send the motherlode cheat to the game.
*/
const motherlode = {
settings:{},
onKeyUp: function (json) {
sims4_get_request('cheat/motherlode');
},
};
const cheat = {
defaultSettings: { cheat: '' },
settings: [],
onWillAppear: function (json) {
this.applySettings(json.context, Utils.getProp(json, 'payload.settings', this.defaultSettings))
},
onDidReceiveSettings: function (json) {
this.applySettings(json.context, Utils.getProp(json, 'payload.settings', this.settings[json.context]))
},
onKeyUp: function (json) {
sims4_get_request('cheat/' + this.settings[json.context].cheat);
},
applySettings: function (context, newSettings) {
this.settings[context] = newSettings
$SD.api.setTitle(context, newSettings.cheat)
},
};
......@@ -34,6 +34,8 @@ find_program(STREAMDECK_DISTRIBUTION_TOOL
DOC "DistributionTool executable from https://developer.elgato.com/documentation/stream-deck/sdk/exporting-your-plugin/"
)
set(_STREAM_DECK_PLUGIN_CMAKE_DIR ${CMAKE_CURRENT_LIST_DIR})
# Function to create a JavaScript-based .streamDeckPlugin file, from a set of HTML files and scripts.
#
# Usage:
......@@ -52,13 +54,24 @@ function(add_streamdeck_plugin PLUGIN_NAME)
list(APPEND DEST_FILES "${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_NAME}.sdPlugin/${_FILE}")
endforeach()
add_custom_command(OUTPUT "${PLUGIN_NAME}.streamDeckPlugin"
COMMAND ${CMAKE_COMMAND} -E remove "${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_NAME}.streamDeckPlugin"
COMMAND ! ${CMAKE_CROSSCOMPILING_EMULATOR} ${STREAMDECK_DISTRIBUTION_TOOL} "-b" "-i" "${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_NAME}.sdPlugin" "-o" "${CMAKE_CURRENT_BINARY_DIR}"
DEPENDS ${DEST_FILES}
VERBATIM
COMMENT "Packing scripts to ${PLUGIN_NAME}.streamDeckPlugin"
)
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows")
configure_file(${_STREAM_DECK_PLUGIN_CMAKE_DIR}/build_plugin.cmd.in build_plugin_${PLUGIN_NAME}.cmd @ONLY)
add_custom_command(OUTPUT "${PLUGIN_NAME}.streamDeckPlugin"
COMMAND ${CMAKE_COMMAND} -E remove "${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_NAME}.streamDeckPlugin"
COMMAND ${CMAKE_CURRENT_BINARY_DIR}/build_plugin_${PLUGIN_NAME}.cmd
DEPENDS ${DEST_FILES} ${CMAKE_CURRENT_BINARY_DIR}/build_plugin_${PLUGIN_NAME}.cmd
VERBATIM
COMMENT "Packing scripts to ${PLUGIN_NAME}.streamDeckPlugin"
)
else()
add_custom_command(OUTPUT "${PLUGIN_NAME}.streamDeckPlugin"
COMMAND ${CMAKE_COMMAND} -E remove "${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_NAME}.streamDeckPlugin"
COMMAND ! ${CMAKE_CROSSCOMPILING_EMULATOR} ${STREAMDECK_DISTRIBUTION_TOOL} "-b" "-i" "${CMAKE_CURRENT_BINARY_DIR}/${PLUGIN_NAME}.sdPlugin" "-o" "${CMAKE_CURRENT_BINARY_DIR}"
DEPENDS ${DEST_FILES}
VERBATIM
COMMENT "Packing scripts to ${PLUGIN_NAME}.streamDeckPlugin"
)
endif()
add_custom_target(${PLUGIN_NAME} ALL
DEPENDS ${PLUGIN_NAME}.streamDeckPlugin
......
:: Build @PLUGIN_NAME@.streamDeckPlugin
:: The DistributionTool returns 0 on failure, 1 on success. This is generally misinterpreted as
:: the reverse. This little script flips the original result and returns 0 on success, 1 on failure,
:: so the build system correctly knows if the build was successful or not.
::
:: This script must be invoked from the build directory where the plugin will be saved to.
@STREAMDECK_DISTRIBUTION_TOOL@ -b -i "@CMAKE_CURRENT_BINARY_DIR@\@PLUGIN_NAME@.sdPlugin" -o "@CMAKE_CURRENT_BINARY_DIR@"
IF %ERRORLEVEL% NEQ 0 (exit /b 0) ELSE (exit /b 1)
......@@ -6,10 +6,12 @@
"Name": "Motherlode",
"Tooltip": "Gives the active family 50,000 simoleons"
},
"net.simply-life.sims4streamdeck.cheat": {
"Name": "Cheat",
"Tooltip": "Send a cheat to the game (does not work in world)"
},
"Localization": {
"More info": "More info",
"Message": "Message",
"Click Me": "Click Me",
"Button": "Button"
"Cheat": "Cheat",
"Enter the cheat command": "Enter the cheat command"
}
}
......@@ -8,6 +8,15 @@
],
"Tooltip": "Motherlode",
"UUID": "net.simply-life.sims4streamdeck.motherlode"
},
{
"Icon": "action/images/cheat",
"Name": "Cheat",
"States": [
{ "Image": "action/images/cheat" }
],
"Tooltip": "Send a cheat to the game (does not work in world)",
"UUID": "net.simply-life.sims4streamdeck.cheat"
}
],
"SDKVersion": 2,
......@@ -15,8 +24,10 @@
"CodePath": "index.html",
"PropertyInspectorPath": "propertyinspector/index.html",
"Description": "Control The Sims 4 from your Stream deck",
"Name": "Sims 4 Stream Deck",
"Name": "Sims 4 Stream Deck",
"Icon": "action/images/emote-plumbob",
"Category": "The Sims 4",
"CategoryIcon": "action/images/emote-plumbob",
"URL": "https://www.simsnetwork.com",
"Version": "1.0.0",
"OS": [
......
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
<g fill="none" fill-rule="evenodd">
<path fill="#9C9C9C" fill-rule="nonzero" d="M1,5 L1,14 L14,14 L14,5 L1,5 Z M0,1 L15,1 L15,15 L0,15 L0,1 Z M14,4 L14,2 L1,2 L1,4 L14,4 Z"/>
<rect width="1" height="1" x="2" fill="#9C9C9C" fill-rule="nonzero"/>
<rect width="1" height="1" x="12" fill="#9C9C9C" fill-rule="nonzero"/>
<g transform="translate(3 7)">
<rect width="1" height="1" x="2" fill="#9C9C9C"/>
<rect width="1" height="1" fill="#666"/>
<rect width="1" height="1" x="4" fill="#9C9C9C"/>
<rect width="1" height="1" x="6" fill="#9C9C9C"/>
<rect width="1" height="1" x="8" fill="#9C9C9C"/>
<rect width="1" height="1" y="2" fill="#9C9C9C"/>
<rect width="1" height="1" x="2" y="2" fill="#9C9C9C"/>
<rect width="1" height="1" x="4" y="2" fill="#9C9C9C"/>
<rect width="1" height="1" x="6" y="2" fill="#9C9C9C"/>
<rect width="1" height="1" x="8" y="2" fill="#9C9C9C"/>
<rect width="1" height="1" y="4" fill="#9C9C9C"/>
<rect width="1" height="1" x="2" y="4" fill="#9C9C9C"/>
<rect width="1" height="1" x="4" y="4" fill="#9C9C9C"/>
<rect width="1" height="1" x="6" y="4" fill="#9C9C9C"/>
<rect width="1" height="1" x="8" y="4" fill="#666"/>
</g>
</g>
</svg>
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Keyshape -->
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="46" height="46" viewBox="0 0 46 46">
<style>
@keyframes a0_t { 0% { transform: translate(0px,0px) scale(1,1); } 50% { transform: translate(23px,0px) scale(0,1); } 100% { transform: translate(0px,0px) scale(1,1); } }
@keyframes a0_f { 0% { fill: #d8d8d8; } 100% { fill: #d8d8d8; } }
@keyframes a0_d { 0% { d: path('M26.7002,16.1301L26.6501,16.0924L18.4447,11.4398L14.3373,13.7874L14.3373,31.9187L18.4511,34.2437L30.0827,27.5941L26.0878,25.3292L18.3286,29.7648L18.3286,15.9149L40.8363,28.6881L40.8228,28.7688C39.6065,32.4179,37.3047,35.5576,34.1665,37.8484C30.9632,40.1865,27.1667,41.4225,23.1877,41.4225C12.9466,41.4225,4.6147,33.1581,4.6147,22.9999C4.6147,12.8415,12.9466,4.57726,23.1877,4.57726C31.0308,4.57726,38.0657,9.51032,40.6929,16.8527C40.888,17.3976,41.0585,17.9576,41.201,18.5197L45.3224,16.1504C45.1466,15.5908,44.9476,15.0335,44.7302,14.4923C43.0331,10.2647,40.1339,6.65801,36.3464,4.0619C32.4692,1.40466,27.9189,0,23.1877,0C16.994,0,11.1711,2.39237,6.7916,6.73651C2.4119,11.0806,0,16.8563,0,22.9999C0,29.1433,2.4119,34.9192,6.7916,39.2635C11.1711,43.6076,16.994,46,23.1877,46C28.6714,46,33.9912,44.0654,38.1673,40.553C42.2755,37.0973,45.0531,32.3177,46,27.0878L26.7002,16.1301L26.7002,16.1301Z'); } 100% { d: path('M26.7002,16.1301L26.6501,16.0924L18.4447,11.4398L14.3373,13.7874L14.3373,31.9187L18.4511,34.2437L30.0827,27.5941L26.0878,25.3292L18.3286,29.7648L18.3286,15.9149L40.8363,28.6881L40.8228,28.7688C39.6065,32.4179,37.3047,35.5576,34.1665,37.8484C30.9632,40.1865,27.1667,41.4225,23.1877,41.4225C12.9466,41.4225,4.6147,33.1581,4.6147,22.9999C4.6147,12.8415,12.9466,4.57726,23.1877,4.57726C31.0308,4.57726,38.0657,9.51032,40.6929,16.8527C40.888,17.3976,41.0585,17.9576,41.201,18.5197L45.3224,16.1504C45.1466,15.5908,44.9476,15.0335,44.7302,14.4923C43.0331,10.2647,40.1339,6.65801,36.3464,4.0619C32.4692,1.40466,27.9189,0,23.1877,0C16.994,0,11.1711,2.39237,6.7916,6.73651C2.4119,11.0806,0,16.8563,0,22.9999C0,29.1433,2.4119,34.9192,6.7916,39.2635C11.1711,43.6076,16.994,46,23.1877,46C28.6714,46,33.9912,44.0654,38.1673,40.553C42.2755,37.0973,45.0531,32.3177,46,27.0878L26.7002,16.1301L26.7002,16.1301Z'); } }
</style>
<path fill="#d8d8d8" fill-rule="evenodd" d="M26.7002,16.1301L26.6501,16.0924L18.4447,11.4398L14.3373,13.7874L14.3373,31.9187L18.4511,34.2437L30.0827,27.5941L26.0878,25.3292L18.3286,29.7648L18.3286,15.9149L40.8363,28.6881L40.8228,28.7688C39.6065,32.4179,37.3047,35.5576,34.1665,37.8484C30.9632,40.1865,27.1667,41.4225,23.1877,41.4225C12.9466,41.4225,4.6147,33.1581,4.6147,22.9999C4.6147,12.8415,12.9466,4.57726,23.1877,4.57726C31.0308,4.57726,38.0657,9.51032,40.6929,16.8527C40.888,17.3976,41.0585,17.9576,41.201,18.5197L45.3224,16.1504C45.1466,15.5908,44.9476,15.0335,44.7302,14.4923C43.0331,10.2647,40.1339,6.65801,36.3464,4.0619C32.4692,1.40466,27.9189,0,23.1877,0C16.994,0,11.1711,2.39237,6.7916,6.73651C2.4119,11.0806,0,16.8563,0,22.9999C0,29.1433,2.4119,34.9192,6.7916,39.2635C11.1711,43.6076,16.994,46,23.1877,46C28.6714,46,33.9912,44.0654,38.1673,40.553C42.2755,37.0973,45.0531,32.3177,46,27.0878L26.7002,16.1301L26.7002,16.1301Z" style="animation: 6s linear infinite both a0_t, 6s linear infinite both a0_f, 6s linear infinite both a0_d;"/>
</svg>
.action-ui {
display: none;
}
.sdpi-wrapper[data-action='net.simply-life.sims4streamdeck.cheat'] .action-ui[data-action='net.simply-life.sims4streamdeck.cheat'] {
display: block;
}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,minimal-ui,viewport-fit=cover">
<meta name=apple-mobile-web-app-capable content=yes>
<meta name=apple-mobile-web-app-status-bar-style content=black>
<title>net.simply-life.sims4streamdeck Property Inspector</title>
<link rel="stylesheet" href="css/sdpi.css">
</head>
<body>
<div class="sdpi-wrapper">
<div id="placeholder"></div>
<html>
<head>
<meta charset="utf-8" />
<meta name=viewport content="width=device-width,initial-scale=1,maximum-scale=1,minimum-scale=1,user-scalable=no,minimal-ui,viewport-fit=cover">
<meta name=apple-mobile-web-app-capable content=yes>
<meta name=apple-mobile-web-app-status-bar-style content=black>
<title>net.simply-life.sims4streamdeck Property Inspector</title>
<link rel="stylesheet" href="css/sdpi.css">
<link rel="stylesheet" href="css/sims4streamdeck.css">
</head>
<body>
<div class="sdpi-wrapper">
<div class="action-ui" data-action="net.simply-life.sims4streamdeck.cheat">
<div class="sdpi-item">
<label class="sdpi-item-label" id="cheat-label" for="cheat" data-localize="Cheat">Cheat</label>
<input class="sdpi-item-value" id="cheat" value="" data-placeholder-localize="Enter the cheat command">
</div>
</div>
</div>
<div class="sdpi-info-label hidden" style="top: -1000;" value=""></div>
<script src="js/common.js"></script>
<script src="js/common_pi.js"></script>
<script src="js/index_pi.js"></script>
</body>
</html>
<div class="sdpi-info-label hidden" style="top: -1000;" value=""></div>
<script src="js/common.js"></script>
<script src="js/common_pi.js"></script>
<script src="js/index_pi.js"></script>
</body>
</html>
......@@ -2,104 +2,22 @@
/* eslint-disable no-extra-boolean-cast */
/* eslint-disable no-else-return */
/**
* This example contains a working Property Inspector, which already communicates
* with the corresponding plugin throug settings and/or direct messages.
* If you want to use other control-types, we recommend copy/paste these from the
* PISamples demo-library, which already contains quite some example DOM elements
*/
/**
* First we declare a global variable, which change all elements behaviour
* globally. It installs the 'onchange' or 'oninput' event on the HTML controls and fiels.
*
* Change this, if you want interactive elements act on any modification (oninput),
* or while their value changes 'onchange'.
*/
var onchangeevt = 'onchange'; // 'oninput';
/**
* cache the static SDPI-WRAPPER, which contains all your HTML elements.
* Please make sure, you put all HTML-elemenets into this wrapper, so they
* are drawn properly using the integrated CSS.
*/
let sdpiWrapper = document.querySelector('.sdpi-wrapper');
/**
* Since the Property Inspector is instantiated every time you select a key
* in Stream Deck software, we can savely cache our settings in a global variable.
*/
let settings;
/**
* The 'connected' event is the first event sent to Property Inspector, after it's instance
* is registered with Stream Deck software. It carries the current websocket, settings,
* and other information about the current environmet in a JSON object.
* You can use it to subscribe to events you want to use in your plugin.
*/
$SD.on('connected', (jsn) => {
/**
* The passed 'applicationInfo' object contains various information about your
* computer, Stream Deck version and OS-settings (e.g. colors as set in your
* OSes display preferences.)
* We use this to inject some dynamic CSS values (saved in 'common_pi.js'), to allow
* drawing proper highlight-colors or progressbars.
*/
console.log("connected");
addDynamicStyles($SD.applicationInfo.colors, 'connectSocket');
/**
* Current settings are passed in the JSON node
* {actionInfo: {
* payload: {
* settings: {
* yoursetting: yourvalue,
* otherthings: othervalues
* ...
* To conveniently read those settings, we have a little utility to read
* arbitrary values from a JSON object, eg:
*
* const foundObject = Utils.getProp(JSON-OBJECT, 'path.to.target', defaultValueIfNotFound)
*/
showAction(Utils.getProp(jsn, 'actionInfo.action', false));
settings = Utils.getProp(jsn, 'actionInfo.payload.settings', false);
if (settings) {
updateUI(settings);
}
});
/**
* The 'sendToPropertyInspector' event can be used to send messages directly from your plugin
* to the Property Inspector without saving these messages to the settings.
*/
});
$SD.on('sendToPropertyInspector', jsn => {
const pl = jsn.payload;
/**
* This is an example, how you could show an error to the user
*/
if (pl.hasOwnProperty('error')) {
sdpiWrapper.innerHTML = `<div class="sdpi-item">
<details class="message caution">
<summary class="${pl.hasOwnProperty('info') ? 'pointer' : ''}">${pl.error}</summary>
${pl.hasOwnProperty('info') ? pl.info : ''}
</details>
</div>`;
} else {
/**
*
* Do something with the data sent from the plugin
* e.g. update some elements in the Property Inspector's UI.
*
*/
}
// TODO?
});
const updateUI = (pl) => {
......@@ -110,7 +28,7 @@ const updateUI = (pl) => {
if (foundElement && foundElement.type !== 'file') {
foundElement.value = pl[e];
const maxl = foundElement.getAttribute('maxlength') || 50;
const labels = document.querySelectorAll(`[for='${foundElement.id}']`);
const labels = document.querySelectorAll(`.length-label[for='${foundElement.id}']`);
if (labels.length) {
for (let x of labels) {
x.textContent = maxl ? `${foundElement.value.length}/${maxl}` : `${foundElement.value.length}`;
......@@ -121,6 +39,19 @@ const updateUI = (pl) => {
})
}
const showAction = (action) => {
sdpiWrapper.dataset.action = action;
const actionUis = sdpiWrapper.querySelectorAll('.action-ui');
for (i = 0; i < actionUis.length; ++i) {
if (actionUis[i].getAttribute('data-action') == action) {
actionUis[i].classList.add('active')
}
else {
actionUis[i].classList.remove('active')
}
}
}
/**
* Something in the PI changed:
* either you clicked a button, dragged a slider or entered some text
......@@ -205,10 +136,9 @@ $SD.on('piDataChanged', (returnValue) => {
if (typeof sdpi_collection !== 'object') return;
if (sdpi_collection.hasOwnProperty('key') && sdpi_collection.key != '') {
if (sdpi_collection.value && sdpi_collection.value !== undefined) {
if (sdpi_collection.hasOwnProperty('value') && sdpi_collection.value !== undefined) {
console.log(sdpi_collection.key, " => ", sdpi_collection.value);
settings[sdpi_collection.key] = sdpi_collection.value;
console.log('setSettings....', settings);
$SD.api.setSettings($SD.uuid, settings);
}
}
......@@ -244,15 +174,7 @@ $SD.on('piDataChanged', (returnValue) => {
}
/** CREATE INTERACTIVE HTML-DOM
* The 'prepareDOMElements' helper is called, to install events on all kinds of
* elements (as seen e.g. in PISamples)
* Elements can get clicked or act on their 'change' or 'input' event. (see at the top
* of this file)
* Messages are then processed using the 'handleSdpiItemChange' method below.
* If you use common elements, you don't need to touch these helpers. Just take care
* setting an 'id' on the element's input-control from which you want to get value(s).
* These helpers allow you to quickly start experimenting and exchanging values with
* your plugin.
* Function taken from the Elgato plugin template.
*/
function prepareDOMElements(baseElement) {
......@@ -268,7 +190,7 @@ function prepareDOMElements(baseElement) {
'PROGRESS',
'CANVAS'
].includes(el.tagName);
const evt = elementsToClick ? 'onclick' : onchangeevt || 'onchange';
const evt = elementsToClick ? 'onclick' : 'oninput';
/** Look for <input><span> combinations, where we consider the span as label for the input
* we don't use `labels` for that, because a range could have 2 labels.
......@@ -454,36 +376,32 @@ function handleSdpiItemChange(e, idx) {
$SD.emit('piDataChanged', returnValue);
}
/**
* This is a quick and simple way to localize elements and labels in the Property
* Inspector's UI without touching their values.
* It uses a quick 'lox()' function, which reads the strings from a global
* variable 'localizedStrings' (in 'common.js')
*/
// eslint-disable-next-line no-unused-vars
String.prototype.loxOrNull = function () {
var a = String(this);
try {
a = $localizedStrings[a];
} catch (b) { a = null }
return a;
};
function localizeUI() {
const el = document.querySelector('.sdpi-wrapper') || document;
let t;
Array.from(el.querySelectorAll('sdpi-item-label')).forEach(e => {
t = e.textContent.lox();
if (e !== t) {
e.innerHTML = e.innerHTML.replace(e.textContent, t);
sdpiWrapper.querySelectorAll('*[data-localize]').forEach(e => {
var t = e.dataset.localize.loxOrNull();
if (t) {
e.innerHTML = t;
}
});
Array.from(el.querySelectorAll('*:not(script)')).forEach(e => {
if (
e.childNodes
&& e.childNodes.length > 0
&& e.childNodes[0].nodeValue
&& typeof e.childNodes[0].nodeValue === 'string'
) {
t = e.childNodes[0].nodeValue.lox();
if (e.childNodes[0].nodeValue !== t) {
e.childNodes[0].nodeValue = t;
}
})
sdpiWrapper.querySelectorAll('*[data-placeholder-localize]').forEach(e => {
var t = e.hasAttribute('placeholder')
? e.dataset.placeholderLocalize.loxOrNull()
: e.dataset.placeholderLocalize.lox();
if (t != null) {
e.setAttribute('placeholder', t)
}
});
})
}
/**
......