Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 3 additions & 10 deletions adapters/android/src/adapter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -168,13 +168,8 @@ impl TreeChangeHandler for AdapterChangeHandler<'_> {
y: scroll_y,
});
}
if old_node.numeric_value() != new_node.numeric_value() && new_node.data().value().is_none()
{
if let (Some(current), Some(min), Some(max)) = (
new_node.numeric_value(),
new_node.min_numeric_value(),
new_node.max_numeric_value(),
) {
if let Some(range) = new_wrapper.range() {
if old_node.numeric_value() != Some(range.current) {
let id = self.node_id_map.get_or_create_java_id(new_node);
let event_type = if self.accessibility_focus == Some(id) {
EVENT_VIEW_SELECTED
Expand All @@ -184,9 +179,7 @@ impl TreeChangeHandler for AdapterChangeHandler<'_> {
self.events.push(QueuedEvent::RangeValueChanged {
virtual_view_id: id,
event_type,
current,
min,
max,
range,
});
}
}
Expand Down
36 changes: 11 additions & 25 deletions adapters/android/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,20 +243,18 @@ fn send_range_value_changed(
host: &JObject,
virtual_view_id: jint,
event_type: jint,
current: f64,
min: f64,
max: f64,
range: Range,
) {
let event = new_event(env, host, virtual_view_id, event_type);
let item_index = if max > min && current >= min && current <= max {
((current - min) * 100.0 / (max - min)) as jint
} else {
0
};
env.call_method(&event, "setItemCount", "(I)V", &[100i32.into()])
.unwrap();
env.call_method(&event, "setCurrentItemIndex", "(I)V", &[item_index.into()])
.unwrap();
env.call_method(
&event,
"setCurrentItemIndex",
"(I)V",
&[range.current_item_index().into()],
)
.unwrap();
send_completed_event(env, host, event);
}

Expand Down Expand Up @@ -327,9 +325,7 @@ pub(crate) enum QueuedEvent {
RangeValueChanged {
virtual_view_id: jint,
event_type: jint,
current: f64,
min: f64,
max: f64,
range: Range,
},
InvalidateHost,
}
Expand Down Expand Up @@ -407,19 +403,9 @@ impl QueuedEvents {
QueuedEvent::RangeValueChanged {
virtual_view_id,
event_type,
current,
min,
max,
range,
} => {
send_range_value_changed(
env,
host,
virtual_view_id,
event_type,
current,
min,
max,
);
send_range_value_changed(env, host, virtual_view_id, event_type, range);
}
QueuedEvent::InvalidateHost => {
env.call_method(host, "invalidate", "()V", &[]).unwrap();
Expand Down
45 changes: 13 additions & 32 deletions adapters/android/src/node.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ impl NodeWrapper<'_> {
self.0.is_selected().unwrap_or(false)
}

pub(crate) fn range(&self) -> Option<Range> {
Range::from_node(self.0)
}

pub(crate) fn content_description(&self) -> Option<String> {
if self.0.label_comes_from_value() {
self.0.value()
Expand Down Expand Up @@ -387,38 +391,15 @@ impl NodeWrapper<'_> {
add_action(env, node_info, ACTION_SCROLL_FORWARD);
}

if self.0.data().value().is_none() {
if let (Some(current), Some(min), Some(max)) = (
self.0.numeric_value(),
self.0.min_numeric_value(),
self.0.max_numeric_value(),
) {
let range_info_class = env
.find_class("android/view/accessibility/AccessibilityNodeInfo$RangeInfo")
.unwrap();
let range_info = env
.call_static_method(
&range_info_class,
"obtain",
"(IFFF)Landroid/view/accessibility/AccessibilityNodeInfo$RangeInfo;",
&[
RANGE_TYPE_FLOAT.into(),
(min as f32).into(),
(max as f32).into(),
(current as f32).into(),
],
)
.unwrap()
.l()
.unwrap();
env.call_method(
node_info,
"setRangeInfo",
"(Landroid/view/accessibility/AccessibilityNodeInfo$RangeInfo;)V",
&[(&range_info).into()],
)
.unwrap();
}
if let Some(range) = self.range() {
let range_info = range.to_java(env);
env.call_method(
node_info,
"setRangeInfo",
"(Landroid/view/accessibility/AccessibilityNodeInfo$RangeInfo;)V",
&[(&range_info).into()],
)
.unwrap();
}

let live = match self.0.live() {
Expand Down
64 changes: 64 additions & 0 deletions adapters/android/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,72 @@ pub(crate) const MOVEMENT_GRANULARITY_WORD: jint = 1 << 1;
pub(crate) const MOVEMENT_GRANULARITY_LINE: jint = 1 << 2;
pub(crate) const MOVEMENT_GRANULARITY_PARAGRAPH: jint = 1 << 3;

pub(crate) const RANGE_TYPE_INT: jint = 0;
pub(crate) const RANGE_TYPE_FLOAT: jint = 1;

#[derive(Clone, Copy, Debug, PartialEq)]
pub(crate) struct Range {
pub(crate) current: f64,
pub(crate) min: f64,
pub(crate) max: f64,
step: Option<f64>,
}

impl Range {
pub(crate) fn from_node(node: &NodeRef) -> Option<Self> {
if node.has_value() {
return None;
}
Some(Self {
current: node.numeric_value()?,
min: node.min_numeric_value()?,
max: node.max_numeric_value()?,
step: node.numeric_value_step(),
})
}

fn range_type(&self) -> jint {
let is_integral = |value: f64| value.fract() == 0.0;
if is_integral(self.current)
&& is_integral(self.min)
&& is_integral(self.max)
&& self.step.is_none_or(is_integral)
{
RANGE_TYPE_INT
} else {
RANGE_TYPE_FLOAT
}
}

pub(crate) fn current_item_index(&self) -> jint {
if self.max > self.min && self.current >= self.min && self.current <= self.max {
((self.current - self.min) * 100.0 / (self.max - self.min)) as jint
} else {
0
}
}

pub(crate) fn to_java<'local>(self, env: &mut JNIEnv<'local>) -> JObject<'local> {
let range_info_class = env
.find_class("android/view/accessibility/AccessibilityNodeInfo$RangeInfo")
.unwrap();
env.call_static_method(
&range_info_class,
"obtain",
"(IFFF)Landroid/view/accessibility/AccessibilityNodeInfo$RangeInfo;",
&[
self.range_type().into(),
(self.min as f32).into(),
(self.max as f32).into(),
(self.current as f32).into(),
],
)
.unwrap()
.l()
.unwrap()
}
}

#[derive(Debug, Default)]
pub(crate) struct NodeIdMap {
java_to_accesskit: HashMap<jint, FullNodeId>,
Expand Down
Loading