feat(actions): item-level Design/Arrange move + untag actions; W3-A polish

Add three MIDI-bindable item actions mirroring the track tag family, routed
through the shared hookcommand: retag selected items' membership then re-drive
mint/apply so each lands on its mode's managed lane (manual-lane items exempt),
all in one undo block. Extract shared item_read seam, simplify applyMintPlan's
lane-count pass, and guard reconcile against unregistered-mode lanes.
This commit is contained in:
2026-07-25 13:30:07 -04:00
parent 22012861c5
commit 261efe5452
9 changed files with 372 additions and 54 deletions
+34
View File
@@ -0,0 +1,34 @@
#pragma once
// item_read — the ONE place a MediaItem* is read for its canonical GUID string and for
// the durable P_LANENAME of the fixed lane it sits on. Before this seam, view.cpp and
// bank_panel.cpp each carried a near-identical private itemGuid / itemLaneName pair
// (both files' comments acknowledged the deliberate copy); the D2 Wave-3-B item actions
// need the same two reads, so the duplication is extracted here — the item-read analog
// of track_guid's single MediaTrack* -> GUID-key formatter.
//
// REAPER-facing shell: the .cpp includes reaper_plugin_functions.h WITHOUT
// REAPERAPI_IMPLEMENT (main.cpp owns the API pointers; here they are extern —
// CLAUDE.md §contract). MediaItem / MediaTrack are forward-declared so this header
// stays SDK-lite. These are shell reads (REAPER string/value getters); the managed/
// manual DECISION that consumes the lane name stays pure in lane_keys (isOnManualLane).
#include <string>
class MediaItem;
class MediaTrack;
namespace reasampler {
// An item's canonical GUID string via GetSetMediaItemInfo_String("GUID"). Empty on a
// read failure (an empty GUID must never be tagged — every caller skips empties).
std::string itemGuid(MediaItem* it);
// The durable P_LANENAME of the fixed lane item `it` currently sits on (read via the
// item's I_FIXEDLANE ordinal, then P_LANENAME:n on `tr`). Empty if the lane is unnamed
// or the param is unavailable. Callers must already know `tr` is a fixed-lane track
// (I_FREEMODE==2) before calling — I_FIXEDLANE is meaningless otherwise; the pure
// isOnManualLane predicate handles the non-fixed-lane case via its own argument, so
// callers should not call this at all for a normal track.
std::string itemLaneName(MediaTrack* tr, MediaItem* it);
} // namespace reasampler