71a3b26a47
Docked SWELL window toggled by a new action, drawing the current bank as per-sample min/max thumbnails (PCM_source + peaks) with an in-memory cache. Pure grid-layout/cache-key math in bank_grid (tested). Renames peaks::Sample -> AudioSample to avoid colliding with bank_model::Sample.
66 lines
2.3 KiB
C++
66 lines
2.3 KiB
C++
// bank_grid — pure implementation. See bank_grid.h. NO REAPER / SWELL / vendor.
|
|
|
|
#include "bank_grid.h"
|
|
|
|
namespace reasampler {
|
|
|
|
int columnsForWidth(int panelWidth, const GridSpec& spec) {
|
|
// Layout: [gap][cell][gap][cell]...[cell][gap]. n cells occupy
|
|
// gap + n*(cellWidth + gap). Solve for the largest n that fits panelWidth,
|
|
// clamped to at least 1 so a too-narrow panel still shows a (clipped) column.
|
|
const int cell = spec.cellWidth + spec.gap;
|
|
if (cell <= 0) return 1; // degenerate spec — one column, avoid divide-by-zero
|
|
const int usable = panelWidth - spec.gap;
|
|
if (usable < spec.cellWidth) return 1;
|
|
const int cols = usable / cell;
|
|
return cols < 1 ? 1 : cols;
|
|
}
|
|
|
|
std::vector<CellRect> computeCellRects(int itemCount,
|
|
int panelWidth,
|
|
const GridSpec& spec) {
|
|
std::vector<CellRect> rects;
|
|
if (itemCount <= 0) return rects;
|
|
|
|
const int cols = columnsForWidth(panelWidth, spec);
|
|
rects.reserve(static_cast<std::size_t>(itemCount));
|
|
|
|
for (int i = 0; i < itemCount; ++i) {
|
|
const int col = i % cols;
|
|
const int row = i / cols;
|
|
CellRect r;
|
|
r.x = spec.gap + col * (spec.cellWidth + spec.gap);
|
|
r.y = spec.gap + row * (spec.cellHeight + spec.gap);
|
|
r.width = spec.cellWidth;
|
|
r.height = spec.cellHeight;
|
|
rects.push_back(r);
|
|
}
|
|
return rects;
|
|
}
|
|
|
|
int contentHeight(int itemCount, int panelWidth, const GridSpec& spec) {
|
|
if (itemCount <= 0) return 0;
|
|
const int cols = columnsForWidth(panelWidth, spec);
|
|
// Ceil-divide item count by columns to get the row count (partial last row
|
|
// still occupies a full row of height).
|
|
const int rows = (itemCount + cols - 1) / cols;
|
|
return spec.gap + rows * (spec.cellHeight + spec.gap);
|
|
}
|
|
|
|
std::string thumbnailKeyString(const ThumbnailKey& key) {
|
|
// Length-prefix the sampleId so a delimiter byte inside an id cannot forge a
|
|
// collision with a different (id, width, generation) triple.
|
|
std::string s;
|
|
s.reserve(key.sampleId.size() + 32);
|
|
s += std::to_string(key.sampleId.size());
|
|
s += ':';
|
|
s += key.sampleId;
|
|
s += '|';
|
|
s += std::to_string(key.width);
|
|
s += '|';
|
|
s += std::to_string(key.generation);
|
|
return s;
|
|
}
|
|
|
|
} // namespace reasampler
|