All checks were successful
Deploy Website / deploy (push) Has been skipped
165 lines
4.0 KiB
Rust
165 lines
4.0 KiB
Rust
use super::CyclicEnum;
|
|
|
|
#[derive(Clone, Copy, PartialEq, Eq, Default)]
|
|
pub enum OptionsFocus {
|
|
#[default]
|
|
ColorScheme,
|
|
HueRotation,
|
|
RefreshRate,
|
|
RuntimeHighlight,
|
|
ShowScope,
|
|
ShowSpectrum,
|
|
ShowLissajous,
|
|
GainBoost,
|
|
NormalizeViz,
|
|
ShowCompletion,
|
|
ShowPreview,
|
|
PerformanceMode,
|
|
Font,
|
|
ZoomFactor,
|
|
WindowSize,
|
|
ResetOnboarding,
|
|
LoadDemoOnStartup,
|
|
}
|
|
|
|
impl CyclicEnum for OptionsFocus {
|
|
const VARIANTS: &'static [Self] = &[
|
|
Self::ColorScheme,
|
|
Self::HueRotation,
|
|
Self::RefreshRate,
|
|
Self::RuntimeHighlight,
|
|
Self::ShowScope,
|
|
Self::ShowSpectrum,
|
|
Self::ShowLissajous,
|
|
Self::GainBoost,
|
|
Self::NormalizeViz,
|
|
Self::ShowCompletion,
|
|
Self::ShowPreview,
|
|
Self::PerformanceMode,
|
|
Self::Font,
|
|
Self::ZoomFactor,
|
|
Self::WindowSize,
|
|
Self::ResetOnboarding,
|
|
Self::LoadDemoOnStartup,
|
|
];
|
|
}
|
|
|
|
const PLUGIN_ONLY: &[OptionsFocus] = &[
|
|
OptionsFocus::Font,
|
|
OptionsFocus::ZoomFactor,
|
|
OptionsFocus::WindowSize,
|
|
];
|
|
|
|
/// Section layout: header line, divider line, then option lines.
|
|
const FULL_LAYOUT: &[(OptionsFocus, usize)] = &[
|
|
// DISPLAY section: header=0, divider=1
|
|
(OptionsFocus::ColorScheme, 2),
|
|
(OptionsFocus::HueRotation, 3),
|
|
(OptionsFocus::RefreshRate, 4),
|
|
(OptionsFocus::RuntimeHighlight, 5),
|
|
(OptionsFocus::ShowScope, 6),
|
|
(OptionsFocus::ShowSpectrum, 7),
|
|
(OptionsFocus::ShowLissajous, 8),
|
|
(OptionsFocus::GainBoost, 9),
|
|
(OptionsFocus::NormalizeViz, 10),
|
|
(OptionsFocus::ShowCompletion, 11),
|
|
(OptionsFocus::ShowPreview, 12),
|
|
(OptionsFocus::PerformanceMode, 13),
|
|
(OptionsFocus::Font, 14),
|
|
(OptionsFocus::ZoomFactor, 15),
|
|
(OptionsFocus::WindowSize, 16),
|
|
// blank=17, ONBOARDING header=18, divider=19
|
|
(OptionsFocus::ResetOnboarding, 20),
|
|
(OptionsFocus::LoadDemoOnStartup, 21),
|
|
];
|
|
|
|
impl OptionsFocus {
|
|
fn is_plugin_only(self) -> bool {
|
|
PLUGIN_ONLY.contains(&self)
|
|
}
|
|
|
|
fn is_visible(self, plugin_mode: bool) -> bool {
|
|
if self.is_plugin_only() && !plugin_mode {
|
|
return false;
|
|
}
|
|
true
|
|
}
|
|
|
|
pub fn line_index(self, plugin_mode: bool) -> usize {
|
|
visible_layout(plugin_mode)
|
|
.iter()
|
|
.find(|(f, _)| *f == self)
|
|
.map(|(_, l)| *l)
|
|
.unwrap_or(0)
|
|
}
|
|
|
|
pub fn at_line(line: usize, plugin_mode: bool) -> Option<OptionsFocus> {
|
|
visible_layout(plugin_mode)
|
|
.iter()
|
|
.find(|(_, l)| *l == line)
|
|
.map(|(f, _)| *f)
|
|
}
|
|
}
|
|
|
|
/// Total number of rendered lines for the options view.
|
|
pub fn total_lines(plugin_mode: bool) -> usize {
|
|
visible_layout(plugin_mode)
|
|
.last()
|
|
.map(|(_, l)| *l + 1)
|
|
.unwrap_or(0)
|
|
}
|
|
|
|
fn visible_layout(plugin_mode: bool) -> Vec<(OptionsFocus, usize)> {
|
|
let mut offset: usize = 0;
|
|
|
|
// Font/Zoom/Window lines (14,15,16) hidden when !plugin_mode
|
|
if !plugin_mode {
|
|
offset += 3;
|
|
}
|
|
|
|
let mut result = Vec::new();
|
|
for &(focus, raw_line) in FULL_LAYOUT {
|
|
if !focus.is_visible(plugin_mode) {
|
|
continue;
|
|
}
|
|
let adjusted = if raw_line <= 13 {
|
|
raw_line
|
|
} else if !plugin_mode && raw_line <= 16 {
|
|
continue;
|
|
} else {
|
|
raw_line - offset
|
|
};
|
|
result.push((focus, adjusted));
|
|
}
|
|
result
|
|
}
|
|
|
|
#[derive(Default)]
|
|
pub struct OptionsState {
|
|
pub focus: OptionsFocus,
|
|
}
|
|
|
|
impl OptionsState {
|
|
pub fn next_focus(&mut self, plugin_mode: bool) {
|
|
let mut f = self.focus;
|
|
loop {
|
|
f = f.next();
|
|
if f.is_visible(plugin_mode) {
|
|
break;
|
|
}
|
|
}
|
|
self.focus = f;
|
|
}
|
|
|
|
pub fn prev_focus(&mut self, plugin_mode: bool) {
|
|
let mut f = self.focus;
|
|
loop {
|
|
f = f.prev();
|
|
if f.is_visible(plugin_mode) {
|
|
break;
|
|
}
|
|
}
|
|
self.focus = f;
|
|
}
|
|
}
|