use crate::app::config_manager::{AppConfig, LockscreenAuthMode};
use crate::lockscreen::auth::is_os_auth_compiled;
use crate::rendering::{Cell, Charset, Theme, VideoBuffer, render_shadow};
use crate::ui::simple_input::SimpleInput;
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum ConfigAction {
None,
#[allow(dead_code)]
Close,
ToggleAutoTiling,
ToggleTilingGaps,
ToggleShowDate,
CycleTheme,
CycleThemeBackward,
CycleBackgroundChar,
CycleBackgroundCharBackward,
CycleKeybindingProfile,
CycleKeybindingProfileBackward,
ToggleTintTerminal,
ToggleAutoSave,
TogglePersistMode,
ToggleLockscreen,
CycleLockscreenAuthMode,
SetupPin,
ToggleNetworkWidget,
#[allow(dead_code)]
EditNetworkInterface,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum ConfigOption {
AutoTiling,
TilingGaps,
ShowDate,
Theme,
KeybindingProfile,
BackgroundChar,
TintTerminal,
AutoSave,
PersistMode,
Lockscreen,
AuthMode,
PinSetup,
NetworkWidget,
}
pub struct ConfigWindow {
pub width: u16,
pub height: u16,
pub x: u16,
pub y: u16,
auto_arrange_row: u16, tiling_gaps_row: u16, show_date_row: u16, theme_row: u16, keybinding_profile_row: u16, background_char_row: u16, tint_terminal_row: u16, auto_save_row: u16, persist_mode_row: u16, lockscreen_row: u16, lockscreen_auth_row: u16, pin_setup_row: u16, status_widgets_header_row: u16, network_widget_row: u16, pub focused_option: Option<ConfigOption>, pub network_interface_input: Option<SimpleInput>, }
impl ConfigWindow {
pub fn new(buffer_width: u16, buffer_height: u16) -> Self {
let width = 60;
let height = 34;
let x = (buffer_width.saturating_sub(width)) / 2;
let y = (buffer_height.saturating_sub(height)) / 2;
let auto_arrange_row = y + 3; let tiling_gaps_row = y + 4; let show_date_row = y + 6; let theme_row = y + 8; let keybinding_profile_row = y + 10; let background_char_row = y + 12; let tint_terminal_row = y + 14; let auto_save_row = y + 16; let persist_mode_row = y + 18; let lockscreen_row = y + 20; let lockscreen_auth_row = y + 22; let pin_setup_row = y + 24; let status_widgets_header_row = y + 26; let network_widget_row = y + 28;
Self {
width,
height,
x,
y,
auto_arrange_row,
tiling_gaps_row,
show_date_row,
theme_row,
keybinding_profile_row,
background_char_row,
tint_terminal_row,
auto_save_row,
persist_mode_row,
lockscreen_row,
lockscreen_auth_row,
pin_setup_row,
status_widgets_header_row,
network_widget_row,
focused_option: Some(ConfigOption::AutoTiling),
network_interface_input: None,
}
}
pub fn is_editing_network_interface(&self) -> bool {
self.network_interface_input.is_some()
}
pub fn start_editing_network_interface(&mut self, current_value: &str) {
self.network_interface_input = Some(SimpleInput::new(current_value, 15));
}
pub fn stop_editing_network_interface(&mut self) -> Option<String> {
self.network_interface_input.take().map(|input| input.text)
}
pub fn cancel_editing_network_interface(&mut self) {
self.network_interface_input = None;
}
pub fn get_network_input_mut(&mut self) -> Option<&mut SimpleInput> {
self.network_interface_input.as_mut()
}
pub fn visible_options(&self, config: &AppConfig) -> Vec<ConfigOption> {
let mut options = vec![ConfigOption::AutoTiling, ConfigOption::TilingGaps];
options.push(ConfigOption::ShowDate);
options.push(ConfigOption::Theme);
options.push(ConfigOption::KeybindingProfile);
options.push(ConfigOption::BackgroundChar);
options.push(ConfigOption::TintTerminal);
options.push(ConfigOption::AutoSave);
options.push(ConfigOption::PersistMode);
options.push(ConfigOption::Lockscreen);
if config.lockscreen_enabled && is_os_auth_compiled() {
options.push(ConfigOption::AuthMode);
}
if config.lockscreen_enabled
&& (config.lockscreen_auth_mode == LockscreenAuthMode::Pin || !is_os_auth_compiled())
{
options.push(ConfigOption::PinSetup);
}
options.push(ConfigOption::NetworkWidget);
options
}
pub fn focus_next(&mut self, config: &AppConfig) {
let visible = self.visible_options(config);
if visible.is_empty() {
return;
}
self.focused_option = match self.focused_option {
None => Some(visible[0]),
Some(current) => {
if let Some(idx) = visible.iter().position(|&o| o == current) {
Some(visible[(idx + 1) % visible.len()])
} else {
Some(visible[0])
}
}
};
}
pub fn focus_previous(&mut self, config: &AppConfig) {
let visible = self.visible_options(config);
if visible.is_empty() {
return;
}
self.focused_option = match self.focused_option {
None => Some(visible[visible.len() - 1]),
Some(current) => {
if let Some(idx) = visible.iter().position(|&o| o == current) {
let new_idx = if idx == 0 { visible.len() - 1 } else { idx - 1 };
Some(visible[new_idx])
} else {
Some(visible[visible.len() - 1])
}
}
};
}
pub fn get_focused_action(&self) -> ConfigAction {
match self.focused_option {
Some(ConfigOption::AutoTiling) => ConfigAction::ToggleAutoTiling,
Some(ConfigOption::TilingGaps) => ConfigAction::ToggleTilingGaps,
Some(ConfigOption::ShowDate) => ConfigAction::ToggleShowDate,
Some(ConfigOption::Theme) => ConfigAction::CycleTheme,
Some(ConfigOption::KeybindingProfile) => ConfigAction::CycleKeybindingProfile,
Some(ConfigOption::BackgroundChar) => ConfigAction::CycleBackgroundChar,
Some(ConfigOption::TintTerminal) => ConfigAction::ToggleTintTerminal,
Some(ConfigOption::AutoSave) => ConfigAction::ToggleAutoSave,
Some(ConfigOption::PersistMode) => ConfigAction::TogglePersistMode,
Some(ConfigOption::Lockscreen) => ConfigAction::ToggleLockscreen,
Some(ConfigOption::AuthMode) => ConfigAction::CycleLockscreenAuthMode,
Some(ConfigOption::PinSetup) => ConfigAction::SetupPin,
Some(ConfigOption::NetworkWidget) => ConfigAction::ToggleNetworkWidget,
None => ConfigAction::None,
}
}
pub fn get_cycle_action(&self, forward: bool) -> ConfigAction {
match self.focused_option {
Some(ConfigOption::Theme) => {
if forward {
ConfigAction::CycleTheme
} else {
ConfigAction::CycleThemeBackward
}
}
Some(ConfigOption::KeybindingProfile) => {
if forward {
ConfigAction::CycleKeybindingProfile
} else {
ConfigAction::CycleKeybindingProfileBackward
}
}
Some(ConfigOption::BackgroundChar) => {
if forward {
ConfigAction::CycleBackgroundChar
} else {
ConfigAction::CycleBackgroundCharBackward
}
}
Some(ConfigOption::AuthMode) => ConfigAction::CycleLockscreenAuthMode,
_ => ConfigAction::None,
}
}
pub fn ensure_focus_valid(&mut self, config: &AppConfig) {
let visible = self.visible_options(config);
if let Some(current) = self.focused_option {
if !visible.contains(¤t) {
self.focused_option = visible.first().copied();
}
}
}
pub fn render(
&self,
buffer: &mut VideoBuffer,
charset: &Charset,
theme: &Theme,
config: &AppConfig,
tint_terminal: bool,
os_auth_available: bool,
) {
let title_bg = theme.config_title_bg;
let title_fg = theme.config_title_fg;
let border_color = theme.config_border;
let content_bg = theme.config_content_bg;
let top_left = charset.border_top_left();
let top_right = charset.border_top_right();
let bottom_left = charset.border_bottom_left();
let bottom_right = charset.border_bottom_right();
let horizontal = charset.border_horizontal();
let vertical = charset.border_vertical();
buffer.set(
self.x,
self.y,
Cell::new(top_left, border_color, content_bg),
);
let title = " Settings ";
let title_start = self.x + (self.width - title.len() as u16) / 2;
for x in 1..title_start - self.x {
buffer.set(
self.x + x,
self.y,
Cell::new(horizontal, border_color, content_bg),
);
}
for (i, ch) in title.chars().enumerate() {
buffer.set(
title_start + i as u16,
self.y,
Cell::new(ch, title_fg, title_bg),
);
}
let close_button_start = self.width - 5;
for x in (title_start + title.len() as u16 - self.x)..close_button_start {
buffer.set(
self.x + x,
self.y,
Cell::new(horizontal, border_color, content_bg),
);
}
buffer.set(
self.x + self.width - 5,
self.y,
Cell::new('[', border_color, content_bg),
);
buffer.set(
self.x + self.width - 4,
self.y,
Cell::new('X', crossterm::style::Color::Red, content_bg),
);
buffer.set(
self.x + self.width - 3,
self.y,
Cell::new(']', border_color, content_bg),
);
buffer.set(
self.x + self.width - 2,
self.y,
Cell::new(horizontal, border_color, content_bg),
);
buffer.set(
self.x + self.width - 1,
self.y,
Cell::new(top_right, border_color, content_bg),
);
for y in 1..(self.height - 1) {
buffer.set(
self.x,
self.y + y,
Cell::new(vertical, border_color, content_bg),
);
for x in 1..(self.width - 1) {
buffer.set(
self.x + x,
self.y + y,
Cell::new(' ', theme.config_content_fg, content_bg),
);
}
buffer.set(
self.x + self.width - 1,
self.y + y,
Cell::new(vertical, border_color, content_bg),
);
}
buffer.set(
self.x,
self.y + self.height - 1,
Cell::new(bottom_left, border_color, content_bg),
);
for x in 1..(self.width - 1) {
buffer.set(
self.x + x,
self.y + self.height - 1,
Cell::new(horizontal, border_color, content_bg),
);
}
buffer.set(
self.x + self.width - 1,
self.y + self.height - 1,
Cell::new(bottom_right, border_color, content_bg),
);
self.render_option(
buffer,
self.auto_arrange_row,
"On startup Auto Tiling:",
config.auto_tiling_on_startup,
charset,
theme,
self.focused_option == Some(ConfigOption::AutoTiling),
);
self.render_option(
buffer,
self.tiling_gaps_row,
"Window gaps:",
config.tiling_gaps,
charset,
theme,
self.focused_option == Some(ConfigOption::TilingGaps),
);
self.render_option(
buffer,
self.show_date_row,
"Show Date in clock:",
config.show_date_in_clock,
charset,
theme,
self.focused_option == Some(ConfigOption::ShowDate),
);
self.render_theme_selector(
buffer,
self.theme_row,
&config.theme,
theme,
self.focused_option == Some(ConfigOption::Theme),
);
self.render_keybinding_profile_selector(
buffer,
self.keybinding_profile_row,
&config.keybinding_profile,
theme,
self.focused_option == Some(ConfigOption::KeybindingProfile),
);
self.render_background_char_selector(
buffer,
self.background_char_row,
config,
theme,
self.focused_option == Some(ConfigOption::BackgroundChar),
);
self.render_option(
buffer,
self.tint_terminal_row,
"Tint terminal content:",
tint_terminal,
charset,
theme,
self.focused_option == Some(ConfigOption::TintTerminal),
);
self.render_option(
buffer,
self.auto_save_row,
"Auto-save session on exit:",
config.auto_save,
charset,
theme,
self.focused_option == Some(ConfigOption::AutoSave),
);
self.render_option(
buffer,
self.persist_mode_row,
"Persist mode (daemon):",
config.persist_enabled,
charset,
theme,
self.focused_option == Some(ConfigOption::PersistMode),
);
self.render_option(
buffer,
self.lockscreen_row,
"Lockscreen (Shift+Q):",
config.lockscreen_enabled,
charset,
theme,
self.focused_option == Some(ConfigOption::Lockscreen),
);
if config.lockscreen_enabled && is_os_auth_compiled() {
self.render_auth_mode_selector(
buffer,
self.lockscreen_auth_row,
config.lockscreen_auth_mode,
os_auth_available,
theme,
self.focused_option == Some(ConfigOption::AuthMode),
);
}
if config.lockscreen_enabled
&& (config.lockscreen_auth_mode == LockscreenAuthMode::Pin || !is_os_auth_compiled())
{
self.render_pin_setup_button(
buffer,
self.pin_setup_row,
config.has_pin_configured(),
theme,
self.focused_option == Some(ConfigOption::PinSetup),
);
}
self.render_section_header(
buffer,
self.status_widgets_header_row,
"Status Bar Widgets",
theme,
);
self.render_network_widget_option(
buffer,
self.network_widget_row,
config.network_widget_enabled,
&config.network_interface,
charset,
theme,
self.focused_option == Some(ConfigOption::NetworkWidget),
);
let instruction = "Up/Down: navigate | Enter: select | ESC: close";
let instruction_x = self.x + (self.width - instruction.len() as u16) / 2;
let instruction_y = self.y + self.height - 2;
for (i, ch) in instruction.chars().enumerate() {
buffer.set(
instruction_x + i as u16,
instruction_y,
Cell::new(ch, theme.config_instructions_fg, content_bg),
);
}
render_shadow(
buffer,
self.x,
self.y,
self.width,
self.height,
charset,
theme,
);
}
#[allow(clippy::too_many_arguments)]
fn render_option(
&self,
buffer: &mut VideoBuffer,
row: u16,
label: &str,
enabled: bool,
charset: &Charset,
theme: &Theme,
focused: bool,
) {
let (fg, bg) = if focused {
(theme.config_content_bg, theme.config_content_fg)
} else {
(theme.config_content_fg, theme.config_content_bg)
};
let option_x = self.x + 2;
let indicator = if focused { '>' } else { ' ' };
buffer.set(self.x + 1, row, Cell::new(indicator, fg, bg));
for (i, ch) in label.chars().enumerate() {
buffer.set(option_x + i as u16, row, Cell::new(ch, fg, bg));
}
let toggle_x = option_x + label.len() as u16 + 1;
if enabled {
let toggle_on = format!("[{} on]", charset.block());
for (i, ch) in toggle_on.chars().enumerate() {
let color = if i == 1 {
theme.config_toggle_on_color
} else {
fg
}; buffer.set(toggle_x + i as u16, row, Cell::new(ch, color, bg));
}
} else {
let toggle_off = format!("[off {}]", charset.shade());
for (i, ch) in toggle_off.chars().enumerate() {
let color = if i == 4 {
theme.config_toggle_off_color
} else {
fg
}; buffer.set(toggle_x + i as u16, row, Cell::new(ch, color, bg));
}
}
}
fn render_theme_selector(
&self,
buffer: &mut VideoBuffer,
row: u16,
current_theme: &str,
theme: &Theme,
focused: bool,
) {
let (fg, bg) = if focused {
(theme.config_content_bg, theme.config_content_fg)
} else {
(theme.config_content_fg, theme.config_content_bg)
};
let option_x = self.x + 2;
let indicator = if focused { '>' } else { ' ' };
buffer.set(self.x + 1, row, Cell::new(indicator, fg, bg));
let label = "Theme:";
for (i, ch) in label.chars().enumerate() {
buffer.set(option_x + i as u16, row, Cell::new(ch, fg, bg));
}
let theme_display = match current_theme {
"classic" => "Classic",
"monochrome" => "Monochrome",
"dark" => "Dark",
"dracu" => "Dracu",
"green_phosphor" => "Green Phosphor",
"amber" => "Amber",
"ndd" => "NDD",
"qbasic" => "QBasic",
"turbo" => "TurboP",
"norton_commander" => "NCC",
"xtree" => "XT",
"wordperfect" => "WP",
"dbase" => "dB",
"system" => "System",
_ => "Classic",
};
let selector_x = option_x + label.len() as u16 + 2;
let selector_text = format!("< {} >", theme_display);
for (i, ch) in selector_text.chars().enumerate() {
buffer.set(selector_x + i as u16, row, Cell::new(ch, fg, bg));
}
}
fn render_keybinding_profile_selector(
&self,
buffer: &mut VideoBuffer,
row: u16,
current_profile: &str,
theme: &Theme,
focused: bool,
) {
use crate::input::keybinding_profile::KeybindingProfile;
let (fg, bg) = if focused {
(theme.config_content_bg, theme.config_content_fg)
} else {
(theme.config_content_fg, theme.config_content_bg)
};
let option_x = self.x + 2;
let indicator = if focused { '>' } else { ' ' };
buffer.set(self.x + 1, row, Cell::new(indicator, fg, bg));
let label = "Keybindings:";
for (i, ch) in label.chars().enumerate() {
buffer.set(option_x + i as u16, row, Cell::new(ch, fg, bg));
}
let display_name = KeybindingProfile::display_name(current_profile);
let selector_x = option_x + label.len() as u16 + 2;
let selector_text = format!("< {} >", display_name);
for (i, ch) in selector_text.chars().enumerate() {
buffer.set(selector_x + i as u16, row, Cell::new(ch, fg, bg));
}
}
fn render_background_char_selector(
&self,
buffer: &mut VideoBuffer,
row: u16,
config: &AppConfig,
theme: &Theme,
focused: bool,
) {
let (fg, bg) = if focused {
(theme.config_content_bg, theme.config_content_fg)
} else {
(theme.config_content_fg, theme.config_content_bg)
};
let option_x = self.x + 2;
let indicator = if focused { '>' } else { ' ' };
buffer.set(self.x + 1, row, Cell::new(indicator, fg, bg));
let label = "Background character:";
for (i, ch) in label.chars().enumerate() {
buffer.set(option_x + i as u16, row, Cell::new(ch, fg, bg));
}
let char_name = config.get_background_char_name();
let char_sample = config.get_background_char();
let selector_x = option_x + label.len() as u16 + 2;
let selector_text = format!("< {} [{}] >", char_name, char_sample);
for (i, ch) in selector_text.chars().enumerate() {
buffer.set(selector_x + i as u16, row, Cell::new(ch, fg, bg));
}
}
fn render_auth_mode_selector(
&self,
buffer: &mut VideoBuffer,
row: u16,
mode: LockscreenAuthMode,
os_auth_available: bool,
theme: &Theme,
focused: bool,
) {
let (fg, bg) = if focused {
(theme.config_content_bg, theme.config_content_fg)
} else {
(theme.config_content_fg, theme.config_content_bg)
};
let option_x = self.x + 2;
let indicator = if focused { '>' } else { ' ' };
buffer.set(self.x + 1, row, Cell::new(indicator, fg, bg));
let label = "Auth mode:";
for (i, ch) in label.chars().enumerate() {
buffer.set(option_x + i as u16, row, Cell::new(ch, fg, bg));
}
let mode_text = match mode {
LockscreenAuthMode::OsAuth => {
if os_auth_available {
"< OS Auth >"
} else {
"< OS Auth (unavail) >"
}
}
LockscreenAuthMode::Pin => "< PIN >",
};
let selector_x = option_x + label.len() as u16 + 2;
for (i, ch) in mode_text.chars().enumerate() {
buffer.set(selector_x + i as u16, row, Cell::new(ch, fg, bg));
}
}
fn render_pin_setup_button(
&self,
buffer: &mut VideoBuffer,
row: u16,
has_pin: bool,
theme: &Theme,
focused: bool,
) {
let (fg, bg) = if focused {
(theme.config_content_bg, theme.config_content_fg)
} else {
(theme.config_content_fg, theme.config_content_bg)
};
let option_x = self.x + 2;
let indicator = if focused { '>' } else { ' ' };
buffer.set(self.x + 1, row, Cell::new(indicator, fg, bg));
let (button_text, status_text) = if has_pin {
("[ Change PIN ]", " PIN is configured")
} else {
("[ Set PIN ]", " PIN required to enable")
};
for (i, ch) in button_text.chars().enumerate() {
buffer.set(
option_x + i as u16,
row,
Cell::new(ch, theme.config_toggle_on_color, bg),
);
}
let status_x = option_x + button_text.len() as u16;
for (i, ch) in status_text.chars().enumerate() {
buffer.set(status_x + i as u16, row, Cell::new(ch, fg, bg));
}
}
fn render_section_header(
&self,
buffer: &mut VideoBuffer,
row: u16,
title: &str,
theme: &Theme,
) {
let fg = theme.config_content_fg;
let bg = theme.config_content_bg;
let padding_left = "─── ";
let padding_right = " ───";
let header = format!("{}{}{}", padding_left, title, padding_right);
let header_x = self.x + 2;
for (i, ch) in header.chars().enumerate() {
buffer.set(header_x + i as u16, row, Cell::new(ch, fg, bg));
}
}
#[allow(clippy::too_many_arguments)]
fn render_network_widget_option(
&self,
buffer: &mut VideoBuffer,
row: u16,
enabled: bool,
interface: &str,
charset: &Charset,
theme: &Theme,
focused: bool,
) {
let is_editing = self.network_interface_input.is_some();
let (fg, bg) = if focused && !is_editing {
(theme.config_content_bg, theme.config_content_fg)
} else {
(theme.config_content_fg, theme.config_content_bg)
};
let option_x = self.x + 2;
let indicator = if focused && !is_editing { '>' } else { ' ' };
buffer.set(self.x + 1, row, Cell::new(indicator, fg, bg));
let label = "Network widget:";
for (i, ch) in label.chars().enumerate() {
buffer.set(option_x + i as u16, row, Cell::new(ch, fg, bg));
}
let toggle_x = option_x + label.len() as u16 + 1;
if enabled {
let toggle_on = format!("[{} on]", charset.block());
for (i, ch) in toggle_on.chars().enumerate() {
let color = if i == 1 {
theme.config_toggle_on_color
} else {
fg
};
buffer.set(toggle_x + i as u16, row, Cell::new(ch, color, bg));
}
} else {
let toggle_off = format!("[off {}]", charset.shade());
for (i, ch) in toggle_off.chars().enumerate() {
let color = if i == 4 {
theme.config_toggle_off_color
} else {
fg
};
buffer.set(toggle_x + i as u16, row, Cell::new(ch, color, bg));
}
}
let interface_x = toggle_x + 8; let field_width = 17u16;
if let Some(ref input) = self.network_interface_input {
input.render(buffer, interface_x, row, field_width, theme, true);
} else {
let interface_display = if interface.is_empty() {
"(not set)".to_string()
} else {
interface.to_string()
};
let padded = format!("[{:<15}]", interface_display);
for (i, ch) in padded.chars().enumerate() {
buffer.set(interface_x + i as u16, row, Cell::new(ch, fg, bg));
}
}
}
pub fn is_close_button_click(&self, x: u16, y: u16) -> bool {
y == self.y && x >= self.x + self.width - 5 && x <= self.x + self.width - 3
}
pub fn handle_click(&self, x: u16, y: u16, config: &AppConfig) -> ConfigAction {
if self.is_close_button_click(x, y) {
return ConfigAction::Close;
}
if y == self.auto_arrange_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::ToggleAutoTiling;
}
}
if y == self.tiling_gaps_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::ToggleTilingGaps;
}
}
if y == self.show_date_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::ToggleShowDate;
}
}
if y == self.theme_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::CycleTheme;
}
}
if y == self.keybinding_profile_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::CycleKeybindingProfile;
}
}
if y == self.background_char_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::CycleBackgroundChar;
}
}
if y == self.tint_terminal_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::ToggleTintTerminal;
}
}
if y == self.auto_save_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::ToggleAutoSave;
}
}
if y == self.persist_mode_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::TogglePersistMode;
}
}
if y == self.lockscreen_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::ToggleLockscreen;
}
}
if config.lockscreen_enabled && is_os_auth_compiled() && y == self.lockscreen_auth_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::CycleLockscreenAuthMode;
}
}
if config.lockscreen_enabled
&& (config.lockscreen_auth_mode == LockscreenAuthMode::Pin || !is_os_auth_compiled())
&& y == self.pin_setup_row
{
if x >= self.x && x < self.x + self.width {
return ConfigAction::SetupPin;
}
}
if y == self.network_widget_row {
if x >= self.x && x < self.x + self.width {
return ConfigAction::ToggleNetworkWidget;
}
}
ConfigAction::None
}
pub fn contains_point(&self, x: u16, y: u16) -> bool {
x >= self.x && x < self.x + self.width && y >= self.y && y < self.y + self.height
}
}