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

Add option to hide/show code block #688

Open
wants to merge 25 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 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
f98ce99
Merge branch 'master' of github.com:MetaCell/neuroglancer into featur…
aranega Feb 27, 2025
035ef48
CC-122 Extract top row as a function and add shadder top row for
aranega Feb 27, 2025
c66cda5
Merge branch 'master' of github.com:MetaCell/neuroglancer into featur…
aranega Mar 12, 2025
fa8d978
CC-122 Introduce generic function to build the top row of
aranega Mar 12, 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
116 changes: 56 additions & 60 deletions src/layer/annotation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,10 @@ 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,
} from "#src/trackable_boolean.js";
import { makeCachedLazyDerivedWatchableValue } from "#src/trackable_value.js";
import type {
AnnotationLayerView,
Expand All @@ -68,17 +70,18 @@ import {
} from "#src/util/json.js";
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 {
addLayerControlToOptionsTab,
type LayerControlDefinition,
registerLayerControl,
} from "#src/widget/layer_control.js";
import { colorLayerControl } from "#src/widget/layer_control_color.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";
import { ShaderCodeWidget } from "#src/widget/shader_code_widget.js";
import {
makeShaderCodeWidgetTopRow,
ShaderCodeWidget,
} from "#src/widget/shader_code_widget.js";
import {
registerLayerShaderControlsTool,
ShaderControls,
Expand Down Expand Up @@ -145,6 +148,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 @@ -389,6 +393,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 Down Expand Up @@ -416,6 +421,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 @@ -436,6 +442,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 @@ -697,6 +704,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 @@ -751,66 +759,54 @@ 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;

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);
topRow.appendChild(
makeMaximizeButton({
title: "Show larger editor view",
onClick: () => {
new ShaderCodeOverlay(this.layer);
element.appendChild(shaderProperties);
element.appendChild(
makeShaderCodeWidgetTopRow(
this.layer,
this.codeWidget,
ShaderCodeOverlay,
{
title: "Documentation on image layer rendering",
href: "https://github.com/google/neuroglancer/blob/master/src/annotation/rendering.md",
},
}),
);
topRow.appendChild(
makeHelpButton({
title: "Documentation on annotation rendering",
href: "https://github.com/google/neuroglancer/blob/master/src/annotation/rendering.md",
}),
"neuroglancer-annotation-dropdown-shader-top-row",
),
);
element.appendChild(topRow);

element.appendChild(this.codeWidget.element);
element.appendChild(
Expand Down
6 changes: 6 additions & 0 deletions src/layer/annotation/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@
flex-shrink: 0;
}

.neuroglancer-annotation-dropdown-shader-top-row {
display: flex;
flex-direction: row;
align-items: center;
}

.neuroglancer-annotation-shader-property-list {
max-height: 8em;
overflow: auto;
Expand Down
45 changes: 21 additions & 24 deletions src/layer/image/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import {
} from "#src/sliceview/volume/image_renderlayer.js";
import { trackableAlphaValue } from "#src/trackable_alpha.js";
import { trackableBlendModeValue } from "#src/trackable_blend.js";
import { TrackableBoolean } 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 @@ -81,20 +82,21 @@ import {
import { ChannelDimensionsWidget } from "#src/widget/channel_dimensions_widget.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";
import type { LayerControlDefinition } from "#src/widget/layer_control.js";
import {
addLayerControlToOptionsTab,
registerLayerControl,
} from "#src/widget/layer_control.js";
import { enumLayerControl } from "#src/widget/layer_control_enum.js";
import { rangeLayerControl } from "#src/widget/layer_control_range.js";
import { makeMaximizeButton } from "#src/widget/maximize_button.js";
import {
renderScaleLayerControl,
VolumeRenderingRenderScaleWidget,
} from "#src/widget/render_scale_widget.js";
import { ShaderCodeWidget } from "#src/widget/shader_code_widget.js";
import {
makeShaderCodeWidgetTopRow,
ShaderCodeWidget,
} from "#src/widget/shader_code_widget.js";
import type { LegendShaderOptions } from "#src/widget/shader_controls.js";
import {
registerLayerShaderControlsTool,
Expand All @@ -105,6 +107,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 +127,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 +208,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 +298,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 +344,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 @@ -534,34 +541,24 @@ class RenderingOptionsTab extends Tab {
);
}

const spacer = document.createElement("div");
spacer.style.flex = "1";

const topRow = document.createElement("div");
topRow.className = "neuroglancer-image-dropdown-top-row";
topRow.appendChild(document.createTextNode("Shader"));
topRow.appendChild(spacer);
topRow.appendChild(
makeMaximizeButton({
title: "Show larger editor view",
onClick: () => {
new ShaderCodeOverlay(this.layer);
element.appendChild(
makeShaderCodeWidgetTopRow(
this.layer,
this.codeWidget,
ShaderCodeOverlay,
{
title: "Documentation on image layer rendering",
href: "https://github.com/google/neuroglancer/blob/master/src/sliceview/image_layer_rendering.md",
},
}),
);
topRow.appendChild(
makeHelpButton({
title: "Documentation on image layer rendering",
href: "https://github.com/google/neuroglancer/blob/master/src/sliceview/image_layer_rendering.md",
}),
"neuroglancer-image-dropdown-top-row",
),
);

element.appendChild(topRow);
element.appendChild(
this.registerDisposer(
new ChannelDimensionsWidget(layer.channelCoordinateSpaceCombiner),
).element,
);

element.appendChild(this.codeWidget.element);
element.appendChild(
this.registerDisposer(
Expand Down
4 changes: 4 additions & 0 deletions src/layer/segmentation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -578,6 +578,7 @@ const Base = UserLayerWithAnnotationsMixin(UserLayer);
export class SegmentationUserLayer extends Base {
sliceViewRenderScaleHistogram = new RenderScaleHistogram();
sliceViewRenderScaleTarget = trackableRenderScaleTarget(1);
codeVisible = new TrackableBoolean(true);

graphConnection = new WatchableValue<
SegmentationGraphSourceConnection | undefined
Expand Down Expand Up @@ -622,6 +623,7 @@ export class SegmentationUserLayer extends Base {

constructor(managedLayer: Borrowed<ManagedUserLayer>) {
super(managedLayer);
this.codeVisible.changed.add(this.specificationChanged.dispatch);
this.registerDisposer(
registerNestedSync((context, group) => {
context.registerDisposer(
Expand Down Expand Up @@ -986,6 +988,7 @@ export class SegmentationUserLayer extends Base {
if (skeletonShader !== undefined) {
skeletonRenderingOptions.shader.restoreState(skeletonShader);
}
this.codeVisible.restoreState(json_keys.SKELETON_CODE_VISIBLE_KEY);
this.displayState.renderScaleTarget.restoreState(
specification[json_keys.MESH_RENDER_SCALE_JSON_KEY],
);
Expand Down Expand Up @@ -1041,6 +1044,7 @@ export class SegmentationUserLayer extends Base {
x[json_keys.ANCHOR_SEGMENT_JSON_KEY] = this.anchorSegment.toJSON();
x[json_keys.SKELETON_RENDERING_JSON_KEY] =
this.displayState.skeletonRenderingOptions.toJSON();
x[json_keys.SKELETON_CODE_VISIBLE_KEY] = this.codeVisible.toJSON();
x[json_keys.MESH_RENDER_SCALE_JSON_KEY] =
this.displayState.renderScaleTarget.toJSON();
x[json_keys.CROSS_SECTION_RENDER_SCALE_JSON_KEY] =
Expand Down
1 change: 1 addition & 0 deletions src/layer/segmentation/json_keys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export const MESH_RENDER_SCALE_JSON_KEY = "meshRenderScale";
export const CROSS_SECTION_RENDER_SCALE_JSON_KEY = "crossSectionRenderScale";
export const SKELETON_RENDERING_JSON_KEY = "skeletonRendering";
export const SKELETON_SHADER_JSON_KEY = "skeletonShader";
export const SKELETON_CODE_VISIBLE_KEY = "codeVisible";
export const SEGMENT_QUERY_JSON_KEY = "segmentQuery";
export const MESH_SILHOUETTE_RENDERING_JSON_KEY = "meshSilhouetteRendering";
export const LINKED_SEGMENTATION_GROUP_JSON_KEY = "linkedSegmentationGroup";
Expand Down
Loading
Loading