summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael Kolb <kolby@google.com>2012-04-10 10:50:06 -0700
committerMichael Kolb <kolby@google.com>2012-04-11 16:22:56 -0700
commit80f750852edf43c6b09e5633f2c6ebdb2ed94a5b (patch)
tree03c7221422487fe91567b270200de3768a9bf800
parent9faa676ad7191d746b186c6b86a727c8fc9241f2 (diff)
downloadandroid_packages_apps_Gello-80f750852edf43c6b09e5633f2c6ebdb2ed94a5b.tar.gz
android_packages_apps_Gello-80f750852edf43c6b09e5633f2c6ebdb2ed94a5b.tar.bz2
android_packages_apps_Gello-80f750852edf43c6b09e5633f2c6ebdb2ed94a5b.zip
Submenus in QuickControls
Change-Id: I5d4fe7fdac1fb58e2e89afe00c468eed632428db
-rw-r--r--res/drawable-hdpi/ic_desktop_holo_dark.pngbin0 -> 867 bytes
-rw-r--r--res/drawable-mdpi/ic_desktop_holo_dark.pngbin0 -> 595 bytes
-rw-r--r--res/drawable-xhdpi/ic_desktop_holo_dark.pngbin0 -> 1099 bytes
-rw-r--r--res/values-sw600dp/dimensions.xml4
-rw-r--r--res/values/colors.xml3
-rw-r--r--res/values/dimensions.xml4
-rw-r--r--src/com/android/browser/BaseUi.java4
-rw-r--r--src/com/android/browser/Controller.java43
-rw-r--r--src/com/android/browser/PhoneUi.java4
-rw-r--r--src/com/android/browser/PieControl.java329
-rw-r--r--src/com/android/browser/PieControlBase.java187
-rw-r--r--src/com/android/browser/PieControlPhone.java123
-rw-r--r--src/com/android/browser/PieControlXLarge.java223
-rw-r--r--src/com/android/browser/UiController.java8
-rw-r--r--src/com/android/browser/XLargeUi.java8
-rw-r--r--src/com/android/browser/view/PieItem.java72
-rw-r--r--src/com/android/browser/view/PieMenu.java285
-rw-r--r--src/com/android/browser/view/PieStackView.java2
18 files changed, 675 insertions, 624 deletions
diff --git a/res/drawable-hdpi/ic_desktop_holo_dark.png b/res/drawable-hdpi/ic_desktop_holo_dark.png
new file mode 100644
index 00000000..76fbb85c
--- /dev/null
+++ b/res/drawable-hdpi/ic_desktop_holo_dark.png
Binary files differ
diff --git a/res/drawable-mdpi/ic_desktop_holo_dark.png b/res/drawable-mdpi/ic_desktop_holo_dark.png
new file mode 100644
index 00000000..1bb8120e
--- /dev/null
+++ b/res/drawable-mdpi/ic_desktop_holo_dark.png
Binary files differ
diff --git a/res/drawable-xhdpi/ic_desktop_holo_dark.png b/res/drawable-xhdpi/ic_desktop_holo_dark.png
new file mode 100644
index 00000000..1689e9df
--- /dev/null
+++ b/res/drawable-xhdpi/ic_desktop_holo_dark.png
Binary files differ
diff --git a/res/values-sw600dp/dimensions.xml b/res/values-sw600dp/dimensions.xml
index ed75f607..a6797f0c 100644
--- a/res/values-sw600dp/dimensions.xml
+++ b/res/values-sw600dp/dimensions.xml
@@ -25,8 +25,8 @@
<!-- For the combined Bookmarks History view -->
<dimen name="combo_paddingTop">50dip</dimen>
<dimen name="combo_horizontalSpacing">8dip</dimen>
- <dimen name="qc_radius_start">50dip</dimen>
- <dimen name="qc_radius_increment">70dip</dimen>
+ <dimen name="qc_radius_start">75dip</dimen>
+ <dimen name="qc_radius_increment">90dip</dimen>
<dimen name="qc_slop">15dip</dimen>
<dimen name="qc_touch_offset">15dip</dimen>
<dimen name="qc_tab_title_height">30dip</dimen>
diff --git a/res/values/colors.xml b/res/values/colors.xml
index 78f48837..ffee48bd 100644
--- a/res/values/colors.xml
+++ b/res/values/colors.xml
@@ -33,7 +33,8 @@
<color name="tabFocusHighlight">#FF99CC00</color>
<color name="qcMenuBackground">#C0000000</color>
<color name="qc_normal">#E02A96BC</color>
- <color name="qc_selected">#F01A5B73</color>
+ <color name="qc_selected">#E0FF8800</color>
+ <color name="qc_sub">#F01A5B73</color>
<color name="qc_tab_nr">#F033B5E5</color>
<color name="tabViewTitleBackground">#D0000000</color>
<color name="navtab_bg">#80606060</color>
diff --git a/res/values/dimensions.xml b/res/values/dimensions.xml
index d6ae6ba9..5e3ec8b4 100644
--- a/res/values/dimensions.xml
+++ b/res/values/dimensions.xml
@@ -27,8 +27,8 @@
<dimen name="widgetItemMinHeight">48dip</dimen>
<dimen name="favicon_size">16dip</dimen>
<dimen name="favicon_padded_size">20dip</dimen>
- <dimen name="qc_radius_start">60dip</dimen>
- <dimen name="qc_radius_increment">70dip</dimen>
+ <dimen name="qc_radius_start">65dip</dimen>
+ <dimen name="qc_radius_increment">80dip</dimen>
<dimen name="qc_slop">10dip</dimen>
<dimen name="qc_touch_offset">15dip</dimen>
<dimen name="qc_tab_title_height">24dip</dimen>
diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java
index 9aaceebb..be389284 100644
--- a/src/com/android/browser/BaseUi.java
+++ b/src/com/android/browser/BaseUi.java
@@ -472,6 +472,10 @@ public abstract class BaseUi implements UI {
return mTitleBar.isEditingUrl();
}
+ public void stopEditingUrl() {
+ mTitleBar.getNavigationBar().stopEditingUrl();
+ }
+
public TitleBar getTitleBar() {
return mTitleBar;
}
diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index 98611843..78a30d62 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -1587,10 +1587,7 @@ public class Controller
break;
case R.id.add_bookmark_menu_id:
- Intent bookmarkIntent = createBookmarkCurrentPageIntent(false);
- if (bookmarkIntent != null) {
- mActivity.startActivity(bookmarkIntent);
- }
+ bookmarkCurrentPage();
break;
case R.id.stop_reload_menu_id:
@@ -1624,14 +1621,10 @@ public class Controller
break;
case R.id.preferences_menu_id:
- Intent intent = new Intent(mActivity, BrowserPreferencesPage.class);
- intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
- getCurrentTopWebView().getUrl());
- mActivity.startActivityForResult(intent, PREFERENCES_PAGE);
+ openPreferences();
break;
case R.id.find_menu_id:
- getCurrentTopWebView().showFindDialog(null, true);
break;
case R.id.save_snapshot_menu_id:
@@ -1703,9 +1696,7 @@ public class Controller
break;
case R.id.ua_desktop_menu_id:
- WebView web = getCurrentWebView();
- mSettings.toggleDesktopUseragent(web);
- web.loadUrl(web.getOriginalUrl());
+ toggleUserAgent();
break;
case R.id.window_one_menu_id:
@@ -1737,6 +1728,34 @@ public class Controller
return true;
}
+ @Override
+ public void toggleUserAgent() {
+ WebView web = getCurrentWebView();
+ mSettings.toggleDesktopUseragent(web);
+ web.loadUrl(web.getOriginalUrl());
+ }
+
+ @Override
+ public void findOnPage() {
+ getCurrentTopWebView().showFindDialog(null, true);
+ }
+
+ @Override
+ public void openPreferences() {
+ Intent intent = new Intent(mActivity, BrowserPreferencesPage.class);
+ intent.putExtra(BrowserPreferencesPage.CURRENT_PAGE,
+ getCurrentTopWebView().getUrl());
+ mActivity.startActivityForResult(intent, PREFERENCES_PAGE);
+ }
+
+ @Override
+ public void bookmarkCurrentPage() {
+ Intent bookmarkIntent = createBookmarkCurrentPageIntent(false);
+ if (bookmarkIntent != null) {
+ mActivity.startActivity(bookmarkIntent);
+ }
+ }
+
private void goLive() {
Tab t = getCurrentTab();
t.loadUrl(t.getUrl(), null);
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index a1f70da4..153533b3 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -52,7 +52,7 @@ public class PhoneUi extends BaseUi {
private static final String LOGTAG = "PhoneUi";
private static final int MSG_INIT_NAVSCREEN = 100;
- private PieControlPhone mPieControl;
+ private PieControl mPieControl;
private NavScreen mNavScreen;
private AnimScreen mAnimScreen;
private NavigationBarPhone mNavigationBar;
@@ -268,7 +268,7 @@ public class PhoneUi extends BaseUi {
mUseQuickControls = useQuickControls;
mTitleBar.setUseQuickControls(mUseQuickControls);
if (useQuickControls) {
- mPieControl = new PieControlPhone(mActivity, mUiController, this);
+ mPieControl = new PieControl(mActivity, mUiController, this);
mPieControl.attachToContainer(mContentView);
} else {
if (mPieControl != null) {
diff --git a/src/com/android/browser/PieControl.java b/src/com/android/browser/PieControl.java
new file mode 100644
index 00000000..68b0c7b9
--- /dev/null
+++ b/src/com/android/browser/PieControl.java
@@ -0,0 +1,329 @@
+/*
+ * 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;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.view.LayoutInflater;
+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.ImageView.ScaleType;
+import android.widget.TextView;
+
+import com.android.browser.UI.ComboViews;
+import com.android.browser.view.PieItem;
+import com.android.browser.view.PieMenu;
+import com.android.browser.view.PieMenu.PieView.OnLayoutListener;
+import com.android.browser.view.PieStackView;
+import com.android.browser.view.PieStackView.OnCurrentListener;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Controller for Quick Controls pie menu
+ */
+public class PieControl implements PieMenu.PieController, OnClickListener {
+
+ protected Activity mActivity;
+ protected UiController mUiController;
+ protected PieMenu mPie;
+ protected int mItemSize;
+ protected TextView mTabsCount;
+ private BaseUi mUi;
+ private PieItem mBack;
+ private PieItem mForward;
+ private PieItem mRefresh;
+ private PieItem mUrl;
+ private PieItem mOptions;
+ private PieItem mBookmarks;
+ private PieItem mHistory;
+ private PieItem mAddBookmark;
+ private PieItem mNewTab;
+ private PieItem mIncognito;
+ private PieItem mClose;
+ private PieItem mShowTabs;
+ private PieItem mInfo;
+ private PieItem mFind;
+ private PieItem mShare;
+ private PieItem mRDS;
+ private TabAdapter mTabAdapter;
+
+ public PieControl(Activity activity, UiController controller, BaseUi ui) {
+ mActivity = activity;
+ mUiController = controller;
+ mItemSize = (int) activity.getResources().getDimension(R.dimen.qc_item_size);
+ mUi = ui;
+ }
+
+ public void stopEditingUrl() {
+ mUi.stopEditingUrl();
+ }
+
+ protected void attachToContainer(FrameLayout container) {
+ if (mPie == null) {
+ mPie = new PieMenu(mActivity);
+ LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
+ LayoutParams.MATCH_PARENT);
+ mPie.setLayoutParams(lp);
+ populateMenu();
+ mPie.setController(this);
+ }
+ container.addView(mPie);
+ }
+
+ protected void removeFromContainer(FrameLayout container) {
+ container.removeView(mPie);
+ }
+
+ protected void forceToTop(FrameLayout container) {
+ if (mPie.getParent() != null) {
+ container.removeView(mPie);
+ container.addView(mPie);
+ }
+ }
+
+ protected void setClickListener(OnClickListener listener, PieItem... items) {
+ for (PieItem item : items) {
+ item.getView().setOnClickListener(listener);
+ }
+ }
+
+ @Override
+ public boolean onOpen() {
+ int n = mUiController.getTabControl().getTabCount();
+ mTabsCount.setText(Integer.toString(n));
+ Tab tab = mUiController.getCurrentTab();
+ mForward.setEnabled(tab.canGoForward());
+ return true;
+ }
+
+ protected void populateMenu() {
+ mBack = makeItem(R.drawable.ic_back_holo_dark, 1);
+ mUrl = makeItem(R.drawable.ic_web_holo_dark, 1);
+ mBookmarks = makeItem(R.drawable.ic_bookmarks_holo_dark, 1);
+ mHistory = makeItem(R.drawable.ic_history_holo_dark, 1);
+ mAddBookmark = makeItem(R.drawable.ic_bookmark_on_holo_dark, 1);
+ mRefresh = makeItem(R.drawable.ic_refresh_holo_dark, 1);
+ mForward = makeItem(R.drawable.ic_forward_holo_dark, 1);
+ mNewTab = makeItem(R.drawable.ic_new_window_holo_dark, 1);
+ mIncognito = makeItem(R.drawable.ic_new_incognito_holo_dark, 1);
+ mClose = makeItem(R.drawable.ic_close_window_holo_dark, 1);
+ mInfo = makeItem(android.R.drawable.ic_menu_info_details, 1);
+ mFind = makeItem(R.drawable.ic_search_holo_dark, 1);
+ mShare = makeItem(R.drawable.ic_share_holo_dark, 1);
+ View tabs = makeTabsView();
+ mShowTabs = new PieItem(tabs, 1);
+ mOptions = makeItem(R.drawable.ic_settings_holo_dark, 1);
+ mRDS = makeItem(R.drawable.ic_desktop_holo_dark, 1);
+ mTabAdapter = new TabAdapter(mActivity, mUiController);
+ PieStackView stack = new PieStackView(mActivity);
+ stack.setLayoutListener(new OnLayoutListener() {
+ @Override
+ public void onLayout(int ax, int ay, boolean left) {
+ buildTabs();
+ }
+ });
+ stack.setOnCurrentListener(mTabAdapter);
+ stack.setAdapter(mTabAdapter);
+ mShowTabs.setPieView(stack);
+ setClickListener(this, mBack, mRefresh, mForward, mUrl, mFind, mInfo,
+ mShare, mBookmarks, mNewTab, mIncognito, mClose, mHistory,
+ mAddBookmark, mOptions, mRDS);
+ // level 1
+ mPie.addItem(mOptions);
+ mOptions.addItem(mRDS);
+ mOptions.addItem(makeFiller());
+ mOptions.addItem(makeFiller());
+ mOptions.addItem(makeFiller());
+ mPie.addItem(mBack);
+ mBack.addItem(mRefresh);
+ mBack.addItem(mForward);
+ mBack.addItem(makeFiller());
+ mBack.addItem(makeFiller());
+ mPie.addItem(mUrl);
+ mUrl.addItem(mFind);
+ mUrl.addItem(mShare);
+ mUrl.addItem(makeFiller());
+ mUrl.addItem(makeFiller());
+ mPie.addItem(mShowTabs);
+ mShowTabs.addItem(mClose);
+ mShowTabs.addItem(mIncognito);
+ mShowTabs.addItem(mNewTab);
+ mShowTabs.addItem(makeFiller());
+ mPie.addItem(mBookmarks);
+ mBookmarks.addItem(makeFiller());
+ mBookmarks.addItem(makeFiller());
+ mBookmarks.addItem(mAddBookmark);
+ mBookmarks.addItem(mHistory);
+ }
+
+ @Override
+ public void onClick(View v) {
+ Tab tab = mUiController.getTabControl().getCurrentTab();
+ WebView web = tab.getWebView();
+ if (mBack.getView() == v) {
+ tab.goBack();
+ } else if (mForward.getView() == v) {
+ tab.goForward();
+ } else if (mRefresh.getView() == v) {
+ if (tab.inPageLoad()) {
+ web.stopLoading();
+ } else {
+ web.reload();
+ }
+ } else if (mUrl.getView() == v) {
+ mUi.editUrl(false);
+ } else if (mBookmarks.getView() == v) {
+ mUiController.bookmarksOrHistoryPicker(ComboViews.Bookmarks);
+ } else if (mHistory.getView() == v) {
+ mUiController.bookmarksOrHistoryPicker(ComboViews.History);
+ } else if (mAddBookmark.getView() == v) {
+ mUiController.bookmarkCurrentPage();
+ } else if (mNewTab.getView() == v) {
+ mUiController.openTabToHomePage();
+ mUi.editUrl(false);
+ } else if (mIncognito.getView() == v) {
+ mUiController.openIncognitoTab();
+ mUi.editUrl(false);
+ } else if (mClose.getView() == v) {
+ mUiController.closeCurrentTab();
+ } else if (mOptions.getView() == v) {
+ mUiController.openPreferences();
+ } else if (mShare.getView() == v) {
+ mUiController.shareCurrentPage();
+ } else if (mInfo.getView() == v) {
+ mUiController.showPageInfo();
+ } else if (mFind.getView() == v) {
+ mUiController.findOnPage();
+ } else if (mRDS.getView() == v) {
+ mUiController.toggleUserAgent();
+ }
+ }
+
+ private void buildTabs() {
+ final List<Tab> tabs = mUiController.getTabs();
+ mUi.getActiveTab().capture();
+ mTabAdapter.setTabs(tabs);
+ PieStackView sym = (PieStackView) mShowTabs.getPieView();
+ sym.setCurrent(mUiController.getTabControl().getCurrentPosition());
+ }
+
+ protected PieItem makeItem(int image, int l) {
+ ImageView view = new ImageView(mActivity);
+ view.setImageResource(image);
+ view.setMinimumWidth(mItemSize);
+ view.setMinimumHeight(mItemSize);
+ view.setScaleType(ScaleType.CENTER);
+ LayoutParams lp = new LayoutParams(mItemSize, mItemSize);
+ view.setLayoutParams(lp);
+ return new PieItem(view, l);
+ }
+
+ protected PieItem makeFiller() {
+ return new PieItem(null, 1);
+ }
+
+ protected View makeTabsView() {
+ View v = mActivity.getLayoutInflater().inflate(R.layout.qc_tabs_view, null);
+ mTabsCount = (TextView) v.findViewById(R.id.label);
+ mTabsCount.setText("1");
+ ImageView image = (ImageView) v.findViewById(R.id.icon);
+ image.setImageResource(R.drawable.ic_windows_holo_dark);
+ image.setScaleType(ScaleType.CENTER);
+ LayoutParams lp = new LayoutParams(mItemSize, mItemSize);
+ v.setLayoutParams(lp);
+ return v;
+ }
+
+ static class TabAdapter extends BaseAdapter implements OnCurrentListener {
+
+ LayoutInflater mInflater;
+ UiController mUiController;
+ private List<Tab> mTabs;
+ private int mCurrent;
+
+ public TabAdapter(Context ctx, UiController ctl) {
+ mInflater = LayoutInflater.from(ctx);
+ mUiController = ctl;
+ mTabs = new ArrayList<Tab>();
+ mCurrent = -1;
+ }
+
+ public void setTabs(List<Tab> tabs) {
+ mTabs = tabs;
+ notifyDataSetChanged();
+ }
+
+ @Override
+ public int getCount() {
+ return mTabs.size();
+ }
+
+ @Override
+ public Tab getItem(int position) {
+ return mTabs.get(position);
+ }
+
+ @Override
+ public long getItemId(int position) {
+ return position;
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ final Tab tab = mTabs.get(position);
+ View view = mInflater.inflate(R.layout.qc_tab,
+ null);
+ ImageView thumb = (ImageView) view.findViewById(R.id.thumb);
+ TextView title1 = (TextView) view.findViewById(R.id.title1);
+ TextView title2 = (TextView) view.findViewById(R.id.title2);
+ Bitmap b = tab.getScreenshot();
+ if (b != null) {
+ thumb.setImageBitmap(b);
+ }
+ if (position > mCurrent) {
+ title1.setVisibility(View.GONE);
+ title2.setText(tab.getTitle());
+ } else {
+ title2.setVisibility(View.GONE);
+ title1.setText(tab.getTitle());
+ }
+ view.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ mUiController.switchToTab(tab);
+ }
+ });
+ return view;
+ }
+
+ @Override
+ public void onSetCurrent(int index) {
+ mCurrent = index;
+ }
+
+ }
+
+}
diff --git a/src/com/android/browser/PieControlBase.java b/src/com/android/browser/PieControlBase.java
deleted file mode 100644
index 830afea6..00000000
--- a/src/com/android/browser/PieControlBase.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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;
-
-import android.app.Activity;
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.view.ViewGroup;
-import android.view.ViewGroup.LayoutParams;
-import android.widget.BaseAdapter;
-import android.widget.FrameLayout;
-import android.widget.ImageView;
-import android.widget.ImageView.ScaleType;
-import android.widget.TextView;
-
-import com.android.browser.view.PieItem;
-import com.android.browser.view.PieMenu;
-import com.android.browser.view.PieStackView.OnCurrentListener;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * base controller for Quick Controls pie menu
- */
-public abstract class PieControlBase implements PieMenu.PieController {
-
- protected Activity mActivity;
- protected UiController mUiController;
- protected PieMenu mPie;
- protected int mItemSize;
- protected TextView mTabsCount;
-
- public PieControlBase(Activity activity, UiController controller) {
- mActivity = activity;
- mUiController = controller;
- mItemSize = (int) activity.getResources().getDimension(R.dimen.qc_item_size);
- }
-
- protected void attachToContainer(FrameLayout container) {
- if (mPie == null) {
- mPie = new PieMenu(mActivity);
- LayoutParams lp = new LayoutParams(LayoutParams.MATCH_PARENT,
- LayoutParams.MATCH_PARENT);
- mPie.setLayoutParams(lp);
- populateMenu();
- mPie.setController(this);
- }
- container.addView(mPie);
- }
-
- protected void removeFromContainer(FrameLayout container) {
- container.removeView(mPie);
- }
-
- protected void forceToTop(FrameLayout container) {
- if (mPie.getParent() != null) {
- container.removeView(mPie);
- container.addView(mPie);
- }
- }
-
- protected abstract void populateMenu();
-
- protected void setClickListener(OnClickListener listener, PieItem... items) {
- for (PieItem item : items) {
- item.getView().setOnClickListener(listener);
- }
- }
-
- @Override
- public boolean onOpen() {
- int n = mUiController.getTabControl().getTabCount();
- mTabsCount.setText(Integer.toString(n));
- return true;
- }
-
- protected PieItem makeItem(int image, int l) {
- ImageView view = new ImageView(mActivity);
- view.setImageResource(image);
- view.setMinimumWidth(mItemSize);
- view.setMinimumHeight(mItemSize);
- view.setScaleType(ScaleType.CENTER);
- LayoutParams lp = new LayoutParams(mItemSize, mItemSize);
- view.setLayoutParams(lp);
- return new PieItem(view, l);
- }
-
- protected View makeTabsView() {
- View v = mActivity.getLayoutInflater().inflate(R.layout.qc_tabs_view, null);
- mTabsCount = (TextView) v.findViewById(R.id.label);
- mTabsCount.setText("1");
- ImageView image = (ImageView) v.findViewById(R.id.icon);
- image.setImageResource(R.drawable.ic_windows_holo_dark);
- image.setScaleType(ScaleType.CENTER);
- LayoutParams lp = new LayoutParams(mItemSize, mItemSize);
- v.setLayoutParams(lp);
- return v;
- }
-
- static class TabAdapter extends BaseAdapter implements OnCurrentListener {
-
- LayoutInflater mInflater;
- UiController mUiController;
- private List<Tab> mTabs;
- private int mCurrent;
-
- public TabAdapter(Context ctx, UiController ctl) {
- mInflater = LayoutInflater.from(ctx);
- mUiController = ctl;
- mTabs = new ArrayList<Tab>();
- mCurrent = -1;
- }
-
- public void setTabs(List<Tab> tabs) {
- mTabs = tabs;
- notifyDataSetChanged();
- }
-
- @Override
- public int getCount() {
- return mTabs.size();
- }
-
- @Override
- public Tab getItem(int position) {
- return mTabs.get(position);
- }
-
- @Override
- public long getItemId(int position) {
- return position;
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final Tab tab = mTabs.get(position);
- View view = mInflater.inflate(R.layout.qc_tab,
- null);
- ImageView thumb = (ImageView) view.findViewById(R.id.thumb);
- TextView title1 = (TextView) view.findViewById(R.id.title1);
- TextView title2 = (TextView) view.findViewById(R.id.title2);
- Bitmap b = tab.getScreenshot();
- if (b != null) {
- thumb.setImageBitmap(b);
- }
- if (position > mCurrent) {
- title1.setVisibility(View.GONE);
- title2.setText(tab.getTitle());
- } else {
- title2.setVisibility(View.GONE);
- title1.setText(tab.getTitle());
- }
- view.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- mUiController.switchToTab(tab);
- }
- });
- return view;
- }
-
- @Override
- public void onSetCurrent(int index) {
- mCurrent = index;
- }
-
- }
-
-}
diff --git a/src/com/android/browser/PieControlPhone.java b/src/com/android/browser/PieControlPhone.java
deleted file mode 100644
index 2b6a3c53..00000000
--- a/src/com/android/browser/PieControlPhone.java
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * 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;
-
-import android.app.Activity;
-import android.view.Menu;
-import android.view.MenuItem;
-import android.view.View;
-import android.view.View.OnClickListener;
-import android.widget.PopupMenu;
-import android.widget.PopupMenu.OnMenuItemClickListener;
-
-import com.android.browser.UI.ComboViews;
-import com.android.browser.view.PieItem;
-import com.android.browser.view.PieMenu.PieView.OnLayoutListener;
-import com.android.browser.view.PieStackView;
-
-import java.util.List;
-
-/**
- * controller for Quick Controls pie menu
- */
-public class PieControlPhone extends PieControlBase implements OnClickListener,
- OnMenuItemClickListener {
-
- private PhoneUi mUi;
- private PieItem mUrl;
- private PieItem mShowTabs;
- private PieItem mOptions;
- private PieItem mNewTab;
- private PieItem mBookmarks;
- private TabAdapter mTabAdapter;
- private PopupMenu mPopup;
-
- public PieControlPhone(Activity activity, UiController controller, PhoneUi ui) {
- super(activity, controller);
- mUi = ui;
- }
-
- protected void populateMenu() {
- mUrl = makeItem(R.drawable.ic_web_holo_dark, 1);
- View tabs = makeTabsView();
- mShowTabs = new PieItem(tabs, 1);
- mTabAdapter = new TabAdapter(mActivity, mUiController);
- PieStackView stack = new PieStackView(mActivity);
- stack.setLayoutListener(new OnLayoutListener() {
- @Override
- public void onLayout(int ax, int ay, boolean left) {
- buildTabs();
- }
- });
- stack.setOnCurrentListener(mTabAdapter);
- stack.setAdapter(mTabAdapter);
- mShowTabs.setPieView(stack);
- mOptions = makeItem(com.android.internal.R.drawable.ic_menu_moreoverflow_normal_holo_dark,
- 1);
-
- // level 1
- mNewTab = makeItem(R.drawable.ic_new_window_holo_dark, 1);
- mBookmarks = makeItem(R.drawable.ic_bookmarks_holo_dark, 1);
- mPie.addItem(mNewTab);
- mPie.addItem(mShowTabs);
- mPie.addItem(mUrl);
- mPie.addItem(mBookmarks);
- mPie.addItem(mOptions);
- setClickListener(this, mUrl, mShowTabs, mOptions, mNewTab, mBookmarks);
- mPopup = new PopupMenu(mActivity, mUi.getTitleBar());
- Menu menu = mPopup.getMenu();
- mPopup.getMenuInflater().inflate(R.menu.browser, menu);
- mPopup.setOnMenuItemClickListener(this);
- }
-
- protected void showMenu() {
- mUiController.updateMenuState(mUiController.getCurrentTab(), mPopup.getMenu());
- mPopup.show();
- }
-
- @Override
- public boolean onMenuItemClick(MenuItem item) {
- return mUiController.onOptionsItemSelected(item);
- }
-
-
- private void buildTabs() {
- final List<Tab> tabs = mUiController.getTabs();
- mUi.getActiveTab().capture();
- mTabAdapter.setTabs(tabs);
- PieStackView sym = (PieStackView) mShowTabs.getPieView();
- sym.setCurrent(mUiController.getTabControl().getCurrentPosition());
-
- }
-
- @Override
- public void onClick(View v) {
- if (mUrl.getView() == v) {
- mUi.editUrl(false);
- } else if (mShowTabs.getView() == v) {
- mUi.showNavScreen();
- } else if (mOptions.getView() == v) {
- showMenu();
- } else if (mNewTab.getView() == v) {
- mUiController.openTabToHomePage();
- mUi.editUrl(false);
- } else if (mBookmarks.getView() == v) {
- mUiController.bookmarksOrHistoryPicker(ComboViews.Bookmarks);
- }
- }
-
-}
diff --git a/src/com/android/browser/PieControlXLarge.java b/src/com/android/browser/PieControlXLarge.java
deleted file mode 100644
index fcc8840d..00000000
--- a/src/com/android/browser/PieControlXLarge.java
+++ /dev/null
@@ -1,223 +0,0 @@
-/*
- * 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.browser;
-
-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.TextView;
-
-import com.android.browser.UI.ComboViews;
-import com.android.browser.view.PieItem;
-import com.android.browser.view.PieListView;
-import com.android.browser.view.PieMenu.PieView.OnLayoutListener;
-import com.android.browser.view.PieStackView;
-
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * controller for Quick Controls pie menu
- */
-public class PieControlXLarge extends PieControlBase implements OnClickListener {
-
- private BaseUi mUi;
- private PieItem mBack;
- private PieItem mForward;
- private PieItem mRefresh;
- private PieItem mUrl;
- private PieItem mOptions;
- private PieItem mBookmarks;
- private PieItem mNewTab;
- private PieItem mClose;
- private MenuAdapter mMenuAdapter;
- private PieItem mShowTabs;
- private TabAdapter mTabAdapter;
-
- public PieControlXLarge(Activity activity, UiController controller, BaseUi ui) {
- super(activity, controller);
- mUiController = controller;
- mUi = ui;
- }
-
- @Override
- protected void attachToContainer(FrameLayout container) {
- super.attachToContainer(container);
- mPie.setUseBackground(true);
- }
-
- protected void populateMenu() {
- mBack = makeItem(R.drawable.ic_back_holo_dark, 1);
- mUrl = makeItem(R.drawable.ic_web_holo_dark, 1);
- mBookmarks = makeItem(R.drawable.ic_bookmarks_holo_dark, 1);
- mRefresh = makeItem(R.drawable.ic_refresh_holo_dark, 2);
- mForward = makeItem(R.drawable.ic_forward_holo_dark, 2);
- mNewTab = makeItem(R.drawable.ic_new_window_holo_dark, 2);
- mClose = makeItem(R.drawable.ic_close_window_holo_dark, 2);
- View tabs = makeTabsView();
- mShowTabs = new PieItem(tabs, 2);
- mOptions = makeItem(com.android.internal.R.drawable.ic_menu_moreoverflow_normal_holo_dark,
- 2);
- mMenuAdapter = new MenuAdapter(mActivity, mUiController);
- mTabAdapter = new TabAdapter(mActivity, mUiController);
- PieStackView stack = new PieStackView(mActivity);
- stack.setLayoutListener(new OnLayoutListener() {
- @Override
- public void onLayout(int ax, int ay, boolean left) {
- buildTabs();
- }
- });
- stack.setOnCurrentListener(mTabAdapter);
- stack.setAdapter(mTabAdapter);
- mShowTabs.setPieView(stack);
- PieListView menuview = new PieListView(mActivity);
- menuview.setLayoutListener(new OnLayoutListener() {
- @Override
- public void onLayout(int ax, int ay, boolean left) {
- buildMenu();
- }
- });
-
- mOptions.setPieView(menuview);
- menuview.setAdapter(mMenuAdapter);
- setClickListener(this, mBack, mRefresh, mForward, mUrl, mBookmarks, mNewTab,
- mClose);
- // level 1
- mPie.addItem(mBack);
- mPie.addItem(mUrl);
- mPie.addItem(mBookmarks);
- // level 2
- mPie.addItem(mForward);
- mPie.addItem(mRefresh);
- mPie.addItem(mOptions);
- mPie.addItem(mShowTabs);
- mPie.addItem(mNewTab);
- mPie.addItem(mClose);
- }
-
- private void buildTabs() {
- final List<Tab> tabs = mUiController.getTabs();
- mUi.getActiveTab().capture();
- mTabAdapter.setTabs(tabs);
- PieStackView sym = (PieStackView) mShowTabs.getPieView();
- sym.setCurrent(mUiController.getTabControl().getCurrentPosition());
- }
-
- private void buildMenu() {
- Menu menu = mUi.getMenu();
- menu.setGroupVisible(R.id.NAV_MENU, false);
- mMenuAdapter.setMenu(menu);
- }
-
- @Override
- public void onClick(View v) {
- Tab tab = mUiController.getTabControl().getCurrentTab();
- WebView web = tab.getWebView();
- if (mBack.getView() == v) {
- tab.goBack();
- } else if (mForward.getView() == v) {
- tab.goForward();
- } else if (mRefresh.getView() == v) {
- if (tab.inPageLoad()) {
- web.stopLoading();
- } else {
- web.reload();
- }
- } else if (mUrl.getView() == v) {
- mUi.editUrl(false);
- } else if (mBookmarks.getView() == v) {
- mUiController.bookmarksOrHistoryPicker(ComboViews.Bookmarks);
- } else if (mNewTab.getView() == v) {
- mUiController.openTabToHomePage();
- mUi.editUrl(false);
- } else if (mClose.getView() == v) {
- mUiController.closeCurrentTab();
- }
- }
-
- 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/UiController.java b/src/com/android/browser/UiController.java
index e7a8953b..46c04321 100644
--- a/src/com/android/browser/UiController.java
+++ b/src/com/android/browser/UiController.java
@@ -65,6 +65,8 @@ public interface UiController {
void bookmarksOrHistoryPicker(ComboViews startView);
+ void bookmarkCurrentPage();
+
void startVoiceSearch();
boolean supportsVoiceSearch();
@@ -103,4 +105,10 @@ public interface UiController {
void showPageInfo();
+ void openPreferences();
+
+ void findOnPage();
+
+ void toggleUserAgent();
+
}
diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java
index b372fab1..391b83eb 100644
--- a/src/com/android/browser/XLargeUi.java
+++ b/src/com/android/browser/XLargeUi.java
@@ -50,7 +50,7 @@ public class XLargeUi extends BaseUi {
private NavigationBarTablet mNavBar;
- private PieControlXLarge mPieControl;
+ private PieControl mPieControl;
private Handler mHandler;
/**
@@ -86,7 +86,7 @@ public class XLargeUi extends BaseUi {
mTitleBar.setUseQuickControls(mUseQuickControls);
if (useQuickControls) {
checkTabCount();
- mPieControl = new PieControlXLarge(mActivity, mUiController, this);
+ mPieControl = new PieControl(mActivity, mUiController, this);
mPieControl.attachToContainer(mContentView);
} else {
mActivity.getActionBar().show();
@@ -230,10 +230,6 @@ public class XLargeUi extends BaseUi {
super.editUrl(clearInput);
}
- void stopEditingUrl() {
- mTitleBar.getNavigationBar().stopEditingUrl();
- }
-
@Override
protected void showTitleBar() {
if (canShowTitleBar()) {
diff --git a/src/com/android/browser/view/PieItem.java b/src/com/android/browser/view/PieItem.java
index 36744472..9e04ecbf 100644
--- a/src/com/android/browser/view/PieItem.java
+++ b/src/com/android/browser/view/PieItem.java
@@ -16,10 +16,12 @@
package com.android.browser.view;
+import android.view.View;
+
import com.android.browser.view.PieMenu.PieView;
-import android.graphics.Path;
-import android.view.View;
+import java.util.ArrayList;
+import java.util.List;
/**
* Pie menu item
@@ -31,20 +33,66 @@ public class PieItem {
private int level;
private float start;
private float sweep;
+ private float animate;
private int inner;
private int outer;
private boolean mSelected;
- private Path mPath;
+ private boolean mEnabled;
+ private List<PieItem> mItems;
public PieItem(View view, int level) {
mView = view;
this.level = level;
+ mEnabled = true;
+ setAnimationAngle(getAnimationAngle());
+ setAlpha(getAlpha());
}
public PieItem(View view, int level, PieView sym) {
mView = view;
this.level = level;
mPieView = sym;
+ mEnabled = false;
+ }
+
+ public boolean hasItems() {
+ return mItems != null;
+ }
+
+ public List<PieItem> getItems() {
+ return mItems;
+ }
+
+ public void addItem(PieItem item) {
+ if (mItems == null) {
+ mItems = new ArrayList<PieItem>();
+ }
+ mItems.add(item);
+ }
+
+ public void setAlpha(float alpha) {
+ if (mView != null) {
+ mView.setAlpha(alpha);
+ }
+ }
+
+ public float getAlpha() {
+ if (mView != null) {
+ return mView.getAlpha();
+ }
+ return 1;
+ }
+
+ public void setAnimationAngle(float a) {
+ animate = a;
+ }
+
+ public float getAnimationAngle() {
+ return animate;
+ }
+
+ public void setEnabled(boolean enabled) {
+ mEnabled = enabled;
}
public void setSelected(boolean s) {
@@ -62,18 +110,21 @@ public class PieItem {
return level;
}
- public void setGeometry(float st, float sw, int inside, int outside, Path p) {
+ public void setGeometry(float st, float sw, int inside, int outside) {
start = st;
sweep = sw;
inner = inside;
outer = outside;
- mPath = p;
}
- public float getStartAngle() {
+ public float getStart() {
return start;
}
+ public float getStartAngle() {
+ return start + animate;
+ }
+
public float getSweep() {
return sweep;
}
@@ -99,11 +150,10 @@ public class PieItem {
}
public PieView getPieView() {
- return mPieView;
- }
-
- public Path getPath() {
- return mPath;
+ if (mEnabled) {
+ return mPieView;
+ }
+ return null;
}
}
diff --git a/src/com/android/browser/view/PieMenu.java b/src/com/android/browser/view/PieMenu.java
index 7f8dd6b8..1fd0e99a 100644
--- a/src/com/android/browser/view/PieMenu.java
+++ b/src/com/android/browser/view/PieMenu.java
@@ -16,8 +16,11 @@
package com.android.browser.view;
-import com.android.browser.R;
-
+import android.animation.Animator;
+import android.animation.Animator.AnimatorListener;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.animation.ValueAnimator.AnimatorUpdateListener;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.Canvas;
@@ -34,12 +37,15 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
+import com.android.browser.R;
+
import java.util.ArrayList;
import java.util.List;
public class PieMenu extends FrameLayout {
private static final int MAX_LEVELS = 5;
+ private static final long ANIMATION = 80;
public interface PieController {
/**
@@ -47,6 +53,8 @@ public class PieMenu extends FrameLayout {
* returns if pie state has been changed
*/
public boolean onOpen();
+ public void stopEditingUrl();
+
}
/**
@@ -74,6 +82,7 @@ public class PieMenu extends FrameLayout {
private int mRadiusInc;
private int mSlop;
private int mTouchOffset;
+ private Path mPath;
private boolean mOpen;
private PieController mController;
@@ -83,14 +92,20 @@ public class PieMenu extends FrameLayout {
private int[] mCounts;
private PieView mPieView = null;
+ // sub menus
+ private List<PieItem> mCurrentItems;
+ private PieItem mOpenItem;
+
private Drawable mBackground;
private Paint mNormalPaint;
private Paint mSelectedPaint;
+ private Paint mSubPaint;
// touch handling
- PieItem mCurrentItem;
+ private PieItem mCurrentItem;
private boolean mUseBackground;
+ private boolean mAnimating;
/**
* @param context
@@ -139,6 +154,9 @@ public class PieMenu extends FrameLayout {
mSelectedPaint = new Paint();
mSelectedPaint.setColor(res.getColor(R.color.qc_selected));
mSelectedPaint.setAntiAlias(true);
+ mSubPaint = new Paint();
+ mSubPaint.setAntiAlias(true);
+ mSubPaint.setColor(res.getColor(R.color.qc_sub));
}
public void setController(PieController ctl) {
@@ -176,18 +194,39 @@ public class PieMenu extends FrameLayout {
private void show(boolean show) {
mOpen = show;
if (mOpen) {
+ mController.stopEditingUrl();
+ mCurrentItems = mItems;
if (mController != null) {
boolean changed = mController.onOpen();
}
layoutPie();
+ animateOpen();
}
if (!show) {
+ mAnimating = false;
mCurrentItem = null;
+ mOpenItem = null;
mPieView = null;
}
invalidate();
}
+ private void animateOpen() {
+ ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+ anim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ for (PieItem item : mCurrentItems) {
+ item.setAnimationAngle((1 - animation.getAnimatedFraction()) * (- item.getStart()));
+ }
+ invalidate();
+ }
+
+ });
+ anim.setDuration(2*ANIMATION);
+ anim.start();
+ }
+
private void setCenter(int x, int y) {
if (x < mSlop) {
mCenter.x = 0;
@@ -202,33 +241,32 @@ public class PieMenu extends FrameLayout {
int rgap = 2;
int inner = mRadius + rgap;
int outer = mRadius + mRadiusInc - rgap;
- int radius = mRadius;
int gap = 1;
for (int i = 0; i < mLevels; i++) {
int level = i + 1;
float sweep = (float) (Math.PI - 2 * emptyangle) / mCounts[level];
float angle = emptyangle + sweep / 2;
- for (PieItem item : mItems) {
+ mPath = makeSlice(getDegrees(0) - gap, getDegrees(sweep) + gap, outer, inner, mCenter);
+ for (PieItem item : mCurrentItems) {
if (item.getLevel() == level) {
View view = item.getView();
- view.measure(view.getLayoutParams().width,
- view.getLayoutParams().height);
- int w = view.getMeasuredWidth();
- int h = view.getMeasuredHeight();
- int r = inner + (outer - inner) * 2 / 3;
- int x = (int) (r * Math.sin(angle));
- int y = mCenter.y - (int) (r * Math.cos(angle)) - h / 2;
- if (onTheLeft()) {
- x = mCenter.x + x - w / 2;
- } else {
- x = mCenter.x - x - w / 2;
+ if (view != null) {
+ view.measure(view.getLayoutParams().width,
+ view.getLayoutParams().height);
+ int w = view.getMeasuredWidth();
+ int h = view.getMeasuredHeight();
+ int r = inner + (outer - inner) * 2 / 3;
+ int x = (int) (r * Math.sin(angle));
+ int y = mCenter.y - (int) (r * Math.cos(angle)) - h / 2;
+ if (onTheLeft()) {
+ x = mCenter.x + x - w / 2;
+ } else {
+ x = mCenter.x - x - w / 2;
+ }
+ view.layout(x, y, x + w, y + h);
}
- view.layout(x, y, x + w, y + h);
float itemstart = angle - sweep / 2;
- Path slice = makeSlice(getDegrees(itemstart) - gap,
- getDegrees(itemstart + sweep) + gap,
- outer, inner, mCenter);
- item.setGeometry(itemstart, sweep, inner, outer, slice);
+ item.setGeometry(itemstart, sweep, inner, outer);
angle += sweep;
}
}
@@ -266,15 +304,18 @@ public class PieMenu extends FrameLayout {
mBackground.draw(canvas);
canvas.restoreToCount(state);
}
- for (PieItem item : mItems) {
- Paint p = item.isSelected() ? mSelectedPaint : mNormalPaint;
- state = canvas.save();
- if (onTheLeft()) {
- canvas.scale(-1, 1);
+ // draw base menu
+ PieItem last = mCurrentItem;
+ if (mOpenItem != null) {
+ last = mOpenItem;
+ }
+ for (PieItem item : mCurrentItems) {
+ if (item != last) {
+ drawItem(canvas, item);
}
- drawPath(canvas, item.getPath(), p);
- canvas.restoreToCount(state);
- drawItem(canvas, item);
+ }
+ if (last != null) {
+ drawItem(canvas, last);
}
if (mPieView != null) {
mPieView.draw(canvas);
@@ -283,19 +324,26 @@ public class PieMenu extends FrameLayout {
}
private void drawItem(Canvas canvas, PieItem item) {
- int outer = item.getOuterRadius();
- int left = mCenter.x - outer;
- int top = mCenter.y - outer;
- // draw the item view
- View view = item.getView();
- int state = canvas.save();
- canvas.translate(view.getX(), view.getY());
- view.draw(canvas);
- canvas.restoreToCount(state);
- }
-
- private void drawPath(Canvas canvas, Path path, Paint paint) {
- canvas.drawPath(path, paint);
+ if (item.getView() != null) {
+ Paint p = item.isSelected() ? mSelectedPaint : mNormalPaint;
+ if (!mItems.contains(item)) {
+ p = item.isSelected() ? mSelectedPaint : mSubPaint;
+ }
+ int state = canvas.save();
+ if (onTheLeft()) {
+ canvas.scale(-1, 1);
+ }
+ float r = getDegrees(item.getStartAngle()) - 270; // degrees(0)
+ canvas.rotate(r, mCenter.x, mCenter.y);
+ canvas.drawPath(mPath, p);
+ canvas.restoreToCount(state);
+ // draw the item view
+ View view = item.getView();
+ state = canvas.save();
+ canvas.translate(view.getX(), view.getY());
+ view.draw(canvas);
+ canvas.restoreToCount(state);
+ }
}
private Path makeSlice(float start, float end, int outer, int inner, Point center) {
@@ -332,9 +380,11 @@ public class PieMenu extends FrameLayout {
handled = mPieView.onTouchEvent(evt);
}
PieItem item = mCurrentItem;
- deselect();
+ if (!mAnimating) {
+ deselect();
+ }
show(false);
- if (!handled && (item != null)) {
+ if (!mAnimating && !handled && (item != null) && (item.getView() != null)) {
item.getView().performClick();
}
return true;
@@ -343,9 +393,13 @@ public class PieMenu extends FrameLayout {
if (mOpen) {
show(false);
}
- deselect();
+ if (!mAnimating) {
+ deselect();
+ invalidate();
+ }
return false;
} else if (MotionEvent.ACTION_MOVE == action) {
+ if (mAnimating) return false;
boolean handled = false;
PointF polar = getPolar(x, y);
int maxr = mRadius + mLevels * mRadiusInc + 50;
@@ -356,6 +410,15 @@ public class PieMenu extends FrameLayout {
invalidate();
return false;
}
+ if (polar.y < mRadius) {
+ if (mOpenItem != null) {
+ closeSub();
+ } else if (!mAnimating) {
+ deselect();
+ invalidate();
+ }
+ return false;
+ }
if (polar.y > maxr) {
deselect();
show(false);
@@ -366,9 +429,10 @@ public class PieMenu extends FrameLayout {
return false;
}
PieItem item = findItem(polar);
- if (mCurrentItem != item) {
+ if (item == null) {
+ } else if (mCurrentItem != item) {
onEnter(item);
- if ((item != null) && item.isPieView()) {
+ if ((item != null) && item.isPieView() && (item.getView() != null)) {
int cx = item.getView().getLeft() + (onTheLeft()
? item.getView().getWidth() : 0);
int cy = item.getView().getTop();
@@ -402,14 +466,125 @@ public class PieMenu extends FrameLayout {
playSoundEffect(SoundEffectConstants.CLICK);
item.setSelected(true);
mPieView = null;
+ mCurrentItem = item;
+ if ((mCurrentItem != mOpenItem) && mCurrentItem.hasItems()) {
+ openSub(mCurrentItem);
+ mOpenItem = item;
+ }
+ } else {
+ mCurrentItem = null;
}
- mCurrentItem = item;
+
+ }
+
+ private void animateOut(final PieItem fixed, AnimatorListener listener) {
+ if ((mCurrentItems == null) || (fixed == null)) return;
+ final float target = fixed.getStartAngle();
+ ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+ anim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ for (PieItem item : mCurrentItems) {
+ if (item != fixed) {
+ item.setAnimationAngle(animation.getAnimatedFraction()
+ * (target - item.getStart()));
+ }
+ }
+ invalidate();
+ }
+ });
+ anim.setDuration(ANIMATION);
+ anim.addListener(listener);
+ anim.start();
+ }
+
+ private void animateIn(final PieItem fixed, AnimatorListener listener) {
+ if ((mCurrentItems == null) || (fixed == null)) return;
+ final float target = fixed.getStartAngle();
+ ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
+ anim.addUpdateListener(new AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ for (PieItem item : mCurrentItems) {
+ if (item != fixed) {
+ item.setAnimationAngle((1 - animation.getAnimatedFraction())
+ * (target - item.getStart()));
+ }
+ }
+ invalidate();
+
+ }
+
+ });
+ anim.setDuration(ANIMATION);
+ anim.addListener(listener);
+ anim.start();
+ }
+
+ private void openSub(final PieItem item) {
+ mAnimating = true;
+ animateOut(item, new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator a) {
+ for (PieItem item : mCurrentItems) {
+ item.setAnimationAngle(0);
+ }
+ mCurrentItems = new ArrayList<PieItem>(mItems.size());
+ int i = 0, j = 0;
+ while (i < mItems.size()) {
+ if (mItems.get(i) == item) {
+ mCurrentItems.add(item);
+ } else {
+ mCurrentItems.add(item.getItems().get(j++));
+ }
+ i++;
+ }
+ layoutPie();
+ animateIn(item, new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator a) {
+ for (PieItem item : mCurrentItems) {
+ item.setAnimationAngle(0);
+ }
+ mAnimating = false;
+ }
+ });
+ }
+ });
+ }
+
+ private void closeSub() {
+ mAnimating = true;
+ if (mCurrentItem != null) {
+ mCurrentItem.setSelected(false);
+ }
+ animateOut(mOpenItem, new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator a) {
+ for (PieItem item : mCurrentItems) {
+ item.setAnimationAngle(0);
+ }
+ mCurrentItems = mItems;
+ mPieView = null;
+ animateIn(mOpenItem, new AnimatorListenerAdapter() {
+ public void onAnimationEnd(Animator a) {
+ for (PieItem item : mCurrentItems) {
+ item.setAnimationAngle(0);
+ }
+ mAnimating = false;
+ mOpenItem = null;
+ mCurrentItem = null;
+ }
+ });
+ }
+ });
}
private void deselect() {
if (mCurrentItem != null) {
mCurrentItem.setSelected(false);
}
+ if (mOpenItem != null) {
+ mOpenItem = null;
+ mCurrentItems = mItems;
+ }
mCurrentItem = null;
mPieView = null;
}
@@ -439,15 +614,19 @@ public class PieMenu extends FrameLayout {
*/
private PieItem findItem(PointF polar) {
// find the matching item:
- for (PieItem item : mItems) {
- if ((item.getInnerRadius() - mTouchOffset < polar.y)
- && (item.getOuterRadius() - mTouchOffset > polar.y)
- && (item.getStartAngle() < polar.x)
- && (item.getStartAngle() + item.getSweep() > polar.x)) {
+ for (PieItem item : mCurrentItems) {
+ if (inside(polar, mTouchOffset, item)) {
return item;
}
}
return null;
}
+ private boolean inside(PointF polar, float offset, PieItem item) {
+ return (item.getInnerRadius() - offset < polar.y)
+ && (item.getOuterRadius() - offset > polar.y)
+ && (item.getStartAngle() < polar.x)
+ && (item.getStartAngle() + item.getSweep() > polar.x);
+ }
+
}
diff --git a/src/com/android/browser/view/PieStackView.java b/src/com/android/browser/view/PieStackView.java
index 16d42cbc..e1f41bd8 100644
--- a/src/com/android/browser/view/PieStackView.java
+++ b/src/com/android/browser/view/PieStackView.java
@@ -50,8 +50,6 @@ public class PieStackView extends BasePieView {
super.setCurrent(ix);
if (mCurrentListener != null) {
mCurrentListener.onSetCurrent(ix);
- buildViews();
- layoutChildrenLinear();
}
}