diff --git a/src/ui/app.py b/src/ui/app.py index 37acaba..96fa5d6 100644 --- a/src/ui/app.py +++ b/src/ui/app.py @@ -2,8 +2,11 @@ from textual.app import App, ComposeResult from textual.widgets import Footer, Tab, Tabs, Header from ui.widgets.sidebar import Sidebar -from ui.widgets.timeline import Timeline +from ui.widgets.timeline import Timeline, TimelineRow from ui.widgets.project_settings import ProjectSettings +from ui.widgets.channel import Channel + +from project import ProjectChannel from song_player import SongPlayer @@ -22,6 +25,17 @@ class AppUI(App): self.song_player = SongPlayer(self) + def create_channel(self, name: str): + self.query_one("#channels").mount(Channel( + len(self.project.channels), + name, + ), before=-1) + self.query_one("#rows").mount(TimelineRow()) + + self.project.channels.append(ProjectChannel( + name + )) + def on_mount(self): self.song_player.play_song(self.app.project) diff --git a/src/ui/screens/channel_create_screen.py b/src/ui/screens/channel_create_screen.py new file mode 100644 index 0000000..fdfa24b --- /dev/null +++ b/src/ui/screens/channel_create_screen.py @@ -0,0 +1,66 @@ +from textual.screen import ModalScreen +from textual.containers import HorizontalGroup, Vertical +from textual.app import ComposeResult +from textual.widgets import Static, Input, Button +from textual.binding import Binding + + +class ChannelCreateScreen(ModalScreen): + DEFAULT_CSS = """ + ChannelCreateScreen { + align: center middle; + + #center { + width: 50; + height: 11; + border: panel $primary; + + align: center top; + padding: 1 2; + + Static { + width: auto; + height: 3; + content-align: left middle; + } + + Input { + width: 25; + } + + Button { + margin-right: 2; + } + + HorizontalGroup { + align: center middle; + margin-bottom: 1; + } + } + + + } + """ + + BINDINGS = [ + Binding("escape", "dismiss", "Cancel", tooltip="Cancel channel creation") + ] + + def on_input_submitted(self, event: Input.Submitted): + self.app.create_channel(event.input.value) + self.dismiss() + + def on_button_pressed(self, event: Button.press): + if event.button.id == "create": + self.app.create_channel(self.query_one(Input).value) + self.dismiss() + + def compose(self) -> ComposeResult: + with Vertical(id="center") as center: + center.border_title = "Create New Channel" + with HorizontalGroup(): + yield Static("Channel Name: ") + yield Input(placeholder="Piano", max_length=50) + with HorizontalGroup(): + yield Button("Cancel", variant="error", id="cancel") + yield Button("Create", variant="success", id="create") \ No newline at end of file diff --git a/src/ui/widgets/sidebar.py b/src/ui/widgets/sidebar.py index 3256d3c..bf22c23 100644 --- a/src/ui/widgets/sidebar.py +++ b/src/ui/widgets/sidebar.py @@ -3,6 +3,7 @@ from textual.widgets import Button, ListView from textual.app import ComposeResult from ui.widgets.channel import Channel +from ui.screens.channel_create_screen import ChannelCreateScreen class Sidebar(Vertical): @@ -22,6 +23,10 @@ class Sidebar(Vertical): } """ + def on_button_pressed(self, event: Button.Pressed): + if event.button.id == "add-channel": + self.app.push_screen(ChannelCreateScreen()) + def compose(self) -> ComposeResult: with VerticalScroll(id="channels"): for i, channel in enumerate(self.app.project.channels): diff --git a/src/ui/widgets/timeline.py b/src/ui/widgets/timeline.py index fe23c73..2b634bd 100644 --- a/src/ui/widgets/timeline.py +++ b/src/ui/widgets/timeline.py @@ -12,8 +12,9 @@ class TimelineRow(Horizontal): DEFAULT_CSS = """ TimelineRow { background: $surface-lighten-1; - max-height: 8; + height: 8; margin-bottom: 1; + width: 100; } """ @@ -22,7 +23,8 @@ class Timeline(Vertical): Timeline { #rows { hatch: "-" $surface-lighten-1; - padding: 1 0; + padding: 0 0; + overflow-x: auto; .beat-line { color: $surface-lighten-1;