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.gallery3d.ui;
     18 
     19 import com.android.gallery3d.R;
     20 import com.android.gallery3d.anim.AlphaAnimation;
     21 import com.android.gallery3d.app.AlbumDataAdapter;
     22 import com.android.gallery3d.app.GalleryActivity;
     23 import com.android.gallery3d.data.MediaItem;
     24 import com.android.gallery3d.data.MediaSet;
     25 import com.android.gallery3d.data.Path;
     26 
     27 import android.content.Context;
     28 import android.view.MotionEvent;
     29 import android.view.View.MeasureSpec;
     30 
     31 public class FilmStripView extends GLView implements ScrollBarView.Listener,
     32         UserInteractionListener {
     33     @SuppressWarnings("unused")
     34     private static final String TAG = "FilmStripView";
     35 
     36     private static final int HIDE_ANIMATION_DURATION = 300;  // 0.3 sec
     37 
     38     public interface Listener {
     39         // Returns false if it cannot jump to the specified index at this time.
     40         boolean onSlotSelected(int slotIndex);
     41     }
     42 
     43     private int mTopMargin, mMidMargin, mBottomMargin;
     44     private int mContentSize, mBarSize, mGripSize;
     45     private AlbumView mAlbumView;
     46     private ScrollBarView mScrollBarView;
     47     private AlbumDataAdapter mAlbumDataAdapter;
     48     private StripDrawer mStripDrawer;
     49     private Listener mListener;
     50     private UserInteractionListener mUIListener;
     51     private NinePatchTexture mBackgroundTexture;
     52 
     53     // The layout of FileStripView is
     54     // topMargin
     55     //             ----+----+
     56     //            /    +----+--\
     57     // contentSize     |    |   thumbSize
     58     //            \    +----+--/
     59     //             ----+----+
     60     // midMargin
     61     //             ----+----+
     62     //            /    +----+--\
     63     //     barSize     |    |   gripSize
     64     //            \    +----+--/
     65     //             ----+----+
     66     // bottomMargin
     67     public FilmStripView(GalleryActivity activity, MediaSet mediaSet,
     68             int topMargin, int midMargin, int bottomMargin, int contentSize,
     69             int thumbSize, int barSize, int gripSize, int gripWidth) {
     70         mTopMargin = topMargin;
     71         mMidMargin = midMargin;
     72         mBottomMargin = bottomMargin;
     73         mContentSize = contentSize;
     74         mBarSize = barSize;
     75         mGripSize = gripSize;
     76 
     77         mStripDrawer = new StripDrawer((Context) activity);
     78         SlotView.Spec spec = new SlotView.Spec();
     79         spec.slotWidth = thumbSize;
     80         spec.slotHeight = thumbSize;
     81         mAlbumView = new AlbumView(activity, spec, thumbSize);
     82         mAlbumView.setOverscrollEffect(SlotView.OVERSCROLL_NONE);
     83         mAlbumView.setSelectionDrawer(mStripDrawer);
     84         mAlbumView.setListener(new SlotView.SimpleListener() {
     85             @Override
     86             public void onDown(int index) {
     87                 FilmStripView.this.onDown(index);
     88             }
     89             @Override
     90             public void onUp() {
     91                 FilmStripView.this.onUp();
     92             }
     93             @Override
     94             public void onSingleTapUp(int slotIndex) {
     95                 FilmStripView.this.onSingleTapUp(slotIndex);
     96             }
     97             @Override
     98             public void onLongTap(int slotIndex) {
     99                 FilmStripView.this.onLongTap(slotIndex);
    100             }
    101             @Override
    102             public void onScrollPositionChanged(int position, int total) {
    103                 FilmStripView.this.onScrollPositionChanged(position, total);
    104             }
    105         });
    106         mAlbumView.setUserInteractionListener(this);
    107         mAlbumDataAdapter = new AlbumDataAdapter(activity, mediaSet);
    108         addComponent(mAlbumView);
    109         mScrollBarView = new ScrollBarView(activity.getAndroidContext(),
    110                 mGripSize, gripWidth);
    111         mScrollBarView.setListener(this);
    112         addComponent(mScrollBarView);
    113 
    114         mAlbumView.setModel(mAlbumDataAdapter);
    115         mBackgroundTexture = new NinePatchTexture(activity.getAndroidContext(),
    116                 R.drawable.navstrip_translucent);
    117     }
    118 
    119     public void setListener(Listener listener) {
    120         mListener = listener;
    121     }
    122 
    123     public void setUserInteractionListener(UserInteractionListener listener) {
    124         mUIListener = listener;
    125     }
    126 
    127     public void show() {
    128         if (getVisibility() == GLView.VISIBLE) return;
    129         startAnimation(null);
    130         setVisibility(GLView.VISIBLE);
    131     }
    132 
    133     public void hide() {
    134         if (getVisibility() == GLView.INVISIBLE) return;
    135         AlphaAnimation animation = new AlphaAnimation(1, 0);
    136         animation.setDuration(HIDE_ANIMATION_DURATION);
    137         startAnimation(animation);
    138         setVisibility(GLView.INVISIBLE);
    139     }
    140 
    141     @Override
    142     protected void onVisibilityChanged(int visibility) {
    143         super.onVisibilityChanged(visibility);
    144         if (visibility == GLView.VISIBLE) {
    145             onUserInteraction();
    146         }
    147     }
    148 
    149     @Override
    150     protected void onMeasure(int widthSpec, int heightSpec) {
    151         int height = mTopMargin + mContentSize + mMidMargin + mBarSize + mBottomMargin;
    152         MeasureHelper.getInstance(this)
    153                 .setPreferredContentSize(MeasureSpec.getSize(widthSpec), height)
    154                 .measure(widthSpec, heightSpec);
    155     }
    156 
    157     @Override
    158     protected void onLayout(
    159             boolean changed, int left, int top, int right, int bottom) {
    160         if (!changed) return;
    161         mAlbumView.layout(0, mTopMargin, right - left, mTopMargin + mContentSize);
    162         int barStart = mTopMargin + mContentSize + mMidMargin;
    163         mScrollBarView.layout(0, barStart, right - left, barStart + mBarSize);
    164         int width = right - left;
    165         int height = bottom - top;
    166     }
    167 
    168     @Override
    169     protected boolean onTouch(MotionEvent event) {
    170         // consume all touch events on the "gray area", so they don't go to
    171         // the photo view below. (otherwise you can scroll the picture through
    172         // it).
    173         return true;
    174     }
    175 
    176     @Override
    177     protected boolean dispatchTouchEvent(MotionEvent event) {
    178         switch (event.getAction()) {
    179             case MotionEvent.ACTION_DOWN:
    180             case MotionEvent.ACTION_MOVE:
    181                 onUserInteractionBegin();
    182                 break;
    183             case MotionEvent.ACTION_UP:
    184             case MotionEvent.ACTION_CANCEL:
    185                 onUserInteractionEnd();
    186                 break;
    187         }
    188 
    189         return super.dispatchTouchEvent(event);
    190     }
    191 
    192     @Override
    193     protected void render(GLCanvas canvas) {
    194         mBackgroundTexture.draw(canvas, 0, 0, getWidth(), getHeight());
    195         super.render(canvas);
    196     }
    197 
    198     private void onDown(int index) {
    199         MediaItem item = mAlbumDataAdapter.get(index);
    200         Path path = (item == null) ? null : item.getPath();
    201         mStripDrawer.setPressedPath(path);
    202         mAlbumView.invalidate();
    203     }
    204 
    205     private void onUp() {
    206         mStripDrawer.setPressedPath(null);
    207         mAlbumView.invalidate();
    208     }
    209 
    210     private void onSingleTapUp(int slotIndex) {
    211         if (mListener.onSlotSelected(slotIndex)) {
    212             mAlbumView.setFocusIndex(slotIndex);
    213         }
    214     }
    215 
    216     private void onLongTap(int slotIndex) {
    217         onSingleTapUp(slotIndex);
    218     }
    219 
    220     private void onScrollPositionChanged(int position, int total) {
    221         mScrollBarView.setContentPosition(position, total);
    222     }
    223 
    224     // Called by AlbumView
    225     @Override
    226     public void onUserInteractionBegin() {
    227         mUIListener.onUserInteractionBegin();
    228     }
    229 
    230     // Called by AlbumView
    231     @Override
    232     public void onUserInteractionEnd() {
    233         mUIListener.onUserInteractionEnd();
    234     }
    235 
    236     // Called by AlbumView
    237     @Override
    238     public void onUserInteraction() {
    239         mUIListener.onUserInteraction();
    240     }
    241 
    242     // Called by ScrollBarView
    243     @Override
    244     public void onScrollBarPositionChanged(int position) {
    245         mAlbumView.setScrollPosition(position);
    246     }
    247 
    248     public void setFocusIndex(int slotIndex) {
    249         mAlbumView.setFocusIndex(slotIndex);
    250         mAlbumView.makeSlotVisible(slotIndex);
    251     }
    252 
    253     public void setStartIndex(int slotIndex) {
    254         mAlbumView.setStartIndex(slotIndex);
    255     }
    256 
    257     public void pause() {
    258         mAlbumView.pause();
    259         mAlbumDataAdapter.pause();
    260     }
    261 
    262     public void resume() {
    263         mAlbumView.resume();
    264         mAlbumDataAdapter.resume();
    265     }
    266 }
    267