Add `SurrenderFocusOn` option (#7471)
* [X] I have followed the instructions in the PR template On touch devices you don't want the keyboard to disappear when scrolling, so this PR adds a `SurrenderFocusOn` enum to configure on what interaction to surrender focus.
This commit is contained in:
parent
5453cceded
commit
bf981b8d3e
|
|
@ -38,10 +38,10 @@ use crate::{
|
|||
viewport::ViewportClass,
|
||||
};
|
||||
|
||||
use self::{hit_test::WidgetHits, interaction::InteractionSnapshot};
|
||||
#[cfg(feature = "accesskit")]
|
||||
use crate::IdMap;
|
||||
|
||||
use self::{hit_test::WidgetHits, interaction::InteractionSnapshot};
|
||||
use crate::input_state::SurrenderFocusOn;
|
||||
|
||||
/// Information given to the backend about when it is time to repaint the ui.
|
||||
///
|
||||
|
|
@ -1430,8 +1430,14 @@ impl Context {
|
|||
res.flags.set(Flags::HOVERED, false);
|
||||
}
|
||||
|
||||
let pointer_pressed_elsewhere = any_press && !res.hovered();
|
||||
if pointer_pressed_elsewhere && memory.has_focus(id) {
|
||||
let should_surrender_focus = match memory.options.input_options.surrender_focus_on {
|
||||
SurrenderFocusOn::Presses => any_press,
|
||||
SurrenderFocusOn::Clicks => input.pointer.any_click(),
|
||||
SurrenderFocusOn::Never => false,
|
||||
};
|
||||
|
||||
let pointer_clicked_elsewhere = should_surrender_focus && !res.hovered();
|
||||
if pointer_clicked_elsewhere && memory.has_focus(id) {
|
||||
memory.surrender_focus(id);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -17,6 +17,37 @@ pub use crate::Key;
|
|||
pub use touch_state::MultiTouchInfo;
|
||||
use touch_state::TouchState;
|
||||
|
||||
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub enum SurrenderFocusOn {
|
||||
/// Surrender focus if the user _presses_ somewhere outside the focused widget.
|
||||
Presses,
|
||||
|
||||
/// Surrender focus if the user _clicks_ somewhere outside the focused widget.
|
||||
#[default]
|
||||
Clicks,
|
||||
|
||||
/// Never surrender focus.
|
||||
Never,
|
||||
}
|
||||
|
||||
impl SurrenderFocusOn {
|
||||
pub fn ui(&mut self, ui: &mut crate::Ui) {
|
||||
ui.horizontal(|ui| {
|
||||
ui.selectable_value(self, Self::Presses, "Presses")
|
||||
.on_hover_text(
|
||||
"Surrender focus if the user presses somewhere outside the focused widget.",
|
||||
);
|
||||
ui.selectable_value(self, Self::Clicks, "Clicks")
|
||||
.on_hover_text(
|
||||
"Surrender focus if the user clicks somewhere outside the focused widget.",
|
||||
);
|
||||
ui.selectable_value(self, Self::Never, "Never")
|
||||
.on_hover_text("Never surrender focus.");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Options for input state handling.
|
||||
#[derive(Clone, Copy, Debug, PartialEq)]
|
||||
#[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))]
|
||||
|
|
@ -58,6 +89,9 @@ pub struct InputOptions {
|
|||
/// and when combined with [`Self::zoom_modifier`] it will result in zooming
|
||||
/// on only the vertical axis.
|
||||
pub vertical_scroll_modifier: Modifiers,
|
||||
|
||||
/// When should we surrender focus from the focused widget?
|
||||
pub surrender_focus_on: SurrenderFocusOn,
|
||||
}
|
||||
|
||||
impl Default for InputOptions {
|
||||
|
|
@ -79,6 +113,7 @@ impl Default for InputOptions {
|
|||
zoom_modifier: Modifiers::COMMAND,
|
||||
horizontal_scroll_modifier: Modifiers::SHIFT,
|
||||
vertical_scroll_modifier: Modifiers::ALT,
|
||||
surrender_focus_on: SurrenderFocusOn::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -95,6 +130,7 @@ impl InputOptions {
|
|||
zoom_modifier,
|
||||
horizontal_scroll_modifier,
|
||||
vertical_scroll_modifier,
|
||||
surrender_focus_on,
|
||||
} = self;
|
||||
crate::Grid::new("InputOptions")
|
||||
.num_columns(2)
|
||||
|
|
@ -155,6 +191,10 @@ impl InputOptions {
|
|||
vertical_scroll_modifier.ui(ui);
|
||||
ui.end_row();
|
||||
|
||||
ui.label("surrender_focus_on");
|
||||
surrender_focus_on.ui(ui);
|
||||
ui.end_row();
|
||||
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -495,7 +495,7 @@ pub use self::{
|
|||
epaint::text::TextWrapMode,
|
||||
grid::Grid,
|
||||
id::{Id, IdMap},
|
||||
input_state::{InputOptions, InputState, MultiTouchInfo, PointerState},
|
||||
input_state::{InputOptions, InputState, MultiTouchInfo, PointerState, SurrenderFocusOn},
|
||||
layers::{LayerId, Order},
|
||||
layout::*,
|
||||
load::SizeHint,
|
||||
|
|
|
|||
Loading…
Reference in New Issue