working on openning and closing files

This commit is contained in:
2026-01-15 16:24:43 +11:00
parent 353c230d15
commit 1cdd04f67b
9 changed files with 269 additions and 15 deletions

View File

@@ -2,12 +2,15 @@ from textual.app import App, ComposeResult
from textual.widgets import Footer, Tab, Tabs, Header
from textual import on, events
from textual_fspicker import FileOpen, FileSave, Filters
from ui.widgets.sidebar import Sidebar
from ui.widgets.timeline import Timeline, TimelineRow
from ui.widgets.project_settings import ProjectSettings
from ui.widgets.channel import Channel
from ui.widgets.context_menu import ContextMenu, NoSelectStatic
from project import ProjectChannel
from project import ProjectChannel, Project
class AppUI(App):
@@ -19,6 +22,9 @@ class AppUI(App):
self.last_zoom_level = self.zoom_level
self.project = project
self.open_project_path = None
self.first_tab_click = True # stupid events firing when the app is first composed :/
@on(events.Key)
async def key_pressed(self, event: events.Key):
if event.key == "space":
@@ -29,22 +35,140 @@ class AppUI(App):
timeline.song_player.play_project(self.app.project)
def create_channel(self, name: str):
new_project_channel = ProjectChannel(
name
)
self.query_one("#channels").mount(Channel(
len(self.project.channels),
new_project_channel,
name,
), before=-1)
self.query_one("#rows").mount(TimelineRow())
self.query_one("#rows").mount(TimelineRow(new_project_channel))
self.project.channels.append(ProjectChannel(
name
))
self.project.channels.append(new_project_channel)
def handle_menu_click(self, choice: str):
# user clicked off the menu
if choice == None: return
match choice:
case "Save":
if not self.open_project_path:
self.handle_menu_click("Save as") # just move it to save as
return
self.project.write_to_file(self.open_project_path)
self.notify("Saved project.")
case "Save as":
def callback(path: str):
if path == None: return
self.open_project_path = path
self.project.write_to_file(path)
self.notify(f"Saved as \"{path}\"", title="Saved")
self.push_screen(FileSave(
filters=Filters(
("Any", lambda _: True),
("TerminalDAW Project File", lambda p: p.suffix.lower() == ".tdp")
)
), callback=callback)
case "Open":
def callback(path: str):
if path == None: return
self.project = Project.from_file(path)
self.open_project_path = path
### load all the ui elements
# sidebar channels
sidebar_channels = self.query_one("#channels")
# we cant use sidebar_channels.remove_children() because that would
# also remove the "Add Channel" button
for child in sidebar_channels.children:
if child.id != "add-channel":
child.remove()
for i, channel in enumerate(self.app.project.channels):
sidebar_channels.mount(Channel(
i,
channel,
channel.name,
channel.mute,
channel.solo,
channel.pan,
channel.volume
), before=-1)
# timeline tracks
timeline = self.query_one(Timeline)
rows = timeline.query_one("#rows")
for channel in self.project.channels:
row = TimelineRow(channel)
row.styles.width = timeline.bar_offset * self.project.song_length
for chunk in channel.chunks:
if chunk.chunk_type == ChunkType.CHUNK:
row.mount(Chunk(chunk_name=chunk.name, bar_pos=chunk.position))
elif chunk.chunk_type == ChunkType.AUDIO:
row.mount(AudioChunk(chunk.audio_data, chunk.sample_rate, chunk.name, chunk.position))
rows.mount(row)
self.notify(f"Loaded \"{path}\"")
self.push_screen(FileOpen(
filters=Filters(
("Any", lambda _: True),
("TerminalDAW Project File", lambda p: p.suffix.lower() == ".tdp")
)
), callback=callback)
case _:
self.notify("Sorry, that isn't implemented yet... ;-;", severity="warning")
@on(Tabs.TabActivated)
async def top_menu_tab_clicked(self, event: Tabs.TabActivated):
if self.first_tab_click:
event.tabs.active = None
self.first_tab_click = False
return
options = {
"File": [
"Save",
"Save as",
"Open",
"Render",
"Settings"
],
"Edit": [
"Copy",
"Paste",
"Cut"
],
"About": [
"Chookspace repo",
"Copyright"
]
}
self.app.push_screen(ContextMenu(options[event.tab.label], self.app.mouse_position + (0, 1)), callback=self.handle_menu_click)
def compose(self) -> ComposeResult:
with Tabs(id="top-menu"):
yield Tab("File")
yield Tab("Edit")
yield Tab("View")
yield Tab("Help")
yield Tabs(
Tab("File"),
Tab("Edit"),
Tab("About"),
id="top-menu")
yield Sidebar()
yield Timeline()
yield ProjectSettings()