mirror of
https://github.com/Azornes/Comfyui-LayerForge.git
synced 2026-03-25 14:25:44 -03:00
unify modifier key handling in CanvasInteractions
Implemented centralized modifier state management with ModifierState interface and getModifierState() method. This eliminates inconsistencies between event-based and state-based modifier checking across mouse, wheel, and keyboard interactions.
This commit is contained in:
@@ -49,6 +49,14 @@ export class CanvasInteractions {
|
|||||||
view: this.canvas.getMouseViewCoordinates(e)
|
view: this.canvas.getMouseViewCoordinates(e)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
getModifierState(e) {
|
||||||
|
return {
|
||||||
|
ctrl: this.interaction.isCtrlPressed || e?.ctrlKey || false,
|
||||||
|
shift: this.interaction.isShiftPressed || e?.shiftKey || false,
|
||||||
|
alt: this.interaction.isAltPressed || e?.altKey || false,
|
||||||
|
meta: this.interaction.isMetaPressed || e?.metaKey || false,
|
||||||
|
};
|
||||||
|
}
|
||||||
preventEventDefaults(e) {
|
preventEventDefaults(e) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -150,6 +158,7 @@ export class CanvasInteractions {
|
|||||||
handleMouseDown(e) {
|
handleMouseDown(e) {
|
||||||
this.canvas.canvas.focus();
|
this.canvas.canvas.focus();
|
||||||
const coords = this.getMouseCoordinates(e);
|
const coords = this.getMouseCoordinates(e);
|
||||||
|
const mods = this.getModifierState(e);
|
||||||
if (this.interaction.mode === 'drawingMask') {
|
if (this.interaction.mode === 'drawingMask') {
|
||||||
this.canvas.maskTool.handleMouseDown(coords.world, coords.view);
|
this.canvas.maskTool.handleMouseDown(coords.world, coords.view);
|
||||||
this.canvas.render();
|
this.canvas.render();
|
||||||
@@ -161,11 +170,11 @@ export class CanvasInteractions {
|
|||||||
}
|
}
|
||||||
// --- Ostateczna, poprawna kolejność sprawdzania ---
|
// --- Ostateczna, poprawna kolejność sprawdzania ---
|
||||||
// 1. Akcje globalne z modyfikatorami (mają najwyższy priorytet)
|
// 1. Akcje globalne z modyfikatorami (mają najwyższy priorytet)
|
||||||
if (e.shiftKey && e.ctrlKey) {
|
if (mods.shift && mods.ctrl) {
|
||||||
this.startCanvasMove(coords.world);
|
this.startCanvasMove(coords.world);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.shiftKey) {
|
if (mods.shift) {
|
||||||
// Clear custom shape when starting canvas resize
|
// Clear custom shape when starting canvas resize
|
||||||
if (this.canvas.outputAreaShape) {
|
if (this.canvas.outputAreaShape) {
|
||||||
// If auto-apply shape mask is enabled, remove the mask before clearing the shape
|
// If auto-apply shape mask is enabled, remove the mask before clearing the shape
|
||||||
@@ -350,14 +359,15 @@ export class CanvasInteractions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
handleLayerWheelTransformation(e) {
|
handleLayerWheelTransformation(e) {
|
||||||
|
const mods = this.getModifierState(e);
|
||||||
const rotationStep = 5 * (e.deltaY > 0 ? -1 : 1);
|
const rotationStep = 5 * (e.deltaY > 0 ? -1 : 1);
|
||||||
const direction = e.deltaY < 0 ? 1 : -1;
|
const direction = e.deltaY < 0 ? 1 : -1;
|
||||||
this.canvas.canvasSelection.selectedLayers.forEach((layer) => {
|
this.canvas.canvasSelection.selectedLayers.forEach((layer) => {
|
||||||
if (e.shiftKey) {
|
if (mods.shift) {
|
||||||
this.handleLayerRotation(layer, e.ctrlKey, direction, rotationStep);
|
this.handleLayerRotation(layer, mods.ctrl, direction, rotationStep);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
this.handleLayerScaling(layer, e.ctrlKey, e.deltaY);
|
this.handleLayerScaling(layer, mods.ctrl, e.deltaY);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -446,11 +456,12 @@ export class CanvasInteractions {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Globalne skróty (Undo/Redo/Copy/Paste)
|
// Globalne skróty (Undo/Redo/Copy/Paste)
|
||||||
if (e.ctrlKey || e.metaKey) {
|
const mods = this.getModifierState(e);
|
||||||
|
if (mods.ctrl || mods.meta) {
|
||||||
let handled = true;
|
let handled = true;
|
||||||
switch (e.key.toLowerCase()) {
|
switch (e.key.toLowerCase()) {
|
||||||
case 'z':
|
case 'z':
|
||||||
if (e.shiftKey) {
|
if (mods.shift) {
|
||||||
this.canvas.redo();
|
this.canvas.redo();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -477,7 +488,7 @@ export class CanvasInteractions {
|
|||||||
}
|
}
|
||||||
// Skróty kontekstowe (zależne od zaznaczenia)
|
// Skróty kontekstowe (zależne od zaznaczenia)
|
||||||
if (this.canvas.canvasSelection.selectedLayers.length > 0) {
|
if (this.canvas.canvasSelection.selectedLayers.length > 0) {
|
||||||
const step = e.shiftKey ? 10 : 1;
|
const step = mods.shift ? 10 : 1;
|
||||||
let needsRender = false;
|
let needsRender = false;
|
||||||
// Używamy e.code dla spójności i niezależności od układu klawiatury
|
// Używamy e.code dla spójności i niezależności od układu klawiatury
|
||||||
const movementKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'BracketLeft', 'BracketRight'];
|
const movementKeys = ['ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown', 'BracketLeft', 'BracketRight'];
|
||||||
@@ -609,7 +620,8 @@ export class CanvasInteractions {
|
|||||||
prepareForDrag(layer, worldCoords) {
|
prepareForDrag(layer, worldCoords) {
|
||||||
// Zaktualizuj zaznaczenie, ale nie zapisuj stanu
|
// Zaktualizuj zaznaczenie, ale nie zapisuj stanu
|
||||||
// Support both Ctrl (Windows/Linux) and Cmd (macOS) for multi-selection
|
// Support both Ctrl (Windows/Linux) and Cmd (macOS) for multi-selection
|
||||||
if (this.interaction.isCtrlPressed || this.interaction.isMetaPressed) {
|
const mods = this.getModifierState();
|
||||||
|
if (mods.ctrl || mods.meta) {
|
||||||
const index = this.canvas.canvasSelection.selectedLayers.indexOf(layer);
|
const index = this.canvas.canvasSelection.selectedLayers.indexOf(layer);
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
this.canvas.canvasSelection.updateSelection([...this.canvas.canvasSelection.selectedLayers, layer]);
|
this.canvas.canvasSelection.updateSelection([...this.canvas.canvasSelection.selectedLayers, layer]);
|
||||||
|
|||||||
@@ -10,6 +10,13 @@ interface MouseCoordinates {
|
|||||||
view: Point;
|
view: Point;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface ModifierState {
|
||||||
|
ctrl: boolean;
|
||||||
|
shift: boolean;
|
||||||
|
alt: boolean;
|
||||||
|
meta: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
interface TransformOrigin {
|
interface TransformOrigin {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
@@ -100,6 +107,15 @@ export class CanvasInteractions {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private getModifierState(e?: MouseEvent | WheelEvent | KeyboardEvent): ModifierState {
|
||||||
|
return {
|
||||||
|
ctrl: this.interaction.isCtrlPressed || (e as any)?.ctrlKey || false,
|
||||||
|
shift: this.interaction.isShiftPressed || (e as any)?.shiftKey || false,
|
||||||
|
alt: this.interaction.isAltPressed || (e as any)?.altKey || false,
|
||||||
|
meta: this.interaction.isMetaPressed || (e as any)?.metaKey || false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private preventEventDefaults(e: Event): void {
|
private preventEventDefaults(e: Event): void {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
@@ -223,6 +239,7 @@ export class CanvasInteractions {
|
|||||||
handleMouseDown(e: MouseEvent): void {
|
handleMouseDown(e: MouseEvent): void {
|
||||||
this.canvas.canvas.focus();
|
this.canvas.canvas.focus();
|
||||||
const coords = this.getMouseCoordinates(e);
|
const coords = this.getMouseCoordinates(e);
|
||||||
|
const mods = this.getModifierState(e);
|
||||||
|
|
||||||
if (this.interaction.mode === 'drawingMask') {
|
if (this.interaction.mode === 'drawingMask') {
|
||||||
this.canvas.maskTool.handleMouseDown(coords.world, coords.view);
|
this.canvas.maskTool.handleMouseDown(coords.world, coords.view);
|
||||||
@@ -238,11 +255,11 @@ export class CanvasInteractions {
|
|||||||
// --- Ostateczna, poprawna kolejność sprawdzania ---
|
// --- Ostateczna, poprawna kolejność sprawdzania ---
|
||||||
|
|
||||||
// 1. Akcje globalne z modyfikatorami (mają najwyższy priorytet)
|
// 1. Akcje globalne z modyfikatorami (mają najwyższy priorytet)
|
||||||
if (e.shiftKey && e.ctrlKey) {
|
if (mods.shift && mods.ctrl) {
|
||||||
this.startCanvasMove(coords.world);
|
this.startCanvasMove(coords.world);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (e.shiftKey) {
|
if (mods.shift) {
|
||||||
// Clear custom shape when starting canvas resize
|
// Clear custom shape when starting canvas resize
|
||||||
if (this.canvas.outputAreaShape) {
|
if (this.canvas.outputAreaShape) {
|
||||||
// If auto-apply shape mask is enabled, remove the mask before clearing the shape
|
// If auto-apply shape mask is enabled, remove the mask before clearing the shape
|
||||||
@@ -454,14 +471,15 @@ export class CanvasInteractions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private handleLayerWheelTransformation(e: WheelEvent): void {
|
private handleLayerWheelTransformation(e: WheelEvent): void {
|
||||||
|
const mods = this.getModifierState(e);
|
||||||
const rotationStep = 5 * (e.deltaY > 0 ? -1 : 1);
|
const rotationStep = 5 * (e.deltaY > 0 ? -1 : 1);
|
||||||
const direction = e.deltaY < 0 ? 1 : -1;
|
const direction = e.deltaY < 0 ? 1 : -1;
|
||||||
|
|
||||||
this.canvas.canvasSelection.selectedLayers.forEach((layer: Layer) => {
|
this.canvas.canvasSelection.selectedLayers.forEach((layer: Layer) => {
|
||||||
if (e.shiftKey) {
|
if (mods.shift) {
|
||||||
this.handleLayerRotation(layer, e.ctrlKey, direction, rotationStep);
|
this.handleLayerRotation(layer, mods.ctrl, direction, rotationStep);
|
||||||
} else {
|
} else {
|
||||||
this.handleLayerScaling(layer, e.ctrlKey, e.deltaY);
|
this.handleLayerScaling(layer, mods.ctrl, e.deltaY);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -552,11 +570,12 @@ export class CanvasInteractions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Globalne skróty (Undo/Redo/Copy/Paste)
|
// Globalne skróty (Undo/Redo/Copy/Paste)
|
||||||
if (e.ctrlKey || e.metaKey) {
|
const mods = this.getModifierState(e);
|
||||||
|
if (mods.ctrl || mods.meta) {
|
||||||
let handled = true;
|
let handled = true;
|
||||||
switch (e.key.toLowerCase()) {
|
switch (e.key.toLowerCase()) {
|
||||||
case 'z':
|
case 'z':
|
||||||
if (e.shiftKey) {
|
if (mods.shift) {
|
||||||
this.canvas.redo();
|
this.canvas.redo();
|
||||||
} else {
|
} else {
|
||||||
this.canvas.undo();
|
this.canvas.undo();
|
||||||
@@ -583,7 +602,7 @@ export class CanvasInteractions {
|
|||||||
|
|
||||||
// Skróty kontekstowe (zależne od zaznaczenia)
|
// Skróty kontekstowe (zależne od zaznaczenia)
|
||||||
if (this.canvas.canvasSelection.selectedLayers.length > 0) {
|
if (this.canvas.canvasSelection.selectedLayers.length > 0) {
|
||||||
const step = e.shiftKey ? 10 : 1;
|
const step = mods.shift ? 10 : 1;
|
||||||
let needsRender = false;
|
let needsRender = false;
|
||||||
|
|
||||||
// Używamy e.code dla spójności i niezależności od układu klawiatury
|
// Używamy e.code dla spójności i niezależności od układu klawiatury
|
||||||
@@ -719,7 +738,8 @@ export class CanvasInteractions {
|
|||||||
prepareForDrag(layer: Layer, worldCoords: Point): void {
|
prepareForDrag(layer: Layer, worldCoords: Point): void {
|
||||||
// Zaktualizuj zaznaczenie, ale nie zapisuj stanu
|
// Zaktualizuj zaznaczenie, ale nie zapisuj stanu
|
||||||
// Support both Ctrl (Windows/Linux) and Cmd (macOS) for multi-selection
|
// Support both Ctrl (Windows/Linux) and Cmd (macOS) for multi-selection
|
||||||
if (this.interaction.isCtrlPressed || this.interaction.isMetaPressed) {
|
const mods = this.getModifierState();
|
||||||
|
if (mods.ctrl || mods.meta) {
|
||||||
const index = this.canvas.canvasSelection.selectedLayers.indexOf(layer);
|
const index = this.canvas.canvasSelection.selectedLayers.indexOf(layer);
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
this.canvas.canvasSelection.updateSelection([...this.canvas.canvasSelection.selectedLayers, layer]);
|
this.canvas.canvasSelection.updateSelection([...this.canvas.canvasSelection.selectedLayers, layer]);
|
||||||
|
|||||||
Reference in New Issue
Block a user