feat(plugins): inspect and edit selected track effects (phase 86)
This commit is contained in:
parent
ccb1d64b9f
commit
eb71ca765f
5 changed files with 33 additions and 4 deletions
|
|
@ -1970,12 +1970,12 @@ Implemented: selected insert Up/Down, bypass and removal, preserving effect meta
|
|||
Show selected effect identity and supported generic controls. Provide reset where supported and clearly identify unavailable native editors/parameters.
|
||||
|
||||
### Tasks and acceptance criteria
|
||||
- [ ] Implement the described workflow with validated errors and safe ownership.
|
||||
- [ ] Pass relevant core and/or GUI tests.
|
||||
- [ ] Document behavior and limitations; commit this phase separately.
|
||||
- [x] Implement the described workflow with validated errors and safe ownership.
|
||||
- [x] Pass relevant core and/or GUI tests.
|
||||
- [x] Document behavior and limitations; commit this phase separately.
|
||||
|
||||
### Implementation status
|
||||
Planned.
|
||||
Implemented: selected insert Inspect/edit verifies identity and shows generic controls with reset/defaults through transactional preparation. Zero-parameter adapters explicitly explain default configuration and unavailable native editors; reset is disabled there. Focused real modal reset/apply/cancel, adoption, undo and reload tests passed with a warning-enabled GUI build.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -44,3 +44,9 @@ Select a slot in the rack, then use **Up**, **Down**, **Bypass** or **Remove**.
|
|||
The selection follows reordered effects. Bypassed slots retain their settings
|
||||
and appear marked in the rack; their nodes are omitted from the compiled graph.
|
||||
Each successful operation creates one project undo step.
|
||||
|
||||
**Inspect / edit** verifies the selected plugin and opens its identity and generic
|
||||
controls. Reset defaults clears parameter automation on Apply. Cancel leaves the
|
||||
project unchanged. Internal effects and LADSPA expose controls; modern adapters
|
||||
currently expose none and run default configurations. Native plugin editor
|
||||
windows and opaque plugin-state chunks are not implemented.
|
||||
|
|
|
|||
|
|
@ -78,11 +78,16 @@ bool xtc_edit_plugin(const xtc_plugin_spec &spec, const xtc_plugin_details &deta
|
|||
((details.flags[i] & XTC_PLUGIN_LOGARITHMIC) ? "; logarithmic hint" : "");
|
||||
auto *range = new Fl_Box(25,y+27,715,25); range->copy_label(hint.c_str()); range->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
|
||||
}
|
||||
if(!spec.control_count) {
|
||||
auto *unavailable=new Fl_Box(25,160,730,75,"This adapter exposes no editable parameters. The plugin runs with its default configuration.\nNative plugin editor windows are not available in this host.");
|
||||
unavailable->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
|
||||
}
|
||||
scroll->end();
|
||||
auto *note = new Fl_Box(15,515,770,30,"Automation overrides static controls. Reset defaults also clears all plugin automation.");
|
||||
note->labelsize(12);
|
||||
struct Reset { const xtc_plugin_details *details; std::array<Fl_Value_Input *,XTC_PLUGIN_CONTROLS> *inputs; unsigned int count; bool used; } reset{&details,&inputs,spec.control_count,false};
|
||||
auto *defaults = new Fl_Button(20,555,170,30,"Reset defaults");
|
||||
if(!spec.control_count)defaults->deactivate();
|
||||
defaults->callback([](Fl_Widget *, void *data) {
|
||||
auto *r = static_cast<Reset *>(data); r->used = true;
|
||||
for (unsigned int i = 0; i < r->count; ++i) (*r->inputs)[i]->value(r->details->parameters[i].default_value);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ class TrackInsertsPanel : public Fl_Group {
|
|||
auto *button=new Fl_Button(left,y+12,82,28,action.name);left+=90;
|
||||
button->callback([](Fl_Widget *w,void *c){auto *p=static_cast<TrackInsertsPanel *>(c);int command=!strcmp(w->label(),"Up") ? -1 : !strcmp(w->label(),"Down") ? 1 : !strcmp(w->label(),"Bypass") ? 2 : 3;p->result(p->edit_slot(command));},this);
|
||||
}
|
||||
auto *inspect=new Fl_Button(x+850,y+12,120,28,"Inspect / edit");
|
||||
inspect->callback([](Fl_Widget *,void *c){auto *p=static_cast<TrackInsertsPanel *>(c);p->result(p->inspect_slot());},this);
|
||||
message_=new Fl_Box(x+16,y+50,w-32,32,"Track input > inserts > output gain > track fader > bus/master");message_->align(FL_ALIGN_LEFT|FL_ALIGN_INSIDE);
|
||||
slots_=new Fl_Hold_Browser(x+16,y+94,230,h-110);slots_->format_char(0);
|
||||
graph_=new GraphWidget(x+260,y+94,w-276,h-110,nullptr,[](void *,const xtc_graph_edit &,size_t *){return XTC_ERR_UNSUPPORTED;},nullptr,message_);
|
||||
|
|
@ -46,6 +48,15 @@ class TrackInsertsPanel : public Fl_Group {
|
|||
void select_track(uint64_t id) {track_=id;refresh(true);}
|
||||
const xtc_graph *graph() const {return model_;}
|
||||
void add(const char *file,unsigned int index) { result(owner_->add_track_effect(track_,file,index)); }
|
||||
xtc_result inspect_slot() {
|
||||
xtc_track_chain chain{};auto r=xtc_project_get_chain(owner_->project_.get(),track_,&chain);size_t index=selected_slot();
|
||||
if(r!=XTC_OK)return r;
|
||||
if(index>=chain.count)return XTC_ERR_INVALID_STATE;
|
||||
xtc_plugin_details details{};xtc_plugin_spec edited{};
|
||||
r=xtc_plugin_describe(&chain.slots[index].plugin,owner_->sample_rate(),&details);if(r!=XTC_OK)return r;
|
||||
if(!xtc_edit_plugin(chain.slots[index].plugin,details,edited))return XTC_OK;
|
||||
chain.slots[index].plugin=edited;return owner_->set_track_chain(track_,chain);
|
||||
}
|
||||
/* Commands: -1 up, 1 down, 2 toggle bypass, 3 remove. */
|
||||
xtc_result edit_slot(int command) {
|
||||
xtc_track_chain chain{};auto r=xtc_project_get_chain(owner_->project_.get(),track_,&chain);size_t index=selected_slot();
|
||||
|
|
|
|||
|
|
@ -242,6 +242,13 @@ int track_insert_tests()
|
|||
CHECK(panel->edit_slot(3)==XTC_OK && window.undo()==XTC_OK);panel->refresh(true);
|
||||
CHECK(xtc_project_get_chain(s->project(),track,&chain)==XTC_OK && chain.count==2);
|
||||
CHECK(panel->edit_slot(3)==XTC_OK);
|
||||
CHECK(xtc_project_get_chain(s->project(),track,&chain)==XTC_OK);chain.slots[0].plugin.values[0]=10;
|
||||
CHECK(window.set_track_chain(track,chain)==XTC_OK);
|
||||
Fl::add_timeout(.05,[](void *){auto *dialog=Fl::modal();CHECK(dialog);press(find(dialog,"Reset defaults"));press(find(dialog,"Apply"));});
|
||||
CHECK(panel->inspect_slot()==XTC_OK);
|
||||
CHECK(xtc_project_get_chain(s->project(),track,&chain)==XTC_OK && chain.slots[0].plugin.values[0]!=10);
|
||||
const auto *cancel_before=s->project();
|
||||
Fl::add_timeout(.05,[](void *){press(find(Fl::modal(),"Cancel"));});CHECK(panel->inspect_slot()==XTC_OK && s->project()==cancel_before);
|
||||
CHECK(window.save_project("/tmp/xtc-inserts-gui.xtc")==XTC_OK && window.new_project()==XTC_OK && window.open_project("/tmp/xtc-inserts-gui.xtc")==XTC_OK);
|
||||
CHECK(xtc_project_get_chain(s->project(),track,&chain)==XTC_OK && chain.count==1);unlink("/tmp/xtc-inserts-gui.xtc");
|
||||
window.do_callback();puts("Track inserts GUI adoption/undo/rollback/reload passed.");return failures ? 1 : 0;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue