// mode_switch — pure implementation. See mode_switch.h. NO REAPER / SWELL / vendor. #include "mode_switch.h" #include namespace reasampler { namespace { // The left edge of segment i in a header of the given x-origin and width divided // into `count` segments. Boundary i is x + (i * width) / count, so segment i spans // [edge(i), edge(i+1)). Because every boundary is derived from the same formula, // consecutive segments share an exact edge (no gap, no overlap) and edge(count) // == x + width precisely. count assumed >= 1 by callers. int segmentEdge(int x, int width, int i, int count) { return x + (i * width) / count; } } // namespace std::vector computeSegmentRects(const HeaderRect& header, int segmentCount) { std::vector rects; if (segmentCount <= 0 || header.width <= 0) return rects; rects.reserve(static_cast(segmentCount)); for (int i = 0; i < segmentCount; ++i) { const int left = segmentEdge(header.x, header.width, i, segmentCount); const int right = segmentEdge(header.x, header.width, i + 1, segmentCount); SegmentRect r; r.x = left; r.y = header.y; r.width = right - left; // absorbs rounding; adjacent segments abut exactly r.height = header.height; rects.push_back(r); } return rects; } int hitTestSegment(int px, int py, const HeaderRect& header, int segmentCount) { if (segmentCount <= 0 || header.width <= 0 || header.height <= 0) return -1; // Reject anything outside the header band first (half-open bounds match the // segment rects). Below the header is where the grid lives — the panel falls // through to grid handling on a -1. if (px < header.x || px >= header.x + header.width || py < header.y || py >= header.y + header.height) return -1; // Inside the band: find the segment whose [edge(i), edge(i+1)) contains px. // Linear over N (N is tiny — one per mode); mirrors the boundary formula so the // hit matches the drawn segment exactly. for (int i = 0; i < segmentCount; ++i) { const int left = segmentEdge(header.x, header.width, i, segmentCount); const int right = segmentEdge(header.x, header.width, i + 1, segmentCount); if (px >= left && px < right) return i; } // Guard: px == header.x + header.width would fail the < above but was already // excluded by the band check. Any residual falls to -1 (defensive, unreachable). return -1; } } // namespace reasampler