diff --git a/src/android/jar/src/org/qtproject/qt/android/CursorHandle.java b/src/android/jar/src/org/qtproject/qt/android/CursorHandle.java index 015ff9349c9..519fe86968d 100644 --- a/src/android/jar/src/org/qtproject/qt/android/CursorHandle.java +++ b/src/android/jar/src/org/qtproject/qt/android/CursorHandle.java @@ -69,6 +69,12 @@ class CursorView extends ImageView class CursorHandle implements ViewTreeObserver.OnPreDrawListener { 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 CursorView m_cursorView = null; private PopupWindow m_popup = null; @@ -138,9 +144,9 @@ class CursorHandle implements ViewTreeObserver.OnPreDrawListener int x2 = x + layoutLocation[0] - activityLocation[0]; 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 ; - } 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; } else { x2 -= m_popup.getWidth() / 4; diff --git a/src/android/jar/src/org/qtproject/qt/android/EditPopupMenu.java b/src/android/jar/src/org/qtproject/qt/android/EditPopupMenu.java index 00097f4003e..e9838bc5bee 100644 --- a/src/android/jar/src/org/qtproject/qt/android/EditPopupMenu.java +++ b/src/android/jar/src/org/qtproject/qt/android/EditPopupMenu.java @@ -23,9 +23,7 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout private int m_posX; private int m_posY; private int m_buttons; - private CursorHandle m_cursorHandle; - private CursorHandle m_leftSelectionHandle; - private CursorHandle m_rightSelectionHandle; + private QtEditText m_currentEditText = null; // TODO, get rid of this reference 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) - void setPosition(final int x, final int y, final int buttons, - CursorHandle cursorHandle, CursorHandle leftSelectionHandle, CursorHandle rightSelectionHandle) + void setPosition(final int x, final int y, final int buttons, final QtEditText editText) { initOverlay(); @@ -76,16 +73,13 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout x2 -= viewSize.x / 2 ; y2 -= viewSize.y; - if (y2 < 0) { - if (cursorHandle != null) { - 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 && editText != null) { + y2 = editText.getSelectionHandleBottom(); } + if (y2 <= 0) + m_layout.requestLayout(); + if (m_layout.getWidth() < x + viewSize.x / 2) x2 = m_layout.getWidth() - viewSize.x; @@ -100,9 +94,7 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout m_posX = x; m_posY = y; m_buttons = buttons; - m_cursorHandle = cursorHandle; - m_leftSelectionHandle = leftSelectionHandle; - m_rightSelectionHandle = rightSelectionHandle; + m_currentEditText = editText; } void hide() { @@ -118,7 +110,7 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout // For example if the keyboard appears. // Adjust the position of the handle accordingly 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; } @@ -129,7 +121,7 @@ class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayout { if ((right - left != oldRight - oldLeft || bottom - top != oldBottom - oldTop) && 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 diff --git a/src/android/jar/src/org/qtproject/qt/android/QtEditText.java b/src/android/jar/src/org/qtproject/qt/android/QtEditText.java index e4fa4b99427..144ad2e8784 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtEditText.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtEditText.java @@ -4,6 +4,7 @@ package org.qtproject.qt.android; +import android.app.Activity; import android.content.Context; import android.graphics.Canvas; import android.text.InputType; @@ -49,6 +50,17 @@ class QtEditText extends View 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) { super(context); @@ -213,6 +225,84 @@ class QtEditText extends View 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) { return (inputHints & ImhNoPredictiveText) != 0 && diff --git a/src/android/jar/src/org/qtproject/qt/android/QtInputDelegate.java b/src/android/jar/src/org/qtproject/qt/android/QtInputDelegate.java index af73463e47e..980bc7da47b 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtInputDelegate.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtInputDelegate.java @@ -51,24 +51,11 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt private int m_portraitKeyboardHeight = 0; private int m_landscapeKeyboardHeight = 0; private int m_probeKeyboardHeightDelayMs = 50; - private CursorHandle m_cursorHandle; - private CursorHandle m_leftSelectionHandle; - private CursorHandle m_rightSelectionHandle; + private EditPopupMenu m_editPopupMenu; 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 int m_oldX, m_oldY; @@ -152,15 +139,9 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt } @Override - public int getSelectHandleWidth() + public int getSelectionHandleWidth() { - int width = 0; - 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; + return m_currentEditText == null ? 0 : m_currentEditText.getSelectionHandleWidth(); } /* 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 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) { - 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; - } + case QtEditText.CursorHandleNotShown: if (m_editPopupMenu != null) m_editPopupMenu.hide(); break; - - case CursorHandleShowNormal: - 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; + case QtEditText.CursorHandleShowSelection: + mode |= QtEditText.CursorHandleShowEdit; break; } @@ -431,9 +374,9 @@ class QtInputDelegate implements QtInputConnection.QtInputConnectionListener, Qt editButtons &= ~EditContextView.PASTE_BUTTON; if (m_editPopupMenu != null) { - if ((mode & CursorHandleShowEdit) == CursorHandleShowEdit && editButtons != 0) { - m_editPopupMenu.setPosition(editX, editY, editButtons, - m_cursorHandle, m_leftSelectionHandle, m_rightSelectionHandle); + if ((mode & QtEditText.CursorHandleShowEdit) == QtEditText.CursorHandleShowEdit && + editButtons != 0) { + m_editPopupMenu.setPosition(editX, editY, editButtons, m_currentEditText); } else { m_editPopupMenu.hide(); } diff --git a/src/android/jar/src/org/qtproject/qt/android/QtInputInterface.java b/src/android/jar/src/org/qtproject/qt/android/QtInputInterface.java index 336488b79ff..af90e230ab1 100644 --- a/src/android/jar/src/org/qtproject/qt/android/QtInputInterface.java +++ b/src/android/jar/src/org/qtproject/qt/android/QtInputInterface.java @@ -14,7 +14,7 @@ interface QtInputInterface { void resetSoftwareKeyboard(); void hideSoftwareKeyboard(); boolean isSoftwareKeyboardVisible(); - int getSelectHandleWidth(); + int getSelectionHandleWidth(); void updateHandles(Activity activity, QtLayout layout, int mode, int editX, int editY, int editButtons, int x1, int y1, int x2, int y2, boolean rtl); QtInputConnection.QtInputConnectionListener getInputConnectionListener(); diff --git a/src/plugins/platforms/android/androidjniinput.cpp b/src/plugins/platforms/android/androidjniinput.cpp index 49c23199a17..732791bc8a0 100644 --- a/src/plugins/platforms/android/androidjniinput.cpp +++ b/src/plugins/platforms/android/androidjniinput.cpp @@ -84,7 +84,7 @@ namespace QtAndroidInput int getSelectHandleWidth() { AndroidBackendRegister *reg = QtAndroid::backendRegister(); - return reg->callInterface("getSelectHandleWidth"); + return reg->callInterface("getSelectionHandleWidth"); } void updateHandles(int mode, QPoint editMenuPos, uint32_t editButtons, QPoint cursor, QPoint anchor, bool rtl)