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 android.graphics.Rect;
     20 
     21 import com.android.gallery3d.app.GalleryActivity;
     22 import com.android.gallery3d.data.MediaItem;
     23 import com.android.gallery3d.ui.PositionRepository.Position;
     24 
     25 public class AlbumView extends SlotView {
     26     @SuppressWarnings("unused")
     27     private static final String TAG = "AlbumView";
     28     private static final int CACHE_SIZE = 64;
     29 
     30     private int mVisibleStart = 0;
     31     private int mVisibleEnd = 0;
     32 
     33     private AlbumSlidingWindow mDataWindow;
     34     private final GalleryActivity mActivity;
     35     private SelectionDrawer mSelectionDrawer;
     36     private int mCacheThumbSize;
     37 
     38     private boolean mIsActive = false;
     39 
     40     public static interface Model {
     41         public int size();
     42         public MediaItem get(int index);
     43         public void setActiveWindow(int start, int end);
     44         public void setModelListener(ModelListener listener);
     45     }
     46 
     47     public static interface ModelListener {
     48         public void onWindowContentChanged(int index);
     49         public void onSizeChanged(int size);
     50     }
     51 
     52     public AlbumView(GalleryActivity activity, SlotView.Spec spec,
     53             int cacheThumbSize) {
     54         super(activity.getAndroidContext());
     55         mCacheThumbSize = cacheThumbSize;
     56         setSlotSpec(spec);
     57         mActivity = activity;
     58     }
     59 
     60     public void setSelectionDrawer(SelectionDrawer drawer) {
     61         mSelectionDrawer = drawer;
     62         if (mDataWindow != null) mDataWindow.setSelectionDrawer(drawer);
     63     }
     64 
     65     public void setModel(Model model) {
     66         if (mDataWindow != null) {
     67             mDataWindow.setListener(null);
     68             setSlotCount(0);
     69             mDataWindow = null;
     70         }
     71         if (model != null) {
     72             mDataWindow = new AlbumSlidingWindow(
     73                     mActivity, model, CACHE_SIZE,
     74                     mCacheThumbSize);
     75             mDataWindow.setSelectionDrawer(mSelectionDrawer);
     76             mDataWindow.setListener(new MyDataModelListener());
     77             setSlotCount(model.size());
     78             updateVisibleRange(getVisibleStart(), getVisibleEnd());
     79         }
     80     }
     81 
     82     public void setFocusIndex(int slotIndex) {
     83         if (mDataWindow != null) {
     84             mDataWindow.setFocusIndex(slotIndex);
     85         }
     86     }
     87 
     88     private void putSlotContent(int slotIndex, DisplayItem item) {
     89         Rect rect = getSlotRect(slotIndex);
     90         Position position = new Position(
     91                 (rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2, 0);
     92         putDisplayItem(position, position, item);
     93     }
     94 
     95     private void updateVisibleRange(int start, int end) {
     96         if (start == mVisibleStart && end == mVisibleEnd) {
     97             // we need to set the mDataWindow active range in any case.
     98             mDataWindow.setActiveWindow(start, end);
     99             return;
    100         }
    101 
    102         if (!mIsActive) {
    103             mVisibleStart = start;
    104             mVisibleEnd = end;
    105             mDataWindow.setActiveWindow(start, end);
    106             return;
    107         }
    108 
    109         if (start >= mVisibleEnd || mVisibleStart >= end) {
    110             for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
    111                 DisplayItem item = mDataWindow.get(i);
    112                 if (item != null) removeDisplayItem(item);
    113             }
    114             mDataWindow.setActiveWindow(start, end);
    115             for (int i = start; i < end; ++i) {
    116                 putSlotContent(i, mDataWindow.get(i));
    117             }
    118         } else {
    119             for (int i = mVisibleStart; i < start; ++i) {
    120                 DisplayItem item = mDataWindow.get(i);
    121                 if (item != null) removeDisplayItem(item);
    122             }
    123             for (int i = end, n = mVisibleEnd; i < n; ++i) {
    124                 DisplayItem item = mDataWindow.get(i);
    125                 if (item != null) removeDisplayItem(item);
    126             }
    127             mDataWindow.setActiveWindow(start, end);
    128             for (int i = start, n = mVisibleStart; i < n; ++i) {
    129                 putSlotContent(i, mDataWindow.get(i));
    130             }
    131             for (int i = mVisibleEnd; i < end; ++i) {
    132                 putSlotContent(i, mDataWindow.get(i));
    133             }
    134         }
    135 
    136         mVisibleStart = start;
    137         mVisibleEnd = end;
    138     }
    139 
    140     @Override
    141     protected void onLayoutChanged(int width, int height) {
    142         // Reput all the items
    143         updateVisibleRange(0, 0);
    144         updateVisibleRange(getVisibleStart(), getVisibleEnd());
    145     }
    146 
    147     @Override
    148     protected void onScrollPositionChanged(int position) {
    149         super.onScrollPositionChanged(position);
    150         updateVisibleRange(getVisibleStart(), getVisibleEnd());
    151     }
    152 
    153     @Override
    154     protected void render(GLCanvas canvas) {
    155         mSelectionDrawer.prepareDrawing();
    156         super.render(canvas);
    157     }
    158 
    159     private class MyDataModelListener implements AlbumSlidingWindow.Listener {
    160 
    161         public void onContentInvalidated() {
    162             invalidate();
    163         }
    164 
    165         public void onSizeChanged(int size) {
    166             if (setSlotCount(size)) {
    167                 // If the layout parameters are changed, we need reput all items.
    168                 // We keep the visible range at the same center but with size 0.
    169                 // So that we can:
    170                 //     1.) flush all visible items
    171                 //     2.) keep the cached data
    172                 int center = (getVisibleStart() + getVisibleEnd()) / 2;
    173                 updateVisibleRange(center, center);
    174             }
    175             updateVisibleRange(getVisibleStart(), getVisibleEnd());
    176             invalidate();
    177         }
    178 
    179         public void onWindowContentChanged(
    180                 int slotIndex, DisplayItem old, DisplayItem update) {
    181             removeDisplayItem(old);
    182             putSlotContent(slotIndex, update);
    183         }
    184     }
    185 
    186     public void resume() {
    187         mIsActive = true;
    188         mDataWindow.resume();
    189         for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
    190             putSlotContent(i, mDataWindow.get(i));
    191         }
    192     }
    193 
    194     public void pause() {
    195         mIsActive = false;
    196         for (int i = mVisibleStart, n = mVisibleEnd; i < n; ++i) {
    197             removeDisplayItem(mDataWindow.get(i));
    198         }
    199         mDataWindow.pause();
    200     }
    201 }
    202