aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/oneroll/tui.py
diff options
context:
space:
mode:
Diffstat (limited to 'src/oneroll/tui.py')
-rw-r--r--src/oneroll/tui.py95
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()