feat: JE-Skin 功能迁移 — One Dark Pro 工业风 + 录制导出
## One Dark Pro 主题 - 替换 ENGINEERING_DARK → ONE_DARK_PRO (#282C34 背景, #C678DD 紫色强调) - 新增 ACCENT_GREEN/RED/BLUE/CYAN/ORANGE 独立色彩常量 ## 录制模块 (recording.rs — 新建) - 全量录制 + 快照录制两种模式 - 暂停/恢复/停止状态管理 - CSV 导出 (channel1,...,channelN,timestamp_ms) - CSV 导入回放 - 线程安全 Arc<Mutex<>> - 4 个单元测试 ## 新 UI 组件 (ui.rs — +343 行) - draw_signal_chart: 实时信号火花图 (min/max/current) - draw_recording_toolbar: 录制控制栏 (全量/快照/暂停/导出/导入) - draw_export_panel: 浮动录制导出面板 - draw_matrix_config_panel: 矩阵配置 (行/列/色域/预设 12x7~64x32) - 连接面板集成录制工具栏 (连接后自动显示) ## 应用集成 (app.rs) - 集成 Recorder, 信号历史, 导出面板, 矩阵配置面板 - 每帧数据自动送入录制器 - 信号历史环形缓冲 (128 帧)
This commit is contained in:
55
src/theme.rs
55
src/theme.rs
@@ -15,20 +15,27 @@ pub struct AppTheme {
|
||||
pub radius: u8,
|
||||
}
|
||||
|
||||
pub const ENGINEERING_DARK: AppTheme = AppTheme {
|
||||
bg: egui::Color32::from_rgb(33, 35, 44),
|
||||
panel: egui::Color32::from_rgb(25, 36, 48),
|
||||
panel_strong: egui::Color32::from_rgb(47, 58, 70),
|
||||
panel_deep: egui::Color32::from_rgb(14, 18, 24),
|
||||
border: egui::Color32::from_rgb(53, 75, 92),
|
||||
border_soft: egui::Color32::from_rgb(36, 53, 66),
|
||||
text: egui::Color32::from_rgb(242, 246, 252),
|
||||
text_dim: egui::Color32::from_rgb(206, 216, 230),
|
||||
accent: egui::Color32::from_rgb(255, 118, 47),
|
||||
accent_hot: egui::Color32::from_rgb(255, 169, 77),
|
||||
radius: 2,
|
||||
pub const ONE_DARK_PRO: AppTheme = AppTheme {
|
||||
bg: egui::Color32::from_rgb(40, 44, 52), // #282C34 editor background
|
||||
panel: egui::Color32::from_rgb(33, 37, 43), // #21252B sidebar/darker
|
||||
panel_strong: egui::Color32::from_rgb(44, 49, 58), // #2C313A slightly lighter
|
||||
panel_deep: egui::Color32::from_rgb(27, 31, 39), // #1B1F27 darkest
|
||||
border: egui::Color32::from_rgb(62, 68, 81), // #3E4451 border
|
||||
border_soft: egui::Color32::from_rgb(44, 49, 58), // #2C313A soft border
|
||||
text: egui::Color32::from_rgb(171, 178, 191), // #ABB2BF default text
|
||||
text_dim: egui::Color32::from_rgb(92, 99, 112), // #5C6370 dimmed text
|
||||
accent: egui::Color32::from_rgb(198, 120, 221), // #C678DD purple (signature)
|
||||
accent_hot: egui::Color32::from_rgb(229, 192, 123), // #E5C07B yellow/gold
|
||||
radius: 3,
|
||||
};
|
||||
|
||||
// Additional One Dark Pro accent colors (standalone constants)
|
||||
pub const ACCENT_GREEN: egui::Color32 = egui::Color32::from_rgb(152, 195, 121); // #98C379
|
||||
pub const ACCENT_RED: egui::Color32 = egui::Color32::from_rgb(224, 108, 117); // #E06C75
|
||||
pub const ACCENT_BLUE: egui::Color32 = egui::Color32::from_rgb(97, 175, 239); // #61AFEF
|
||||
pub const ACCENT_CYAN: egui::Color32 = egui::Color32::from_rgb(86, 182, 194); // #56B6C2
|
||||
pub const ACCENT_ORANGE: egui::Color32 = egui::Color32::from_rgb(209, 154, 102); // #D19A66
|
||||
|
||||
pub fn apply_theme(ctx: &egui::Context, theme: &AppTheme) {
|
||||
let mut visuals = egui::Visuals::dark();
|
||||
visuals.override_text_color = Some(theme.text);
|
||||
@@ -39,7 +46,7 @@ pub fn apply_theme(ctx: &egui::Context, theme: &AppTheme) {
|
||||
visuals.faint_bg_color = theme.panel_strong;
|
||||
visuals.code_bg_color = theme.panel_deep;
|
||||
visuals.warn_fg_color = theme.accent_hot;
|
||||
visuals.error_fg_color = egui::Color32::from_rgb(255, 98, 82);
|
||||
visuals.error_fg_color = ACCENT_RED;
|
||||
|
||||
visuals.widgets.noninteractive.bg_fill = theme.panel_strong;
|
||||
visuals.widgets.noninteractive.bg_stroke = egui::Stroke::new(1.0, theme.border_soft);
|
||||
@@ -47,13 +54,13 @@ pub fn apply_theme(ctx: &egui::Context, theme: &AppTheme) {
|
||||
visuals.widgets.inactive.bg_fill = theme.panel_strong;
|
||||
visuals.widgets.inactive.bg_stroke = egui::Stroke::new(1.0, theme.border_soft);
|
||||
visuals.widgets.inactive.fg_stroke = egui::Stroke::new(1.0, theme.text);
|
||||
visuals.widgets.hovered.bg_fill = egui::Color32::from_rgb(58, 69, 82);
|
||||
visuals.widgets.hovered.bg_fill = egui::Color32::from_rgb(55, 61, 72);
|
||||
visuals.widgets.hovered.bg_stroke = egui::Stroke::new(1.0, theme.border);
|
||||
visuals.widgets.hovered.fg_stroke = egui::Stroke::new(1.0, theme.text);
|
||||
visuals.widgets.active.bg_fill = theme.accent;
|
||||
visuals.widgets.active.bg_stroke = egui::Stroke::new(1.0, theme.accent_hot);
|
||||
visuals.widgets.active.fg_stroke = egui::Stroke::new(1.0, egui::Color32::WHITE);
|
||||
visuals.widgets.open.bg_fill = egui::Color32::from_rgb(43, 55, 68);
|
||||
visuals.widgets.open.bg_fill = egui::Color32::from_rgb(50, 56, 66);
|
||||
visuals.widgets.open.bg_stroke = egui::Stroke::new(1.0, theme.border);
|
||||
visuals.widgets.open.fg_stroke = egui::Stroke::new(1.0, theme.text);
|
||||
|
||||
@@ -126,9 +133,9 @@ pub fn apply_fonts(ctx: &egui::Context) {
|
||||
pub fn panel_frame(ctx: &egui::Context) -> egui::Frame {
|
||||
let style = ctx.global_style();
|
||||
egui::Frame::window(&style)
|
||||
.fill(ENGINEERING_DARK.panel)
|
||||
.stroke(egui::Stroke::new(1.0, ENGINEERING_DARK.border))
|
||||
.corner_radius(egui::CornerRadius::same(ENGINEERING_DARK.radius))
|
||||
.fill(ONE_DARK_PRO.panel)
|
||||
.stroke(egui::Stroke::new(1.0, ONE_DARK_PRO.border))
|
||||
.corner_radius(egui::CornerRadius::same(ONE_DARK_PRO.radius))
|
||||
.shadow(egui::epaint::Shadow {
|
||||
offset: [0, 12],
|
||||
blur: 26,
|
||||
@@ -139,23 +146,23 @@ pub fn panel_frame(ctx: &egui::Context) -> egui::Frame {
|
||||
|
||||
pub fn group_frame() -> egui::Frame {
|
||||
egui::Frame::new()
|
||||
.fill(ENGINEERING_DARK.panel_deep)
|
||||
.stroke(egui::Stroke::new(1.0, ENGINEERING_DARK.border_soft))
|
||||
.fill(ONE_DARK_PRO.panel_deep)
|
||||
.stroke(egui::Stroke::new(1.0, ONE_DARK_PRO.border_soft))
|
||||
.corner_radius(egui::CornerRadius::same(2))
|
||||
.inner_margin(egui::Margin::symmetric(6, 5))
|
||||
}
|
||||
|
||||
pub fn tag_button(label: impl Into<egui::WidgetText>) -> egui::Button<'static> {
|
||||
egui::Button::new(label)
|
||||
.fill(ENGINEERING_DARK.panel_strong)
|
||||
.stroke(egui::Stroke::new(1.0, ENGINEERING_DARK.border))
|
||||
.fill(ONE_DARK_PRO.panel_strong)
|
||||
.stroke(egui::Stroke::new(1.0, ONE_DARK_PRO.border))
|
||||
.corner_radius(egui::CornerRadius::same(2))
|
||||
}
|
||||
|
||||
pub fn dim_text() -> egui::Color32 {
|
||||
ENGINEERING_DARK.text_dim
|
||||
ONE_DARK_PRO.text_dim
|
||||
}
|
||||
|
||||
pub fn accent_text() -> egui::Color32 {
|
||||
ENGINEERING_DARK.accent_hot
|
||||
ONE_DARK_PRO.accent_hot
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user