implementing UI for bottom controls
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
pymp3
|
pymp3
|
||||||
textual
|
textual
|
||||||
textual-slider
|
textual-slider
|
||||||
|
textual-plot
|
||||||
numpy
|
numpy
|
||||||
@@ -3,6 +3,7 @@ from textual.widgets import Footer
|
|||||||
|
|
||||||
from ui.widgets.sidebar import Sidebar
|
from ui.widgets.sidebar import Sidebar
|
||||||
from ui.widgets.timeline import Timeline
|
from ui.widgets.timeline import Timeline
|
||||||
|
from ui.widgets.project_settings import ProjectSettings
|
||||||
|
|
||||||
|
|
||||||
class AppUI(App):
|
class AppUI(App):
|
||||||
@@ -13,4 +14,5 @@ class AppUI(App):
|
|||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
yield Sidebar()
|
yield Sidebar()
|
||||||
yield Timeline()
|
yield Timeline()
|
||||||
|
yield ProjectSettings()
|
||||||
yield Footer()
|
yield Footer()
|
||||||
@@ -1,9 +1,11 @@
|
|||||||
import librosa
|
import librosa
|
||||||
import pyloudnorm as pyln
|
import pyloudnorm as pyln
|
||||||
import math
|
import math
|
||||||
|
import random
|
||||||
|
|
||||||
from textual.containers import Vertical
|
from textual.containers import Vertical
|
||||||
from textual.widgets import Sparkline
|
from textual.widgets import Sparkline
|
||||||
|
from textual_plot import HiResMode, PlotWidget
|
||||||
|
|
||||||
from ui.widgets.chunk_types.chunk import Chunk
|
from ui.widgets.chunk_types.chunk import Chunk
|
||||||
|
|
||||||
@@ -12,7 +14,7 @@ from ui.widgets.chunk_types.chunk import Chunk
|
|||||||
class AudioChunk(Chunk):
|
class AudioChunk(Chunk):
|
||||||
DEFAULT_CSS = """
|
DEFAULT_CSS = """
|
||||||
AudioChunk {
|
AudioChunk {
|
||||||
|
align: left middle;
|
||||||
Sparkline {
|
Sparkline {
|
||||||
margin: 1;
|
margin: 1;
|
||||||
}
|
}
|
||||||
@@ -41,6 +43,11 @@ class AudioChunk(Chunk):
|
|||||||
|
|
||||||
self.styles.width = (self.num_samples / self.sample_rate) / self.app.zoom_level
|
self.styles.width = (self.num_samples / self.sample_rate) / self.app.zoom_level
|
||||||
|
|
||||||
|
def on_mount(self):
|
||||||
|
for plot in self.query(PlotWidget):
|
||||||
|
plot.margin_top = 0
|
||||||
|
plot.margin_left = 0
|
||||||
|
plot.margin_bottom = 0
|
||||||
|
|
||||||
def compose(self) -> ComposeResult:
|
def compose(self) -> ComposeResult:
|
||||||
|
|
||||||
@@ -56,6 +63,8 @@ class AudioChunk(Chunk):
|
|||||||
samples.append(self.audio[channel, sample])
|
samples.append(self.audio[channel, sample])
|
||||||
|
|
||||||
yield Sparkline(data=samples)
|
yield Sparkline(data=samples)
|
||||||
|
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# just display the one channel
|
# just display the one channel
|
||||||
samples = []
|
samples = []
|
||||||
@@ -64,4 +73,3 @@ class AudioChunk(Chunk):
|
|||||||
samples.append(self.audio[sample])
|
samples.append(self.audio[sample])
|
||||||
|
|
||||||
yield Sparkline(data=samples)
|
yield Sparkline(data=samples)
|
||||||
|
|
||||||
48
src/ui/widgets/project_settings.py
Normal file
48
src/ui/widgets/project_settings.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
from textual.containers import Horizontal
|
||||||
|
from textual.app import ComposeResult
|
||||||
|
from textual.widgets import Button, Input, Static
|
||||||
|
|
||||||
|
|
||||||
|
class ProjectSettings(Horizontal):
|
||||||
|
DEFAULT_CSS = """
|
||||||
|
ProjectSettings {
|
||||||
|
height: 6;
|
||||||
|
margin-bottom: 1;
|
||||||
|
dock: bottom;
|
||||||
|
background: $surface-darken-1;
|
||||||
|
border-top: tall $surface-lighten-1;
|
||||||
|
align-vertical: middle;
|
||||||
|
padding: 0 1;
|
||||||
|
|
||||||
|
Button {
|
||||||
|
max-width: 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
#song-bpm {
|
||||||
|
max-width: 12;
|
||||||
|
}
|
||||||
|
|
||||||
|
#song-time-sig {
|
||||||
|
max-width: 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
Static {
|
||||||
|
height: 3;
|
||||||
|
content-align: left middle;
|
||||||
|
width: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.border_title = "Project"
|
||||||
|
|
||||||
|
def compose(self) -> ComposeResult:
|
||||||
|
yield Button("▶", tooltip="Play song", flat=True, id="play-button", variant="success") # icon becomes "⏸" when song is playing
|
||||||
|
|
||||||
|
yield Static(" BPM: ")
|
||||||
|
yield Input("120", placeholder="120", valid_empty=False, type="integer", max_length=3, id="song-bpm")
|
||||||
|
|
||||||
|
yield Static(" Time Signature: ")
|
||||||
|
yield Input("4/4", placeholder="4/4", valid_empty=False, id="song-time-sig")
|
||||||
Reference in New Issue
Block a user