mirror of
https://github.com/barsdeveloper/ueblueprint.git
synced 2026-02-21 06:05:45 +08:00
Input refactoring (#12)
* Fix folder name typo * Smaller fixes * Shortcut rename to Shortcuts * Fix quoted attributes in UE 5.3 * remove KeyboardShortcutAction * Remove more trivial classes * Rename IKeyboardShortcut * Node delete shortcut
This commit is contained in:
@@ -21,15 +21,17 @@ export default class IMouseClickDrag extends IPointing {
|
||||
case this.options.clickButton:
|
||||
// Either doesn't matter or consider the click only when clicking on the parent, not descandants
|
||||
if (!this.options.strictTarget || e.target == e.currentTarget) {
|
||||
if (this.options.consumeEvent) {
|
||||
if (this.consumeEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
// Attach the listeners
|
||||
this.#movementListenedElement.addEventListener("mousemove", this.#mouseStartedMovingHandler)
|
||||
document.addEventListener("mouseup", this.#mouseUpHandler)
|
||||
this.clickedPosition = this.locationFromEvent(e)
|
||||
this.blueprint.mousePosition[0] = this.clickedPosition[0]
|
||||
this.blueprint.mousePosition[1] = this.clickedPosition[1]
|
||||
this.setLocationFromEvent(e)
|
||||
this.clickedPosition[0] = this.location[0]
|
||||
this.clickedPosition[1] = this.location[1]
|
||||
this.blueprint.mousePosition[0] = this.location[0]
|
||||
this.blueprint.mousePosition[1] = this.location[1]
|
||||
if (this.target instanceof IDraggableElement) {
|
||||
this.clickedOffset = [
|
||||
this.clickedPosition[0] - this.target.locationX,
|
||||
@@ -49,7 +51,7 @@ export default class IMouseClickDrag extends IPointing {
|
||||
|
||||
/** @param {MouseEvent} e */
|
||||
#mouseStartedMovingHandler = e => {
|
||||
if (this.options.consumeEvent) {
|
||||
if (this.consumeEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
// Delegate from now on to this.#mouseMoveHandler
|
||||
@@ -58,19 +60,19 @@ export default class IMouseClickDrag extends IPointing {
|
||||
// Handler calls e.preventDefault() when it receives the event, this means dispatchEvent returns false
|
||||
const dragEvent = this.getEvent(Configuration.trackingMouseEventName.begin)
|
||||
this.#trackingMouse = this.target.dispatchEvent(dragEvent) == false
|
||||
const location = this.locationFromEvent(e)
|
||||
this.setLocationFromEvent(e)
|
||||
// Do actual actions
|
||||
this.lastLocation = Utility.snapToGrid(this.clickedPosition[0], this.clickedPosition[1], this.stepSize)
|
||||
this.startDrag(location)
|
||||
this.startDrag(this.location)
|
||||
this.started = true
|
||||
}
|
||||
|
||||
/** @param {MouseEvent} e */
|
||||
#mouseMoveHandler = e => {
|
||||
if (this.options.consumeEvent) {
|
||||
if (this.consumeEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
const location = this.locationFromEvent(e)
|
||||
const location = this.setLocationFromEvent(e)
|
||||
const movement = [e.movementX, e.movementY]
|
||||
this.dragTo(location, movement)
|
||||
if (this.#trackingMouse) {
|
||||
@@ -104,7 +106,7 @@ export default class IMouseClickDrag extends IPointing {
|
||||
/** @param {MouseEvent} e */
|
||||
#mouseUpHandler = e => {
|
||||
if (!this.options.exitAnyButton || e.button == this.options.clickButton) {
|
||||
if (this.options.consumeEvent) {
|
||||
if (this.consumeEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
// Remove the handlers of "mousemove" and "mouseup"
|
||||
|
||||
@@ -1,12 +1,29 @@
|
||||
import IInput from "../IInput.js"
|
||||
import Utility from "../../Utility.js"
|
||||
|
||||
/** @typedef {import("../keyboard/KeyboardShortcut.js").default} KeyboardShortcut */
|
||||
|
||||
/**
|
||||
* @template {HTMLElement} T
|
||||
* @template {Element} T
|
||||
* @extends {IInput<T>}
|
||||
*/
|
||||
export default class IPointing extends IInput {
|
||||
|
||||
#location = [0, 0]
|
||||
get location() {
|
||||
return this.#location
|
||||
}
|
||||
|
||||
/** @type {KeyboardShortcut?} */
|
||||
#enablerKey
|
||||
get enablerKey() {
|
||||
return this.#enablerKey
|
||||
}
|
||||
#enablerActivated = true
|
||||
get enablerActivated() {
|
||||
return this.#enablerActivated
|
||||
}
|
||||
|
||||
constructor(target, blueprint, options = {}) {
|
||||
options.ignoreTranslateCompensate ??= false
|
||||
options.ignoreScale ??= false
|
||||
@@ -14,17 +31,28 @@ export default class IPointing extends IInput {
|
||||
super(target, blueprint, options)
|
||||
/** @type {HTMLElement} */
|
||||
this.movementSpace = options.movementSpace
|
||||
if (options.enablerKey) {
|
||||
this.#enablerKey = options.enablerKey
|
||||
this.#enablerKey.onKeyDown = () => this.#enablerActivated = true
|
||||
this.#enablerKey.onKeyUp = () => this.#enablerActivated = false
|
||||
this.#enablerKey.consumeEvent = false
|
||||
this.#enablerKey.listenEvents()
|
||||
this.#enablerActivated = false
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {MouseEvent} mouseEvent */
|
||||
locationFromEvent(mouseEvent) {
|
||||
const location = Utility.convertLocation(
|
||||
setLocationFromEvent(mouseEvent) {
|
||||
let location = Utility.convertLocation(
|
||||
[mouseEvent.clientX, mouseEvent.clientY],
|
||||
this.movementSpace,
|
||||
this.options.ignoreScale
|
||||
)
|
||||
return this.options.ignoreTranslateCompensate
|
||||
location = this.options.ignoreTranslateCompensate
|
||||
? location
|
||||
: this.blueprint.compensateTranslation(location[0], location[1])
|
||||
this.#location[0] = location[0]
|
||||
this.#location[1] = location[1]
|
||||
return this.#location
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,26 +2,40 @@ import Configuration from "../../Configuration.js"
|
||||
import IPointing from "./IPointing.js"
|
||||
|
||||
/**
|
||||
* @template {HTMLElement} T
|
||||
* @typedef {import("../../Blueprint.js").default} Blueprint
|
||||
* @typedef {import("../keyboard/KeyboardShortcut.js").default} KeyboardShortcut
|
||||
*/
|
||||
|
||||
/**
|
||||
* @template {Element} T
|
||||
* @extends {IPointing<T>}
|
||||
*/
|
||||
export default class MouseClick extends IPointing {
|
||||
|
||||
static #ignoreEvent =
|
||||
/** @param {MouseClick} self */
|
||||
self => { }
|
||||
|
||||
/** @param {MouseEvent} e */
|
||||
#mouseDownHandler = e => {
|
||||
this.blueprint.setFocused(true)
|
||||
if (this.enablerKey && !this.enablerActivated) {
|
||||
return
|
||||
}
|
||||
switch (e.button) {
|
||||
case this.options.clickButton:
|
||||
// Either doesn't matter or consider the click only when clicking on the target, not descandants
|
||||
if (!this.options.strictTarget || e.target === e.currentTarget) {
|
||||
if (this.options.consumeEvent) {
|
||||
if (this.consumeEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
// Attach the listeners
|
||||
document.addEventListener("mouseup", this.#mouseUpHandler)
|
||||
this.clickedPosition = this.locationFromEvent(e)
|
||||
this.blueprint.mousePosition[0] = this.clickedPosition[0]
|
||||
this.blueprint.mousePosition[1] = this.clickedPosition[1]
|
||||
this.setLocationFromEvent(e)
|
||||
this.clickedPosition[0] = this.location[0]
|
||||
this.clickedPosition[1] = this.location[1]
|
||||
this.blueprint.mousePosition[0] = this.location[0]
|
||||
this.blueprint.mousePosition[1] = this.location[1]
|
||||
this.clicked(this.clickedPosition)
|
||||
}
|
||||
break
|
||||
@@ -36,7 +50,7 @@ export default class MouseClick extends IPointing {
|
||||
/** @param {MouseEvent} e */
|
||||
#mouseUpHandler = e => {
|
||||
if (!this.options.exitAnyButton || e.button == this.options.clickButton) {
|
||||
if (this.options.consumeEvent) {
|
||||
if (this.consumeEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
// Remove the handlers of "mousemove" and "mouseup"
|
||||
@@ -47,12 +61,25 @@ export default class MouseClick extends IPointing {
|
||||
|
||||
clickedPosition = [0, 0]
|
||||
|
||||
constructor(target, blueprint, options = {}) {
|
||||
/**
|
||||
* @param {T} target
|
||||
* @param {Blueprint} blueprint
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(
|
||||
target,
|
||||
blueprint,
|
||||
options = {},
|
||||
onClick = MouseClick.#ignoreEvent,
|
||||
onUnclick = MouseClick.#ignoreEvent,
|
||||
) {
|
||||
options.clickButton ??= Configuration.mouseClickButton
|
||||
options.consumeEvent ??= true
|
||||
options.exitAnyButton ??= true
|
||||
options.strictTarget ??= false
|
||||
super(target, blueprint, options)
|
||||
this.onClick = onClick
|
||||
this.onUnclick = onUnclick
|
||||
this.listenEvents()
|
||||
}
|
||||
|
||||
@@ -69,8 +96,10 @@ export default class MouseClick extends IPointing {
|
||||
|
||||
/* Subclasses will override the following methods */
|
||||
clicked(location) {
|
||||
this.onClick(this)
|
||||
}
|
||||
|
||||
unclicked(location) {
|
||||
this.onUnclick(this)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,10 +12,10 @@ export default class MouseDbClick extends IPointing {
|
||||
/** @param {MouseEvent} e */
|
||||
#mouseDbClickHandler = e => {
|
||||
if (!this.options.strictTarget || e.target === e.currentTarget) {
|
||||
if (this.options.consumeEvent) {
|
||||
if (this.consumeEvent) {
|
||||
e.stopImmediatePropagation() // Captured, don't call anyone else
|
||||
}
|
||||
this.clickedPosition = this.locationFromEvent(e)
|
||||
this.clickedPosition = this.setLocationFromEvent(e)
|
||||
this.blueprint.mousePosition[0] = this.clickedPosition[0]
|
||||
this.blueprint.mousePosition[1] = this.clickedPosition[1]
|
||||
this.dbclicked(this.clickedPosition)
|
||||
|
||||
@@ -9,7 +9,9 @@ export default class MouseTracking extends IPointing {
|
||||
/** @param {MouseEvent} e */
|
||||
#mousemoveHandler= e => {
|
||||
e.preventDefault()
|
||||
this.blueprint.mousePosition = this.locationFromEvent(e)
|
||||
this.setLocationFromEvent(e)
|
||||
this.blueprint.mousePosition[0] = this.location[0]
|
||||
this.blueprint.mousePosition[1] = this.location[1]
|
||||
}
|
||||
|
||||
/** @param {CustomEvent} e */
|
||||
|
||||
@@ -2,13 +2,26 @@ import IPointing from "./IPointing.js"
|
||||
|
||||
/** @typedef {import("../../Blueprint.js").default} Blueprint */
|
||||
|
||||
export default class IMouseWheel extends IPointing {
|
||||
export default class MouseWheel extends IPointing {
|
||||
|
||||
static #ignoreEvent =
|
||||
/** @param {MouseWheel} self */
|
||||
self => { }
|
||||
|
||||
#variation = 0
|
||||
get variation() {
|
||||
return this.#variation
|
||||
}
|
||||
|
||||
/** @param {WheelEvent} e */
|
||||
#mouseWheelHandler = e => {
|
||||
if (this.enablerKey && !this.enablerActivated) {
|
||||
return
|
||||
}
|
||||
e.preventDefault()
|
||||
const location = this.locationFromEvent(e)
|
||||
this.wheel(e.deltaY, location)
|
||||
this.#variation = e.deltaY
|
||||
this.setLocationFromEvent(e)
|
||||
this.wheel()
|
||||
}
|
||||
|
||||
/** @param {WheelEvent} e */
|
||||
@@ -19,11 +32,17 @@ export default class IMouseWheel extends IPointing {
|
||||
* @param {Blueprint} blueprint
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(target, blueprint, options = {}) {
|
||||
constructor(
|
||||
target,
|
||||
blueprint,
|
||||
options = {},
|
||||
onWheel = MouseWheel.#ignoreEvent,
|
||||
) {
|
||||
options.listenOnFocus = true
|
||||
options.strictTarget ??= false
|
||||
super(target, blueprint, options)
|
||||
this.strictTarget = options.strictTarget
|
||||
this.onWheel = onWheel
|
||||
}
|
||||
|
||||
listenEvents() {
|
||||
@@ -36,7 +55,8 @@ export default class IMouseWheel extends IPointing {
|
||||
this.movementSpace.parentElement?.removeEventListener("wheel", this.#mouseParentWheelHandler)
|
||||
}
|
||||
|
||||
/* Subclasses will override the following method */
|
||||
wheel(variation, location) {
|
||||
/* Subclasses can override */
|
||||
wheel() {
|
||||
this.onWheel(this)
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import Configuration from "../../Configuration.js"
|
||||
import IMouseWheel from "./IMouseWheel.js"
|
||||
import MouseWheel from "./MouseWheel.js"
|
||||
|
||||
export default class Zoom extends IMouseWheel {
|
||||
export default class Zoom extends MouseWheel {
|
||||
|
||||
#accumulatedVariation = 0
|
||||
|
||||
@@ -16,19 +16,17 @@ export default class Zoom extends IMouseWheel {
|
||||
this.#enableZoonIn = value
|
||||
}
|
||||
|
||||
wheel(variation, location) {
|
||||
this.#accumulatedVariation += -variation
|
||||
variation = this.#accumulatedVariation
|
||||
wheel() {
|
||||
this.#accumulatedVariation += -this.variation
|
||||
if (Math.abs(this.#accumulatedVariation) < Configuration.mouseWheelZoomThreshold) {
|
||||
return
|
||||
} else {
|
||||
this.#accumulatedVariation = 0
|
||||
}
|
||||
let zoomLevel = this.blueprint.getZoom()
|
||||
if (!this.enableZoonIn && zoomLevel == 0 && variation > 0) {
|
||||
if (!this.enableZoonIn && zoomLevel == 0 && this.#accumulatedVariation > 0) {
|
||||
return
|
||||
}
|
||||
zoomLevel += Math.sign(variation)
|
||||
this.blueprint.setZoom(zoomLevel, location)
|
||||
zoomLevel += Math.sign(this.#accumulatedVariation)
|
||||
this.blueprint.setZoom(zoomLevel, this.location)
|
||||
this.#accumulatedVariation = 0
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user