ShiErFeng/shierfeng-fastapi-backend/cli/tui/screens/confirm.py
2026-07-24 09:43:10 +08:00

129 lines
3.3 KiB
Python

from textual import on
from textual.app import ComposeResult
from textual.binding import Binding
from textual.containers import Horizontal, Vertical
from textual.screen import ModalScreen
from textual.widgets import Button, Static
from cli.tui.copy import TUI_COPY
class ActionConfirmScreen(ModalScreen[bool]):
"""
通用动作确认弹窗。
:param title: 弹窗标题
:param lines: 预览文本行
:param confirm_label: 确认按钮文本
"""
CSS = """
ActionConfirmScreen {
align: center middle;
}
#action-confirm-dialog {
width: 96;
max-width: 96;
border: heavy #38d8ff;
background: #06111b;
padding: 1 2;
}
#action-confirm-title {
text-style: bold;
color: #e9fcff;
margin-bottom: 1;
}
#action-confirm-body {
border: round #18425d;
background: #081827;
color: #d8f7ff;
padding: 1 2;
margin-bottom: 1;
}
#action-confirm-actions {
height: auto;
align-horizontal: right;
}
#action-confirm-hint {
color: #8fc6d6;
margin-bottom: 1;
}
#action-confirm-cancel {
margin-right: 1;
}
"""
BINDINGS = [
Binding('escape', 'cancel', TUI_COPY.build_confirm_binding_label('cancel'), show=False),
Binding('enter', 'submit', TUI_COPY.build_confirm_binding_label('submit'), show=False),
]
def __init__(self, title: str, lines: list[str], confirm_label: str) -> None:
super().__init__()
self._dialog_title = title
self._dialog_lines = lines
self._confirm_label = confirm_label
def compose(self) -> ComposeResult:
"""
构建确认弹窗界面。
:return: Textual 组件结果
"""
with Vertical(id='action-confirm-dialog'):
yield Static(self._dialog_title, id='action-confirm-title', markup=False)
yield Static('\n'.join(self._dialog_lines), id='action-confirm-body', markup=False)
yield Static(TUI_COPY.build_action_confirm_hint(), id='action-confirm-hint', markup=False)
with Horizontal(id='action-confirm-actions'):
yield Button(TUI_COPY.build_action_confirm_cancel_label(), id='action-confirm-cancel')
yield Button(self._confirm_label, id='action-confirm-submit', variant='primary')
def on_mount(self) -> None:
"""
弹窗挂载后默认聚焦确认按钮。
:return: None
"""
self.call_after_refresh(self.query_one('#action-confirm-submit', Button).focus)
def action_cancel(self) -> None:
"""
取消并关闭弹窗。
:return: None
"""
self.dismiss(False)
def action_submit(self) -> None:
"""
通过键盘确认执行当前动作。
:return: None
"""
submit_button = self.query_one('#action-confirm-submit', Button)
submit_button.press()
@on(Button.Pressed, '#action-confirm-cancel')
def on_cancel_pressed(self) -> None:
"""
响应取消按钮。
:return: None
"""
self.dismiss(False)
@on(Button.Pressed, '#action-confirm-submit')
def on_submit_pressed(self) -> None:
"""
响应确认按钮。
:return: None
"""
self.dismiss(True)