2nd Pass Render
This commit is contained in:
@@ -0,0 +1,134 @@
|
||||
#include "shell/panel/footer_input.h"
|
||||
#include "shell/panel/panel_state.h"
|
||||
#include "core/view/view_mode_model.h"
|
||||
#include "shell/actions/bank_actions.h"
|
||||
#include "shell/persist/session.h" // ReaSamplerSession — view/tail reads + mutation
|
||||
|
||||
#define REAPERAPI_MINIMAL
|
||||
#define REAPERAPI_WANT_EnumProjects
|
||||
#define REAPERAPI_WANT_MarkProjectDirty
|
||||
#define REAPERAPI_WANT_Main_OnCommand
|
||||
#include "reaper_plugin_functions.h"
|
||||
|
||||
namespace reasampler::panel {
|
||||
|
||||
namespace {
|
||||
// Commits the current tail setting to ext state and marks the active project dirty so the
|
||||
// change travels inside the .rpp on Ctrl+S — closes the gap where toggle/scroll would dirty
|
||||
// the project but never write the new value. No-ops cleanly on an unsaved project.
|
||||
void markTailDirty()
|
||||
{
|
||||
if (g_panel.session) g_panel.session->saveToActiveProject();
|
||||
ReaProject* proj = EnumProjects(-1, nullptr, 0);
|
||||
if (proj) MarkProjectDirty(proj);
|
||||
}
|
||||
|
||||
// click was confirmed on the toggle button;
|
||||
// detect which mode segment was hit (if any)
|
||||
bool clickToggle(int x, int y, ui::FooterBarRect toggleRect)
|
||||
{
|
||||
const int seg = hitTestSegment(x, y, toggleRect, modeCount());
|
||||
if (seg >= 0) {
|
||||
const ViewModeModel& view = g_panel.session->view();
|
||||
const std::vector<Mode>& modes = view.modes().all();
|
||||
|
||||
if (seg < static_cast<int>(modes.size())) {
|
||||
const std::string& id = modes[static_cast<std::size_t>(seg)].id;
|
||||
const bool isActive = id == view.activeModeId();
|
||||
const int cmd = modeActivateCommandId(id);
|
||||
if (modeSegmentEnabled(isActive, g_panel.modeSwitchBlocked, cmd != 0)) {
|
||||
if (cmd != 0 && Main_OnCommand) Main_OnCommand(cmd, 0);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// click was confirmed on the Tail button
|
||||
void clickTail()
|
||||
{
|
||||
TailSetting& tail = g_panel.session->tail();
|
||||
tail.mode = cycleTailMode(tail.mode);
|
||||
markTailDirty();
|
||||
invalidatePanel();
|
||||
}
|
||||
|
||||
void clickSecondPass()
|
||||
{
|
||||
TailSetting& tail = g_panel.session->tail();
|
||||
tail.secondPass = capture::toggleSecondPass(tail.secondPass);
|
||||
markTailDirty();
|
||||
invalidatePanel();
|
||||
}
|
||||
|
||||
// click was confirmed on the prune button
|
||||
void clickPrune()
|
||||
{
|
||||
// Fires through its registered command id (not the session directly) so the panel
|
||||
// affordance and the bindable action share the one guarded dry-run/confirm/delete
|
||||
// path in doBankPruneFolder.
|
||||
const int cmd = bankPruneCommandId();
|
||||
if (cmd != 0) Main_OnCommand(cmd, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Returns: true if the click was inside the footer bar,
|
||||
// false if the click was outside the footer bar.
|
||||
bool handleFooterClick(int x, int y, int w, int h)
|
||||
{
|
||||
|
||||
const ButtonRect pb = pruneButtonRectFor(w, h);
|
||||
if (hitTestPruneButton(x, y, pb)) {
|
||||
clickPrune();
|
||||
return true;
|
||||
}
|
||||
|
||||
const FooterBarLayout fb = footerBarLayoutFor(w, h);
|
||||
if (g_panel.session) {
|
||||
FooterHit clicked = hitTestFooterBar(x, y, fb);
|
||||
|
||||
// The short-circuit cases
|
||||
if (clicked == FooterHit::Outside) { return false; }
|
||||
if (clicked == FooterHit::Invalid) { return true; }
|
||||
|
||||
// Check actual clickable elements:
|
||||
|
||||
// Cycles None -> Auto -> Manual -> None
|
||||
if (clicked == FooterHit::Tail) { clickTail(); }
|
||||
|
||||
// Detect which segment was selected and activate that mode
|
||||
if (clicked == FooterHit::Toggle) { clickToggle(x, y, fb.toggle); }
|
||||
|
||||
// Toggle 2nd Pass Render
|
||||
if (clicked == FooterHit::SecondPass) { clickSecondPass(); }
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// If we reach this point, no valid click target inside the footer was hit.
|
||||
return false;
|
||||
}
|
||||
|
||||
bool handleFooterWheel(int x, int y, int delta) {
|
||||
if (!g_panel.session) return false;
|
||||
|
||||
TailSetting& tail = g_panel.session->tail();
|
||||
if (tail.mode != TailMode::Manual) return false; // fine-adjust is Manual-only
|
||||
|
||||
// One notch is WHEEL_DELTA (120); accumulate whole notches so a high-res trackpad
|
||||
// that sends fractional deltas still steps predictably. Sign carries direction.
|
||||
const int notches = delta / 120;
|
||||
if (notches == 0) return false; // sub-notch movement — nothing to apply yet
|
||||
|
||||
const double before = tail.manualMs;
|
||||
tail.manualMs = adjustManualMs(tail.manualMs, notches, kManualStepMs);
|
||||
if (tail.manualMs == before) return true; // already at a bound — consumed, no change
|
||||
|
||||
markTailDirty();
|
||||
invalidatePanel(); // label shows the new length live
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user