Fix style of disabled widgets (#4163)

* Broke in https://github.com/emilk/egui/pull/4026/files

The `Response::sense` for `enabled: false` widgets was wrong, leading to
the wrong widget style.
This commit is contained in:
Emil Ernerfeldt 2024-03-12 11:14:12 +01:00 committed by GitHub
parent 827fdefd83
commit d0a6bbf2b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 45 additions and 20 deletions

View File

@ -1018,12 +1018,7 @@ impl Context {
///
/// If the widget already exists, its state (sense, Rect, etc) will be updated.
#[allow(clippy::too_many_arguments)]
pub(crate) fn create_widget(&self, mut w: WidgetRect) -> Response {
if !w.enabled {
w.sense.click = false;
w.sense.drag = false;
}
pub(crate) fn create_widget(&self, w: WidgetRect) -> Response {
// Remember this widget
self.write(|ctx| {
let viewport = ctx.viewport();
@ -1130,7 +1125,8 @@ impl Context {
let input = &viewport.input;
let memory = &mut ctx.memory;
if sense.click
if enabled
&& sense.click
&& memory.has_focus(id)
&& (input.key_pressed(Key::Space) || input.key_pressed(Key::Enter))
{
@ -1139,7 +1135,10 @@ impl Context {
}
#[cfg(feature = "accesskit")]
if sense.click && input.has_accesskit_action_request(id, accesskit::Action::Default) {
if enabled
&& sense.click
&& input.has_accesskit_action_request(id, accesskit::Action::Default)
{
res.clicked[PointerButton::Primary as usize] = true;
}
@ -1159,7 +1158,7 @@ impl Context {
for pointer_event in &input.pointer.pointer_events {
if let PointerEvent::Released { click, button } = pointer_event {
if sense.click && clicked {
if enabled && sense.click && clicked {
if let Some(click) = click {
res.clicked[*button as usize] = true;
res.double_clicked[*button as usize] = click.is_double();

View File

@ -78,6 +78,16 @@ pub fn hit_test(
let top_layer = closest_hit.layer_id;
close.retain(|w| w.layer_id == top_layer);
// If the widget is disabled, treat it as if it isn't sensing anything.
// This simplifies the code in `hit_test_on_close` so it doesn't have to check
// the `enabled` flag everywhere:
for w in &mut close {
if !w.enabled {
w.sense.click = false;
w.sense.drag = false;
}
}
let pos_in_layer = pos_in_layers.get(&top_layer).copied().unwrap_or(pos);
let hits = hit_test_on_close(&close, pos_in_layer);

View File

@ -161,18 +161,20 @@ pub(crate) fn interact(
if dragged.is_none() {
// Check if we started dragging something new:
if let Some(widget) = interaction.potential_drag_id.and_then(|id| widgets.get(id)) {
let is_dragged = if widget.sense.click && widget.sense.drag {
// This widget is sensitive to both clicks and drags.
// When the mouse first is pressed, it could be either,
// so we postpone the decision until we know.
input.pointer.is_decidedly_dragging()
} else {
// This widget is just sensitive to drags, so we can mark it as dragged right away:
widget.sense.drag
};
if widget.enabled {
let is_dragged = if widget.sense.click && widget.sense.drag {
// This widget is sensitive to both clicks and drags.
// When the mouse first is pressed, it could be either,
// so we postpone the decision until we know.
input.pointer.is_decidedly_dragging()
} else {
// This widget is just sensitive to drags, so we can mark it as dragged right away:
widget.sense.drag
};
if is_dragged {
dragged = Some(widget.id);
if is_dragged {
dragged = Some(widget.id);
}
}
}
}

View File

@ -42,6 +42,13 @@ pub struct Response {
pub interact_rect: Rect,
/// The senses (click and/or drag) that the widget was interested in (if any).
///
/// Note: if [`Self::enabled`] is `false`, then
/// the widget _effectively_ doesn't sense anything,
/// but can still have the same `Sense`.
/// This is because the sense informs the styling of the widget,
/// but we don't want to change the style when a widget is disabled
/// (that is handled by the `Painter` directly).
pub sense: Sense,
/// Was the widget enabled?

View File

@ -29,6 +29,13 @@ pub struct WidgetRect {
pub interact_rect: Rect,
/// How the widget responds to interaction.
///
/// Note: if [`Self::enabled`] is `false`, then
/// the widget _effectively_ doesn't sense anything,
/// but can still have the same `Sense`.
/// This is because the sense informs the styling of the widget,
/// but we don't want to change the style when a widget is disabled
/// (that is handled by the `Painter` directly).
pub sense: Sense,
/// Is the widget enabled?