f2cdf676f3
Fixes a hidden-parent solo replay that could silence the mix. Also closes the N-mode segment silent no-op, amends the invariant comment, trims view.cpp under 600 lines, hedges two SDK inferences, drops a dead null-check.
76 lines
3.9 KiB
C++
76 lines
3.9 KiB
C++
#pragma once
|
|
#include "core/ui/rect.h"
|
|
// footer_bar — layout + hit-test for the bank_panel footer's LEFT group: the [Arrange|Design]
|
|
// mode toggle, its compact count label, and the Tail button, left-to-right at the footer's left.
|
|
//
|
|
// Affordance order, left -> right:
|
|
// [Arrange|Design] toggle . count label . Tail button . ... . Prune (rightmost, warn)
|
|
// The view/session controls group at the left; Prune stays isolated at the far right, warn-
|
|
// colored (the only byte-deleting affordance) and owned separately by prune_button — footer_bar
|
|
// reserves a right margin (rightReserve) so its own affordances never run under it.
|
|
//
|
|
// The toggle here is only the overall BOX; the shell hands its width to mode_switch
|
|
// (computeSegmentRects / hitTestSegment) for per-segment tiling — mode_switch stays the one
|
|
// owner of segment geometry.
|
|
|
|
#include "core/ui/prune_button.h" // FooterRect — the shared footer strip input type
|
|
|
|
namespace reasampler::ui {
|
|
|
|
// One placed affordance's rect, top-left origin. empty() means "not placed" (footer too narrow
|
|
// after earlier affordances claimed their space) — shell draws/hit-tests nothing for it.
|
|
using FooterBarRect = Rect;
|
|
|
|
// The laid-out footer LEFT group. Any box may be empty when the footer is too narrow to fit it
|
|
// left of the reserved right margin; placement is greedy left-to-right (toggle survives longest,
|
|
// Tail drops first on a very narrow footer).
|
|
struct FooterBarLayout {
|
|
FooterBarRect toggle;
|
|
FooterBarRect count;
|
|
FooterBarRect tail;
|
|
|
|
bool operator==(const FooterBarLayout& o) const {
|
|
return toggle == o.toggle && count == o.count && tail == o.tail;
|
|
}
|
|
};
|
|
|
|
// Which footer LEFT-group affordance a point landed on. Prune is hit-tested separately via
|
|
// hitTestPruneButton.
|
|
enum class FooterHit { None, Toggle, Tail };
|
|
|
|
// Layout inputs, in pixels; defaults are the bank_panel footer metrics.
|
|
// * rightReserve — pixels reserved at the footer's right for the prune button + version
|
|
// readout; footer_bar never places an affordance whose right edge would cross into it.
|
|
struct FooterBarSpec {
|
|
int toggleWidth = 132;
|
|
int countWidth = 64;
|
|
int tailWidth = 132;
|
|
int gap = 6;
|
|
int leftPad = 8;
|
|
int verticalInset = 4;
|
|
int rightReserve = 168; // clears prune_button (rightInset 84 + width 72) + margin
|
|
};
|
|
|
|
// Lays out the footer LEFT group inside `footer` per `spec`: toggle, count label, Tail button,
|
|
// each `gap` px apart from footer.left + leftPad. Greedy — an affordance places only if it fits
|
|
// left of (footer.right - rightReserve); once one doesn't fit, the rest are suppressed too.
|
|
// countWidth <= 0 suppresses the count label without leaving a gap for the Tail button.
|
|
FooterBarLayout computeFooterBar(const FooterRect& footer, const FooterBarSpec& spec);
|
|
|
|
// The affordance (px, py) lands on, or FooterHit::None for a miss (or a hit on the count label,
|
|
// a passive readout, never a control). Half-open bounds match computeFooterBar.
|
|
FooterHit hitTestFooterBar(int px, int py, const FooterBarLayout& layout);
|
|
|
|
// Whether one [Arrange|Design] segment is live. A mode switch is refused while the project
|
|
// plays or records (shell/view::transportBlocksModeSwitch), so an unreachable segment must READ
|
|
// dead before the click, not merely refuse on it. The ACTIVE segment stays live regardless: it
|
|
// fires a reapply, which is never gated, and dimming the mode you are already in would read as
|
|
// "this mode is unavailable" rather than "you cannot leave it right now". `routable` is whether
|
|
// the shell resolved a live command id for this segment (the model is N-mode, the UI ships two
|
|
// seeded ids — a third registered mode has no action to route through, so its segment must read
|
|
// dead rather than paint live and silently no-op on click). Passed IN so this predicate — and
|
|
// `core/ui` — stays REAPER-free, exactly as `transportRunning` is.
|
|
bool modeSegmentEnabled(bool isActiveSegment, bool transportRunning, bool routable);
|
|
|
|
} // namespace reasampler::ui
|