blob: efe708bd1c8467fc327e9da80199c72d962a29c2 [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.gallery3d.ui;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.view.MotionEvent;
import android.view.View.MeasureSpec;
import com.android.gallery3d.R;
import com.android.gallery3d.util.Utils;
public class HeadUpDisplay extends GLView {
private static final int POPUP_WINDOW_OVERLAP = 20;
private static final int POPUP_TRIANGLE_OFFSET = 15;
private static final float MAX_HEIGHT_RATIO = 0.8f;
private static final float MAX_WIDTH_RATIO = 0.8f;
private static int sPopupWindowOverlap = -1;
private static int sPopupTriangleOffset;
private MenuItemBar mBottomBar;
private MenuBar mTopBar;
private HudMenuInterface mMenu;
private final Context mContext;
private PopupWindow mPopupWindow;
private GLListView mListView;
private GLView mAnchorView;
private ResourceTexture mPathIcons[];
private String mPathTitle[];
private static void initializeStaticVariables(Context context) {
if (sPopupWindowOverlap >= 0) return;
sPopupWindowOverlap = Utils.dpToPixel(context, POPUP_WINDOW_OVERLAP);
sPopupTriangleOffset = Utils.dpToPixel(context, POPUP_TRIANGLE_OFFSET);
}
public HeadUpDisplay(Context context) {
initializeStaticVariables(context);
mContext = context;
}
@Override
protected void onLayout(
boolean changesize, int left, int top, int right, int bottom) {
int width = right - left;
int height = bottom - top;
int widthSpec = MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY);
int heightSpec = MeasureSpec.UNSPECIFIED;
mTopBar.measure(widthSpec, heightSpec);
mBottomBar.measure(widthSpec, heightSpec);
mTopBar.layout(0, 0, width, mTopBar.getMeasuredHeight());
mBottomBar.layout(
0, height - mBottomBar.getMeasuredHeight(), width, height);
if (mPopupWindow != null
&& mPopupWindow.getVisibility() == GLView.VISIBLE) {
this.layoutPopupWindow(mAnchorView);
}
}
public void setMenu(HudMenuInterface menu) {
mMenu = menu;
mTopBar = menu.getTopMenuBar();
mBottomBar = menu.getBottomMenuBar();
addComponent(mTopBar);
addComponent(mBottomBar);
mBottomBar.setOnSelectedListener(new BottomBarSelectedListener());
}
@Override
protected boolean onTouch(MotionEvent event) {
if (mPopupWindow != null &&
mPopupWindow.getVisibility() == GLView.VISIBLE) {
mBottomBar.setSelectedItem(null);
return true;
}
return false;
}
@Override
protected boolean dispatchTouchEvent(MotionEvent event,
int x, int y, GLView component, boolean checkBounds) {
if (mPopupWindow != null
&& mPopupWindow.getVisibility() == GLView.VISIBLE
&& component != mPopupWindow && component != mBottomBar) {
return false;
}
return super.dispatchTouchEvent(event, x, y, component, checkBounds);
}
private void layoutPopupWindow(GLView anchorView) {
mAnchorView = anchorView;
Rect rect = new Rect();
getBoundsOf(anchorView, rect);
int width = (int) (getWidth() * MAX_WIDTH_RATIO + .5);
int height = (int) (getHeight() * MAX_HEIGHT_RATIO + .5);
mPopupWindow.measure(
MeasureSpec.makeMeasureSpec(width, MeasureSpec.AT_MOST),
MeasureSpec.makeMeasureSpec(height, MeasureSpec.AT_MOST));
width = mPopupWindow.getMeasuredWidth();
height = mPopupWindow.getMeasuredHeight();
int anchorX = (rect.left + rect.right) / 2;
int anchorY = rect.top + sPopupWindowOverlap;
int xoffset = Utils.clamp(anchorX - width / 2, 0, getWidth() - width);
int yoffset = Math.max(0, anchorY - height);
mPopupWindow.setAnchorPosition(anchorX - xoffset);
mPopupWindow.layout(
xoffset, yoffset, xoffset + width, yoffset + height);
}
private void initializePopupWindow() {
Context context = mContext;
mListView = new GLListView(context);
mListView.setOnItemSelectedListener(new PopupMenuItemListener());
mPopupWindow = new PopupWindow();
mPopupWindow.setBackground(
new NinePatchTexture(context, R.drawable.popup));
mPopupWindow.setAnchor(new ResourceTexture(
context, R.drawable.popup_triangle_bottom),
(int) (sPopupTriangleOffset + 0.5));
mListView.setHighLight(new NinePatchTexture(
context, R.drawable.popup_option_selected));
mPopupWindow.setContent(mListView);
mPopupWindow.setVisibility(GLView.INVISIBLE);
super.addComponent(mPopupWindow);
}
private class PopupMenuItemListener implements GLListView.OnItemSelectedListener {
public void onItemSelected(GLView view, int position) {
if (mMenu != null) mMenu.onMenuItemSelected(mListView.getDataModel(), position);
mPopupWindow.popoff();
}
}
private class BottomBarSelectedListener implements OnSelectedListener {
public void onSelected(GLView source) {
if (source == null) {
mPopupWindow.popoff();
} else {
if (mPopupWindow == null) initializePopupWindow();
mListView.setDataModel(mMenu.getMenuModel(source));
layoutPopupWindow(source);
if (mPopupWindow.getVisibility() != GLView.VISIBLE) {
mPopupWindow.popup();
}
}
}
}
public int getTopBarBottomPosition() {
Rect rect = new Rect();
getBoundsOf(mTopBar, rect);
return rect.bottom;
}
public int getBottomBarTopPosition() {
Rect rect = new Rect();
getBoundsOf(mBottomBar, rect);
return rect.top;
}
}