Home | History | Annotate | Download | only in ui
      1 /*
      2  * Copyright (C) 2010 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 javax.microedition.khronos.opengles.GL11;
     20 
     21 import android.graphics.Rect;
     22 import android.view.MotionEvent;
     23 import android.view.View.MeasureSpec;
     24 import android.view.animation.AlphaAnimation;
     25 
     26 public class IndicatorBar extends GLView {
     27 
     28     public static final int INDEX_NONE = -1;
     29 
     30     private NinePatchTexture mBackground;
     31     private NinePatchTexture mHighlight;
     32     private int mSelectedIndex = INDEX_NONE;
     33 
     34     private OnItemSelectedListener mSelectedListener;
     35     private boolean mActivated = false;
     36 
     37     private boolean mSelectionChanged = false;
     38 
     39     private class Background extends GLView {
     40         @Override
     41         protected void render(GLRootView root, GL11 gl) {
     42             mBackground.setSize(getWidth(), getHeight());
     43             mBackground.draw(root, 0, 0);
     44 
     45             if (mActivated && mSelectedIndex != INDEX_NONE
     46                     && mHighlight != null) {
     47                 Rect bounds = IndicatorBar.this.getComponent(
     48                         mSelectedIndex + 1).mBounds;
     49                 mHighlight.setSize(bounds.width(), bounds.height());
     50                 mHighlight.draw(root, bounds.left, bounds.top);
     51             }
     52         }
     53     }
     54 
     55     public interface OnItemSelectedListener {
     56         public void onItemSelected(GLView view, int position);
     57         public void onNothingSelected();
     58     }
     59 
     60     public IndicatorBar() {
     61         GLView background = new Background();
     62         background.setVisibility(GLView.INVISIBLE);
     63         addComponent(background);
     64     }
     65 
     66     public void overrideSettings(String key, String value) {
     67         for (int i = 1, n = getComponentCount(); i < n; ++i) {
     68             AbstractIndicator indicator = (AbstractIndicator) getComponent(i);
     69             indicator.overrideSettings(key, value);
     70         }
     71     }
     72 
     73     public void setOnItemSelectedListener(OnItemSelectedListener l) {
     74         mSelectedListener = l;
     75     }
     76 
     77     public void setBackground(NinePatchTexture background) {
     78         if (mBackground == background) return;
     79         mBackground = background;
     80         if (background != null) {
     81             setPaddings(background.getPaddings());
     82         } else {
     83             setPaddings(0, 0, 0, 0);
     84         }
     85         invalidate();
     86     }
     87 
     88     public void setHighlight(NinePatchTexture highlight) {
     89         if (mHighlight == highlight) return;
     90         mHighlight = highlight;
     91         invalidate();
     92     }
     93 
     94     @Override
     95     protected void onMeasure(int widthSpec, int heightSpec) {
     96         int width = 0;
     97         int height = 0;
     98         for (int i = 1, n = getComponentCount(); i < n; ++i) {
     99             GLView component = getComponent(i);
    100             component.measure(
    101                     MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
    102             width = Math.max(width, component.getMeasuredWidth());
    103             height += component.getMeasuredHeight();
    104         }
    105         new MeasureHelper(this)
    106                 .setPreferredContentSize(width, height)
    107                 .measure(widthSpec, heightSpec);
    108     }
    109 
    110     @Override
    111     protected void onLayout(
    112             boolean changed, int left, int top, int right, int bottom) {
    113         // Background
    114         getComponent(0).layout(0, 0, right - left, bottom - top);
    115 
    116         int count = getComponentCount();
    117         Rect p = mPaddings;
    118         int cBottom = bottom - top - p.bottom;
    119         int cRight = right - left - p.right;
    120         int yoffset = mPaddings.top;
    121         int xoffset = mPaddings.left;
    122         for (int i = 1; i < count; ++i) {
    123             int cHeight = (cBottom - yoffset) / (count - i);
    124             int nextYoffset = yoffset + cHeight;
    125             getComponent(i).layout(xoffset, yoffset, cRight, nextYoffset);
    126             yoffset = nextYoffset;
    127         }
    128     }
    129 
    130     private void setSelectedItem(GLView view, int index) {
    131         if (index == mSelectedIndex) return;
    132         mSelectionChanged = true;
    133         mSelectedIndex = index;
    134         if (mSelectedListener != null) {
    135             if (index == INDEX_NONE) {
    136                 mSelectedListener.onNothingSelected();
    137             } else {
    138                 mSelectedListener.onItemSelected(view, index);
    139             }
    140         }
    141         invalidate();
    142     }
    143 
    144     public void setSelectedIndex(int index) {
    145         if (index == mSelectedIndex) return;
    146         setSelectedItem(index == INDEX_NONE ? null :getComponent(index), index);
    147     }
    148 
    149     public void setActivated(boolean activated) {
    150         if (activated == mActivated) return;
    151         mActivated = activated;
    152         if (activated) {
    153             GLView background = getComponent(0);
    154             background.setVisibility(GLView.VISIBLE);
    155             AlphaAnimation anim = new AlphaAnimation(0, 1);
    156             anim.setDuration(200);
    157             background.startAnimation(anim);
    158         } else {
    159             GLView background = getComponent(0);
    160             background.setVisibility(GLView.INVISIBLE);
    161             AlphaAnimation anim = new AlphaAnimation(1, 0);
    162             anim.setDuration(200);
    163             background.startAnimation(anim);
    164         }
    165     }
    166 
    167     public boolean isActivated() {
    168         return mActivated;
    169     }
    170 
    171     @Override
    172     protected boolean dispatchTouchEvent(MotionEvent event) {
    173         // Do not pass motion events to children
    174         return onTouch(event);
    175     }
    176 
    177     @Override @SuppressWarnings("fallthrough")
    178     protected boolean onTouch(MotionEvent event) {
    179         int y = (int) event.getY();
    180         switch (event.getAction()) {
    181             case MotionEvent.ACTION_DOWN:
    182                 mSelectionChanged = false;
    183                 setActivated(true);
    184             case MotionEvent.ACTION_MOVE:
    185                 for (int i = 1, n = getComponentCount(); i < n; ++i) {
    186                     GLView component = getComponent(i);
    187                     if (y <= component.mBounds.bottom) {
    188                         setSelectedItem(component, i - 1);
    189                         return true;
    190                     }
    191                 }
    192                 setSelectedItem(null, INDEX_NONE);
    193                 break;
    194             case MotionEvent.ACTION_UP:
    195                 if (mSelectionChanged == false) {
    196                     setSelectedItem(null, INDEX_NONE);
    197                 }
    198         }
    199         return true;
    200     }
    201 
    202     public void reloadPreferences() {
    203         for (int i = 1, n = getComponentCount(); i < n; ++i) {
    204             ((AbstractIndicator) getComponent(i)).reloadPreferences();
    205         }
    206     }
    207 
    208     public void setOrientation(int orientation) {
    209         for (int i = 1, n = getComponentCount(); i < n; ++i) {
    210             ((AbstractIndicator) getComponent(i)).setOrientation(orientation);
    211         }
    212     }
    213 
    214     public int getSelectedIndex() {
    215         return mSelectedIndex;
    216     }
    217 }
    218