@@ -2517,6 +2517,7 @@ <h2>Controls</h2>
25172517 lastTerminalActorMap = compiled . terminalActorMap || { } ;
25182518 lastMapTable = compiled . mapTable || [ ] ;
25192519 lastSceneControls = _extractSceneControls ( compiled . ast ) ;
2520+ window . _lastCompiledAST = compiled . ast ;
25202521 buildControlsPanel ( ) ;
25212522
25222523 // Handle @scene directives — create tabs + load child sources
@@ -2844,9 +2845,26 @@ <h2>Controls</h2>
28442845 if ( dispatcher . _mapEngine ) {
28452846 dispatcher . _mapEngine . setOnStructuralChange ( ( target , value ) => {
28462847 const container = document . getElementById ( 'controlsContent' ) ;
2847- if ( ! container ) return ;
28482848
2849- if ( target . kind === 'flag' ) {
2849+ if ( target . kind === 'flag' && target . name === 'ratio' && target . actor ) {
2850+ // Structural property: actor is a polymetric group label
2851+ // Find the group by label in the timeline and modify its ratio
2852+ const tl = window . _timeline ;
2853+ if ( tl && tl . polyGroups ) {
2854+ const groupIdx = tl . polyGroups . findIndex ( g => g . label === target . actor ) ;
2855+ if ( groupIdx >= 0 ) {
2856+ // CC 0-127 → ratio 0.25 to 4.0 (log scale, 64=1.0)
2857+ const ratio = value <= 64
2858+ ? 0.25 + ( value / 64 ) * 0.75 // 0→0.25, 64→1.0
2859+ : 1.0 + ( ( value - 64 ) / 63 ) * 3.0 ; // 64→1.0, 127→4.0
2860+ rewriteGroupRatio ( groupIdx , ratio ) ;
2861+ produce ( ) ;
2862+ return ;
2863+ }
2864+ }
2865+ }
2866+
2867+ if ( target . kind === 'flag' && container ) {
28502868 // Update flag input in Flags section
28512869 const flagInput = container . querySelector ( `.flag-input[data-flag="${ target . name } "]` ) ;
28522870 if ( flagInput ) {
@@ -2856,11 +2874,11 @@ <h2>Controls</h2>
28562874 }
28572875 const flagVal = container . querySelector ( `.slider-value[data-for="flag_${ target . name } "]` ) ;
28582876 if ( flagVal ) flagVal . textContent = Math . round ( value ) ;
2859- }
28602877
2861- // Also update knobs/sliders if a control was changed
2862- if ( target . kind === 'flag' && dispatcher . onControlChange ) {
2863- dispatcher . onControlChange ( target . name , value ) ;
2878+ // Also update knobs/sliders if a control was changed
2879+ if ( dispatcher . onControlChange ) {
2880+ dispatcher . onControlChange ( target . name , value ) ;
2881+ }
28642882 }
28652883 } ) ;
28662884 }
@@ -4338,10 +4356,52 @@ <h2>Controls</h2>
43384356 } ) ;
43394357 const src = window . getEditorSource ? getEditorSource ( ) : '' ;
43404358 window . _timeline . load ( tokens , { cvTable : lastCVTable , controlTable : lastControlTable , source : src } ) ;
4359+ _injectPolyGroupLabels ( ) ;
43414360 } ) ;
43424361 } else {
43434362 const src = window . getEditorSource ? getEditorSource ( ) : '' ;
43444363 window . _timeline . load ( tokens , { cvTable : lastCVTable , controlTable : lastControlTable , source : src } ) ;
4364+ _injectPolyGroupLabels ( ) ;
4365+ }
4366+ }
4367+
4368+ /**
4369+ * Inject polymetric group labels from the AST into the timeline's polyGroups.
4370+ * The timeline parses {,} markers from tokens but doesn't know the BPscript labels.
4371+ */
4372+ function _injectPolyGroupLabels ( ) {
4373+ const tl = window . _timeline ;
4374+ if ( ! tl || ! tl . polyGroups ) return ;
4375+
4376+ // Extract labels from AST (in openOrder)
4377+ const labels = [ ] ;
4378+ function walkRhs ( elements ) {
4379+ for ( const el of elements ) {
4380+ if ( el . type === 'Polymetric' ) {
4381+ labels . push ( el . label || null ) ;
4382+ if ( el . voices ) {
4383+ for ( const voice of el . voices ) {
4384+ if ( Array . isArray ( voice ) ) walkRhs ( voice ) ;
4385+ }
4386+ }
4387+ }
4388+ }
4389+ }
4390+
4391+ const ast = window . _lastCompiledAST ;
4392+ if ( ast ?. subgrammars ) {
4393+ for ( const sg of ast . subgrammars ) {
4394+ for ( const rule of sg . rules || [ ] ) {
4395+ if ( rule . rhs ) walkRhs ( rule . rhs ) ;
4396+ }
4397+ }
4398+ }
4399+
4400+ // Match by openOrder
4401+ for ( let i = 0 ; i < tl . polyGroups . length && i < labels . length ; i ++ ) {
4402+ if ( labels [ i ] ) {
4403+ tl . polyGroups [ i ] . label = labels [ i ] ;
4404+ }
43454405 }
43464406}
43474407
0 commit comments