Skip to content

07 Printing Measures

In this chapter, we will track the final beat and print 4/4 measure numbers in the right margin.

Beats

To know where measure labels should end, track the last beat in the level. As with the duration, store it in data declared with the level_data decorator. Add beats to Chart in guide/preview/chart.py:

python
@level_data
class Chart:
    beats: float
    duration: float

Then update PreviewNote.preprocess in guide/preview/note.py so each note contributes both its beat and its time:

python
class PreviewNote(PreviewArchetype):
    # ...

    def preprocess(self):
        Chart.beats = max(Chart.beats, self.beat)
        Chart.duration = max(Chart.duration, beat_to_time(self.beat))

    # ...

Measures

This guide supports 4/4 time: each measure contains four beats, and measure 1 starts at beat 0. In guide/preview/stage.py, add print_measures and call it from render after print_times. Start the loop at beat 4, which is measure 2, so the measure 1 label does not overlap the initial BPM marker:

python
from sonolus.script.timing import beat_to_time


class PreviewStage(PreviewArchetype):
    # ...

    def render(self):
        # ...

        self.print_measures()

    def print_measures(self):
        for beat in range(4, floor(Chart.beats) + 1, 4):
            print_at_time(
                beat / 4 + 1,
                beat_to_time(beat),
                fmt=PrintFormat.MEASURE_COUNT,
                decimal_places=0,
                color=PrintColor.NEUTRAL,
                side="right",
            )

Checkpoint

Refresh Preview. Measure 2 should appear in the right margin at beat 4, followed by another measure number every four beats. Measure 1 should have no label.