From 72220186e34878ac8ac8097627a8592120a98172 Mon Sep 17 00:00:00 2001 From: aranega Date: Mon, 4 Nov 2024 09:26:45 -0600 Subject: [PATCH 1/6] Add option to hide/show code block for image layer --- src/layer/image/index.ts | 37 +++++++++++++++++++++++++++++++++++++ src/layer/index.ts | 14 ++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/layer/image/index.ts b/src/layer/image/index.ts index 256050060..1bc7f048e 100644 --- a/src/layer/image/index.ts +++ b/src/layer/image/index.ts @@ -15,6 +15,8 @@ */ import "#src/layer/image/style.css"; +import svgClosedEye from "ikonate/icons/eye-closed.svg?raw"; +import svgOpenedEye from "ikonate/icons/eye.svg?raw"; import type { CoordinateSpace } from "#src/coordinate_transform.js"; import { @@ -82,6 +84,7 @@ import { ChannelDimensionsWidget } from "#src/widget/channel_dimensions_widget.j import { makeCopyButton } from "#src/widget/copy_button.js"; import type { DependentViewContext } from "#src/widget/dependent_view_widget.js"; import { makeHelpButton } from "#src/widget/help_button.js"; +import { makeIcon } from "#src/widget/icon.js"; import type { LayerControlDefinition } from "#src/widget/layer_control.js"; import { addLayerControlToOptionsTab, @@ -540,6 +543,38 @@ class RenderingOptionsTab extends Tab { topRow.className = "neuroglancer-image-dropdown-top-row"; topRow.appendChild(document.createTextNode("Shader")); topRow.appendChild(spacer); + + const managedLayer = this.layer.managedLayer; + const codeVisibilityControl = makeIcon({ + title: managedLayer.codeVisible ? "Hide code": "Show code", + svg: managedLayer.codeVisible ? svgOpenedEye : svgClosedEye, + onClick: () => { + const button = codeVisibilityControl as HTMLDivElement; + managedLayer.setCodeVisible(!managedLayer.codeVisible) + if (managedLayer.codeVisible) { + button.title = "Hide code"; + button.innerHTML = svgOpenedEye + this.codeWidget.element.style.display = "block"; + } else { + button.title = "Show code"; + button.innerHTML = svgClosedEye + this.codeWidget.element.style.display = "none"; + } + }}); + // managedLayer.layerChanged.add(() => { + // const button = codeVisibilityControl as HTMLDivElement; + // if (managedLayer.codeVisible) { + // button.title = "Hide code"; + // button.innerHTML = svgOpenedEye + // this.codeWidget.element.style.display = "block"; + // } else { + // button.title = "Show code"; + // button.innerHTML = svgClosedEye + // this.codeWidget.element.style.display = "none"; + // } + // }); + + topRow.appendChild(codeVisibilityControl); topRow.appendChild( makeMaximizeButton({ title: "Show larger editor view", @@ -561,6 +596,8 @@ class RenderingOptionsTab extends Tab { new ChannelDimensionsWidget(layer.channelCoordinateSpaceCombiner), ).element, ); + + this.codeWidget.element.style.display = managedLayer.codeVisible ? "block" : "none"; element.appendChild(this.codeWidget.element); element.appendChild( this.registerDisposer( diff --git a/src/layer/index.ts b/src/layer/index.ts index ff3f7d8d2..0624af296 100644 --- a/src/layer/index.ts +++ b/src/layer/index.ts @@ -710,6 +710,7 @@ export class ManagedUserLayer extends RefCounted { } visible = true; + codeVisible = true; archived = false; get supportsPickOption() { @@ -764,6 +765,7 @@ export class ManagedUserLayer extends RefCounted { } const layerSpec = userLayer.toJSON(); layerSpec.name = this.name; + layerSpec.codeVisible = this.codeVisible; if (!this.visible) { if (this.archived) { layerSpec.archived = true; @@ -774,6 +776,12 @@ export class ManagedUserLayer extends RefCounted { return layerSpec; } + setCodeVisible(value: boolean) { + if (value === this.codeVisible) return; + this.codeVisible = value; + this.layerChanged.dispatch(); + } + setVisible(value: boolean) { if (value === this.visible) return; if (value && this.archived) { @@ -2018,6 +2026,12 @@ function initializeLayerFromSpecNoRestoreState( } else { managedLayer.visible = false; } + managedLayer.codeVisible = verifyOptionalObjectProperty( + spec, + "codeVisible", + verifyBoolean, + true, + ) const layerConstructor = layerTypes.get(layerType) || NewUserLayer; managedLayer.layer = new layerConstructor(managedLayer); return spec; From a783ebfdb00ff86020ca2ef747789374c5731023 Mon Sep 17 00:00:00 2001 From: aranega Date: Fri, 8 Nov 2024 05:29:31 -0600 Subject: [PATCH 2/6] CC-122 Clean code for code-box visibility --- src/layer/image/index.ts | 23 ++++++----------------- src/widget/shader_code_widget.ts | 8 ++++++++ 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/layer/image/index.ts b/src/layer/image/index.ts index 1bc7f048e..61dae218c 100644 --- a/src/layer/image/index.ts +++ b/src/layer/image/index.ts @@ -545,34 +545,24 @@ class RenderingOptionsTab extends Tab { topRow.appendChild(spacer); const managedLayer = this.layer.managedLayer; + const codeVisible = managedLayer.codeVisible; + this.codeWidget.element.style.display = managedLayer.codeVisible ? "block" : "none"; + this.codeWidget.setVisible(codeVisible); const codeVisibilityControl = makeIcon({ - title: managedLayer.codeVisible ? "Hide code": "Show code", - svg: managedLayer.codeVisible ? svgOpenedEye : svgClosedEye, + title: codeVisible ? "Hide code": "Show code", + svg: codeVisible ? svgOpenedEye : svgClosedEye, onClick: () => { const button = codeVisibilityControl as HTMLDivElement; managedLayer.setCodeVisible(!managedLayer.codeVisible) if (managedLayer.codeVisible) { button.title = "Hide code"; button.innerHTML = svgOpenedEye - this.codeWidget.element.style.display = "block"; } else { button.title = "Show code"; button.innerHTML = svgClosedEye - this.codeWidget.element.style.display = "none"; } + this.codeWidget.setVisible(managedLayer.codeVisible); }}); - // managedLayer.layerChanged.add(() => { - // const button = codeVisibilityControl as HTMLDivElement; - // if (managedLayer.codeVisible) { - // button.title = "Hide code"; - // button.innerHTML = svgOpenedEye - // this.codeWidget.element.style.display = "block"; - // } else { - // button.title = "Show code"; - // button.innerHTML = svgClosedEye - // this.codeWidget.element.style.display = "none"; - // } - // }); topRow.appendChild(codeVisibilityControl); topRow.appendChild( @@ -597,7 +587,6 @@ class RenderingOptionsTab extends Tab { ).element, ); - this.codeWidget.element.style.display = managedLayer.codeVisible ? "block" : "none"; element.appendChild(this.codeWidget.element); element.appendChild( this.registerDisposer( diff --git a/src/widget/shader_code_widget.ts b/src/widget/shader_code_widget.ts index c86fae81c..e6e3d0401 100644 --- a/src/widget/shader_code_widget.ts +++ b/src/widget/shader_code_widget.ts @@ -189,4 +189,12 @@ export class ShaderCodeWidget extends RefCounted { this.textEditor = undefined; super.disposed(); } + + setVisible(visible: boolean) { + this.element.style.display = visible ? "block" : "none"; + } + + isVisible() { + return this.element.style.display === "block"; + } } From e3ebbdf0b8e4e7bae3cd8037e1ec22a49ed57f72 Mon Sep 17 00:00:00 2001 From: aranega Date: Fri, 8 Nov 2024 05:44:38 -0600 Subject: [PATCH 3/6] CC-154 Add code block visibility control for annotation layer --- src/layer/annotation/index.ts | 25 +++++++++++++++++++++++++ src/layer/image/index.ts | 2 +- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/layer/annotation/index.ts b/src/layer/annotation/index.ts index 35c1a4e43..76d4375e5 100644 --- a/src/layer/annotation/index.ts +++ b/src/layer/annotation/index.ts @@ -15,6 +15,8 @@ */ import "#src/layer/annotation/style.css"; +import svgClosedEye from "ikonate/icons/eye-closed.svg?raw"; +import svgOpenedEye from "ikonate/icons/eye.svg?raw"; import type { AnnotationDisplayState } from "#src/annotation/annotation_layer_state.js"; import { AnnotationLayerState } from "#src/annotation/annotation_layer_state.js"; @@ -69,6 +71,7 @@ import { import { NullarySignal } from "#src/util/signal.js"; import { DependentViewWidget } from "#src/widget/dependent_view_widget.js"; import { makeHelpButton } from "#src/widget/help_button.js"; +import { makeIcon } from "#src/widget/icon.js"; import { LayerReferenceWidget } from "#src/widget/layer_reference.js"; import { makeMaximizeButton } from "#src/widget/maximize_button.js"; import { RenderScaleWidget } from "#src/widget/render_scale_widget.js"; @@ -783,6 +786,28 @@ class RenderingOptionsTab extends Tab { label.style.flex = "1"; label.textContent = "Annotation shader:"; topRow.appendChild(label); + + const managedLayer = this.layer.managedLayer; + const codeVisible = managedLayer.codeVisible; + this.codeWidget.element.style.display = managedLayer.codeVisible ? "block" : "none"; + this.codeWidget.setVisible(codeVisible); + const codeVisibilityControl = makeIcon({ + title: codeVisible ? "Hide code": "Show code", + svg: codeVisible ? svgOpenedEye : svgClosedEye, + onClick: () => { + const button = codeVisibilityControl as HTMLDivElement; + managedLayer.setCodeVisible(!managedLayer.codeVisible) + if (managedLayer.codeVisible) { + button.title = "Hide code"; + button.innerHTML = svgOpenedEye + } else { + button.title = "Show code"; + button.innerHTML = svgClosedEye + } + this.codeWidget.setVisible(managedLayer.codeVisible); + }}); + topRow.appendChild(codeVisibilityControl); + topRow.appendChild( makeMaximizeButton({ title: "Show larger editor view", diff --git a/src/layer/image/index.ts b/src/layer/image/index.ts index 61dae218c..5a338a10b 100644 --- a/src/layer/image/index.ts +++ b/src/layer/image/index.ts @@ -563,8 +563,8 @@ class RenderingOptionsTab extends Tab { } this.codeWidget.setVisible(managedLayer.codeVisible); }}); - topRow.appendChild(codeVisibilityControl); + topRow.appendChild( makeMaximizeButton({ title: "Show larger editor view", From 77532fbbdbf07b71e0f0a7c8fae4c998a8b77f95 Mon Sep 17 00:00:00 2001 From: aranega Date: Fri, 8 Nov 2024 06:00:21 -0600 Subject: [PATCH 4/6] CC-156 Add code visibility control for single mesh layer --- src/layer/single_mesh/index.ts | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/src/layer/single_mesh/index.ts b/src/layer/single_mesh/index.ts index 6e2b68694..a8cc1c956 100644 --- a/src/layer/single_mesh/index.ts +++ b/src/layer/single_mesh/index.ts @@ -15,6 +15,8 @@ */ import "#src/layer/single_mesh/style.css"; +import svgClosedEye from "ikonate/icons/eye-closed.svg?raw"; +import svgOpenedEye from "ikonate/icons/eye.svg?raw"; import type { ManagedUserLayer } from "#src/layer/index.js"; import { @@ -37,6 +39,7 @@ import type { Borrowed } from "#src/util/disposable.js"; import { RefCounted } from "#src/util/disposable.js"; import { removeChildren, removeFromParent } from "#src/util/dom.js"; import { makeHelpButton } from "#src/widget/help_button.js"; +import { makeIcon } from "#src/widget/icon.js"; import { makeMaximizeButton } from "#src/widget/maximize_button.js"; import { ShaderCodeWidget } from "#src/widget/shader_code_widget.js"; import { @@ -207,6 +210,28 @@ class DisplayOptionsTab extends Tab { spacer.style.flex = "1"; topRow.appendChild(spacer); + + const managedLayer = this.layer.managedLayer; + const codeVisible = managedLayer.codeVisible; + this.codeWidget.element.style.display = managedLayer.codeVisible ? "block" : "none"; + this.codeWidget.setVisible(codeVisible); + const codeVisibilityControl = makeIcon({ + title: codeVisible ? "Hide code": "Show code", + svg: codeVisible ? svgOpenedEye : svgClosedEye, + onClick: () => { + const button = codeVisibilityControl as HTMLDivElement; + managedLayer.setCodeVisible(!managedLayer.codeVisible) + if (managedLayer.codeVisible) { + button.title = "Hide code"; + button.innerHTML = svgOpenedEye + } else { + button.title = "Show code"; + button.innerHTML = svgClosedEye + } + this.codeWidget.setVisible(managedLayer.codeVisible); + }}); + topRow.appendChild(codeVisibilityControl); + topRow.appendChild( makeMaximizeButton({ title: "Show larger editor view", From 87d9433202cf4e5950a41416723536f2871b6a70 Mon Sep 17 00:00:00 2001 From: aranega Date: Fri, 8 Nov 2024 06:10:47 -0600 Subject: [PATCH 5/6] CC-157 Improve state handling for code box hidden --- src/layer/index.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/layer/index.ts b/src/layer/index.ts index 0624af296..fb894cd0f 100644 --- a/src/layer/index.ts +++ b/src/layer/index.ts @@ -765,7 +765,9 @@ export class ManagedUserLayer extends RefCounted { } const layerSpec = userLayer.toJSON(); layerSpec.name = this.name; - layerSpec.codeVisible = this.codeVisible; + if (!this.codeVisible) { + layerSpec.codeVisible = false; + } if (!this.visible) { if (this.archived) { layerSpec.archived = true; From 684807c427d9b7071d9161b04cff235eb4bd6315 Mon Sep 17 00:00:00 2001 From: aranega Date: Thu, 14 Nov 2024 07:14:19 -0600 Subject: [PATCH 6/6] Hide shader properties in annotation when code is not displayed --- src/layer/annotation/index.ts | 77 ++++++++++++++++++----------------- src/layer/image/index.ts | 1 - 2 files changed, 40 insertions(+), 38 deletions(-) diff --git a/src/layer/annotation/index.ts b/src/layer/annotation/index.ts index 76d4375e5..d0ecf4c43 100644 --- a/src/layer/annotation/index.ts +++ b/src/layer/annotation/index.ts @@ -743,42 +743,42 @@ class RenderingOptionsTab extends Tab { super(); const { element } = this; element.classList.add("neuroglancer-annotation-rendering-tab"); - element.appendChild( - this.registerDisposer( - new DependentViewWidget( - layer.annotationDisplayState.annotationProperties, - (properties, parent) => { - if (properties === undefined || properties.length === 0) return; - const propertyList = document.createElement("div"); - parent.appendChild(propertyList); - propertyList.classList.add( - "neuroglancer-annotation-shader-property-list", + const shaderProperties = this.registerDisposer( + new DependentViewWidget( + layer.annotationDisplayState.annotationProperties, + (properties, parent) => { + if (properties === undefined || properties.length === 0) return; + const propertyList = document.createElement("div"); + parent.appendChild(propertyList); + propertyList.classList.add( + "neuroglancer-annotation-shader-property-list", + ); + for (const property of properties) { + const div = document.createElement("div"); + div.classList.add("neuroglancer-annotation-shader-property"); + const typeElement = document.createElement("span"); + typeElement.classList.add( + "neuroglancer-annotation-shader-property-type", ); - for (const property of properties) { - const div = document.createElement("div"); - div.classList.add("neuroglancer-annotation-shader-property"); - const typeElement = document.createElement("span"); - typeElement.classList.add( - "neuroglancer-annotation-shader-property-type", - ); - typeElement.textContent = property.type; - const nameElement = document.createElement("span"); - nameElement.classList.add( - "neuroglancer-annotation-shader-property-identifier", - ); - nameElement.textContent = `prop_${property.identifier}`; - div.appendChild(typeElement); - div.appendChild(nameElement); - const { description } = property; - if (description !== undefined) { - div.title = description; - } - propertyList.appendChild(div); + typeElement.textContent = property.type; + const nameElement = document.createElement("span"); + nameElement.classList.add( + "neuroglancer-annotation-shader-property-identifier", + ); + nameElement.textContent = `prop_${property.identifier}`; + div.appendChild(typeElement); + div.appendChild(nameElement); + const { description } = property; + if (description !== undefined) { + div.title = description; } - }, - ), - ).element, - ); + propertyList.appendChild(div); + } + }, + ), + ).element; + + element.appendChild(shaderProperties); const topRow = document.createElement("div"); topRow.className = "neuroglancer-segmentation-dropdown-skeleton-shader-header"; @@ -788,9 +788,10 @@ class RenderingOptionsTab extends Tab { topRow.appendChild(label); const managedLayer = this.layer.managedLayer; + shaderProperties.style.display = managedLayer.codeVisible ? "block" : "none"; const codeVisible = managedLayer.codeVisible; - this.codeWidget.element.style.display = managedLayer.codeVisible ? "block" : "none"; this.codeWidget.setVisible(codeVisible); + const codeVisibilityControl = makeIcon({ title: codeVisible ? "Hide code": "Show code", svg: codeVisible ? svgOpenedEye : svgClosedEye, @@ -799,10 +800,12 @@ class RenderingOptionsTab extends Tab { managedLayer.setCodeVisible(!managedLayer.codeVisible) if (managedLayer.codeVisible) { button.title = "Hide code"; - button.innerHTML = svgOpenedEye + button.innerHTML = svgOpenedEye; + shaderProperties.style.display = "block"; } else { button.title = "Show code"; - button.innerHTML = svgClosedEye + button.innerHTML = svgClosedEye; + shaderProperties.style.display = "none"; } this.codeWidget.setVisible(managedLayer.codeVisible); }}); diff --git a/src/layer/image/index.ts b/src/layer/image/index.ts index 5a338a10b..72c9b32d6 100644 --- a/src/layer/image/index.ts +++ b/src/layer/image/index.ts @@ -546,7 +546,6 @@ class RenderingOptionsTab extends Tab { const managedLayer = this.layer.managedLayer; const codeVisible = managedLayer.codeVisible; - this.codeWidget.element.style.display = managedLayer.codeVisible ? "block" : "none"; this.codeWidget.setVisible(codeVisible); const codeVisibilityControl = makeIcon({ title: codeVisible ? "Hide code": "Show code",