refactor: enhance search field focus functionality and input handling

This commit is contained in:
2026-01-28 00:28:08 +03:00
parent 6df826f210
commit 03df631690
4 changed files with 103 additions and 101 deletions
+7 -2
View File
@@ -356,12 +356,17 @@ impl SoundpadGui {
fn draw_files(&mut self, ui: &mut Ui, area_size: Vec2) { fn draw_files(&mut self, ui: &mut Ui, area_size: Vec2) {
ui.vertical(|ui| { ui.vertical(|ui| {
ui.horizontal(|ui| { ui.horizontal(|ui| {
let search_field = ui.add_sized( let search_field_response = ui.add_sized(
[ui.available_width(), 22.0], [ui.available_width(), 22.0],
TextEdit::singleline(&mut self.app_state.search_query).hint_text("Search..."), TextEdit::singleline(&mut self.app_state.search_query).hint_text("Search..."),
); );
self.app_state.search_field_id = Some(search_field.id); if self.app_state.force_focus_search {
search_field_response.request_focus();
self.app_state.force_focus_search = false;
}
self.app_state.search_field_id = Some(search_field_response.id);
}); });
ui.separator(); ui.separator();
+27 -23
View File
@@ -1,30 +1,35 @@
use crate::gui::SoundpadGui; use crate::gui::SoundpadGui;
use egui::{Context, Key}; use egui::{Context, Id, Key, Modifiers};
use std::path::PathBuf; use std::path::PathBuf;
impl SoundpadGui { impl SoundpadGui {
pub fn handle_input(&mut self, ctx: &Context) { fn key_pressed(&self, ctx: &Context, key: Key) -> bool {
if ctx.memory(|reader| { reader.focused() }.is_some()) { ctx.input(|i| i.key_pressed(key))
return;
} }
ctx.input(|i| { fn modifiers(&self, ctx: &Context) -> Modifiers {
ctx.input(|i| i.modifiers)
}
pub fn handle_input(&mut self, ctx: &Context) {
let modifiers = self.modifiers(ctx);
// Close app on espace // Close app on espace
if i.key_pressed(Key::Escape) { if self.key_pressed(ctx, Key::Escape) {
std::process::exit(0); std::process::exit(0);
} }
// Open/close settings // Open/close settings
if i.key_pressed(Key::I) { if self.key_pressed(ctx, Key::I) {
self.app_state.show_settings = !self.app_state.show_settings; self.app_state.show_settings = !self.app_state.show_settings;
} }
if i.key_pressed(Key::Enter) && self.app_state.selected_file.is_some() { if self.key_pressed(ctx, Key::Enter) && self.app_state.selected_file.is_some() {
let path = &self.app_state.selected_file.clone().unwrap(); let path = &self.app_state.selected_file.clone().unwrap();
if i.modifiers.ctrl { if modifiers.ctrl {
self.play_file(path, true); self.play_file(path, true);
} else if i.modifiers.shift } else if modifiers.shift
&& let Some(last_track) = self.audio_player_state.tracks.last() && let Some(last_track) = self.audio_player_state.tracks.last()
{ {
self.stop(Some(last_track.id)); self.stop(Some(last_track.id));
@@ -36,29 +41,28 @@ impl SoundpadGui {
if !self.app_state.show_settings { if !self.app_state.show_settings {
// Pause / resume audio on space // Pause / resume audio on space
if i.key_pressed(Key::Space) { if self.key_pressed(ctx, Key::Space) {
self.play_toggle(); self.play_toggle();
} }
// Stop all audio tracks on backspace // Stop all audio tracks on backspace
if i.key_pressed(Key::Backspace) { if self.key_pressed(ctx, Key::Backspace) {
self.stop(None); self.stop(None);
} }
// Focus search field // Focus search field
if i.key_pressed(Key::Slash) && self.app_state.search_field_id.is_some() { if self.key_pressed(ctx, Key::Slash) {
self.app_state.force_focus_id = self.app_state.search_field_id; self.app_state.force_focus_search = true;
} }
// Iterate through dirs if there are some // Iterate through dirs if there are some
if i.modifiers.ctrl { if modifiers.ctrl {
let arrow_up_pressed = i.key_pressed(Key::ArrowUp); let arrow_up_pressed = self.key_pressed(ctx, Key::ArrowUp);
let arrow_down_pressed = i.key_pressed(Key::ArrowDown); let arrow_down_pressed = self.key_pressed(ctx, Key::ArrowDown);
if arrow_up_pressed || arrow_down_pressed { if arrow_up_pressed || arrow_down_pressed {
if i.modifiers.shift && !self.app_state.dirs.is_empty() { if modifiers.shift && !self.app_state.dirs.is_empty() {
let mut dirs: Vec<PathBuf> = let mut dirs: Vec<PathBuf> = self.app_state.dirs.iter().cloned().collect();
self.app_state.dirs.iter().cloned().collect();
dirs.sort(); dirs.sort();
let current_dir_index: i8; let current_dir_index: i8;
@@ -74,8 +78,8 @@ impl SoundpadGui {
let mut new_dir_index: i8; let mut new_dir_index: i8;
new_dir_index = current_dir_index - arrow_up_pressed as i8 new_dir_index =
+ arrow_down_pressed as i8; current_dir_index - arrow_up_pressed as i8 + arrow_down_pressed as i8;
if new_dir_index < 0 { if new_dir_index < 0 {
new_dir_index = (dirs.len() - 1) as i8; new_dir_index = (dirs.len() - 1) as i8;
@@ -117,6 +121,6 @@ impl SoundpadGui {
} }
} }
} }
}); // });
} }
} }
-7
View File
@@ -86,13 +86,6 @@ impl App for SoundpadGui {
} }
self.draw(ui).ok(); self.draw(ui).ok();
if let Some(force_focus_id) = self.app_state.force_focus_id {
ui.memory_mut(|reder| {
reder.request_focus(force_focus_id);
});
self.app_state.force_focus_id = None;
}
}); });
ctx.request_repaint_after_secs(1.0 / 60.0); ctx.request_repaint_after_secs(1.0 / 60.0);
+3 -3
View File
@@ -28,9 +28,12 @@ pub struct AppState {
pub show_settings: bool, pub show_settings: bool,
pub volume_dragged: bool, pub volume_dragged: bool,
pub force_focus_search: bool,
pub volume_slider_value: f32, pub volume_slider_value: f32,
pub search_field_id: Option<Id>,
pub ignore_volume_update_until: Option<Instant>, pub ignore_volume_update_until: Option<Instant>,
pub current_dir: Option<PathBuf>, pub current_dir: Option<PathBuf>,
@@ -38,9 +41,6 @@ pub struct AppState {
pub selected_file: Option<PathBuf>, pub selected_file: Option<PathBuf>,
pub files: HashSet<PathBuf>, pub files: HashSet<PathBuf>,
pub search_field_id: Option<Id>,
pub force_focus_id: Option<Id>,
} }
#[derive(Default, Debug, Clone)] #[derive(Default, Debug, Clone)]