Fix calculation of more keys keyboard position based on key preview

Bug: 6135881
Change-Id: Id1c4e2c13d13b474466cb9b42b425aa9f6f9448b
This commit is contained in:
Tadashi G. Takaoka 2012-04-27 23:44:28 +09:00
parent 47021b7a94
commit 7ecc1081ab
12 changed files with 96 additions and 137 deletions

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<resources>
<dimen name="keyboard_key_feedback_background_holo_width">46.67dp</dimen>
<dimen name="keyboard_key_feedback_background_holo_height">58.67dp</dimen>
</resources>

View file

@ -53,7 +53,7 @@
<fraction name="key_uppercase_letter_ratio">40%</fraction>
<fraction name="key_preview_text_ratio">90%</fraction>
<fraction name="spacebar_text_ratio">40.000%</fraction>
<dimen name="key_preview_offset">12.8dp</dimen>
<dimen name="key_preview_offset">0.0dp</dimen>
<dimen name="key_preview_offset_ics">1.6dp</dimen>
<!-- popup_key_height x -0.5 -->

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<resources>
<dimen name="keyboard_key_feedback_background_holo_width">46dp</dimen>
<dimen name="keyboard_key_feedback_background_holo_height">58dp</dimen>
</resources>

View file

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
**
** Copyright 2011, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
-->
<resources>
<dimen name="keyboard_key_feedback_background_holo_width">47dp</dimen>
<dimen name="keyboard_key_feedback_background_holo_height">57dp</dimen>
</resources>

View file

@ -91,10 +91,6 @@
<attr name="keyPreviewLeftBackground" format="reference" />
<!-- The background for the right edge key press feedback. -->
<attr name="keyPreviewRightBackground" format="reference" />
<!-- The width of rectangle part of the key press feedback background. -->
<attr name="keyPreviewBackgroundWidth" format="dimension" />
<!-- The height of rectangle part of the key press feedback background. -->
<attr name="keyPreviewBackgroundHeight" format="dimension" />
<!-- The text color for key press feedback. -->
<attr name="keyPreviewTextColor" format="color" />
<!-- Vertical offset of the key press feedback from the key. -->

View file

@ -27,7 +27,6 @@
<dimen name="popup_key_height">52.8dp</dimen>
<dimen name="more_keys_keyboard_horizontal_edges_padding">16dp</dimen>
<dimen name="more_keys_keyboard_key_horizontal_padding">8dp</dimen>
<fraction name="keyboard_top_padding">1.556%p</fraction>
@ -66,7 +65,7 @@
<fraction name="key_preview_text_ratio">82%</fraction>
<fraction name="spacebar_text_ratio">33.735%</fraction>
<dimen name="key_preview_height">80dp</dimen>
<dimen name="key_preview_offset">16.0dp</dimen>
<dimen name="key_preview_offset">-8.0dp</dimen>
<dimen name="key_label_horizontal_padding">4dp</dimen>
<dimen name="key_hint_letter_padding">1dp</dimen>

View file

@ -108,8 +108,6 @@
</style>
<style name="MoreKeysKeyboardPanelStyle">
<item name="android:background">@drawable/keyboard_popup_panel_background</item>
<item name="android:paddingLeft">@dimen/more_keys_keyboard_horizontal_edges_padding</item>
<item name="android:paddingRight">@dimen/more_keys_keyboard_horizontal_edges_padding</item>
</style>
<style name="SuggestionsStripBackgroundStyle">
<item name="android:background">@drawable/keyboard_suggest_strip</item>
@ -311,8 +309,6 @@
<item name="keyPreviewBackground">@drawable/keyboard_key_feedback_ics</item>
<item name="keyPreviewLeftBackground">@drawable/keyboard_key_feedback_left_ics</item>
<item name="keyPreviewRightBackground">@drawable/keyboard_key_feedback_right_ics</item>
<item name="keyPreviewBackgroundWidth">@dimen/keyboard_key_feedback_background_holo_width</item>
<item name="keyPreviewBackgroundHeight">@dimen/keyboard_key_feedback_background_holo_height</item>
<item name="keyPreviewTextColor">#FFFFFFFF</item>
<item name="keyPreviewOffset">@dimen/key_preview_offset_ics</item>
<item name="shadowColor">#00000000</item>
@ -346,8 +342,6 @@
</style>
<style name="MoreKeysKeyboardPanelStyle.IceCreamSandwich">
<item name="android:background">@drawable/keyboard_popup_panel_background_holo</item>
<item name="android:paddingLeft">@dimen/more_keys_keyboard_horizontal_edges_padding_ics</item>
<item name="android:paddingRight">@dimen/more_keys_keyboard_horizontal_edges_padding_ics</item>
</style>
<style name="SuggestionsStripBackgroundStyle.IceCreamSandwich">
<item name="android:background">@drawable/keyboard_suggest_strip_holo</item>

View file

@ -272,8 +272,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
public final Drawable mPreviewBackground;
public final Drawable mPreviewLeftBackground;
public final Drawable mPreviewRightBackground;
public final int mPreviewBackgroundWidth;
public final int mPreviewBackgroundHeight;
public final int mPreviewTextColor;
public final int mPreviewOffset;
public final int mPreviewHeight;
@ -283,6 +281,31 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
private final float mPreviewTextRatio;
private final float mKeyLetterRatio;
// The graphical geometry of the key preview.
// <-width->
// +-------+ ^
// | | |
// |preview| height (visible)
// | | |
// + + ^ v
// \ / |offset
// +-\ /-+ v
// | +-+ |
// |parent |
// | key|
// +-------+
// The background of a {@link TextView} being used for a key preview may have invisible
// paddings. To align the more keys keyboard panel's visible part with the visible part of
// the background, we need to record the width and height of key preview that don't include
// invisible paddings.
public int mPreviewVisibleWidth;
public int mPreviewVisibleHeight;
// The key preview may have an arbitrary offset and its background that may have a bottom
// padding. To align the more keys keyboard and the key preview we also need to record the
// offset between the top edge of parent key and the bottom of the visible part of key
// preview background.
public int mPreviewVisibleOffset;
public int mPreviewTextSize;
public int mKeyLetterSize;
public final int[] mCoordinates = new int[2];
@ -298,10 +321,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
setAlpha(mPreviewBackground, PREVIEW_ALPHA);
setAlpha(mPreviewLeftBackground, PREVIEW_ALPHA);
setAlpha(mPreviewRightBackground, PREVIEW_ALPHA);
mPreviewBackgroundWidth = a.getDimensionPixelSize(
R.styleable.KeyboardView_keyPreviewBackgroundWidth, 0);
mPreviewBackgroundHeight = a.getDimensionPixelSize(
R.styleable.KeyboardView_keyPreviewBackgroundHeight, 0);
mPreviewOffset = a.getDimensionPixelOffset(
R.styleable.KeyboardView_keyPreviewOffset, 0);
mPreviewHeight = a.getDimensionPixelSize(
@ -838,13 +857,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
}
}
@Override
public void showKeyPreview(PointerTracker tracker) {
if (mShowKeyPreviewPopup) {
showKey(tracker);
}
}
@Override
public void dismissKeyPreview(PointerTracker tracker) {
mDrawingHandler.dismissKeyPreview(mDelayAfterPreview, tracker);
@ -861,7 +873,10 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
keyPreview, ViewLayoutUtils.newLayoutParam(mPreviewPlacer, 0, 0));
}
private void showKey(PointerTracker tracker) {
@Override
public void showKeyPreview(PointerTracker tracker) {
if (!mShowKeyPreviewPopup) return;
final TextView previewText = tracker.getKeyPreviewText();
// If the key preview has no parent view yet, add it to the ViewGroup which can place
// key preview absolutely in SoftInputWindow.
@ -878,8 +893,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
return;
final KeyPreviewDrawParams params = mKeyPreviewDrawParams;
final int keyDrawX = key.mX + key.mVisualInsetsLeft;
final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
final String label = key.isShiftedLetterActivated() ? key.mHintLabel : key.mLabel;
// What we show as preview should match what we show on a key top in onBufferDraw().
if (label != null) {
@ -902,13 +915,24 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
previewText.measure(
ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
final int previewWidth = Math.max(previewText.getMeasuredWidth(), keyDrawWidth
+ previewText.getPaddingLeft() + previewText.getPaddingRight());
final int keyDrawWidth = key.mWidth - key.mVisualInsetsLeft - key.mVisualInsetsRight;
final int previewWidth = previewText.getMeasuredWidth();
final int previewHeight = params.mPreviewHeight;
// The width and height of visible part of the key preview background. The content marker
// of the background 9-patch have to cover the visible part of the background.
params.mPreviewVisibleWidth = previewWidth - previewText.getPaddingLeft()
- previewText.getPaddingRight();
params.mPreviewVisibleHeight = previewHeight - previewText.getPaddingTop()
- previewText.getPaddingBottom();
// The distance between the top edge of the parent key and the bottom of the visible part
// of the key preview background.
params.mPreviewVisibleOffset = params.mPreviewOffset - previewText.getPaddingBottom();
getLocationInWindow(params.mCoordinates);
int previewX = keyDrawX - (previewWidth - keyDrawWidth) / 2 + params.mCoordinates[0];
final int previewY = key.mY - previewHeight
+ params.mCoordinates[1] + params.mPreviewOffset;
// 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
// the left/right background is used if such background is specified.
int previewX = key.mX + key.mVisualInsetsLeft - (previewWidth - keyDrawWidth) / 2
+ params.mCoordinates[0];
if (previewX < 0) {
previewX = 0;
if (params.mPreviewLeftBackground != null) {
@ -920,6 +944,10 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
previewText.setBackgroundDrawable(params.mPreviewRightBackground);
}
}
// The key preview is placed vertically above the top edge of the parent key with an
// arbitrary offset.
final int previewY = key.mY - previewHeight + params.mPreviewOffset
+ params.mCoordinates[1];
// Set the preview background state
previewText.getBackground().setState(

View file

@ -527,9 +527,8 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
final MoreKeysKeyboardView moreKeysKeyboardView =
(MoreKeysKeyboardView)container.findViewById(R.id.more_keys_keyboard_view);
final Keyboard parentKeyboard = getKeyboard();
final Keyboard moreKeysKeyboard = new MoreKeysKeyboard.Builder(
this, parentKeyboard.mMoreKeysTemplate, parentKey, parentKeyboard).build();
final Keyboard moreKeysKeyboard = new MoreKeysKeyboard.Builder(container, parentKey, this)
.build();
moreKeysKeyboardView.setKeyboard(moreKeysKeyboard);
container.measure(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
@ -598,10 +597,19 @@ public class LatinKeyboardView extends KeyboardView implements PointerTracker.Ke
mMoreKeysPanel = moreKeysPanel;
mMoreKeysPanelPointerTrackerId = tracker.mPointerId;
final Keyboard keyboard = getKeyboard();
final int pointX = (mConfigShowMoreKeysKeyboardAtTouchedPoint) ? tracker.getLastX()
final boolean keyPreviewEnabled = isKeyPreviewPopupEnabled() && !parentKey.noKeyPreview();
// 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)
? tracker.getLastX()
: parentKey.mX + parentKey.mWidth / 2;
final int pointY = parentKey.mY - keyboard.mVerticalGap;
// 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.
final int pointY = parentKey.mY + (keyPreviewEnabled
? mKeyPreviewDrawParams.mPreviewVisibleOffset
: -parentKey.mVerticalGap);
moreKeysPanel.showMoreKeysPanel(
this, this, pointX, pointY, mMoreKeysWindow, mKeyboardActionListener);
final int translatedX = moreKeysPanel.translateX(tracker.getLastX());

View file

@ -18,6 +18,7 @@ package com.android.inputmethod.keyboard;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;
import android.view.View;
import com.android.inputmethod.keyboard.internal.KeySpecParser.MoreKeySpec;
import com.android.inputmethod.keyboard.internal.KeyboardIconsSet;
@ -251,30 +252,38 @@ public class MoreKeysKeyboard extends Keyboard {
}
}
public Builder(KeyboardView view, int xmlId, Key parentKey, Keyboard parentKeyboard) {
super(view.getContext(), new MoreKeysKeyboardParams());
load(xmlId, parentKeyboard.mId);
/**
* The builder of MoreKeysKeyboard.
* @param containerView the container of {@link MoreKeysKeyboardView}.
* @param parentKey the {@link Key} that invokes more keys keyboard.
* @param parentKeyboardView the {@link KeyboardView} that contains the parentKey.
*/
public Builder(View containerView, Key parentKey, KeyboardView parentKeyboardView) {
super(containerView.getContext(), new MoreKeysKeyboardParams());
final Keyboard parentKeyboard = parentKeyboardView.getKeyboard();
load(parentKeyboard.mMoreKeysTemplate, parentKeyboard.mId);
// TODO: More keys keyboard's vertical gap is currently calculated heuristically.
// Should revise the algorithm.
mParams.mVerticalGap = parentKeyboard.mVerticalGap / 2;
mParentKey = parentKey;
final int previewWidth = view.mKeyPreviewDrawParams.mPreviewBackgroundWidth;
final int previewHeight = view.mKeyPreviewDrawParams.mPreviewBackgroundHeight;
final int width, height;
// Use pre-computed width and height if these values are available and more keys
// keyboard has only one key to mitigate visual flicker between key preview and more
// keys keyboard.
final boolean validKeyPreview = view.isKeyPreviewPopupEnabled()
&& !parentKey.noKeyPreview() && (previewWidth > 0) && (previewHeight > 0);
final boolean singleMoreKeyWithPreview = validKeyPreview
&& parentKey.mMoreKeys.length == 1;
final boolean singleMoreKeyWithPreview = parentKeyboardView.isKeyPreviewPopupEnabled()
&& !parentKey.noKeyPreview() && parentKey.mMoreKeys.length == 1;
if (singleMoreKeyWithPreview) {
width = previewWidth;
height = previewHeight + mParams.mVerticalGap;
// Use pre-computed width and height if this more keys keyboard has only one key to
// mitigate visual flicker between key preview and more keys keyboard.
// Caveats for the visual assets: To achieve this effect, both the key preview
// backgrounds and the more keys keyboard panel background have the exact same
// left/right/top paddings. The bottom paddings of both backgrounds don't need to
// be considered because the vertical positions of both backgrounds were already
// adjusted with their bottom paddings deducted.
width = parentKeyboardView.mKeyPreviewDrawParams.mPreviewVisibleWidth;
height = parentKeyboardView.mKeyPreviewDrawParams.mPreviewVisibleHeight
+ mParams.mVerticalGap;
} else {
width = getMaxKeyWidth(view, parentKey, mParams.mDefaultKeyWidth);
width = getMaxKeyWidth(parentKeyboardView, parentKey, mParams.mDefaultKeyWidth);
height = parentKeyboard.mMostCommonKeyHeight;
}
final int dividerWidth;
@ -288,8 +297,9 @@ public class MoreKeysKeyboard extends Keyboard {
dividerWidth = 0;
}
mParams.setParameters(parentKey.mMoreKeys.length, parentKey.getMoreKeysColumn(),
width, height, parentKey.mX + parentKey.mWidth / 2, view.getMeasuredWidth(),
parentKey.isFixedColumnOrderMoreKeys(), dividerWidth);
width, height, parentKey.mX + parentKey.mWidth / 2,
parentKeyboardView.getMeasuredWidth(), parentKey.isFixedColumnOrderMoreKeys(),
dividerWidth);
}
private static int getMaxKeyWidth(KeyboardView view, Key parentKey, int minKeyWidth) {

View file

@ -141,10 +141,8 @@ public class MoreKeysKeyboardView extends KeyboardView implements MoreKeysPanel
final MoreKeysKeyboard pane = (MoreKeysKeyboard)getKeyboard();
final int defaultCoordX = pane.getDefaultCoordX();
// The coordinates of panel's left-top corner in parentView's coordinate system.
final int x = pointX - defaultCoordX - container.getPaddingLeft()
+ parentView.getPaddingLeft();
final int y = pointY - container.getMeasuredHeight() + container.getPaddingBottom()
+ parentView.getPaddingTop();
final int x = pointX - defaultCoordX - container.getPaddingLeft();
final int y = pointY - container.getMeasuredHeight() + container.getPaddingBottom();
window.setContentView(container);
window.setWidth(container.getMeasuredWidth());

View file

@ -149,10 +149,8 @@ public class MoreSuggestionsView extends KeyboardView implements MoreKeysPanel {
final MoreSuggestions pane = (MoreSuggestions)getKeyboard();
final int defaultCoordX = pane.mOccupiedWidth / 2;
// The coordinates of panel's left-top corner in parentView's coordinate system.
final int x = pointX - defaultCoordX - container.getPaddingLeft()
+ parentView.getPaddingLeft();
final int y = pointY - container.getMeasuredHeight() + container.getPaddingBottom()
+ parentView.getPaddingTop();
final int x = pointX - defaultCoordX - container.getPaddingLeft();
final int y = pointY - container.getMeasuredHeight() + container.getPaddingBottom();
window.setContentView(container);
window.setWidth(container.getMeasuredWidth());