SecondLevelIndicatorControlBar.java revision b7d0a0704e437a1892fbf2a6e5138cf36df9fde8
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 17package com.android.camera.ui; 18 19import com.android.camera.PreferenceGroup; 20import com.android.camera.R; 21import com.android.camera.Util; 22 23import android.content.Context; 24import android.util.AttributeSet; 25import android.view.MotionEvent; 26import android.view.View; 27import android.widget.ImageView; 28 29/** 30 * A view that contains camera setting indicators which are spread over a 31 * vertical bar in preview frame. 32 */ 33public class SecondLevelIndicatorControlBar extends IndicatorControl implements 34 View.OnClickListener { 35 private static final String TAG = "SecondLevelIndicatorControlBar"; 36 private static int ICON_SPACING = Util.dpToPixel(24); 37 private ImageView mCloseIcon; 38 private View mDivider; // the divider line 39 int mDegree = 0; 40 int mSelectedIndex = -1; 41 42 public SecondLevelIndicatorControlBar(Context context, AttributeSet attrs) { 43 super(context, attrs); 44 } 45 46 @Override 47 protected void onFinishInflate() { 48 mDivider = findViewById(R.id.divider); 49 } 50 51 public void initialize(Context context, PreferenceGroup group, 52 String[] keys, String[] otherSettingKeys) { 53 if (mCloseIcon == null) { 54 mCloseIcon = new ColorFilterImageView(context); 55 mCloseIcon.setImageResource(R.drawable.btn_close_settings); 56 mCloseIcon.setOnClickListener(this); 57 addView(mCloseIcon); 58 } 59 setPreferenceGroup(group); 60 addControls(keys, otherSettingKeys); 61 if (mDegree != 0) setDegree(mDegree); 62 } 63 64 public void onClick(View view) { 65 dismissSettingPopup(); 66 mOnIndicatorEventListener.onIndicatorEvent( 67 OnIndicatorEventListener.EVENT_LEAVE_SECOND_LEVEL_INDICATOR_BAR); 68 } 69 70 private int getTouchViewIndex(int y, int height) { 71 int padding = getPaddingTop(); 72 int iconHeight = mCloseIcon.getMeasuredHeight(); 73 int totalIconHeight = iconHeight + ICON_SPACING; 74 // If the current touch location is on close icon and above. 75 if (y < padding + totalIconHeight) return indexOfChild(mCloseIcon); 76 77 // The first two views are close icon and divider line, we have to 78 // calculate if the touch event is on the rest indicator buttons. 79 int count = getChildCount(); 80 if (count < 3) return -1; 81 int selectionHeight = (count - 2) * totalIconHeight - (ICON_SPACING / 2); 82 int selectionY = height - padding - selectionHeight; 83 if (y < selectionY) return -1; 84 return (2 + (y - selectionY) / totalIconHeight); 85 } 86 87 @Override 88 public boolean dispatchTouchEvent(MotionEvent event) { 89 if (!onFilterTouchEventForSecurity(event)) return false; 90 91 int action = event.getAction(); 92 if (!isEnabled()) return false; 93 94 double x = (double) event.getX(); 95 double y = (double) event.getY(); 96 int height = getHeight(); 97 if (height == 0) return false; // the event is sent before onMeasure() 98 if (x > getWidth()) x = getWidth(); 99 if (y >= height) y = height - 1; 100 101 int index = getTouchViewIndex((int) y, height); 102 if (index == -1) return true; 103 View b = getChildAt(index); 104 b.dispatchTouchEvent(event); 105 if ((mSelectedIndex != -1) && (index != mSelectedIndex)) { 106 View v = getChildAt(mSelectedIndex); 107 if (v instanceof AbstractIndicatorButton) { 108 AbstractIndicatorButton c = (AbstractIndicatorButton) v; 109 event.setAction(MotionEvent.ACTION_CANCEL); 110 c.dispatchTouchEvent(event); 111 c.dismissPopup(); 112 } 113 114 if (action == MotionEvent.ACTION_MOVE) { 115 event.setAction(MotionEvent.ACTION_DOWN); 116 b.dispatchTouchEvent(event); 117 } 118 } 119 mSelectedIndex = index; 120 return true; 121 } 122 123 @Override 124 public void setDegree(int degree) { 125 mDegree = degree; 126 super.setDegree(degree); 127 } 128 129 @Override 130 protected void onLayout( 131 boolean changed, int left, int top, int right, int bottom) { 132 int count = getChildCount(); 133 if (count == 0) return; 134 int width = right - left; 135 int height = bottom - top; 136 int iconHeight = mCloseIcon.getMeasuredHeight(); 137 int padding = getPaddingTop(); 138 139 // The first icon is close button. 140 mCloseIcon.layout(0, padding, width, (padding + iconHeight)); 141 // And layout the divider line. 142 mDivider.layout(0, (padding + iconHeight), 143 width, (padding + iconHeight + mDivider.getMeasuredHeight())); 144 145 // Layout from the last icon up. 146 int startY = height - iconHeight - padding; 147 int decrement = iconHeight + ICON_SPACING; 148 for (int i = count - 1; i > 1; --i) { 149 getChildAt(i).layout(0, startY, width, startY + iconHeight); 150 startY -= decrement; 151 } 152 } 153 154 @Override 155 public void setEnabled(boolean enabled) { 156 super.setEnabled(enabled); 157 if (mCurrentMode == MODE_VIDEO) { 158 mCloseIcon.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE); 159 } 160 mCloseIcon.setEnabled(enabled); 161 } 162} 163