fix: focus find on window focus if text box did not have focus
This commit is contained in:
parent
d7454b8685
commit
73446cdafc
2 changed files with 54 additions and 4 deletions
37
src/main.rs
37
src/main.rs
|
|
@ -351,6 +351,7 @@ pub enum Message {
|
|||
DialogMessage(DialogMessage),
|
||||
Find(Option<bool>),
|
||||
FindCaseSensitive(bool),
|
||||
FindFocused(bool),
|
||||
FindNext,
|
||||
FindPrevious,
|
||||
FindReplace,
|
||||
|
|
@ -466,7 +467,7 @@ pub struct App {
|
|||
auto_scroll: Option<f32>,
|
||||
dialog_opt: Option<Dialog<Message>>,
|
||||
dialog_page_opt: Option<DialogPage>,
|
||||
find_opt: Option<bool>,
|
||||
find_opt: Option<FindField>,
|
||||
find_replace_id: widget::Id,
|
||||
find_replace_value: String,
|
||||
find_search_id: widget::Id,
|
||||
|
|
@ -480,6 +481,12 @@ pub struct App {
|
|||
modifiers: Modifiers,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
struct FindField {
|
||||
replace: bool,
|
||||
has_focus: bool,
|
||||
}
|
||||
|
||||
impl App {
|
||||
pub fn active_tab(&self) -> Option<&Tab> {
|
||||
self.tab_model.active_data()
|
||||
|
|
@ -780,7 +787,12 @@ impl App {
|
|||
}
|
||||
_ => Task::none(),
|
||||
}
|
||||
} else if self.find_opt.is_some() {
|
||||
} else if self.find_opt.is_some_and(
|
||||
|FindField {
|
||||
replace: _,
|
||||
has_focus,
|
||||
}| has_focus,
|
||||
) {
|
||||
widget::text_input::focus(self.find_search_id.clone())
|
||||
} else {
|
||||
widget::text_input::focus(self.text_box_id.clone())
|
||||
|
|
@ -1811,7 +1823,10 @@ impl Application for App {
|
|||
}
|
||||
}
|
||||
Message::Find(find_opt) => {
|
||||
self.find_opt = find_opt;
|
||||
self.find_opt = find_opt.map(|f| FindField {
|
||||
replace: f,
|
||||
has_focus: true,
|
||||
});
|
||||
|
||||
// Focus correct input
|
||||
return self.update_focus();
|
||||
|
|
@ -1938,6 +1953,14 @@ impl Application for App {
|
|||
config_set!(find_wrap_around, find_wrap_around);
|
||||
return self.update_config();
|
||||
}
|
||||
Message::FindFocused(has_focus) => {
|
||||
if let Some(f) = self.find_opt.as_mut() {
|
||||
*f = FindField {
|
||||
replace: f.replace,
|
||||
has_focus,
|
||||
};
|
||||
}
|
||||
}
|
||||
Message::GitProjectStatus(project_status) => {
|
||||
self.git_project_status = Some(project_status);
|
||||
}
|
||||
|
|
@ -2809,6 +2832,7 @@ impl Application for App {
|
|||
Some(Tab::Editor(tab)) => {
|
||||
let mut text_box = text_box(&tab.editor, self.config.metrics(tab.zoom_adj()))
|
||||
.id(self.text_box_id.clone())
|
||||
.on_focus(Message::FindFocused(false))
|
||||
.on_auto_scroll(Message::AutoScroll)
|
||||
.on_changed(Message::TabChanged(tab_id))
|
||||
.has_context_menu(tab.context_menu.is_some())
|
||||
|
|
@ -2918,7 +2942,11 @@ impl Application for App {
|
|||
None => {}
|
||||
}
|
||||
|
||||
if let Some(replace) = &self.find_opt {
|
||||
if let Some(FindField {
|
||||
replace,
|
||||
has_focus: _,
|
||||
}) = &self.find_opt
|
||||
{
|
||||
let find_input =
|
||||
widget::text_input::text_input(fl!("find-placeholder"), &self.find_search_value)
|
||||
.id(self.find_search_id.clone())
|
||||
|
|
@ -2930,6 +2958,7 @@ impl Application for App {
|
|||
Message::FindNext
|
||||
}
|
||||
})
|
||||
.on_focus(Message::FindFocused(true))
|
||||
.width(Length::Fixed(320.0))
|
||||
.trailing_icon(
|
||||
button::custom(icon_cache_get("edit-clear-symbolic", 16))
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ pub struct TextBox<'a, Message> {
|
|||
padding: Padding,
|
||||
on_auto_scroll: Option<Box<dyn Fn(Option<f32>) -> Message + 'a>>,
|
||||
on_changed: Option<Message>,
|
||||
on_focus: Option<Message>,
|
||||
click_timing: Duration,
|
||||
has_context_menu: bool,
|
||||
on_context_menu: Option<Box<dyn Fn(Option<Point>) -> Message + 'a>>,
|
||||
|
|
@ -63,6 +64,7 @@ where
|
|||
padding: Padding::new(0.0),
|
||||
on_auto_scroll: None,
|
||||
on_changed: None,
|
||||
on_focus: None,
|
||||
click_timing: Duration::from_millis(500),
|
||||
has_context_menu: false,
|
||||
on_context_menu: None,
|
||||
|
|
@ -118,6 +120,11 @@ where
|
|||
self.line_numbers = true;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn on_focus(mut self, on_focus: Message) -> Self {
|
||||
self.on_focus = Some(on_focus);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
pub fn text_box<'a, Message>(
|
||||
|
|
@ -948,6 +955,13 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(on_focus) = self.on_focus.as_ref()
|
||||
&& state.emit_focus
|
||||
{
|
||||
state.emit_focus = false;
|
||||
shell.publish(on_focus.clone());
|
||||
}
|
||||
|
||||
let mut status = Status::Ignored;
|
||||
match event {
|
||||
Event::Keyboard(KeyEvent::KeyPressed {
|
||||
|
|
@ -1034,6 +1048,10 @@ where
|
|||
if let Some(p) = cursor_position.position_in(layout.bounds()) {
|
||||
state.is_focused = true;
|
||||
|
||||
if let Some(on_focus) = self.on_focus.as_ref() {
|
||||
shell.publish(on_focus.clone());
|
||||
}
|
||||
|
||||
// Handle left click drag
|
||||
if let Button::Left = button {
|
||||
let x_logical = p.x - self.padding.left;
|
||||
|
|
@ -1263,6 +1281,7 @@ pub struct State {
|
|||
dragging: Option<Dragging>,
|
||||
editor_offset_x: Cell<i32>,
|
||||
is_focused: bool,
|
||||
emit_focus: bool,
|
||||
scale_factor: Cell<f32>,
|
||||
scrollbar_v_rect: Cell<Rectangle<f32>>,
|
||||
scrollbar_h_rect: Cell<Option<Rectangle<f32>>>,
|
||||
|
|
@ -1278,6 +1297,7 @@ impl State {
|
|||
dragging: None,
|
||||
editor_offset_x: Cell::new(0),
|
||||
is_focused: false,
|
||||
emit_focus: false,
|
||||
scale_factor: Cell::new(1.0),
|
||||
scrollbar_v_rect: Cell::new(Rectangle::default()),
|
||||
scrollbar_h_rect: Cell::new(None),
|
||||
|
|
@ -1293,6 +1313,7 @@ impl operation::Focusable for State {
|
|||
|
||||
fn focus(&mut self) {
|
||||
self.is_focused = true;
|
||||
self.emit_focus = true;
|
||||
}
|
||||
|
||||
fn unfocus(&mut self) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue