mirror of
https://github.com/slint-ui/slint.git
synced 2025-10-28 02:39:42 +00:00
Hide Android selection handles when scrolled out of view
In a LineEdit with a long text, when dragging the selection to the point where the anchor scrolls out of view in the other direection, it used to keep being visible, outside the LineEdit. This commit fixes that by passing the clip rect to the java code that positions the selection handles.
This commit is contained in:
parent
92ebe92f62
commit
b23a657c44
4 changed files with 43 additions and 13 deletions
|
|
@ -243,18 +243,31 @@ class SlintInputView extends View {
|
|||
mCursorHandle.setPosition(left_x, left_y);
|
||||
handleHeight = mCursorHandle.getHeight();
|
||||
} else if (num_handles == 2) {
|
||||
if (mLeftHandle == null) {
|
||||
mLeftHandle = new InputHandle(this, android.R.attr.textSelectHandleLeft);
|
||||
if (left_x != -1) {
|
||||
if (mLeftHandle == null) {
|
||||
mLeftHandle = new InputHandle(this, android.R.attr.textSelectHandleLeft);
|
||||
}
|
||||
mLeftHandle.setPosition(left_x, left_y);
|
||||
handleHeight = mLeftHandle.getHeight();
|
||||
} else {
|
||||
if (mLeftHandle != null) {
|
||||
mLeftHandle.hide();
|
||||
}
|
||||
}
|
||||
if (mRightHandle == null) {
|
||||
mRightHandle = new InputHandle(this, android.R.attr.textSelectHandleRight);
|
||||
if (right_x != -1) {
|
||||
if (mRightHandle == null) {
|
||||
mRightHandle = new InputHandle(this, android.R.attr.textSelectHandleRight);
|
||||
}
|
||||
mRightHandle.setPosition(right_x, right_y);
|
||||
handleHeight = mRightHandle.getHeight();
|
||||
} else {
|
||||
if (mRightHandle != null) {
|
||||
mRightHandle.hide();
|
||||
}
|
||||
}
|
||||
if (mCursorHandle != null) {
|
||||
mCursorHandle.hide();
|
||||
}
|
||||
mLeftHandle.setPosition(left_x, left_y);
|
||||
mRightHandle.setPosition(right_x, right_y);
|
||||
handleHeight = mLeftHandle.getHeight();
|
||||
showActionMenu();
|
||||
} else {
|
||||
if (mCursorHandle != null) {
|
||||
|
|
|
|||
|
|
@ -194,15 +194,22 @@ impl JavaHelper {
|
|||
};
|
||||
env.delete_local_ref(class_it)?;
|
||||
|
||||
let cur_origin = data.cursor_rect_origin.to_physical(scale_factor);
|
||||
let cur_origin = data.cursor_rect_origin.to_physical(scale_factor); // i32
|
||||
let anchor_origin = data.anchor_point.to_physical(scale_factor);
|
||||
let cur_size = data.cursor_rect_size.to_physical(scale_factor);
|
||||
|
||||
let cur_visible = data.clip_rect.map_or(true, |r| {
|
||||
r.contains(i_slint_core::lengths::logical_point_from_api(data.cursor_rect_origin))
|
||||
});
|
||||
let anchor_visible = data.clip_rect.map_or(true, |r| {
|
||||
r.contains(i_slint_core::lengths::logical_point_from_api(data.anchor_point))
|
||||
});
|
||||
|
||||
// Add 2*cur_size.width to the y position to be a bit under the cursor
|
||||
let cursor_height = cur_size.height as i32 + 2 * cur_size.width as i32;
|
||||
let cur_x = cur_origin.x + cur_size.width as i32 / 2;
|
||||
let cur_x = if cur_visible { cur_origin.x + cur_size.width as i32 / 2 } else { -1 };
|
||||
let cur_y = cur_origin.y + cursor_height;
|
||||
let anchor_x = anchor_origin.x;
|
||||
let anchor_x = if anchor_visible { anchor_origin.x } else { -1 };
|
||||
let anchor_y = anchor_origin.y + 2 * cur_size.width as i32;
|
||||
|
||||
env.call_method(
|
||||
|
|
|
|||
|
|
@ -1505,15 +1505,22 @@ impl TextInput {
|
|||
let cursor_relative =
|
||||
self.cursor_rect_for_byte_offset(cursor_position, window_adapter, self_rc);
|
||||
let geometry = self_rc.geometry();
|
||||
let origin = self_rc.map_to_window(geometry.origin).to_vector();
|
||||
let origin = self_rc.map_to_window(geometry.origin);
|
||||
let origin_vector = origin.to_vector();
|
||||
let cursor_rect_origin =
|
||||
crate::api::LogicalPosition::from_euclid(cursor_relative.origin + origin);
|
||||
crate::api::LogicalPosition::from_euclid(cursor_relative.origin + origin_vector);
|
||||
let cursor_rect_size = crate::api::LogicalSize::from_euclid(cursor_relative.size);
|
||||
let anchor_point = crate::api::LogicalPosition::from_euclid(
|
||||
self.cursor_rect_for_byte_offset(anchor_position, window_adapter, self_rc).origin
|
||||
+ origin
|
||||
+ origin_vector
|
||||
+ cursor_relative.size,
|
||||
);
|
||||
let maybe_parent =
|
||||
self_rc.parent_item(crate::item_tree::ParentItemTraversalMode::StopAtPopups);
|
||||
let clip_rect = maybe_parent.map(|parent| {
|
||||
let geom = parent.geometry();
|
||||
LogicalRect::new(parent.map_to_window(geom.origin), geom.size)
|
||||
});
|
||||
|
||||
InputMethodProperties {
|
||||
text,
|
||||
|
|
@ -1525,6 +1532,7 @@ impl TextInput {
|
|||
cursor_rect_size,
|
||||
anchor_point,
|
||||
input_type: self.input_type(),
|
||||
clip_rect,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -293,6 +293,8 @@ pub struct InputMethodProperties {
|
|||
pub anchor_point: LogicalPosition,
|
||||
/// The type of input for the text edit.
|
||||
pub input_type: InputType,
|
||||
/// The clip rect in window coordinates
|
||||
pub clip_rect: Option<LogicalRect>,
|
||||
}
|
||||
|
||||
/// This struct describes layout constraints of a resizable element, such as a window.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue