mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-18 20:34:54 +08:00
Various improvements
This commit is contained in:
169
dist/ueblueprint.js
vendored
169
dist/ueblueprint.js
vendored
@@ -742,8 +742,9 @@ class Utility {
|
||||
/** @param {String} value */
|
||||
static clearHTMLWhitespace(value) {
|
||||
return value
|
||||
.replaceAll(" ", "\u00A0")
|
||||
.replaceAll("<br>", "\n")
|
||||
.replaceAll(" ", "\u00A0") // whitespace
|
||||
.replaceAll("<br>", "\n") // newlines
|
||||
.replaceAll(/(\<!--.*?\-->)/g, "") // html comments
|
||||
}
|
||||
|
||||
/** @param {String} value */
|
||||
@@ -829,7 +830,7 @@ class IEntity extends Observable {
|
||||
} else if (
|
||||
!(attribute in values)
|
||||
&& defaultValue !== undefined
|
||||
&& !(defaultValue instanceof TypeInitialization && !defaultValue.showDefault)
|
||||
&& !(defaultValue instanceof TypeInitialization && (!defaultValue.showDefault || defaultValue.ignored))
|
||||
) {
|
||||
console.warn(
|
||||
`${this.constructor.name} will add attribute ${prefix}${attribute} not defined in the serialized data`
|
||||
@@ -2258,6 +2259,11 @@ class ITemplate {
|
||||
this.element = element;
|
||||
}
|
||||
|
||||
/** @returns {IInput[]} */
|
||||
createInputObjects() {
|
||||
return []
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
}
|
||||
|
||||
@@ -2270,7 +2276,7 @@ class ITemplate {
|
||||
}
|
||||
|
||||
render() {
|
||||
return $``
|
||||
return w
|
||||
}
|
||||
|
||||
/** @param {Map} changedProperties */
|
||||
@@ -2288,18 +2294,24 @@ class ITemplate {
|
||||
cleanup() {
|
||||
this.#inputObjects.forEach(v => v.unlistenDOMElement());
|
||||
}
|
||||
|
||||
/** @returns {IInput[]} */
|
||||
createInputObjects() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
/** @typedef {import("../../Blueprint").default} Blueprint */
|
||||
|
||||
/**
|
||||
* @template {HTMLElement} T
|
||||
* @extends IInput<T>
|
||||
*/
|
||||
class IKeyboardShortcut extends IInput {
|
||||
|
||||
/** @type {KeyBindingEntity[]} */
|
||||
#activationKeys
|
||||
|
||||
/**
|
||||
* @param {T} target
|
||||
* @param {Blueprint} blueprint
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options.activateAnyKey ??= false;
|
||||
options.activationKeys ??= [];
|
||||
@@ -3042,6 +3054,7 @@ class ISelectableDraggableElement extends IDraggableElement {
|
||||
}
|
||||
|
||||
constructor(...args) {
|
||||
// @ts-expect-error
|
||||
super(...args);
|
||||
this.selected = false;
|
||||
this.listeningDrag = false;
|
||||
@@ -3704,8 +3717,6 @@ class LinkElement extends IFromToPositionedElement {
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-link", LinkElement);
|
||||
|
||||
/** @typedef {import("../../element/PinElement").default} PinElement */
|
||||
|
||||
/** @extends IMouseClickDrag<PinElement> */
|
||||
@@ -4059,8 +4070,6 @@ class ColorHandlerElement extends IDraggableControlElement {
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-color-handler", ColorHandlerElement);
|
||||
|
||||
/** @typedef {import("../element/ColorHandlerElement").default} ColorHandlerElement */
|
||||
|
||||
/** @extends {IDraggableControlTemplate<ColorHandlerElement>} */
|
||||
@@ -4085,8 +4094,6 @@ class ColorSliderElement extends IDraggableControlElement {
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-ui-slider", ColorSliderElement);
|
||||
|
||||
/** @typedef {import("../element/WindowElement").default} WindowElement */
|
||||
|
||||
/** @extends {IDraggablePositionedTemplate<WindowElement>} */
|
||||
@@ -4262,9 +4269,10 @@ class ColorPickerWindowTemplate extends WindowTemplate {
|
||||
|
||||
#tempColor = new LinearColorEntity()
|
||||
|
||||
#colorHexReplace(channel, value) {
|
||||
#colorHexReplace(channel, value, opaque = false) {
|
||||
const colorHex = this.color.toRGBAString();
|
||||
return `${colorHex.substring(0, 2 * channel)}${value}${colorHex.substring(2 + 2 * channel)}`
|
||||
const result = `${colorHex.substring(0, 2 * channel)}${value}${colorHex.substring(2 + 2 * channel)}`;
|
||||
return opaque ? `${result.substring(0, 6)}FF` : result
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
@@ -4363,7 +4371,7 @@ class ColorPickerWindowTemplate extends WindowTemplate {
|
||||
let channelValue = 0;
|
||||
let background = "";
|
||||
const getCommonBackground = channel =>
|
||||
`linear-gradient(to right, #${this.#colorHexReplace(channel, '00')}, #${this.#colorHexReplace(channel, 'ff')})`;
|
||||
`linear-gradient(to right, #${this.#colorHexReplace(channel, '00', true)}, #${this.#colorHexReplace(channel, 'ff', true)})`;
|
||||
switch (channel) {
|
||||
case 0:
|
||||
channelLetter = "r";
|
||||
@@ -4399,13 +4407,13 @@ class ColorPickerWindowTemplate extends WindowTemplate {
|
||||
this.color.H.value,
|
||||
0,
|
||||
this.color.V.value,
|
||||
this.color.A.value
|
||||
1
|
||||
), this.#tempColor.toRGBAString()},`
|
||||
+ `#${this.#tempColor.setFromHSVA(
|
||||
this.color.H.value,
|
||||
1,
|
||||
this.color.V.value,
|
||||
this.color.A.value,
|
||||
1,
|
||||
), this.#tempColor.toRGBAString()})`;
|
||||
break
|
||||
case 6:
|
||||
@@ -4504,7 +4512,7 @@ class ColorPickerWindowTemplate extends WindowTemplate {
|
||||
</div>
|
||||
</div>
|
||||
<div class="ueb-color-control">
|
||||
<span class="ueb-color-control-label">Hex sRGB</span>
|
||||
<span class="ueb-color-control-label">Hex sRGB</span>
|
||||
<div class="ueb-color-picker-hex-srgb ueb-text-input">
|
||||
<span class="ueb-pin-input-content" role="textbox" contenteditable="true"
|
||||
.innerText="${colorSRGB}"
|
||||
@@ -4562,19 +4570,15 @@ class IInputPinTemplate extends PinTemplate {
|
||||
/** @param {Map} changedProperties */
|
||||
firstUpdated(changedProperties) {
|
||||
super.firstUpdated(changedProperties);
|
||||
this.#inputContentElements = /** @type {HTMLElement[]} */([...this.element.querySelectorAll(".ueb-pin-input-content")]);
|
||||
this.#inputContentElements = /** @type {HTMLElement[]} */([...this.element.querySelectorAll("ueb-input")]);
|
||||
if (this.#inputContentElements.length) {
|
||||
this.setInputs(this.getInputs(), false);
|
||||
let self = this;
|
||||
this.onFocusHandler = _ => this.element.blueprint.dispatchEditTextEvent(true);
|
||||
this.onFocusOutHandler = e => {
|
||||
e.preventDefault();
|
||||
document.getSelection()?.removeAllRanges(); // Deselect text inside the input
|
||||
self.setInputs(this.getInputs(), true);
|
||||
this.element.blueprint.dispatchEditTextEvent(false);
|
||||
};
|
||||
this.#inputContentElements.forEach(element => {
|
||||
element.addEventListener("focus", this.onFocusHandler);
|
||||
element.addEventListener("focusout", this.onFocusOutHandler);
|
||||
});
|
||||
}
|
||||
@@ -4583,7 +4587,6 @@ class IInputPinTemplate extends PinTemplate {
|
||||
cleanup() {
|
||||
super.cleanup();
|
||||
this.#inputContentElements.forEach(element => {
|
||||
element.removeEventListener("focus", this.onFocusHandler);
|
||||
element.removeEventListener("focusout", this.onFocusOutHandler);
|
||||
});
|
||||
}
|
||||
@@ -4624,9 +4627,9 @@ class IInputPinTemplate extends PinTemplate {
|
||||
if (this.element.isInput()) {
|
||||
return $`
|
||||
<div class="ueb-pin-input">
|
||||
<span class="ueb-pin-input-content" role="textbox" contenteditable="true"
|
||||
<ueb-input
|
||||
.innerText="${IInputPinTemplate.stringFromUEToInput(this.element.entity.DefaultValue.toString())}">
|
||||
</span>
|
||||
</ueb-input>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
@@ -4787,8 +4790,6 @@ class WindowElement extends IDraggableElement {
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-window", WindowElement);
|
||||
|
||||
/**
|
||||
* @typedef {import("../element/PinElement").default} PinElement
|
||||
* @typedef {import("../entity/LinearColorEntity").default} LinearColorEntity
|
||||
@@ -4952,9 +4953,9 @@ class RealPinTemplate extends INumericPinTemplate {
|
||||
if (this.element.isInput()) {
|
||||
return $`
|
||||
<div class="ueb-pin-input">
|
||||
<span class="ueb-pin-input-content" role="textbox" contenteditable="true"
|
||||
<ueb-input
|
||||
.innerText="${IInputPinTemplate.stringFromUEToInput(Utility.minDecimals(this.element.entity.DefaultValue))}">
|
||||
</span>
|
||||
</ueb-input>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
@@ -5287,8 +5288,6 @@ class PinElement extends IElement {
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-pin", PinElement);
|
||||
|
||||
/** @typedef {import("../element/NodeElement").default} NodeElement */
|
||||
|
||||
/** @extends {ISelectableDraggableTemplate<NodeElement>} */
|
||||
@@ -5521,8 +5520,6 @@ class NodeElement extends ISelectableDraggableElement {
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-node", NodeElement);
|
||||
|
||||
class Paste extends IInput {
|
||||
|
||||
static #serializer = new ObjectSerializer()
|
||||
@@ -5926,8 +5923,6 @@ class SelectorElement extends IFromToPositionedElement {
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-selector", SelectorElement);
|
||||
|
||||
class Unfocus extends IInput {
|
||||
|
||||
/** @type {(e: MouseEvent) => void} */
|
||||
@@ -6479,9 +6474,9 @@ class Blueprint extends IElement {
|
||||
this.dispatchEvent(event);
|
||||
}
|
||||
|
||||
dispatchEditTextEvent(value) {
|
||||
dispatchEditTextEvent(beginning) {
|
||||
const event = new CustomEvent(
|
||||
value
|
||||
beginning
|
||||
? Configuration.editTextEventName.begin
|
||||
: Configuration.editTextEventName.end
|
||||
);
|
||||
@@ -6491,6 +6486,95 @@ class Blueprint extends IElement {
|
||||
|
||||
customElements.define("ueb-blueprint", Blueprint);
|
||||
|
||||
class IFocus extends IInput {
|
||||
|
||||
/** @type {(e: FocusEvent) => void} */
|
||||
#focusHandler
|
||||
|
||||
/** @type {(e: FocusEvent) => void} */
|
||||
#focusoutHandler
|
||||
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options.listenOnFocus ??= true;
|
||||
super(target, blueprint, options);
|
||||
this.#focusHandler = e => {
|
||||
e.preventDefault();
|
||||
this.focused();
|
||||
};
|
||||
this.#focusoutHandler = e => {
|
||||
e.preventDefault();
|
||||
this.unfocused();
|
||||
};
|
||||
}
|
||||
|
||||
listenEvents() {
|
||||
this.target.addEventListener("focus", this.#focusHandler);
|
||||
this.target.addEventListener("focusout", this.#focusoutHandler);
|
||||
}
|
||||
|
||||
unlistenEvents() {
|
||||
this.target.removeEventListener("focus", this.#focusHandler);
|
||||
this.target.removeEventListener("focusout", this.#focusoutHandler);
|
||||
}
|
||||
|
||||
focused() {
|
||||
}
|
||||
|
||||
unfocused() {
|
||||
}
|
||||
}
|
||||
|
||||
class FocusTextEdit extends IFocus {
|
||||
|
||||
focused() {
|
||||
this.blueprint.dispatchEditTextEvent(true);
|
||||
}
|
||||
|
||||
unfocused() {
|
||||
document.getSelection()?.removeAllRanges(); // Deselect eventually selected text inside the input
|
||||
this.blueprint.dispatchEditTextEvent(false);
|
||||
}
|
||||
}
|
||||
|
||||
/** @typedef {import ("../element/InputElement").default} InputElement */
|
||||
|
||||
/** @extends {ITemplate<InputElement>} */
|
||||
class InputTemplate extends ITemplate {
|
||||
|
||||
createInputObjects() {
|
||||
return [
|
||||
...super.createInputObjects(),
|
||||
new FocusTextEdit(this.element, this.element.blueprint),
|
||||
]
|
||||
}
|
||||
|
||||
/** @param {Map} changedProperties */
|
||||
firstUpdated(changedProperties) {
|
||||
super.firstUpdated(changedProperties);
|
||||
this.element.classList.add("ueb-pin-input-content");
|
||||
this.element.setAttribute("role", "textbox");
|
||||
this.element.contentEditable = "true";
|
||||
}
|
||||
}
|
||||
|
||||
class InputElement extends IElement {
|
||||
|
||||
constructor() {
|
||||
super({}, new InputTemplate());
|
||||
}
|
||||
}
|
||||
|
||||
function defineElements() {
|
||||
customElements.define("ueb-color-handler", ColorHandlerElement);
|
||||
customElements.define("ueb-input", InputElement);
|
||||
customElements.define("ueb-link", LinkElement);
|
||||
customElements.define("ueb-node", NodeElement);
|
||||
customElements.define("ueb-pin", PinElement);
|
||||
customElements.define("ueb-selector", SelectorElement);
|
||||
customElements.define("ueb-ui-slider", ColorSliderElement);
|
||||
customElements.define("ueb-window", WindowElement);
|
||||
}
|
||||
|
||||
/**
|
||||
* @typedef {import("../entity/IEntity").default} IEntity
|
||||
* @typedef {import("../entity/TypeInitialization").AnyValue} AnyValue
|
||||
@@ -6769,6 +6853,7 @@ function initializeSerializerFactory() {
|
||||
);
|
||||
}
|
||||
|
||||
initializeSerializerFactory();
|
||||
initializeSerializerFactory();
|
||||
defineElements();
|
||||
|
||||
export { Blueprint, Configuration, LinkElement, NodeElement };
|
||||
|
||||
4
dist/ueblueprint.min.js
vendored
4
dist/ueblueprint.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -401,9 +401,9 @@ export default class Blueprint extends IElement {
|
||||
this.dispatchEvent(event)
|
||||
}
|
||||
|
||||
dispatchEditTextEvent(value) {
|
||||
dispatchEditTextEvent(beginning) {
|
||||
const event = new CustomEvent(
|
||||
value
|
||||
beginning
|
||||
? Configuration.editTextEventName.begin
|
||||
: Configuration.editTextEventName.end
|
||||
)
|
||||
|
||||
@@ -236,8 +236,9 @@ export default class Utility {
|
||||
/** @param {String} value */
|
||||
static clearHTMLWhitespace(value) {
|
||||
return value
|
||||
.replaceAll(" ", "\u00A0")
|
||||
.replaceAll("<br>", "\n")
|
||||
.replaceAll(" ", "\u00A0") // whitespace
|
||||
.replaceAll("<br>", "\n") // newlines
|
||||
.replaceAll(/(\<!--.*?\-->)/g, "") // html comments
|
||||
}
|
||||
|
||||
/** @param {String} value */
|
||||
|
||||
@@ -14,5 +14,3 @@ export default class ColorHandlerElement extends IDraggableControlElement {
|
||||
super({}, new ColorHandlerTemplate())
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-color-handler", ColorHandlerElement)
|
||||
|
||||
@@ -10,5 +10,3 @@ export default class ColorSliderElement extends IDraggableControlElement {
|
||||
super({}, new ColorSliderTemplate())
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-ui-slider", ColorSliderElement)
|
||||
|
||||
@@ -60,4 +60,4 @@ export default class IFromToPositionedElement extends IElement {
|
||||
this.toX += offsetX
|
||||
this.toY += offsetY
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@ export default class ISelectableDraggableElement extends IDraggableElement {
|
||||
}
|
||||
|
||||
constructor(...args) {
|
||||
// @ts-expect-error
|
||||
super(...args)
|
||||
this.selected = false
|
||||
this.listeningDrag = false
|
||||
|
||||
@@ -3,11 +3,7 @@ import IElement from "./IElement"
|
||||
|
||||
export default class InputElement extends IElement {
|
||||
|
||||
static elementName = "ueb-input"
|
||||
|
||||
constructor() {
|
||||
super({}, new InputTemplate())
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(InputElement.elementName, InputElement)
|
||||
|
||||
@@ -247,5 +247,3 @@ export default class LinkElement extends IFromToPositionedElement {
|
||||
this.linkMessageText = `${this.sourcePin.pinType} is not compatible with ${this.destinationPin.pinType}.`
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-link", LinkElement)
|
||||
|
||||
@@ -164,5 +164,3 @@ export default class NodeElement extends ISelectableDraggableElement {
|
||||
this.setShowAdvancedPinDisplay(this.entity.AdvancedPinDisplay?.toString() != "Shown")
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-node", NodeElement)
|
||||
|
||||
@@ -232,5 +232,3 @@ export default class PinElement extends IElement {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-pin", PinElement)
|
||||
|
||||
@@ -39,5 +39,3 @@ export default class SelectorElement extends IFromToPositionedElement {
|
||||
this.toY = 0
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-selector", SelectorElement)
|
||||
|
||||
@@ -49,5 +49,3 @@ export default class WindowElement extends IDraggableElement {
|
||||
this.dispatchEvent(deleteEvent)
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("ueb-window", WindowElement)
|
||||
|
||||
19
js/element/defineElements.js
Normal file
19
js/element/defineElements.js
Normal file
@@ -0,0 +1,19 @@
|
||||
import ColorHandlerElement from "./ColorHandlerElement"
|
||||
import ColorSliderElement from "./ColorSliderElement"
|
||||
import InputElement from "./InputElement"
|
||||
import LinkElement from "./LinkElement"
|
||||
import NodeElement from "./NodeElement"
|
||||
import PinElement from "./PinElement"
|
||||
import SelectorElement from "./SelectorElement"
|
||||
import WindowElement from "./WindowElement"
|
||||
|
||||
export default function defineElements() {
|
||||
customElements.define("ueb-color-handler", ColorHandlerElement)
|
||||
customElements.define("ueb-input", InputElement)
|
||||
customElements.define("ueb-link", LinkElement)
|
||||
customElements.define("ueb-node", NodeElement)
|
||||
customElements.define("ueb-pin", PinElement)
|
||||
customElements.define("ueb-selector", SelectorElement)
|
||||
customElements.define("ueb-ui-slider", ColorSliderElement)
|
||||
customElements.define("ueb-window", WindowElement)
|
||||
}
|
||||
@@ -41,7 +41,7 @@ export default class IEntity extends Observable {
|
||||
} else if (
|
||||
!(attribute in values)
|
||||
&& defaultValue !== undefined
|
||||
&& !(defaultValue instanceof TypeInitialization && !defaultValue.showDefault)
|
||||
&& !(defaultValue instanceof TypeInitialization && (!defaultValue.showDefault || defaultValue.ignored))
|
||||
) {
|
||||
console.warn(
|
||||
`${this.constructor.name} will add attribute ${prefix}${attribute} not defined in the serialized data`
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import Blueprint from "./Blueprint"
|
||||
import Configuration from "./Configuration"
|
||||
import defineElements from "./element/defineElements"
|
||||
import initializeSerializerFactory from "./serialization/initializeSerializerFactory"
|
||||
import LinkElement from "./element/LinkElement"
|
||||
import NodeElement from "./element/NodeElement"
|
||||
|
||||
initializeSerializerFactory()
|
||||
defineElements()
|
||||
|
||||
export { Blueprint as Blueprint, NodeElement as NodeElement, LinkElement as LinkElement, Configuration as Configuration }
|
||||
|
||||
13
js/input/common/FocusTextEdit.js
Normal file
13
js/input/common/FocusTextEdit.js
Normal file
@@ -0,0 +1,13 @@
|
||||
import IFocus from "./IFocus"
|
||||
|
||||
export default class FocusTextEdit extends IFocus {
|
||||
|
||||
focused() {
|
||||
this.blueprint.dispatchEditTextEvent(true)
|
||||
}
|
||||
|
||||
unfocused() {
|
||||
document.getSelection()?.removeAllRanges() // Deselect eventually selected text inside the input
|
||||
this.blueprint.dispatchEditTextEvent(false)
|
||||
}
|
||||
}
|
||||
40
js/input/common/IFocus.js
Normal file
40
js/input/common/IFocus.js
Normal file
@@ -0,0 +1,40 @@
|
||||
import IInput from "../IInput"
|
||||
|
||||
export default class IFocus extends IInput {
|
||||
|
||||
/** @type {(e: FocusEvent) => void} */
|
||||
#focusHandler
|
||||
|
||||
/** @type {(e: FocusEvent) => void} */
|
||||
#focusoutHandler
|
||||
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options.listenOnFocus ??= true
|
||||
super(target, blueprint, options)
|
||||
const self = this
|
||||
this.#focusHandler = e => {
|
||||
e.preventDefault()
|
||||
this.focused()
|
||||
}
|
||||
this.#focusoutHandler = e => {
|
||||
e.preventDefault()
|
||||
this.unfocused()
|
||||
}
|
||||
}
|
||||
|
||||
listenEvents() {
|
||||
this.target.addEventListener("focus", this.#focusHandler)
|
||||
this.target.addEventListener("focusout", this.#focusoutHandler)
|
||||
}
|
||||
|
||||
unlistenEvents() {
|
||||
this.target.removeEventListener("focus", this.#focusHandler)
|
||||
this.target.removeEventListener("focusout", this.#focusoutHandler)
|
||||
}
|
||||
|
||||
focused() {
|
||||
}
|
||||
|
||||
unfocused() {
|
||||
}
|
||||
}
|
||||
@@ -3,11 +3,22 @@ import IInput from "../IInput"
|
||||
import ISerializer from "../../serialization/ISerializer"
|
||||
import KeyBindingEntity from "../../entity/KeyBindingEntity"
|
||||
|
||||
/** @typedef {import("../../Blueprint").default} Blueprint */
|
||||
|
||||
/**
|
||||
* @template {HTMLElement} T
|
||||
* @extends IInput<T>
|
||||
*/
|
||||
export default class IKeyboardShortcut extends IInput {
|
||||
|
||||
/** @type {KeyBindingEntity[]} */
|
||||
#activationKeys
|
||||
|
||||
/**
|
||||
* @param {T} target
|
||||
* @param {Blueprint} blueprint
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options.activateAnyKey ??= false
|
||||
options.activationKeys ??= []
|
||||
|
||||
41
js/input/keybaord/KeyboardShortcutAction.js
Normal file
41
js/input/keybaord/KeyboardShortcutAction.js
Normal file
@@ -0,0 +1,41 @@
|
||||
import IKeyboardShortcut from "./IKeyboardShortcut"
|
||||
|
||||
/** @typedef {import("../../Blueprint").default} Blueprint */
|
||||
|
||||
/**
|
||||
* @template {HTMLElement} T
|
||||
* @extends IKeyboardShortcut<T>
|
||||
*/
|
||||
export default class KeyboardShortcutAction extends IKeyboardShortcut {
|
||||
|
||||
static #ignoreEvent =
|
||||
/** @param {KeyboardShortcutAction} self */
|
||||
self => { }
|
||||
|
||||
/**
|
||||
* @param {T} target
|
||||
* @param {Blueprint} blueprint
|
||||
* @param {Object} options
|
||||
* @param {(self: KeyboardShortcutAction<T>) => void} onKeyDown
|
||||
* @param {(self: KeyboardShortcutAction<T>) => void} onKeyUp
|
||||
*/
|
||||
constructor(
|
||||
target,
|
||||
blueprint,
|
||||
options,
|
||||
onKeyDown = KeyboardShortcutAction.#ignoreEvent,
|
||||
onKeyUp = KeyboardShortcutAction.#ignoreEvent
|
||||
) {
|
||||
super(target, blueprint, options)
|
||||
this.onKeyDown = onKeyDown
|
||||
this.onKeyUp = onKeyUp
|
||||
}
|
||||
|
||||
fire() {
|
||||
this.onKeyDown(this)
|
||||
}
|
||||
|
||||
unfire() {
|
||||
this.onKeyUp(this)
|
||||
}
|
||||
}
|
||||
@@ -124,9 +124,10 @@ export default class ColorPickerWindowTemplate extends WindowTemplate {
|
||||
|
||||
#tempColor = new LinearColorEntity()
|
||||
|
||||
#colorHexReplace(channel, value) {
|
||||
#colorHexReplace(channel, value, opaque = false) {
|
||||
const colorHex = this.color.toRGBAString()
|
||||
return `${colorHex.substring(0, 2 * channel)}${value}${colorHex.substring(2 + 2 * channel)}`
|
||||
const result = `${colorHex.substring(0, 2 * channel)}${value}${colorHex.substring(2 + 2 * channel)}`
|
||||
return opaque ? `${result.substring(0, 6)}FF` : result
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
@@ -225,7 +226,7 @@ export default class ColorPickerWindowTemplate extends WindowTemplate {
|
||||
let channelValue = 0
|
||||
let background = ""
|
||||
const getCommonBackground = channel =>
|
||||
`linear-gradient(to right, #${this.#colorHexReplace(channel, '00')}, #${this.#colorHexReplace(channel, 'ff')})`
|
||||
`linear-gradient(to right, #${this.#colorHexReplace(channel, '00', true)}, #${this.#colorHexReplace(channel, 'ff', true)})`
|
||||
switch (channel) {
|
||||
case 0:
|
||||
channelLetter = "r"
|
||||
@@ -261,13 +262,13 @@ export default class ColorPickerWindowTemplate extends WindowTemplate {
|
||||
this.color.H.value,
|
||||
0,
|
||||
this.color.V.value,
|
||||
this.color.A.value
|
||||
1
|
||||
), this.#tempColor.toRGBAString()},`
|
||||
+ `#${this.#tempColor.setFromHSVA(
|
||||
this.color.H.value,
|
||||
1,
|
||||
this.color.V.value,
|
||||
this.color.A.value,
|
||||
1,
|
||||
), this.#tempColor.toRGBAString()})`
|
||||
break
|
||||
case 6:
|
||||
@@ -366,7 +367,7 @@ export default class ColorPickerWindowTemplate extends WindowTemplate {
|
||||
</div>
|
||||
</div>
|
||||
<div class="ueb-color-control">
|
||||
<span class="ueb-color-control-label">Hex sRGB</span>
|
||||
<span class="ueb-color-control-label">Hex sRGB</span>
|
||||
<div class="ueb-color-picker-hex-srgb ueb-text-input">
|
||||
<span class="ueb-pin-input-content" role="textbox" contenteditable="true"
|
||||
.innerText="${colorSRGB}"
|
||||
|
||||
@@ -37,19 +37,15 @@ export default class IInputPinTemplate extends PinTemplate {
|
||||
/** @param {Map} changedProperties */
|
||||
firstUpdated(changedProperties) {
|
||||
super.firstUpdated(changedProperties)
|
||||
this.#inputContentElements = /** @type {HTMLElement[]} */([...this.element.querySelectorAll(".ueb-pin-input-content")])
|
||||
this.#inputContentElements = /** @type {HTMLElement[]} */([...this.element.querySelectorAll("ueb-input")])
|
||||
if (this.#inputContentElements.length) {
|
||||
this.setInputs(this.getInputs(), false)
|
||||
let self = this
|
||||
this.onFocusHandler = _ => this.element.blueprint.dispatchEditTextEvent(true)
|
||||
this.onFocusOutHandler = e => {
|
||||
e.preventDefault()
|
||||
document.getSelection()?.removeAllRanges() // Deselect text inside the input
|
||||
self.setInputs(this.getInputs(), true)
|
||||
this.element.blueprint.dispatchEditTextEvent(false)
|
||||
}
|
||||
this.#inputContentElements.forEach(element => {
|
||||
element.addEventListener("focus", this.onFocusHandler)
|
||||
element.addEventListener("focusout", this.onFocusOutHandler)
|
||||
})
|
||||
}
|
||||
@@ -58,7 +54,6 @@ export default class IInputPinTemplate extends PinTemplate {
|
||||
cleanup() {
|
||||
super.cleanup()
|
||||
this.#inputContentElements.forEach(element => {
|
||||
element.removeEventListener("focus", this.onFocusHandler)
|
||||
element.removeEventListener("focusout", this.onFocusOutHandler)
|
||||
})
|
||||
}
|
||||
@@ -99,9 +94,9 @@ export default class IInputPinTemplate extends PinTemplate {
|
||||
if (this.element.isInput()) {
|
||||
return html`
|
||||
<div class="ueb-pin-input">
|
||||
<span class="ueb-pin-input-content" role="textbox" contenteditable="true"
|
||||
<ueb-input
|
||||
.innerText="${IInputPinTemplate.stringFromUEToInput(this.element.entity.DefaultValue.toString())}">
|
||||
</span>
|
||||
</ueb-input>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { css, html } from "lit"
|
||||
import { css, nothing } from "lit"
|
||||
|
||||
/**
|
||||
* @typedef {import("../element/IElement").default} IElement
|
||||
@@ -24,6 +24,11 @@ export default class ITemplate {
|
||||
this.element = element
|
||||
}
|
||||
|
||||
/** @returns {IInput[]} */
|
||||
createInputObjects() {
|
||||
return []
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
}
|
||||
|
||||
@@ -36,7 +41,7 @@ export default class ITemplate {
|
||||
}
|
||||
|
||||
render() {
|
||||
return html``
|
||||
return nothing
|
||||
}
|
||||
|
||||
/** @param {Map} changedProperties */
|
||||
@@ -54,9 +59,4 @@ export default class ITemplate {
|
||||
cleanup() {
|
||||
this.#inputObjects.forEach(v => v.unlistenDOMElement())
|
||||
}
|
||||
|
||||
/** @returns {IInput[]} */
|
||||
createInputObjects() {
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import FocusTextEdit from "../input/common/FocusTextEdit"
|
||||
import ITemplate from "./ITemplate"
|
||||
|
||||
/** @typedef {import ("../element/InputElement").default} InputElement */
|
||||
@@ -5,20 +6,18 @@ import ITemplate from "./ITemplate"
|
||||
/** @extends {ITemplate<InputElement>} */
|
||||
export default class InputTemplate extends ITemplate {
|
||||
|
||||
createInputObjects() {
|
||||
return [
|
||||
...super.createInputObjects(),
|
||||
new FocusTextEdit(this.element, this.element.blueprint),
|
||||
]
|
||||
}
|
||||
|
||||
/** @param {Map} changedProperties */
|
||||
firstUpdated(changedProperties) {
|
||||
super.firstUpdated(changedProperties)
|
||||
this.onFocusHandler =
|
||||
/** @param {FocusEvent} e */
|
||||
e => this.element.blueprint.dispatchEditTextEvent(true)
|
||||
this.onFocusOutHandler =
|
||||
/** @param {FocusEvent} e */
|
||||
e => {
|
||||
e.preventDefault()
|
||||
document.getSelection()?.removeAllRanges() // Deselect text inside the input
|
||||
this.element.blueprint.dispatchEditTextEvent(false)
|
||||
}
|
||||
this.element.addEventListener("focus", this.onFocusHandler)
|
||||
this.element.addEventListener("focusout", this.onFocusOutHandler)
|
||||
this.element.classList.add("ueb-pin-input-content")
|
||||
this.element.setAttribute("role", "textbox")
|
||||
this.element.contentEditable = "true"
|
||||
}
|
||||
}
|
||||
@@ -17,9 +17,9 @@ export default class RealPinTemplate extends INumericPinTemplate {
|
||||
if (this.element.isInput()) {
|
||||
return html`
|
||||
<div class="ueb-pin-input">
|
||||
<span class="ueb-pin-input-content" role="textbox" contenteditable="true"
|
||||
<ueb-input
|
||||
.innerText="${IInputPinTemplate.stringFromUEToInput(Utility.minDecimals(this.element.entity.DefaultValue))}">
|
||||
</span>
|
||||
</ueb-input>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user