diff options
| author | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-04-02 22:46:48 +0300 |
|---|---|---|
| committer | Ogulcan Celik <ogulcancelik@gmail.com> | 2026-04-02 23:25:01 +0300 |
| commit | 0165c333ddf0707ed4455f48048feb50bd6500ba (patch) | |
| tree | 616e9c47882680573d6b94703fe93faeef420feb /src/app/state.rs | |
| parent | 0ef1e277f34471a7ffb7a0fdc7e419ec4b8f8e1e (diff) | |
refactor popup menu and selection list interactions
Diffstat (limited to 'src/app/state.rs')
| -rw-r--r-- | src/app/state.rs | 68 |
1 files changed, 60 insertions, 8 deletions
diff --git a/src/app/state.rs b/src/app/state.rs index d80903cf..91e9061e 100644 --- a/src/app/state.rs +++ b/src/app/state.rs @@ -385,11 +385,63 @@ pub const THEME_NAMES: &[&str] = &[ "rose-pine", ]; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct MenuListState { + pub highlighted: usize, +} + +impl MenuListState { + pub fn new(highlighted: usize) -> Self { + Self { highlighted } + } + + pub fn move_prev(&mut self) { + self.highlighted = self.highlighted.saturating_sub(1); + } + + pub fn move_next(&mut self, item_count: usize) { + if item_count > 0 { + self.highlighted = (self.highlighted + 1).min(item_count - 1); + } + } + + pub fn hover(&mut self, idx: Option<usize>) { + if let Some(idx) = idx { + self.highlighted = idx; + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub struct SelectionListState { + pub selected: usize, +} + +impl SelectionListState { + pub fn new(selected: usize) -> Self { + Self { selected } + } + + pub fn move_prev(&mut self) { + self.selected = self.selected.saturating_sub(1); + } + + pub fn move_next(&mut self, item_count: usize) { + if item_count > 0 { + self.selected = (self.selected + 1).min(item_count - 1); + } + } + + pub fn select(&mut self, idx: usize) { + self.selected = idx; + } +} + pub struct SettingsState { /// Which section tab is active. pub section: SettingsSection, /// Selected item index within the current section. - pub selected: usize, + pub list: SelectionListState, /// The palette before opening settings (for cancel/restore). pub original_palette: Option<Palette>, /// The theme name before opening settings. @@ -429,7 +481,7 @@ pub struct ContextMenuState { pub kind: ContextMenuKind, pub x: u16, pub y: u16, - pub selected: usize, + pub list: MenuListState, } impl ContextMenuState { @@ -481,7 +533,7 @@ pub struct AppState { pub request_complete_onboarding: bool, pub name_input: String, pub onboarding_step: usize, - pub onboarding_selected: usize, + pub onboarding_list: SelectionListState, pub release_notes: Option<ReleaseNotesState>, // View geometry (computed before render, consumed by render + mouse) pub view: ViewState, @@ -513,8 +565,8 @@ pub struct AppState { pub theme_name: String, /// Settings panel state. pub settings: SettingsState, - /// Currently selected item in the bottom-right global launcher menu. - pub global_menu_selected: usize, + /// Highlight state for the bottom-right global launcher menu. + pub global_menu: MenuListState, } impl AppState { @@ -573,7 +625,7 @@ impl AppState { request_complete_onboarding: false, name_input: String::new(), onboarding_step: 0, - onboarding_selected: 1, + onboarding_list: SelectionListState::new(1), release_notes: None, view: ViewState { sidebar_rect: Rect::default(), @@ -642,11 +694,11 @@ impl AppState { theme_name: "catppuccin".to_string(), settings: SettingsState { section: SettingsSection::Theme, - selected: 0, + list: SelectionListState::new(0), original_palette: None, original_theme: None, }, - global_menu_selected: 0, + global_menu: MenuListState::new(0), } } } |
