129 lines
3.3 KiB
Python
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)
|