Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2013 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.camera.ui;
     18 
     19 import android.content.Context;
     20 import android.graphics.Canvas;
     21 import android.graphics.Typeface;
     22 import android.graphics.drawable.Drawable;
     23 import android.util.AttributeSet;
     24 import android.view.MotionEvent;
     25 import android.widget.FrameLayout;
     26 import android.widget.TextView;
     27 
     28 import com.android.camera.util.ApiHelper;
     29 import com.android.camera2.R;
     30 
     31 /**
     32  * This is a package private class, as it is not intended to be visible or used
     33  * outside of this package.
     34  *
     35  * ModeSelectorItem is a FrameLayout that contains an ImageView to display the
     36  * icon for the corresponding mode, a TextView that explains what the mode is,
     37  * and a GradientDrawable at the end of the TextView.
     38  *
     39  * The purpose of this class is to encapsulate different drawing logic into
     40  * its own class. There are two drawing mode, <code>FLY_IN</code>
     41  * and <code>FLY_OUT</code>. They define how we draw the view when
     42  * we display the view partially.
     43  */
     44 class ModeSelectorItem extends FrameLayout {
     45     private TextView mText;
     46     private ModeIconView mIcon;
     47     private int mVisibleWidth = 0;
     48     private final int mMinVisibleWidth;
     49     private VisibleWidthChangedListener mListener = null;
     50 
     51     private int mWidth;
     52     private int mModeId;
     53 
     54     /**
     55      * A listener that gets notified when the visible width of the current item
     56      * is changed.
     57      */
     58     public interface VisibleWidthChangedListener {
     59         public void onVisibleWidthChanged(int width);
     60     }
     61 
     62     public ModeSelectorItem(Context context, AttributeSet attrs) {
     63         super(context, attrs);
     64         setWillNotDraw(false);
     65         setClickable(true);
     66         mMinVisibleWidth = getResources()
     67                 .getDimensionPixelSize(R.dimen.mode_selector_icon_block_width);
     68     }
     69 
     70     @Override
     71     public void onFinishInflate() {
     72         mIcon = (ModeIconView) findViewById(R.id.selector_icon);
     73         mText = (TextView) findViewById(R.id.selector_text);
     74         Typeface typeface;
     75         if (ApiHelper.HAS_ROBOTO_MEDIUM_FONT) {
     76             typeface = Typeface.create("sans-serif-medium", Typeface.NORMAL);
     77         } else {
     78             // Load roboto_light typeface from assets.
     79             typeface = Typeface.createFromAsset(getResources().getAssets(),
     80                     "Roboto-Medium.ttf");
     81         }
     82         mText.setTypeface(typeface);
     83     }
     84 
     85     public void setDefaultBackgroundColor(int color) {
     86         setBackgroundColor(color);
     87     }
     88 
     89     /**
     90      * Sets a listener that receives a callback when the visible width of this
     91      * selector item changes.
     92      */
     93     public void setVisibleWidthChangedListener(VisibleWidthChangedListener listener) {
     94         mListener = listener;
     95     }
     96 
     97     @Override
     98     public void setSelected(boolean selected) {
     99         mIcon.setSelected(selected);
    100     }
    101 
    102     @Override
    103     public boolean dispatchTouchEvent(MotionEvent ev) {
    104         // Do not dispatch any touch event, so that all the events that are received
    105         // in onTouchEvent() are only through forwarding.
    106          return false;
    107     }
    108 
    109     @Override
    110     public boolean onTouchEvent(MotionEvent ev) {
    111         super.onTouchEvent(ev);
    112         return false;
    113     }
    114 
    115     /**
    116      * When swiping in, we truncate the end of the item if the visible width
    117      * is not enough to show the whole item. When swiping out, we truncate the
    118      * front of the text (i.e. offset the text).
    119      *
    120      * @param swipeIn whether swiping direction is swiping in (i.e. from left
    121      *                to right)
    122      */
    123     public void onSwipeModeChanged(boolean swipeIn) {
    124         mText.setTranslationX(0);
    125     }
    126 
    127     public void setText(CharSequence text) {
    128         mText.setText(text);
    129     }
    130 
    131     @Override
    132     public void onLayout(boolean changed, int left, int top, int right, int bottom) {
    133         super.onLayout(changed, left, top, right, bottom);
    134         mWidth = right - left;
    135         if (changed && mVisibleWidth > 0) {
    136             // Reset mode list to full screen
    137             setVisibleWidth(mWidth);
    138         }
    139     }
    140 
    141     /**
    142      * Sets image resource as the icon for the mode. By default, all drawables instances
    143      * loaded from the same resource share a common state; if you modify the state
    144      * of one instance, all the other instances will receive the same modification.
    145      * In order to modify properties of this icon drawable without affecting other
    146      * drawables, here we use a mutable drawable which is guaranteed to not share
    147      * states with other drawables.
    148      *
    149      * @param resource resource id of the asset to be used as icon
    150      */
    151     public void setImageResource(int resource) {
    152         Drawable drawableIcon = getResources().getDrawable(resource);
    153         if (drawableIcon != null) {
    154             drawableIcon = drawableIcon.mutate();
    155         }
    156         mIcon.setIconDrawable(drawableIcon);
    157     }
    158 
    159     /**
    160      * Sets the visible width preferred for the item. The item can then decide how
    161      * to draw itself based on the visible width and whether it's being swiped in
    162      * or out. This function will be called on every frame during animation. It should
    163      * only do minimal work required to get the animation working.
    164      *
    165      * @param newWidth new visible width
    166      */
    167     public void setVisibleWidth(int newWidth) {
    168         int fullyShownIconWidth = getMaxVisibleWidth();
    169         newWidth = Math.max(newWidth, 0);
    170         // Visible width should not be greater than view width
    171         newWidth = Math.min(newWidth, fullyShownIconWidth);
    172 
    173         if (mVisibleWidth != newWidth) {
    174             mVisibleWidth = newWidth;
    175             if (mListener != null) {
    176                 mListener.onVisibleWidthChanged(newWidth);
    177             }
    178         }
    179         invalidate();
    180     }
    181 
    182     /**
    183      * Getter for visible width. This function will get called during animation as
    184      * well.
    185      *
    186      * @return The visible width of this item
    187      */
    188     public int getVisibleWidth() {
    189         return mVisibleWidth;
    190     }
    191 
    192     /**
    193      * Draw the view based on the drawing mode. Clip the canvas if necessary.
    194      *
    195      * @param canvas The Canvas to which the View is rendered.
    196      */
    197     @Override
    198     public void draw(Canvas canvas) {
    199         float transX = 0f;
    200         // If the given width is less than the icon width, we need to translate icon
    201         if (mVisibleWidth < mMinVisibleWidth + mIcon.getLeft()) {
    202             transX = mMinVisibleWidth + mIcon.getLeft() - mVisibleWidth;
    203         }
    204         canvas.save();
    205         canvas.translate(-transX, 0);
    206         super.draw(canvas);
    207         canvas.restore();
    208     }
    209 
    210     /**
    211      * Sets the color that will be used in the drawable for highlight state.
    212      *
    213      * @param highlightColor color for the highlight state
    214      */
    215     public void setHighlightColor(int highlightColor) {
    216         mIcon.setHighlightColor(highlightColor);
    217     }
    218 
    219     /**
    220      * @return highlightColor color for the highlight state
    221      */
    222     public int getHighlightColor() {
    223         return mIcon.getHighlightColor();
    224     }
    225 
    226     /**
    227      * Gets the maximum visible width of the mode icon. The mode item will be
    228      * full shown when the mode icon has max visible width.
    229      */
    230     public int getMaxVisibleWidth() {
    231         return mIcon.getLeft() + mMinVisibleWidth;
    232     }
    233 
    234     /**
    235      * Gets the position of the icon center relative to the window.
    236      *
    237      * @param loc integer array of size 2, to hold the position x and y
    238      */
    239     public void getIconCenterLocationInWindow(int[] loc) {
    240         mIcon.getLocationInWindow(loc);
    241         loc[0] += mMinVisibleWidth / 2;
    242         loc[1] += mMinVisibleWidth / 2;
    243     }
    244 
    245     /**
    246      * Sets the mode id of the current item.
    247      *
    248      * @param modeId id of the mode represented by current item.
    249      */
    250     public void setModeId(int modeId) {
    251         mModeId = modeId;
    252     }
    253 
    254     /**
    255      * Gets the mode id of the current item.
    256      */
    257     public int getModeId() {
    258         return mModeId;
    259     }
    260 
    261     /**
    262      * @return The {@link ModeIconView} attached to this item.
    263      */
    264     public ModeIconView getIcon() {
    265         return mIcon;
    266     }
    267 
    268     /**
    269      * Sets the alpha on the mode text.
    270      */
    271     public void setTextAlpha(float alpha) {
    272         mText.setAlpha(alpha);
    273     }
    274 }
    275