blob: c1b9b2f61747c76d669c8842e2ae5619f2e4da78 [file] [log] [blame]
/*
* Copyright (C) 2010 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.camera.ui;
import com.android.camera.IconListPreference;
import com.android.camera.PreferenceGroup;
import com.android.camera.R;
import com.android.camera.Util;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
/**
* A view that contains camera setting indicators which are spread over a
* vertical bar in preview frame.
*/
public class SecondLevelIndicatorControlBar extends IndicatorControl implements
View.OnClickListener, AbstractIndicatorButton.IndicatorChangeListener {
private static final String TAG = "SecondLevelIndicatorControlBar";
private static int ICON_SPACING = Util.dpToPixel(16);
private View mCloseIcon;
private View mDivider; // the divider line
private View mPopupedIndicator;
int mOrientation = 0;
int mSelectedIndex = -1;
// There are some views in the ViewGroup before adding the indicator buttons,
// such as Close icon, divider line and the hightlight bar, we need to
// remember the count of the non-indicator buttons for getTouchViewIndex().
int mNonIndicatorButtonCount;
public SecondLevelIndicatorControlBar(Context context, AttributeSet attrs) {
super(context, attrs);
}
@Override
protected void onFinishInflate() {
mDivider = findViewById(R.id.divider);
mCloseIcon = findViewById(R.id.back_to_first_level);
mCloseIcon.setOnClickListener(this);
}
public void initialize(Context context, PreferenceGroup group,
String[] keys, String[] otherSettingKeys) {
setPreferenceGroup(group);
mNonIndicatorButtonCount = getChildCount();
addControls(keys, otherSettingKeys);
if (mOrientation != 0) setOrientation(mOrientation);
}
public void onClick(View view) {
dismissSettingPopup();
mOnIndicatorEventListener.onIndicatorEvent(
OnIndicatorEventListener.EVENT_LEAVE_SECOND_LEVEL_INDICATOR_BAR);
}
private int getTouchViewIndex(int x, int width) {
// If the current touch location is on close icon and above.
if (x > mCloseIcon.getLeft()) return indexOfChild(mCloseIcon);
// Calculate if the touch event is on the indicator buttons.
int count = getChildCount();
if (count == mNonIndicatorButtonCount) return -1;
// The baseline will be the first indicator button's top minus spacing.
View firstIndicatorButton = getChildAt(mNonIndicatorButtonCount);
int baselineX = firstIndicatorButton.getRight() + (ICON_SPACING / 2);
if (x > baselineX) return -1;
int iconWidth = firstIndicatorButton.getMeasuredWidth();
int buttonRange = iconWidth + ICON_SPACING;
return (mNonIndicatorButtonCount + ((baselineX - x) / buttonRange));
}
private void dispatchRelativeTouchEvent(View view, MotionEvent event) {
event.offsetLocation(-view.getLeft(), -view.getTop());
view.dispatchTouchEvent(event);
event.offsetLocation(view.getLeft(), view.getTop());
}
@Override
public boolean dispatchTouchEvent(MotionEvent event) {
if (!onFilterTouchEventForSecurity(event)) return false;
int action = event.getAction();
if (!isEnabled()) return false;
double x = (double) event.getX();
int width = getWidth();
if (width == 0) return false; // the event is sent before onMeasure()
if (x > width) x = width;
int index = getTouchViewIndex((int) x, width);
// Cancel the previous target if we moved out of it
if ((mSelectedIndex != -1) && (index != mSelectedIndex)) {
View p = getChildAt(mSelectedIndex);
int oldAction = event.getAction();
event.setAction(MotionEvent.ACTION_CANCEL);
dispatchRelativeTouchEvent(p, event);
event.setAction(oldAction);
if (p instanceof AbstractIndicatorButton) {
AbstractIndicatorButton b = (AbstractIndicatorButton) p;
b.dismissPopup();
}
}
// Send event to the target
View v = getChildAt(index);
if (v == null) return true;
// Change MOVE to DOWN if this is a new target
if (mSelectedIndex != index && action == MotionEvent.ACTION_MOVE) {
event.setAction(MotionEvent.ACTION_DOWN);
}
dispatchRelativeTouchEvent(v, event);
mSelectedIndex = index;
return true;
}
@Override
public IndicatorButton addIndicator(Context context, IconListPreference pref) {
IndicatorButton b = super.addIndicator(context, pref);
b.setBackgroundResource(R.drawable.bg_pressed);
b.setIndicatorChangeListener(this);
return b;
}
@Override
public OtherSettingIndicatorButton addOtherSettingIndicator(Context context,
int resId, String[] keys) {
OtherSettingIndicatorButton b =
super.addOtherSettingIndicator(context, resId, keys);
b.setBackgroundResource(R.drawable.bg_pressed);
b.setIndicatorChangeListener(this);
return b;
}
@Override
public void onShowIndicator(View view, boolean showed) {
// Ignore those events if not current popup.
if (!showed && (mPopupedIndicator != view)) return;
mPopupedIndicator = (showed ? view : null);
// Show or dismiss the side indicator highlight.
requestLayout();
}
@Override
public void setOrientation(int orientation) {
mOrientation = orientation;
super.setOrientation(orientation);
}
@Override
protected void onLayout(
boolean changed, int left, int top, int right, int bottom) {
int count = getChildCount();
if (count == 0) return;
int width = right - left;
int height = bottom - top;
int iconWidth = mCloseIcon.getMeasuredWidth();
int padding = getPaddingLeft();
// Layout from the last icon up.
int offsetX = padding;
int increment = iconWidth + ICON_SPACING;
for (int i = count - 1; i >= mNonIndicatorButtonCount; --i) {
getChildAt(i).layout(offsetX, 0, offsetX + iconWidth, height);
offsetX += increment;
}
// And layout the divider line.
offsetX = width - iconWidth - 2 * padding;
mDivider.layout(offsetX, padding, (offsetX + mDivider.getMeasuredWidth()),
(height - padding));
offsetX = width - iconWidth - padding;
// The first icon is close button.
mCloseIcon.layout(offsetX, 0, (offsetX + iconWidth), height);
}
@Override
public void setEnabled(boolean enabled) {
super.setEnabled(enabled);
if (mCurrentMode == MODE_VIDEO) {
mCloseIcon.setVisibility(enabled ? View.VISIBLE : View.INVISIBLE);
}
mCloseIcon.setEnabled(enabled);
}
}