diff options
| author | Michael Kolb <kolby@google.com> | 2010-07-08 15:41:55 -0700 |
|---|---|---|
| committer | Michael Kolb <kolby@google.com> | 2010-07-27 13:28:43 -0700 |
| commit | fe25199a6f975c67d28afcc1de56b0f987b66cd8 (patch) | |
| tree | f505e4b04283a2e26d32091648ae7a4c3c0d7664 /src/com/android/browser/TitleBarXLarge.java | |
| parent | b4b83182219908210d4554466367736692faf6ce (diff) | |
| download | packages_apps_Browser-fe25199a6f975c67d28afcc1de56b0f987b66cd8.tar.gz packages_apps_Browser-fe25199a6f975c67d28afcc1de56b0f987b66cd8.tar.bz2 packages_apps_Browser-fe25199a6f975c67d28afcc1de56b0f987b66cd8.zip | |
tabbed title bar work
bug # http://b/issue?id=2712871
added tab bar
added tab status callbacks to Tab and TabControl
added compact progress/stop/refresh button
added UrlInputView for auto-complete suggestions
modified BrowserProvider for url input suggestions
modified BrowserActivity to use TitleBarXLarge
Change-Id: I62db2be5b89f4c4f27c09dbc6fee7b3b0d5e91b5
Diffstat (limited to 'src/com/android/browser/TitleBarXLarge.java')
| -rw-r--r-- | src/com/android/browser/TitleBarXLarge.java | 531 |
1 files changed, 434 insertions, 97 deletions
diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java index 0d799a8b4..fd6d67b00 100644 --- a/src/com/android/browser/TitleBarXLarge.java +++ b/src/com/android/browser/TitleBarXLarge.java @@ -16,108 +16,168 @@ package com.android.browser; +import android.app.SearchManager; import android.content.Context; +import android.content.Intent; +import android.content.res.Configuration; import android.content.res.Resources; -import android.graphics.drawable.Animatable; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; -import android.util.DisplayMetrics; -import android.util.TypedValue; +import android.graphics.drawable.LayerDrawable; +import android.graphics.drawable.PaintDrawable; import android.view.ContextMenu; import android.view.LayoutInflater; import android.view.MenuInflater; import android.view.View; import android.widget.ImageView; -import android.widget.ProgressBar; +import android.widget.LinearLayout; import android.widget.TextView; -import com.android.common.speech.LoggingEvents; +import com.android.browser.TabControl.TabChangeListener; +import com.android.browser.UrlInputView.UrlInputListener; + +import java.util.HashMap; +import java.util.Map; /** - * This class represents a title bar for a particular "tab" or "window" in the - * browser. + * tabbed title bar for xlarge screen browser */ -public class TitleBarXLarge extends TitleBarBase { - private Drawable mCircularProgress; - private ProgressBar mHorizontalProgress; - private Drawable mStopDrawable; - private Drawable mReloadDrawable; - private boolean mInLoad; - private BrowserActivity mBrowserActivity; - - private final View mBackButton; - private final View mForwardButton; - private final View mStar; - private final View mMenu; - private final ImageView mStopButton; - private final TextView mTitle; - private final View mAllButton; - - public TitleBarXLarge(BrowserActivity context) { +public class TitleBarXLarge extends TitleBarBase + implements TabChangeListener, UrlInputListener { + + private static final int PROGRESS_MAX = 100; + + private static final int TAB_WIDTH_SELECTED = 400; + private static final int TAB_WIDTH_UNSELECTED = 150; + + private BrowserActivity mBrowserActivity; + private Drawable mStopDrawable; + private Drawable mReloadDrawable; + private Drawable mSelectedBackground; + private Drawable mUnselectedBackground; + + private View mBackButton; + private View mForwardButton; + private View mStar; + private View mMenu; + private View mAllButton; + private TabScrollView mTabs; + private View mNewButton; + private TabControl mControl; + private UrlInputView mUrlView; + + private boolean mIsInLandscape; + private Map<Tab, TabViewData> mTabMap; + + private float mDensityScale; + + public TitleBarXLarge(BrowserActivity context, TabControl tabcontrol) { super(context); - Resources resources = context.getResources(); - LayoutInflater factory = LayoutInflater.from(context); - factory.inflate(R.layout.title_bar_xlarge, this); + mDensityScale = context.getResources().getDisplayMetrics().density; + mTabMap = new HashMap<Tab, TabViewData>(); mBrowserActivity = context; + mControl = tabcontrol; + Resources resources = context.getResources(); + mSelectedBackground = resources.getDrawable(R.drawable.tab_selected_bg); + mUnselectedBackground = resources.getDrawable(R.drawable.tab_unselected_bg); + mStopDrawable = resources.getDrawable(R.drawable.progress_stop); + mReloadDrawable = resources.getDrawable(R.drawable.ic_reload); + rebuildLayout(context, true); + // register the tab change listener + mControl.setOnTabChangeListener(this); + } - mTitle = (TextView) findViewById(R.id.title); - mTitle.setCompoundDrawablePadding(5); - mTitle.setLongClickable(true); + void rebuildLayout() { + rebuildLayout(mBrowserActivity, false); + } - mLockIcon = (ImageView) findViewById(R.id.lock); - mFavicon = (ImageView) findViewById(R.id.favicon); - mStopButton = (ImageView) findViewById(R.id.stop); - mStopDrawable = mStopButton.getDrawable(); - mReloadDrawable = resources.getDrawable(R.drawable.ic_reload); + private void rebuildLayout(Context context, boolean rebuildData) { + removeAllViews(); + LayoutInflater factory = LayoutInflater.from(context); + factory.inflate(R.layout.title_bar_tabbed, this); - mAllButton = (ImageView) findViewById(R.id.all_btn); - mCircularProgress = (Drawable) resources.getDrawable( - com.android.internal.R.drawable.search_spinner); - DisplayMetrics metrics = resources.getDisplayMetrics(); - int iconDimension = (int) TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, 20f, metrics); - mCircularProgress.setBounds(0, 0, iconDimension, iconDimension); - mHorizontalProgress = (ProgressBar) findViewById( - R.id.progress_horizontal); - mHorizontalProgress.setProgressDrawable( - resources.getDrawable(R.drawable.progress)); - - // FIXME: Change enabled states based on whether you can go + mTabs = (TabScrollView) findViewById(R.id.tabs); + mNewButton = findViewById(R.id.newtab); + mUrlView = (UrlInputView) findViewById(R.id.editurl); + mAllButton = findViewById(R.id.all_btn); + // TODO: Change enabled states based on whether you can go // back/forward. Probably should be done inside onPageStarted. mBackButton = findViewById(R.id.back); mForwardButton = findViewById(R.id.forward); mStar = findViewById(R.id.star); mMenu = findViewById(R.id.menu); View.OnClickListener listener = new View.OnClickListener() { - public void onClick(View v) { - if (mBackButton == v) { - mBrowserActivity.getTopWindow().goBack(); - } else if (mForwardButton == v) { - mBrowserActivity.getTopWindow().goForward(); - } else if (mStar == v) { - mBrowserActivity.promptAddOrInstallBookmark(); - } else if (mMenu == v) { - mBrowserActivity.openOptionsMenu(); - } else if (mStopButton == v) { - if (mInLoad) { - mBrowserActivity.stopLoading(); - } else { - mBrowserActivity.getTopWindow().reload(); - } - } else if (mTitle == v) { - mBrowserActivity.editUrl(); - } else if (mAllButton == v) { - // FIXME: Show the new bookmarks/windows view. - mBrowserActivity.bookmarksOrHistoryPicker(false); - } + public void onClick(View v) { + if (mBackButton == v) { + mBrowserActivity.getTopWindow().goBack(); + } else if (mForwardButton == v) { + mBrowserActivity.getTopWindow().goForward(); + } else if (mStar == v) { + mBrowserActivity.promptAddOrInstallBookmark(); + } else if (mMenu == v) { + mBrowserActivity.openOptionsMenu(); + } else if (mAllButton == v) { + // TODO: Show the new bookmarks/windows view. + mBrowserActivity.bookmarksOrHistoryPicker(false); + } else if (mNewButton == v) { + mBrowserActivity.openTabToHomePage(); } + } }; mBackButton.setOnClickListener(listener); mForwardButton.setOnClickListener(listener); mStar.setOnClickListener(listener); - mStopButton.setOnClickListener(listener); - mTitle.setOnClickListener(listener); mAllButton.setOnClickListener(listener); mMenu.setOnClickListener(listener); + mNewButton.setOnClickListener(listener); + + mIsInLandscape = mBrowserActivity.getResources().getConfiguration().orientation + == Configuration.ORIENTATION_LANDSCAPE; + mUrlView.setVisibility(mIsInLandscape ? View.GONE : View.VISIBLE); + mUrlView.setUrlInputListener(this); + buildTabs(rebuildData); + // ensure title bar state + onCurrentTab(mControl.getCurrentTab()); + } + + void showUrlEditor(TabViewData tabdata) { + mUrlView.setVisibility(View.VISIBLE); + if (mIsInLandscape) { + mTabs.setVisibility(View.GONE); + mUrlView.requestFocus(); + mUrlView.forceIme(); + } + } + + void hideUrlEditor() { + Tab tab = mControl.getCurrentTab(); + if (mIsInLandscape) { + mUrlView.setVisibility(View.GONE); + mTabs.setVisibility(View.VISIBLE); + } else { + // portrait mode + mUrlView.setText(tab.getWebView().getUrl()); + } + tab.getWebView().requestFocus(); + } + + + // UrlInputListener implementation + + @Override + public void onAction(String text) { + hideUrlEditor(); + Intent i = new Intent(); + i.setAction(Intent.ACTION_SEARCH); + i.putExtra(SearchManager.QUERY, text); + mBrowserActivity.onNewIntent(i); + } + + @Override + public void onDismiss() { + hideUrlEditor(); } @Override @@ -127,44 +187,321 @@ public class TitleBarXLarge extends TitleBarBase { mBrowserActivity.onCreateContextMenu(menu, this, null); } + @Override + /* package */ void setLock(Drawable d) { + // TODO: handle in tab specific callback + } + + @Override + /* package */ void setFavicon(Bitmap icon) { + // this is handled in the tab specific callback + } + /** * Update the progress, from 0 to 100. */ + @Override /* package */ void setProgress(int newProgress) { - if (newProgress >= mHorizontalProgress.getMax()) { - mTitle.setCompoundDrawables(null, null, null, null); - ((Animatable) mCircularProgress).stop(); - mHorizontalProgress.setVisibility(View.GONE); - mInLoad = false; - mStopButton.setImageDrawable(mReloadDrawable); + // this is handled in tab specific callback + } + + @Override + /* package */ void setDisplayTitle(String title) { + // this is done in tab specific callback + } + + private void buildTabs(boolean needsRebuilding) { + mTabs.clearTabs(); + for (int i = 0; i < mControl.getTabCount(); i++) { + Tab tab = mControl.getTab(i); + TabViewData data = buildTab(needsRebuilding, tab); + TabView tv = buildView(data); + } + mTabs.setSelectedTab(mControl.getCurrentIndex()); + } + + private TabViewData buildTab(boolean needsRebuilding, Tab tab) { + TabViewData data = null; + if (needsRebuilding) { + data = new TabViewData(tab); + mTabMap.put(tab, data); } else { - mHorizontalProgress.setProgress(newProgress); - if (!mInLoad && getWindowToken() != null) { - // checking the window token lets us be sure that we - // are attached to a window before starting the animation, - // preventing a potential race condition - // (fix for bug http://b/2115736) - mTitle.setCompoundDrawables(null, null, mCircularProgress, - null); - ((Animatable) mCircularProgress).start(); - mHorizontalProgress.setVisibility(View.VISIBLE); - mInLoad = true; - mStopButton.setImageDrawable(mStopDrawable); - } + data = mTabMap.get(tab); } + return data; + } + + private TabView buildView(final TabViewData data) { + TabView tv = new TabView(mBrowserActivity, data); + tv.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (mTabs.getSelectedTab() == v) { + showUrlEditor(data); + } else { + int ix = mControl.getTabIndex(data.mTab); + mTabs.setSelectedTab(ix); + mBrowserActivity.switchToTab(ix); + } + } + }); + mTabs.addTab(tv); + return tv; } /** - * Update the text displayed in the title bar. - * @param title String to display. If null, the loading string will be - * shown. + * the views used in the tab bar */ - /* package */ void setDisplayTitle(String title) { - if (title == null) { - mTitle.setText(R.string.title_bar_loading); - } else { + class TabView extends LinearLayout { + + TabViewData mTabData; + View mTabContent; + TextView mTitle; + ImageView mIconView; + ImageView mLock; + CircularProgressView mStop; + ImageView mClose; + boolean mSelected; + boolean mInLoad; + + /** + * @param context + */ + public TabView(Context context, TabViewData tab) { + super(context); + mTabData = tab; + LayoutInflater inflater = LayoutInflater.from(mContext); + mTabContent = inflater.inflate(R.layout.tab_title, this); + mTitle = (TextView) mTabContent.findViewById(R.id.title); + mIconView = (ImageView) mTabContent.findViewById(R.id.favicon); + mLock = (ImageView) mTabContent.findViewById(R.id.lock); + mStop = (CircularProgressView) mTabContent.findViewById(R.id.stop); + mStop.setMaxProgress(PROGRESS_MAX); + mClose = (ImageView) mTabContent.findViewById(R.id.close); + mClose.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + closeTab(); + } + }); + mStop.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + if (mInLoad) { + mBrowserActivity.stopLoading(); + } else { + mBrowserActivity.getTopWindow().reload(); + } + } + }); + mSelected = false; + mInLoad = false; + // update the status + updateFromData(); + } + + private void updateFromData() { + mTabData.mTabView = this; + if (mTabData.mUrl != null) { + setDisplayTitle(mTabData.mUrl); + } + if (mTabData.mTitle != null) { + setDisplayTitle(mTabData.mTitle); + } + setProgress(mTabData.mProgress); + if (mTabData.mIcon != null) { + setFavicon(mTabData.mIcon); + } + if (mTabData.mLock != null) { + setLock(mTabData.mLock); + } + } + + @Override + public void setSelected(boolean selected) { + mSelected = selected; + mStop.setVisibility(mSelected ? View.VISIBLE : View.GONE); + mIconView.setVisibility(mSelected ? View.VISIBLE : View.GONE); + super.setSelected(selected); + setBackgroundDrawable(selected ? mSelectedBackground + : mUnselectedBackground); + setLayoutParams(new LayoutParams(selected ? + (int) (TAB_WIDTH_SELECTED * mDensityScale) + : (int) (TAB_WIDTH_UNSELECTED * mDensityScale), + LayoutParams.WRAP_CONTENT)); + } + + void setDisplayTitle(String title) { mTitle.setText(title); } + + void setFavicon(Drawable d) { + mIconView.setImageDrawable(d); + } + + void setLock(Drawable d) { + if (null == d) { + mLock.setVisibility(View.GONE); + } else { + mLock.setImageDrawable(d); + mLock.setVisibility(View.VISIBLE); + } + } + + void setTitleCompoundDrawables(Drawable left, Drawable top, + Drawable right, Drawable bottom) { + mTitle.setCompoundDrawables(left, top, right, bottom); + } + + void setProgress(int newProgress) { + mStop.setProgress(newProgress); + if (newProgress >= PROGRESS_MAX) { + mInLoad = false; + mStop.setImageDrawable(mReloadDrawable); + } else { + if (!mInLoad && getWindowToken() != null) { + // checking the window token lets us be sure that we + // are attached to a window before starting the animation, + // preventing a potential race condition + // (fix for bug http://b/2115736) + mInLoad = true; + mStop.setImageDrawable(mStopDrawable); + } + } + } + + private void closeTab() { + if (mTabData.mTab == mControl.getCurrentTab()) { + mBrowserActivity.closeCurrentWindow(); + } else { + mBrowserActivity.closeTab(mTabData.mTab); + } + } + + } + + /** + * class to store tab state within the title bar + */ + class TabViewData { + + Tab mTab; + TabView mTabView; + int mProgress; + Drawable mIcon; + Drawable mLock; + String mTitle; + String mUrl; + + TabViewData(Tab tab) { + mTab = tab; + } + + void setUrlAndTitle(String url, String title) { + mUrl = url; + mTitle = title; + if (mTabView != null) { + if (title != null) { + mTabView.setDisplayTitle(title); + } else if (url != null) { + mTabView.setDisplayTitle(url); + } + } + } + + void setProgress(int newProgress) { + mProgress = newProgress; + if (mTabView != null) { + mTabView.setProgress(mProgress); + } + } + + void setFavicon(Bitmap icon) { + Drawable[] array = new Drawable[3]; + array[0] = new PaintDrawable(Color.BLACK); + array[1] = new PaintDrawable(Color.WHITE); + if (icon == null) { + array[2] = mGenericFavicon; + } else { + array[2] = new BitmapDrawable(icon); + } + LayerDrawable d = new LayerDrawable(array); + d.setLayerInset(1, 1, 1, 1, 1); + d.setLayerInset(2, 2, 2, 2, 2); + mIcon = d; + if (mTabView != null) { + mTabView.setFavicon(mIcon); + } + } + + } + + // TabChangeListener implementation + + @Override + public void onCurrentTab(Tab tab) { + mTabs.setSelectedTab(mControl.getCurrentIndex()); + TabViewData tvd = mTabMap.get(tab); + if (tvd != null) { + if (tvd.mUrl != null) { + mUrlView.setText(tvd.mUrl); + } + setProgress(tvd.mProgress); + } + } + + @Override + public void onFavicon(Tab tab, Bitmap favicon) { + TabViewData tvd = mTabMap.get(tab); + if (tvd != null) { + tvd.setFavicon(favicon); + } + } + + @Override + public void onNewTab(Tab tab) { + TabViewData tvd = buildTab(true, tab); + buildView(tvd); + } + + @Override + public void onProgress(Tab tab, int progress) { + TabViewData tvd = mTabMap.get(tab); + if (tvd != null) { + tvd.setProgress(progress); + } + if (tab == mControl.getCurrentTab()) { + setProgress(progress); + } + } + + @Override + public void onRemoveTab(Tab tab) { + TabViewData tvd = mTabMap.get(tab); + TabView tv = tvd.mTabView; + if (tv != null) { + mTabs.removeTab(tv); + } + mTabMap.remove(tab); + } + + @Override + public void onUrlAndTitle(Tab tab, String url, String title) { + TabViewData tvd = mTabMap.get(tab); + if (tvd != null) { + tvd.setUrlAndTitle(url, title); + } + if ((url != null) && (tab == mControl.getCurrentTab())) { + mUrlView.setText(url); + } + } + + @Override + public void onPageFinished(Tab tab) { + } + + @Override + public void onPageStarted(Tab tab) { } } |
