Q-W1 pt2: core/shell/app relocation + sub-namespaces; one concrete ui::Rect (LTRB fork retired); slot_map split from bank_book; BankIndex→BankModel; 59/59 green
This commit is contained in:
@@ -0,0 +1,96 @@
|
||||
// capture_browser.cpp — see capture_browser.h. Pure math; no host types.
|
||||
|
||||
#include "core/instrument/ui/capture_browser.h"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
namespace reasampler::instrument::ui {
|
||||
|
||||
namespace {
|
||||
|
||||
// The left edge of tab i in a strip of the given x-origin and width divided into `count`
|
||||
// equal segments (mirror of mode_switch::segmentEdge). Every boundary derives from the same
|
||||
// formula, so consecutive tabs share an exact edge and the last tab reaches x+width exactly.
|
||||
int tabEdge(int x, int width, int i, int count) {
|
||||
return x + (i * width) / count;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
BrowserLayout layoutBrowser(int w, int h) {
|
||||
const int cw = std::max(0, w);
|
||||
const int ch = std::max(0, h);
|
||||
|
||||
BrowserLayout out;
|
||||
const int tabH = std::min(kBrowserTabHeight, ch);
|
||||
out.tabStrip = Rect::ltrb(0, 0, cw, tabH);
|
||||
out.grid = Rect::ltrb(0, tabH, cw, ch);
|
||||
|
||||
const int gridW = std::max(0, out.grid.width);
|
||||
out.columns = std::max(1, gridW / kBrowserCardWidth);
|
||||
return out;
|
||||
}
|
||||
|
||||
Rect cardCellRect(const BrowserLayout& layout, int index) {
|
||||
if (index < 0) return Rect{};
|
||||
const int cols = std::max(1, layout.columns);
|
||||
const int col = index % cols;
|
||||
const int row = index / cols;
|
||||
const int left = layout.grid.x + col * kBrowserCardWidth;
|
||||
const int top = layout.grid.y + row * kBrowserCardHeight;
|
||||
return Rect::ltrb(left, top, left + kBrowserCardWidth, top + kBrowserCardHeight);
|
||||
}
|
||||
|
||||
Rect cardContentRect(const BrowserLayout& layout, int index) {
|
||||
if (index < 0) return Rect{};
|
||||
const Rect cell = cardCellRect(layout, index);
|
||||
return Rect::ltrb(cell.x + kBrowserCardGutter, cell.y + kBrowserCardGutter,
|
||||
cell.right() - kBrowserCardGutter, cell.bottom() - kBrowserCardGutter);
|
||||
}
|
||||
|
||||
Rect cardThumbnailRect(const BrowserLayout& layout, int index) {
|
||||
if (index < 0) return Rect{};
|
||||
const Rect content = cardContentRect(layout, index);
|
||||
const int thumbH = std::min(kBrowserThumbHeight, std::max(0, content.height));
|
||||
return Rect::ltrb(content.x, content.y, content.right(), content.y + thumbH);
|
||||
}
|
||||
|
||||
Rect cardLabelRect(const BrowserLayout& layout, int index) {
|
||||
if (index < 0) return Rect{};
|
||||
const Rect content = cardContentRect(layout, index);
|
||||
const Rect thumb = cardThumbnailRect(layout, index);
|
||||
return Rect::ltrb(content.x, thumb.bottom(), content.right(), content.bottom());
|
||||
}
|
||||
|
||||
int cardHitTest(const BrowserLayout& layout, int cardCount, int x, int y) {
|
||||
if (cardCount <= 0) return -1;
|
||||
if (!contains(layout.grid, x, y)) return -1;
|
||||
const int cols = std::max(1, layout.columns);
|
||||
const int col = (x - layout.grid.x) / kBrowserCardWidth;
|
||||
const int row = (y - layout.grid.y) / kBrowserCardHeight;
|
||||
if (col < 0 || col >= cols) return -1; // past the last column (right dead-zone)
|
||||
const int index = row * cols + col;
|
||||
if (index < 0 || index >= cardCount) return -1;
|
||||
// Only a hit inside the card CONTENT counts — a click in the inter-card gutter misses.
|
||||
if (!contains(cardContentRect(layout, index), x, y)) return -1;
|
||||
return index;
|
||||
}
|
||||
|
||||
Rect filterTabRect(const BrowserLayout& layout, int tabCount, int index) {
|
||||
if (tabCount <= 0 || index < 0 || index >= tabCount) return Rect{};
|
||||
const Rect& strip = layout.tabStrip;
|
||||
const int left = tabEdge(strip.x, std::max(0, strip.width), index, tabCount);
|
||||
const int right = tabEdge(strip.x, std::max(0, strip.width), index + 1, tabCount);
|
||||
return Rect::ltrb(left, strip.y, right, strip.bottom());
|
||||
}
|
||||
|
||||
int filterTabHitTest(const BrowserLayout& layout, int tabCount, int x, int y) {
|
||||
if (tabCount <= 0) return -1;
|
||||
if (!contains(layout.tabStrip, x, y)) return -1;
|
||||
for (int i = 0; i < tabCount; ++i) {
|
||||
if (contains(filterTabRect(layout, tabCount, i), x, y)) return i;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
} // namespace reasampler::instrument::ui
|
||||
Reference in New Issue
Block a user