Add accessibility to `ProgressBar` and `Spinner` (#4139)
- Introduces `WidgetType::ProgressIndicator` and maps it to the corresponding AccessKit role. - A `Spinner` is now exposed as a widget indicating a progress for which a completion state is not known. - On the other hand, a `ProgressBar` reports a completion state and can possibly be labeled. Note that a label is not used if not explicitly asked by the user, as it would be redundant information. Assistive technologies prefer the numerical value so they can, for instance, emit beeps of which the frequency rise as the completion state increase. I had to call `floor` on the progression as it seems all the ATs I tested would round the value, hence reporting something different than what is displayed on the label.
This commit is contained in:
parent
a1d5145c16
commit
76411b5d74
|
|
@ -633,6 +633,7 @@ impl WidgetInfo {
|
|||
WidgetType::ColorButton => "color button",
|
||||
WidgetType::ImageButton => "image button",
|
||||
WidgetType::CollapsingHeader => "collapsing header",
|
||||
WidgetType::ProgressIndicator => "progress indicator",
|
||||
WidgetType::Label | WidgetType::Other => "",
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -643,6 +643,8 @@ pub enum WidgetType {
|
|||
|
||||
CollapsingHeader,
|
||||
|
||||
ProgressIndicator,
|
||||
|
||||
/// If you cannot fit any of the above slots.
|
||||
///
|
||||
/// If this is something you think should be added, file an issue.
|
||||
|
|
|
|||
|
|
@ -783,6 +783,7 @@ impl Response {
|
|||
WidgetType::Slider => Role::Slider,
|
||||
WidgetType::DragValue => Role::SpinButton,
|
||||
WidgetType::ColorButton => Role::ColorWell,
|
||||
WidgetType::ProgressIndicator => Role::ProgressIndicator,
|
||||
WidgetType::Other => Role::Unknown,
|
||||
});
|
||||
if let Some(label) = info.label {
|
||||
|
|
|
|||
|
|
@ -113,6 +113,17 @@ impl Widget for ProgressBar {
|
|||
let (outer_rect, response) =
|
||||
ui.allocate_exact_size(vec2(desired_width, height), Sense::hover());
|
||||
|
||||
response.widget_info(|| {
|
||||
let mut info = if let Some(ProgressBarText::Custom(text)) = &text {
|
||||
WidgetInfo::labeled(WidgetType::ProgressIndicator, text.text())
|
||||
} else {
|
||||
WidgetInfo::new(WidgetType::ProgressIndicator)
|
||||
};
|
||||
info.value = Some((progress as f64 * 100.0).floor());
|
||||
|
||||
info
|
||||
});
|
||||
|
||||
if ui.is_rect_visible(response.rect) {
|
||||
if animate {
|
||||
ui.ctx().request_repaint();
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
use epaint::{emath::lerp, vec2, Color32, Pos2, Rect, Shape, Stroke};
|
||||
|
||||
use crate::{Response, Sense, Ui, Widget};
|
||||
use crate::{Response, Sense, Ui, Widget, WidgetInfo, WidgetType};
|
||||
|
||||
/// A spinner widget used to indicate loading.
|
||||
///
|
||||
|
|
@ -66,6 +66,7 @@ impl Widget for Spinner {
|
|||
.size
|
||||
.unwrap_or_else(|| ui.style().spacing.interact_size.y);
|
||||
let (rect, response) = ui.allocate_exact_size(vec2(size, size), Sense::hover());
|
||||
response.widget_info(|| WidgetInfo::new(WidgetType::ProgressIndicator));
|
||||
self.paint_at(ui, rect);
|
||||
|
||||
response
|
||||
|
|
|
|||
Loading…
Reference in New Issue