From 416e4fa987d2f9bcfd315cc33049f1a2b97eccfb Mon Sep 17 00:00:00 2001 From: JK Date: Sun, 14 Jun 2026 00:41:24 +0200 Subject: [PATCH] feat(tikz): enhance canvas coordinate handling and modal overlay management --- .../tikz-editor/components/canvas-grid.ts | 11 +++++----- src/features/tikz-editor/tikz-editor-modal.ts | 15 ++++++++++++-- src/features/tikz/live-preview-overlay.ts | 20 ++++++++++++++++++- src/main.ts | 20 +++---------------- 4 files changed, 41 insertions(+), 25 deletions(-) diff --git a/src/features/tikz-editor/components/canvas-grid.ts b/src/features/tikz-editor/components/canvas-grid.ts index 21c081e..a9fcb54 100644 --- a/src/features/tikz-editor/components/canvas-grid.ts +++ b/src/features/tikz-editor/components/canvas-grid.ts @@ -447,13 +447,13 @@ export class CanvasGrid { }); } - private getCanvasCoords(e: MouseEvent): { x: number; y: number } { + private getCanvasCoords(e: MouseEvent, snap = true): { x: number; y: number } { const rect = this.workspaceEl.getBoundingClientRect(); const zoom = this.context.getZoom(); const rawX = (e.clientX - rect.left) / zoom; const rawY = (e.clientY - rect.top) / zoom; - if (this.context.isSnapToGrid() && !e.ctrlKey) { + if (snap && this.context.isSnapToGrid() && !e.ctrlKey) { const gridSize = this.context.isHalfGrid() ? this.context.PX_PER_UNIT / 2 : this.context.PX_PER_UNIT; @@ -608,11 +608,12 @@ export class CanvasGrid { this.context.handleSelectVertices([]); } - this.lassoStart = coords; - this.lassoCurrent = coords; + const nonSnappedCoords = this.getCanvasCoords(e, false); + this.lassoStart = nonSnappedCoords; + this.lassoCurrent = nonSnappedCoords; const onMouseMove = (moveEvent: MouseEvent) => { - const mCoords = this.getCanvasCoords(moveEvent); + const mCoords = this.getCanvasCoords(moveEvent, false); this.lassoCurrent = mCoords; this.renderWires(); }; diff --git a/src/features/tikz-editor/tikz-editor-modal.ts b/src/features/tikz-editor/tikz-editor-modal.ts index b2c9473..e55e165 100644 --- a/src/features/tikz-editor/tikz-editor-modal.ts +++ b/src/features/tikz-editor/tikz-editor-modal.ts @@ -338,7 +338,7 @@ export class TikzEditorModal extends Modal implements TikzEditorContext { const offset = this.PX_PER_UNIT / 2; // Offset by half grid (40px) const copies = elementsToDuplicate.map(el => { - const copy: EditorElement = JSON.parse(JSON.stringify(el)); + const copy = JSON.parse(JSON.stringify(el)) as EditorElement; copy.id = this.createId(); copy.x += offset; copy.y += offset; @@ -535,7 +535,7 @@ export class TikzEditorModal extends Modal implements TikzEditorContext { const uniqueIds = Array.from(new Set(this.selectedVertices.map(v => v.elementId))); const selectedElements = this.elements.filter(el => uniqueIds.includes(el.id)); if (selectedElements.length > 0) { - this.copiedElements = JSON.parse(JSON.stringify(selectedElements)); + this.copiedElements = JSON.parse(JSON.stringify(selectedElements)) as EditorElement[]; showNotice(`Copied ${selectedElements.length} component(s)`); } return; @@ -612,6 +612,17 @@ export class TikzEditorModal extends Modal implements TikzEditorContext { // Modal Lifecycles onOpen() { + this.plugin.isTikzEditorOpen = true; + this.plugin.updateEditorExtensions(); + + const removeOverlays = (doc: Document) => { + doc.querySelectorAll('.tikz-live-preview-overlay').forEach(el => el.remove()); + }; + removeOverlays(activeDocument); + if (this.app.workspace.containerEl && this.app.workspace.containerEl.ownerDocument) { + removeOverlays(this.app.workspace.containerEl.ownerDocument); + } + const { contentEl, containerEl } = this; contentEl.empty(); diff --git a/src/features/tikz/live-preview-overlay.ts b/src/features/tikz/live-preview-overlay.ts index 9a79141..2ea288f 100644 --- a/src/features/tikz/live-preview-overlay.ts +++ b/src/features/tikz/live-preview-overlay.ts @@ -53,6 +53,17 @@ class TikzLivePreviewOverlay { if (this.overlayEl) return; const doc = this.view.dom.ownerDocument; + const isModalOpen = + this.plugin.isTikzEditorOpen || + !!doc.querySelector('.tikz-editor-modal') || + !!activeDocument.querySelector('.tikz-editor-modal') || + !!this.plugin.app.workspace.containerEl.ownerDocument?.querySelector('.tikz-editor-modal'); + + if (isModalOpen) { + this.destroy(); + return; + } + const body = doc.body; this.overlayEl = doc.createElement('div'); @@ -412,7 +423,14 @@ export const createTikzLivePreviewPlugin = (plugin: LatexReferencer): Extension constructor(private view: EditorView) {} update(update: ViewUpdate) { - if (!plugin.settings.enableTikzjax || plugin.isTikzEditorOpen) { + const doc = update.view.dom.ownerDocument; + const isModalOpen = + plugin.isTikzEditorOpen || + !!doc.querySelector('.tikz-editor-modal') || + !!activeDocument.querySelector('.tikz-editor-modal') || + !!plugin.app.workspace.containerEl.ownerDocument?.querySelector('.tikz-editor-modal'); + + if (!plugin.settings.enableTikzjax || isModalOpen) { this.cleanup(); return; } diff --git a/src/main.ts b/src/main.ts index 8952af3..4d5f0a2 100644 --- a/src/main.ts +++ b/src/main.ts @@ -316,14 +316,7 @@ export default class LatexReferencer extends Plugin { typeof activeView?.getViewData === 'function' ? activeView.getViewData() : null; if (!activeFile || targetFile.path !== activeFile.path || activeContent === null) { - return oldFunc.call( - this, - hoverParent, - targetEl, - linktext, - sourcePath, - state - ) as unknown; + return oldFunc.call(this, hoverParent, targetEl, linktext, sourcePath, state); } const equations = getEquations(activeFile, activeContent); @@ -333,21 +326,14 @@ export default class LatexReferencer extends Plugin { const line = targetEquation.$position.start; const newState = { ...state, scroll: line }; // Immediately call the original function with the correct line number - return oldFunc.call( - this, - hoverParent, - targetEl, - linktext, - sourcePath, - newState - ) as unknown; + return oldFunc.call(this, hoverParent, targetEl, linktext, sourcePath, newState); } } } // If it's not our link, or if we couldn't find it in the cache, // call the original function without modification. - return oldFunc.call(this, hoverParent, targetEl, linktext, sourcePath, state) as unknown; + return oldFunc.call(this, hoverParent, targetEl, linktext, sourcePath, state); }; } });