Clean plugins
This commit is contained in:
@@ -56,9 +56,31 @@ impl CyclicEnum for OptionsFocus {
|
||||
];
|
||||
}
|
||||
|
||||
// Line indices when Font/ZoomFactor are shown (plugin mode).
|
||||
// In terminal mode, Font/ZoomFactor are absent; all lines after ShowPreview shift up by 2.
|
||||
const FOCUS_LINES: &[(OptionsFocus, usize)] = &[
|
||||
const PLUGIN_ONLY: &[OptionsFocus] = &[
|
||||
OptionsFocus::Font,
|
||||
OptionsFocus::ZoomFactor,
|
||||
OptionsFocus::WindowSize,
|
||||
];
|
||||
|
||||
const STANDALONE_ONLY: &[OptionsFocus] = &[
|
||||
OptionsFocus::LinkEnabled,
|
||||
OptionsFocus::StartStopSync,
|
||||
OptionsFocus::Quantum,
|
||||
OptionsFocus::MidiOutput0,
|
||||
OptionsFocus::MidiOutput1,
|
||||
OptionsFocus::MidiOutput2,
|
||||
OptionsFocus::MidiOutput3,
|
||||
OptionsFocus::MidiInput0,
|
||||
OptionsFocus::MidiInput1,
|
||||
OptionsFocus::MidiInput2,
|
||||
OptionsFocus::MidiInput3,
|
||||
];
|
||||
|
||||
/// Section layout: header line, divider line, then option lines.
|
||||
/// Each entry gives the raw line offsets assuming ALL sections are visible
|
||||
/// (plugin mode with Font/Zoom/Window shown).
|
||||
const FULL_LAYOUT: &[(OptionsFocus, usize)] = &[
|
||||
// DISPLAY section: header=0, divider=1
|
||||
(OptionsFocus::ColorScheme, 2),
|
||||
(OptionsFocus::HueRotation, 3),
|
||||
(OptionsFocus::RefreshRate, 4),
|
||||
@@ -70,51 +92,112 @@ const FOCUS_LINES: &[(OptionsFocus, usize)] = &[
|
||||
(OptionsFocus::Font, 10),
|
||||
(OptionsFocus::ZoomFactor, 11),
|
||||
(OptionsFocus::WindowSize, 12),
|
||||
// blank=13, ABLETON LINK header=14, divider=15
|
||||
(OptionsFocus::LinkEnabled, 16),
|
||||
(OptionsFocus::StartStopSync, 17),
|
||||
(OptionsFocus::Quantum, 18),
|
||||
// blank=19, SESSION header=20, divider=21, Tempo=22, Beat=23, Phase=24
|
||||
// blank=25, MIDI OUTPUTS header=26, divider=27
|
||||
(OptionsFocus::MidiOutput0, 28),
|
||||
(OptionsFocus::MidiOutput1, 29),
|
||||
(OptionsFocus::MidiOutput2, 30),
|
||||
(OptionsFocus::MidiOutput3, 31),
|
||||
// blank=32, MIDI INPUTS header=33, divider=34
|
||||
(OptionsFocus::MidiInput0, 35),
|
||||
(OptionsFocus::MidiInput1, 36),
|
||||
(OptionsFocus::MidiInput2, 37),
|
||||
(OptionsFocus::MidiInput3, 38),
|
||||
// blank=39, ONBOARDING header=40, divider=41
|
||||
(OptionsFocus::ResetOnboarding, 42),
|
||||
];
|
||||
|
||||
const PLUGIN_ONLY: &[OptionsFocus] = &[OptionsFocus::Font, OptionsFocus::ZoomFactor, OptionsFocus::WindowSize];
|
||||
|
||||
impl OptionsFocus {
|
||||
fn is_plugin_only(self) -> bool {
|
||||
PLUGIN_ONLY.contains(&self)
|
||||
}
|
||||
|
||||
fn is_standalone_only(self) -> bool {
|
||||
STANDALONE_ONLY.contains(&self)
|
||||
}
|
||||
|
||||
fn is_visible(self, plugin_mode: bool) -> bool {
|
||||
if self.is_plugin_only() && !plugin_mode {
|
||||
return false;
|
||||
}
|
||||
if self.is_standalone_only() && plugin_mode {
|
||||
return false;
|
||||
}
|
||||
true
|
||||
}
|
||||
|
||||
pub fn line_index(self, plugin_mode: bool) -> usize {
|
||||
let base = FOCUS_LINES
|
||||
visible_layout(plugin_mode)
|
||||
.iter()
|
||||
.find(|(f, _)| *f == self)
|
||||
.map(|(_, l)| *l)
|
||||
.unwrap_or(0);
|
||||
if plugin_mode || base <= 9 {
|
||||
base
|
||||
} else {
|
||||
base - 3
|
||||
}
|
||||
.unwrap_or(0)
|
||||
}
|
||||
|
||||
pub fn at_line(line: usize, plugin_mode: bool) -> Option<OptionsFocus> {
|
||||
FOCUS_LINES.iter().find_map(|(f, l)| {
|
||||
if f.is_plugin_only() && !plugin_mode {
|
||||
return None;
|
||||
}
|
||||
let effective = if plugin_mode || *l <= 9 { *l } else { *l - 3 };
|
||||
if effective == line { Some(*f) } else { None }
|
||||
})
|
||||
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)
|
||||
}
|
||||
|
||||
/// Compute (focus, line_index) pairs for only the visible options,
|
||||
/// with line indices adjusted to account for hidden sections.
|
||||
fn visible_layout(plugin_mode: bool) -> Vec<(OptionsFocus, usize)> {
|
||||
// Start from the full layout and compute adjusted line numbers.
|
||||
// Hidden items + their section headers/dividers/blanks shrink the layout.
|
||||
|
||||
// We know the exact section structure, so we compute the offset to subtract
|
||||
// based on which sections are hidden.
|
||||
let mut offset: usize = 0;
|
||||
|
||||
// Font/Zoom/Window lines (10,11,12) hidden when !plugin_mode
|
||||
if !plugin_mode {
|
||||
offset += 3; // 3 lines for Font, ZoomFactor, WindowSize
|
||||
}
|
||||
|
||||
// Link + Session + MIDI sections hidden when plugin_mode
|
||||
// These span from blank(13) through MidiInput3(38) = 26 lines
|
||||
if plugin_mode {
|
||||
// blank + LINK header + divider + 3 options + blank + SESSION header + divider + 3 readonlys
|
||||
// + blank + MIDI OUT header + divider + 4 options + blank + MIDI IN header + divider + 4 options
|
||||
// = 26 lines (indices 13..=38)
|
||||
let link_section_lines = 26;
|
||||
offset += link_section_lines;
|
||||
}
|
||||
|
||||
let mut result = Vec::new();
|
||||
for &(focus, raw_line) in FULL_LAYOUT {
|
||||
if !focus.is_visible(plugin_mode) {
|
||||
continue;
|
||||
}
|
||||
// Lines at or below index 9 (ShowPreview) are never shifted
|
||||
let adjusted = if raw_line <= 9 {
|
||||
raw_line
|
||||
} else if !plugin_mode && raw_line <= 12 {
|
||||
// Font/Zoom/Window — these are hidden, skip
|
||||
continue;
|
||||
} else {
|
||||
raw_line - offset
|
||||
};
|
||||
result.push((focus, adjusted));
|
||||
}
|
||||
result
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OptionsState {
|
||||
pub focus: OptionsFocus,
|
||||
@@ -125,7 +208,7 @@ impl OptionsState {
|
||||
let mut f = self.focus;
|
||||
loop {
|
||||
f = f.next();
|
||||
if !f.is_plugin_only() || plugin_mode {
|
||||
if f.is_visible(plugin_mode) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -136,7 +219,7 @@ impl OptionsState {
|
||||
let mut f = self.focus;
|
||||
loop {
|
||||
f = f.prev();
|
||||
if !f.is_plugin_only() || plugin_mode {
|
||||
if f.is_visible(plugin_mode) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user