Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CC-122/126 Add option to hide/show code block #47

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
7222018
Add option to hide/show code block for image layer
aranega Nov 4, 2024
a783ebf
CC-122 Clean code for code-box visibility
aranega Nov 8, 2024
e3ebbdf
CC-154 Add code block visibility control for annotation layer
aranega Nov 8, 2024
77532fb
CC-156 Add code visibility control for single mesh layer
aranega Nov 8, 2024
87d9433
CC-157 Improve state handling for code box hidden
aranega Nov 8, 2024
ca34789
Merge pull request #48 from MetaCell/feature/CC-154
aranega Nov 13, 2024
9cd8698
Merge pull request #49 from MetaCell/feature/CC-156
aranega Nov 13, 2024
8e15490
Merge pull request #50 from MetaCell/feature/CC-157
aranega Nov 13, 2024
684807c
Hide shader properties in annotation when code is not displayed
aranega Nov 14, 2024
d5fe172
Change button icon and background when clicked
aranega Nov 21, 2024
635f9b9
Change icon from code to code-alt
aranega Nov 21, 2024
80d4256
Refactor layer code visibility feature
aranega Nov 26, 2024
5b46a3f
Fix tooltip swap for code visibility
aranega Dec 5, 2024
feeba32
refactor: remove unused commented code
seankmartin Dec 5, 2024
7ce500c
Add back event dispatch on name change for layers
aranega Dec 18, 2024
81d67af
Merge branch 'feature/CC-122' of github.com:MetaCell/neuroglancer int…
aranega Dec 18, 2024
2a57ea5
feat: save test on image user layer code visible
seankmartin Jan 22, 2025
0e618b8
fix: correct linking state and refactor code visibility
seankmartin Jan 23, 2025
b97d2e0
Merge branch 'master' of github.com:google/neuroglancer into feature/…
aranega Jan 23, 2025
0a81f6a
Move code visibility option to user layer for mesh and annotations
aranega Jan 23, 2025
6253e2f
refactor: remove old comments and use ElementVisibilityFromTrackableB…
seankmartin Jan 23, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 67 additions & 36 deletions src/layer/annotation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import "#src/layer/annotation/style.css";
import svgCode from "ikonate/icons/code-alt.svg?raw";

import type { AnnotationDisplayState } from "#src/annotation/annotation_layer_state.js";
import { AnnotationLayerState } from "#src/annotation/annotation_layer_state.js";
Expand Down Expand Up @@ -43,8 +44,11 @@ import { Overlay } from "#src/overlay.js";
import { getWatchableRenderLayerTransform } from "#src/render_coordinate_transform.js";
import { RenderLayerRole } from "#src/renderlayer.js";
import type { SegmentationDisplayState } from "#src/segmentation_display_state/frontend.js";
import type { TrackableBoolean } from "#src/trackable_boolean.js";
import { TrackableBooleanCheckbox } from "#src/trackable_boolean.js";
import {
TrackableBoolean,
TrackableBooleanCheckbox,
ElementVisibilityFromTrackableBoolean,
} from "#src/trackable_boolean.js";
import { makeCachedLazyDerivedWatchableValue } from "#src/trackable_value.js";
import type {
AnnotationLayerView,
Expand All @@ -67,6 +71,7 @@ import {
verifyStringArray,
} from "#src/util/json.js";
import { NullarySignal } from "#src/util/signal.js";
import { CheckboxIcon } from "#src/widget/checkbox_icon.js";
import { DependentViewWidget } from "#src/widget/dependent_view_widget.js";
import { makeHelpButton } from "#src/widget/help_button.js";
import { LayerReferenceWidget } from "#src/widget/layer_reference.js";
Expand Down Expand Up @@ -138,6 +143,7 @@ interface LinkedSegmentationLayer {
const LINKED_SEGMENTATION_LAYER_JSON_KEY = "linkedSegmentationLayer";
const FILTER_BY_SEGMENTATION_JSON_KEY = "filterBySegmentation";
const IGNORE_NULL_SEGMENT_FILTER_JSON_KEY = "ignoreNullSegmentFilter";
const CODE_VISIBLE_KEY = "codeVisible";

class LinkedSegmentationLayers extends RefCounted {
changed = new NullarySignal();
Expand Down Expand Up @@ -382,6 +388,7 @@ class LinkedSegmentationLayersWidget extends RefCounted {
const Base = UserLayerWithAnnotationsMixin(UserLayer);
export class AnnotationUserLayer extends Base {
localAnnotations: LocalAnnotationSource | undefined;
codeVisible = new TrackableBoolean(true);
private localAnnotationProperties: AnnotationPropertySpec[] | undefined;
private localAnnotationRelationships: string[];
private localAnnotationsJson: any = undefined;
Expand All @@ -407,6 +414,7 @@ export class AnnotationUserLayer extends Base {
this.linkedSegmentationLayers.changed.add(
this.specificationChanged.dispatch,
);
this.codeVisible.changed.add(this.specificationChanged.dispatch);
this.annotationDisplayState.ignoreNullSegmentFilter.changed.add(
this.specificationChanged.dispatch,
);
Expand All @@ -427,6 +435,7 @@ export class AnnotationUserLayer extends Base {
restoreState(specification: any) {
super.restoreState(specification);
this.linkedSegmentationLayers.restoreState(specification);
this.codeVisible.restoreState(specification[CODE_VISIBLE_KEY]);
this.localAnnotationsJson = specification[ANNOTATIONS_JSON_KEY];
this.localAnnotationProperties = verifyOptionalObjectProperty(
specification,
Expand Down Expand Up @@ -688,6 +697,7 @@ export class AnnotationUserLayer extends Base {
const x = super.toJSON();
x[CROSS_SECTION_RENDER_SCALE_JSON_KEY] =
this.annotationCrossSectionRenderScaleTarget.toJSON();
x[CODE_VISIBLE_KEY] = this.codeVisible.toJSON();
x[PROJECTION_RENDER_SCALE_JSON_KEY] =
this.annotationProjectionRenderScaleTarget.toJSON();
if (this.localAnnotations !== undefined) {
Expand Down Expand Up @@ -742,49 +752,70 @@ class RenderingOptionsTab extends Tab {
const { element } = this;
this.codeWidget = this.registerDisposer(makeShaderCodeWidget(this.layer));
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",
);
typeElement.textContent = property.type;
const nameElement = document.createElement("span");
nameElement.classList.add(
"neuroglancer-annotation-shader-property-identifier",
);
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);
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";
const label = document.createElement("div");
label.style.flex = "1";
label.textContent = "Annotation shader:";
topRow.appendChild(label);

this.registerDisposer(
new ElementVisibilityFromTrackableBoolean(
this.layer.codeVisible,
this.codeWidget.element,
),
);
this.registerDisposer(
new ElementVisibilityFromTrackableBoolean(
this.layer.codeVisible,
shaderProperties,
),
);
const codeVisibilityControl = new CheckboxIcon(this.layer.codeVisible, {
enableTitle: "Show code",
disableTitle: "Hide code",
backgroundScheme: "dark",
svg: svgCode,
});
topRow.appendChild(codeVisibilityControl.element);

topRow.appendChild(
makeMaximizeButton({
title: "Show larger editor view",
Expand Down
28 changes: 28 additions & 0 deletions src/layer/image/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import "#src/layer/image/style.css";
import svgCode from "ikonate/icons/code-alt.svg?raw";

import type { CoordinateSpace } from "#src/coordinate_transform.js";
import {
Expand Down Expand Up @@ -49,6 +50,10 @@ import {
} from "#src/sliceview/volume/image_renderlayer.js";
import { trackableAlphaValue } from "#src/trackable_alpha.js";
import { trackableBlendModeValue } from "#src/trackable_blend.js";
import {
TrackableBoolean,
ElementVisibilityFromTrackableBoolean,
} from "#src/trackable_boolean.js";
import { trackableFiniteFloat } from "#src/trackable_finite_float.js";
import type { WatchableValueInterface } from "#src/trackable_value.js";
import {
Expand Down Expand Up @@ -79,6 +84,7 @@ import {
ShaderControlState,
} from "#src/webgl/shader_ui_controls.js";
import { ChannelDimensionsWidget } from "#src/widget/channel_dimensions_widget.js";
import { CheckboxIcon } from "#src/widget/checkbox_icon.js";
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";
Expand All @@ -105,6 +111,7 @@ import { Tab } from "#src/widget/tab_view.js";
const OPACITY_JSON_KEY = "opacity";
const BLEND_JSON_KEY = "blend";
const SHADER_JSON_KEY = "shader";
const CODE_VISIBLE_KEY = "codeVisible";
const SHADER_CONTROLS_JSON_KEY = "shaderControls";
const CROSS_SECTION_RENDER_SCALE_JSON_KEY = "crossSectionRenderScale";
const CHANNEL_DIMENSIONS_JSON_KEY = "channelDimensions";
Expand All @@ -124,6 +131,7 @@ const [
export class ImageUserLayer extends Base {
opacity = trackableAlphaValue(0.5);
blendMode = trackableBlendModeValue();
codeVisible = new TrackableBoolean(true);
fragmentMain = getTrackableFragmentMain();
shaderError = makeWatchableShaderError();
dataType = new WatchableValue<DataType | undefined>(undefined);
Expand Down Expand Up @@ -204,6 +212,7 @@ export class ImageUserLayer extends Base {
isLocalDimension;
this.blendMode.changed.add(this.specificationChanged.dispatch);
this.opacity.changed.add(this.specificationChanged.dispatch);
this.codeVisible.changed.add(this.specificationChanged.dispatch);
this.volumeRenderingGain.changed.add(this.specificationChanged.dispatch);
this.fragmentMain.changed.add(this.specificationChanged.dispatch);
this.shaderControlState.changed.add(this.specificationChanged.dispatch);
Expand Down Expand Up @@ -293,6 +302,7 @@ export class ImageUserLayer extends Base {
restoreState(specification: any) {
super.restoreState(specification);
this.opacity.restoreState(specification[OPACITY_JSON_KEY]);
this.codeVisible.restoreState(specification[CODE_VISIBLE_KEY]);
verifyOptionalObjectProperty(specification, BLEND_JSON_KEY, (blendValue) =>
this.blendMode.restoreState(blendValue),
);
Expand Down Expand Up @@ -338,6 +348,7 @@ export class ImageUserLayer extends Base {
const x = super.toJSON();
x[OPACITY_JSON_KEY] = this.opacity.toJSON();
x[BLEND_JSON_KEY] = this.blendMode.toJSON();
x[CODE_VISIBLE_KEY] = this.codeVisible.toJSON();
x[SHADER_JSON_KEY] = this.fragmentMain.toJSON();
x[SHADER_CONTROLS_JSON_KEY] = this.shaderControlState.toJSON();
x[CROSS_SECTION_RENDER_SCALE_JSON_KEY] =
Expand Down Expand Up @@ -541,6 +552,22 @@ class RenderingOptionsTab extends Tab {
topRow.className = "neuroglancer-image-dropdown-top-row";
topRow.appendChild(document.createTextNode("Shader"));
topRow.appendChild(spacer);

this.registerDisposer(
new ElementVisibilityFromTrackableBoolean(
this.layer.codeVisible,
this.codeWidget.element,
),
);

const codeVisibilityControl = new CheckboxIcon(this.layer.codeVisible, {
enableTitle: "Show code",
disableTitle: "Hide code",
backgroundScheme: "dark",
svg: svgCode,
});
topRow.appendChild(codeVisibilityControl.element);

topRow.appendChild(
makeMaximizeButton({
title: "Show larger editor view",
Expand All @@ -562,6 +589,7 @@ class RenderingOptionsTab extends Tab {
new ChannelDimensionsWidget(layer.channelCoordinateSpaceCombiner),
).element,
);

element.appendChild(this.codeWidget.element);
element.appendChild(
this.registerDisposer(
Expand Down
27 changes: 27 additions & 0 deletions src/layer/single_mesh/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/

import "#src/layer/single_mesh/style.css";
import svgCode from "ikonate/icons/code-alt.svg?raw";

import type { ManagedUserLayer } from "#src/layer/index.js";
import {
Expand All @@ -31,11 +32,16 @@ import {
SingleMeshDisplayState,
SingleMeshLayer,
} from "#src/single_mesh/frontend.js";
import {
ElementVisibilityFromTrackableBoolean,
TrackableBoolean,
} from "#src/trackable_boolean.js";
import type { WatchableValueInterface } from "#src/trackable_value.js";
import { WatchableValue } from "#src/trackable_value.js";
import type { Borrowed } from "#src/util/disposable.js";
import { RefCounted } from "#src/util/disposable.js";
import { removeChildren, removeFromParent } from "#src/util/dom.js";
import { CheckboxIcon } from "#src/widget/checkbox_icon.js";
import { makeHelpButton } from "#src/widget/help_button.js";
import { makeMaximizeButton } from "#src/widget/maximize_button.js";
import { ShaderCodeWidget } from "#src/widget/shader_code_widget.js";
Expand All @@ -47,14 +53,18 @@ import { Tab } from "#src/widget/tab_view.js";

const SHADER_JSON_KEY = "shader";
const SHADER_CONTROLS_JSON_KEY = "shaderControls";
const CODE_VISIBLE_KEY = "codeVisible";

export class SingleMeshUserLayer extends UserLayer {
displayState = new SingleMeshDisplayState();
codeVisible = new TrackableBoolean(true);

vertexAttributes = new WatchableValue<VertexAttributeInfo[] | undefined>(
undefined,
);
constructor(public managedLayer: Borrowed<ManagedUserLayer>) {
super(managedLayer);
this.codeVisible.changed.add(this.specificationChanged.dispatch);
this.registerDisposer(
this.displayState.shaderControlState.changed.add(
this.specificationChanged.dispatch,
Expand All @@ -75,6 +85,7 @@ export class SingleMeshUserLayer extends UserLayer {

restoreState(specification: any) {
super.restoreState(specification);
this.codeVisible.restoreState(specification[CODE_VISIBLE_KEY]);
this.displayState.fragmentMain.restoreState(specification[SHADER_JSON_KEY]);
this.displayState.shaderControlState.restoreState(
specification[SHADER_CONTROLS_JSON_KEY],
Expand Down Expand Up @@ -116,6 +127,7 @@ export class SingleMeshUserLayer extends UserLayer {
const x = super.toJSON();
x[SHADER_JSON_KEY] = this.displayState.fragmentMain.toJSON();
x[SHADER_CONTROLS_JSON_KEY] = this.displayState.shaderControlState.toJSON();
x[CODE_VISIBLE_KEY] = this.codeVisible.toJSON();
return x;
}

Expand Down Expand Up @@ -210,6 +222,21 @@ class DisplayOptionsTab extends Tab {
spacer.style.flex = "1";

topRow.appendChild(spacer);

this.registerDisposer(
new ElementVisibilityFromTrackableBoolean(
this.layer.codeVisible,
this.codeWidget.element,
),
);
const codeVisibilityControl = new CheckboxIcon(this.layer.codeVisible, {
enableTitle: "Show code",
disableTitle: "Hide code",
backgroundScheme: "dark",
svg: svgCode,
});
topRow.appendChild(codeVisibilityControl.element);

topRow.appendChild(
makeMaximizeButton({
title: "Show larger editor view",
Expand Down
Loading