@@ -314,6 +314,8 @@ class NodeMidiProgramsListPropertyComponent : public PropertyComponent,
314314 // Show up to maxVisibleRows rows before scrolling.
315315 const int rows = jlimit (1 , maxVisibleRows, jmax (1 , programs.size ()));
316316 setPreferredHeight (rows * rowHeight + 2 );
317+
318+ selectCurrentProgramRow ();
317319 }
318320
319321 /* * Draw the full-width table with no property label. PropertyComponent
@@ -339,6 +341,7 @@ class NodeMidiProgramsListPropertyComponent : public PropertyComponent,
339341 fetchPrograms ();
340342 list.setVisible (! programs.isEmpty ());
341343 list.updateContent ();
344+ selectCurrentProgramRow ();
342345 list.repaint ();
343346 repaint ();
344347 }
@@ -400,11 +403,35 @@ class NodeMidiProgramsListPropertyComponent : public PropertyComponent,
400403 return ;
401404 if (ProcessorPtr ptr = node.getObject ())
402405 {
403- node.setMidiProgram (programs.getReference (rowNumber).program );
406+ const int program = programs.getReference (rowNumber).program ;
407+ if (program == ptr->getMidiProgram ())
408+ return ; // already loaded — don't discard live edits by reloading
409+ node.setMidiProgram (program);
404410 ptr->reloadMidiProgram (); // fires midiProgramChanged -> panel refreshes
405411 }
406412 }
407413
414+ /* * Highlights the row matching the node's currently-loaded MIDI program.
415+ The current program can change from a table click, the slider selector,
416+ or a Program Change message received externally. All three update the
417+ Processor's program (the single source of truth here — the Node model
418+ property is not touched by externally-received program changes), and all
419+ funnel through midiProgramChanged, which rebuilds this component. */
420+ void selectCurrentProgramRow ()
421+ {
422+ ProcessorPtr ptr = node.getObject ();
423+ const int current = ptr != nullptr ? ptr->getMidiProgram () : -1 ;
424+ for (int i = 0 ; i < programs.size (); ++i)
425+ {
426+ if (programs.getReference (i).program == current)
427+ {
428+ list.selectRow (i);
429+ return ;
430+ }
431+ }
432+ list.deselectAllRows ();
433+ }
434+
408435 void renameRow (int rowNumber, const String& newName)
409436 {
410437 if (isGlobal || ! isPositiveAndBelow (rowNumber, programs.size ()))
@@ -501,7 +528,11 @@ class NodeMidiProgramsListPropertyComponent : public PropertyComponent,
501528 name.setBounds (r);
502529 }
503530
504- void mouseDown (const MouseEvent&) override { owner.selectRow (row); }
531+ void mouseDown (const MouseEvent&) override
532+ {
533+ owner.selectRow (row); // instant highlight before the async reload completes
534+ owner.loadRow (row);
535+ }
505536 void mouseDoubleClick (const MouseEvent& e) override
506537 {
507538 // Double-clicking the name edits it (handled by the Label); only
0 commit comments