Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit edf5daa8 authored by Tadashi G. Takaoka's avatar Tadashi G. Takaoka Committed by Android (Google) Code Review
Browse files

Merge "Support invalidating multiple keys in KeyboardView"

parents bd4ba23d 299ac263
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -114,7 +114,7 @@


        <attr name="shadowColor" format="color" />
        <attr name="shadowColor" format="color" />
        <attr name="shadowRadius" format="float" />
        <attr name="shadowRadius" format="float" />
        <attr name="backgroundDimAmount" format="float" />
        <attr name="backgroundDimAlpha" format="integer" />


        <attr name="keyTextStyle" format="enum">
        <attr name="keyTextStyle" format="enum">
            <!-- This should be aligned with Typeface.NORMAL etc. -->
            <!-- This should be aligned with Typeface.NORMAL etc. -->
+1 −1
Original line number Original line Diff line number Diff line
@@ -65,7 +65,7 @@
        <item name="verticalCorrection">@dimen/keyboard_vertical_correction</item>
        <item name="verticalCorrection">@dimen/keyboard_vertical_correction</item>
        <item name="shadowColor">#BB000000</item>
        <item name="shadowColor">#BB000000</item>
        <item name="shadowRadius">2.75</item>
        <item name="shadowRadius">2.75</item>
        <item name="backgroundDimAmount">0.5</item>
        <item name="backgroundDimAlpha">128</item>
        <!-- Common attributes of LatinKeyboardView -->
        <!-- Common attributes of LatinKeyboardView -->
        <item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item>
        <item name="keyHysteresisDistance">@dimen/config_key_hysteresis_distance</item>
        <item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item>
        <item name="touchNoiseThresholdTime">@integer/config_touch_noise_threshold_time</item>
+49 −42
Original line number Original line Diff line number Diff line
@@ -44,11 +44,12 @@ import com.android.inputmethod.latin.StaticInnerHandlerWrapper;
import com.android.inputmethod.latin.StringUtils;
import com.android.inputmethod.latin.StringUtils;


import java.util.HashMap;
import java.util.HashMap;
import java.util.HashSet;


/**
/**
 * A view that renders a virtual {@link Keyboard}.
 * A view that renders a virtual {@link Keyboard}.
 *
 *
 * @attr ref R.styleable#KeyboardView_backgroundDimAmount
 * @attr ref R.styleable#KeyboardView_backgroundDimAlpha
 * @attr ref R.styleable#KeyboardView_keyBackground
 * @attr ref R.styleable#KeyboardView_keyBackground
 * @attr ref R.styleable#KeyboardView_keyLetterRatio
 * @attr ref R.styleable#KeyboardView_keyLetterRatio
 * @attr ref R.styleable#KeyboardView_keyLargeLetterRatio
 * @attr ref R.styleable#KeyboardView_keyLargeLetterRatio
@@ -81,7 +82,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
    // XML attributes
    // XML attributes
    protected final float mVerticalCorrection;
    protected final float mVerticalCorrection;
    protected final int mMoreKeysLayout;
    protected final int mMoreKeysLayout;
    private final float mBackgroundDimAmount;
    private final int mBackgroundDimAlpha;


    // HORIZONTAL ELLIPSIS "...", character for popup hint.
    // HORIZONTAL ELLIPSIS "...", character for popup hint.
    private static final String POPUP_HINT_CHAR = "\u2026";
    private static final String POPUP_HINT_CHAR = "\u2026";
@@ -110,12 +111,12 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
    private boolean mNeedsToDimBackground;
    private boolean mNeedsToDimBackground;
    /** Whether the keyboard bitmap buffer needs to be redrawn before it's blitted. **/
    /** Whether the keyboard bitmap buffer needs to be redrawn before it's blitted. **/
    private boolean mBufferNeedsUpdate;
    private boolean mBufferNeedsUpdate;
    /** The dirty region in the keyboard bitmap */
    /** True if all keys should be drawn */
    private final Rect mDirtyRect = new Rect();
    private boolean mInvalidateAllKeys;
    /** The key to invalidate. */
    /** The keys that should be drawn */
    private Key mInvalidatedKey;
    private final HashSet<Key> mInvalidatedKeys = new HashSet<Key>();
    /** The dirty region for single key drawing */
    /** The region of invalidated keys */
    private final Rect mInvalidatedKeyRect = new Rect();
    private final Rect mInvalidatedKeysRect = new Rect();
    /** The keyboard bitmap buffer for faster updates */
    /** The keyboard bitmap buffer for faster updates */
    private Bitmap mBuffer;
    private Bitmap mBuffer;
    /** The canvas for the above mutable keyboard bitmap */
    /** The canvas for the above mutable keyboard bitmap */
@@ -335,7 +336,7 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
        mVerticalCorrection = a.getDimensionPixelOffset(
        mVerticalCorrection = a.getDimensionPixelOffset(
                R.styleable.KeyboardView_verticalCorrection, 0);
                R.styleable.KeyboardView_verticalCorrection, 0);
        mMoreKeysLayout = a.getResourceId(R.styleable.KeyboardView_moreKeysLayout, 0);
        mMoreKeysLayout = a.getResourceId(R.styleable.KeyboardView_moreKeysLayout, 0);
        mBackgroundDimAmount = a.getFloat(R.styleable.KeyboardView_backgroundDimAmount, 0.5f);
        mBackgroundDimAlpha = a.getInt(R.styleable.KeyboardView_backgroundDimAlpha, 0);
        a.recycle();
        a.recycle();


        mDelayAfterPreview = mKeyPreviewDrawParams.mLingerTimeout;
        mDelayAfterPreview = mKeyPreviewDrawParams.mLingerTimeout;
@@ -366,8 +367,6 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
        mKeyboard = keyboard;
        mKeyboard = keyboard;
        LatinImeLogger.onSetKeyboard(keyboard);
        LatinImeLogger.onSetKeyboard(keyboard);
        requestLayout();
        requestLayout();
        mDirtyRect.set(0, 0, getWidth(), getHeight());
        mBufferNeedsUpdate = true;
        invalidateAllKeys();
        invalidateAllKeys();
        final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
        final int keyHeight = keyboard.mMostCommonKeyHeight - keyboard.mVerticalGap;
        mKeyDrawParams.updateKeyHeight(keyHeight);
        mKeyDrawParams.updateKeyHeight(keyHeight);
@@ -434,47 +433,50 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
            if (mBuffer != null)
            if (mBuffer != null)
                mBuffer.recycle();
                mBuffer.recycle();
            mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            mBuffer = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
            mDirtyRect.union(0, 0, width, height);
            mInvalidateAllKeys = true;
            if (mCanvas != null) {
            if (mCanvas != null) {
                mCanvas.setBitmap(mBuffer);
                mCanvas.setBitmap(mBuffer);
            } else {
            } else {
                mCanvas = new Canvas(mBuffer);
                mCanvas = new Canvas(mBuffer);
            }
            }
        }
        }
        final Canvas canvas = mCanvas;
        canvas.clipRect(mDirtyRect, Op.REPLACE);
        canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);


        if (mKeyboard == null) return;
        if (mKeyboard == null) return;


        final Canvas canvas = mCanvas;
        final Paint paint = mPaint;
        final KeyDrawParams params = mKeyDrawParams;
        final KeyDrawParams params = mKeyDrawParams;
        if (mInvalidatedKey != null && mInvalidatedKeyRect.contains(mDirtyRect)) {

            // Draw a single key.
        if (mInvalidateAllKeys || mInvalidatedKeys.isEmpty()) {
            final int keyDrawX = mInvalidatedKey.mX + mInvalidatedKey.mVisualInsetsLeft
            mInvalidatedKeysRect.set(0, 0, getWidth(), getHeight());
                    + getPaddingLeft();
            canvas.clipRect(mInvalidatedKeysRect, Op.REPLACE);
            final int keyDrawY = mInvalidatedKey.mY + getPaddingTop();
            canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);
            canvas.translate(keyDrawX, keyDrawY);
            onDrawKey(mInvalidatedKey, canvas, mPaint, params);
            canvas.translate(-keyDrawX, -keyDrawY);
        } else {
            // Draw all keys.
            // Draw all keys.
            for (final Key key : mKeyboard.mKeys) {
            for (final Key key : mKeyboard.mKeys) {
                final int keyDrawX = key.mX + key.mVisualInsetsLeft + getPaddingLeft();
                onDrawKey(key, canvas, paint, params);
                final int keyDrawY = key.mY + getPaddingTop();
            }
                canvas.translate(keyDrawX, keyDrawY);
        } else {
                onDrawKey(key, canvas, mPaint, params);
            // Draw invalidated keys.
                canvas.translate(-keyDrawX, -keyDrawY);
            for (final Key key : mInvalidatedKeys) {
                final int x = key.mX + getPaddingLeft();
                final int y = key.mY + getPaddingTop();
                mInvalidatedKeysRect.set(x, y, x + key.mWidth, y + key.mHeight);
                canvas.clipRect(mInvalidatedKeysRect, Op.REPLACE);
                canvas.drawColor(Color.BLACK, PorterDuff.Mode.CLEAR);
                onDrawKey(key, canvas, paint, params);
            }
            }
        }
        }


        // Overlay a dark rectangle to dim the entire keyboard
        // Overlay a dark rectangle to dim the entire keyboard
        if (mNeedsToDimBackground) {
        if (mNeedsToDimBackground) {
            mPaint.setColor((int) (mBackgroundDimAmount * 0xFF) << 24);
            paint.setColor(Color.BLACK);
            canvas.drawRect(0, 0, width, height, mPaint);
            paint.setAlpha(mBackgroundDimAlpha);
            canvas.drawRect(0, 0, width, height, paint);
        }
        }


        mInvalidatedKey = null;
        mInvalidatedKeys.clear();
        mDirtyRect.setEmpty();
        mInvalidatedKeysRect.setEmpty();
        mInvalidateAllKeys = false;
    }
    }


    public void dimEntireKeyboard(boolean dimmed) {
    public void dimEntireKeyboard(boolean dimmed) {
@@ -486,10 +488,16 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
    }
    }


    private void onDrawKey(Key key, Canvas canvas, Paint paint, KeyDrawParams params) {
    private void onDrawKey(Key key, Canvas canvas, Paint paint, KeyDrawParams params) {
        final int keyDrawX = key.mX + key.mVisualInsetsLeft + getPaddingLeft();
        final int keyDrawY = key.mY + getPaddingTop();
        canvas.translate(keyDrawX, keyDrawY);

        if (!key.isSpacer()) {
        if (!key.isSpacer()) {
            onDrawKeyBackground(key, canvas, params);
            onDrawKeyBackground(key, canvas, params);
        }
        }
        onDrawKeyTopVisuals(key, canvas, paint, params);
        onDrawKeyTopVisuals(key, canvas, paint, params);

        canvas.translate(-keyDrawX, -keyDrawY);
    }
    }


    // Draw key background.
    // Draw key background.
@@ -905,9 +913,9 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
     * @see #invalidateKey(Key)
     * @see #invalidateKey(Key)
     */
     */
    public void invalidateAllKeys() {
    public void invalidateAllKeys() {
        mDirtyRect.union(0, 0, getWidth(), getHeight());
        mInvalidatedKeys.clear();
        mInvalidateAllKeys = true;
        mBufferNeedsUpdate = true;
        mBufferNeedsUpdate = true;
        mInvalidatedKey = null;
        invalidate();
        invalidate();
    }
    }


@@ -920,22 +928,21 @@ public class KeyboardView extends View implements PointerTracker.DrawingProxy {
     */
     */
    @Override
    @Override
    public void invalidateKey(Key key) {
    public void invalidateKey(Key key) {
        if (key == null)
        if (mInvalidateAllKeys) return;
            return;
        if (key == null) return;
        mInvalidatedKey = key;
        mInvalidatedKeys.add(key);
        final int x = key.mX + getPaddingLeft();
        final int x = key.mX + getPaddingLeft();
        final int y = key.mY + getPaddingTop();
        final int y = key.mY + getPaddingTop();
        mInvalidatedKeyRect.set(x, y, x + key.mWidth, y + key.mHeight);
        mInvalidatedKeysRect.union(x, y, x + key.mWidth, y + key.mHeight);
        mDirtyRect.union(mInvalidatedKeyRect);
        mBufferNeedsUpdate = true;
        mBufferNeedsUpdate = true;
        invalidate(mInvalidatedKeyRect);
        invalidate(mInvalidatedKeysRect);
    }
    }


    public void closing() {
    public void closing() {
        PointerTracker.dismissAllKeyPreviews();
        PointerTracker.dismissAllKeyPreviews();
        cancelAllMessages();
        cancelAllMessages();


        mDirtyRect.union(0, 0, getWidth(), getHeight());
        mInvalidateAllKeys = true;
        requestLayout();
        requestLayout();
    }
    }