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 KeyPreviewDrawParams(final TypedArray mainKeyboardViewAttr)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 setVisibleOffset(final int previewVisibleOffset)87 public void setVisibleOffset(final int previewVisibleOffset) { 88 mVisibleOffset = previewVisibleOffset; 89 } 90 getVisibleOffset()91 public int getVisibleOffset() { 92 return mVisibleOffset; 93 } 94 setGeometry(final View previewTextView)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 getVisibleWidth()109 public int getVisibleWidth() { 110 return mVisibleWidth; 111 } 112 getVisibleHeight()113 public int getVisibleHeight() { 114 return mVisibleHeight; 115 } 116 setPopupEnabled(final boolean enabled, final int lingerTimeout)117 public void setPopupEnabled(final boolean enabled, final int lingerTimeout) { 118 mShowPopup = enabled; 119 mLingerTimeout = lingerTimeout; 120 } 121 isPopupEnabled()122 public boolean isPopupEnabled() { 123 return mShowPopup; 124 } 125 getLingerTimeout()126 public int getLingerTimeout() { 127 return mLingerTimeout; 128 } 129 setAnimationParams(final boolean hasCustomAnimationParams, final float showUpStartXScale, final float showUpStartYScale, final int showUpDuration, final float dismissEndXScale, final float dismissEndYScale, final int dismissDuration)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 createShowUpAnimator(final View target)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 createDismissAnimator(final View target)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