mwe full cycle form input
parent
24e85d7005
commit
37786f56b5
@ -0,0 +1,67 @@
|
|||||||
|
import os
|
||||||
|
|
||||||
|
from textual.app import App, ComposeResult
|
||||||
|
from textual.screen import Screen
|
||||||
|
from textual.widgets import Header, Footer, Placeholder, Label
|
||||||
|
|
||||||
|
from sqlalchemy import create_engine
|
||||||
|
from sqlalchemy.orm import sessionmaker
|
||||||
|
from ffx.model.show import Base, Show
|
||||||
|
from ffx.model.pattern import Pattern
|
||||||
|
|
||||||
|
from .shows_screen import ShowsScreen
|
||||||
|
from .warning_screen import WarningScreen
|
||||||
|
from .dashboard_screen import DashboardScreen
|
||||||
|
from .settings_screen import SettingsScreen
|
||||||
|
from .help_screen import HelpScreen
|
||||||
|
|
||||||
|
class FfxApp(App):
|
||||||
|
|
||||||
|
TITLE = "FFX"
|
||||||
|
|
||||||
|
BINDINGS = [
|
||||||
|
("q", "quit()", "Quit"),
|
||||||
|
# ("d", "switch_mode('dashboard')", "Dashboard"),
|
||||||
|
# ("s", "switch_mode('settings')", "Settings"),
|
||||||
|
("h", "switch_mode('help')", "Help"),
|
||||||
|
]
|
||||||
|
|
||||||
|
# MODES = {
|
||||||
|
# "shows": ShowsScreen,
|
||||||
|
# "warning": WarningScreen,
|
||||||
|
# "dashboard": DashboardScreen,
|
||||||
|
# "settings": SettingsScreen,
|
||||||
|
# "help": HelpScreen,
|
||||||
|
# }
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, context = {}):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
# Data 'input' variable
|
||||||
|
self.context = context
|
||||||
|
|
||||||
|
# Initialize DB
|
||||||
|
homeDir = os.path.expanduser("~")
|
||||||
|
ffxVarDir = os.path.join(homeDir, '.local', 'var', 'ffx')
|
||||||
|
if not os.path.exists(ffxVarDir):
|
||||||
|
os.makedirs(ffxVarDir)
|
||||||
|
|
||||||
|
self.context['database_url'] = f"sqlite:///{os.path.join(ffxVarDir, 'ffx.db')}"
|
||||||
|
self.context['database_engine'] = create_engine(self.context['database_url'])
|
||||||
|
self.context['database_session'] = sessionmaker(bind=self.context['database_engine'])
|
||||||
|
|
||||||
|
Base.metadata.create_all(self.context['database_engine'])
|
||||||
|
|
||||||
|
|
||||||
|
def on_mount(self) -> None:
|
||||||
|
|
||||||
|
|
||||||
|
# Show Shows Screen
|
||||||
|
#self.switch_mode("shows")
|
||||||
|
self.push_screen(ShowsScreen())
|
||||||
|
|
||||||
|
|
||||||
|
def getContext(self):
|
||||||
|
"""Data 'output' method"""
|
||||||
|
return self.context
|
@ -1,2 +0,0 @@
|
|||||||
class FilePattern():
|
|
||||||
pass
|
|
@ -0,0 +1,10 @@
|
|||||||
|
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
|
||||||
|
from sqlalchemy.orm import relationship, sessionmaker
|
||||||
|
|
||||||
|
from .show import Base
|
||||||
|
|
||||||
|
class Pattern(Base):
|
||||||
|
|
||||||
|
__tablename__ = 'patterns'
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
pattern = Column(String)
|
@ -0,0 +1,13 @@
|
|||||||
|
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
|
||||||
|
from sqlalchemy.orm import relationship, sessionmaker
|
||||||
|
|
||||||
|
from sqlalchemy.orm import declarative_base
|
||||||
|
|
||||||
|
Base = declarative_base()
|
||||||
|
|
||||||
|
class Show(Base):
|
||||||
|
|
||||||
|
__tablename__ = 'shows'
|
||||||
|
id = Column(Integer, primary_key=True)
|
||||||
|
name = Column(String)
|
||||||
|
year = Column(Integer)
|
@ -1,39 +0,0 @@
|
|||||||
from textual.app import App, ComposeResult
|
|
||||||
from textual.screen import Screen
|
|
||||||
from textual.widgets import Header, Footer, Placeholder, Label
|
|
||||||
|
|
||||||
from .shows_screen import ShowsScreen
|
|
||||||
from .warning_screen import WarningScreen
|
|
||||||
from .dashboard_screen import DashboardScreen
|
|
||||||
from .settings_screen import SettingsScreen
|
|
||||||
from .help_screen import HelpScreen
|
|
||||||
|
|
||||||
class ModesApp(App):
|
|
||||||
|
|
||||||
TITLE = "FFX"
|
|
||||||
|
|
||||||
BINDINGS = [
|
|
||||||
("q", "quit()", "Quit"),
|
|
||||||
# ("d", "switch_mode('dashboard')", "Dashboard"),
|
|
||||||
# ("s", "switch_mode('settings')", "Settings"),
|
|
||||||
# ("h", "switch_mode('help')", "Help"),
|
|
||||||
]
|
|
||||||
|
|
||||||
MODES = {
|
|
||||||
"shows": ShowsScreen,
|
|
||||||
"warning": WarningScreen,
|
|
||||||
"dashboard": DashboardScreen,
|
|
||||||
"settings": SettingsScreen,
|
|
||||||
"help": HelpScreen,
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, context = {}):
|
|
||||||
super().__init__()
|
|
||||||
self.context = context
|
|
||||||
|
|
||||||
def on_mount(self) -> None:
|
|
||||||
self.switch_mode("shows")
|
|
||||||
|
|
||||||
def getContext(self):
|
|
||||||
return self.context
|
|
@ -1,2 +0,0 @@
|
|||||||
class Show():
|
|
||||||
pass
|
|
@ -0,0 +1,166 @@
|
|||||||
|
import click
|
||||||
|
|
||||||
|
from textual import events
|
||||||
|
from textual.app import App, ComposeResult
|
||||||
|
from textual.screen import Screen
|
||||||
|
from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button, Input
|
||||||
|
from textual.containers import Grid, Horizontal
|
||||||
|
|
||||||
|
from ffx.model.show import Show
|
||||||
|
|
||||||
|
# class IdInput(Input):
|
||||||
|
# def on_key(self, event: events.Key) -> None:
|
||||||
|
# if event == "enter":
|
||||||
|
# quit()
|
||||||
|
|
||||||
|
class ShowDetailsScreen(Screen):
|
||||||
|
|
||||||
|
CSS = """
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
grid-size: 2;
|
||||||
|
grid-rows: 2 auto;
|
||||||
|
grid-columns: 30 auto;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Input {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
Button {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
#toplabel {
|
||||||
|
height: 1;
|
||||||
|
column-span: 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#two {
|
||||||
|
column-span: 2;
|
||||||
|
row-span: 2;
|
||||||
|
tint: magenta 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
height: 100%;
|
||||||
|
border: solid green;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
#BINDINGS = [
|
||||||
|
# #("q", "quit()", "Quit"),
|
||||||
|
# ("h", "switch_mode('help')", "Help")
|
||||||
|
#]
|
||||||
|
|
||||||
|
#def action_quit(self):
|
||||||
|
# quit()
|
||||||
|
|
||||||
|
def __init__(self, show_id = None):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.context = self.app.getContext()
|
||||||
|
|
||||||
|
self.Session = self.context['database_session'] # convenience
|
||||||
|
|
||||||
|
self.show_id = show_id
|
||||||
|
|
||||||
|
def action_submit(self):
|
||||||
|
quit()
|
||||||
|
|
||||||
|
def compose(self):
|
||||||
|
|
||||||
|
yield Header()
|
||||||
|
|
||||||
|
with Grid():
|
||||||
|
|
||||||
|
yield Static("New Show" if self.show_id is None else "Show", id="toplabel")
|
||||||
|
yield Static("ID")
|
||||||
|
yield Input(type="text", id="id_input")
|
||||||
|
yield Static("Name")
|
||||||
|
yield Input(type="text", id="name_input")
|
||||||
|
yield Static("Year")
|
||||||
|
yield Input(type="text", id="year_input")
|
||||||
|
|
||||||
|
yield Static("")
|
||||||
|
yield Static("")
|
||||||
|
|
||||||
|
yield Static("")
|
||||||
|
yield Static("")
|
||||||
|
|
||||||
|
yield Button("Save", id="save_button")
|
||||||
|
yield Button("Cancel", id="cancel_button")
|
||||||
|
|
||||||
|
yield Static("", id="output_static")
|
||||||
|
|
||||||
|
|
||||||
|
yield Footer()
|
||||||
|
|
||||||
|
def getValues(self):
|
||||||
|
showId = int(self.query_one("#id_input", Input).value)
|
||||||
|
showName = self.query_one("#name_input", Input).value
|
||||||
|
showYear = self.query_one("#year_input", Input).value
|
||||||
|
return showId, showName, showYear
|
||||||
|
|
||||||
|
|
||||||
|
def on_input_submitted(self, event: Input.Submitted) -> None:
|
||||||
|
|
||||||
|
showId, showName, showYear = self.getValues()
|
||||||
|
|
||||||
|
#self.query_one("#output_static", Static).update(f"{showId} - {showName} ({showYear})")
|
||||||
|
|
||||||
|
# if event.input.id == "id_input":
|
||||||
|
# # Retrieve the entered text
|
||||||
|
# name = event.value
|
||||||
|
# # Display the result in the output label
|
||||||
|
# self.query_one("#output_static", Static).update(f"Hello, {name}!")
|
||||||
|
# self.set_focus(self.query_one("#name_input", Input))
|
||||||
|
#
|
||||||
|
# if event.input.id == "name_input":
|
||||||
|
# # Retrieve the entered text
|
||||||
|
# name = event.value
|
||||||
|
# # Display the result in the output label
|
||||||
|
# self.query_one("#output_static", Static).update(f"Yo, {name}!")
|
||||||
|
# self.set_focus(self.query_one("#year_input", Input))
|
||||||
|
#
|
||||||
|
# if event.input.id == "year_input":
|
||||||
|
# # Retrieve the entered text
|
||||||
|
# name = event.value
|
||||||
|
# # Display the result in the output label
|
||||||
|
# self.query_one("#output_static", Static).update(f"Ya, {name}!")
|
||||||
|
# self.set_focus(None)
|
||||||
|
|
||||||
|
# Event handler for button press
|
||||||
|
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||||
|
# Check if the button pressed is the one we are interested in
|
||||||
|
if event.button.id == "save_button":
|
||||||
|
|
||||||
|
showId, showName, showYear = self.getValues()
|
||||||
|
self.query_one("#output_static", Static).update(f"{showId} - {showName} ({showYear})")
|
||||||
|
|
||||||
|
self.addShow(showId, showName, showYear)
|
||||||
|
#TODO: Validation
|
||||||
|
|
||||||
|
# self.app.pop_screen()
|
||||||
|
self.dismiss(showId)
|
||||||
|
|
||||||
|
if event.button.id == "cancel_button":
|
||||||
|
self.app.pop_screen()
|
||||||
|
|
||||||
|
def addShow(self, show_id, show_name, show_year):
|
||||||
|
|
||||||
|
try:
|
||||||
|
s = self.Session()
|
||||||
|
show = Show(id = show_id,
|
||||||
|
name = show_name,
|
||||||
|
year = show_year)
|
||||||
|
|
||||||
|
s.add(show)
|
||||||
|
s.commit()
|
||||||
|
except Exception as ex:
|
||||||
|
click.ClickException(f"ShowDetailsScreen.addShow(): {repr(ex)}")
|
||||||
|
finally:
|
||||||
|
s.close()
|
||||||
|
|
@ -0,0 +1,60 @@
|
|||||||
|
import click
|
||||||
|
|
||||||
|
from textual.app import App, ComposeResult
|
||||||
|
from textual.screen import Screen
|
||||||
|
from textual.widgets import Header, Footer, Placeholder, Label, ListView, ListItem, Static, DataTable, Button
|
||||||
|
from textual.containers import Grid, Horizontal
|
||||||
|
|
||||||
|
from ffx.model.show import Show
|
||||||
|
|
||||||
|
class ShowNewScreen(Screen):
|
||||||
|
|
||||||
|
CSS = """
|
||||||
|
|
||||||
|
Grid {
|
||||||
|
grid-size: 2;
|
||||||
|
grid-rows: 2 auto;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
padding: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#top {
|
||||||
|
height: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#two {
|
||||||
|
column-span: 2;
|
||||||
|
row-span: 2;
|
||||||
|
tint: magenta 40%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.box {
|
||||||
|
height: 100%;
|
||||||
|
border: solid green;
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
|
||||||
|
BINDINGS = [
|
||||||
|
("q", "quit()", "Quit"),
|
||||||
|
("h", "switch_mode('help')", "Help")
|
||||||
|
]
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
self.context = self.app.getContext()
|
||||||
|
|
||||||
|
self.Session = self.context['database_session'] # convenience
|
||||||
|
|
||||||
|
|
||||||
|
def compose(self):
|
||||||
|
|
||||||
|
yield Header()
|
||||||
|
|
||||||
|
with Grid():
|
||||||
|
|
||||||
|
yield Static("New Show")
|
||||||
|
|
||||||
|
yield Footer()
|
Loading…
Reference in New Issue