Update key preview positioning and scaling, use touch origin offset for moreKey detection

This commit is contained in:
Aleksandras Kostarevas 2024-09-17 09:58:56 +03:00
parent 9e75e45056
commit 7a01d1e6e6
7 changed files with 42 additions and 55 deletions

View File

@ -622,25 +622,13 @@ public final class MainKeyboardView extends KeyboardView implements DrawingProxy
final int[] lastCoords = CoordinateUtils.newInstance();
tracker.getLastCoordinates(lastCoords);
final boolean keyPreviewEnabled = mKeyPreviewDrawParams.isPopupEnabled();
// The more keys keyboard is usually horizontally aligned with the center of the parent key.
// If showMoreKeysKeyboardAtTouchedPoint is true and the key preview is disabled, the more
// keys keyboard is placed at the touch point of the parent key.
final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint && !keyPreviewEnabled)
? CoordinateUtils.x(lastCoords)
: key.getX() + key.getWidth() / 2;
// The more keys keyboard is usually vertically aligned with the top edge of the parent key
// (plus vertical gap). If the key preview is enabled, the more keys keyboard is vertically
// aligned with the bottom edge of the visible part of the key preview.
// {@code mPreviewVisibleOffset} has been set appropriately in
// {@link KeyboardView#showKeyPreview(PointerTracker)}.
final int pointY;
if(key.isActionKey()) {
pointY = key.getY();
} else {
pointY = key.getY() + mKeyPreviewDrawParams.getVisibleOffset() + (keyPreviewEnabled ? key.getHeight() : key.getVerticalGap());
}
moreKeysKeyboardView.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener);
final int bottomPadding = mKeyPreviewChoreographer.getBottomPaddingForKey(getContext(), key);
final int pointX = key.getDrawX() + key.getDrawWidth() / 2;
final int pointY = key.getY() + key.getHeight() - bottomPadding;
moreKeysKeyboardView.showMoreKeysPanel(this, this, pointX, pointY, mKeyboardActionListener, lastCoords);
return moreKeysKeyboardView;
}

View File

@ -318,7 +318,7 @@ public final class MoreKeysKeyboard extends Keyboard {
int dimension = (int)(context.getResources().getDisplayMetrics().density * 44.5f);
keyWidth = getMaxKeyWidth(key, Math.min(dimension, key.getTotalWidth()), padding, paintToMeasure);
rowHeight = dimension;
rowHeight = Math.max(key.getHeight(), dimension);
}
final int dividerWidth = 0; // TODO: Remove divider
final List<MoreKeySpec> moreKeys = key.getMoreKeys();

View File

@ -121,7 +121,7 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
@Override
public void showMoreKeysPanel(final View parentView, final Controller controller,
final int pointX, final int pointY, final KeyboardActionListener listener) {
final int pointX, final int pointY, final KeyboardActionListener listener, final int[] touchOrigin) {
mController = controller;
mListener = listener;
final View container = getContainerView();
@ -139,8 +139,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
container.setX(panelX);
container.setY(panelY);
mOriginX = x + container.getPaddingLeft();
mOriginY = y + container.getPaddingTop();
mOriginX = CoordinateUtils.x(touchOrigin) - getDefaultCoordX();
mOriginY = CoordinateUtils.y(touchOrigin) - container.getMeasuredHeight();
controller.onShowMoreKeysPanel(this);
final MoreKeysKeyboardAccessibilityDelegate accessibilityDelegate = mAccessibilityDelegate;
if (accessibilityDelegate != null

View File

@ -61,7 +61,7 @@ public interface MoreKeysPanel {
// TODO: Currently the MoreKeysPanel is inside a container view that is added to the parent.
// Consider the simpler approach of placing the MoreKeysPanel itself into the parent view.
public void showMoreKeysPanel(View parentView, Controller controller, int pointX,
int pointY, KeyboardActionListener listener);
int pointY, KeyboardActionListener listener, int[] touchOrigin);
/**
* Dismisses the more keys panel and calls the controller's onDismissMoreKeysPanel to remove

View File

@ -103,6 +103,11 @@ public final class KeyPreviewChoreographer {
showKeyPreview(key, keyPreviewView, withAnimation);
}
public int getBottomPaddingForKey(final Context context, final Key key) {
final float density = context.getResources().getDisplayMetrics().density;
return Math.max(key.getHeight(), (int)(64.0f * density));
}
private void placeKeyPreview(final Key key, final KeyPreviewView keyPreviewView,
final KeyboardIconsSet iconsSet, final KeyDrawParams drawParams,
final int keyboardViewWidth, final int[] originCoords) {
@ -110,8 +115,16 @@ public final class KeyPreviewChoreographer {
keyPreviewView.measure(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mParams.setGeometry(keyPreviewView);
final int previewWidth = keyPreviewView.getMeasuredWidth();
final int previewHeight = mParams.mPreviewHeight;
final float density = keyPreviewView.getContext().getResources().getDisplayMetrics().density;
final int bottomPadding = getBottomPaddingForKey(keyPreviewView.getContext(), key);
final int topArea = Math.max(key.getHeight(), (int)(44.0f * density));
final int previewWidth = Math.min(Math.max(key.getWidth(), (int)(34.0f * density)), (int)(80.0f * density));
final int previewHeight = topArea + bottomPadding;
keyPreviewView.setPadding(0, 0, 0, bottomPadding);
final int keyDrawWidth = key.getDrawWidth();
// The key preview is horizontally aligned with the center of the visible part of the
// parent key. If it doesn't fit in this {@link KeyboardView}, it is moved inward to fit and

View File

@ -49,7 +49,7 @@ public class KeyPreviewView extends androidx.appcompat.widget.AppCompatTextView
public KeyPreviewView(final Context context, final AttributeSet attrs, final int defStyleAttr) {
super(context, attrs, defStyleAttr);
setGravity(Gravity.CENTER);
setGravity(Gravity.BOTTOM | Gravity.CENTER_HORIZONTAL);
}
public void setPreviewVisual(final Key key, final KeyboardIconsSet iconsSet,
@ -64,13 +64,13 @@ public class KeyPreviewView extends androidx.appcompat.widget.AppCompatTextView
setCompoundDrawables(null, null, null, null);
setTextColor(drawParams.mPreviewTextColor);
setTextSize(TypedValue.COMPLEX_UNIT_PX, key.selectPreviewTextSize(drawParams));
setTextSize(TypedValue.COMPLEX_UNIT_PX, key.selectTextSize(drawParams));
setTypeface(key.selectPreviewTypeface(drawParams));
// TODO Should take care of temporaryShiftLabel here.
setTextAndScaleX(key.getPreviewLabel());
setTextAndScaleX(key.getWidth(), key.getPreviewLabel());
}
private void setTextAndScaleX(final String text) {
private void setTextAndScaleX(int maxWidth, final String text) {
setTextScaleX(1.0f);
setText(text);
if (sNoScaleXTextSet.contains(text)) {
@ -83,8 +83,6 @@ public class KeyPreviewView extends androidx.appcompat.widget.AppCompatTextView
return;
}
background.getPadding(mBackgroundPadding);
final int maxWidth = background.getIntrinsicWidth() - mBackgroundPadding.left
- mBackgroundPadding.right;
final float width = getTextWidth(text, getPaint());
if (width <= maxWidth) {
sNoScaleXTextSet.add(text);

View File

@ -229,7 +229,6 @@ class BasicThemeProvider(val context: Context, val colorScheme: KeyboardColorSch
colors[R.styleable.Keyboard_Key_keyHintLabelColor] = onKeyColorHalf
colors[R.styleable.Keyboard_Key_keyShiftedLetterHintInactivatedColor] = onKeyColorHalf
colors[R.styleable.Keyboard_Key_keyShiftedLetterHintActivatedColor] = onKeyColorHalf
colors[R.styleable.Keyboard_Key_keyPreviewTextColor] = onSecondary
colors[R.styleable.MainKeyboardView_languageOnSpacebarTextColor] = onKeyColorHalf
colors[R.styleable.MainKeyboardView_gestureTrailColor] = primary
colors[R.styleable.MainKeyboardView_slidingKeyInputPreviewColor] = primary
@ -316,11 +315,11 @@ class BasicThemeProvider(val context: Context, val colorScheme: KeyboardColorSch
},
KeyVisualStyle.MoreKey to VisualStyleDescriptor(
backgroundDrawable = coloredRoundedRectangle(primaryContainer, dp(24.dp)),
backgroundDrawable = coloredRoundedRectangle(primaryContainer, dp(8.dp)),
foregroundColor = onPrimaryContainer,
backgroundDrawablePressed = coloredRoundedRectangle(onPrimaryContainer, dp(24.dp)),
foregroundColorPressed = primaryContainer
backgroundDrawablePressed = coloredRoundedRectangle(primary, dp(8.dp)),
foregroundColorPressed = onPrimary
),
KeyVisualStyle.Functional to if(keyBorders) {
@ -405,28 +404,17 @@ class BasicThemeProvider(val context: Context, val colorScheme: KeyboardColorSch
)
}
keyFeedback = ShapeDrawable().apply {
paint.color = secondary
shape = RoundRectShape(
floatArrayOf(
dp(8.dp), dp(8.dp), dp(8.dp), dp(8.dp),
dp(8.dp), dp(8.dp), dp(8.dp), dp(8.dp),
), null, null
)
intrinsicWidth = dp(48.dp).roundToInt()
intrinsicHeight = dp(24.dp).roundToInt()
setPadding(0, 0, 0, dp(50.dp).roundToInt())
keyFeedback = GradientDrawable(
GradientDrawable.Orientation.TOP_BOTTOM,
intArrayOf(primaryContainer, primaryContainer),
).apply {
cornerRadius = dp(8.dp)
}
colors[R.styleable.Keyboard_Key_keyPreviewTextColor] = onPrimaryContainer
moreKeysTextColor = onPrimaryContainer
moreKeysKeyboardBackground = coloredRoundedRectangle(primaryContainer, dp(28.dp)).apply {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val padding = dp(4.dp).roundToInt()
setPadding(padding, padding, padding, padding)
}
}
moreKeysKeyboardBackground = coloredRoundedRectangle(primaryContainer, dp(8.dp))
assert(icons.keys == KeyboardIconsSet.validIcons) {
"Icons differ. Missing: ${KeyboardIconsSet.validIcons - icons.keys}, extraneous: ${icons.keys - KeyboardIconsSet.validIcons}"