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