Labels can now be focused so they can be read by screen-reader

This commit is contained in:
Emil Ernerfeldt 2021-03-09 19:58:41 +01:00
parent 33d2f16041
commit 3fbc07659c
3 changed files with 38 additions and 9 deletions

View file

@ -196,13 +196,13 @@ impl CtxRef {
changed: false, // must be set by the widget itself
};
if !enabled || sense == Sense::hover() || !layer_id.allow_interaction() {
if !enabled || !sense.focusable || !layer_id.allow_interaction() {
// Not interested or allowed input:
self.memory().surrender_kb_focus(id);
return response;
}
if sense.click {
if sense.focusable {
self.memory().interested_in_kb_focus(id);
}

View file

@ -7,6 +7,11 @@ pub struct Sense {
/// sliders, windows, scroll bars, scroll areas ...
pub drag: bool,
/// this widgets want focus.
/// Anything interactive + labels that can be focused
/// for the benefit of screen readers.
pub focusable: bool,
}
impl Sense {
@ -15,6 +20,17 @@ impl Sense {
Self {
click: false,
drag: false,
focusable: false,
}
}
/// Senses no clicks or drags, but can be focused with the keyboard.
/// Used for labels that can be focused for the benefit of screen readers.
pub fn focusable_noninteractive() -> Self {
Self {
click: false,
drag: false,
focusable: true,
}
}
@ -28,6 +44,7 @@ impl Sense {
Self {
click: true,
drag: false,
focusable: true,
}
}
@ -36,6 +53,7 @@ impl Sense {
Self {
click: false,
drag: true,
focusable: true,
}
}
@ -44,6 +62,7 @@ impl Sense {
Self {
click: true,
drag: true,
focusable: true,
}
}
@ -53,6 +72,7 @@ impl Sense {
Self {
click: self.click | other.click,
drag: self.drag | other.drag,
focusable: self.focusable | other.focusable,
}
}
}

View file

@ -159,6 +159,10 @@ impl Label {
// This should be the easiest method of putting text anywhere.
pub fn paint_galley(&self, ui: &mut Ui, pos: Pos2, galley: Galley) {
self.paint_galley_kb_focus(ui, pos, galley, false)
}
fn paint_galley_kb_focus(&self, ui: &mut Ui, pos: Pos2, galley: Galley, kb_focus: bool) {
let Self {
mut background_color,
code,
@ -170,6 +174,8 @@ impl Label {
..
} = *self;
let underline = underline || kb_focus;
let text_color = if let Some(text_color) = self.text_color {
text_color
} else if strong {
@ -237,6 +243,8 @@ impl Label {
impl Widget for Label {
fn ui(self, ui: &mut Ui) -> Response {
let sense = Sense::focusable_noninteractive();
if self.should_wrap(ui)
&& ui.layout().main_dir() == Direction::LeftToRight
&& ui.layout().main_wrap()
@ -260,7 +268,7 @@ impl Widget for Label {
assert!(!galley.rows.is_empty(), "Galleys are never empty");
let rect = galley.rows[0].rect().translate(vec2(pos.x, pos.y));
let id = ui.advance_cursor_after_rect(rect);
let mut total_response = ui.interact(rect, id, Sense::hover());
let mut response = ui.interact(rect, id, sense);
let mut y_translation = 0.0;
if let Some(row) = galley.rows.get(1) {
@ -276,15 +284,16 @@ impl Widget for Label {
row.y_max += y_translation;
let rect = row.rect().translate(vec2(pos.x, pos.y));
ui.advance_cursor_after_rect(rect);
total_response |= ui.interact(rect, id, Sense::hover());
response |= ui.interact(rect, id, sense);
}
self.paint_galley(ui, pos, galley);
total_response
response.widget_info(|| WidgetInfo::labeled(WidgetType::Label, &galley.text));
self.paint_galley_kb_focus(ui, pos, galley, response.has_kb_focus());
response
} else {
let galley = self.layout(ui);
let (rect, response) = ui.allocate_exact_size(galley.size, Sense::hover());
self.paint_galley(ui, rect.min, galley);
let (rect, response) = ui.allocate_exact_size(galley.size, sense);
response.widget_info(|| WidgetInfo::labeled(WidgetType::Label, &galley.text));
self.paint_galley_kb_focus(ui, rect.min, galley, response.has_kb_focus());
response
}
}