fix(SegmentationStyle): Fix inactive contour visibility and styling. (#5563)

* Opacity, fill and outline properties for active and inactive contours
are now consistent with those for label map segmentations.
The properties for inactive segmentations are applied to BOTH
inactive contours and label maps.

* Activate the selected segmentation for a type when the alpha, outline width, or fill/outline visibility is changed.
This commit is contained in:
Joe Boccanfuso authored and GitHub committed 2025-11-19 17:55:53 -05:00
1 parent 62797acd9a
commit 5c17c262ea
23 files changed
+395 -361

No files matched your search

@@ -40,6 +40,7 @@ export const SegmentationTableRoot = (props: SegmentationTableProps) => {
disabled = false,
children,
showConfig: externalShowConfig,
selectedSegmentationIdForType,
...contextProps
} = props;
@@ -55,6 +56,11 @@ export const SegmentationTableRoot = (props: SegmentationTableProps) => {
const activeRepresentation = props.activeRepresentation || activeSegmentationInfo?.representation;
const activeSegmentation = props.activeSegmentation || activeSegmentationInfo?.segmentation;
const selectedSegmentationForTypeInfo = data.find(
info => info.segmentation?.segmentationId === selectedSegmentationIdForType
);
const selectedSegmentationForTypeRepresentation = selectedSegmentationForTypeInfo?.representation;
// Extract style properties or use defaults
const {
fillAlpha = props.fillAlpha || 0.5,
@@ -62,7 +68,7 @@ export const SegmentationTableRoot = (props: SegmentationTableProps) => {
outlineWidth = props.outlineWidth || 1,
renderFill = props.renderFill !== undefined ? props.renderFill : true,
renderOutline = props.renderOutline !== undefined ? props.renderOutline : true,
} = activeRepresentation?.styles ?? {};
} = selectedSegmentationForTypeRepresentation?.styles ?? {};
// Check if SegmentationTableConfig is present in children
const hasConfigComponent = Children.toArray(children).some(
@@ -102,6 +108,7 @@ export const SegmentationTableRoot = (props: SegmentationTableProps) => {
activeSegmentationId,
activeSegmentation,
activeRepresentation,
selectedSegmentationIdForType,
...contextProps,
setShowConfig: toggleShowConfig,
}}
@@ -14,8 +14,9 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> =
renderFill,
renderOutline,
setRenderFill,
setRenderFillInactive,
setRenderOutline,
activeRepresentation,
setRenderOutlineInactive,
fillAlpha,
fillAlphaInactive,
outlineWidth,
@@ -24,6 +25,7 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> =
setOutlineWidth,
renderInactiveSegmentations,
toggleRenderInactiveSegmentations,
segmentationRepresentationType,
data,
} = useSegmentationTableContext('SegmentationTableConfig');
@@ -48,14 +50,20 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> =
}
onValueChange={value => {
if (value === 'fill-and-outline') {
setRenderFill({ type: activeRepresentation.type }, true);
setRenderOutline({ type: activeRepresentation.type }, true);
setRenderFill({ type: segmentationRepresentationType }, true);
setRenderOutline({ type: segmentationRepresentationType }, true);
setRenderFillInactive({ type: segmentationRepresentationType }, true);
setRenderOutlineInactive({ type: segmentationRepresentationType }, true);
} else if (value === 'outline') {
setRenderFill({ type: activeRepresentation.type }, false);
setRenderOutline({ type: activeRepresentation.type }, true);
setRenderFill({ type: segmentationRepresentationType }, false);
setRenderOutline({ type: segmentationRepresentationType }, true);
setRenderFillInactive({ type: segmentationRepresentationType }, false);
setRenderOutlineInactive({ type: segmentationRepresentationType }, true);
} else {
setRenderFill({ type: activeRepresentation.type }, true);
setRenderOutline({ type: activeRepresentation.type }, false);
setRenderFill({ type: segmentationRepresentationType }, true);
setRenderOutline({ type: segmentationRepresentationType }, false);
setRenderFillInactive({ type: segmentationRepresentationType }, true);
setRenderOutlineInactive({ type: segmentationRepresentationType }, false);
}
}}
>
@@ -81,7 +89,9 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> =
<Slider
className="mx-1 flex-1"
value={[fillAlpha]}
onValueChange={([value]) => setFillAlpha({ type: activeRepresentation.type }, value)}
onValueChange={([value]) =>
setFillAlpha({ type: segmentationRepresentationType }, value)
}
max={1}
min={0}
step={0.1}
@@ -90,7 +100,7 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> =
className="mx-1 w-10 flex-none"
value={fillAlpha}
onChange={e =>
setFillAlpha({ type: activeRepresentation.type }, Number(e.target.value))
setFillAlpha({ type: segmentationRepresentationType }, Number(e.target.value))
}
/>
</div>
@@ -101,7 +111,9 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> =
</Label>
<Slider
value={[outlineWidth]}
onValueChange={([value]) => setOutlineWidth({ type: activeRepresentation.type }, value)}
onValueChange={([value]) =>
setOutlineWidth({ type: segmentationRepresentationType }, value)
}
max={10}
min={0}
step={0.1}
@@ -110,7 +122,7 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> =
<Input
value={outlineWidth}
onChange={e =>
setOutlineWidth({ type: activeRepresentation.type }, Number(e.target.value))
setOutlineWidth({ type: segmentationRepresentationType }, Number(e.target.value))
}
className="mx-1 w-10 flex-none text-center"
/>
@@ -136,9 +148,7 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> =
<Slider
className="mx-1 flex-1"
value={[fillAlphaInactive]}
onValueChange={([value]) =>
setFillAlphaInactive({ type: activeRepresentation.type }, value)
}
onValueChange={([value]) => setFillAlphaInactive({}, value)}
max={1}
min={0}
step={0.1}
@@ -146,9 +156,7 @@ export const SegmentationTableConfig: React.FC<{ children?: React.ReactNode }> =
<Input
className="mx-1 w-10 flex-none"
value={fillAlphaInactive}
onChange={e =>
setFillAlphaInactive({ type: activeRepresentation.type }, Number(e.target.value))
}
onChange={e => setFillAlphaInactive({}, Number(e.target.value))}
/>
</div>
)}
@@ -75,10 +75,12 @@ export interface SegmentationTableContextType {
// Function handlers
setShowConfig?: (show: boolean) => void;
setRenderFill?: ({ type }: { type: string }, value: boolean) => void;
setRenderFillInactive?: ({ type }: { type: string }, value: boolean) => void;
setRenderOutline?: ({ type }: { type: string }, value: boolean) => void;
setRenderOutlineInactive?: ({ type }: { type: string }, value: boolean) => void;
setOutlineWidth?: ({ type }: { type: string }, value: number) => void;
setFillAlpha?: ({ type }: { type: string }, value: number) => void;
setFillAlphaInactive?: ({ type }: { type: string }, value: number) => void;
setFillAlphaInactive?: ({ type }: { type?: string }, value: number) => void;
toggleRenderInactiveSegmentations?: () => void;
onSegmentationAdd?: ({
segmentationId,