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.