#pragma once // insert — placement of bank samples into the arrange (M6). REAPER-facing shell: // it reads the bank_panel's current selection, resolves each selected sample's // file, and drops it into the arrange at the edit cursor via InsertMedia, wrapped // in an undo block. // // THE INTENDED PLACEMENT PATH (CONTEXT.md §load-bearing principle): capture NEVER // auto-inserts; `insert` is the deliberate, user-invoked placement act, so it IS // allowed and expected to add items to the arrange. It must only ever run from its // own action — never from a capture path. // // Non-destructive to the bank: insert references the bank file (adds an arrange // item pointing at it); it never modifies the bank, the bank files, or ext state. // No SILENT time-stretch: conform-to-tempo is an explicit opt-in on the request, // defaulting OFF (native length). See insert_plan for the mode-bit computation. // // The header is SDK-free: all REAPER API use lives in insert.cpp. The pure // mode-bit arithmetic lives in insert_plan (unit-tested outside the DAW). #include "insert_plan.h" namespace reasampler { class ReaSamplerSession; // What one insert action does. Carries the InsertMedia options (target track + // tempo-conform choice) so the two action variants (native-length vs // conform-to-tempo) differ only by this struct — no divergent code paths. struct InsertRequest { InsertOptions options; // defaults: current track, no conform, native length }; // The outcome of an insert action, for the caller to log to the console. enum class InsertStatus { Ok, // one or more samples inserted NoSelection, // the panel had no selection — a no-op (not an error) NoProject, // no saved project, so no resolvable bank dir — no-op NothingResolved, // a selection existed but no sample resolved to a file }; struct InsertResult { InsertStatus status = InsertStatus::NoSelection; int inserted = 0; // how many samples were actually placed int skipped = 0; // selected-but-unresolvable/unreadable samples skipped }; // Runs the insert: reads the bank panel's single focused sample and the user's // currently-selected track set, then inserts the sample onto EACH selected track // at the SAME edit-cursor position. Snapshot/restore ensures the user's track // selection and cursor position are unchanged after the action. The whole operation // is wrapped in a single Undo_BeginBlock2 / Undo_EndBlock2. // // No-op cases (with console messages): // - No track selected: prints "select a track first." // - No sample selected in the panel: NoSelection status. // - Unsaved project (no resolvable bank dir): NoProject status. // - Sample id not in bank / file missing: NothingResolved status. // // `session` supplies the live bank the selected id resolves against. InsertResult runInsert(ReaSamplerSession* session, const InsertRequest& request); } // namespace reasampler