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-163 Add annotation color as a tool in the layer's render tab #53

Closed
wants to merge 14 commits into from
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
44 changes: 43 additions & 1 deletion src/layer/annotation/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ 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 { makeCachedLazyDerivedWatchableValue } from "#src/trackable_value.js";
import { makeCachedLazyDerivedWatchableValue, observeWatchable } from "#src/trackable_value.js";
import type {
AnnotationLayerView,
MergedAnnotationStates,
Expand All @@ -69,6 +69,8 @@ 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 { 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";
Expand All @@ -87,6 +89,7 @@ const CROSS_SECTION_RENDER_SCALE_JSON_KEY = "crossSectionAnnotationSpacing";
const PROJECTION_RENDER_SCALE_JSON_KEY = "projectionAnnotationSpacing";
const SHADER_JSON_KEY = "shader";
const SHADER_CONTROLS_JSON_KEY = "shaderControls";
const ANNOTATION_COLOR_JSON_KEY = "annotationColor";

function addPointAnnotations(annotations: LocalAnnotationSource, obj: any) {
if (obj === undefined) {
Expand Down Expand Up @@ -455,6 +458,9 @@ export class AnnotationUserLayer extends Base {
this.annotationDisplayState.shaderControls.restoreState(
specification[SHADER_CONTROLS_JSON_KEY],
);
this.annotationDisplayState.color.restoreState(
specification[ANNOTATION_COLOR_JSON_KEY],
)
}

getLegacyDataSourceSpecifications(
Expand Down Expand Up @@ -709,6 +715,8 @@ export class AnnotationUserLayer extends Base {
x[SHADER_JSON_KEY] = this.annotationDisplayState.shader.toJSON();
x[SHADER_CONTROLS_JSON_KEY] =
this.annotationDisplayState.shaderControls.toJSON();
x[ANNOTATION_COLOR_JSON_KEY] =
this.annotationDisplayState.color.toJSON();
Object.assign(x, this.linkedSegmentationLayers.toJSON());
return x;
}
Expand Down Expand Up @@ -740,6 +748,24 @@ class RenderingOptionsTab extends Tab {
super();
const { element } = this;
element.classList.add("neuroglancer-annotation-rendering-tab");

const colorControlToolWidget = element.appendChild(
seankmartin marked this conversation as resolved.
Show resolved Hide resolved
addLayerControlToOptionsTab(this, layer, this.visibility, LAYER_CONTROLS[ANNOTATION_COLOR_JSON_KEY])
);
this.registerDisposer(
observeWatchable((hasDefaultColor) => {
if (hasDefaultColor) {
colorControlToolWidget.style.display = "";
} else {
colorControlToolWidget.style.display = "none";
this.layer.toolBinder.removeJsonString(ANNOTATION_COLOR_JSON_KEY);
}
}, makeCachedLazyDerivedWatchableValue(
(shader) => shader.match(/\bdefaultColor\b/) !== null,
layer.annotationDisplayState.shaderControls.processedFragmentMain
))
)

element.appendChild(
this.registerDisposer(
new DependentViewWidget(
Expand Down Expand Up @@ -776,6 +802,7 @@ class RenderingOptionsTab extends Tab {
),
).element,
);

const topRow = document.createElement("div");
topRow.className =
"neuroglancer-segmentation-dropdown-skeleton-shader-header";
Expand Down Expand Up @@ -813,6 +840,21 @@ class RenderingOptionsTab extends Tab {
}
}

const LAYER_CONTROLS: Record<string, LayerControlDefinition<AnnotationUserLayer>> = {
[ANNOTATION_COLOR_JSON_KEY]: {
label: "Annotation default color",
title: "Annotation shader default color (enabled with 'defaultColor()' in the shader code)",
toolJson: ANNOTATION_COLOR_JSON_KEY,
...colorLayerControl(
(layer: AnnotationUserLayer) => layer.annotationDisplayState.color,
),
},
};

for (const control of Object.values(LAYER_CONTROLS)) {
registerLayerControl(AnnotationUserLayer, control);
}

registerLayerType(AnnotationUserLayer);
registerLayerType(AnnotationUserLayer, "pointAnnotation");
registerLayerTypeDetector((subsource) => {
Expand Down
16 changes: 0 additions & 16 deletions src/ui/annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,6 @@ import {
registerCallbackWhenSegmentationDisplayStateChanged,
SegmentWidgetFactory,
} from "#src/segmentation_display_state/frontend.js";
import { ElementVisibilityFromTrackableBoolean } from "#src/trackable_boolean.js";
import type { WatchableValueInterface } from "#src/trackable_value.js";
import {
AggregateWatchableValue,
Expand Down Expand Up @@ -101,7 +100,6 @@ import { NullarySignal, Signal } from "#src/util/signal.js";
import { Uint64 } from "#src/util/uint64.js";
import * as vector from "#src/util/vector.js";
import { makeAddButton } from "#src/widget/add_button.js";
import { ColorWidget } from "#src/widget/color.js";
import { makeCopyButton } from "#src/widget/copy_button.js";
import { makeDeleteButton } from "#src/widget/delete_button.js";
import type { DependentViewContext } from "#src/widget/dependent_view_widget.js";
Expand Down Expand Up @@ -394,20 +392,6 @@ export class AnnotationLayerView extends Tab {
toolbox.className = "neuroglancer-annotation-toolbox";

layer.initializeAnnotationLayerViewTab(this);
const colorPicker = this.registerDisposer(
new ColorWidget(this.displayState.color),
);
colorPicker.element.title = "Change annotation display color";
this.registerDisposer(
new ElementVisibilityFromTrackableBoolean(
makeCachedLazyDerivedWatchableValue(
(shader) => shader.match(/\bdefaultColor\b/) !== null,
displayState.shaderControls.processedFragmentMain,
),
colorPicker.element,
),
);
toolbox.appendChild(colorPicker.element);
const { mutableControls } = this;
const pointButton = makeIcon({
text: annotationTypeHandlers[AnnotationType.POINT].icon,
Expand Down
2 changes: 1 addition & 1 deletion src/ui/tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,7 @@ export class LocalToolBinder<
}

removeJsonString(toolJsonString: string) {
const key = this.jsonToKey.get(toolJsonString);
const key = this.jsonToKey.get(toolJsonString) || this.jsonToKey.get(JSON.stringify(toolJsonString));
if (key === undefined) return;
this.set(key, undefined);
}
Expand Down
Loading