diff options
Diffstat (limited to 'src/oneroll/tui.py')
| -rw-r--r-- | src/oneroll/tui.py | 95 |
1 files changed, 50 insertions, 45 deletions
diff --git a/src/oneroll/tui.py b/src/oneroll/tui.py index 9e4e4c9..fa0eb09 100644 --- a/src/oneroll/tui.py +++ b/src/oneroll/tui.py @@ -16,91 +16,91 @@ from datetime import datetime from . import OneRoll, roll, roll_statistics, CommonRolls + class RollResult(Message): """Throw result message""" - + def __init__(self, result: Dict[str, Any], expression: str) -> None: self.result = result self.expression = expression super().__init__() + class ExpressionInput(Input): """Expression input box""" - + def __init__(self) -> None: super().__init__( - placeholder="输入骰子表达式,如 3d6 + 2", - id="expression_input" + placeholder="输入骰子表达式,如 3d6 + 2", id="expression_input" ) - + def on_key(self, event) -> None: if event.key == "enter": self.post_message(RollResult(roll(self.value), self.value)) self.value = "" + class QuickRollButton(Button): """Quick Throw Button""" - + def __init__(self, label: str, expression: str) -> None: self.expression = expression super().__init__(label, id=f"quick_{expression}") - + def on_button_pressed(self) -> None: self.post_message(RollResult(roll(self.expression), self.expression)) + class RollHistory(DataTable): """Throw History Table""" - + def __init__(self) -> None: super().__init__() self.add_columns("时间", "表达式", "总点数", "详情") - + def add_roll(self, result: Dict[str, Any], expression: str) -> None: """Add throw record""" time_str = datetime.now().strftime("%H:%M:%S") - self.add_row( - time_str, - expression, - str(result["total"]), - result["details"] - ) + self.add_row(time_str, expression, str(result["total"]), result["details"]) # keep table at bottom self.scroll_end() + class StatisticsPanel(Static): """Statistics Panel""" - + def __init__(self) -> None: super().__init__("统计功能", id="stats_panel") - + def show_statistics(self, expression: str, times: int = 100) -> None: """Show statistics information""" try: stats = roll_statistics(expression, times) stats_text = f""" -统计结果: {expression} (投掷 {stats['count']} 次) +统计结果: {expression} (投掷 {stats["count"]} 次) -最小值: {stats['min']} -最大值: {stats['max']} -平均值: {stats['mean']:.2f} -总和: {stats['total']} +最小值: {stats["min"]} +最大值: {stats["max"]} +平均值: {stats["mean"]:.2f} +总和: {stats["total"]} """ self.update(stats_text) except Exception as e: self.update(f"统计错误: {e}") + class RollDisplay(Static): - """The throwing result shows """ - + """The throwing result shows""" + def __init__(self) -> None: super().__init__("等待投掷...", id="roll_display") - + def show_result(self, result: Dict[str, Any], expression: str) -> None: """Display throwing result""" total = result["total"] details = result["details"] rolls = result["rolls"] - + # a kind of color selection based on result if total >= 15: color = "green" @@ -108,7 +108,7 @@ class RollDisplay(Static): color = "yellow" else: color = "red" - + display_text = f"""[bold blue]🎲 {expression}[/bold blue] [bold]总点数:[/bold] [bold {color}]{total}[/bold {color}] @@ -119,13 +119,16 @@ class RollDisplay(Static): # show the comment comment = result.get("comment", "") if comment: - display_text += f"\n\n[bold]注释:[/bold] [italic blue]{comment}[/italic blue]" - + display_text += ( + f"\n\n[bold]注释:[/bold] [italic blue]{comment}[/italic blue]" + ) + self.update(display_text) + class OneRollTUI(App): """OneRoll 终端用户界面""" - + CSS = """ Screen { layout: vertical; @@ -163,14 +166,14 @@ class OneRollTUI(App): margin: 1; } """ - + def compose(self) -> ComposeResult: """UI components""" yield Header() - + with Container(): yield ExpressionInput() - + with Horizontal(classes="quick_buttons"): yield QuickRollButton("D20", CommonRolls.D20) yield QuickRollButton("优势", CommonRolls.D20_ADVANTAGE) @@ -178,35 +181,35 @@ class OneRollTUI(App): yield QuickRollButton("属性", CommonRolls.ATTRIBUTE_ROLL) yield QuickRollButton("3D6", "3d6") yield QuickRollButton("2D6", "2d6") - + yield RollDisplay() - + with Tabs(): with Tab("历史记录", id="history_tab"): yield RollHistory(id="history_table") - + with Tab("统计", id="stats_tab"): yield StatisticsPanel() - + yield Footer() - + def on_mount(self) -> None: """Initialization during interface mount""" self.title = "OneRoll 骰子投掷器" self.sub_title = "高性能骰子表达式解析器" - + # Set focus to the input box self.query_one(ExpressionInput).focus() - + def on_roll_result(self, message: RollResult) -> None: # display result roll_display = self.query_one(RollDisplay) roll_display.show_result(message.result, message.expression) - + # add history history_table = self.query_one(RollHistory) history_table.add_roll(message.result, message.expression) - + def on_key(self, event) -> None: if event.key == "ctrl+q": self.exit() @@ -214,7 +217,7 @@ class OneRollTUI(App): self.show_help() elif event.key == "ctrl+s": self.show_statistics() - + def show_help(self) -> None: help_text = """ OneRoll 骰子投掷器 @@ -237,15 +240,17 @@ OneRoll 骰子投掷器 • Ctrl+S - 显示统计 • Enter - 执行投掷 """ - + self.notify(help_text, title="帮助信息", timeout=10) - + def show_statistics(self) -> None: self.notify("统计功能开发中...", title="统计") + def run_tui(): app = OneRollTUI() app.run() + if __name__ == "__main__": run_tui() |
