From b7b1316e7095565eb0c6370f46dc1fee972df61e Mon Sep 17 00:00:00 2001 From: Araxeus Date: Sat, 17 Apr 2021 22:55:25 +0300 Subject: [PATCH] add rapidFire option to counter prompt --- providers/prompt/index.js | 16 +++++--- providers/prompt/page/prompt.js | 69 +++++++++++++++++++++++++++------ providers/prompt/readme.md | 2 +- 3 files changed, 69 insertions(+), 18 deletions(-) diff --git a/providers/prompt/index.js b/providers/prompt/index.js index 1e29766f..009c8c7a 100644 --- a/providers/prompt/index.js +++ b/providers/prompt/index.js @@ -18,8 +18,8 @@ function electronPrompt(options, parentWindow) { //custom options override default const options_ = Object.assign( { - width: DEFAULT_WIDTH, - height: DEFAULT_HEIGHT, + width: options?.type === "counter" ? DEFAULT_COUNTER_WIDTH : DEFAULT_WIDTH, + height:options?.type === "counter" ? DEFAULT_COUNTER_HEIGHT: DEFAULT_HEIGHT, resizable: false, title: "Prompt", label: "Please input a value:", @@ -28,6 +28,7 @@ function electronPrompt(options, parentWindow) { value: null, type: "input", selectOptions: null, + counterOptions: {minimum: null, maximum: null, multiFire: false}, icon: null, useHtmlLabel: false, customStylesheet: null, @@ -40,10 +41,13 @@ function electronPrompt(options, parentWindow) { options || {} ); - options_.minWidth = options.minWidth || options.width || - options_.type === "counter" ? DEFAULT_COUNTER_WIDTH : DEFAULT_WIDTH; - options_.minHeight = options.minHeight || options.height || - options_.type === "counter" ? DEFAULT_COUNTER_HEIGHT : DEFAULT_HEIGHT; + options_.minWidth = options?.minWidth || options?.width || options_.width; + options_.minHeight = options?.minHeight || options?.height || options_.height; + + if (options_.type === "counter" && (options_.counterOptions !== null && typeof options_.selectOptions !== "object")) { + reject(new Error('"counterOptions" must be an object if specified')); + return; + } if (options_.type === "select" && (options_.selectOptions === null || typeof options_.selectOptions !== "object")) { reject(new Error('"selectOptions" must be an object')); diff --git a/providers/prompt/page/prompt.js b/providers/prompt/page/prompt.js index ac79f106..3cad04ac 100644 --- a/providers/prompt/page/prompt.js +++ b/providers/prompt/page/prompt.js @@ -4,7 +4,7 @@ const { ipcRenderer } = require("electron"); let promptId = null; let promptOptions = null; -function $(selector) { +function $(selector) { return document.querySelector(selector); } @@ -62,6 +62,8 @@ function promptRegister() { switch (promptOptions.type) { case "counter": + dataElement = promptCreateCounter(); + break; case "input": dataElement = promptCreateInput(); break; @@ -73,8 +75,6 @@ function promptRegister() { } if (promptOptions.type === "counter") { - dataElement.style.width = "unset"; - dataElement.style["text-align"] = "center"; dataContainerElement.append(createMinusButton(dataElement)); dataContainerElement.append(dataElement); dataContainerElement.append(createPlusButton(dataElement)); @@ -212,27 +212,74 @@ function promptCreateSelect() { return dataElement; } +let pressed = false; +function multiFire(timer, scaleSpeed, callback, ...args) { + if (!pressed) { + return; + } + if (timer > scaleSpeed) { + timer -= scaleSpeed; + } + callback(...args); + setTimeout(multiFire, timer, timer, scaleSpeed, callback, ...args) +} + function createMinusButton(dataElement) { + function doMinus() { + dataElement.value = validateCounterInput(parseInt(dataElement.value) - 1); + } const minusBtn = document.createElement("span"); minusBtn.textContent = "-"; minusBtn.classList.add("minus"); - minusBtn.onmousedown = () => { - dataElement.value = validateCounterInput(parseInt(dataElement.value) - 1); - }; + if (promptOptions.counterOptions?.multiFire) { + minusBtn.onmousedown = () => { + pressed = true; + multiFire(500, 100, doMinus); + }; + + } else { + minusBtn.onmousedown = () => { + doMinus(); + }; + } return minusBtn; } function createPlusButton(dataElement) { + function doPlus() { + dataElement.value = validateCounterInput(parseInt(dataElement.value) + 1); + } const plusBtn = document.createElement("span"); plusBtn.textContent = "+"; plusBtn.classList.add("plus"); - plusBtn.onmousedown = () => { - dataElement.value = validateCounterInput(parseInt(dataElement.value) + 1); - }; - + if (promptOptions.counterOptions?.multiFire) { + plusBtn.onmousedown = () => { + pressed = true; + multiFire(500, 100, doPlus); + }; + } else { + plusBtn.onmousedown = () => { + doPlus(); + }; + } return plusBtn; } +function promptCreateCounter() { + if (promptOptions.counterOptions?.multiFire) { + document.onmouseup = () => { + pressed = false; + }; + } + + const dataElement = promptCreateInput(); + + dataElement.style.width = "unset"; + dataElement.style["text-align"] = "center"; + + return dataElement; +} + //validate counter function validateCounterInput(input) { const min = promptOptions.counterOptions?.minimum; @@ -245,6 +292,6 @@ function validateCounterInput(input) { if (max !== undefined && input > max) { return max; } - + return input; } diff --git a/providers/prompt/readme.md b/providers/prompt/readme.md index eff1f907..ec272375 100644 --- a/providers/prompt/readme.md +++ b/providers/prompt/readme.md @@ -45,7 +45,7 @@ prompt({ | value | (optional, string) The default value for the input field. Defaults to null. | | type | (optional, string) The type of input field, either 'input' for a standard text input field or 'select' for a dropdown type input or 'counter' for a number counter with buttons. Defaults to 'input'. | | inputAttrs | (optional, object) The attributes of the input field, analagous to the HTML attributes: `{type: 'text', required: true}` -> ``. Used if the type is 'input' -| counterOptions | (optional, object) minimum and maximum of counter in format: `{minimum: %int%, maximum: %int%} ` | +| counterOptions | (optional, object) minimum and maximum of counter, and if continuous input is enabled. format: `{minimum: %int%, maximum: %int%, multiFire: %boolean%`. min+max values defaults to null and multiFire defaults to false. | | selectOptions | (optional, object) The items for the select dropdown if using the 'select' type in the format 'value': 'display text', where the value is what will be given to the then block and the display text is what the user will see. | | useHtmlLabel | (optional, boolean) Whether the label should be interpreted as HTML or not. Defaults to false. | | width | (optional, integer) The width of the prompt window. Defaults to 370. |