feat: Add ability to hide magnify glass preview and refine info panel visibility based on glass state.
This commit is contained in:
@@ -68,7 +68,11 @@ export class InfoPanel {
|
||||
this.magnifyGlass.updateMagnifiedView = (() => {
|
||||
originalUpdateMagnifiedView();
|
||||
|
||||
if (this.stateManager.state.settings["🔍MagnifyGlass.InfoPanelEnabled"] && this.magnifyGlass.state.active) {
|
||||
// Only schedule info update if panel is enabled, glass is active, AND preview is visible
|
||||
// This prevents extra work when glass preview is hidden via hover controls
|
||||
if (this.stateManager.state.settings["🔍MagnifyGlass.InfoPanelEnabled"] &&
|
||||
this.magnifyGlass.state.active &&
|
||||
this.stateManager.state.isGlassPreviewVisible !== false) {
|
||||
this.scheduleInfoUpdate();
|
||||
}
|
||||
}).bind(this);
|
||||
@@ -79,6 +83,13 @@ export class InfoPanel {
|
||||
|
||||
this.magnifyGlass.ui.show = (() => {
|
||||
originalShow();
|
||||
|
||||
// CRITICAL: Only restore panel if the magnify glass is actually active
|
||||
// This prevents the panel from showing when toggle() is switching it OFF
|
||||
if (!this.magnifyGlass.state.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.stateManager.state.settings["🔍MagnifyGlass.InfoPanelEnabled"]) {
|
||||
// Restore state: If it was visible before hide, make it visible now.
|
||||
// Otherwise only show controls.
|
||||
@@ -114,6 +125,12 @@ export class InfoPanel {
|
||||
|
||||
originalHide();
|
||||
this.uiManager.hide();
|
||||
|
||||
// FORCE HIDE: Directly set panel display to none as a safety measure
|
||||
if (this.uiManager.elements.panel) {
|
||||
this.uiManager.elements.panel.style.display = 'none';
|
||||
}
|
||||
|
||||
// Explicitly hide floating controls when glass is disabled
|
||||
if (this.uiManager.elements.controls) {
|
||||
this.uiManager.elements.controls.style.display = 'none';
|
||||
@@ -140,6 +157,8 @@ export class InfoPanel {
|
||||
|
||||
// Safety: If disabled or inactive, ensure hidden and return
|
||||
if (!settings["🔍MagnifyGlass.InfoPanelEnabled"] || !isActive) {
|
||||
// Hide the panel completely when the glass is inactive
|
||||
this.uiManager.hide();
|
||||
if (this.uiManager.elements.controls && this.uiManager.elements.controls.style.display !== 'none') {
|
||||
this.uiManager.elements.controls.style.display = 'none';
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import type { ComfyApp, ComfyNode, ComfyWidget, GatheredInfo, NodeInfo, WidgetInfo, MediaInfo } from '../types/comfyui';
|
||||
|
||||
declare const app: ComfyApp;
|
||||
declare const LiteGraph: any;
|
||||
|
||||
/**
|
||||
* Information Gatherer class.
|
||||
|
||||
@@ -147,8 +147,15 @@ export class PositionManager {
|
||||
return;
|
||||
}
|
||||
|
||||
const isPanelVisible = this.stateManager.state.isPanelVisible;
|
||||
// NEW: Check if Magnify Glass is active globally
|
||||
const magnifyGlass = window.comfyUIMagnifyGlass;
|
||||
if (magnifyGlass && !magnifyGlass.state.active) {
|
||||
controlsElement.style.display = 'none';
|
||||
return;
|
||||
}
|
||||
|
||||
const isPanelVisible = this.stateManager.state.isPanelVisible;
|
||||
|
||||
let referenceRect: DOMRect | null = null;
|
||||
|
||||
// 1. Position relative to PANEL (Preferred if visible)
|
||||
|
||||
@@ -305,10 +305,13 @@ export class UIManager {
|
||||
this.updateControlStates();
|
||||
this.updatePinnedState(); // Update visual class
|
||||
|
||||
// Toggle ONLY the visual visibility (opacity) of the glass preview
|
||||
// The tool remains active so the inspector can track position
|
||||
// Toggle BOTH the visual visibility AND the rendering
|
||||
// This fully disables the offscreen renderer when preview is hidden
|
||||
const magnifyGlass = (window as any).comfyUIMagnifyGlass;
|
||||
if (magnifyGlass && magnifyGlass.ui?.setPreviewVisibility) {
|
||||
if (magnifyGlass && magnifyGlass.setGlassPreviewActive) {
|
||||
magnifyGlass.setGlassPreviewActive(this.stateManager.state.isGlassPreviewVisible);
|
||||
} else if (magnifyGlass && magnifyGlass.ui?.setPreviewVisibility) {
|
||||
// Fallback for backwards compatibility
|
||||
magnifyGlass.ui.setPreviewVisibility(this.stateManager.state.isGlassPreviewVisible);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -137,11 +137,11 @@ export class EventHandler {
|
||||
toggleGlassBtn.click();
|
||||
this.magnifyGlass.debugger.log(`Glass Preview Toggled (via button)`);
|
||||
} else {
|
||||
// Fallback: toggle via UI directly if button not found
|
||||
// Fallback: toggle via setGlassPreviewActive directly if button not found
|
||||
const glassDiv = this.magnifyGlass.ui.glassDiv;
|
||||
if (glassDiv) {
|
||||
const isVisible = glassDiv.style.display !== 'none' && glassDiv.style.opacity !== '0';
|
||||
this.magnifyGlass.ui.setPreviewVisibility(!isVisible);
|
||||
this.magnifyGlass.setGlassPreviewActive(!isVisible);
|
||||
this.magnifyGlass.debugger.log(`Glass Preview Toggled (fallback): ${!isVisible ? 'ON' : 'OFF'}`);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,6 +48,9 @@ export class MagnifierState {
|
||||
/** Whether glass drag mode is enabled (move icon on hover controls) */
|
||||
isDragModeEnabled: boolean;
|
||||
|
||||
/** Whether glass preview is hidden via hover controls (but tool still active) */
|
||||
isPreviewHidden: boolean;
|
||||
|
||||
// --- Debug Metrics for Virtual Zoom ---
|
||||
virtualMouseCssX: number;
|
||||
virtualMouseCssY: number;
|
||||
@@ -74,6 +77,7 @@ export class MagnifierState {
|
||||
this.canvasOffsetY = 0;
|
||||
this.isRenderScheduled = false;
|
||||
this.isDragModeEnabled = false;
|
||||
this.isPreviewHidden = false;
|
||||
|
||||
this.virtualMouseCssX = 0;
|
||||
this.virtualMouseCssY = 0;
|
||||
|
||||
@@ -132,21 +132,120 @@ export class MagnifyGlass {
|
||||
*/
|
||||
toggle(): void {
|
||||
const state = this.state;
|
||||
const config = this.config;
|
||||
|
||||
if (state.active) {
|
||||
// TURNING OFF - Force hide everything
|
||||
state.active = false;
|
||||
this.ui.hide();
|
||||
|
||||
// SIMPLE FIX: Force hide info panel directly by DOM
|
||||
this.forceHideInfoPanel();
|
||||
} else {
|
||||
// TURNING ON
|
||||
state.active = true;
|
||||
this.removeForceHide(); // Remove force-hidden class before showing
|
||||
this.ui.show();
|
||||
// Update initial position if needed
|
||||
if (this.eventHandler) {
|
||||
this.eventHandler.updateInitialPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set glass preview visibility WITHOUT affecting info panel.
|
||||
* This is used by the toggle-glass hover control button.
|
||||
* When hidden, the renderer stops completely to save performance.
|
||||
* When shown, the renderer resumes.
|
||||
*
|
||||
* @param visible - true to show and enable rendering, false to hide and disable
|
||||
*/
|
||||
setGlassPreviewActive(visible: boolean): void {
|
||||
// Track this state internally
|
||||
this.state.isPreviewHidden = !visible;
|
||||
|
||||
if (visible) {
|
||||
// Show the glass preview
|
||||
this.ui.setPreviewVisibility(true);
|
||||
// Resume rendering on next mouse move
|
||||
} else {
|
||||
// Hide the glass preview visually
|
||||
this.ui.setPreviewVisibility(false);
|
||||
// The rendering will be skipped in updateMagnifiedView due to isPreviewHidden check
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Force hide the info panel using CSS class with !important.
|
||||
* This bypasses all state management and inline style overrides.
|
||||
*/
|
||||
private forceHideInfoPanel(): void {
|
||||
// Ensure CSS rule exists
|
||||
this.ensureForceHideCssRule();
|
||||
|
||||
// Add the force-hidden class to info panel
|
||||
const infoPanel = document.querySelector('.magnify-info-panel');
|
||||
if (infoPanel) {
|
||||
infoPanel.classList.add('magnify-glass-force-hidden');
|
||||
}
|
||||
|
||||
// Add the force-hidden class to floating controls
|
||||
const floatingControls = document.querySelector('.floating-controls');
|
||||
if (floatingControls) {
|
||||
floatingControls.classList.add('magnify-glass-force-hidden');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the force-hidden class when glass is showing.
|
||||
*/
|
||||
private removeForceHide(): void {
|
||||
const infoPanel = document.querySelector('.magnify-info-panel');
|
||||
if (infoPanel) {
|
||||
infoPanel.classList.remove('magnify-glass-force-hidden');
|
||||
}
|
||||
|
||||
const floatingControls = document.querySelector('.floating-controls');
|
||||
if (floatingControls) {
|
||||
floatingControls.classList.remove('magnify-glass-force-hidden');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure the CSS rule for force-hidden exists.
|
||||
*/
|
||||
private ensureForceHideCssRule(): void {
|
||||
const styleId = 'magnify-glass-force-hide-style';
|
||||
if (document.getElementById(styleId)) return;
|
||||
|
||||
const style = document.createElement('style');
|
||||
style.id = styleId;
|
||||
style.textContent = `
|
||||
.magnify-glass-force-hidden {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the glass preview is visible.
|
||||
* Returns false if hidden via hover controls.
|
||||
*/
|
||||
private isGlassPreviewVisible(): boolean {
|
||||
// Check info panel extension state for isGlassPreviewVisible
|
||||
const extensions = (window as any).comfyUIMagnifyGlassExtensions;
|
||||
if (extensions && extensions.length > 0) {
|
||||
const infoPanel = extensions[0];
|
||||
if (infoPanel?.stateManager?.state) {
|
||||
return infoPanel.stateManager.state.isGlassPreviewVisible !== false;
|
||||
}
|
||||
}
|
||||
// Default to visible if we can't find the state
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the magnified view.
|
||||
*/
|
||||
@@ -155,6 +254,12 @@ export class MagnifyGlass {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip rendering if glass preview is hidden via hover controls
|
||||
// This prevents double FPS when only the info panel is active
|
||||
if (this.state.isPreviewHidden) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get canvas transformation info
|
||||
this.updateCanvasTransformation();
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ describe('ConfigManager', () => {
|
||||
expect(configManager.activationKey).toBe('x');
|
||||
expect(configManager.altRequired).toBe(false);
|
||||
expect(configManager.followCursor).toBe(false);
|
||||
expect(configManager.debugMode).toBe(false);
|
||||
// Note: debugMode was removed from ConfigManager
|
||||
});
|
||||
|
||||
it('should initialize offsets to zero', () => {
|
||||
|
||||
@@ -46,7 +46,7 @@ class InfoPanel {
|
||||
const originalUpdateMagnifiedView = this.magnifyGlass.updateMagnifiedView.bind(this.magnifyGlass);
|
||||
this.magnifyGlass.updateMagnifiedView = (() => {
|
||||
originalUpdateMagnifiedView();
|
||||
if (this.stateManager.state.settings["🔍MagnifyGlass.InfoPanelEnabled"] && this.magnifyGlass.state.active) {
|
||||
if (this.stateManager.state.settings["🔍MagnifyGlass.InfoPanelEnabled"] && this.magnifyGlass.state.active && this.stateManager.state.isGlassPreviewVisible !== false) {
|
||||
this.scheduleInfoUpdate();
|
||||
}
|
||||
}).bind(this);
|
||||
@@ -54,6 +54,9 @@ class InfoPanel {
|
||||
const originalHide = this.magnifyGlass.ui.hide.bind(this.magnifyGlass.ui);
|
||||
this.magnifyGlass.ui.show = (() => {
|
||||
originalShow();
|
||||
if (!this.magnifyGlass.state.active) {
|
||||
return;
|
||||
}
|
||||
if (this.stateManager.state.settings["🔍MagnifyGlass.InfoPanelEnabled"]) {
|
||||
if (this.stateManager.state.wasPanelVisibleBeforeHide) {
|
||||
this.uiManager.show();
|
||||
@@ -77,6 +80,9 @@ class InfoPanel {
|
||||
this.stateManager.state.wasPanelVisibleBeforeHide = this.stateManager.state.isPanelVisible;
|
||||
originalHide();
|
||||
this.uiManager.hide();
|
||||
if (this.uiManager.elements.panel) {
|
||||
this.uiManager.elements.panel.style.display = "none";
|
||||
}
|
||||
if (this.uiManager.elements.controls) {
|
||||
this.uiManager.elements.controls.style.display = "none";
|
||||
}
|
||||
@@ -94,6 +100,7 @@ class InfoPanel {
|
||||
const settings = this.stateManager.state.settings;
|
||||
const isActive = this.magnifyGlass.state.active;
|
||||
if (!settings["🔍MagnifyGlass.InfoPanelEnabled"] || !isActive) {
|
||||
this.uiManager.hide();
|
||||
if (this.uiManager.elements.controls && this.uiManager.elements.controls.style.display !== "none") {
|
||||
this.uiManager.elements.controls.style.display = "none";
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -109,8 +109,12 @@ class PositionManager {
|
||||
controlsElement.style.display = "none";
|
||||
return;
|
||||
}
|
||||
const isPanelVisible = this.stateManager.state.isPanelVisible;
|
||||
const magnifyGlass = window.comfyUIMagnifyGlass;
|
||||
if (magnifyGlass && !magnifyGlass.state.active) {
|
||||
controlsElement.style.display = "none";
|
||||
return;
|
||||
}
|
||||
const isPanelVisible = this.stateManager.state.isPanelVisible;
|
||||
let referenceRect = null;
|
||||
if (isPanelVisible && this.panelElement) {
|
||||
if (this.cachedPanelPosition) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -200,7 +200,9 @@ class UIManager {
|
||||
this.updateControlStates();
|
||||
this.updatePinnedState();
|
||||
const magnifyGlass = window.comfyUIMagnifyGlass;
|
||||
if (magnifyGlass && ((_a = magnifyGlass.ui) == null ? void 0 : _a.setPreviewVisibility)) {
|
||||
if (magnifyGlass && magnifyGlass.setGlassPreviewActive) {
|
||||
magnifyGlass.setGlassPreviewActive(this.stateManager.state.isGlassPreviewVisible);
|
||||
} else if (magnifyGlass && ((_a = magnifyGlass.ui) == null ? void 0 : _a.setPreviewVisibility)) {
|
||||
magnifyGlass.ui.setPreviewVisibility(this.stateManager.state.isGlassPreviewVisible);
|
||||
}
|
||||
break;
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -107,7 +107,7 @@ class EventHandler {
|
||||
const glassDiv = this.magnifyGlass.ui.glassDiv;
|
||||
if (glassDiv) {
|
||||
const isVisible = glassDiv.style.display !== "none" && glassDiv.style.opacity !== "0";
|
||||
this.magnifyGlass.ui.setPreviewVisibility(!isVisible);
|
||||
this.magnifyGlass.setGlassPreviewActive(!isVisible);
|
||||
this.magnifyGlass.debugger.log(`Glass Preview Toggled (fallback): ${!isVisible ? "ON" : "OFF"}`);
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -29,6 +29,8 @@ class MagnifierState {
|
||||
__publicField(this, "isRenderScheduled");
|
||||
/** Whether glass drag mode is enabled (move icon on hover controls) */
|
||||
__publicField(this, "isDragModeEnabled");
|
||||
/** Whether glass preview is hidden via hover controls (but tool still active) */
|
||||
__publicField(this, "isPreviewHidden");
|
||||
// --- Debug Metrics for Virtual Zoom ---
|
||||
__publicField(this, "virtualMouseCssX");
|
||||
__publicField(this, "virtualMouseCssY");
|
||||
@@ -52,6 +54,7 @@ class MagnifierState {
|
||||
this.canvasOffsetY = 0;
|
||||
this.isRenderScheduled = false;
|
||||
this.isDragModeEnabled = false;
|
||||
this.isPreviewHidden = false;
|
||||
this.virtualMouseCssX = 0;
|
||||
this.virtualMouseCssY = 0;
|
||||
this.virtualGraphX = 0;
|
||||
|
||||
@@ -1 +1 @@
|
||||
{"version":3,"file":"MagnifierState.js","sources":["../../src/magnify-glass/MagnifierState.ts"],"sourcesContent":["/**\n * ComfyUI MagnifyGlass - MagnifierState (TypeScript)\n * \n * Manages the state of the magnifying glass.\n */\n\n/**\n * Magnifier state class.\n * Tracks activation state, cursor position, and canvas transforms.\n */\nexport class MagnifierState {\n /** Whether the magnifier is currently active */\n active: boolean;\n\n /** Track if the glass has been activated before */\n wasActivatedBefore: boolean;\n\n /** Cursor X relative to litegraphCanvas */\n x: number;\n\n /** Cursor Y relative to litegraphCanvas */\n y: number;\n\n /** Calculated source area X */\n sourceX: number;\n\n /** Calculated source area Y */\n sourceY: number;\n\n /** Calculated source area width */\n sourceWidth: number;\n\n /** Calculated source area height */\n sourceHeight: number;\n\n /** Current canvas scale/zoom */\n canvasScale: number;\n\n /** Canvas translation X */\n canvasOffsetX: number;\n\n /** Canvas translation Y */\n canvasOffsetY: number;\n\n /** Flag to manage requestAnimationFrame */\n isRenderScheduled: boolean;\n\n /** Whether glass drag mode is enabled (move icon on hover controls) */\n isDragModeEnabled: boolean;\n\n // --- Debug Metrics for Virtual Zoom ---\n virtualMouseCssX: number;\n virtualMouseCssY: number;\n virtualGraphX: number;\n virtualGraphY: number;\n virtualNewOffsetX: number;\n virtualNewOffsetY: number;\n\n // --- Manual Calibration ---\n virtualDebugOffsetX: number;\n virtualDebugOffsetY: number;\n\n constructor() {\n this.active = false;\n this.wasActivatedBefore = false;\n this.x = 0;\n this.y = 0;\n this.sourceX = 0;\n this.sourceY = 0;\n this.sourceWidth = 0;\n this.sourceHeight = 0;\n this.canvasScale = 1.0;\n this.canvasOffsetX = 0;\n this.canvasOffsetY = 0;\n this.isRenderScheduled = false;\n this.isDragModeEnabled = false;\n\n this.virtualMouseCssX = 0;\n this.virtualMouseCssY = 0;\n this.virtualGraphX = 0;\n this.virtualGraphY = 0;\n this.virtualNewOffsetX = 0;\n this.virtualNewOffsetY = 0;\n this.virtualDebugOffsetX = 0;\n this.virtualDebugOffsetY = 0;\n }\n\n /**\n * Reset state to initial values.\n */\n reset(): void {\n this.active = false;\n this.wasActivatedBefore = false;\n this.x = 0;\n this.y = 0;\n this.sourceX = 0;\n this.sourceY = 0;\n this.sourceWidth = 0;\n this.sourceHeight = 0;\n this.canvasScale = 1.0;\n this.canvasOffsetX = 0;\n this.canvasOffsetY = 0;\n this.isRenderScheduled = false;\n }\n}\n"],"names":[],"mappings":";;;AAUO,MAAM,eAAe;AAAA,EAoDxB,cAAc;AAlDd;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AAAA;AACA;AAGI,SAAK,SAAS;AACd,SAAK,qBAAqB;AAC1B,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,oBAAoB;AACzB,SAAK,oBAAoB;AAEzB,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,oBAAoB;AACzB,SAAK,oBAAoB;AACzB,SAAK,sBAAsB;AAC3B,SAAK,sBAAsB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACV,SAAK,SAAS;AACd,SAAK,qBAAqB;AAC1B,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,oBAAoB;AAAA,EAC7B;AACJ;"}
|
||||
{"version":3,"file":"MagnifierState.js","sources":["../../src/magnify-glass/MagnifierState.ts"],"sourcesContent":["/**\n * ComfyUI MagnifyGlass - MagnifierState (TypeScript)\n * \n * Manages the state of the magnifying glass.\n */\n\n/**\n * Magnifier state class.\n * Tracks activation state, cursor position, and canvas transforms.\n */\nexport class MagnifierState {\n /** Whether the magnifier is currently active */\n active: boolean;\n\n /** Track if the glass has been activated before */\n wasActivatedBefore: boolean;\n\n /** Cursor X relative to litegraphCanvas */\n x: number;\n\n /** Cursor Y relative to litegraphCanvas */\n y: number;\n\n /** Calculated source area X */\n sourceX: number;\n\n /** Calculated source area Y */\n sourceY: number;\n\n /** Calculated source area width */\n sourceWidth: number;\n\n /** Calculated source area height */\n sourceHeight: number;\n\n /** Current canvas scale/zoom */\n canvasScale: number;\n\n /** Canvas translation X */\n canvasOffsetX: number;\n\n /** Canvas translation Y */\n canvasOffsetY: number;\n\n /** Flag to manage requestAnimationFrame */\n isRenderScheduled: boolean;\n\n /** Whether glass drag mode is enabled (move icon on hover controls) */\n isDragModeEnabled: boolean;\n\n /** Whether glass preview is hidden via hover controls (but tool still active) */\n isPreviewHidden: boolean;\n\n // --- Debug Metrics for Virtual Zoom ---\n virtualMouseCssX: number;\n virtualMouseCssY: number;\n virtualGraphX: number;\n virtualGraphY: number;\n virtualNewOffsetX: number;\n virtualNewOffsetY: number;\n\n // --- Manual Calibration ---\n virtualDebugOffsetX: number;\n virtualDebugOffsetY: number;\n\n constructor() {\n this.active = false;\n this.wasActivatedBefore = false;\n this.x = 0;\n this.y = 0;\n this.sourceX = 0;\n this.sourceY = 0;\n this.sourceWidth = 0;\n this.sourceHeight = 0;\n this.canvasScale = 1.0;\n this.canvasOffsetX = 0;\n this.canvasOffsetY = 0;\n this.isRenderScheduled = false;\n this.isDragModeEnabled = false;\n this.isPreviewHidden = false;\n\n this.virtualMouseCssX = 0;\n this.virtualMouseCssY = 0;\n this.virtualGraphX = 0;\n this.virtualGraphY = 0;\n this.virtualNewOffsetX = 0;\n this.virtualNewOffsetY = 0;\n this.virtualDebugOffsetX = 0;\n this.virtualDebugOffsetY = 0;\n }\n\n /**\n * Reset state to initial values.\n */\n reset(): void {\n this.active = false;\n this.wasActivatedBefore = false;\n this.x = 0;\n this.y = 0;\n this.sourceX = 0;\n this.sourceY = 0;\n this.sourceWidth = 0;\n this.sourceHeight = 0;\n this.canvasScale = 1.0;\n this.canvasOffsetX = 0;\n this.canvasOffsetY = 0;\n this.isRenderScheduled = false;\n }\n}\n"],"names":[],"mappings":";;;AAUO,MAAM,eAAe;AAAA,EAuDxB,cAAc;AArDd;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AAGA;AAAA;AACA;AACA;AACA;AACA;AACA;AAGA;AAAA;AACA;AAGI,SAAK,SAAS;AACd,SAAK,qBAAqB;AAC1B,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,oBAAoB;AACzB,SAAK,oBAAoB;AACzB,SAAK,kBAAkB;AAEvB,SAAK,mBAAmB;AACxB,SAAK,mBAAmB;AACxB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,oBAAoB;AACzB,SAAK,oBAAoB;AACzB,SAAK,sBAAsB;AAC3B,SAAK,sBAAsB;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,QAAc;AACV,SAAK,SAAS;AACd,SAAK,qBAAqB;AAC1B,SAAK,IAAI;AACT,SAAK,IAAI;AACT,SAAK,UAAU;AACf,SAAK,UAAU;AACf,SAAK,cAAc;AACnB,SAAK,eAAe;AACpB,SAAK,cAAc;AACnB,SAAK,gBAAgB;AACrB,SAAK,gBAAgB;AACrB,SAAK,oBAAoB;AAAA,EAC7B;AACJ;"}
|
||||
@@ -85,18 +85,95 @@ class MagnifyGlass {
|
||||
*/
|
||||
toggle() {
|
||||
const state = this.state;
|
||||
this.config;
|
||||
if (state.active) {
|
||||
state.active = false;
|
||||
this.ui.hide();
|
||||
this.forceHideInfoPanel();
|
||||
} else {
|
||||
state.active = true;
|
||||
this.removeForceHide();
|
||||
this.ui.show();
|
||||
if (this.eventHandler) {
|
||||
this.eventHandler.updateInitialPosition();
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Set glass preview visibility WITHOUT affecting info panel.
|
||||
* This is used by the toggle-glass hover control button.
|
||||
* When hidden, the renderer stops completely to save performance.
|
||||
* When shown, the renderer resumes.
|
||||
*
|
||||
* @param visible - true to show and enable rendering, false to hide and disable
|
||||
*/
|
||||
setGlassPreviewActive(visible) {
|
||||
this.state.isPreviewHidden = !visible;
|
||||
if (visible) {
|
||||
this.ui.setPreviewVisibility(true);
|
||||
} else {
|
||||
this.ui.setPreviewVisibility(false);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Force hide the info panel using CSS class with !important.
|
||||
* This bypasses all state management and inline style overrides.
|
||||
*/
|
||||
forceHideInfoPanel() {
|
||||
this.ensureForceHideCssRule();
|
||||
const infoPanel = document.querySelector(".magnify-info-panel");
|
||||
if (infoPanel) {
|
||||
infoPanel.classList.add("magnify-glass-force-hidden");
|
||||
}
|
||||
const floatingControls = document.querySelector(".floating-controls");
|
||||
if (floatingControls) {
|
||||
floatingControls.classList.add("magnify-glass-force-hidden");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Remove the force-hidden class when glass is showing.
|
||||
*/
|
||||
removeForceHide() {
|
||||
const infoPanel = document.querySelector(".magnify-info-panel");
|
||||
if (infoPanel) {
|
||||
infoPanel.classList.remove("magnify-glass-force-hidden");
|
||||
}
|
||||
const floatingControls = document.querySelector(".floating-controls");
|
||||
if (floatingControls) {
|
||||
floatingControls.classList.remove("magnify-glass-force-hidden");
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Ensure the CSS rule for force-hidden exists.
|
||||
*/
|
||||
ensureForceHideCssRule() {
|
||||
const styleId = "magnify-glass-force-hide-style";
|
||||
if (document.getElementById(styleId)) return;
|
||||
const style = document.createElement("style");
|
||||
style.id = styleId;
|
||||
style.textContent = `
|
||||
.magnify-glass-force-hidden {
|
||||
display: none !important;
|
||||
visibility: hidden !important;
|
||||
opacity: 0 !important;
|
||||
}
|
||||
`;
|
||||
document.head.appendChild(style);
|
||||
}
|
||||
/**
|
||||
* Check if the glass preview is visible.
|
||||
* Returns false if hidden via hover controls.
|
||||
*/
|
||||
isGlassPreviewVisible() {
|
||||
var _a;
|
||||
const extensions = window.comfyUIMagnifyGlassExtensions;
|
||||
if (extensions && extensions.length > 0) {
|
||||
const infoPanel = extensions[0];
|
||||
if ((_a = infoPanel == null ? void 0 : infoPanel.stateManager) == null ? void 0 : _a.state) {
|
||||
return infoPanel.stateManager.state.isGlassPreviewVisible !== false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
/**
|
||||
* Update the magnified view.
|
||||
*/
|
||||
@@ -104,6 +181,9 @@ class MagnifyGlass {
|
||||
if (!this.state.active || !this.renderer || !this.litegraphCanvas) {
|
||||
return;
|
||||
}
|
||||
if (this.state.isPreviewHidden) {
|
||||
return;
|
||||
}
|
||||
this.updateCanvasTransformation();
|
||||
this.calculateSourceRegion();
|
||||
if (!this.state.isRenderScheduled) {
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user