feat(gui): reorder, bypass and remove track inserts (phase 85)
This commit is contained in:
parent
2ecc9df343
commit
ccb1d64b9f
4 changed files with 40 additions and 4 deletions
|
|
@ -1955,12 +1955,12 @@ Implemented: case-insensitive path/name search and All/LADSPA/VST2/VST3/CLAP fil
|
|||
Expose move up/down, remove and bypass with one undo step per action and safe prepared-plan adoption.
|
||||
|
||||
### 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 Up/Down, bypass and removal, preserving effect metadata and selection on reorder. Every successful edit prepares a candidate and records one undo step. Focused GUI checks cover boundary rejection, order, bypass, removal/undo and saved chain reload; warning-enabled build passed.
|
||||
|
||||
---
|
||||
|
||||
|
|
|
|||
|
|
@ -39,3 +39,8 @@ The library searches configured Preferences paths recursively (including VST3
|
|||
bundle contents), with case-insensitive search and format filters. LADSPA and
|
||||
VST2 both use `.so`, so those filters share candidates until inspection identifies
|
||||
the ABI. Listing files executes no plugin code. Only inspect trusted binaries.
|
||||
|
||||
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.
|
||||
|
|
|
|||
|
|
@ -29,6 +29,12 @@ class TrackInsertsPanel : public Fl_Group {
|
|||
add->add("Internal Delay",0,[](Fl_Widget *,void *c){static_cast<TrackInsertsPanel *>(c)->add(XTC_BUILTIN_PATH,2);},this);
|
||||
add->add("Internal Reverb",0,[](Fl_Widget *,void *c){static_cast<TrackInsertsPanel *>(c)->add(XTC_BUILTIN_PATH,3);},this);
|
||||
add->add("Plugin library...",0,[](Fl_Widget *,void *c){auto *p=static_cast<TrackInsertsPanel *>(c);std::string file;if(!xtc_choose_plugin_file(p->owner_->settings(),file))return;unsigned int index=0;if(xtc_choose_plugin(file.c_str(),p->owner_->sample_rate(),index))p->add(file.c_str(),index);},this);
|
||||
struct Action {const char *name;int command;};
|
||||
int left=x+486;
|
||||
for(const auto &action:{Action{"Up",-1},Action{"Down",1},Action{"Bypass",2},Action{"Remove",3}}) {
|
||||
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);
|
||||
}
|
||||
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_);
|
||||
|
|
@ -40,6 +46,22 @@ 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)); }
|
||||
/* 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();
|
||||
if(r!=XTC_OK)return r;
|
||||
if(index>=chain.count)return XTC_ERR_INVALID_STATE;
|
||||
size_t selected=index;
|
||||
if(command==-1 || command==1) {
|
||||
if((command==-1 && !index) || (command==1 && index+1>=chain.count))return XTC_ERR_INVALID_ARGUMENT;
|
||||
selected=command==-1 ? index-1 : index+1;std::swap(chain.slots[index],chain.slots[selected]);
|
||||
}else if(command==2)chain.slots[index].enabled=!chain.slots[index].enabled;
|
||||
else if(command==3) {for(size_t i=index+1;i<chain.count;++i)chain.slots[i-1]=chain.slots[i];chain.slots[--chain.count]={};}
|
||||
else return XTC_ERR_INVALID_ARGUMENT;
|
||||
r=owner_->set_track_chain(track_,chain);
|
||||
if(r==XTC_OK && chain.count)slots_->select(static_cast<int>(std::min(selected,chain.count-1)+1));
|
||||
return r;
|
||||
}
|
||||
void refresh(bool force=false) {
|
||||
const xtc_project *project=owner_->project_.get();size_t count=0,clips=0;xtc_project_get_counts(project,&count,&clips);
|
||||
std::vector<uint64_t> ids;std::vector<std::string> names;
|
||||
|
|
|
|||
|
|
@ -233,6 +233,15 @@ int track_insert_tests()
|
|||
auto *before=s->project();submit_result=XTC_ERR_INVALID_STATE;
|
||||
CHECK(window.add_track_effect(track,XTC_BUILTIN_PATH,3)==XTC_ERR_INVALID_STATE && s->project()==before);submit_result=XTC_OK;
|
||||
CHECK(window.add_track_effect(track,"/missing/plugin.so",0)!=XTC_OK && s->project()==before);
|
||||
CHECK(window.add_track_effect(track,XTC_BUILTIN_PATH,3)==XTC_OK);
|
||||
CHECK(panel->edit_slot(-1)==XTC_ERR_INVALID_ARGUMENT);
|
||||
CHECK(panel->edit_slot(1)==XTC_OK && panel->selected_slot()==1);
|
||||
CHECK(xtc_project_get_chain(s->project(),track,&chain)==XTC_OK && chain.slots[1].plugin.index==2);
|
||||
CHECK(panel->edit_slot(2)==XTC_OK);
|
||||
CHECK(xtc_project_get_chain(s->project(),track,&chain)==XTC_OK && !chain.slots[1].enabled);
|
||||
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(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