Android: Move CursorHandles to QtEditText
The CursorHandles are the handles visible when trying to select text from a text edit, or select a position in the text. As it is not used anywhere outside a text edit, move it inside QtEditText, making it easier to handle cases where we have multiple windows, and multiple QtTextEdits. Task-number: QTBUG-126180 Change-Id: I765f229050ca33887570c1434bdc0a2aa3659649 Reviewed-by: Assam Boudjelthia <assam.boudjelthia@qt.io> (cherry picked from commit 996e1fba5e83e09a897272b16062a8e4fad291ef) Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
This commit is contained in:
parent
e1b7a0d3ee
commit
f149f0245f
@ -69,6 +69,12 @@ class CursorView extends ImageView
|
|||||||
class CursorHandle implements ViewTreeObserver.OnPreDrawListener
|
class CursorHandle implements ViewTreeObserver.OnPreDrawListener
|
||||||
{
|
{
|
||||||
private static final String QtTag = "QtCursorHandle";
|
private static final String QtTag = "QtCursorHandle";
|
||||||
|
|
||||||
|
// Handle IDs
|
||||||
|
static final int IdCursorHandle = 1;
|
||||||
|
static final int IdLeftHandle = 2;
|
||||||
|
static final int IdRightHandle = 3;
|
||||||
|
|
||||||
private final View m_layout;
|
private final View m_layout;
|
||||||
private CursorView m_cursorView = null;
|
private CursorView m_cursorView = null;
|
||||||
private PopupWindow m_popup = null;
|
private PopupWindow m_popup = null;
|
||||||
@ -138,9 +144,9 @@ class CursorHandle implements ViewTreeObserver.OnPreDrawListener
|
|||||||
int x2 = x + layoutLocation[0] - activityLocation[0];
|
int x2 = x + layoutLocation[0] - activityLocation[0];
|
||||||
int y2 = y + layoutLocation[1] + m_yShift + (activityLocationInWindow[1] - activityLocation[1]);
|
int y2 = y + layoutLocation[1] + m_yShift + (activityLocationInWindow[1] - activityLocation[1]);
|
||||||
|
|
||||||
if (m_id == QtInputDelegate.IdCursorHandle) {
|
if (m_id == IdCursorHandle) {
|
||||||
x2 -= m_popup.getWidth() / 2 ;
|
x2 -= m_popup.getWidth() / 2 ;
|
||||||
} else if ((m_id == QtInputDelegate.IdLeftHandle && !m_rtl) || (m_id == QtInputDelegate.IdRightHandle && m_rtl)) {
|
} else if ((m_id == IdLeftHandle && !m_rtl) || (m_id == IdRightHandle && m_rtl)) {
|
||||||
x2 -= m_popup.getWidth() * 3 / 4;
|
x2 -= m_popup.getWidth() * 3 / 4;
|
||||||
} else {
|
} else {
|
||||||
x2 -= m_popup.getWidth() / 4;
|
x2 -= m_popup.getWidth() / 4;
|
||||||
|
@ -23,9 +23,7 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout
|
|||||||
private int m_posX;
|
private int m_posX;
|
||||||
private int m_posY;
|
private int m_posY;
|
||||||
private int m_buttons;
|
private int m_buttons;
|
||||||
private CursorHandle m_cursorHandle;
|
private QtEditText m_currentEditText = null; // TODO, get rid of this reference
|
||||||
private CursorHandle m_leftSelectionHandle;
|
|
||||||
private CursorHandle m_rightSelectionHandle;
|
|
||||||
|
|
||||||
EditPopupMenu(Activity activity, View layout)
|
EditPopupMenu(Activity activity, View layout)
|
||||||
{
|
{
|
||||||
@ -53,8 +51,7 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Show the handle at a given position (or move it if it is already shown)
|
// Show the handle at a given position (or move it if it is already shown)
|
||||||
void setPosition(final int x, final int y, final int buttons,
|
void setPosition(final int x, final int y, final int buttons, final QtEditText editText)
|
||||||
CursorHandle cursorHandle, CursorHandle leftSelectionHandle, CursorHandle rightSelectionHandle)
|
|
||||||
{
|
{
|
||||||
initOverlay();
|
initOverlay();
|
||||||
|
|
||||||
@ -76,16 +73,13 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout
|
|||||||
x2 -= viewSize.x / 2 ;
|
x2 -= viewSize.x / 2 ;
|
||||||
|
|
||||||
y2 -= viewSize.y;
|
y2 -= viewSize.y;
|
||||||
if (y2 < 0) {
|
if (y2 < 0 && editText != null) {
|
||||||
if (cursorHandle != null) {
|
y2 = editText.getSelectionHandleBottom();
|
||||||
y2 = cursorHandle.bottom();
|
|
||||||
} else if (leftSelectionHandle != null && rightSelectionHandle != null) {
|
|
||||||
y2 = Math.max(leftSelectionHandle.bottom(), rightSelectionHandle.bottom());
|
|
||||||
if (y2 <= 0)
|
|
||||||
m_layout.requestLayout();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (y2 <= 0)
|
||||||
|
m_layout.requestLayout();
|
||||||
|
|
||||||
if (m_layout.getWidth() < x + viewSize.x / 2)
|
if (m_layout.getWidth() < x + viewSize.x / 2)
|
||||||
x2 = m_layout.getWidth() - viewSize.x;
|
x2 = m_layout.getWidth() - viewSize.x;
|
||||||
|
|
||||||
@ -100,9 +94,7 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout
|
|||||||
m_posX = x;
|
m_posX = x;
|
||||||
m_posY = y;
|
m_posY = y;
|
||||||
m_buttons = buttons;
|
m_buttons = buttons;
|
||||||
m_cursorHandle = cursorHandle;
|
m_currentEditText = editText;
|
||||||
m_leftSelectionHandle = leftSelectionHandle;
|
|
||||||
m_rightSelectionHandle = rightSelectionHandle;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void hide() {
|
void hide() {
|
||||||
@ -118,7 +110,7 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout
|
|||||||
// For example if the keyboard appears.
|
// For example if the keyboard appears.
|
||||||
// Adjust the position of the handle accordingly
|
// Adjust the position of the handle accordingly
|
||||||
if (m_popup != null && m_popup.isShowing())
|
if (m_popup != null && m_popup.isShowing())
|
||||||
setPosition(m_posX, m_posY, m_buttons, m_cursorHandle, m_leftSelectionHandle, m_rightSelectionHandle);
|
setPosition(m_posX, m_posY, m_buttons, m_currentEditText);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -129,7 +121,7 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout
|
|||||||
{
|
{
|
||||||
if ((right - left != oldRight - oldLeft || bottom - top != oldBottom - oldTop) &&
|
if ((right - left != oldRight - oldLeft || bottom - top != oldBottom - oldTop) &&
|
||||||
m_popup != null && m_popup.isShowing())
|
m_popup != null && m_popup.isShowing())
|
||||||
setPosition(m_posX, m_posY, m_buttons, m_cursorHandle, m_leftSelectionHandle, m_rightSelectionHandle);
|
setPosition(m_posX, m_posY, m_buttons, m_currentEditText);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
|
|
||||||
package org.qtproject.qt.android;
|
package org.qtproject.qt.android;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
import android.text.InputType;
|
import android.text.InputType;
|
||||||
@ -49,6 +50,17 @@ class QtEditText extends View
|
|||||||
|
|
||||||
private final QtInputConnectionListener m_qtInputConnectionListener;
|
private final QtInputConnectionListener m_qtInputConnectionListener;
|
||||||
|
|
||||||
|
|
||||||
|
// Values coming from QAndroidInputContext::CursorHandleShowMode
|
||||||
|
static final int CursorHandleNotShown = 0;
|
||||||
|
static final int CursorHandleShowNormal = 1;
|
||||||
|
static final int CursorHandleShowSelection = 2;
|
||||||
|
static final int CursorHandleShowEdit = 0x100;
|
||||||
|
|
||||||
|
private CursorHandle m_cursorHandle;
|
||||||
|
private CursorHandle m_leftSelectionHandle;
|
||||||
|
private CursorHandle m_rightSelectionHandle;
|
||||||
|
|
||||||
QtEditText(Context context, QtInputConnectionListener listener)
|
QtEditText(Context context, QtInputConnectionListener listener)
|
||||||
{
|
{
|
||||||
super(context);
|
super(context);
|
||||||
@ -213,6 +225,84 @@ class QtEditText extends View
|
|||||||
return imeOptions;
|
return imeOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getSelectionHandleBottom()
|
||||||
|
{
|
||||||
|
if (m_cursorHandle != null)
|
||||||
|
return m_cursorHandle.bottom();
|
||||||
|
if (m_leftSelectionHandle != null && m_rightSelectionHandle != null)
|
||||||
|
return Math.max(m_leftSelectionHandle.bottom(), m_rightSelectionHandle.bottom());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int getSelectionHandleWidth()
|
||||||
|
{
|
||||||
|
if (m_leftSelectionHandle != null && m_rightSelectionHandle != null)
|
||||||
|
return Math.max(m_leftSelectionHandle.width(), m_rightSelectionHandle.width());
|
||||||
|
if (m_cursorHandle != null)
|
||||||
|
return m_cursorHandle.width();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void updateHandles(int mode, int editX, int editY, int editButtons,
|
||||||
|
int x1, int y1, int x2, int y2, boolean rtl)
|
||||||
|
{
|
||||||
|
switch (mode & 0xff)
|
||||||
|
{
|
||||||
|
case CursorHandleNotShown:
|
||||||
|
if (m_cursorHandle != null) {
|
||||||
|
m_cursorHandle.hide();
|
||||||
|
m_cursorHandle = null;
|
||||||
|
}
|
||||||
|
if (m_rightSelectionHandle != null) {
|
||||||
|
m_rightSelectionHandle.hide();
|
||||||
|
m_leftSelectionHandle.hide();
|
||||||
|
m_rightSelectionHandle = null;
|
||||||
|
m_leftSelectionHandle = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CursorHandleShowNormal:
|
||||||
|
if (m_cursorHandle == null) {
|
||||||
|
// We pass this to the CursorHandle to use the QtEditText to calculate its
|
||||||
|
// position. This is OK as the QtEditText size matches the QtWindow size.
|
||||||
|
// If the size of the QtEditText is changed to not reflect the window's anymore,
|
||||||
|
// this should be changed to use getParent() instead of this.
|
||||||
|
m_cursorHandle = new CursorHandle((Activity) getContext(), this,
|
||||||
|
CursorHandle.IdCursorHandle,
|
||||||
|
android.R.attr.textSelectHandle, false);
|
||||||
|
}
|
||||||
|
m_cursorHandle.setPosition(x1, y1);
|
||||||
|
if (m_rightSelectionHandle != null) {
|
||||||
|
m_rightSelectionHandle.hide();
|
||||||
|
m_leftSelectionHandle.hide();
|
||||||
|
m_rightSelectionHandle = null;
|
||||||
|
m_leftSelectionHandle = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case CursorHandleShowSelection:
|
||||||
|
if (m_rightSelectionHandle == null) {
|
||||||
|
m_leftSelectionHandle = new CursorHandle((Activity) getContext(), this,
|
||||||
|
CursorHandle.IdLeftHandle,
|
||||||
|
!rtl ? android.R.attr.textSelectHandleLeft :
|
||||||
|
android.R.attr.textSelectHandleRight,
|
||||||
|
rtl);
|
||||||
|
m_rightSelectionHandle = new CursorHandle((Activity) getContext(), this,
|
||||||
|
CursorHandle.IdRightHandle,
|
||||||
|
!rtl ? android.R.attr.textSelectHandleRight :
|
||||||
|
android.R.attr.textSelectHandleLeft,
|
||||||
|
rtl);
|
||||||
|
}
|
||||||
|
m_leftSelectionHandle.setPosition(x1,y1);
|
||||||
|
m_rightSelectionHandle.setPosition(x2,y2);
|
||||||
|
if (m_cursorHandle != null) {
|
||||||
|
m_cursorHandle.hide();
|
||||||
|
m_cursorHandle = null;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private boolean isDisablePredictiveTextWorkaround(int inputHints)
|
private boolean isDisablePredictiveTextWorkaround(int inputHints)
|
||||||
{
|
{
|
||||||
return (inputHints & ImhNoPredictiveText) != 0 &&
|
return (inputHints & ImhNoPredictiveText) != 0 &&
|
||||||
|
@ -51,24 +51,11 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt
|
|||||||
private int m_portraitKeyboardHeight = 0;
|
private int m_portraitKeyboardHeight = 0;
|
||||||
private int m_landscapeKeyboardHeight = 0;
|
private int m_landscapeKeyboardHeight = 0;
|
||||||
private int m_probeKeyboardHeightDelayMs = 50;
|
private int m_probeKeyboardHeightDelayMs = 50;
|
||||||
private CursorHandle m_cursorHandle;
|
|
||||||
private CursorHandle m_leftSelectionHandle;
|
|
||||||
private CursorHandle m_rightSelectionHandle;
|
|
||||||
private EditPopupMenu m_editPopupMenu;
|
private EditPopupMenu m_editPopupMenu;
|
||||||
|
|
||||||
private int m_softInputMode = 0;
|
private int m_softInputMode = 0;
|
||||||
|
|
||||||
// Values coming from QAndroidInputContext::CursorHandleShowMode
|
|
||||||
private static final int CursorHandleNotShown = 0;
|
|
||||||
private static final int CursorHandleShowNormal = 1;
|
|
||||||
private static final int CursorHandleShowSelection = 2;
|
|
||||||
private static final int CursorHandleShowEdit = 0x100;
|
|
||||||
|
|
||||||
// Handle IDs
|
|
||||||
static final int IdCursorHandle = 1;
|
|
||||||
static final int IdLeftHandle = 2;
|
|
||||||
static final int IdRightHandle = 3;
|
|
||||||
|
|
||||||
private static Boolean m_tabletEventSupported = null;
|
private static Boolean m_tabletEventSupported = null;
|
||||||
|
|
||||||
private static int m_oldX, m_oldY;
|
private static int m_oldX, m_oldY;
|
||||||
@ -152,15 +139,9 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getSelectHandleWidth()
|
public int getSelectionHandleWidth()
|
||||||
{
|
{
|
||||||
int width = 0;
|
return m_currentEditText == null ? 0 : m_currentEditText.getSelectionHandleWidth();
|
||||||
if (m_leftSelectionHandle != null && m_rightSelectionHandle != null) {
|
|
||||||
width = Math.max(m_leftSelectionHandle.width(), m_rightSelectionHandle.width());
|
|
||||||
} else if (m_cursorHandle != null) {
|
|
||||||
width = m_cursorHandle.width();
|
|
||||||
}
|
|
||||||
return width;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* called from the C++ code when the position of the cursor or selection handles needs to
|
/* called from the C++ code when the position of the cursor or selection handles needs to
|
||||||
@ -375,55 +356,17 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt
|
|||||||
int editX, int editY, int editButtons,
|
int editX, int editY, int editButtons,
|
||||||
int x1, int y1, int x2, int y2, boolean rtl)
|
int x1, int y1, int x2, int y2, boolean rtl)
|
||||||
{
|
{
|
||||||
|
if (m_currentEditText != null)
|
||||||
|
m_currentEditText.updateHandles(mode, editX, editY, editButtons, x1, y1, x2, y2, rtl);
|
||||||
|
|
||||||
switch (mode & 0xff)
|
switch (mode & 0xff)
|
||||||
{
|
{
|
||||||
case CursorHandleNotShown:
|
case QtEditText.CursorHandleNotShown:
|
||||||
if (m_cursorHandle != null) {
|
|
||||||
m_cursorHandle.hide();
|
|
||||||
m_cursorHandle = null;
|
|
||||||
}
|
|
||||||
if (m_rightSelectionHandle != null) {
|
|
||||||
m_rightSelectionHandle.hide();
|
|
||||||
m_leftSelectionHandle.hide();
|
|
||||||
m_rightSelectionHandle = null;
|
|
||||||
m_leftSelectionHandle = null;
|
|
||||||
}
|
|
||||||
if (m_editPopupMenu != null)
|
if (m_editPopupMenu != null)
|
||||||
m_editPopupMenu.hide();
|
m_editPopupMenu.hide();
|
||||||
break;
|
break;
|
||||||
|
case QtEditText.CursorHandleShowSelection:
|
||||||
case CursorHandleShowNormal:
|
mode |= QtEditText.CursorHandleShowEdit;
|
||||||
if (m_cursorHandle == null) {
|
|
||||||
m_cursorHandle = new CursorHandle(activity, layout, IdCursorHandle,
|
|
||||||
android.R.attr.textSelectHandle, false);
|
|
||||||
}
|
|
||||||
m_cursorHandle.setPosition(x1, y1);
|
|
||||||
if (m_rightSelectionHandle != null) {
|
|
||||||
m_rightSelectionHandle.hide();
|
|
||||||
m_leftSelectionHandle.hide();
|
|
||||||
m_rightSelectionHandle = null;
|
|
||||||
m_leftSelectionHandle = null;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CursorHandleShowSelection:
|
|
||||||
if (m_rightSelectionHandle == null) {
|
|
||||||
m_leftSelectionHandle = new CursorHandle(activity, layout, IdLeftHandle,
|
|
||||||
!rtl ? android.R.attr.textSelectHandleLeft :
|
|
||||||
android.R.attr.textSelectHandleRight,
|
|
||||||
rtl);
|
|
||||||
m_rightSelectionHandle = new CursorHandle(activity, layout, IdRightHandle,
|
|
||||||
!rtl ? android.R.attr.textSelectHandleRight :
|
|
||||||
android.R.attr.textSelectHandleLeft,
|
|
||||||
rtl);
|
|
||||||
}
|
|
||||||
m_leftSelectionHandle.setPosition(x1,y1);
|
|
||||||
m_rightSelectionHandle.setPosition(x2,y2);
|
|
||||||
if (m_cursorHandle != null) {
|
|
||||||
m_cursorHandle.hide();
|
|
||||||
m_cursorHandle = null;
|
|
||||||
}
|
|
||||||
mode |= CursorHandleShowEdit;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -431,9 +374,9 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt
|
|||||||
editButtons &= ~EditContextView.PASTE_BUTTON;
|
editButtons &= ~EditContextView.PASTE_BUTTON;
|
||||||
|
|
||||||
if (m_editPopupMenu != null) {
|
if (m_editPopupMenu != null) {
|
||||||
if ((mode & CursorHandleShowEdit) == CursorHandleShowEdit && editButtons != 0) {
|
if ((mode & QtEditText.CursorHandleShowEdit) == QtEditText.CursorHandleShowEdit &&
|
||||||
m_editPopupMenu.setPosition(editX, editY, editButtons,
|
editButtons != 0) {
|
||||||
m_cursorHandle, m_leftSelectionHandle, m_rightSelectionHandle);
|
m_editPopupMenu.setPosition(editX, editY, editButtons, m_currentEditText);
|
||||||
} else {
|
} else {
|
||||||
m_editPopupMenu.hide();
|
m_editPopupMenu.hide();
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ interface QtInputInterface {
|
|||||||
void resetSoftwareKeyboard();
|
void resetSoftwareKeyboard();
|
||||||
void hideSoftwareKeyboard();
|
void hideSoftwareKeyboard();
|
||||||
boolean isSoftwareKeyboardVisible();
|
boolean isSoftwareKeyboardVisible();
|
||||||
int getSelectHandleWidth();
|
int getSelectionHandleWidth();
|
||||||
void updateHandles(Activity activity, QtLayout layout, int mode, int editX, int editY,
|
void updateHandles(Activity activity, QtLayout layout, int mode, int editX, int editY,
|
||||||
int editButtons, int x1, int y1, int x2, int y2, boolean rtl);
|
int editButtons, int x1, int y1, int x2, int y2, boolean rtl);
|
||||||
QtInputConnection.QtInputConnectionListener getInputConnectionListener();
|
QtInputConnection.QtInputConnectionListener getInputConnectionListener();
|
||||||
|
@ -84,7 +84,7 @@ namespace QtAndroidInput
|
|||||||
int getSelectHandleWidth()
|
int getSelectHandleWidth()
|
||||||
{
|
{
|
||||||
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
AndroidBackendRegister *reg = QtAndroid::backendRegister();
|
||||||
return reg->callInterface<QtJniTypes::QtInputInterface, jint>("getSelectHandleWidth");
|
return reg->callInterface<QtJniTypes::QtInputInterface, jint>("getSelectionHandleWidth");
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
|
void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user