Files
HeurAMS/src/heurams/interface/widgets/basic_puzzle.py
T
2026-05-22 22:33:57 +08:00

119 lines
4.0 KiB
Python

from textual.containers import Horizontal, ScrollableContainer
from textual.message import Message
from textual.widget import Widget
from textual.widgets import Button, Label, Static
import heurams.kernel.particles as pt
from heurams.i18n import _
from .base_puzzle_widget import BasePuzzleWidget
class BasicEvaluation(BasePuzzleWidget):
def __init__(
self,
*children: Widget,
atom: pt.Atom,
alia: str = "",
name: str | None = None,
id: str | None = None,
classes: str | None = None,
disabled: bool = False,
markup: bool = True,
) -> None:
super().__init__(
*children,
atom=atom,
name=name,
id=id,
classes=classes,
disabled=disabled,
markup=markup,
)
class RatingChanged(Message):
def __init__(self, rating: int) -> None:
self.rating = rating # Rating value (0-5)
super().__init__()
# Feedback mapping
feedback_mapping = {
"feedback_5": {"rating": 5, "text": _("Perfect recall")},
"feedback_4": {"rating": 4, "text": _("Correct after hesitation")},
"feedback_3": {"rating": 3, "text": _("Correct with difficulty")},
"feedback_2": {"rating": 2, "text": _("Wrong but familiar")},
"feedback_1": {"rating": 1, "text": _("Wrong and unfamiliar")},
"feedback_0": {"rating": 0, "text": _("Complete blank")},
}
def compose(self):
# Show main content
yield Label(self.atom.registry["nucleon"]["content"], id="main")
# Show instruction (optional)
yield Static(_("Evaluate how well you remember this content: "), classes="instruction")
# Button container
with ScrollableContainer(id="button_container"):
btn = {}
btn["5"] = Button(
_("Perfect recall"), variant="success", id="feedback_5", classes="choice"
)
btn["4"] = Button(
_("Correct after hesitation"), variant="success", id="feedback_4", classes="choice"
)
btn["3"] = Button(
_("Correct with difficulty"), variant="warning", id="feedback_3", classes="choice"
)
btn["2"] = Button(
_("Wrong but familiar"), variant="warning", id="feedback_2", classes="choice"
)
btn["1"] = Button(
_("Wrong and unfamiliar"), variant="error", id="feedback_1", classes="choice"
)
btn["0"] = Button(
_("Complete blank"), variant="error", id="feedback_0", classes="choice"
)
# Layout buttons
yield Horizontal(btn["5"], btn["4"])
yield Horizontal(btn["3"], btn["2"])
yield Horizontal(btn["1"], btn["0"])
def on_button_pressed(self, event: Button.Pressed) -> None:
"""处理按钮点击事件"""
button_id = event.button.id
if button_id in self.feedback_mapping:
feedback_info = self.feedback_mapping[button_id]
self.post_message(
self.RatingChanged(
rating=feedback_info["rating"],
)
)
event.button.add_class("selected")
self.disable_other_buttons(button_id)
def disable_other_buttons(self, selected_button_id: str) -> None:
for button in self.query("Button.choice"):
if button.id != selected_button_id:
button.disabled = True
def enable_all_buttons(self) -> None:
for button in self.query("Button.choice"):
button.disabled = False
def on_key(self, event) -> None:
if event.key in ["0", "1", "2", "3", "4", "5"]:
button_id = f"feedback_{event.key}"
if button_id in self.feedback_mapping:
# 模拟按钮点击
self.post_message(
self.RatingChanged(
rating=self.feedback_mapping[button_id]["rating"],
)
)