@@ -79,6 +79,7 @@ import {
7979 setControlsInShader ,
8080 ShaderControlState ,
8181} from "#src/webgl/shader_ui_controls.js" ;
82+ import { AccordionState , AccordionTab } from "#src/widget/accordion.js" ;
8283import { ChannelDimensionsWidget } from "#src/widget/channel_dimensions_widget.js" ;
8384import { makeCopyButton } from "#src/widget/copy_button.js" ;
8485import type { DependentViewContext } from "#src/widget/dependent_view_widget.js" ;
@@ -102,7 +103,6 @@ import {
102103 registerLayerShaderControlsTool ,
103104 ShaderControls ,
104105} from "#src/widget/shader_controls.js" ;
105- import { Tab } from "#src/widget/tab_view.js" ;
106106
107107const OPACITY_JSON_KEY = "opacity" ;
108108const BLEND_JSON_KEY = "blend" ;
@@ -114,6 +114,10 @@ const CHANNEL_DIMENSIONS_JSON_KEY = "channelDimensions";
114114const VOLUME_RENDERING_JSON_KEY = "volumeRendering" ;
115115const VOLUME_RENDERING_GAIN_JSON_KEY = "volumeRenderingGain" ;
116116const VOLUME_RENDERING_DEPTH_SAMPLES_JSON_KEY = "volumeRenderingDepthSamples" ;
117+ const RENDERING_ACCORDION_JSON_KEY = "renderingAccordion" ;
118+ const SLICE_SECTION_JSON_KEY = "sliceExpanded" ;
119+ const VOLUME_RENDERING_SECTION_JSON_KEY = "volumeRenderingExpanded" ;
120+ const SHADER_SECTION_JSON_KEY = "shaderExpanded" ;
117121
118122export interface ImageLayerSelectionState extends UserLayerSelectionState {
119123 value : any ;
@@ -157,6 +161,28 @@ export class ImageUserLayer extends Base {
157161 ) ;
158162 volumeRenderingMode = trackableShaderModeValue ( ) ;
159163
164+ renderingAccordionState = this . registerDisposer (
165+ new AccordionState ( {
166+ accordionJsonKey : RENDERING_ACCORDION_JSON_KEY ,
167+ sections : [
168+ {
169+ jsonKey : SLICE_SECTION_JSON_KEY ,
170+ displayName : "Slice 2D" ,
171+ } ,
172+ {
173+ jsonKey : VOLUME_RENDERING_SECTION_JSON_KEY ,
174+ displayName : "Volume rendering" ,
175+ } ,
176+ {
177+ jsonKey : SHADER_SECTION_JSON_KEY ,
178+ displayName : "Shader controls" ,
179+ defaultExpanded : true ,
180+ isDefaultKey : true ,
181+ } ,
182+ ] ,
183+ } ) ,
184+ ) ;
185+
160186 shaderControlState = this . registerDisposer (
161187 new ShaderControlState (
162188 this . fragmentMain ,
@@ -219,10 +245,13 @@ export class ImageUserLayer extends Base {
219245 this . volumeRenderingDepthSamplesTarget . changed . add (
220246 this . specificationChanged . dispatch ,
221247 ) ;
248+ this . renderingAccordionState . specificationChanged . add (
249+ this . specificationChanged . dispatch ,
250+ ) ;
222251 this . tabs . add ( "rendering" , {
223252 label : "Rendering" ,
224253 order : - 100 ,
225- getter : ( ) => new RenderingOptionsTab ( this ) ,
254+ getter : ( ) => new RenderingOptionsTab ( this , this . renderingAccordionState ) ,
226255 } ) ;
227256 this . tabs . default = "rendering" ;
228257 }
@@ -339,6 +368,13 @@ export class ImageUserLayer extends Base {
339368 volumeRenderingDepthSamplesTarget ,
340369 ) ,
341370 ) ;
371+ verifyOptionalObjectProperty (
372+ specification ,
373+ RENDERING_ACCORDION_JSON_KEY ,
374+ ( accordionState ) => {
375+ this . renderingAccordionState . restoreState ( accordionState ) ;
376+ } ,
377+ ) ;
342378 }
343379 toJSON ( ) {
344380 const x = super . toJSON ( ) ;
@@ -354,6 +390,7 @@ export class ImageUserLayer extends Base {
354390 x [ VOLUME_RENDERING_GAIN_JSON_KEY ] = this . volumeRenderingGain . toJSON ( ) ;
355391 x [ VOLUME_RENDERING_DEPTH_SAMPLES_JSON_KEY ] =
356392 this . volumeRenderingDepthSamplesTarget . toJSON ( ) ;
393+ x [ RENDERING_ACCORDION_JSON_KEY ] = this . renderingAccordionState . toJSON ( ) ;
357394 return x ;
358395 }
359396
@@ -470,6 +507,7 @@ const LAYER_CONTROLS: LayerControlDefinition<ImageUserLayer>[] = [
470507 {
471508 label : "Resolution (slice)" ,
472509 toolJson : CROSS_SECTION_RENDER_SCALE_JSON_KEY ,
510+ sectionKey : SLICE_SECTION_JSON_KEY ,
473511 ...renderScaleLayerControl ( ( layer ) => ( {
474512 histogram : layer . sliceViewRenderScaleHistogram ,
475513 target : layer . sliceViewRenderScaleTarget ,
@@ -478,21 +516,25 @@ const LAYER_CONTROLS: LayerControlDefinition<ImageUserLayer>[] = [
478516 {
479517 label : "Blending (slice)" ,
480518 toolJson : BLEND_JSON_KEY ,
519+ sectionKey : SLICE_SECTION_JSON_KEY ,
481520 ...enumLayerControl ( ( layer ) => layer . blendMode ) ,
482521 } ,
483522 {
484523 label : "Opacity (slice)" ,
485524 toolJson : OPACITY_JSON_KEY ,
525+ sectionKey : SLICE_SECTION_JSON_KEY ,
486526 ...rangeLayerControl ( ( layer ) => ( { value : layer . opacity } ) ) ,
487527 } ,
488528 {
489529 label : "Volume rendering (experimental)" ,
490530 toolJson : VOLUME_RENDERING_JSON_KEY ,
531+ sectionKey : VOLUME_RENDERING_SECTION_JSON_KEY ,
491532 ...enumLayerControl ( ( layer ) => layer . volumeRenderingMode ) ,
492533 } ,
493534 {
494535 label : "Gain (3D)" ,
495536 toolJson : VOLUME_RENDERING_GAIN_JSON_KEY ,
537+ sectionKey : VOLUME_RENDERING_SECTION_JSON_KEY ,
496538 isValid : ( layer ) =>
497539 makeCachedDerivedWatchableValue (
498540 ( volumeRenderingMode ) =>
@@ -507,6 +549,7 @@ const LAYER_CONTROLS: LayerControlDefinition<ImageUserLayer>[] = [
507549 {
508550 label : "Resolution (3D)" ,
509551 toolJson : VOLUME_RENDERING_DEPTH_SAMPLES_JSON_KEY ,
552+ sectionKey : VOLUME_RENDERING_SECTION_JSON_KEY ,
510553 isValid : ( layer ) =>
511554 makeCachedDerivedWatchableValue (
512555 ( volumeRenderingMode ) =>
@@ -527,21 +570,25 @@ for (const control of LAYER_CONTROLS) {
527570 registerLayerControl ( ImageUserLayer , control ) ;
528571}
529572
530- class RenderingOptionsTab extends Tab {
573+ class RenderingOptionsTab extends AccordionTab {
531574 codeWidget : ShaderCodeWidget ;
532- constructor ( public layer : ImageUserLayer ) {
533- super ( ) ;
575+ constructor (
576+ public layer : ImageUserLayer ,
577+ protected accordionState : AccordionState ,
578+ ) {
579+ super ( accordionState ) ;
534580 const { element } = this ;
535581 this . codeWidget = this . registerDisposer ( makeShaderCodeWidget ( this . layer ) ) ;
536582 element . classList . add ( "neuroglancer-image-dropdown" ) ;
537583
538584 for ( const control of LAYER_CONTROLS ) {
539- element . appendChild (
585+ this . appendChild (
540586 addLayerControlToOptionsTab ( this , layer , this . visibility , control ) ,
587+ control . sectionKey ,
541588 ) ;
542589 }
543590
544- element . appendChild (
591+ this . appendChild (
545592 makeShaderCodeWidgetTopRow (
546593 this . layer ,
547594 this . codeWidget ,
@@ -553,14 +600,14 @@ class RenderingOptionsTab extends Tab {
553600 "neuroglancer-image-dropdown-top-row" ,
554601 ) ,
555602 ) ;
556- element . appendChild (
603+ this . appendChild (
557604 this . registerDisposer (
558605 new ChannelDimensionsWidget ( layer . channelCoordinateSpaceCombiner ) ,
559606 ) . element ,
560607 ) ;
561608
562- element . appendChild ( this . codeWidget . element ) ;
563- element . appendChild (
609+ this . appendChild ( this . codeWidget . element ) ;
610+ this . appendChild (
564611 this . registerDisposer (
565612 new ShaderControls (
566613 layer . shaderControlState ,
0 commit comments