diff --git a/src/index.ts b/src/index.ts index 013accf..872f4a1 100644 --- a/src/index.ts +++ b/src/index.ts @@ -63,12 +63,31 @@ const extension: JupyterFrontEndPlugin = { languageRegistry: IEditorLanguageRegistry ) => { console.log('JupyterLab extension URDF is activated!'); - const { commands } = app; + const { commands, shell } = app; // Tracker const namespace = 'jupyterlab-urdf'; const tracker = new WidgetTracker({ namespace }); + // Track and persist split panel state + const splitDoneKey = 'jupyterlab-urdf:splitDone'; + const leftEditorRefKey = 'jupyterlab-urdf:leftEditorRefId'; + const rightViewerRefKey = 'jupyterlab-urdf:rightViewerRefId'; + let splitDone = localStorage.getItem(splitDoneKey) === 'true'; + let leftEditorRefId: string | null = localStorage.getItem(leftEditorRefKey); + let rightViewerRefId: string | null = + localStorage.getItem(rightViewerRefKey); + + // Reset our “splitDone” flags & remove saved refs + function resetSplitState() { + splitDone = false; + localStorage.setItem(splitDoneKey, 'false'); + leftEditorRefId = null; + rightViewerRefId = null; + localStorage.removeItem(leftEditorRefKey); + localStorage.removeItem(rightViewerRefKey); + } + // State restoration: reopen document if it was open previously if (restorer) { restorer.restore(tracker, { @@ -89,7 +108,7 @@ const extension: JupyterFrontEndPlugin = { }); // Add widget to tracker when created - widgetFactory.widgetCreated.connect((sender, widget) => { + widgetFactory.widgetCreated.connect(async (sender, widget) => { widget.title.icon = urdf_icon; widget.title.iconClass = 'jp-URDFIcon'; @@ -98,6 +117,53 @@ const extension: JupyterFrontEndPlugin = { tracker.save(widget); }); tracker.add(widget); + + // Reset split state when all widgets are closed + widget.disposed.connect(() => { + if (tracker.size === 0) { + resetSplitState(); + } + }); + + // Detect stale editor-ref + if (splitDone && leftEditorRefId) { + // look through all widgets in the main area + const allMain = [...shell.widgets('main')]; + const stillHasEditor = allMain.some(w => w.id === leftEditorRefId); + if (!stillHasEditor) { + // the editor tab was closed ⇒ reset split state + resetSplitState(); + } + } + + // Split layout on first open, then tab into panels + if (!splitDone) { + const editor = await commands.execute('docmanager:open', { + path: widget.context.path, + factory: 'Editor', + options: { mode: 'split-left', ref: widget.id } + }); + splitDone = true; + localStorage.setItem(splitDoneKey, 'true'); + leftEditorRefId = editor.id; + rightViewerRefId = widget.id; + localStorage.setItem(leftEditorRefKey, leftEditorRefId as string); + localStorage.setItem(rightViewerRefKey, rightViewerRefId as string); + } else { + if (rightViewerRefId) { + shell.add(widget, 'main', { + mode: 'tab-after', + ref: rightViewerRefId + }); + } + if (leftEditorRefId) { + await commands.execute('docmanager:open', { + path: widget.context.path, + factory: 'Editor', + options: { mode: 'tab-after', ref: leftEditorRefId } + }); + } + } }); // Register widget and model factories diff --git a/style/base.css b/style/base.css index 78527b6..6626fd3 100644 --- a/style/base.css +++ b/style/base.css @@ -128,3 +128,9 @@ max-height: 50vh; overflow: scroll; } + +/* Expand hover area to reach color pickers */ +.urdf-gui .cr.color .c:hover { + padding: 15px 0; + margin: -15px 0; +}