Android: Fix positioning of text editor context menu
The old code in QtActivityDelegate.updateHandles() and EditPopupMenu.setPosition() could use size of EditPopupMenu.m_view to calculate position of context menu before that size was calculated during an asynchronous layout pass. In particular m_view reports size 0x0 when context menu is opened for the first time after start of the application. In this case the context menu was displayed on top of the text editor instead of being displayed above it. This patch fixes that problem by moving all positioning code from QtActivityDelegate.updateHandles() to EditPopupMenu.setPosition() and adding an OnLayoutChangeListener which calls setPosition() again each time the size of m_view changes, including when it changes for the first time from 0x0 to a real value. Change-Id: I670fef811a4dcba5524f7520ea41a47978dd10f1 Reviewed-by: BogDan Vatra <bogdan@kdab.com>
This commit is contained in:
parent
a04629d9c2
commit
5f4b03659b
@ -59,7 +59,8 @@ import android.view.ViewGroup;
|
|||||||
import android.R;
|
import android.R;
|
||||||
|
|
||||||
// Helper class that manages a cursor or selection handle
|
// Helper class that manages a cursor or selection handle
|
||||||
public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, EditContextView.OnClickListener
|
public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, View.OnLayoutChangeListener,
|
||||||
|
EditContextView.OnClickListener
|
||||||
{
|
{
|
||||||
private View m_layout = null;
|
private View m_layout = null;
|
||||||
private EditContextView m_view = null;
|
private EditContextView m_view = null;
|
||||||
@ -67,10 +68,15 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, EditCo
|
|||||||
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 CursorHandle m_leftSelectionHandle;
|
||||||
|
private CursorHandle m_rightSelectionHandle;
|
||||||
|
|
||||||
public EditPopupMenu(Activity activity, View layout)
|
public EditPopupMenu(Activity activity, View layout)
|
||||||
{
|
{
|
||||||
m_view = new EditContextView(activity, this);
|
m_view = new EditContextView(activity, this);
|
||||||
|
m_view.addOnLayoutChangeListener(this);
|
||||||
|
|
||||||
m_layout = layout;
|
m_layout = layout;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,13 +96,9 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, EditCo
|
|||||||
m_layout.getViewTreeObserver().addOnPreDrawListener(this);
|
m_layout.getViewTreeObserver().addOnPreDrawListener(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getHeight()
|
|
||||||
{
|
|
||||||
return m_view.getHeight();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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)
|
||||||
public void setPosition(final int x, final int y, final int buttons)
|
public void setPosition(final int x, final int y, final int buttons,
|
||||||
|
CursorHandle cursorHandle, CursorHandle leftSelectionHandle, CursorHandle rightSelectionHandle)
|
||||||
{
|
{
|
||||||
initOverlay();
|
initOverlay();
|
||||||
|
|
||||||
@ -109,6 +111,14 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, EditCo
|
|||||||
|
|
||||||
x2 -= m_view.getWidth() / 2 ;
|
x2 -= m_view.getWidth() / 2 ;
|
||||||
|
|
||||||
|
y2 -= m_view.getHeight();
|
||||||
|
if (y2 < 0) {
|
||||||
|
if (cursorHandle != null)
|
||||||
|
y2 = cursorHandle.bottom();
|
||||||
|
else if (leftSelectionHandle != null && rightSelectionHandle != null)
|
||||||
|
y2 = Math.max(leftSelectionHandle.bottom(), rightSelectionHandle.bottom());
|
||||||
|
}
|
||||||
|
|
||||||
if (m_layout.getWidth() < x + m_view.getWidth() / 2)
|
if (m_layout.getWidth() < x + m_view.getWidth() / 2)
|
||||||
x2 = m_layout.getWidth() - m_view.getWidth();
|
x2 = m_layout.getWidth() - m_view.getWidth();
|
||||||
|
|
||||||
@ -123,6 +133,9 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, EditCo
|
|||||||
m_posX = x;
|
m_posX = x;
|
||||||
m_posY = y;
|
m_posY = y;
|
||||||
m_buttons = buttons;
|
m_buttons = buttons;
|
||||||
|
m_cursorHandle = cursorHandle;
|
||||||
|
m_leftSelectionHandle = leftSelectionHandle;
|
||||||
|
m_rightSelectionHandle = rightSelectionHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hide() {
|
public void hide() {
|
||||||
@ -138,11 +151,20 @@ public class EditPopupMenu implements ViewTreeObserver.OnPreDrawListener, EditCo
|
|||||||
// 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);
|
setPosition(m_posX, m_posY, m_buttons, m_cursorHandle, m_leftSelectionHandle, m_rightSelectionHandle);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLayoutChange(View v, int left, int top, int right, int bottom,
|
||||||
|
int oldLeft, int oldTop, int oldRight, int oldBottom)
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void contextButtonClicked(int buttonId) {
|
public void contextButtonClicked(int buttonId) {
|
||||||
switch (buttonId) {
|
switch (buttonId) {
|
||||||
|
@ -553,16 +553,8 @@ public class QtActivityDelegate
|
|||||||
editButtons &= ~EditContextView.PASTE_BUTTON;
|
editButtons &= ~EditContextView.PASTE_BUTTON;
|
||||||
|
|
||||||
if ((mode & CursorHandleShowEdit) == CursorHandleShowEdit && editButtons != 0) {
|
if ((mode & CursorHandleShowEdit) == CursorHandleShowEdit && editButtons != 0) {
|
||||||
editY -= m_editPopupMenu.getHeight();
|
m_editPopupMenu.setPosition(editX, editY, editButtons, m_cursorHandle, m_leftSelectionHandle,
|
||||||
if (editY < 0) {
|
m_rightSelectionHandle);
|
||||||
if (m_cursorHandle != null)
|
|
||||||
editY = m_cursorHandle.bottom();
|
|
||||||
else if (m_leftSelectionHandle != null && m_rightSelectionHandle != null)
|
|
||||||
editY = Math.max(m_leftSelectionHandle.bottom(), m_rightSelectionHandle.bottom());
|
|
||||||
else
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_editPopupMenu.setPosition(editX, editY, editButtons);
|
|
||||||
} else {
|
} else {
|
||||||
if (m_editPopupMenu != null)
|
if (m_editPopupMenu != null)
|
||||||
m_editPopupMenu.hide();
|
m_editPopupMenu.hide();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user