const int notePositionScale = 10; const int notePositionStep = 1000 * notePositionScale; const int notePositionRebalanceThreshold = 1; int toStoredNotePosition(double position) { return (position * notePositionScale).round(); } double fromStoredNotePosition(int storedPosition) { return storedPosition / notePositionScale; } int nextTopNotePosition(Iterable storedPositions) { int? highestPosition; for (final int position in storedPositions) { if (highestPosition == null || position > highestPosition) { highestPosition = position; } } if (highestPosition == null) { return 0; } return highestPosition + notePositionStep; } int? midpointNotePosition({ required int higherPosition, required int lowerPosition, }) { final int gap = higherPosition - lowerPosition; if (gap <= notePositionRebalanceThreshold) { return null; } return lowerPosition + (gap ~/ 2); } List rebalanceNotePositions(int itemCount) { return List.generate( itemCount, (int index) => (itemCount - 1 - index) * notePositionStep, ); }