Improve hand mode panels and recording
This commit is contained in:
83
src/ui.rs
83
src/ui.rs
@@ -7,7 +7,7 @@ use crate::{
|
||||
serial_core::serial::{SerialIoStats, SerialProtocol},
|
||||
style::{
|
||||
self, ACCENT_BLUE, ACCENT_GREEN, ACCENT_ORANGE, ACCENT_RED, METRICS, ONE_DARK_PRO,
|
||||
dim_text, group_frame, layout, panel_frame, tag_button,
|
||||
dim_text, group_frame, layout, panel_frame, rich_tag_button, tag_button,
|
||||
},
|
||||
utils::serial_enum,
|
||||
};
|
||||
@@ -196,7 +196,7 @@ pub fn draw_connect_panel(
|
||||
});
|
||||
|
||||
ui.add_space(METRICS.row_gap);
|
||||
draw_connect_action_row(ui, conn_state, is_connected, config, connection);
|
||||
draw_connect_action_row(ui, conn_state, is_connected, config, connection, recorder);
|
||||
|
||||
if is_connected {
|
||||
draw_recording_toolbar(ui, recorder, export_path);
|
||||
@@ -289,6 +289,7 @@ fn draw_connect_action_row(
|
||||
is_connected: bool,
|
||||
config: &ConnectPanelState,
|
||||
connection: &ConnectionManager,
|
||||
recorder: &Recorder,
|
||||
) {
|
||||
ui.horizontal(|ui| {
|
||||
let status_text = match conn_state {
|
||||
@@ -324,6 +325,7 @@ fn draw_connect_action_row(
|
||||
config.cols as u32,
|
||||
config.mode.baud_rate(),
|
||||
config.mode.protocol(),
|
||||
recorder.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -336,6 +338,7 @@ pub fn draw_config_panel(
|
||||
panel: &mut FloatingPanelState,
|
||||
config: &mut ConfigPanelState,
|
||||
connection: &ConnectionManager,
|
||||
recorder: &Recorder,
|
||||
) -> Option<SerialMode> {
|
||||
let mut changed_mode = None;
|
||||
let conn_state = connection.state();
|
||||
@@ -354,7 +357,7 @@ pub fn draw_config_panel(
|
||||
|
||||
// draw_mode_row(ui, config);
|
||||
ui.separator();
|
||||
draw_connection_row(ui, config, connection, conn_state);
|
||||
draw_connection_row(ui, config, connection, recorder, conn_state);
|
||||
ui.add_space(8.0);
|
||||
// Legacy serial parameter grid is intentionally kept commented for future hardware:
|
||||
// draw_serial_grid(ui, config);
|
||||
@@ -392,6 +395,7 @@ fn draw_connection_row(
|
||||
ui: &mut egui::Ui,
|
||||
config: &mut ConfigPanelState,
|
||||
connection: &ConnectionManager,
|
||||
recorder: &Recorder,
|
||||
conn_state: ConnectionState,
|
||||
) {
|
||||
ui.horizontal(|ui| {
|
||||
@@ -460,6 +464,7 @@ fn draw_connection_row(
|
||||
7,
|
||||
config.mode.baud_rate(),
|
||||
config.mode.protocol(),
|
||||
recorder.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -744,10 +749,13 @@ const FORCE_CHART_MAX_N: f32 = 25.6;
|
||||
const FORCE_CHART_SAMPLE_SECONDS: f32 = 0.1;
|
||||
const FORCE_PANEL_ACTIVE_TAIL: usize = 8;
|
||||
|
||||
const HAND_FORCE_PANEL_WIDTH: f32 = 260.0;
|
||||
const HAND_FORCE_PANEL_HEIGHT: f32 = 150.0;
|
||||
const HAND_FORCE_PANEL_MIN_WIDTH: f32 = 280.0;
|
||||
const HAND_FORCE_PANEL_MAX_WIDTH: f32 = 500.0;
|
||||
const HAND_FORCE_PANEL_MIN_HEIGHT: f32 = 140.0;
|
||||
const HAND_FORCE_PANEL_MAX_HEIGHT: f32 = 190.0;
|
||||
const HAND_FORCE_PANEL_GAP: f32 = 12.0;
|
||||
const HAND_FORCE_PANEL_BOTTOM_MARGIN: f32 = 24.0;
|
||||
const HAND_FORCE_PANEL_SIDE_MARGIN: f32 = 24.0;
|
||||
const HAND_FORCE_PANEL_VERTICAL_MARGIN: f32 = 28.0;
|
||||
const HAND_FORCE_PANEL_TITLES: [(&str, &str); 7] = [
|
||||
("T1", "拇指"),
|
||||
("T2", "食指"),
|
||||
@@ -772,29 +780,49 @@ pub fn draw_hand_force_panels(ctx: &egui::Context, visible: bool, histories: &[V
|
||||
.any(|history| has_recent_resultant_force(history));
|
||||
let target_visible = visible && hand_active;
|
||||
let screen = ctx.content_rect();
|
||||
let first_row_y = screen.bottom()
|
||||
- HAND_FORCE_PANEL_BOTTOM_MARGIN
|
||||
- HAND_FORCE_PANEL_HEIGHT * 2.0
|
||||
- HAND_FORCE_PANEL_GAP;
|
||||
let second_row_y = screen.bottom() - HAND_FORCE_PANEL_BOTTOM_MARGIN - HAND_FORCE_PANEL_HEIGHT;
|
||||
let side_width = ((screen.width() - HAND_FORCE_PANEL_SIDE_MARGIN * 4.0) * 0.25).max(0.0);
|
||||
let panel_width = side_width
|
||||
.min(HAND_FORCE_PANEL_MAX_WIDTH)
|
||||
.max(HAND_FORCE_PANEL_MIN_WIDTH.min(side_width));
|
||||
let left_x = screen.left() + HAND_FORCE_PANEL_SIDE_MARGIN;
|
||||
let right_x = screen.right() - HAND_FORCE_PANEL_SIDE_MARGIN - panel_width;
|
||||
let left_count = 4usize;
|
||||
let right_count = HAND_FORCE_PANEL_TITLES.len() - left_count;
|
||||
let available_height = (screen.height() - HAND_FORCE_PANEL_VERTICAL_MARGIN * 2.0).max(0.0);
|
||||
let panel_height = ((available_height - (left_count - 1) as f32 * HAND_FORCE_PANEL_GAP)
|
||||
/ left_count as f32)
|
||||
.clamp(
|
||||
HAND_FORCE_PANEL_MIN_HEIGHT.min(available_height),
|
||||
HAND_FORCE_PANEL_MAX_HEIGHT,
|
||||
);
|
||||
let left_height =
|
||||
left_count as f32 * panel_height + (left_count - 1) as f32 * HAND_FORCE_PANEL_GAP;
|
||||
let right_height = right_count as f32 * panel_height
|
||||
+ (right_count.saturating_sub(1)) as f32 * HAND_FORCE_PANEL_GAP;
|
||||
let left_top = screen.center().y - left_height * 0.5;
|
||||
let right_top = screen.center().y - right_height * 0.5;
|
||||
|
||||
for index in 0..HAND_FORCE_PANEL_TITLES.len() {
|
||||
let history = histories.get(index).map(Vec::as_slice).unwrap_or(&[]);
|
||||
let (code, title) = HAND_FORCE_PANEL_TITLES[index];
|
||||
let row_count: usize = if index < 4 { 4 } else { 3 };
|
||||
let row_index = if index < 4 { index } else { index - 4 };
|
||||
let total_width = row_count as f32 * HAND_FORCE_PANEL_WIDTH
|
||||
+ (row_count.saturating_sub(1)) as f32 * HAND_FORCE_PANEL_GAP;
|
||||
let row_left = screen.center().x - total_width * 0.5;
|
||||
let target_x =
|
||||
row_left + row_index as f32 * (HAND_FORCE_PANEL_WIDTH + HAND_FORCE_PANEL_GAP);
|
||||
let target_y = if index < 4 { first_row_y } else { second_row_y };
|
||||
let (target_x, target_y) = if index < left_count {
|
||||
(
|
||||
left_x,
|
||||
left_top + index as f32 * (panel_height + HAND_FORCE_PANEL_GAP),
|
||||
)
|
||||
} else {
|
||||
let right_index = index - left_count;
|
||||
(
|
||||
right_x,
|
||||
right_top + right_index as f32 * (panel_height + HAND_FORCE_PANEL_GAP),
|
||||
)
|
||||
};
|
||||
|
||||
draw_force_chart_area(
|
||||
ctx,
|
||||
egui::Id::new(format!("hand_force_panel_{index}")),
|
||||
egui::pos2(target_x, target_y),
|
||||
egui::vec2(HAND_FORCE_PANEL_WIDTH, HAND_FORCE_PANEL_HEIGHT),
|
||||
egui::vec2(panel_width, panel_height),
|
||||
target_visible,
|
||||
code,
|
||||
title,
|
||||
@@ -1079,7 +1107,10 @@ fn draw_floating_panel(
|
||||
.show(ctx, |ui| {
|
||||
ui.spacing_mut().item_spacing = egui::vec2(METRICS.item_gap, 6.0);
|
||||
ui.horizontal(|ui| {
|
||||
if ui.add(tag_button("隐藏")).clicked() {
|
||||
if ui
|
||||
.add(rich_tag_button("隐藏", style::ONE_DARK_PRO.text_dim))
|
||||
.clicked()
|
||||
{
|
||||
hide_requested = true;
|
||||
}
|
||||
ui.add_space(6.0);
|
||||
@@ -1685,7 +1716,10 @@ pub fn draw_matrix_config_panel(
|
||||
(48, 24, "48×24"),
|
||||
(64, 32, "64×32"),
|
||||
] {
|
||||
if ui.add(tag_button(*name)).clicked() {
|
||||
if ui
|
||||
.add(rich_tag_button(*name, style::ONE_DARK_PRO.text_dim))
|
||||
.clicked()
|
||||
{
|
||||
config.rows = *r;
|
||||
config.cols = *c;
|
||||
}
|
||||
@@ -1715,7 +1749,10 @@ pub fn draw_matrix_config_panel(
|
||||
|
||||
ui.add_space(METRICS.row_gap);
|
||||
|
||||
if ui.add(tag_button("重置默认")).clicked() {
|
||||
if ui
|
||||
.add(rich_tag_button("重置默认", style::ONE_DARK_PRO.text_dim))
|
||||
.clicked()
|
||||
{
|
||||
*config = MatrixConfigState::default();
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user