Home | History | Annotate | Download | only in internal
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 package com.android.inputmethod.keyboard.internal;
     18 
     19 import android.animation.Animator;
     20 import android.animation.AnimatorInflater;
     21 import android.animation.AnimatorSet;
     22 import android.animation.ObjectAnimator;
     23 import android.content.res.TypedArray;
     24 import android.view.View;
     25 import android.view.animation.AccelerateInterpolator;
     26 import android.view.animation.DecelerateInterpolator;
     27 
     28 import com.android.inputmethod.latin.R;
     29 
     30 public final class KeyPreviewDrawParams {
     31     // XML attributes of {@link MainKeyboardView}.
     32     public final int mPreviewOffset;
     33     public final int mPreviewHeight;
     34     public final int mPreviewBackgroundResId;
     35     private final int mShowUpAnimatorResId;
     36     private final int mDismissAnimatorResId;
     37     private boolean mHasCustomAnimationParams;
     38     private int mShowUpDuration;
     39     private int mDismissDuration;
     40     private float mShowUpStartXScale;
     41     private float mShowUpStartYScale;
     42     private float mDismissEndXScale;
     43     private float mDismissEndYScale;
     44     private int mLingerTimeout;
     45     private boolean mShowPopup = true;
     46 
     47     // The graphical geometry of the key preview.
     48     // <-width->
     49     // +-------+   ^
     50     // |       |   |
     51     // |preview| height (visible)
     52     // |       |   |
     53     // +       + ^ v
     54     //  \     /  |offset
     55     // +-\   /-+ v
     56     // |  +-+  |
     57     // |parent |
     58     // |    key|
     59     // +-------+
     60     // The background of a {@link TextView} being used for a key preview may have invisible
     61     // paddings. To align the more keys keyboard panel's visible part with the visible part of
     62     // the background, we need to record the width and height of key preview that don't include
     63     // invisible paddings.
     64     private int mVisibleWidth;
     65     private int mVisibleHeight;
     66     // The key preview may have an arbitrary offset and its background that may have a bottom
     67     // padding. To align the more keys keyboard and the key preview we also need to record the
     68     // offset between the top edge of parent key and the bottom of the visible part of key
     69     // preview background.
     70     private int mVisibleOffset;
     71 
     72     public KeyPreviewDrawParams(final TypedArray mainKeyboardViewAttr) {
     73         mPreviewOffset = mainKeyboardViewAttr.getDimensionPixelOffset(
     74                 R.styleable.MainKeyboardView_keyPreviewOffset, 0);
     75         mPreviewHeight = mainKeyboardViewAttr.getDimensionPixelSize(
     76                 R.styleable.MainKeyboardView_keyPreviewHeight, 0);
     77         mPreviewBackgroundResId = mainKeyboardViewAttr.getResourceId(
     78                 R.styleable.MainKeyboardView_keyPreviewBackground, 0);
     79         mLingerTimeout = mainKeyboardViewAttr.getInt(
     80                 R.styleable.MainKeyboardView_keyPreviewLingerTimeout, 0);
     81         mShowUpAnimatorResId = mainKeyboardViewAttr.getResourceId(
     82                 R.styleable.MainKeyboardView_keyPreviewShowUpAnimator, 0);
     83         mDismissAnimatorResId = mainKeyboardViewAttr.getResourceId(
     84                 R.styleable.MainKeyboardView_keyPreviewDismissAnimator, 0);
     85     }
     86 
     87     public void setVisibleOffset(final int previewVisibleOffset) {
     88         mVisibleOffset = previewVisibleOffset;
     89     }
     90 
     91     public int getVisibleOffset() {
     92         return mVisibleOffset;
     93     }
     94 
     95     public void setGeometry(final View previewTextView) {
     96         final int previewWidth = previewTextView.getMeasuredWidth();
     97         final int previewHeight = mPreviewHeight;
     98         // The width and height of visible part of the key preview background. The content marker
     99         // of the background 9-patch have to cover the visible part of the background.
    100         mVisibleWidth = previewWidth - previewTextView.getPaddingLeft()
    101                 - previewTextView.getPaddingRight();
    102         mVisibleHeight = previewHeight - previewTextView.getPaddingTop()
    103                 - previewTextView.getPaddingBottom();
    104         // The distance between the top edge of the parent key and the bottom of the visible part
    105         // of the key preview background.
    106         setVisibleOffset(mPreviewOffset - previewTextView.getPaddingBottom());
    107     }
    108 
    109     public int getVisibleWidth() {
    110         return mVisibleWidth;
    111     }
    112 
    113     public int getVisibleHeight() {
    114         return mVisibleHeight;
    115     }
    116 
    117     public void setPopupEnabled(final boolean enabled, final int lingerTimeout) {
    118         mShowPopup = enabled;
    119         mLingerTimeout = lingerTimeout;
    120     }
    121 
    122     public boolean isPopupEnabled() {
    123         return mShowPopup;
    124     }
    125 
    126     public int getLingerTimeout() {
    127         return mLingerTimeout;
    128     }
    129 
    130     public void setAnimationParams(final boolean hasCustomAnimationParams,
    131             final float showUpStartXScale, final float showUpStartYScale, final int showUpDuration,
    132             final float dismissEndXScale, final float dismissEndYScale, final int dismissDuration) {
    133         mHasCustomAnimationParams = hasCustomAnimationParams;
    134         mShowUpStartXScale = showUpStartXScale;
    135         mShowUpStartYScale = showUpStartYScale;
    136         mShowUpDuration = showUpDuration;
    137         mDismissEndXScale = dismissEndXScale;
    138         mDismissEndYScale = dismissEndYScale;
    139         mDismissDuration = dismissDuration;
    140     }
    141 
    142     private static final float KEY_PREVIEW_SHOW_UP_END_SCALE = 1.0f;
    143     private static final AccelerateInterpolator ACCELERATE_INTERPOLATOR =
    144             new AccelerateInterpolator();
    145     private static final DecelerateInterpolator DECELERATE_INTERPOLATOR =
    146             new DecelerateInterpolator();
    147 
    148     public Animator createShowUpAnimator(final View target) {
    149         if (mHasCustomAnimationParams) {
    150             final ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(
    151                     target, View.SCALE_X, mShowUpStartXScale,
    152                     KEY_PREVIEW_SHOW_UP_END_SCALE);
    153             final ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(
    154                     target, View.SCALE_Y, mShowUpStartYScale,
    155                     KEY_PREVIEW_SHOW_UP_END_SCALE);
    156             final AnimatorSet showUpAnimator = new AnimatorSet();
    157             showUpAnimator.play(scaleXAnimator).with(scaleYAnimator);
    158             showUpAnimator.setDuration(mShowUpDuration);
    159             showUpAnimator.setInterpolator(DECELERATE_INTERPOLATOR);
    160             return showUpAnimator;
    161         }
    162         final Animator animator = AnimatorInflater.loadAnimator(
    163                 target.getContext(), mShowUpAnimatorResId);
    164         animator.setTarget(target);
    165         animator.setInterpolator(DECELERATE_INTERPOLATOR);
    166         return animator;
    167     }
    168 
    169     public Animator createDismissAnimator(final View target) {
    170         if (mHasCustomAnimationParams) {
    171             final ObjectAnimator scaleXAnimator = ObjectAnimator.ofFloat(
    172                     target, View.SCALE_X, mDismissEndXScale);
    173             final ObjectAnimator scaleYAnimator = ObjectAnimator.ofFloat(
    174                     target, View.SCALE_Y, mDismissEndYScale);
    175             final AnimatorSet dismissAnimator = new AnimatorSet();
    176             dismissAnimator.play(scaleXAnimator).with(scaleYAnimator);
    177             final int dismissDuration = Math.min(mDismissDuration, mLingerTimeout);
    178             dismissAnimator.setDuration(dismissDuration);
    179             dismissAnimator.setInterpolator(ACCELERATE_INTERPOLATOR);
    180             return dismissAnimator;
    181         }
    182         final Animator animator = AnimatorInflater.loadAnimator(
    183                 target.getContext(), mDismissAnimatorResId);
    184         animator.setTarget(target);
    185         animator.setInterpolator(ACCELERATE_INTERPOLATOR);
    186         return animator;
    187     }
    188 }
    189