mirror of
https://github.com/slint-ui/slint.git
synced 2025-08-30 23:27:22 +00:00
WIP: android cursor handle
This commit is contained in:
parent
98daa71010
commit
291a0bdc66
3 changed files with 94 additions and 9 deletions
|
@ -71,7 +71,7 @@ impl i_slint_core::window::WindowAdapterInternal for AndroidWindowAdapter {
|
||||||
match request {
|
match request {
|
||||||
i_slint_core::window::InputMethodRequest::Enable(props) => {
|
i_slint_core::window::InputMethodRequest::Enable(props) => {
|
||||||
self.java_helper
|
self.java_helper
|
||||||
.set_imm_data(&props)
|
.set_imm_data(&props, self.window.scale_factor())
|
||||||
.unwrap_or_else(|e| print_jni_error(&self.app, e));
|
.unwrap_or_else(|e| print_jni_error(&self.app, e));
|
||||||
self.java_helper
|
self.java_helper
|
||||||
.show_or_hide_soft_input(true)
|
.show_or_hide_soft_input(true)
|
||||||
|
@ -79,7 +79,7 @@ impl i_slint_core::window::WindowAdapterInternal for AndroidWindowAdapter {
|
||||||
}
|
}
|
||||||
i_slint_core::window::InputMethodRequest::Update(props) => {
|
i_slint_core::window::InputMethodRequest::Update(props) => {
|
||||||
self.java_helper
|
self.java_helper
|
||||||
.set_imm_data(&props)
|
.set_imm_data(&props, self.window.scale_factor())
|
||||||
.unwrap_or_else(|e| print_jni_error(&self.app, e));
|
.unwrap_or_else(|e| print_jni_error(&self.app, e));
|
||||||
}
|
}
|
||||||
i_slint_core::window::InputMethodRequest::Disable => {
|
i_slint_core::window::InputMethodRequest::Disable => {
|
||||||
|
|
|
@ -1,20 +1,92 @@
|
||||||
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
// Copyright © SixtyFPS GmbH <info@slint.dev>
|
||||||
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-1.1 OR LicenseRef-Slint-commercial
|
||||||
|
|
||||||
|
import android.view.MotionEvent;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
import android.view.inputmethod.InputConnection;
|
import android.view.inputmethod.InputConnection;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
import android.content.res.Resources;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.Selection;
|
import android.text.Selection;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
|
import android.util.DisplayMetrics;
|
||||||
|
import android.util.TypedValue;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.widget.FrameLayout;
|
import android.widget.FrameLayout;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.PopupWindow;
|
||||||
import android.view.inputmethod.BaseInputConnection;
|
import android.view.inputmethod.BaseInputConnection;
|
||||||
|
|
||||||
|
class InputHandle extends ImageView {
|
||||||
|
private PopupWindow mPopupWindow;
|
||||||
|
private float mPressedX;
|
||||||
|
private float mPressedY;
|
||||||
|
private SlintInputView mRootView;
|
||||||
|
|
||||||
|
public InputHandle(SlintInputView rootView, int attr) {
|
||||||
|
super(rootView.getContext());
|
||||||
|
mRootView = rootView;
|
||||||
|
Context ctx = rootView.getContext();
|
||||||
|
// this.mInputView = mInputView;
|
||||||
|
|
||||||
|
mPopupWindow = new PopupWindow(ctx, null, android.R.attr.textSelectHandleWindowStyle);
|
||||||
|
mPopupWindow.setSplitTouchEnabled(true);
|
||||||
|
mPopupWindow.setClippingEnabled(false);
|
||||||
|
int[] attrs = { attr };
|
||||||
|
Drawable drawable = ctx.getTheme().obtainStyledAttributes(attrs).getDrawable(0);
|
||||||
|
mPopupWindow.setWidth(drawable.getIntrinsicWidth());
|
||||||
|
mPopupWindow.setHeight(drawable.getIntrinsicHeight());
|
||||||
|
this.setImageDrawable(drawable);
|
||||||
|
|
||||||
|
// mPopupWindow.setBackgroundDrawable(null);
|
||||||
|
// mPopupWindow.setAnimationStyle(0);
|
||||||
|
// mPopupWindow.setWindowLayoutType(WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL);
|
||||||
|
// mPopupWindow.setEnterTransition(null);
|
||||||
|
// mPopupWindow.setExitTransition(null);
|
||||||
|
|
||||||
|
mPopupWindow.setContentView(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent ev) {
|
||||||
|
switch (ev.getActionMasked()) {
|
||||||
|
case MotionEvent.ACTION_DOWN: {
|
||||||
|
mPressedX = ev.getRawX();
|
||||||
|
mPressedY = ev.getRawY();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_MOVE: {
|
||||||
|
// setSelectionAt
|
||||||
|
// (Math.round(ev.getRawX() - mPressedX), Math.round(ev.getRawY() - mPressedY));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
case MotionEvent.ACTION_CANCEL:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPosition(int x, int y) {
|
||||||
|
DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
|
||||||
|
y += mPopupWindow.getHeight();
|
||||||
|
x -= mPopupWindow.getWidth() / 2;
|
||||||
|
mPopupWindow.showAtLocation(mRootView, 0, x, y);
|
||||||
|
mPopupWindow.update(x, y, -1, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hide() {
|
||||||
|
mPopupWindow.dismiss();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class SlintInputView extends View {
|
class SlintInputView extends View {
|
||||||
private String mText = "";
|
private String mText = "";
|
||||||
private int mCursorPosition = 0;
|
private int mCursorPosition = 0;
|
||||||
|
@ -34,6 +106,7 @@ class SlintInputView extends View {
|
||||||
@Override
|
@Override
|
||||||
public SpannableStringBuilder replace(int start, int end, CharSequence tb, int tbstart, int tbend) {
|
public SpannableStringBuilder replace(int start, int end, CharSequence tb, int tbstart, int tbend) {
|
||||||
super.replace(start, end, tb, tbstart, tbend);
|
super.replace(start, end, tb, tbstart, tbend);
|
||||||
|
mHandle.hide();
|
||||||
if (mInBatch == 0) {
|
if (mInBatch == 0) {
|
||||||
update();
|
update();
|
||||||
} else {
|
} else {
|
||||||
|
@ -127,6 +200,15 @@ class SlintInputView extends View {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private InputHandle mHandle;
|
||||||
|
|
||||||
|
public void setCursorPos(int rect_x, int rect_y, int rect_w, int rect_h) {
|
||||||
|
if (mHandle == null) {
|
||||||
|
mHandle = new InputHandle(this, android.R.attr.textSelectHandle);
|
||||||
|
}
|
||||||
|
mHandle.setPosition(rect_x + rect_w / 2, rect_y + rect_h + 2 * rect_w);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SlintAndroidJavaHelper {
|
public class SlintAndroidJavaHelper {
|
||||||
|
@ -178,12 +260,10 @@ public class SlintAndroidJavaHelper {
|
||||||
mActivity.runOnUiThread(new Runnable() {
|
mActivity.runOnUiThread(new Runnable() {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(rect_w, rect_h);
|
|
||||||
layoutParams.setMargins(rect_x, rect_y, 0, 0);
|
|
||||||
mInputView.setLayoutParams(layoutParams);
|
|
||||||
int selStart = Math.min(cursor_position, anchor_position);
|
int selStart = Math.min(cursor_position, anchor_position);
|
||||||
int selEnd = Math.max(cursor_position, anchor_position);
|
int selEnd = Math.max(cursor_position, anchor_position);
|
||||||
mInputView.setText(text, selStart, selEnd, preedit_start, preedit_end, input_type);
|
mInputView.setText(text, selStart, selEnd, preedit_start, preedit_end, input_type);
|
||||||
|
mInputView.setCursorPos(rect_x, rect_y, rect_w, rect_h);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,6 +103,7 @@ impl JavaHelper {
|
||||||
pub fn set_imm_data(
|
pub fn set_imm_data(
|
||||||
&self,
|
&self,
|
||||||
data: &i_slint_core::window::InputMethodProperties,
|
data: &i_slint_core::window::InputMethodProperties,
|
||||||
|
scale_factor: f32
|
||||||
) -> Result<(), jni::errors::Error> {
|
) -> Result<(), jni::errors::Error> {
|
||||||
self.with_jni_env(|env, helper| {
|
self.with_jni_env(|env, helper| {
|
||||||
let mut text = data.text.to_string();
|
let mut text = data.text.to_string();
|
||||||
|
@ -138,6 +139,10 @@ impl JavaHelper {
|
||||||
}
|
}
|
||||||
_ => 0 as jint,
|
_ => 0 as jint,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let cur_origin = data.cursor_rect_origin.to_physical(scale_factor);
|
||||||
|
let cur_size = data.cursor_rect_size.to_physical(scale_factor);
|
||||||
|
|
||||||
env.call_method(
|
env.call_method(
|
||||||
helper,
|
helper,
|
||||||
"set_imm_data",
|
"set_imm_data",
|
||||||
|
@ -148,10 +153,10 @@ impl JavaHelper {
|
||||||
JValue::from(to_utf16(anchor_position) as jint),
|
JValue::from(to_utf16(anchor_position) as jint),
|
||||||
JValue::from(to_utf16(data.preedit_offset) as jint),
|
JValue::from(to_utf16(data.preedit_offset) as jint),
|
||||||
JValue::from(to_utf16(data.preedit_offset + data.preedit_text.len()) as jint),
|
JValue::from(to_utf16(data.preedit_offset + data.preedit_text.len()) as jint),
|
||||||
JValue::from(data.cursor_rect_origin.x as jint),
|
JValue::from(cur_origin.x as jint),
|
||||||
JValue::from(data.cursor_rect_origin.y as jint),
|
JValue::from(cur_origin.y as jint),
|
||||||
JValue::from(data.cursor_rect_size.width as jint),
|
JValue::from(cur_size.width as jint),
|
||||||
JValue::from(data.cursor_rect_size.height as jint),
|
JValue::from(cur_size.height as jint),
|
||||||
JValue::from(input_type),
|
JValue::from(input_type),
|
||||||
],
|
],
|
||||||
)?;
|
)?;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue