refactor: TUI 布局重构 — 经典三行:状态栏 + 主显示区 + 固定底部输入
布局改为 grid-rows: auto 1fr 3: - Row 1 (auto): 系统监控 + 插件状态 紧凑状态栏 - Row 2 (1fr): 合并日志/消息为单一可滚动主显示区 - Row 3 (3 lines): 固定高度输入栏,始终可见 同时: - 移除 Header/Footer 节省空间 - show_message 路由到 log_display - 清理未使用的 message_display 分离逻辑 - 移除未使用的 reactive/Horizontal imports Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
+33
-101
@@ -6,9 +6,8 @@ import sys
|
|||||||
import io
|
import io
|
||||||
import time
|
import time
|
||||||
from textual.app import App
|
from textual.app import App
|
||||||
from textual.containers import Container, ScrollableContainer, Horizontal
|
from textual.containers import Container, ScrollableContainer
|
||||||
from textual.widgets import Static, Input, Header, Footer, LoadingIndicator
|
from textual.widgets import Static, Input
|
||||||
from textual.reactive import reactive
|
|
||||||
from textual.suggester import Suggester
|
from textual.suggester import Suggester
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -552,105 +551,46 @@ class TUIFramework(App):
|
|||||||
|
|
||||||
|
|
||||||
def _generate_css(self):
|
def _generate_css(self):
|
||||||
"""根据配置动态生成CSS - 增强版"""
|
"""动态生成 CSS — 经典三行布局:状态栏 + 主内容 + 固定底部输入"""
|
||||||
try:
|
return """
|
||||||
tui_config = self.config.get('tui', {})
|
|
||||||
layout_config = tui_config.get('layout', {})
|
|
||||||
styles_config = tui_config.get('styles', {})
|
|
||||||
|
|
||||||
# 获取布局配置,使用默认值
|
|
||||||
grid_rows = layout_config.get('grid_rows', '7fr 2fr 1fr')
|
|
||||||
|
|
||||||
# 获取样式配置,使用默认值
|
|
||||||
log_area_style = styles_config.get('log_area', 'border: solid green; overflow-y: auto;')
|
|
||||||
message_area_style = styles_config.get('message_area', 'border: solid yellow; overflow-y: auto;')
|
|
||||||
input_area_style = styles_config.get('input_area', 'border: solid red;')
|
|
||||||
|
|
||||||
css = f"""
|
|
||||||
Screen {{
|
|
||||||
layout: grid;
|
|
||||||
grid-size: 1 3;
|
|
||||||
grid-rows: {grid_rows};
|
|
||||||
}}
|
|
||||||
|
|
||||||
#log-area {{
|
|
||||||
{log_area_style}
|
|
||||||
overflow-y: auto;
|
|
||||||
scrollbar-size: 1 1;
|
|
||||||
}}
|
|
||||||
|
|
||||||
#message-area {{
|
|
||||||
{message_area_style}
|
|
||||||
overflow-y: auto;
|
|
||||||
scrollbar-size: 1 1;
|
|
||||||
}}
|
|
||||||
|
|
||||||
#input-area {{
|
|
||||||
{input_area_style}
|
|
||||||
}}
|
|
||||||
|
|
||||||
/* 自定义滚动条样式 */
|
|
||||||
ScrollableContainer {{
|
|
||||||
scrollbar-color: #666 #222;
|
|
||||||
scrollbar-color-hover: #888 #333;
|
|
||||||
overflow-y: auto;
|
|
||||||
}}
|
|
||||||
|
|
||||||
/* 确保内容正确换行 */
|
|
||||||
Static {{
|
|
||||||
width: 100%;
|
|
||||||
content-align: left middle;
|
|
||||||
overflow-y: auto;
|
|
||||||
}}
|
|
||||||
"""
|
|
||||||
logger.debug(f"生成的TUI CSS:\n{css}")
|
|
||||||
return css
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logger.error(f"生成TUI CSS时出错: {str(e)}", exc_info=True)
|
|
||||||
# 返回默认CSS作为回退
|
|
||||||
return """
|
|
||||||
Screen {
|
Screen {
|
||||||
layout: grid;
|
layout: grid;
|
||||||
grid-size: 1 3;
|
grid-size: 1 3;
|
||||||
grid-rows: 7fr 2fr 1fr;
|
grid-rows: auto 1fr 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
#log-area {
|
#monitor-area {
|
||||||
border: solid green;
|
height: 2;
|
||||||
overflow-y: auto;
|
padding: 0 1;
|
||||||
scrollbar-size: 1 1;
|
background: $panel;
|
||||||
|
color: $text;
|
||||||
}
|
}
|
||||||
|
|
||||||
#message-area {
|
#main-area {
|
||||||
border: solid yellow;
|
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
scrollbar-size: 1 1;
|
scrollbar-size: 1 1;
|
||||||
|
border: solid $primary;
|
||||||
}
|
}
|
||||||
|
|
||||||
#input-area {
|
#input-area {
|
||||||
border: solid red;
|
height: 3;
|
||||||
|
border: solid $secondary;
|
||||||
|
padding: 0 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 自定义滚动条样式 */
|
|
||||||
ScrollableContainer {
|
ScrollableContainer {
|
||||||
scrollbar-color: #666 #222;
|
scrollbar-color: #666 #222;
|
||||||
scrollbar-color-hover: #888 #333;
|
scrollbar-color-hover: #888 #333;
|
||||||
overflow-y: auto;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 确保内容正确换行 */
|
|
||||||
Static {
|
Static {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
content-align: left middle;
|
content-align: left top;
|
||||||
overflow-y: auto;
|
|
||||||
}
|
}
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def compose(self):
|
def compose(self):
|
||||||
"""组合界面"""
|
"""组合界面 — 状态栏 / 主显示区(日志+消息) / 底部输入栏"""
|
||||||
yield Header()
|
|
||||||
yield Container(
|
yield Container(
|
||||||
self.system_monitor,
|
self.system_monitor,
|
||||||
self.plugin_panel,
|
self.plugin_panel,
|
||||||
@@ -658,23 +598,18 @@ class TUIFramework(App):
|
|||||||
)
|
)
|
||||||
yield ScrollableContainer(
|
yield ScrollableContainer(
|
||||||
self.log_display,
|
self.log_display,
|
||||||
id="log-area"
|
id="main-area",
|
||||||
)
|
|
||||||
yield ScrollableContainer(
|
|
||||||
self.message_display,
|
|
||||||
id="message-area"
|
|
||||||
)
|
)
|
||||||
self.command_suggester = CommandSuggester(self.command_service)
|
self.command_suggester = CommandSuggester(self.command_service)
|
||||||
self.command_input = Input(
|
self.command_input = Input(
|
||||||
placeholder="输入指令... Tab 补全",
|
placeholder="🐱 输入指令... Tab 补全",
|
||||||
suggester=self.command_suggester,
|
suggester=self.command_suggester,
|
||||||
id="command-input",
|
id="command-input",
|
||||||
)
|
)
|
||||||
yield Container(
|
yield Container(
|
||||||
self.command_input,
|
self.command_input,
|
||||||
id="input-area"
|
id="input-area",
|
||||||
)
|
)
|
||||||
yield Footer()
|
|
||||||
|
|
||||||
async def on_mount(self):
|
async def on_mount(self):
|
||||||
"""挂载完成事件"""
|
"""挂载完成事件"""
|
||||||
@@ -720,16 +655,21 @@ class TUIFramework(App):
|
|||||||
self.show_message(f"指令处理错误: {str(e)}", "error")
|
self.show_message(f"指令处理错误: {str(e)}", "error")
|
||||||
|
|
||||||
def show_message(self, message: str, msg_type: str = "info", persistent: bool = False):
|
def show_message(self, message: str, msg_type: str = "info", persistent: bool = False):
|
||||||
"""显示消息"""
|
"""显示消息到主显示区(log_display)"""
|
||||||
try:
|
try:
|
||||||
self.message_display.add_message(message, msg_type, persistent)
|
prefix = {"info": "ℹ️", "success": "✅", "error": "❌", "warning": "⚠️",
|
||||||
|
"command": "▶️", "debug": "🔍"}.get(msg_type, "📝")
|
||||||
|
for line in message.strip().split("\n"):
|
||||||
|
if line.strip():
|
||||||
|
self.log_display.add_log_line(f"{prefix} {line.strip()}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"❌ 显示TUI消息时出错: {str(e)}")
|
print(f"❌ 显示TUI消息时出错: {str(e)}")
|
||||||
|
|
||||||
def clear_messages(self, clear_persistent: bool = False):
|
def clear_messages(self, clear_persistent: bool = False):
|
||||||
"""清空消息区域"""
|
"""清空主显示区"""
|
||||||
try:
|
try:
|
||||||
self.message_display.clear_messages(clear_persistent)
|
self.log_display.log_lines.clear()
|
||||||
|
self.log_display.update("")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"❌ 清空消息时出错: {str(e)}")
|
print(f"❌ 清空消息时出错: {str(e)}")
|
||||||
|
|
||||||
@@ -853,13 +793,9 @@ class TuiService:
|
|||||||
|
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
if target in ["all", "log"]:
|
if target in ["all", "log", "message"]:
|
||||||
log_state = self.tui_app.log_display.toggle_auto_scroll(enabled)
|
log_state = self.tui_app.log_display.toggle_auto_scroll(enabled)
|
||||||
result.append(f"📜 日志自动滚动: {'✅ 启用' if log_state else '❌ 禁用'}")
|
result.append(f"📜 自动滚动: {'✅ 启用' if log_state else '❌ 禁用'}")
|
||||||
|
|
||||||
if target in ["all", "message"]:
|
|
||||||
msg_state = self.tui_app.message_display.toggle_auto_scroll(enabled)
|
|
||||||
result.append(f"💬 消息自动滚动: {'✅ 启用' if msg_state else '❌ 禁用'}")
|
|
||||||
|
|
||||||
return "\n".join(result)
|
return "\n".join(result)
|
||||||
|
|
||||||
@@ -874,13 +810,9 @@ class TuiService:
|
|||||||
|
|
||||||
result = []
|
result = []
|
||||||
|
|
||||||
if target in ["all", "log"]:
|
if target in ["all", "log", "message"]:
|
||||||
self.tui_app.log_display.scroll_to_bottom()
|
self.tui_app.log_display.scroll_to_bottom()
|
||||||
result.append("📜 日志区域已滚动到底部")
|
result.append("📜 已滚动到底部")
|
||||||
|
|
||||||
if target in ["all", "message"]:
|
|
||||||
self.tui_app.message_display.scroll_to_bottom()
|
|
||||||
result.append("💬 消息区域已滚动到底部")
|
|
||||||
|
|
||||||
return "\n".join(result)
|
return "\n".join(result)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user