OSDN Git Service

Updates to 3D gallery source.
[android-x86/packages-apps-Gallery2.git] / src / com / cooliris / media / PathBarLayer.java
1 package com.cooliris.media;
2
3 import java.util.ArrayList;
4
5 import javax.microedition.khronos.opengles.GL11;
6
7 import android.graphics.Typeface;
8 import android.view.MotionEvent;
9
10 public final class PathBarLayer extends Layer {
11     private static final StringTexture.Config sPathFormat = new StringTexture.Config();
12     private final ArrayList<Component> mComponents = new ArrayList<Component>();
13     private static final int FILL = R.drawable.pathbar_bg;
14     private static final int JOIN = R.drawable.pathbar_join;
15     private static final int CAP = R.drawable.pathbar_cap;
16     private Component mTouchItem = null;
17
18     static {
19         sPathFormat.fontSize = 18f * Gallery.PIXEL_DENSITY;
20     }
21
22     public PathBarLayer() {
23     }
24
25     public void pushLabel(int icon, String label, Runnable action) {
26         mComponents.add(new Component(icon, label, action, 0));
27         recomputeComponents();
28     }
29     
30     public void setAnimatedIcons(final int[] icons) {
31         final int numComponents = mComponents.size();
32         for (int i = 0; i < numComponents; ++i) {
33             final Component component = mComponents.get(i);
34             if (component != null) {
35                 if (component.animatedIcons != null) {
36                     component.animatedIcons = null;
37                 }
38                 if (i == numComponents - 1) {
39                     component.animatedIcons = icons;
40                 }
41             }
42         }
43     }
44
45     public void changeLabel(String label) {
46         if (label == null || label.length() == 0)
47             return;
48         Component component = popLabel();
49         if (component != null) {
50             pushLabel(component.icon, label, component.action);
51         }
52     }
53     
54     public String getCurrentLabel() {
55         final ArrayList<Component> components = mComponents;
56         int lastIndex = components.size() - 1;
57         if (lastIndex < 0) {
58             return "";
59         }
60         Component retVal = components.get(lastIndex);
61         return retVal.origString;
62     }
63
64     public Component popLabel() {
65         final ArrayList<Component> components = mComponents;
66         int lastIndex = components.size() - 1;
67         if (lastIndex < 0) {
68             return null;
69         }
70         Component retVal = components.get(lastIndex);
71         components.remove(lastIndex);
72         return retVal;
73     }
74
75     private static final class Component {
76         public String origString;
77         public int icon;
78         public Runnable action;
79         public StringTexture texture;
80         public float width;
81         public float animWidth;
82         public float x;
83         public int[] animatedIcons;
84         public float timeElapsed;
85         private static final float ICON_WIDTH = 38.0f;
86
87         Component(int icon, String label, Runnable action, float widthLeft) {
88             this.action = action;
89             origString = label;
90             this.icon = icon;
91             computeLabel(widthLeft);
92         }
93
94         public final void computeLabel(float widthLeft) {
95             Typeface typeface = sPathFormat.bold ? Typeface.DEFAULT_BOLD : Typeface.DEFAULT;
96             String label = "";
97             if (origString != null) {
98                 label = origString.substring(0, StringTexture.lengthToFit(sPathFormat.fontSize, widthLeft, typeface, origString));
99                 if (label.length() != origString.length()) {
100                     label += "...";
101                 }
102             }
103             this.texture = new StringTexture(label, sPathFormat);
104         }
105
106         public final boolean update(float timeElapsed) {
107             this.timeElapsed += timeElapsed;
108             if (animWidth == 0.0f) {
109                 animWidth = width;
110             }
111             animWidth = FloatUtils.animate(animWidth, width, timeElapsed);
112             if (animatedIcons != null && animatedIcons.length > 1)
113                 return true;
114             if (animWidth == width) {
115                 return false;
116             } else {
117                 return true;
118             }
119         }
120
121         public float getIconWidth() {
122             return ICON_WIDTH * Gallery.PIXEL_DENSITY;
123         }
124     }
125
126     @Override
127     public void generate(RenderView view, RenderView.Lists lists) {
128         lists.blendedList.add(this);
129         lists.hitTestList.add(this);
130         lists.updateList.add(this);
131     }
132
133     private void layout() {
134         int numComponents = mComponents.size();
135         for (int i = 0; i < numComponents; ++i) {
136             Component component = mComponents.get(i);
137             float iconWidth = (component.icon == 0) ? 0 : component.getIconWidth();
138             if (iconWidth == 0) {
139                 iconWidth = 8 * Gallery.PIXEL_DENSITY;
140             }
141             float offset = 5 * Gallery.PIXEL_DENSITY;
142             float thisComponentWidth = (i != numComponents - 1) ? iconWidth + offset : component.texture.computeTextWidth()
143                     + iconWidth + offset;
144             component.width = thisComponentWidth;
145         }
146     }
147
148     @Override
149     public boolean update(RenderView view, float timeElapsed) {
150         layout();
151         boolean retVal = false;
152         int numComponents = mComponents.size();
153         for (int i = 0; i < numComponents; i++) {
154             Component component = mComponents.get(i);
155             retVal |= component.update(timeElapsed);
156         }
157         return retVal;
158     }
159
160     @Override
161     public void renderBlended(RenderView view, GL11 gl) {
162         // Draw components.
163         final Texture fill = view.getResource(FILL);
164         final Texture join = view.getResource(JOIN);
165         final Texture cap = view.getResource(CAP);
166         final float y = mY + 3;
167         int x = (int) (3 * Gallery.PIXEL_DENSITY);
168         float height = mHeight;
169         int numComponents = mComponents.size();
170         for (int i = 0; i < numComponents; ++i) {
171             Component component = mComponents.get(i);
172             component.x = x;
173             // Draw the left join if not the first component, and the fill.
174             // TODO: Draw the pressed background for mTouchItem.
175             final int width = (int) component.animWidth;
176             if (i != 0) {
177                 view.draw2D(join, x - join.getWidth(), y);
178                 if (view.bind(fill)) {
179                     view.draw2D(x, y, 0f, width, height);
180                 }
181             } else if (view.bind(fill)) {
182                 view.draw2D(0f, y, 0f, x + width, height);
183             }
184
185             if (i == numComponents - 1) {
186                 // Draw the cap on the right edge.
187                 view.draw2D(cap, x + width, y);
188             }
189             float xOffset = 5 * Gallery.PIXEL_DENSITY;
190             // Draw the label.
191             final int[] icons = component.animatedIcons;
192             
193             // Cycles animated icons.
194             final int iconId = (icons != null && icons.length > 0) ? icons[(int) (component.timeElapsed * 20.0f)
195                     % icons.length] : component.icon;
196             final Texture icon = view.getResource(iconId);
197             if (icon != null) {
198                 view.loadTexture(icon);
199                 view.draw2D(icon, x + xOffset, y - 2 * Gallery.PIXEL_DENSITY);
200             }
201             if (i == numComponents - 1) {
202                 final StringTexture texture = component.texture;
203                 view.loadTexture(texture);
204                 float iconWidth = component.getIconWidth();
205                 if (texture.computeTextWidth() <= (width - iconWidth)) {
206                     float textOffset = (iconWidth == 0) ? 8 * Gallery.PIXEL_DENSITY : iconWidth;
207                     view.draw2D(texture, x + textOffset, y + 5);
208                 }
209             }
210             x += (int) (width + (21 * Gallery.PIXEL_DENSITY + 0.5f));
211         }
212     }
213
214     private Component hitTestItems(float x, float y) {
215         if (y >= mY && y < mY + mHeight) {
216             int numComponents = mComponents.size();
217             for (int i = 0; i < numComponents; i++) {
218                 final Component component = mComponents.get(i);
219                 float componentx = component.x;
220                 if (x >= componentx && x < componentx + component.width) {
221                     return component;
222                 }
223             }
224         }
225         return null;
226     }
227
228     @Override
229     public boolean onTouchEvent(MotionEvent event) {
230         final float x = event.getX();
231         final float y = event.getY();
232         switch (event.getAction()) {
233         case MotionEvent.ACTION_DOWN:
234             mTouchItem = hitTestItems(x, y);
235             break;
236         case MotionEvent.ACTION_MOVE:
237             break;
238         case MotionEvent.ACTION_UP:
239             if (mTouchItem != null) {
240                 mTouchItem.action.run();
241             }
242         case MotionEvent.ACTION_CANCEL:
243             mTouchItem = null;
244             break;
245         }
246         return true;
247     }
248
249     public void recomputeComponents() {
250         float width = mWidth;
251         width -= 20f * Gallery.PIXEL_DENSITY;
252         int numComponents = mComponents.size();
253         for (int i = 0; i < numComponents; i++) {
254             Component component = mComponents.get(i);
255             width -= (component.getIconWidth() + 20.0f * Gallery.PIXEL_DENSITY);
256             component.computeLabel(width);
257         }
258     }
259
260     public int getNumLevels() {
261         return mComponents.size();
262     }
263
264     public void clear() {
265         mComponents.clear();
266     }
267 }