// card_meta — pure implementation. See card_meta.h. #include "core/ui/card_meta.h" #include #include namespace reasampler::ui { Rect cardNameStrip(const Rect& cell) { // Both strips plus a waveform band at least as tall as one strip; below that the card // is a text block, not a thumbnail. const int minHeight = 3 * kCardStripHeight; if (cell.width <= 2 * kCardStripPad || cell.height < minHeight) return Rect{}; // Inset by 1px from the top edge so the name never sits on the selection border. return Rect{cell.x + kCardStripPad, cell.y + 1, cell.width - 2 * kCardStripPad, kCardStripHeight}; } std::string formatBarsBeats(const MusicalLength& m) { if (m.tempoBpm <= 0.0 || m.timeSigNum <= 0 || m.timeSigDenom <= 0) return {}; const double len = m.lengthSeconds > 0.0 ? m.lengthSeconds : 0.0; // A quarter-note is 60/tempo s; a beat is (4/denom) quarter-notes. const double secondsPerBeat = (60.0 / m.tempoBpm) * (4.0 / m.timeSigDenom); double totalBeats = len / secondsPerBeat; // Snap to an exact beat within epsilon so a bar-aligned capture reads "2.1.00" rather than // "1.4.99" from FP error just under the boundary. const double snapped = std::floor(totalBeats + 0.5); if (std::fabs(totalBeats - snapped) < 1e-6) totalBeats = snapped; double wholeBeats = std::floor(totalBeats); double frac = totalBeats - wholeBeats; const long wb = static_cast(wholeBeats); const long bar = wb / m.timeSigNum + 1; const long beat = wb % m.timeSigNum + 1; int sub = static_cast(std::floor(frac * 100.0)); if (sub < 0) sub = 0; if (sub > 99) sub = 99; char buf[48]; std::snprintf(buf, sizeof(buf), "%ld.%ld.%02d", bar, beat, sub); return buf; } std::string formatSecondsMs(double lengthSeconds) { double len = lengthSeconds > 0.0 ? lengthSeconds : 0.0; long secs = static_cast(std::floor(len)); // Round to nearest ms, not floor: FP storage error would otherwise render e.g. "62.036" // for a value that should read "62.037". int ms = static_cast((len - static_cast(secs)) * 1000.0 + 0.5); if (ms >= 1000) { ms -= 1000; ++secs; } // rounding can carry into the next second if (ms < 0) ms = 0; char buf[48]; std::snprintf(buf, sizeof(buf), "%ld.%03d", secs, ms); return buf; } } // namespace reasampler::ui