feat(interface): 改进仪表盘
This commit is contained in:
@@ -1,12 +1,15 @@
|
||||
from typing import Type
|
||||
from time import sleep
|
||||
print("欢迎使用基本用户界面!")
|
||||
print("加载配置... ", end="", flush=True)
|
||||
from heurams.context import *
|
||||
print("已完成!")
|
||||
|
||||
print("加载用户界面框架... ", end="", flush=True)
|
||||
from textual.app import App
|
||||
from textual.driver import Driver
|
||||
from textual.widgets import Button
|
||||
print("已完成!")
|
||||
|
||||
from heurams.context import config_var
|
||||
from heurams.services.logger import get_logger
|
||||
|
||||
print("加载用户界面布局... ", end="", flush=True)
|
||||
from .screens.about import AboutScreen
|
||||
from .screens.dashboard import DashboardScreen
|
||||
from .screens.llmchat import LLMChatScreen
|
||||
@@ -16,27 +19,9 @@ from .screens.radio import RadioScreen
|
||||
from .screens.repocreator import RepoCreatorScreen
|
||||
from .screens.repoeditor import RepoEditorScreen
|
||||
from .screens.synctool import SyncScreen
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
|
||||
def environment_check():
|
||||
from pathlib import Path
|
||||
|
||||
logger.debug("检查环境路径")
|
||||
subdir = ["cache/voice", "repo", "global", "config"]
|
||||
for i in subdir:
|
||||
i = Path(config_var.get()["paths"]["data"]) / i
|
||||
if not i.exists():
|
||||
logger.info("创建目录: %s", i)
|
||||
print(f"创建 {i}")
|
||||
i.mkdir(exist_ok=True, parents=True)
|
||||
else:
|
||||
logger.debug("目录已存在: %s", i)
|
||||
print(f"找到 {i}")
|
||||
logger.debug("环境检查完成")
|
||||
|
||||
|
||||
print("已完成!")
|
||||
print(f"组件目录: {rootdir}")
|
||||
print(f"工作目录: {workdir}")
|
||||
class HeurAMSApp(App):
|
||||
TITLE = "潜进"
|
||||
CSS_PATH = "css/main.tcss"
|
||||
@@ -61,7 +46,6 @@ class HeurAMSApp(App):
|
||||
}
|
||||
|
||||
def on_mount(self) -> None:
|
||||
environment_check()
|
||||
self.push_screen("dashboard")
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
from textual.app import App
|
||||
from textual.widgets import Button
|
||||
|
||||
from heurams.interface import *
|
||||
from heurams.context import config_var
|
||||
from heurams.interface import HeurAMSApp
|
||||
from heurams.services.logger import get_logger
|
||||
|
||||
from .screens.about import AboutScreen
|
||||
from .screens.dashboard import DashboardScreen
|
||||
from .screens.precache import PrecachingScreen
|
||||
from .screens.repocreator import RepoCreatorScreen
|
||||
|
||||
logger = get_logger(__name__)
|
||||
|
||||
def environment_check():
|
||||
from pathlib import Path
|
||||
|
||||
logger.debug("检查环境路径")
|
||||
subdir = ["cache/voice", "repo", "global", "config"]
|
||||
for i in subdir:
|
||||
i = Path(config_var.get()["paths"]["data"]) / i
|
||||
if not i.exists():
|
||||
logger.info("创建目录: %s", i)
|
||||
print(f"创建 {i}")
|
||||
i.mkdir(exist_ok=True, parents=True)
|
||||
else:
|
||||
logger.debug("目录已存在: %s", i)
|
||||
print(f"找到 {i}")
|
||||
logger.debug("环境检查完成")
|
||||
|
||||
def main():
|
||||
environment_check()
|
||||
app = HeurAMSApp()
|
||||
app.run()
|
||||
app.run(inline=False)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,7 +1,20 @@
|
||||
|
||||
|
||||
NavigatorScreen {
|
||||
align: center middle;
|
||||
}
|
||||
|
||||
|
||||
.repo_listitem {
|
||||
layout: grid;
|
||||
grid-size: 2;
|
||||
}
|
||||
|
||||
.repo_listitem_btn {
|
||||
dock: right;
|
||||
offset: -5% 0
|
||||
}
|
||||
|
||||
#dialog {
|
||||
grid-size: 2;
|
||||
grid-gutter: 1 1;
|
||||
@@ -40,6 +53,10 @@ LLMChatScreen {
|
||||
background: $surface;
|
||||
}
|
||||
|
||||
#dashboardtop {
|
||||
height: 4
|
||||
}
|
||||
|
||||
#input-container {
|
||||
height: 3;
|
||||
margin-top: 1;
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
"""仪表盘界面"""
|
||||
|
||||
from functools import reduce
|
||||
import pathlib
|
||||
from pathlib import Path
|
||||
|
||||
from textual.app import ComposeResult
|
||||
from textual.containers import ScrollableContainer
|
||||
from textual.containers import ScrollableContainer, Container, Horizontal, Vertical
|
||||
from textual.screen import Screen
|
||||
from textual.widgets import Button, Footer, Header, Label, ListItem, ListView, Static
|
||||
from textual.layouts import horizontal
|
||||
|
||||
import heurams.kernel.particles as pt
|
||||
import heurams.services.timer as timer
|
||||
@@ -42,21 +44,35 @@ class DashboardScreen(Screen):
|
||||
self.repostat = {}
|
||||
self.title2dirname = {}
|
||||
self.title2repo = {}
|
||||
self.dirname2repo = {}
|
||||
self._load_data()
|
||||
|
||||
def compose(self) -> ComposeResult:
|
||||
"""组合界面组件"""
|
||||
yield Header(show_clock=True)
|
||||
yield ScrollableContainer(
|
||||
Label('欢迎使用 "潜进" 启发式辅助记忆调度器', classes="title-label"),
|
||||
Label(
|
||||
f"当前 UNIX 日时间戳: {timer.get_daystamp()} (UTC+{config_var.get()['timezone_offset'] / 3600})"
|
||||
),
|
||||
Label(f"全局算法设置: {config_var.get()['algorithm']['default']}"),
|
||||
Label("选择待学习或待修改的项目:", classes="title-label"),
|
||||
ListView(id="repo-list", classes="repo-list-view"),
|
||||
Label(f'"潜进" 启发式辅助记忆调度器 版本 {version.ver} '),
|
||||
)
|
||||
with ScrollableContainer():
|
||||
yield Horizontal(
|
||||
Vertical(
|
||||
Label('欢迎使用 "潜进" 启发式辅助记忆调度器'),
|
||||
Label(
|
||||
f"当前 UNIX 日时间戳: {timer.get_daystamp()} (UTC+{config_var.get()['timezone_offset'] / 3600})"
|
||||
),
|
||||
Label(f"全局算法设置: {config_var.get()['algorithm']['default']}"),
|
||||
Label("选择待学习或待修改的项目:"),
|
||||
classes="column",
|
||||
),
|
||||
Vertical(
|
||||
Label(f"已加载 {len(self.repostat)} 个单元集", classes='dataview'),
|
||||
Label(f"共计 {reduce(lambda x, y: x + y, map(lambda x: x.get('unit_sum'), self.repostat.values()))} 个单元", classes='dataview'),
|
||||
Label(f"已激活 {reduce(lambda x, y: x + y, map(lambda x: x.get('activated_sum'), self.repostat.values()))} 个单元", classes='dataview'),
|
||||
Label(""),
|
||||
classes="column",
|
||||
),
|
||||
id="dashboardtop"
|
||||
)
|
||||
|
||||
yield ListView(id="repo-list", classes="repo-list-view")
|
||||
yield Label(f'"潜进" 启发式辅助记忆调度器 版本 {version.ver} ')
|
||||
yield Footer()
|
||||
|
||||
def _load_data(self):
|
||||
@@ -105,6 +121,7 @@ class DashboardScreen(Screen):
|
||||
self.repostat[dirname] = stat
|
||||
self.title2dirname[title] = dirname
|
||||
self.title2repo[title] = repo
|
||||
self.dirname2repo[dirname] = repo
|
||||
|
||||
def on_mount(self) -> None:
|
||||
"""挂载组件时初始化"""
|
||||
@@ -132,7 +149,7 @@ class DashboardScreen(Screen):
|
||||
|
||||
for repotitle in repotitles:
|
||||
prompt = self.repostat[self.title2dirname[repotitle]]["prompt"]
|
||||
list_item = ListItem(Label(prompt))
|
||||
list_item = ListItem(Label(prompt), Button(f"开始学习", flat=True, variant="primary", classes="repo_listitem_btn", id=f"launch_{self.repostat[self.title2dirname[repotitle]]['dirname']}"), classes="repo_listitem")
|
||||
repo_list_widget.append(list_item)
|
||||
|
||||
# if not self.stay_enabled[repodir]:
|
||||
@@ -169,6 +186,9 @@ class DashboardScreen(Screen):
|
||||
self.app.push_screen(NavigatorScreen())
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
logger.debug(f"event.button.id: {event.button.id}")
|
||||
"""处理按钮点击事件"""
|
||||
if event.button.id == "navigator-button":
|
||||
self.action_open_navigator()
|
||||
if str(event.button.id).startswith("launch_"): # type: ignore
|
||||
from .preparation import launch
|
||||
launch(repo=self.dirname2repo[event.button.id[7:]], app=self.app, scheduled_num=-1) # type: ignore
|
||||
# TODO: 这样启动的记忆实例的状态机无法绑定到 PreparationScreen 中
|
||||
@@ -123,36 +123,41 @@ class PreparationScreen(Screen):
|
||||
event.stop()
|
||||
logger.debug("按下按钮")
|
||||
if event.button.id == "start_memorizing_button":
|
||||
atoms = list()
|
||||
for i in self.repo.ident_index:
|
||||
n = pt.Nucleon.create_on_nucleonic_data(
|
||||
nucleonic_data=self.repo.nucleonic_data_lict.get_itemic_unit(i)
|
||||
)
|
||||
e = pt.Electron.create_on_electonic_data(
|
||||
electronic_data=self.repo.electronic_data_lict.get_itemic_unit(i)
|
||||
)
|
||||
a = pt.Atom(n, e, self.repo.orbitic_data)
|
||||
atoms.append(a)
|
||||
|
||||
atoms_to_provide = list()
|
||||
left_new = self.scheduled_num
|
||||
for i in atoms:
|
||||
i: pt.Atom
|
||||
if i.registry["electron"].is_activated():
|
||||
if i.registry["electron"].is_due():
|
||||
atoms_to_provide.append(i)
|
||||
else:
|
||||
left_new -= 1
|
||||
if left_new >= 0:
|
||||
atoms_to_provide.append(i)
|
||||
import heurams.kernel.reactor as rt
|
||||
|
||||
from .memoqueue import MemScreen
|
||||
|
||||
pheser = rt.Phaser(atoms_to_provide)
|
||||
save_func = self.repo.persist_to_repodir
|
||||
memscreen = MemScreen(pheser, save_func, repo=self.repo)
|
||||
self.app.push_screen(memscreen)
|
||||
launch(repo=self.repo, app=self.app, scheduled_num=self.scheduled_num)
|
||||
|
||||
elif event.button.id == "precache_button":
|
||||
self.action_precache()
|
||||
|
||||
def launch(repo, app, scheduled_num):
|
||||
if scheduled_num == -1:
|
||||
scheduled_num = config_var.get()["scheduled_num"]
|
||||
atoms = list()
|
||||
for i in repo.ident_index:
|
||||
n = pt.Nucleon.create_on_nucleonic_data(
|
||||
nucleonic_data=repo.nucleonic_data_lict.get_itemic_unit(i)
|
||||
)
|
||||
e = pt.Electron.create_on_electonic_data(
|
||||
electronic_data=repo.electronic_data_lict.get_itemic_unit(i)
|
||||
)
|
||||
a = pt.Atom(n, e, repo.orbitic_data)
|
||||
atoms.append(a)
|
||||
|
||||
atoms_to_provide = list()
|
||||
left_new = scheduled_num
|
||||
for i in atoms:
|
||||
i: pt.Atom
|
||||
if i.registry["electron"].is_activated():
|
||||
if i.registry["electron"].is_due():
|
||||
atoms_to_provide.append(i)
|
||||
else:
|
||||
left_new -= 1
|
||||
if left_new >= 0:
|
||||
atoms_to_provide.append(i)
|
||||
import heurams.kernel.reactor as rt
|
||||
|
||||
from .memoqueue import MemScreen
|
||||
|
||||
pheser = rt.Phaser(atoms_to_provide)
|
||||
save_func = repo.persist_to_repodir
|
||||
memscreen = MemScreen(pheser, save_func, repo=repo)
|
||||
app.push_screen(memscreen)
|
||||
|
||||
@@ -5,7 +5,7 @@ from typing import TypedDict
|
||||
from textual.containers import Container
|
||||
from textual.message import Message
|
||||
from textual.widget import Widget
|
||||
from textual.widgets import Button, Label
|
||||
from textual.widgets import Button, Label, Markdown
|
||||
|
||||
import heurams.kernel.particles as pt
|
||||
import heurams.kernel.puzzles as pz
|
||||
@@ -66,7 +66,7 @@ class ClozePuzzle(BasePuzzleWidget):
|
||||
|
||||
def compose(self):
|
||||
yield Label(self.puzzle.wording, id="sentence")
|
||||
yield Label(f"当前输入: {self.inputlist}", id="inputpreview")
|
||||
yield Markdown(f"> {self.listprint(self.inputlist)}", id="inputpreview")
|
||||
# 渲染当前问题的选项
|
||||
with Container(id="btn-container"):
|
||||
for i in self.ans:
|
||||
@@ -77,9 +77,18 @@ class ClozePuzzle(BasePuzzleWidget):
|
||||
|
||||
yield Button("退格", id="delete")
|
||||
|
||||
def listprint(self, lst):
|
||||
s = ""
|
||||
if lst:
|
||||
lastone = lst[-1]
|
||||
for i in lst[:-1]:
|
||||
s += (i + ' ')
|
||||
s += f" `{lastone}`"
|
||||
return s
|
||||
|
||||
def update_display(self):
|
||||
preview = self.query_one("#inputpreview")
|
||||
preview.update(f"当前输入: {self.inputlist}") # type: ignore
|
||||
preview.update(f"> {self.listprint(self.inputlist)}") # type: ignore
|
||||
|
||||
def on_button_pressed(self, event: Button.Pressed) -> None:
|
||||
button_id = event.button.id
|
||||
|
||||
@@ -67,9 +67,7 @@ class Recognition(BasePuzzleWidget):
|
||||
f";{delim}": ";",
|
||||
f":{delim}": ":",
|
||||
}
|
||||
|
||||
nucleon = self.atom.registry["nucleon"]
|
||||
metadata = self.atom.registry["nucleon"]
|
||||
|
||||
primary = cfg["primary"]
|
||||
|
||||
with Center():
|
||||
|
||||
Reference in New Issue
Block a user