Merge "Clear existing completion when psychic is turned off." into honeycomb-mr1
diff --git a/res/drawable/qc_menu_selector.xml b/res/drawable/qc_menu_selector.xml
new file mode 100644
index 0000000..141f165
--- /dev/null
+++ b/res/drawable/qc_menu_selector.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_pressed="true"
+ android:drawable="@*android:drawable/list_selector_pressed_holo_dark" />
+ <item android:state_pressed="false" android:drawable="@drawable/clear" />
+</selector>
diff --git a/res/layout/qc_menu_item.xml b/res/layout/qc_menu_item.xml
new file mode 100644
index 0000000..9e4a2e8
--- /dev/null
+++ b/res/layout/qc_menu_item.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:minHeight="44dip"
+ android:background="@drawable/qc_menu_selector"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:gravity="center"
+ android:paddingLeft="8dip"
+ android:paddingRight="8dip"
+ android:paddingTop="4dip"
+ android:paddingBottom="4dip"
+ />
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f05f44f..5a8a110 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -354,7 +354,7 @@
<!-- Settings category for sync under general settings. This includes bookmark sync with Chrome [CHAR-LIMIT=50] -->
<string name="pref_general_sync_title">Sync</string>
<!-- Settings category for autofill under general. [CHAR-LIMIT=50] -->
- <string name="pref_general_autofill_title">Autofill</string>
+ <string name="pref_general_autofill_title">Auto-fill</string>
<!-- Checkbox setting to enable or disable syncing bookmarks and other data with Google Chrome. [CHAR-LIMIT=48] -->
<string name="pref_personal_sync_with_chrome">Sync with Google Chrome</string>
<!-- Checkbox setting to enable or disable syncing bookmarks and other data with Google Chrome. [CHAR-LIMIT=none] -->
@@ -397,7 +397,7 @@
<string name="autologin_bar_error">Login failed.</string>
<!-- Heading for the AutoFill profile editor to tell the user what AutoFill does and why they should fill out the profile. [CHAR-LIMIT=None] -->
- <string name="autofill_profile_editor_heading">AutoFill will use your profile to help you complete web forms in a single click.</string>
+ <string name="autofill_profile_editor_heading">Enter the data you want to auto-fill in web fields when you touch them.</string>
<!-- String for the user's full name in the AutoFill profile editor. [CHAR-LIMIT=32] -->
<string name="autofill_profile_editor_name">Full name:</string>
<!-- String for the user's e-mail address in the AutoFill profile editor. [CHAR-LIMIT=32] -->
@@ -438,10 +438,10 @@
<string name="autofill_setup_dialog_message">Browser can automatically complete web forms like this one. Would you like to set up your profile?</string>
<!-- Toast message displayed when the user decides to not set up autofill at this time. We want to remind them that they can configure
it through the Browser Settings menu. [CHAR-LIMIT=NONE] -->
- <string name="autofill_setup_dialog_negative_toast">AutoFill can always be configured through Browser Settings.</string>
+ <string name="autofill_setup_dialog_negative_toast">Auto-fill can always be configured through Browser Settings.</string>
<!-- Text on a checkbox in the "setup autofill" dialog which is shown to the user when they are prompted to set up the autofill feature.
The checkbox allows them to specify they would like to disable the feature altogether [CHAR-LIMIT=NONE] -->
- <string name="disable_autofill">Disable AutoFill</string>
+ <string name="disable_autofill">Disable auto-fill</string>
<!-- Settings screen, section title [CHAR-LIMIT=50] -->
<string name="pref_privacy_security_title">Privacy & security</string>
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index b108fd8..5084e31 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -616,6 +616,11 @@
// menu handling callbacks
@Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ return true;
+ }
+
+ @Override
public void onOptionsMenuOpened() {
}
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 7a6ea41..19ad40e 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -1479,7 +1479,7 @@
break;
}
mCurrentMenuState = mMenuState;
- return true;
+ return mUi.onPrepareOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
@@ -1931,6 +1931,13 @@
R.dimen.bookmarkThumbnailHeight);
}
+ static Bitmap createScreenshot(Tab tab, int width, int height) {
+ if ((tab != null) && (tab.getWebView() != null)) {
+ return createScreenshot(tab.getWebView(), width, height);
+ }
+ return null;
+ }
+
private static Bitmap createScreenshot(WebView view, int width, int height) {
// We render to a bitmap 2x the desired size so that we can then
// re-scale it with filtering since canvas.scale doesn't filter
diff --git a/src/com/android/browser/PieControl.java b/src/com/android/browser/PieControl.java
index ad47c72..302cbc0 100644
--- a/src/com/android/browser/PieControl.java
+++ b/src/com/android/browser/PieControl.java
@@ -17,15 +17,26 @@
package com.android.browser;
import com.android.browser.view.PieItem;
+import com.android.browser.view.PieListView;
import com.android.browser.view.PieMenu;
import android.app.Activity;
+import android.content.Context;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
+import android.view.ViewGroup;
import android.view.ViewGroup.LayoutParams;
import android.webkit.WebView;
+import android.widget.BaseAdapter;
import android.widget.FrameLayout;
import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+import java.util.List;
/**
* controller for Quick Controls pie menu
@@ -44,6 +55,7 @@
private PieItem mBookmarks;
private PieItem mNewTab;
private PieItem mClose;
+ private MenuAdapter mMenuAdapter;
public PieControl(Activity activity, UiController controller, XLargeUi ui) {
mActivity = activity;
@@ -67,11 +79,14 @@
mOptions = makeItem(
com.android.internal.R.drawable.ic_menu_moreoverflow_normal_holo_dark,
2);
+ mMenuAdapter = new MenuAdapter(mActivity, mUiController);
+ PieMenuView menusym = new PieMenuView(mActivity);
+ mOptions.setPieView(menusym);
+ menusym.setAdapter(mMenuAdapter);
setClickListener(mBack,
mRefresh,
mForward,
mUrl,
- mOptions,
mBookmarks,
mNewTab,
mClose
@@ -91,6 +106,10 @@
container.addView(mPie);
}
+ protected void onMenuOpened(Menu menu) {
+ mMenuAdapter.setMenu(menu);
+ }
+
protected void removeFromContainer(FrameLayout container) {
container.removeView(mPie);
}
@@ -135,8 +154,6 @@
}
} else if (mUrl.getView() == v) {
mUi.showTitleBarAndEdit();
- } else if (mOptions.getView() == v) {
- mActivity.openOptionsMenu();
} else if (mBookmarks.getView() == v) {
mUiController.bookmarksOrHistoryPicker(false);
} else if (mNewTab.getView() == v) {
@@ -152,4 +169,83 @@
return false;
}
+ private class PieMenuView extends PieListView {
+
+ /**
+ * @param ctx
+ */
+ public PieMenuView(Context ctx) {
+ super(ctx);
+ }
+
+ @Override
+ public void layout(int anchorX, int anchorY, boolean left) {
+ mActivity.openOptionsMenu();
+ super.layout(anchorX, anchorY, left);
+ }
+
+ }
+
+ private static class MenuAdapter extends BaseAdapter
+ implements OnClickListener {
+
+ List<MenuItem> mItems;
+ UiController mUiController;
+ LayoutInflater mInflater;
+
+ public MenuAdapter(Context ctx, UiController ctl) {
+ mUiController = ctl;
+ mInflater = LayoutInflater.from(ctx);
+ mItems = new ArrayList<MenuItem>();
+ }
+
+ public void setMenu(Menu menu) {
+ mItems.clear();
+ for (int i = 0; i < menu.size(); i++) {
+ MenuItem item = menu.getItem(i);
+ if (item.isEnabled() && item.isVisible()) {
+ mItems.add(item);
+ }
+ }
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mItems.size();
+ }
+
+ @Override
+ public MenuItem getItem(int position) {
+ return mItems.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v.getTag() != null) {
+ mUiController.onOptionsItemSelected((MenuItem) v.getTag());
+ }
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final MenuItem item = mItems.get(position);
+ View view = mInflater.inflate(
+ R.layout.qc_menu_item, null);
+ TextView label =
+ (TextView) view.findViewById(R.id.title);
+ label.setText(item.getTitle());
+ label.setTag(item);
+ label.setOnClickListener(this);
+ label.setLayoutParams(new LayoutParams(240, 32));
+ return label;
+ }
+
+ }
+
}
diff --git a/src/com/android/browser/ScrollWebView.java b/src/com/android/browser/ScrollWebView.java
index 2ee2ac0..8c89e51 100644
--- a/src/com/android/browser/ScrollWebView.java
+++ b/src/com/android/browser/ScrollWebView.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.graphics.Bitmap;
-import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
@@ -36,9 +35,7 @@
private boolean mBackgroundRemoved = false;
private boolean mUserInitiated = false;
private TitleBarBase mTitleBar;
- private boolean mDrawCached = false;
private Bitmap mBitmap;
- private Paint mCachePaint = new Paint();
/**
* @param context
@@ -137,46 +134,22 @@
mScrollListener = l;
}
- @Override
- public void invalidate() {
- if (!mDrawCached) {
- super.invalidate();
- }
- }
-
// callback for scroll events
interface ScrollListener {
public void onScroll(int visibleTitleHeight, boolean userInitiated);
}
- void setDrawCached(boolean cached) {
- if (cached == mDrawCached) return;
- if (cached) {
- buildDrawingCache();
- mBitmap = getDrawingCache(false);
- mDrawCached = (mBitmap != null);
- } else {
- mDrawCached = false;
- mBitmap = null;
- destroyDrawingCache();
- }
- }
-
@Override
protected void onDraw(android.graphics.Canvas c) {
- if (mDrawCached) {
- c.drawBitmap(mBitmap, getScrollX(), getScrollY(), mCachePaint);
- } else {
- super.onDraw(c);
- if (!mBackgroundRemoved && getRootView().getBackground() != null) {
- mBackgroundRemoved = true;
- post(new Runnable() {
- public void run() {
- getRootView().setBackgroundDrawable(null);
- }
- });
- }
+ super.onDraw(c);
+ if (!mBackgroundRemoved && getRootView().getBackground() != null) {
+ mBackgroundRemoved = true;
+ post(new Runnable() {
+ public void run() {
+ getRootView().setBackgroundDrawable(null);
+ }
+ });
}
}
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 47cefbc..70028ea 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -1757,4 +1757,5 @@
}
}
};
+
}
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java
index cbe666c..51cf0c3 100644
--- a/src/com/android/browser/TitleBarXLarge.java
+++ b/src/com/android/browser/TitleBarXLarge.java
@@ -16,16 +16,14 @@
package com.android.browser;
-import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
import com.android.browser.UI.DropdownChangeListener;
+import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
import com.android.browser.search.SearchEngine;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
-import android.database.DataSetObserver;
import android.graphics.Bitmap;
-import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.KeyEvent;
@@ -40,7 +38,6 @@
import android.widget.ImageButton;
import android.widget.ImageView;
-import java.util.ArrayList;
import java.util.List;
/**
@@ -84,8 +81,8 @@
R.drawable.textfield_active_holo_dark);
mUnfocusDrawable = resources.getDrawable(
R.drawable.textfield_default_holo_dark);
- initLayout(activity);
mInVoiceMode = false;
+ initLayout(activity);
}
@Override
@@ -380,7 +377,9 @@
public void setInVoiceMode(boolean voicemode, List<String> voiceResults) {
mInVoiceMode = voicemode;
mUrlInput.setVoiceResults(voiceResults);
- mUrlIcon.setImageDrawable(mSearchButton.getDrawable());
+ if (voicemode) {
+ mUrlIcon.setImageDrawable(mSearchButton.getDrawable());
+ }
}
@Override
diff --git a/src/com/android/browser/UI.java b/src/com/android/browser/UI.java
index bec7034..13f8af2 100644
--- a/src/com/android/browser/UI.java
+++ b/src/com/android/browser/UI.java
@@ -89,6 +89,8 @@
public void revertVoiceTitleBar(Tab tab);
+ public boolean onPrepareOptionsMenu(Menu menu);
+
public void onOptionsMenuOpened();
public void onExtendedMenuOpened();
diff --git a/src/com/android/browser/UiController.java b/src/com/android/browser/UiController.java
index 551d0ce..65fa5f8 100644
--- a/src/com/android/browser/UiController.java
+++ b/src/com/android/browser/UiController.java
@@ -19,6 +19,7 @@
import com.android.browser.UI.DropdownChangeListener;
import android.content.Intent;
+import android.view.MenuItem;
import android.webkit.WebView;
import java.util.List;
@@ -88,4 +89,7 @@
void unregisterOptionsMenuHandler(OptionsMenuHandler handler);
void registerDropdownChangeListener(DropdownChangeListener d);
+
+ boolean onOptionsItemSelected(MenuItem item);
+
}
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index 2bcfe35..9b5a884 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -18,9 +18,6 @@
import com.android.browser.ScrollWebView.ScrollListener;
-import android.animation.Animator;
-import android.animation.Animator.AnimatorListener;
-import android.animation.ObjectAnimator;
import android.app.ActionBar;
import android.app.Activity;
import android.content.pm.PackageManager;
@@ -30,6 +27,7 @@
import android.view.ActionMode;
import android.view.Gravity;
import android.view.KeyEvent;
+import android.view.Menu;
import android.view.View;
import android.webkit.WebChromeClient.CustomViewCallback;
import android.webkit.WebView;
@@ -51,7 +49,6 @@
private boolean mUseQuickControls;
private PieControl mPieControl;
- private boolean mInAnimation = false;
private Handler mHandler;
/**
@@ -121,15 +118,14 @@
private void checkTabCount() {
if (mUseQuickControls) {
- int n = mTabBar.getTabCount();
- if (n >= 2) {
- mActionBar.show();
- } else if (n == 1) {
+ if (mTabControl.getTabCount() == 1) {
mHandler.post(new Runnable() {
public void run() {
mActionBar.hide();
}
});
+ } else {
+ mActionBar.show();
}
}
}
@@ -227,56 +223,8 @@
@Override
public void setActiveTab(final Tab tab) {
- if (mInAnimation) return;
- if ((tab != mActiveTab) && (mActiveTab != null)) {
- mInAnimation = true;
- // animate between the two
- final ScrollWebView fromWV = (ScrollWebView) mActiveTab.getWebView();
- fromWV.setDrawCached(true);
- fromWV.setEmbeddedTitleBar(null);
- final ScrollWebView toWV = (ScrollWebView) tab.getWebView();
- if (!mUseQuickControls) {
- if (mTitleBar.getParent() == null) {
- toWV.setEmbeddedTitleBar(mTitleBar);
- }
- }
- toWV.setDrawCached(true);
- attachTabToContentView(tab);
- super.setActiveTab(tab, false);
- ObjectAnimator transition = ObjectAnimator.ofFloat(
- toWV, "alpha", 0f, 1f);
- transition.setDuration(mActivity.getResources()
- .getInteger(R.integer.tabFadeDuration));
- transition.addListener(new AnimatorListener() {
- @Override
- public void onAnimationCancel(Animator animation) {
- fromWV.setDrawCached(false);
- toWV.setDrawCached(false);
- setActiveTab(tab, false);
- mInAnimation = false;
- }
-
- @Override
- public void onAnimationEnd(Animator animation) {
- fromWV.setDrawCached(false);
- toWV.setDrawCached(false);
- setActiveTab(tab, false);
- mInAnimation = false;
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
- }
-
- @Override
- public void onAnimationStart(Animator animation) {
- }
- });
- transition.start();
- } else {
- super.setActiveTab(tab, true);
- setActiveTab(tab, true);
- }
+ super.setActiveTab(tab, true);
+ setActiveTab(tab, true);
}
@Override
@@ -511,4 +459,14 @@
mTitleBar.registerDropdownChangeListener(d);
}
+ @Override
+ public boolean onPrepareOptionsMenu(Menu menu) {
+ if (mUseQuickControls) {
+ mPieControl.onMenuOpened(menu);
+ return false;
+ } else {
+ return true;
+ }
+ }
+
}
diff --git a/src/com/android/browser/view/BasePieView.java b/src/com/android/browser/view/BasePieView.java
new file mode 100644
index 0000000..515545a
--- /dev/null
+++ b/src/com/android/browser/view/BasePieView.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright (C) 2011 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.browser.view;
+
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.view.MotionEvent;
+import android.view.View;
+import android.widget.Adapter;
+
+import java.util.ArrayList;
+
+/**
+ * common code for pie views
+ */
+public abstract class BasePieView implements PieMenu.PieView {
+
+ protected Adapter mAdapter;
+ private DataSetObserver mObserver;
+ protected ArrayList<View> mViews;
+
+ protected int mCurrent;
+ protected int mChildWidth;
+ protected int mChildHeight;
+ protected int mWidth;
+ protected int mHeight;
+ protected int mLeft;
+ protected int mTop;
+
+ public BasePieView() {
+ }
+
+ public void setAdapter(Adapter adapter) {
+ mAdapter = adapter;
+ if (adapter == null) {
+ if (mAdapter != null) {
+ mAdapter.unregisterDataSetObserver(mObserver);
+ }
+ mViews = null;
+ mCurrent = -1;
+ } else {
+ mObserver = new DataSetObserver() {
+ @Override
+ public void onChanged() {
+ buildViews();
+ }
+
+ @Override
+ public void onInvalidated() {
+ mViews.clear();
+ }
+ };
+ mAdapter.registerDataSetObserver(mObserver);
+ setCurrent(0);
+ }
+ }
+
+ public void setCurrent(int ix) {
+ mCurrent = ix;
+ }
+
+ public Adapter getAdapter() {
+ return mAdapter;
+ }
+
+ protected void buildViews() {
+ if (mAdapter != null) {
+ final int n = mAdapter.getCount();
+ if (mViews == null) {
+ mViews = new ArrayList<View>(n);
+ } else {
+ mViews.clear();
+ }
+ mChildWidth = 0;
+ mChildHeight = 0;
+ for (int i = 0; i < n; i++) {
+ View view = mAdapter.getView(i, null, null);
+ view.measure(View.MeasureSpec.UNSPECIFIED,
+ View.MeasureSpec.UNSPECIFIED);
+ mChildWidth = Math.max(mChildWidth, view.getMeasuredWidth());
+ mChildHeight = Math.max(mChildHeight, view.getMeasuredHeight());
+ mViews.add(view);
+ }
+ }
+ }
+
+ /**
+ * this will be called before the first draw call
+ * needs to set top, left, width, height
+ */
+ @Override
+ public abstract void layout(int anchorX, int anchorY, boolean left);
+
+ @Override
+ public abstract void draw(Canvas canvas);
+
+ protected void drawView(View view, Canvas canvas) {
+ final int state = canvas.save();
+ canvas.translate(view.getLeft(), view.getTop());
+ view.draw(canvas);
+ canvas.restoreToCount(state);
+ }
+
+ protected abstract int findChildAt(int y);
+
+ @Override
+ public boolean onTouchEvent(MotionEvent evt) {
+ int action = evt.getActionMasked();
+ int evtx = (int) evt.getX();
+ int evty = (int) evt.getY();
+ if ((evtx < mLeft) || (evtx >= mLeft + mWidth)
+ || (evty < mTop) || (evty >= mTop + mHeight)) {
+ return false;
+ }
+ switch (action) {
+ case MotionEvent.ACTION_MOVE:
+ View v = mViews.get(mCurrent);
+ setCurrent(Math.max(0, Math.min(mViews.size() -1,
+ findChildAt(evty))));
+ View v1 = mViews.get(mCurrent);
+ if (v != v1) {
+ v.setPressed(false);
+ v1.setPressed(true);
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ mViews.get(mCurrent).performClick();
+ mViews.get(mCurrent).setPressed(false);
+ break;
+ default:
+ break;
+ }
+ return true;
+ }
+
+}
diff --git a/src/com/android/browser/view/PieItem.java b/src/com/android/browser/view/PieItem.java
index c09dba2..84a6ac0 100644
--- a/src/com/android/browser/view/PieItem.java
+++ b/src/com/android/browser/view/PieItem.java
@@ -16,6 +16,8 @@
package com.android.browser.view;
+import com.android.browser.view.PieMenu.PieView;
+
import android.view.View;
/**
@@ -24,6 +26,7 @@
public class PieItem {
private View mView;
+ private PieView mPieView;
private int level;
private float start;
private float sweep;
@@ -36,6 +39,12 @@
this.level = level;
}
+ public PieItem(View view, int level, PieView sym) {
+ mView = view;
+ this.level = level;
+ mPieView = sym;
+ }
+
public void setSelected(boolean s) {
mSelected = s;
if (mView != null) {
@@ -74,8 +83,20 @@
return outer;
}
+ public boolean isPieView() {
+ return (mPieView != null);
+ }
+
public View getView() {
return mView;
}
+ public void setPieView(PieView sym) {
+ mPieView = sym;
+ }
+
+ public PieView getPieView() {
+ return mPieView;
+ }
+
}
diff --git a/src/com/android/browser/view/PieListView.java b/src/com/android/browser/view/PieListView.java
new file mode 100644
index 0000000..5fee51d
--- /dev/null
+++ b/src/com/android/browser/view/PieListView.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2011 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.browser.view;
+
+import com.android.browser.R;
+
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.view.View;
+
+/**
+ * shows views in a menu style list
+ */
+public class PieListView extends BasePieView {
+
+ private Paint mBgPaint;
+
+ public PieListView(Context ctx) {
+ mBgPaint = new Paint();
+ mBgPaint.setColor(ctx.getResources().getColor(R.color.qcMenuBackground));
+ }
+
+ /**
+ * this will be called before the first draw call
+ */
+ @Override
+ public void layout(int anchorX, int anchorY, boolean left) {
+ buildViews();
+ mWidth = mChildWidth;
+ mHeight = mChildHeight * mAdapter.getCount();
+ mLeft = anchorX + (left ? 0 : - mChildWidth);
+ mTop = anchorY - mHeight / 2;
+ if (mViews != null) {
+ layoutChildrenLinear();
+ }
+ }
+
+ protected void layoutChildrenLinear() {
+ final int n = mViews.size();
+ int top = mTop;
+ for (View view : mViews) {
+ view.layout(mLeft, top, mLeft + mChildWidth, top + mChildHeight);
+ top += mChildHeight;
+ }
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ canvas.drawRect(mLeft, mTop, mLeft + mWidth, mTop + mHeight, mBgPaint);
+ if (mViews != null) {
+ for (View view : mViews) {
+ drawView(view, canvas);
+ }
+ }
+ }
+
+ @Override
+ protected int findChildAt(int y) {
+ final int ix = (y - mTop) * mViews.size() / mHeight;
+ return ix;
+ }
+
+}
diff --git a/src/com/android/browser/view/PieMenu.java b/src/com/android/browser/view/PieMenu.java
index 98c0f59..22ebd18 100644
--- a/src/com/android/browser/view/PieMenu.java
+++ b/src/com/android/browser/view/PieMenu.java
@@ -46,6 +46,19 @@
public boolean onOpen();
}
+ /**
+ * A view like object that lives off of the pie menu
+ */
+ public interface PieView {
+
+ public void layout(int anchorX, int anchorY, boolean onleft);
+
+ public void draw(Canvas c);
+
+ public boolean onTouchEvent(MotionEvent evt);
+
+ }
+
private Point mCenter;
private int mRadius;
private int mRadiusInc;
@@ -57,6 +70,7 @@
private List<PieItem> mItems;
private int mLevels;
private int[] mCounts;
+ private PieView mPieView = null;
private Drawable mBackground;
@@ -143,6 +157,7 @@
}
if (!show) {
mCurrentItem = null;
+ mPieView = null;
}
invalidate();
}
@@ -159,6 +174,7 @@
private void layoutPie() {
int inner = mRadius;
int outer = mRadius + mRadiusInc;
+ int radius = mRadius;
for (int i = 0; i < mLevels; i++) {
int level = i + 1;
float sweep = (float) Math.PI / (mCounts[level] + 1);
@@ -205,6 +221,9 @@
for (PieItem item : mItems) {
drawItem(canvas, item);
}
+ if (mPieView != null) {
+ mPieView.draw(canvas);
+ }
}
}
@@ -236,10 +255,14 @@
}
} else if (MotionEvent.ACTION_UP == action) {
if (mOpen) {
+ boolean handled = false;
+ if (mPieView != null) {
+ handled = mPieView.onTouchEvent(evt);
+ }
PieItem item = mCurrentItem;
deselect();
show(false);
- if (item != null) {
+ if (!handled && (item != null)) {
item.getView().performClick();
}
return true;
@@ -254,6 +277,13 @@
boolean handled = false;
PointF polar = getPolar(x, y);
int maxr = mRadius + mLevels * mRadiusInc + 50;
+ if (mPieView != null) {
+ handled = mPieView.onTouchEvent(evt);
+ }
+ if (handled) {
+ invalidate();
+ return false;
+ }
if (polar.y > maxr) {
deselect();
show(false);
@@ -266,6 +296,13 @@
PieItem item = findItem(polar);
if (mCurrentItem != item) {
onEnter(item);
+ if ((item != null) && item.isPieView()) {
+ int cx = item.getView().getLeft() + (onTheLeft()
+ ? item.getView().getWidth() : 0);
+ int cy = item.getView().getTop();
+ mPieView = item.getPieView();
+ layoutPieView(mPieView, cx, cy);
+ }
invalidate();
}
}
@@ -273,6 +310,10 @@
return false;
}
+ private void layoutPieView(PieView pv, int x, int y) {
+ pv.layout(x, y, onTheLeft());
+ }
+
/**
* enter a slice for a view
* updates model only
@@ -287,6 +328,7 @@
// clear up stack
playSoundEffect(SoundEffectConstants.CLICK);
item.setSelected(true);
+ mPieView = null;
}
mCurrentItem = item;
}
@@ -296,6 +338,7 @@
mCurrentItem.setSelected(false);
}
mCurrentItem = null;
+ mPieView = null;
}
private PointF getPolar(float x, float y) {