• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 com.android.camera.IconListPreference;
20 import com.android.camera.PreferenceGroup;
21 import com.android.camera.R;
22 import com.android.camera.Util;
23 
24 import android.content.Context;
25 import android.util.AttributeSet;
26 import android.view.MotionEvent;
27 import android.view.View;
28 import android.widget.ImageView;
29 
30 /**
31  * A view that contains camera setting indicators which are spread over a
32  * vertical bar in preview frame.
33  */
34 public class SecondLevelIndicatorControlBar extends IndicatorControl implements
35         View.OnClickListener, AbstractIndicatorButton.IndicatorChangeListener {
36     private static final String TAG = "SecondLevelIndicatorControlBar";
37     private static int ICON_SPACING = Util.dpToPixel(16);
38     private View mCloseIcon;
39     private View mDivider; // the divider line
40     private View mIndicatorHighlight; // the side highlight bar
41     private View mPopupedIndicator;
42     int mDegree = 0;
43     int mSelectedIndex = -1;
44     // There are some views in the ViewGroup before adding the indicator buttons,
45     // such as Close icon, divider line and the hightlight bar, we need to
46     // remember the count of the non-indicator buttons for getTouchViewIndex().
47     int mNonIndicatorButtonCount;
48 
SecondLevelIndicatorControlBar(Context context, AttributeSet attrs)49     public SecondLevelIndicatorControlBar(Context context, AttributeSet attrs) {
50         super(context, attrs);
51     }
52 
53     @Override
onFinishInflate()54     protected void onFinishInflate() {
55         mDivider = findViewById(R.id.divider);
56         mIndicatorHighlight = findViewById(R.id.indicator_highlight);
57         mCloseIcon = findViewById(R.id.back_to_first_level);
58         mCloseIcon.setOnClickListener(this);
59     }
60 
initialize(Context context, PreferenceGroup group, String[] keys, String[] otherSettingKeys)61     public void initialize(Context context, PreferenceGroup group,
62             String[] keys, String[] otherSettingKeys) {
63 
64         setPreferenceGroup(group);
65         mNonIndicatorButtonCount = getChildCount();
66         addControls(keys, otherSettingKeys);
67         if (mDegree != 0) setDegree(mDegree);
68     }
69 
onClick(View view)70     public void onClick(View view) {
71         dismissSettingPopup();
72         mOnIndicatorEventListener.onIndicatorEvent(
73                     OnIndicatorEventListener.EVENT_LEAVE_SECOND_LEVEL_INDICATOR_BAR);
74     }
75 
getTouchViewIndex(int y, int height)76     private int getTouchViewIndex(int y, int height) {
77         // If the current touch location is on close icon and above.
78         if (y < mCloseIcon.getBottom()) return indexOfChild(mCloseIcon);
79 
80         // Calculate if the touch event is on the indicator buttons.
81         int count = getChildCount();
82         if (count == mNonIndicatorButtonCount) return -1;
83         // The baseline will be the first indicator button's top minus spacing.
84         View firstIndicatorButton = getChildAt(mNonIndicatorButtonCount);
85         int baselineY = firstIndicatorButton.getTop() - (ICON_SPACING / 2);
86         if (y < baselineY) return -1;
87         int iconHeight = firstIndicatorButton.getMeasuredHeight();
88         int buttonRange = iconHeight + ICON_SPACING;
89         return (mNonIndicatorButtonCount + (y - baselineY) / buttonRange);
90     }
91 
92     @Override
dispatchTouchEvent(MotionEvent event)93     public boolean dispatchTouchEvent(MotionEvent event) {
94         if (!onFilterTouchEventForSecurity(event)) return false;
95 
96         int action = event.getAction();
97         if (!isEnabled()) return false;
98 
99         double x = (double) event.getX();
100         double y = (double) event.getY();
101         int height = getHeight();
102         if (height == 0) return false; // the event is sent before onMeasure()
103         if (x > getWidth()) x = getWidth();
104         if (y >= height) y = height - 1;
105 
106         int index = getTouchViewIndex((int) y, height);
107         if (index == -1) return true;
108         View b = getChildAt(index);
109         b.dispatchTouchEvent(event);
110         if ((mSelectedIndex != -1) && (index != mSelectedIndex)) {
111             View v = getChildAt(mSelectedIndex);
112             if (v instanceof AbstractIndicatorButton) {
113                 AbstractIndicatorButton c = (AbstractIndicatorButton) v;
114                 event.setAction(MotionEvent.ACTION_CANCEL);
115                 c.dispatchTouchEvent(event);
116                 c.dismissPopup();
117             }
118 
119             if (action == MotionEvent.ACTION_MOVE) {
120                 event.setAction(MotionEvent.ACTION_DOWN);
121                 b.dispatchTouchEvent(event);
122             }
123         }
124         mSelectedIndex = index;
125         return true;
126     }
127 
128     @Override
addIndicator(Context context, IconListPreference pref)129     public IndicatorButton addIndicator(Context context, IconListPreference pref) {
130         IndicatorButton b = super.addIndicator(context, pref);
131         b.setIndicatorChangeListener(this);
132         return b;
133     }
134 
135     @Override
addOtherSettingIndicator(Context context, int resId, String[] keys)136     public OtherSettingIndicatorButton addOtherSettingIndicator(Context context,
137             int resId, String[] keys) {
138         OtherSettingIndicatorButton b =
139                 super.addOtherSettingIndicator(context, resId, keys);
140         b.setIndicatorChangeListener(this);
141         return b;
142     }
143 
144     @Override
onShowIndicator(View view, boolean showed)145     public void onShowIndicator(View view, boolean showed) {
146         // Ignore those events if not current popup.
147         if (!showed && (mPopupedIndicator != view)) return;
148         mPopupedIndicator = (showed ? view : null);
149         // Show or dismiss the side indicator highlight.
150         requestLayout();
151     }
152 
153     @Override
setDegree(int degree)154     public void setDegree(int degree) {
155         mDegree = degree;
156         super.setDegree(degree);
157     }
158 
159     @Override
onLayout( boolean changed, int left, int top, int right, int bottom)160     protected void onLayout(
161             boolean changed, int left, int top, int right, int bottom) {
162         int count = getChildCount();
163         if (count == 0) return;
164         int width = right - left;
165         int height = bottom - top;
166         int iconHeight = mCloseIcon.getMeasuredHeight();
167         int padding = getPaddingTop();
168 
169         // The first icon is close button.
170         int offsetY = padding;
171         mCloseIcon.layout(0, padding, width, (padding + iconHeight));
172 
173         // And layout the divider line.
174         offsetY += (iconHeight + padding);
175         mDivider.layout(padding, offsetY,
176                 (width - padding), (offsetY + mDivider.getMeasuredHeight()));
177 
178         // Layout from the last icon up.
179         int startY = height - iconHeight - padding;
180         int decrement = iconHeight + ICON_SPACING;
181         for (int i = count - 1; i >= mNonIndicatorButtonCount; --i) {
182             getChildAt(i).layout(0, startY, width, startY + iconHeight);
183             startY -= decrement;
184         }
185 
186         // Hightlight the selected indicator if exists.
187         if (mPopupedIndicator == null) {
188             mIndicatorHighlight.setVisibility(View.GONE);
189         } else {
190             mIndicatorHighlight.setVisibility(View.VISIBLE);
191             // Keep the top and bottom of the hightlight the same as
192             // the 'active' indicator button.
193             mIndicatorHighlight.layout(0, mPopupedIndicator.getTop(),
194                     mIndicatorHighlight.getLayoutParams().width,
195                     mPopupedIndicator.getBottom());
196         }
197    }
198 
199     @Override
setEnabled(boolean enabled)200     public void setEnabled(boolean enabled) {
201         super.setEnabled(enabled);
202         if (mCurrentMode == MODE_VIDEO) {
203             mCloseIcon.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
204         }
205         mCloseIcon.setEnabled(enabled);
206     }
207 }
208