from textual.containers import Vertical, VerticalScroll, Horizontal, VerticalGroup, HorizontalGroup from textual.widgets import Rule from textual.app import ComposeResult from ui.widgets.chunk_types.audio import AudioChunk, Chunk from ui.widgets.play_head import PlayHead from project import ChunkType class TimelineRow(Horizontal): DEFAULT_CSS = """ TimelineRow { background: $surface-lighten-1; max-height: 8; margin-bottom: 1; } """ class Timeline(Vertical): DEFAULT_CSS = """ Timeline { #rows { hatch: "-" $surface-lighten-1; padding: 1 0; .beat-line { color: $surface-lighten-1; } .bar-line { color: $surface-lighten-2; } .beat-line, .bar-line { dock: left; margin: 0; } } PlayHead { layer: top; } } """ def __init__(self): super().__init__() self.bar_offset = self.app.project.bpm / 8 * (0.0333 / self.app.zoom_level) def compose(self) -> ComposeResult: with VerticalScroll(id="rows"): for i in range(1, 17): bar = None if (i) % 4 == 0: bar = Rule.vertical(classes="bar-line", line_style="double") else: bar = Rule.vertical(classes="beat-line") bar.offset = (self.bar_offset * i, 0) yield bar for channel in self.app.project.channels: with TimelineRow(): for chunk in channel.chunks: if chunk.chunk_type == ChunkType.CHUNK: yield Chunk(chunk_name=chunk.name) elif chunk.chunk_type == ChunkType.AUDIO: yield AudioChunk(chunk.audio_data, chunk.sample_rate, chunk.name) #yield PlayHead()