Phase 33: add a flat modern DAW workspace and track creation workflow
This commit is contained in:
parent
fe484537f9
commit
d800a6392e
19 changed files with 711 additions and 115 deletions
|
|
@ -18,6 +18,7 @@
|
|||
#include <cstring>
|
||||
#include <cmath>
|
||||
#include <initializer_list>
|
||||
#include <utility>
|
||||
#include <cstdlib>
|
||||
|
||||
/* Fake only the public C backend boundary. Real FLTK widgets, callbacks and
|
||||
|
|
@ -315,8 +316,8 @@ int main(int argc, char **argv)
|
|||
CHECK(xtc_project_get_counts(sequence->project(), &track_count, &clip_count) == XTC_OK && track_count == 1 && clip_count == 1);
|
||||
xtc_clip_info region{};
|
||||
CHECK(xtc_project_get_clip(sequence->project(), 0, ®ion) == XTC_OK);
|
||||
gesture(sequence, 150, 50, 144, 0); // Move by three beats.
|
||||
gesture(sequence, 265, 50, 48, 0); // Trim left edge by one beat.
|
||||
gesture(sequence, 210, 50, 144, 0); // Move by three beats.
|
||||
gesture(sequence, 325, 50, 48, 0); // Trim left edge by one beat.
|
||||
CHECK(xtc_project_get_clip(sequence->project(), 0, ®ion) == XTC_OK &&
|
||||
region.start_tick == 3840 && region.length_tick == 2880 && region.offset_tick == 960);
|
||||
int width = sequence->w();
|
||||
|
|
@ -373,7 +374,7 @@ int main(int argc, char **argv)
|
|||
xtc_track_info t{}; xtc_project_get_track(sequence->project(), audio_row, &t);
|
||||
if (t.id == audio_clip.track_id) break;
|
||||
}
|
||||
gesture(sequence, 121 + static_cast<int>(audio_clip.start_tick*48/960), 50 + static_cast<int>(audio_row)*56, 0, 0);
|
||||
gesture(sequence, 181 + static_cast<int>(audio_clip.start_tick*48/960), 50 + static_cast<int>(audio_row)*56, 0, 0);
|
||||
CHECK(sequence->selected_clip() == audio_clip.id);
|
||||
CHECK(sequence->audio_properties(0.5f, 1, 1) == XTC_OK);
|
||||
sequence->position(audio_clip.start_tick+1);
|
||||
|
|
@ -848,6 +849,49 @@ int main(int argc, char **argv)
|
|||
unlink("/tmp/xtc-gui-instrument.xtc"); window.do_callback();
|
||||
}
|
||||
}
|
||||
// Flat workspace creation is one history edit, and failed preparation keeps
|
||||
// the current model. Exercise real sidebar buttons rather than mock actions.
|
||||
reset();
|
||||
{
|
||||
MainWindow window(false); window.show();
|
||||
auto *sequence = timeline(&window);
|
||||
CHECK(sequence != nullptr);
|
||||
auto *midi = find(&window,"New MIDI track");
|
||||
auto *audio = find(&window,"New audio track");
|
||||
CHECK(midi && audio && find(&window,"Import WAV") && find(&window,"Edit MIDI notes"));
|
||||
press(midi);
|
||||
size_t tracks = 0, clips = 0;
|
||||
xtc_project_get_counts(sequence->project(),&tracks,&clips);
|
||||
CHECK(tracks == 1 && clips == 1);
|
||||
uint64_t track = sequence->selected_track(), clip = sequence->selected_clip();
|
||||
xtc_clip_info info{}; CHECK(xtc_project_find_clip(sequence->project(),clip,&info) == XTC_OK && info.midi);
|
||||
CHECK(window.mixer()->selected_track() == track);
|
||||
CHECK(window.open_piano_roll() == XTC_OK);
|
||||
CHECK(window.undo(false) == XTC_OK);
|
||||
xtc_project_get_counts(sequence->project(),&tracks,&clips); CHECK(tracks == 0 && clips == 0);
|
||||
CHECK(window.undo(true) == XTC_OK);
|
||||
CHECK(sequence->select(track,clip)); pump();
|
||||
CHECK(contains(&window,"MIDI track"));
|
||||
press(audio);
|
||||
xtc_project_get_counts(sequence->project(),&tracks,&clips); CHECK(tracks == 2 && clips == 1);
|
||||
const xtc_project *before = sequence->project();
|
||||
reserve_result = XTC_ERR_OUT_OF_MEMORY;
|
||||
CHECK(window.create_track(true) == XTC_ERR_OUT_OF_MEMORY && sequence->project() == before);
|
||||
reserve_result = XTC_OK; submit_result = XTC_ERR_INVALID_STATE;
|
||||
CHECK(window.create_track(false) == XTC_ERR_INVALID_STATE && sequence->project() == before);
|
||||
submit_result = XTC_OK;
|
||||
// Exercise the supported minimum and a larger workspace with real layout.
|
||||
for (auto size : {std::pair<int,int>{1220,720},{1600,1000}}) {
|
||||
window.resize(window.x(),window.y(),size.first,size.second); pump();
|
||||
CHECK(midi->x() >= 0 && midi->x()+midi->w() <= sequence->parent()->x());
|
||||
CHECK(sequence->parent()->x()+sequence->parent()->w() <= window.w());
|
||||
CHECK(find(&window,"Play")->visible_r() && midi->visible_r());
|
||||
}
|
||||
CHECK(window.save_project("/tmp/xtc-workspace.xtc") == XTC_OK);
|
||||
CHECK(window.new_project() == XTC_OK && window.open_project("/tmp/xtc-workspace.xtc") == XTC_OK);
|
||||
xtc_project_get_counts(sequence->project(),&tracks,&clips); CHECK(tracks == 2 && clips == 1);
|
||||
unlink("/tmp/xtc-workspace.xtc"); window.do_callback();
|
||||
}
|
||||
if (failures != 0) return 1;
|
||||
std::printf("GUI controls/errors/views/timers/cleanup passed: %u opens, %u closes.\n", opens, closes);
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ def main():
|
|||
example = resources / 'xtc/examples/midi-demo.xtc'
|
||||
run([str(binaries / 'xtc-check'), '--inspect', str(example)])
|
||||
assert (resources / 'xtc/examples/README.md').is_file()
|
||||
run([str(binaries / 'xtc-check'), '--inspect', str(resources / 'xtc/examples/modern-session.xtc')])
|
||||
assert (docs / 'WORKSPACE.md').is_file()
|
||||
diagnose = subprocess.check_output([str(binaries / 'xtc-check'), '--diagnose'], text=True)
|
||||
assert 'Project formats: 1..12' in diagnose and 'JACK compiled:' in diagnose
|
||||
# Replacing a file symlink must not overwrite an unrelated target.
|
||||
|
|
|
|||
|
|
@ -110,7 +110,7 @@ int main(int argc, char **argv)
|
|||
CHECK(window.piano_roll());
|
||||
CHECK(window.piano_roll()->add_note(0, 960, 60) == XTC_OK);
|
||||
CHECK(window.piano_roll()->add_note(960, 960, 64) == XTC_OK);
|
||||
gesture(*timeline, 150, 50, 96); // Move the clip two beats using its body.
|
||||
gesture(*timeline, 210, 50, 96); // Move the clip two beats using its body.
|
||||
CHECK(xtc_project_get_clip(timeline->project(), 0, &arranged) == XTC_OK);
|
||||
CHECK(arranged.start_tick == 1920 && arranged.length_tick == 3840);
|
||||
CHECK(window.import_audio(wave.c_str()) == XTC_OK);
|
||||
|
|
@ -137,7 +137,7 @@ int main(int argc, char **argv)
|
|||
size_t actual_nodes, actual_edges;
|
||||
CHECK(xtc_graph_get_counts(xtc_project_graph(timeline->project()), &actual_nodes, &actual_edges) == XTC_OK);
|
||||
CHECK(actual_nodes == nodes && actual_edges == edges);
|
||||
gesture(*timeline, 216, 10, 0); // Ruler seeks two beats while stopped.
|
||||
gesture(*timeline, 276, 10, 0); // Ruler seeks two beats while stopped.
|
||||
CHECK(timeline->position() == 1920);
|
||||
press(window, "Play"); pump();
|
||||
CHECK(!button(window, "Play")->active() && button(window, "Pause")->active());
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue