mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-04 08:28:17 +08:00
Refactoring, various fixes
This commit is contained in:
@@ -1,14 +1,36 @@
|
||||
export default class IContext {
|
||||
|
||||
/** @type {HTMLElement} */
|
||||
target
|
||||
|
||||
/** @type {import("../Blueprint").default}" */
|
||||
blueprint
|
||||
|
||||
/** @type {Object} */
|
||||
options
|
||||
|
||||
#hasFocus = false
|
||||
|
||||
get hasFocus() {
|
||||
return this.#hasFocus
|
||||
}
|
||||
|
||||
set hasFocus(_) {
|
||||
}
|
||||
|
||||
constructor(target, blueprint, options) {
|
||||
/** @type {HTMLElement} */
|
||||
this.target = target
|
||||
/** @type {import("../Blueprint").default}" */
|
||||
this.blueprint = blueprint
|
||||
this.options = options
|
||||
let self = this
|
||||
this.blueprintFocusHandler = _ => self.listenEvents()
|
||||
this.blueprintUnfocusHandler = _ => self.unlistenEvents()
|
||||
this.blueprintFocusHandler = _ => {
|
||||
this.#hasFocus = true
|
||||
self.listenEvents()
|
||||
}
|
||||
this.blueprintUnfocusHandler = _ => {
|
||||
self.unlistenEvents()
|
||||
this.#hasFocus = false
|
||||
}
|
||||
if (options?.wantsFocusCallback ?? false) {
|
||||
this.blueprint.addEventListener("blueprint-focus", this.blueprintFocusHandler)
|
||||
this.blueprint.addEventListener("blueprint-unfocus", this.blueprintUnfocusHandler)
|
||||
|
||||
@@ -1,76 +1,71 @@
|
||||
import Configuration from "../../Configuration"
|
||||
import IContext from "../IContext"
|
||||
import Parsimmon from "parsimmon"
|
||||
|
||||
let P = Parsimmon
|
||||
|
||||
class KeyGrammar {
|
||||
|
||||
// Creates a grammar where each alternative is the string from ModifierKey mapped to a number for bit or use
|
||||
ModifierKey = r => P.alt(...Configuration.ModifierKeys.map((v, i) => P.string(v).map(_ => 1 << i)))
|
||||
Key = r => P.alt(...Object.keys(Configuration.Keys).map(v => P.string(v))).map(v => Configuration.Keys[v])
|
||||
KeyboardShortcut = r => P.alt(
|
||||
P.seqMap(
|
||||
P.seqMap(r.ModifierKey, P.optWhitespace, P.string(Configuration.keysSeparator), (v, _, __) => v)
|
||||
.atLeast(1)
|
||||
.map(v => v.reduce((acc, cur) => acc | cur)),
|
||||
P.optWhitespace,
|
||||
r.Key,
|
||||
(modifierKeysFlag, _, key) => ({
|
||||
key: key,
|
||||
ctrlKey: Boolean(modifierKeysFlag & (1 << Configuration.ModifierKeys.indexOf("Ctrl"))),
|
||||
shiftKey: Boolean(modifierKeysFlag & (1 << Configuration.ModifierKeys.indexOf("Shift"))),
|
||||
altKey: Boolean(modifierKeysFlag & (1 << Configuration.ModifierKeys.indexOf("Alt"))),
|
||||
metaKey: Boolean(modifierKeysFlag & (1 << Configuration.ModifierKeys.indexOf("Meta")))
|
||||
})
|
||||
),
|
||||
r.Key.map(v => ({ key: v }))
|
||||
)
|
||||
.trim(P.optWhitespace)
|
||||
}
|
||||
|
||||
import ISerializer from "../../serialization/ISerializer"
|
||||
import KeyBindingEntity from "../../entity/KeyBindingEntity"
|
||||
export default class IKeyboardShortcut extends IContext {
|
||||
|
||||
static keyGrammar = P.createLanguage(new KeyGrammar())
|
||||
/** @type {KeyBindingEntity} */
|
||||
#activationKeys
|
||||
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options.wantsFocusCallback = true
|
||||
options.activationKeys ??= []
|
||||
if (!(options.activationKeys instanceof Array)) {
|
||||
options.activationKeys = [options.activationKeys]
|
||||
}
|
||||
options.activationKeys = options.activationKeys.map(v => {
|
||||
if (v instanceof KeyBindingEntity) {
|
||||
return v
|
||||
}
|
||||
if (v.constructor === String) {
|
||||
const parsed = ISerializer.grammar.KeyBinding.parse(v)
|
||||
if (parsed.status) {
|
||||
return parsed.value
|
||||
}
|
||||
}
|
||||
throw new Error("Unexpected key value")
|
||||
})
|
||||
|
||||
super(target, blueprint, options)
|
||||
|
||||
/** @type {String[]} */
|
||||
this.key = this.options.key
|
||||
this.ctrlKey = options.ctrlKey ?? false
|
||||
this.shiftKey = options.shiftKey ?? false
|
||||
this.altKey = options.altKey ?? false
|
||||
this.metaKey = options.metaKey ?? false
|
||||
this.#activationKeys = this.options.activationKeys ?? []
|
||||
|
||||
let self = this
|
||||
/** @param {KeyboardEvent} e */
|
||||
this.keyDownHandler = e => {
|
||||
if (
|
||||
e.code == self.key
|
||||
&& e.ctrlKey === self.ctrlKey
|
||||
&& e.shiftKey === self.shiftKey
|
||||
&& e.altKey === self.altKey
|
||||
&& e.metaKey === self.metaKey
|
||||
) {
|
||||
self.fire()
|
||||
self.#activationKeys.some(keyEntry =>
|
||||
keyEntry.bShift === e.shiftKey
|
||||
&& keyEntry.bCtrl === e.ctrlKey
|
||||
&& keyEntry.bAlt === e.altKey
|
||||
&& keyEntry.bCmd === e.metaKey
|
||||
&& Configuration.Keys[keyEntry.Key] === e.code
|
||||
)) {
|
||||
e.preventDefault()
|
||||
return true
|
||||
self.fire()
|
||||
document.removeEventListener("keydown", self.keyDownHandler)
|
||||
document.addEventListener("keyup", self.keyUpHandler)
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {String} keyString
|
||||
* @returns {Object}
|
||||
*/
|
||||
static keyOptionsParse(options, keyString) {
|
||||
options = {
|
||||
...options,
|
||||
...IKeyboardShortcut.keyGrammar.KeyboardShortcut.parse(keyString).value
|
||||
/** @param {KeyboardEvent} e */
|
||||
this.keyUpHandler = e => {
|
||||
if (
|
||||
self.#activationKeys.some(keyEntry =>
|
||||
keyEntry.bShift && e.key === "Shift"
|
||||
|| keyEntry.bCtrl && e.key === "Control"
|
||||
|| keyEntry.bAlt && e.key === "Alt"
|
||||
|| keyEntry.bCmd && e.key === "Meta" // Unsure about this, what key is that?
|
||||
|| Configuration.Keys[keyEntry.Key] === e.code
|
||||
|
||||
)) {
|
||||
e.preventDefault()
|
||||
self.unfire()
|
||||
document.removeEventListener("keyup", this.keyUpHandler)
|
||||
document.addEventListener("keydown", this.keyDownHandler)
|
||||
}
|
||||
}
|
||||
return options
|
||||
|
||||
}
|
||||
|
||||
listenEvents() {
|
||||
@@ -81,6 +76,11 @@ export default class IKeyboardShortcut extends IContext {
|
||||
document.removeEventListener("keydown", this.keyDownHandler)
|
||||
}
|
||||
|
||||
// Subclasses will want to override
|
||||
|
||||
fire() {
|
||||
}
|
||||
|
||||
unfire() {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import Configuration from "../../Configuration"
|
||||
import IKeyboardShortcut from "./IKeyboardShortcut"
|
||||
|
||||
export default class KeyvoardCanc extends IKeyboardShortcut {
|
||||
export default class KeyboardCanc extends IKeyboardShortcut {
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} target
|
||||
@@ -9,7 +9,10 @@ export default class KeyvoardCanc extends IKeyboardShortcut {
|
||||
* @param {OBject} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options = IKeyboardShortcut.keyOptionsParse(options, Configuration.deleteNodesKeyboardKey)
|
||||
options = {
|
||||
...options,
|
||||
activationKeys: Configuration.deleteNodesKeyboardKey
|
||||
}
|
||||
super(target, blueprint, options)
|
||||
}
|
||||
|
||||
|
||||
31
js/input/keybaord/KeyboardEnableZoom.js
Normal file
31
js/input/keybaord/KeyboardEnableZoom.js
Normal file
@@ -0,0 +1,31 @@
|
||||
import Configuration from "../../Configuration"
|
||||
import IKeyboardShortcut from "./IKeyboardShortcut"
|
||||
import Zoom from "../mouse/Zoom"
|
||||
|
||||
export default class KeyboardEnableZoom extends IKeyboardShortcut {
|
||||
|
||||
/** @type {} */
|
||||
#zoomInputObject
|
||||
|
||||
/**
|
||||
* @param {HTMLElement} target
|
||||
* @param {import("../../Blueprint").default} blueprint
|
||||
* @param {OBject} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options = {
|
||||
...options,
|
||||
activationKeys: Configuration.enableZoomIn
|
||||
}
|
||||
super(target, blueprint, options)
|
||||
}
|
||||
|
||||
fire() {
|
||||
this.zoomInputObject = this.blueprint.getInputObject(Zoom)
|
||||
zoomInputObject.enableZoonIn = true
|
||||
}
|
||||
|
||||
unfire() {
|
||||
this.#zoomInputObject.enableZoom = false
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,10 @@ export default class KeyboardSelectAll extends IKeyboardShortcut {
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options = IKeyboardShortcut.keyOptionsParse(options, Configuration.selectAllKeyboardKey)
|
||||
options = {
|
||||
...options,
|
||||
activationKeys: Configuration.selectAllKeyboardKey
|
||||
}
|
||||
super(target, blueprint, options)
|
||||
}
|
||||
|
||||
|
||||
@@ -101,6 +101,7 @@ export default class IMouseClickDrag extends IPointing {
|
||||
if (self.started) {
|
||||
self.endDrag()
|
||||
}
|
||||
self.unclicked()
|
||||
if (self.#trackingMouse) {
|
||||
const dragEvent = self.getEvent(Configuration.trackingMouseEventName.end)
|
||||
this.target.dispatchEvent(dragEvent)
|
||||
@@ -146,4 +147,7 @@ export default class IMouseClickDrag extends IPointing {
|
||||
|
||||
endDrag() {
|
||||
}
|
||||
|
||||
unclicked(location) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,11 @@ export default class Select extends IMouseClickDrag {
|
||||
endDrag() {
|
||||
if (this.started) {
|
||||
this.selectorElement.finishSelecting()
|
||||
} else {
|
||||
}
|
||||
}
|
||||
|
||||
unclicked() {
|
||||
if (!this.started) {
|
||||
this.blueprint.unselectAll()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,27 @@ import IMouseWheel from "./IMouseWheel"
|
||||
|
||||
export default class Zoom extends IMouseWheel {
|
||||
|
||||
#enableZoonIn = false
|
||||
|
||||
get enableZoonIn() {
|
||||
return this.#enableZoonIn
|
||||
}
|
||||
|
||||
set enableZoonIn(value) {
|
||||
value = Boolean(value)
|
||||
if (value == this.#enableZoonIn) {
|
||||
return
|
||||
}
|
||||
this.#enableZoonIn = value
|
||||
}
|
||||
|
||||
wheel(variation, location) {
|
||||
let zoomLevel = this.blueprint.getZoom()
|
||||
zoomLevel -= variation
|
||||
variation = -variation
|
||||
if (!this.enableZoonIn && zoomLevel == 0 && variation > 0) {
|
||||
return
|
||||
}
|
||||
zoomLevel += variation
|
||||
this.blueprint.setZoom(zoomLevel, location)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user