pub const PANEL_PROFILES: [&str; 2] = ["ground_station", "visor"];
pub fn has_panel(profile: &str) -> bool {
PANEL_PROFILES.contains(&profile)
}
pub const PASSTHROUGH: &str = "passthrough";
pub const SHUTDOWN_PROMPT: &str = "shutdown_prompt";
pub const PREV_SCREEN: &str = "prev_screen";
pub const PLUGIN_SCREEN_PREFIX: &str = "plugin:";
pub const CAPTURE_HUD_SCREEN: &str = "plugin:capture_hud";
pub const GROUND_STATION_BUTTONS: [(&str, &str); 8] = [
("B1_short", "cycle_screen"),
("B1_long", "toggle_backlight"),
("B2_short", "show_network"),
("B2_long", "show_qr"),
("B3_short", "confirm"),
("B3_long", "pair_drone"),
("B4_short", "back"),
("B4_long", "menu"),
];
pub const VISOR_BUTTONS: [(&str, &str); 8] = [
("B1_short", PASSTHROUGH),
("B1_long", SHUTDOWN_PROMPT),
("B2_short", PASSTHROUGH),
("B2_long", PASSTHROUGH),
("B3_short", "cycle_screen"),
("B3_long", PASSTHROUGH),
("B4_short", "back"),
("B4_long", PASSTHROUGH),
];
pub const ENCODER_BUTTONS: [(&str, &str); 4] = [
("ENC_CW_short", "cycle_screen"),
("ENC_CCW_short", PREV_SCREEN),
("ENC_SW_short", "confirm"),
("ENC_SW_long", "back"),
];
pub const GROUND_STATION_SCREENS: [&str; 9] = [
"home", "link", "drone", "network", "system", "qr", "gnss", "radios", "lora",
];
pub const VISOR_SCREENS: [&str; 5] = [CAPTURE_HUD_SCREEN, "cameras", "sensors", "storage", "about"];
pub fn default_buttons(profile: &str) -> &'static [(&'static str, &'static str)] {
if profile == "visor" {
&VISOR_BUTTONS
} else {
&GROUND_STATION_BUTTONS
}
}
pub fn default_screens(profile: &str) -> &'static [&'static str] {
if profile == "visor" {
&VISOR_SCREENS
} else {
&GROUND_STATION_SCREENS
}
}
pub fn plugin_screen_name(screen: &str) -> Option<&str> {
screen
.strip_prefix(PLUGIN_SCREEN_PREFIX)
.filter(|name| !name.is_empty())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn visor_defaults_match_the_capture_layout() {
let map: std::collections::HashMap<_, _> =
default_buttons("visor").iter().copied().collect();
assert_eq!(map["B1_short"], PASSTHROUGH);
assert_eq!(map["B2_short"], PASSTHROUGH);
assert_eq!(map["B3_short"], "cycle_screen");
assert_eq!(map["B4_short"], "back");
assert_eq!(map["B1_long"], SHUTDOWN_PROMPT);
assert_eq!(
default_screens("visor"),
[
"plugin:capture_hud",
"cameras",
"sensors",
"storage",
"about"
]
);
}
#[test]
fn ground_station_defaults_keep_their_map_and_add_the_new_screens() {
let map: std::collections::HashMap<_, _> =
default_buttons("ground_station").iter().copied().collect();
assert_eq!(map["B1_short"], "cycle_screen");
assert_eq!(map.len(), 8);
assert!(default_screens("ground_station").ends_with(&["gnss", "radios", "lora"]));
assert_eq!(default_buttons("drone"), default_buttons("ground_station"));
}
#[test]
fn plugin_screen_ids_resolve_their_name() {
assert_eq!(plugin_screen_name(CAPTURE_HUD_SCREEN), Some("capture_hud"));
assert_eq!(plugin_screen_name("plugin:"), None);
assert_eq!(plugin_screen_name("cameras"), None);
assert!(has_panel("visor") && has_panel("ground_station") && !has_panel("drone"));
}
#[test]
fn encoder_defaults_mirror_the_screen_carousel_and_never_shadow_a_button() {
let map: std::collections::HashMap<_, _> = ENCODER_BUTTONS.iter().copied().collect();
assert_eq!(map["ENC_CW_short"], "cycle_screen");
assert_eq!(map["ENC_CCW_short"], PREV_SCREEN);
assert_eq!(map["ENC_SW_short"], "confirm");
assert_eq!(map["ENC_SW_long"], "back");
for profile in PANEL_PROFILES {
let buttons = default_buttons(profile);
assert!(ENCODER_BUTTONS
.iter()
.all(|(key, _)| buttons.iter().all(|(b, _)| b != key)));
}
}
}