From 0f602f3933dcd88702fdb514b6611e3066ca7a2b Mon Sep 17 00:00:00 2001 From: John Reck Date: Thu, 7 Jul 2011 15:38:43 -0700 Subject: TitleBar refactor Change-Id: I0a2df041529143c8e0ff17af341376a3f827be04 --- src/com/android/browser/AutologinBar.java | 145 +++++ src/com/android/browser/BaseUi.java | 59 +- src/com/android/browser/BrowserWebView.java | 4 +- src/com/android/browser/Controller.java | 2 +- src/com/android/browser/NavigationBarBase.java | 333 ++++++++++++ src/com/android/browser/NavigationBarPhone.java | 229 ++++++++ src/com/android/browser/NavigationBarTablet.java | 236 ++++++++ src/com/android/browser/PhoneUi.java | 25 +- src/com/android/browser/TitleBar.java | 341 ++++++++++++ src/com/android/browser/TitleBarBase.java | 664 ----------------------- src/com/android/browser/TitleBarPhone.java | 250 --------- src/com/android/browser/TitleBarXLarge.java | 251 --------- src/com/android/browser/XLargeUi.java | 34 +- 13 files changed, 1337 insertions(+), 1236 deletions(-) create mode 100644 src/com/android/browser/AutologinBar.java create mode 100644 src/com/android/browser/NavigationBarBase.java create mode 100644 src/com/android/browser/NavigationBarPhone.java create mode 100644 src/com/android/browser/NavigationBarTablet.java create mode 100644 src/com/android/browser/TitleBar.java delete mode 100644 src/com/android/browser/TitleBarBase.java delete mode 100644 src/com/android/browser/TitleBarPhone.java delete mode 100644 src/com/android/browser/TitleBarXLarge.java (limited to 'src/com') diff --git a/src/com/android/browser/AutologinBar.java b/src/com/android/browser/AutologinBar.java new file mode 100644 index 00000000..e57d614b --- /dev/null +++ b/src/com/android/browser/AutologinBar.java @@ -0,0 +1,145 @@ +/* + * 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.content.Context; +import android.util.AttributeSet; +import android.view.ContextThemeWrapper; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.ArrayAdapter; +import android.widget.Button; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.Spinner; +import android.widget.TextView; + +import com.android.browser.DeviceAccountLogin.AutoLoginCallback; + +public class AutologinBar extends LinearLayout implements OnClickListener, + AutoLoginCallback { + + protected Spinner mAutoLoginAccount; + protected Button mAutoLoginLogin; + protected ProgressBar mAutoLoginProgress; + protected TextView mAutoLoginError; + protected View mAutoLoginCancel; + protected DeviceAccountLogin mAutoLoginHandler; + protected ArrayAdapter mAccountsAdapter; + protected TitleBar mTitleBar; + + public AutologinBar(Context context) { + super(context); + } + + public AutologinBar(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public AutologinBar(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mAutoLoginAccount = (Spinner) findViewById(R.id.autologin_account); + mAutoLoginLogin = (Button) findViewById(R.id.autologin_login); + mAutoLoginLogin.setOnClickListener(this); + mAutoLoginProgress = (ProgressBar) findViewById(R.id.autologin_progress); + mAutoLoginError = (TextView) findViewById(R.id.autologin_error); + mAutoLoginCancel = findViewById(R.id.autologin_close); + mAutoLoginCancel.setOnClickListener(this); + } + + public void setTitleBar(TitleBar titleBar) { + mTitleBar = titleBar; + } + + @Override + public void onClick(View v) { + if (mAutoLoginCancel == v) { + if (mAutoLoginHandler != null) { + mAutoLoginHandler.cancel(); + mAutoLoginHandler = null; + } + hideAutoLogin(true); + } else if (mAutoLoginLogin == v) { + if (mAutoLoginHandler != null) { + mAutoLoginAccount.setEnabled(false); + mAutoLoginLogin.setEnabled(false); + mAutoLoginProgress.setVisibility(View.VISIBLE); + mAutoLoginError.setVisibility(View.GONE); + mAutoLoginHandler.login( + mAutoLoginAccount.getSelectedItemPosition(), this); + } + } + } + + public void updateAutoLogin(Tab tab, boolean animate) { + DeviceAccountLogin login = tab.getDeviceAccountLogin(); + if (login != null) { + mAutoLoginHandler = login; + ContextThemeWrapper wrapper = new ContextThemeWrapper(mContext, + android.R.style.Theme_Holo_Light); + mAccountsAdapter = new ArrayAdapter(wrapper, + android.R.layout.simple_spinner_item, login.getAccountNames()); + mAccountsAdapter.setDropDownViewResource( + android.R.layout.simple_spinner_dropdown_item); + mAutoLoginAccount.setAdapter(mAccountsAdapter); + mAutoLoginAccount.setSelection(0); + mAutoLoginAccount.setEnabled(true); + mAutoLoginLogin.setEnabled(true); + mAutoLoginProgress.setVisibility(View.INVISIBLE); + mAutoLoginError.setVisibility(View.GONE); + switch (login.getState()) { + case DeviceAccountLogin.PROCESSING: + mAutoLoginAccount.setEnabled(false); + mAutoLoginLogin.setEnabled(false); + mAutoLoginProgress.setVisibility(View.VISIBLE); + break; + case DeviceAccountLogin.FAILED: + mAutoLoginProgress.setVisibility(View.INVISIBLE); + mAutoLoginError.setVisibility(View.VISIBLE); + break; + case DeviceAccountLogin.INITIAL: + break; + default: + throw new IllegalStateException(); + } + showAutoLogin(animate); + } else { + hideAutoLogin(animate); + } + } + + void showAutoLogin(boolean animate) { + mTitleBar.showAutoLogin(animate); + } + + void hideAutoLogin(boolean animate) { + mTitleBar.hideAutoLogin(animate); + } + + @Override + public void loginFailed() { + mAutoLoginAccount.setEnabled(true); + mAutoLoginLogin.setEnabled(true); + mAutoLoginProgress.setVisibility(View.INVISIBLE); + mAutoLoginError.setVisibility(View.VISIBLE); + } + +} diff --git a/src/com/android/browser/BaseUi.java b/src/com/android/browser/BaseUi.java index 9de2c579..5551ecae 100644 --- a/src/com/android/browser/BaseUi.java +++ b/src/com/android/browser/BaseUi.java @@ -17,7 +17,6 @@ package com.android.browser; import android.app.Activity; -import android.content.pm.PackageManager; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Bitmap; @@ -110,6 +109,8 @@ public abstract class BaseUi implements UI, OnTouchListener { private boolean mActivityPaused; protected boolean mUseQuickControls; + protected TitleBar mTitleBar; + private NavigationBarBase mNavigationBar; public BaseUi(Activity browser, UiController controller) { mActivity = browser; @@ -140,6 +141,10 @@ public abstract class BaseUi implements UI, OnTouchListener { config.getScaledOverscrollDistance()); mTitlebarScrollTriggerSlop = Math.max(mTitlebarScrollTriggerSlop, config.getScaledTouchSlop()); + mTitleBar = new TitleBar(mActivity, mUiController, this, + mContentView); + mTitleBar.setProgress(100); + mNavigationBar = mTitleBar.getNavigationBar(); } private void cancelStopToast() { @@ -170,6 +175,10 @@ public abstract class BaseUi implements UI, OnTouchListener { public void onConfigurationChanged(Configuration config) { } + public Activity getActivity() { + return mActivity; + } + // key handling @Override @@ -205,7 +214,7 @@ public abstract class BaseUi implements UI, OnTouchListener { public void bookmarkedStatusHasChanged(Tab tab) { if (tab.inForeground()) { boolean isBookmark = tab.isBookmarkedSite(); - getTitleBar().setCurrentUrlIsBookmark(isBookmark); + mNavigationBar.setCurrentUrlIsBookmark(isBookmark); } } @@ -248,10 +257,10 @@ public abstract class BaseUi implements UI, OnTouchListener { onTabDataChanged(tab); onProgressChanged(tab); boolean incognito = mActiveTab.getWebView().isPrivateBrowsingEnabled(); - getTitleBar().setIncognitoMode(incognito); + mNavigationBar.setIncognitoMode(incognito); updateAutoLogin(tab, false); if (web != null && web.getVisibleTitleHeight() - != getTitleBar().getEmbeddedHeight() + != mTitleBar.getEmbeddedHeight() && !mUseQuickControls) { showTitleBarForDuration(); } @@ -422,7 +431,7 @@ public abstract class BaseUi implements UI, OnTouchListener { mUiController.endActionMode(); } showTitleBar(); - getTitleBar().startEditingUrl(clearInput); + mNavigationBar.startEditingUrl(clearInput); } boolean canShowTitleBar() { @@ -433,27 +442,29 @@ public abstract class BaseUi implements UI, OnTouchListener { && !mUiController.isInCustomActionMode(); } - void showTitleBar() { + protected void showTitleBar() { if (canShowTitleBar()) { - getTitleBar().show(); + mTitleBar.show(); } } protected void hideTitleBar() { - if (getTitleBar().isShowing()) { - getTitleBar().hide(); + if (mTitleBar.isShowing()) { + mTitleBar.hide(); } } protected boolean isTitleBarShowing() { - return getTitleBar().isShowing(); + return mTitleBar.isShowing(); } public boolean isEditingUrl() { - return getTitleBar().isEditingUrl(); + return mTitleBar.isEditingUrl(); } - protected abstract TitleBarBase getTitleBar(); + public TitleBar getTitleBar() { + return mTitleBar; + } protected void setTitleGravity(int gravity) { WebView web = getWebView(); @@ -464,20 +475,20 @@ public abstract class BaseUi implements UI, OnTouchListener { @Override public void showVoiceTitleBar(String title, List results) { - getTitleBar().setInVoiceMode(true, results); - getTitleBar().setDisplayTitle(title); + mNavigationBar.setInVoiceMode(true, results); + mNavigationBar.setDisplayTitle(title); } @Override public void revertVoiceTitleBar(Tab tab) { - getTitleBar().setInVoiceMode(false, null); + mNavigationBar.setInVoiceMode(false, null); String url = tab.getUrl(); - getTitleBar().setDisplayTitle(url); + mNavigationBar.setDisplayTitle(url); } @Override public void registerDropdownChangeListener(DropdownChangeListener d) { - getTitleBar().registerDropdownChangeListener(d); + mNavigationBar.registerDropdownChangeListener(d); } @Override @@ -492,7 +503,7 @@ public abstract class BaseUi implements UI, OnTouchListener { FrameLayout wrapper = (FrameLayout) mContentView.findViewById(R.id.webview_wrapper); wrapper.setVisibility(View.GONE); - getTitleBar().stopEditingUrl(); + mNavigationBar.stopEditingUrl(); dismissIME(); hideTitleBar(); if (mActiveTab != null) { @@ -599,7 +610,7 @@ public abstract class BaseUi implements UI, OnTouchListener { } protected void updateAutoLogin(Tab tab, boolean animate) { - getTitleBar().updateAutoLogin(tab, animate); + mTitleBar.updateAutoLogin(tab, animate); } /** @@ -621,7 +632,7 @@ public abstract class BaseUi implements UI, OnTouchListener { } else if (lockIconType == LockIcon.LOCK_ICON_MIXED) { d = mMixLockIcon; } - getTitleBar().setLock(d); + mNavigationBar.setLock(d); } protected void setUrlTitle(Tab tab) { @@ -632,7 +643,7 @@ public abstract class BaseUi implements UI, OnTouchListener { } if (tab.isInVoiceSearchMode()) return; if (tab.inForeground()) { - getTitleBar().setDisplayTitle(url); + mNavigationBar.setDisplayTitle(url); } } @@ -640,7 +651,7 @@ public abstract class BaseUi implements UI, OnTouchListener { protected void setFavicon(Tab tab) { if (tab.inForeground()) { Bitmap icon = tab.getFavicon(); - getTitleBar().setFavicon(icon); + mNavigationBar.setFavicon(icon); } } @@ -793,7 +804,7 @@ public abstract class BaseUi implements UI, OnTouchListener { } } - protected Drawable getFaviconDrawable(Bitmap icon) { + public Drawable getFaviconDrawable(Bitmap icon) { Drawable[] array = new Drawable[3]; array[0] = new PaintDrawable(Color.BLACK); PaintDrawable p = new PaintDrawable(Color.WHITE); @@ -819,7 +830,7 @@ public abstract class BaseUi implements UI, OnTouchListener { * as if the user is editing the URL bar or if the page is loading */ public void suggestHideTitleBar() { - if (!isLoading() && !isEditingUrl()) { + if (!isLoading() && !isEditingUrl() && !mTitleBar.inAutoLogin()) { hideTitleBar(); } } diff --git a/src/com/android/browser/BrowserWebView.java b/src/com/android/browser/BrowserWebView.java index 80f4a538..cd29135c 100644 --- a/src/com/android/browser/BrowserWebView.java +++ b/src/com/android/browser/BrowserWebView.java @@ -33,7 +33,7 @@ import java.util.Map; public class BrowserWebView extends WebView { private boolean mBackgroundRemoved = false; - private TitleBarBase mTitleBar; + private TitleBar mTitleBar; private int mCaptureSize; private Bitmap mCapture; private WebProxyView mProxyView; @@ -107,7 +107,7 @@ public class BrowserWebView extends WebView { @Override public void setEmbeddedTitleBar(final View title) { super.setEmbeddedTitleBar(title); - mTitleBar = (TitleBarBase) title; + mTitleBar = (TitleBar) title; } public boolean hasTitleBar() { diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java index f4563bd1..116f0e08 100644 --- a/src/com/android/browser/Controller.java +++ b/src/com/android/browser/Controller.java @@ -1287,7 +1287,7 @@ public class Controller protected void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) { - if (v instanceof TitleBarBase) { + if (v instanceof TitleBar) { return; } if (!(v instanceof WebView)) { diff --git a/src/com/android/browser/NavigationBarBase.java b/src/com/android/browser/NavigationBarBase.java new file mode 100644 index 00000000..a0593522 --- /dev/null +++ b/src/com/android/browser/NavigationBarBase.java @@ -0,0 +1,333 @@ +/* + * 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.SearchManager; +import android.content.Context; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.os.Bundle; +import android.speech.RecognizerResultsIntent; +import android.util.AttributeSet; +import android.view.KeyEvent; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.View.OnFocusChangeListener; +import android.webkit.WebView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.PopupMenu; +import android.widget.PopupMenu.OnMenuItemClickListener; + +import com.android.browser.UI.DropdownChangeListener; +import com.android.browser.UrlInputView.UrlInputListener; +import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher; + +import java.util.List; + +public class NavigationBarBase extends LinearLayout implements OnClickListener, + OnMenuItemClickListener, UrlInputListener, OnFocusChangeListener, + TextChangeWatcher { + + protected BaseUi mBaseUi; + protected TitleBar mTitleBar; + protected UiController mUiController; + protected UrlInputView mUrlInput; + protected boolean mInVoiceMode = false; + + private ImageView mFavicon; + private ImageView mLockIcon; + private View mUaSwitcher; + + public NavigationBarBase(Context context) { + super(context); + } + + public NavigationBarBase(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public NavigationBarBase(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mLockIcon = (ImageView) findViewById(R.id.lock); + mFavicon = (ImageView) findViewById(R.id.favicon); + mUrlInput = (UrlInputView) findViewById(R.id.url); + mUrlInput.setUrlInputListener(this); + mUrlInput.setController(mUiController); + mUrlInput.setOnFocusChangeListener(this); + mUrlInput.setSelectAllOnFocus(true); + mUrlInput.addQueryTextWatcher(this); + } + + public void setTitleBar(TitleBar titleBar) { + mTitleBar = titleBar; + mBaseUi = mTitleBar.getUi(); + mUiController = mTitleBar.getUiController(); + } + + public void setLock(Drawable d) { + if (mLockIcon == null) return; + if (d == null) { + mLockIcon.setVisibility(View.GONE); + } else { + mLockIcon.setImageDrawable(d); + mLockIcon.setVisibility(View.VISIBLE); + } + } + + public void setFavicon(Bitmap icon) { + if (mFavicon == null) return; + mFavicon.setImageDrawable(mBaseUi.getFaviconDrawable(icon)); + } + + public void setUaSwitcher(View v) { + if (mUaSwitcher != null) { + mUaSwitcher.setOnClickListener(null); + } + mUaSwitcher = v; + mUaSwitcher.setOnClickListener(this); + } + + @Override + public void onClick(View v) { + if (mUaSwitcher == v) { + BrowserSettings settings = BrowserSettings.getInstance(); + WebView web = mTitleBar.getCurrentWebView(); + if (web == null) return; + boolean desktop = settings.hasDesktopUseragent(web); + PopupMenu popup = new PopupMenu(mContext, mUaSwitcher); + Menu menu = popup.getMenu(); + popup.getMenuInflater().inflate(R.menu.ua_switcher, menu); + menu.findItem(R.id.ua_mobile_menu_id).setChecked(!desktop); + menu.findItem(R.id.ua_desktop_menu_id).setChecked(desktop); + popup.setOnMenuItemClickListener(this); + popup.show(); + } + } + + @Override + public boolean onMenuItemClick(MenuItem item) { + BrowserSettings settings = BrowserSettings.getInstance(); + WebView web = mTitleBar.getCurrentWebView(); + if (web == null) return false; + boolean desktop = settings.hasDesktopUseragent(web); + switch (item.getItemId()) { + case R.id.ua_mobile_menu_id: + if (desktop) { + settings.toggleDesktopUseragent(web); + web.loadUrl(web.getOriginalUrl()); + } + return true; + case R.id.ua_desktop_menu_id: + if (!desktop) { + settings.toggleDesktopUseragent(web); + web.loadUrl(web.getOriginalUrl()); + } + return true; + } + return false; + } + + @Override + public void onFocusChange(View view, boolean hasFocus) { + // if losing focus and not in touch mode, leave as is + if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) { + setFocusState(hasFocus); + } + if (hasFocus) { + mBaseUi.showTitleBar(); + mUrlInput.forceIme(); + if (mInVoiceMode) { + mUrlInput.forceFilter(); + } + } else if (!mUrlInput.needsUpdate()) { + mUrlInput.dismissDropDown(); + mUrlInput.hideIME(); + if (mUrlInput.getText().length() == 0) { + Tab currentTab = mUiController.getTabControl().getCurrentTab(); + if (currentTab != null) { + mUrlInput.setText(currentTab.getUrl(), false); + } + } + mBaseUi.suggestHideTitleBar(); + } + mUrlInput.clearNeedsUpdate(); + } + + protected void setFocusState(boolean focus) { + } + + protected void setSearchMode(boolean voiceSearchEnabled) {} + + public boolean isEditingUrl() { + return mUrlInput.hasFocus(); + } + + void stopEditingUrl() { + mUrlInput.clearFocus(); + } + + void setDisplayTitle(String title) { + if (!isEditingUrl()) { + mUrlInput.setText(title, false); + } + } + + // UrlInput text watcher + + @Override + public void onTextChanged(String newText) { + if (mUrlInput.hasFocus()) { + // clear voice mode when user types + setInVoiceMode(false, null); + } + } + + // voicesearch + + public void setInVoiceMode(boolean voicemode, List voiceResults) { + mInVoiceMode = voicemode; + mUrlInput.setVoiceResults(voiceResults); + } + + void setIncognitoMode(boolean incognito) { + mUrlInput.setIncognitoMode(incognito); + } + + void clearCompletions() { + mUrlInput.setSuggestedText(null); + } + + // UrlInputListener implementation + + /** + * callback from suggestion dropdown + * user selected a suggestion + */ + @Override + public void onAction(String text, String extra, String source) { + mUiController.getCurrentTopWebView().requestFocus(); + if (UrlInputView.TYPED.equals(source)) { + String url = UrlUtils.smartUrlFilter(text, false); + Tab t = mBaseUi.getActiveTab(); + // Only shortcut javascript URIs for now, as there is special + // logic in UrlHandler for other schemas + if (url != null && t != null && url.startsWith("javascript:")) { + mUiController.loadUrl(t, url); + setDisplayTitle(text); + return; + } + } + Intent i = new Intent(); + String action = null; + if (UrlInputView.VOICE.equals(source)) { + action = RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS; + source = null; + } else { + action = Intent.ACTION_SEARCH; + } + i.setAction(action); + i.putExtra(SearchManager.QUERY, text); + if (extra != null) { + i.putExtra(SearchManager.EXTRA_DATA_KEY, extra); + } + if (source != null) { + Bundle appData = new Bundle(); + appData.putString(com.android.common.Search.SOURCE, source); + i.putExtra(SearchManager.APP_DATA, appData); + } + mUiController.handleNewIntent(i); + setDisplayTitle(text); + } + + @Override + public void onDismiss() { + final Tab currentTab = mBaseUi.getActiveTab(); + mBaseUi.hideTitleBar(); + post(new Runnable() { + public void run() { + clearFocus(); + if ((currentTab != null) && !mInVoiceMode) { + setDisplayTitle(currentTab.getUrl()); + } + } + }); + } + + /** + * callback from the suggestion dropdown + * copy text to input field and stay in edit mode + */ + @Override + public void onCopySuggestion(String text) { + mUrlInput.setText(text, true); + if (text != null) { + mUrlInput.setSelection(text.length()); + } + } + + public void setCurrentUrlIsBookmark(boolean isBookmark) { + } + + @Override + public boolean dispatchKeyEventPreIme(KeyEvent evt) { + if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) { + // catch back key in order to do slightly more cleanup than usual + mUrlInput.clearFocus(); + return true; + } + return super.dispatchKeyEventPreIme(evt); + } + + void registerDropdownChangeListener(DropdownChangeListener d) { + mUrlInput.registerDropdownChangeListener(d); + } + + /** + * called from the Ui when the user wants to edit + * @param clearInput clear the input field + */ + void startEditingUrl(boolean clearInput) { + // editing takes preference of progress + setVisibility(View.VISIBLE); + if (mTitleBar.useQuickControls()) { + mTitleBar.getProgressView().setVisibility(View.GONE); + } + if (!mUrlInput.hasFocus()) { + mUrlInput.requestFocus(); + } + if (clearInput) { + mUrlInput.setText(""); + } else if (mInVoiceMode) { + mUrlInput.showDropDown(); + } + } + + public void onProgressStarted() { + } + + public void onProgressStopped() { + } + +} diff --git a/src/com/android/browser/NavigationBarPhone.java b/src/com/android/browser/NavigationBarPhone.java new file mode 100644 index 00000000..c0ce4289 --- /dev/null +++ b/src/com/android/browser/NavigationBarPhone.java @@ -0,0 +1,229 @@ +/* + * 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.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.util.AttributeSet; +import android.view.ContextMenu; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.ViewConfiguration; +import android.webkit.WebView; +import android.widget.ImageView; +import android.widget.PopupMenu; +import android.widget.PopupMenu.OnDismissListener; + +import com.android.browser.UrlInputView.StateListener; + +public class NavigationBarPhone extends NavigationBarBase implements + StateListener, OnDismissListener { + + private ImageView mStopButton; + private ImageView mVoiceButton; + private Drawable mStopDrawable; + private Drawable mRefreshDrawable; + private View mTabSwitcher; + private View mComboIcon; + private View mTitleContainer; + private View mMore; + private Drawable mTextfieldBgDrawable; + private boolean mMenuShowing; + private boolean mNeedsMenu; + + public NavigationBarPhone(Context context) { + super(context); + } + + public NavigationBarPhone(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public NavigationBarPhone(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mStopButton = (ImageView) findViewById(R.id.stop); + mStopButton.setOnClickListener(this); + mVoiceButton = (ImageView) findViewById(R.id.voice); + mVoiceButton.setOnClickListener(this); + mTabSwitcher = findViewById(R.id.tab_switcher); + mTabSwitcher.setOnClickListener(this); + mMore = findViewById(R.id.more); + mMore.setOnClickListener(this); + mComboIcon = findViewById(R.id.iconcombo); + mTitleContainer = findViewById(R.id.title_bg); + setFocusState(false); + Resources res = getContext().getResources(); + mStopDrawable = res.getDrawable(R.drawable.ic_stop_holo_dark); + mRefreshDrawable = res.getDrawable(R.drawable.ic_refresh_holo_dark); + mTextfieldBgDrawable = res.getDrawable(R.drawable.textfield_active_holo_dark); + setUaSwitcher(mComboIcon); + mUrlInput.setContainer(this); + mUrlInput.setStateListener(this); + mNeedsMenu = !ViewConfiguration.get(getContext()).hasPermanentMenuKey(); + } + + @Override + public void createContextMenu(ContextMenu menu) { + Activity activity = mBaseUi.getActivity(); + MenuInflater inflater = activity.getMenuInflater(); + inflater.inflate(R.menu.title_context, menu); + activity.onCreateContextMenu(menu, this, null); + } + + @Override + protected void setSearchMode(boolean voiceSearchEnabled) { + boolean showvoicebutton = voiceSearchEnabled && + mUiController.supportsVoiceSearch(); + mVoiceButton.setVisibility(showvoicebutton ? View.VISIBLE : + View.GONE); + } + + @Override + public void onProgressStarted() { + super.onProgressStarted(); + if (mStopButton.getDrawable() != mStopDrawable) { + mStopButton.setImageDrawable(mStopDrawable); + if (mStopButton.getVisibility() != View.VISIBLE) { + mComboIcon.setVisibility(View.GONE); + mStopButton.setVisibility(View.VISIBLE); + } + } + } + + @Override + public void onProgressStopped() { + super.onProgressStopped(); + mStopButton.setVisibility(View.GONE); + mStopButton.setImageDrawable(mRefreshDrawable); + if (!isEditingUrl()) { + mComboIcon.setVisibility(View.VISIBLE); + } + } + + /** + * Update the text displayed in the title bar. + * @param title String to display. If null, the new tab string will be + * shown. + */ + @Override + void setDisplayTitle(String title) { + if (!isEditingUrl()) { + if (title == null) { + mUrlInput.setText(R.string.new_tab); + } else { + mUrlInput.setText(title); + } + mUrlInput.setSelection(0); + } + } + + @Override + public void onClick(View v) { + if (v == mStopButton) { + if (mTitleBar.isInLoad()) { + mUiController.stopLoading(); + } else { + WebView web = mBaseUi.getWebView(); + if (web != null) { + stopEditingUrl(); + web.reload(); + } + } + } else if (v == mVoiceButton) { + mUiController.startVoiceSearch(); + } else if (v == mTabSwitcher) { + mBaseUi.onMenuKey(); + } else if (mMore == v) { + showMenu(); + } else { + super.onClick(v); + } + } + + public boolean isMenuShowing() { + return mMenuShowing; + } + + private void showMenu() { + mMenuShowing = true; + PopupMenu popup = new PopupMenu(mContext, mMore); + Menu menu = popup.getMenu(); + popup.getMenuInflater().inflate(R.menu.browser, menu); + menu.setGroupVisible(R.id.NAV_MENU, false); + popup.setOnMenuItemClickListener(this); + popup.setOnDismissListener(this); + popup.show(); + } + + @Override + public void onDismiss(PopupMenu menu) { + onMenuHidden(); + } + + @Override + public boolean onMenuItemClick(MenuItem item) { + onMenuHidden(); + boolean res = mUiController.onOptionsItemSelected(item); + if (!res) { + return super.onMenuItemClick(item); + } + return res; + } + + private void onMenuHidden() { + mMenuShowing = false; + mBaseUi.showTitleBarForDuration(); + } + + @Override + public void onStateChanged(int state) { + switch(state) { + case StateListener.STATE_NORMAL: + mComboIcon.setVisibility(View.VISIBLE); + mStopButton.setVisibility(View.GONE); + setSearchMode(false); + mTabSwitcher.setVisibility(View.VISIBLE); + mTitleContainer.setBackgroundDrawable(null); + mMore.setVisibility(mNeedsMenu ? View.VISIBLE : View.GONE); + break; + case StateListener.STATE_HIGHLIGHTED: + mComboIcon.setVisibility(View.GONE); + mStopButton.setVisibility(View.VISIBLE); + setSearchMode(true); + mTabSwitcher.setVisibility(View.GONE); + mMore.setVisibility(View.GONE); + mTitleContainer.setBackgroundDrawable(mTextfieldBgDrawable); + break; + case StateListener.STATE_EDITED: + mComboIcon.setVisibility(View.GONE); + mStopButton.setVisibility(View.GONE); + setSearchMode(false); + mTabSwitcher.setVisibility(View.GONE); + mMore.setVisibility(View.GONE); + mTitleContainer.setBackgroundDrawable(mTextfieldBgDrawable); + break; + } + } +} diff --git a/src/com/android/browser/NavigationBarTablet.java b/src/com/android/browser/NavigationBarTablet.java new file mode 100644 index 00000000..b7b3ed95 --- /dev/null +++ b/src/com/android/browser/NavigationBarTablet.java @@ -0,0 +1,236 @@ +/* + * 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.content.Context; +import android.content.res.Resources; +import android.graphics.drawable.Drawable; +import android.text.TextUtils; +import android.util.AttributeSet; +import android.view.View; +import android.webkit.WebView; +import android.widget.ImageButton; +import android.widget.ImageView; + +import java.util.List; + +public class NavigationBarTablet extends NavigationBarBase { + + private Drawable mStopDrawable; + private Drawable mReloadDrawable; + + private View mUrlContainer; + private ImageButton mBackButton; + private ImageButton mForwardButton; + private ImageView mStar; + private ImageView mUrlIcon; + private ImageView mSearchButton; + private View mGoButton; + private ImageView mStopButton; + private View mAllButton; + private View mClearButton; + private ImageView mVoiceSearch; + private Drawable mFocusDrawable; + private Drawable mUnfocusDrawable; + + public NavigationBarTablet(Context context) { + super(context); + init(context); + } + + public NavigationBarTablet(Context context, AttributeSet attrs) { + super(context, attrs); + init(context); + } + + public NavigationBarTablet(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + init(context); + } + + private void init(Context context) { + Resources resources = context.getResources(); + mStopDrawable = resources.getDrawable(R.drawable.ic_stop_holo_dark); + mReloadDrawable = resources.getDrawable(R.drawable.ic_refresh_holo_dark); + mFocusDrawable = resources.getDrawable( + R.drawable.textfield_active_holo_dark); + mUnfocusDrawable = resources.getDrawable( + R.drawable.textfield_default_holo_dark); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + 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 = (ImageButton) findViewById(R.id.back); + mForwardButton = (ImageButton) findViewById(R.id.forward); + mUrlIcon = (ImageView) findViewById(R.id.url_icon); + mStar = (ImageView) findViewById(R.id.star); + mStopButton = (ImageView) findViewById(R.id.stop); + mSearchButton = (ImageView) findViewById(R.id.search); + mGoButton = findViewById(R.id.go); + mClearButton = findViewById(R.id.clear); + mVoiceSearch = (ImageView) findViewById(R.id.voicesearch); + mUrlContainer = findViewById(R.id.urlbar_focused); + mBackButton.setOnClickListener(this); + mForwardButton.setOnClickListener(this); + mStar.setOnClickListener(this); + mAllButton.setOnClickListener(this); + mStopButton.setOnClickListener(this); + mSearchButton.setOnClickListener(this); + mGoButton.setOnClickListener(this); + mClearButton.setOnClickListener(this); + mVoiceSearch.setOnClickListener(this); + setUaSwitcher(mUrlIcon); + mUrlInput.setContainer(mUrlContainer); + } + + @Override + public void setTitleBar(TitleBar titleBar) { + super.setTitleBar(titleBar); + setFocusState(false); + } + + void updateNavigationState(Tab tab) { + WebView web = tab.getWebView(); + if (web != null) { + mBackButton.setImageResource(web.canGoBack() + ? R.drawable.ic_back_holo_dark + : R.drawable.ic_back_disabled_holo_dark); + mForwardButton.setImageResource(web.canGoForward() + ? R.drawable.ic_forward_holo_dark + : R.drawable.ic_forward_disabled_holo_dark); + } + updateUrlIcon(); + } + + @Override + public void setCurrentUrlIsBookmark(boolean isBookmark) { + mStar.setActivated(isBookmark); + } + + @Override + public void onClick(View v) { + if (mBackButton == v) { + mUiController.getCurrentTopWebView().goBack(); + } else if (mForwardButton == v) { + mUiController.getCurrentTopWebView().goForward(); + } else if (mStar == v) { + mUiController.bookmarkCurrentPage(true); + } else if (mAllButton == v) { + mUiController.bookmarksOrHistoryPicker(false); + } else if (mSearchButton == v) { + mBaseUi.editUrl(true); + } else if (mStopButton == v) { + stopOrRefresh(); + } else if (mGoButton == v) { + if (!TextUtils.isEmpty(mUrlInput.getText())) { + onAction(mUrlInput.getText().toString(), null, + UrlInputView.TYPED); + } + } else if (mClearButton == v) { + clearOrClose(); + } else if (mVoiceSearch == v) { + mUiController.startVoiceSearch(); + } else { + super.onClick(v); + } + } + + private void clearOrClose() { + if (TextUtils.isEmpty(mUrlInput.getUserText())) { + // close + mUrlInput.clearFocus(); + } else { + // clear + mUrlInput.setText(""); + } + } + + void updateUrlIcon() { + mUrlIcon.setImageResource(mInVoiceMode ? + R.drawable.ic_search_holo_dark + : R.drawable.ic_web_holo_dark); + } + + @Override + protected void setFocusState(boolean focus) { + super.setFocusState(focus); + if (focus) { + mSearchButton.setVisibility(View.GONE); + mStar.setVisibility(View.GONE); + mClearButton.setVisibility(View.VISIBLE); + mUrlIcon.setImageResource(R.drawable.ic_search_holo_dark); + updateSearchMode(false); + } else { + mGoButton.setVisibility(View.GONE); + mVoiceSearch.setVisibility(View.GONE); + mStar.setVisibility(View.VISIBLE); + mClearButton.setVisibility(View.GONE); + if (mTitleBar.useQuickControls()) { + mSearchButton.setVisibility(View.GONE); + } else { + mSearchButton.setVisibility(View.VISIBLE); + } + updateUrlIcon(); + } + mUrlContainer.setBackgroundDrawable(focus + ? mFocusDrawable : mUnfocusDrawable); + } + + private void stopOrRefresh() { + if (mTitleBar.isInLoad()) { + mUiController.stopLoading(); + } else { + mUiController.getCurrentTopWebView().reload(); + } + } + + @Override + public void onProgressStarted() { + mStopButton.setImageDrawable(mStopDrawable); + } + + @Override + public void onProgressStopped() { + mStopButton.setImageDrawable(mReloadDrawable); + } + + protected void updateSearchMode(boolean userEdited) { + setSearchMode(!userEdited || TextUtils.isEmpty(mUrlInput.getUserText())); + } + + @Override + protected void setSearchMode(boolean voiceSearchEnabled) { + boolean showvoicebutton = voiceSearchEnabled && + mUiController.supportsVoiceSearch(); + mVoiceSearch.setVisibility(showvoicebutton ? View.VISIBLE : + View.GONE); + mGoButton.setVisibility(voiceSearchEnabled ? View.GONE : + View.VISIBLE); + } + + @Override + public void setInVoiceMode(boolean voicemode, List voiceResults) { + super.setInVoiceMode(voicemode, voiceResults); + if (voicemode) { + mUrlIcon.setImageDrawable(mSearchButton.getDrawable()); + } + } + +} diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java index d1db5786..8b0c1466 100644 --- a/src/com/android/browser/PhoneUi.java +++ b/src/com/android/browser/PhoneUi.java @@ -34,10 +34,10 @@ public class PhoneUi extends BaseUi { private static final String LOGTAG = "PhoneUi"; - private TitleBarPhone mTitleBar; private ActiveTabsPage mActiveTabsPage; private PieControlPhone mPieControl; private NavScreen mNavScreen; + private NavigationBarPhone mNavigationBar; boolean mExtendedMenuOpen; boolean mOptionsMenuOpen; @@ -49,13 +49,9 @@ public class PhoneUi extends BaseUi { */ public PhoneUi(Activity browser, UiController controller) { super(browser, controller); - mTitleBar = new TitleBarPhone(mActivity, mUiController, this, - mContentView); - // mTitleBar will be always be shown in the fully loaded mode on - // phone - mTitleBar.setProgress(100); mActivity.getActionBar().hide(); setUseQuickControls(BrowserSettings.getInstance().useQuickControls()); + mNavigationBar = (NavigationBarPhone) mTitleBar.getNavigationBar(); } @Override @@ -86,7 +82,7 @@ public class PhoneUi extends BaseUi { @Override public void editUrl(boolean clearInput) { if (mUseQuickControls) { - getTitleBar().setShowProgressOnly(false); + mTitleBar.setShowProgressOnly(false); } super.editUrl(clearInput); } @@ -178,11 +174,6 @@ public class PhoneUi extends BaseUi { tab.getTopWindow().requestFocus(); } - @Override - protected TitleBarBase getTitleBar() { - return mTitleBar; - } - /** * Suggest to the UI that the title bar can be hidden. The UI will then * decide whether or not to hide based off a number of factors, such @@ -190,8 +181,8 @@ public class PhoneUi extends BaseUi { */ @Override public void suggestHideTitleBar() { - if (!isLoading() && !isEditingUrl() && !mTitleBar.isMenuShowing()) { - hideTitleBar(); + if (!mNavigationBar.isMenuShowing()) { + super.suggestHideTitleBar(); } } @@ -266,9 +257,9 @@ public class PhoneUi extends BaseUi { protected void setTitleGravity(int gravity) { if (mUseQuickControls) { FrameLayout.LayoutParams lp = - (FrameLayout.LayoutParams) getTitleBar().getLayoutParams(); + (FrameLayout.LayoutParams) mTitleBar.getLayoutParams(); lp.gravity = gravity; - getTitleBar().setLayoutParams(lp); + mTitleBar.setLayoutParams(lp); } else { super.setTitleGravity(gravity); } @@ -277,7 +268,7 @@ public class PhoneUi extends BaseUi { @Override public void setUseQuickControls(boolean useQuickControls) { mUseQuickControls = useQuickControls; - getTitleBar().setUseQuickControls(mUseQuickControls); + mTitleBar.setUseQuickControls(mUseQuickControls); if (useQuickControls) { mPieControl = new PieControlPhone(mActivity, mUiController, this); mPieControl.attachToContainer(mContentView); diff --git a/src/com/android/browser/TitleBar.java b/src/com/android/browser/TitleBar.java new file mode 100644 index 00000000..4e931242 --- /dev/null +++ b/src/com/android/browser/TitleBar.java @@ -0,0 +1,341 @@ +/* + * 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.animation.Animator; +import android.animation.Animator.AnimatorListener; +import android.animation.ObjectAnimator; +import android.content.Context; +import android.content.res.Resources; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; +import android.view.animation.AnimationUtils; +import android.view.animation.DecelerateInterpolator; +import android.webkit.WebView; +import android.widget.AbsoluteLayout; +import android.widget.FrameLayout; +import android.widget.RelativeLayout; + + +/** + * Base class for a title bar used by the browser. + */ +public class TitleBar extends RelativeLayout { + + private static final int PROGRESS_MAX = 100; + private static final float ANIM_TITLEBAR_DECELERATE = 2.5f; + + private UiController mUiController; + private BaseUi mBaseUi; + private FrameLayout mParent; + private PageProgressView mProgress; + + private AutologinBar mAutoLogin; + private NavigationBarBase mNavBar; + private boolean mUseQuickControls; + + //state + private boolean mShowing; + private boolean mInLoad; + private boolean mSkipTitleBarAnimations; + private Animator mTitleBarAnimator; + + public TitleBar(Context context, UiController controller, BaseUi ui, + FrameLayout parent) { + super(context, null); + mUiController = controller; + mBaseUi = ui; + mParent = parent; + initLayout(context); + } + + private void initLayout(Context context) { + LayoutInflater factory = LayoutInflater.from(context); + factory.inflate(R.layout.title_bar, this); + mProgress = (PageProgressView) findViewById(R.id.progress); + mAutoLogin = (AutologinBar) findViewById(R.id.autologin); + mAutoLogin.setTitleBar(this); + mNavBar = (NavigationBarBase) findViewById(R.id.taburlbar); + mNavBar.setTitleBar(this); + } + + public BaseUi getUi() { + return mBaseUi; + } + + public UiController getUiController() { + return mUiController; + } + + public void setUseQuickControls(boolean use) { + mUseQuickControls = use; + setLayoutParams(makeLayoutParams()); + } + + void setShowProgressOnly(boolean progress) { + if (progress && !inAutoLogin()) { + mNavBar.setVisibility(View.GONE); + } else { + mNavBar.setVisibility(View.VISIBLE); + } + } + + void setSkipTitleBarAnimations(boolean skip) { + mSkipTitleBarAnimations = skip; + } + + void setupTitleBarAnimator(Animator animator) { + Resources res = mContext.getResources(); + int duration = res.getInteger(R.integer.titlebar_animation_duration); + animator.setInterpolator(new DecelerateInterpolator( + ANIM_TITLEBAR_DECELERATE)); + animator.setDuration(duration); + } + + void show() { + if (mUseQuickControls) { + mParent.addView(this); + } else { + if (!mSkipTitleBarAnimations) { + cancelTitleBarAnimation(false); + int visibleHeight = getVisibleTitleHeight(); + float startPos = (-getEmbeddedHeight() + visibleHeight); + if (getTranslationY() != 0) { + startPos = Math.max(startPos, getTranslationY()); + } + mTitleBarAnimator = ObjectAnimator.ofFloat(this, + "translationY", + startPos, 0); + setupTitleBarAnimator(mTitleBarAnimator); + mTitleBarAnimator.start(); + } + mBaseUi.setTitleGravity(Gravity.TOP); + } + mShowing = true; + } + + void hide() { + if (mUseQuickControls) { + mParent.removeView(this); + } else { + if (!mSkipTitleBarAnimations) { + cancelTitleBarAnimation(false); + int visibleHeight = getVisibleTitleHeight(); + mTitleBarAnimator = ObjectAnimator.ofFloat(this, + "translationY", getTranslationY(), + (-getEmbeddedHeight() + visibleHeight)); + mTitleBarAnimator.addListener(mHideTileBarAnimatorListener); + setupTitleBarAnimator(mTitleBarAnimator); + mTitleBarAnimator.start(); + } else { + mBaseUi.setTitleGravity(Gravity.NO_GRAVITY); + } + } + mShowing = false; + } + + boolean isShowing() { + return mShowing; + } + + void cancelTitleBarAnimation(boolean reset) { + if (mTitleBarAnimator != null) { + mTitleBarAnimator.cancel(); + mTitleBarAnimator = null; + } + if (reset) { + setTranslationY(0); + } + } + + private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() { + + boolean mWasCanceled; + @Override + public void onAnimationStart(Animator animation) { + mWasCanceled = false; + } + + @Override + public void onAnimationRepeat(Animator animation) { + } + + @Override + public void onAnimationEnd(Animator animation) { + if (!mWasCanceled) { + setTranslationY(0); + } + mBaseUi.setTitleGravity(Gravity.NO_GRAVITY); + } + + @Override + public void onAnimationCancel(Animator animation) { + mWasCanceled = true; + } + }; + + private int getVisibleTitleHeight() { + Tab tab = mBaseUi.getActiveTab(); + WebView webview = tab != null ? tab.getWebView() : null; + return webview != null ? webview.getVisibleTitleHeight() : 0; + } + + /** + * Update the progress, from 0 to 100. + */ + public void setProgress(int newProgress) { + if (newProgress >= PROGRESS_MAX) { + mProgress.setProgress(PageProgressView.MAX_PROGRESS); + mProgress.setVisibility(View.GONE); + mInLoad = false; + mNavBar.onProgressStopped(); + // check if needs to be hidden + if (!isEditingUrl() && !inAutoLogin()) { + hide(); + if (mUseQuickControls) { + setShowProgressOnly(false); + } + } + } else { + if (!mInLoad) { + mProgress.setVisibility(View.VISIBLE); + mInLoad = true; + mNavBar.onProgressStarted(); + } + mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS + / PROGRESS_MAX); + if (!mShowing) { + if (mUseQuickControls && !isEditingUrl()) { + setShowProgressOnly(true); + } + show(); + } + } + } + + public int getEmbeddedHeight() { + int height = mNavBar.getHeight(); + if (mAutoLogin.getVisibility() == View.VISIBLE) { + height += mAutoLogin.getHeight(); + } + return height; + } + + public void updateAutoLogin(Tab tab, boolean animate) { + mAutoLogin.updateAutoLogin(tab, animate); + } + + public void showAutoLogin(boolean animate) { + if (mUseQuickControls) { + mBaseUi.showTitleBar(); + } + mAutoLogin.setVisibility(View.VISIBLE); + if (animate) { + mAutoLogin.startAnimation(AnimationUtils.loadAnimation( + getContext(), R.anim.autologin_enter)); + } + } + + public void hideAutoLogin(boolean animate) { + if (mUseQuickControls) { + mBaseUi.hideTitleBar(); + mAutoLogin.setVisibility(View.GONE); + mBaseUi.refreshWebView(); + } else { + if (animate) { + Animation anim = AnimationUtils.loadAnimation(getContext(), + R.anim.autologin_exit); + anim.setAnimationListener(new AnimationListener() { + @Override + public void onAnimationEnd(Animation a) { + mAutoLogin.setVisibility(View.GONE); + mBaseUi.refreshWebView(); + } + + @Override + public void onAnimationStart(Animation a) { + } + + @Override + public void onAnimationRepeat(Animation a) { + } + }); + mAutoLogin.startAnimation(anim); + } else if (mAutoLogin.getAnimation() == null) { + mAutoLogin.setVisibility(View.GONE); + mBaseUi.refreshWebView(); + } + } + } + + public boolean inAutoLogin() { + return mAutoLogin.getVisibility() == View.VISIBLE; + } + + public boolean isEditingUrl() { + return mNavBar.isEditingUrl(); + } + + public WebView getCurrentWebView() { + Tab t = mBaseUi.getActiveTab(); + if (t != null) { + return t.getWebView(); + } else { + return null; + } + } + + public PageProgressView getProgressView() { + return mProgress; + } + + public NavigationBarBase getNavigationBar() { + return mNavBar; + } + + public boolean useQuickControls() { + return mUseQuickControls; + } + + public boolean isInLoad() { + return mInLoad; + } + + private ViewGroup.LayoutParams makeLayoutParams() { + if (mUseQuickControls) { + return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, + LayoutParams.WRAP_CONTENT); + } else { + return new AbsoluteLayout.LayoutParams( + LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, + 0, 0); + } + } + + @Override + public View focusSearch(View focused, int dir) { + if (FOCUS_DOWN == dir && hasFocus()) { + return getCurrentWebView(); + } + return super.focusSearch(focused, dir); + } + +} diff --git a/src/com/android/browser/TitleBarBase.java b/src/com/android/browser/TitleBarBase.java deleted file mode 100644 index 17b9e19c..00000000 --- a/src/com/android/browser/TitleBarBase.java +++ /dev/null @@ -1,664 +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.animation.Animator; -import android.animation.Animator.AnimatorListener; -import android.animation.ObjectAnimator; -import android.app.SearchManager; -import android.content.Context; -import android.content.Intent; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.os.Bundle; -import android.speech.RecognizerResultsIntent; -import android.text.TextUtils; -import android.view.ContextThemeWrapper; -import android.view.Gravity; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.Menu; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnFocusChangeListener; -import android.view.ViewGroup; -import android.view.animation.Animation; -import android.view.animation.Animation.AnimationListener; -import android.view.animation.AnimationUtils; -import android.view.animation.DecelerateInterpolator; -import android.webkit.WebView; -import android.widget.AbsoluteLayout; -import android.widget.ArrayAdapter; -import android.widget.Button; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.PopupMenu; -import android.widget.PopupMenu.OnMenuItemClickListener; -import android.widget.ProgressBar; -import android.widget.RelativeLayout; -import android.widget.Spinner; -import android.widget.TextView; - -import com.android.browser.UI.DropdownChangeListener; -import com.android.browser.UrlInputView.UrlInputListener; -import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher; - -import java.util.List; - -/** - * Base class for a title bar used by the browser. - */ -public class TitleBarBase extends RelativeLayout - implements OnClickListener, OnFocusChangeListener, UrlInputListener, - TextChangeWatcher, DeviceAccountLogin.AutoLoginCallback, - OnMenuItemClickListener { - - protected static final int PROGRESS_MAX = 100; - private static final float ANIM_TITLEBAR_DECELERATE = 2.5f; - - // These need to be set by the subclass. - protected ImageView mFavicon; - protected ImageView mLockIcon; - - protected UiController mUiController; - protected BaseUi mBaseUi; - protected FrameLayout mParent; - protected PageProgressView mProgress; - protected UrlInputView mUrlInput; - protected boolean mInVoiceMode; - protected View mContainer; - private View mUaSwitcher; - - // Auto-login UI - protected View mAutoLogin; - protected Spinner mAutoLoginAccount; - protected Button mAutoLoginLogin; - protected ProgressBar mAutoLoginProgress; - protected TextView mAutoLoginError; - protected View mAutoLoginCancel; - protected DeviceAccountLogin mAutoLoginHandler; - protected ArrayAdapter mAccountsAdapter; - protected boolean mUseQuickControls; - - //state - protected boolean mShowing; - protected boolean mInLoad; - protected boolean mSkipTitleBarAnimations; - private Animator mTitleBarAnimator; - - public TitleBarBase(Context context, UiController controller, BaseUi ui, - FrameLayout parent) { - super(context, null); - mUiController = controller; - mBaseUi = ui; - mParent = parent; - } - - protected void initLayout(Context context, int layoutId) { - LayoutInflater factory = LayoutInflater.from(context); - factory.inflate(layoutId, this); - mContainer = findViewById(R.id.taburlbar); - mProgress = (PageProgressView) findViewById(R.id.progress); - mUrlInput = (UrlInputView) findViewById(R.id.url); - mLockIcon = (ImageView) findViewById(R.id.lock); - mUrlInput.setUrlInputListener(this); - mUrlInput.setController(mUiController); - mUrlInput.setOnFocusChangeListener(this); - mUrlInput.setSelectAllOnFocus(true); - mUrlInput.addQueryTextWatcher(this); - mAutoLogin = findViewById(R.id.autologin); - mAutoLoginAccount = (Spinner) findViewById(R.id.autologin_account); - mAutoLoginLogin = (Button) findViewById(R.id.autologin_login); - mAutoLoginLogin.setOnClickListener(this); - mAutoLoginProgress = (ProgressBar) findViewById(R.id.autologin_progress); - mAutoLoginError = (TextView) findViewById(R.id.autologin_error); - mAutoLoginCancel = mAutoLogin.findViewById(R.id.autologin_close); - mAutoLoginCancel.setOnClickListener(this); - } - - protected void setupUrlInput() { - } - - protected void setUseQuickControls(boolean use) { - mUseQuickControls = use; - setLayoutParams(makeLayoutParams()); - } - - void setShowProgressOnly(boolean progress) { - if (progress && !inAutoLogin()) { - mContainer.setVisibility(View.GONE); - } else { - mContainer.setVisibility(View.VISIBLE); - } - } - - void setSkipTitleBarAnimations(boolean skip) { - mSkipTitleBarAnimations = skip; - } - - void setupTitleBarAnimator(Animator animator) { - Resources res = mContext.getResources(); - int duration = res.getInteger(R.integer.titlebar_animation_duration); - animator.setInterpolator(new DecelerateInterpolator( - ANIM_TITLEBAR_DECELERATE)); - animator.setDuration(duration); - } - - void show() { - if (mUseQuickControls) { - mParent.addView(this); - } else { - if (!mSkipTitleBarAnimations) { - cancelTitleBarAnimation(false); - int visibleHeight = getVisibleTitleHeight(); - float startPos = (-getEmbeddedHeight() + visibleHeight); - if (getTranslationY() != 0) { - startPos = Math.max(startPos, getTranslationY()); - } - mTitleBarAnimator = ObjectAnimator.ofFloat(this, - "translationY", - startPos, 0); - setupTitleBarAnimator(mTitleBarAnimator); - mTitleBarAnimator.start(); - } - mBaseUi.setTitleGravity(Gravity.TOP); - } - mShowing = true; - } - - void hide() { - if (mUseQuickControls) { - mParent.removeView(this); - } else { - if (!mSkipTitleBarAnimations) { - cancelTitleBarAnimation(false); - int visibleHeight = getVisibleTitleHeight(); - mTitleBarAnimator = ObjectAnimator.ofFloat(this, - "translationY", getTranslationY(), - (-getEmbeddedHeight() + visibleHeight)); - mTitleBarAnimator.addListener(mHideTileBarAnimatorListener); - setupTitleBarAnimator(mTitleBarAnimator); - mTitleBarAnimator.start(); - } else { - mBaseUi.setTitleGravity(Gravity.NO_GRAVITY); - } - } - mShowing = false; - } - - boolean isShowing() { - return mShowing; - } - - void cancelTitleBarAnimation(boolean reset) { - if (mTitleBarAnimator != null) { - mTitleBarAnimator.cancel(); - mTitleBarAnimator = null; - } - if (reset) { - setTranslationY(0); - } - } - - private AnimatorListener mHideTileBarAnimatorListener = new AnimatorListener() { - - boolean mWasCanceled; - @Override - public void onAnimationStart(Animator animation) { - mWasCanceled = false; - } - - @Override - public void onAnimationRepeat(Animator animation) { - } - - @Override - public void onAnimationEnd(Animator animation) { - if (!mWasCanceled) { - setTranslationY(0); - } - mBaseUi.setTitleGravity(Gravity.NO_GRAVITY); - } - - @Override - public void onAnimationCancel(Animator animation) { - mWasCanceled = true; - } - }; - - private int getVisibleTitleHeight() { - Tab tab = mBaseUi.getActiveTab(); - WebView webview = tab != null ? tab.getWebView() : null; - return webview != null ? webview.getVisibleTitleHeight() : 0; - } - - /** - * Update the progress, from 0 to 100. - */ - void setProgress(int newProgress) { - if (newProgress >= PROGRESS_MAX) { - mProgress.setProgress(PageProgressView.MAX_PROGRESS); - mProgress.setVisibility(View.GONE); - mInLoad = false; - onProgressStopped(); - // check if needs to be hidden - if (!isEditingUrl() && !inAutoLogin()) { - hide(); - if (mUseQuickControls) { - setShowProgressOnly(false); - } - } - } else { - if (!mInLoad) { - mProgress.setVisibility(View.VISIBLE); - mInLoad = true; - onProgressStarted(); - } - mProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS - / PROGRESS_MAX); - if (!mShowing) { - if (mUseQuickControls && !isEditingUrl()) { - setShowProgressOnly(true); - } - show(); - } - } - } - - protected void onProgressStarted() { - } - - protected void onProgressStopped() { - } - - /* package */ void setLock(Drawable d) { - assert mLockIcon != null; - if (null == d) { - mLockIcon.setVisibility(View.GONE); - } else { - mLockIcon.setImageDrawable(d); - mLockIcon.setVisibility(View.VISIBLE); - } - } - - /* package */ void setFavicon(Bitmap icon) { - mFavicon.setImageDrawable(mBaseUi.getFaviconDrawable(icon)); - } - - public int getEmbeddedHeight() { - int height = mContainer.getHeight(); - if (mAutoLogin.getVisibility() == View.VISIBLE) { - height += mAutoLogin.getHeight(); - } - return height; - } - - protected void updateAutoLogin(Tab tab, boolean animate) { - DeviceAccountLogin login = tab.getDeviceAccountLogin(); - if (login != null) { - mAutoLoginHandler = login; - ContextThemeWrapper wrapper = new ContextThemeWrapper(mContext, - android.R.style.Theme_Holo_Light); - mAccountsAdapter = new ArrayAdapter(wrapper, - android.R.layout.simple_spinner_item, login.getAccountNames()); - mAccountsAdapter.setDropDownViewResource( - android.R.layout.simple_spinner_dropdown_item); - mAutoLoginAccount.setAdapter(mAccountsAdapter); - mAutoLoginAccount.setSelection(0); - mAutoLoginAccount.setEnabled(true); - mAutoLoginLogin.setEnabled(true); - mAutoLoginProgress.setVisibility(View.INVISIBLE); - mAutoLoginError.setVisibility(View.GONE); - switch (login.getState()) { - case DeviceAccountLogin.PROCESSING: - mAutoLoginAccount.setEnabled(false); - mAutoLoginLogin.setEnabled(false); - mAutoLoginProgress.setVisibility(View.VISIBLE); - break; - case DeviceAccountLogin.FAILED: - mAutoLoginProgress.setVisibility(View.INVISIBLE); - mAutoLoginError.setVisibility(View.VISIBLE); - break; - case DeviceAccountLogin.INITIAL: - break; - default: - throw new IllegalStateException(); - } - showAutoLogin(animate); - } else { - hideAutoLogin(animate); - } - } - - protected void showAutoLogin(boolean animate) { - if (mUseQuickControls) { - mBaseUi.showTitleBar(); - } - mAutoLogin.setVisibility(View.VISIBLE); - if (animate) { - mAutoLogin.startAnimation(AnimationUtils.loadAnimation( - getContext(), R.anim.autologin_enter)); - } - } - - protected void hideAutoLogin(boolean animate) { - mAutoLoginHandler = null; - if (mUseQuickControls) { - mBaseUi.hideTitleBar(); - mAutoLogin.setVisibility(View.GONE); - mBaseUi.refreshWebView(); - } else { - if (animate) { - Animation anim = AnimationUtils.loadAnimation(getContext(), - R.anim.autologin_exit); - anim.setAnimationListener(new AnimationListener() { - @Override - public void onAnimationEnd(Animation a) { - mAutoLogin.setVisibility(View.GONE); - mBaseUi.refreshWebView(); - } - - @Override - public void onAnimationStart(Animation a) { - } - - @Override - public void onAnimationRepeat(Animation a) { - } - }); - mAutoLogin.startAnimation(anim); - } else if (mAutoLogin.getAnimation() == null) { - mAutoLogin.setVisibility(View.GONE); - mBaseUi.refreshWebView(); - } - } - } - - @Override - public void loginFailed() { - mAutoLoginAccount.setEnabled(true); - mAutoLoginLogin.setEnabled(true); - mAutoLoginProgress.setVisibility(View.INVISIBLE); - mAutoLoginError.setVisibility(View.VISIBLE); - } - - - protected boolean inAutoLogin() { - return mAutoLoginHandler != null; - } - - public void setUaSwitcher(View v) { - if (mUaSwitcher != null) { - mUaSwitcher.setOnClickListener(null); - } - mUaSwitcher = v; - mUaSwitcher.setOnClickListener(this); - } - - @Override - public void onClick(View v) { - if (mAutoLoginCancel == v) { - if (mAutoLoginHandler != null) { - mAutoLoginHandler.cancel(); - mAutoLoginHandler = null; - } - hideAutoLogin(true); - } else if (mAutoLoginLogin == v) { - if (mAutoLoginHandler != null) { - mAutoLoginAccount.setEnabled(false); - mAutoLoginLogin.setEnabled(false); - mAutoLoginProgress.setVisibility(View.VISIBLE); - mAutoLoginError.setVisibility(View.GONE); - mAutoLoginHandler.login( - mAutoLoginAccount.getSelectedItemPosition(), this); - } - } else if (mUaSwitcher == v) { - BrowserSettings settings = BrowserSettings.getInstance(); - WebView web = getCurrentWebView(); - if (web == null) return; - boolean desktop = settings.hasDesktopUseragent(web); - PopupMenu popup = new PopupMenu(mContext, mUaSwitcher); - Menu menu = popup.getMenu(); - popup.getMenuInflater().inflate(R.menu.ua_switcher, menu); - menu.findItem(R.id.ua_mobile_menu_id).setChecked(!desktop); - menu.findItem(R.id.ua_desktop_menu_id).setChecked(desktop); - popup.setOnMenuItemClickListener(this); - popup.show(); - } - } - - @Override - public boolean onMenuItemClick(MenuItem item) { - BrowserSettings settings = BrowserSettings.getInstance(); - WebView web = getCurrentWebView(); - if (web == null) return false; - boolean desktop = settings.hasDesktopUseragent(web); - switch (item.getItemId()) { - case R.id.ua_mobile_menu_id: - if (desktop) { - settings.toggleDesktopUseragent(web); - web.loadUrl(web.getOriginalUrl()); - } - return true; - case R.id.ua_desktop_menu_id: - if (!desktop) { - settings.toggleDesktopUseragent(web); - web.loadUrl(web.getOriginalUrl()); - } - return true; - } - return false; - } - - @Override - public void onFocusChange(View view, boolean hasFocus) { - // if losing focus and not in touch mode, leave as is - if (hasFocus || view.isInTouchMode() || mUrlInput.needsUpdate()) { - setFocusState(hasFocus); - } - if (hasFocus) { - mBaseUi.showTitleBar(); - mUrlInput.forceIme(); - if (mInVoiceMode) { - mUrlInput.forceFilter(); - } - } else if (!mUrlInput.needsUpdate()) { - mUrlInput.dismissDropDown(); - mUrlInput.hideIME(); - if (mUrlInput.getText().length() == 0) { - Tab currentTab = mUiController.getTabControl().getCurrentTab(); - if (currentTab != null) { - mUrlInput.setText(currentTab.getUrl(), false); - } - } - mBaseUi.suggestHideTitleBar(); - } - mUrlInput.clearNeedsUpdate(); - } - - protected void setFocusState(boolean focus) { - } - - protected void setSearchMode(boolean voiceSearchEnabled) {} - - boolean isEditingUrl() { - return mUrlInput.hasFocus(); - } - - void stopEditingUrl() { - mUrlInput.clearFocus(); - } - - void setDisplayTitle(String title) { - if (!isEditingUrl()) { - mUrlInput.setText(title, false); - } - } - - // UrlInput text watcher - - @Override - public void onTextChanged(String newText) { - if (mUrlInput.hasFocus()) { - // clear voice mode when user types - setInVoiceMode(false, null); - } - } - - // voicesearch - - public void setInVoiceMode(boolean voicemode, List voiceResults) { - mInVoiceMode = voicemode; - mUrlInput.setVoiceResults(voiceResults); - } - - void setIncognitoMode(boolean incognito) { - mUrlInput.setIncognitoMode(incognito); - } - - void clearCompletions() { - mUrlInput.setSuggestedText(null); - } - - // UrlInputListener implementation - - /** - * callback from suggestion dropdown - * user selected a suggestion - */ - @Override - public void onAction(String text, String extra, String source) { - mUiController.getCurrentTopWebView().requestFocus(); - if (UrlInputView.TYPED.equals(source)) { - String url = UrlUtils.smartUrlFilter(text, false); - Tab t = mBaseUi.getActiveTab(); - // Only shortcut javascript URIs for now, as there is special - // logic in UrlHandler for other schemas - if (url != null && t != null && url.startsWith("javascript:")) { - mUiController.loadUrl(t, url); - setDisplayTitle(text); - return; - } - } - Intent i = new Intent(); - String action = null; - if (UrlInputView.VOICE.equals(source)) { - action = RecognizerResultsIntent.ACTION_VOICE_SEARCH_RESULTS; - source = null; - } else { - action = Intent.ACTION_SEARCH; - } - i.setAction(action); - i.putExtra(SearchManager.QUERY, text); - if (extra != null) { - i.putExtra(SearchManager.EXTRA_DATA_KEY, extra); - } - if (source != null) { - Bundle appData = new Bundle(); - appData.putString(com.android.common.Search.SOURCE, source); - i.putExtra(SearchManager.APP_DATA, appData); - } - mUiController.handleNewIntent(i); - setDisplayTitle(text); - } - - @Override - public void onDismiss() { - final Tab currentTab = mBaseUi.getActiveTab(); - mBaseUi.hideTitleBar(); - post(new Runnable() { - public void run() { - clearFocus(); - if ((currentTab != null) && !mInVoiceMode) { - setDisplayTitle(currentTab.getUrl()); - } - } - }); - } - - /** - * callback from the suggestion dropdown - * copy text to input field and stay in edit mode - */ - @Override - public void onCopySuggestion(String text) { - mUrlInput.setText(text, true); - if (text != null) { - mUrlInput.setSelection(text.length()); - } - } - - public void setCurrentUrlIsBookmark(boolean isBookmark) { - } - - @Override - public boolean dispatchKeyEventPreIme(KeyEvent evt) { - if (evt.getKeyCode() == KeyEvent.KEYCODE_BACK) { - // catch back key in order to do slightly more cleanup than usual - mUrlInput.clearFocus(); - return true; - } - return super.dispatchKeyEventPreIme(evt); - } - - protected WebView getCurrentWebView() { - Tab t = mBaseUi.getActiveTab(); - if (t != null) { - return t.getWebView(); - } else { - return null; - } - } - - void registerDropdownChangeListener(DropdownChangeListener d) { - mUrlInput.registerDropdownChangeListener(d); - } - - /** - * called from the Ui when the user wants to edit - * @param clearInput clear the input field - */ - void startEditingUrl(boolean clearInput) { - // editing takes preference of progress - mContainer.setVisibility(View.VISIBLE); - if (mUseQuickControls) { - mProgress.setVisibility(View.GONE); - } - if (!mUrlInput.hasFocus()) { - mUrlInput.requestFocus(); - } - if (clearInput) { - mUrlInput.setText(""); - } else if (mInVoiceMode) { - mUrlInput.showDropDown(); - } - } - - private ViewGroup.LayoutParams makeLayoutParams() { - if (mUseQuickControls) { - return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT, - LayoutParams.WRAP_CONTENT); - } else { - return new AbsoluteLayout.LayoutParams( - LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT, - 0, 0); - } - } - -} diff --git a/src/com/android/browser/TitleBarPhone.java b/src/com/android/browser/TitleBarPhone.java deleted file mode 100644 index 66b46484..00000000 --- a/src/com/android/browser/TitleBarPhone.java +++ /dev/null @@ -1,250 +0,0 @@ -/* - * Copyright (C) 2009 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.content.res.Resources; -import android.graphics.drawable.Drawable; -import android.view.ContextMenu; -import android.view.Menu; -import android.view.MenuInflater; -import android.view.MenuItem; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnFocusChangeListener; -import android.view.ViewConfiguration; -import android.webkit.WebView; -import android.widget.FrameLayout; -import android.widget.ImageView; -import android.widget.PopupMenu; -import android.widget.PopupMenu.OnDismissListener; - -import com.android.browser.UrlInputView.StateListener; -import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher; - -import java.util.List; - -/** - * This class represents a title bar for a particular "tab" or "window" in the - * browser. - */ -public class TitleBarPhone extends TitleBarBase implements OnFocusChangeListener, - OnClickListener, TextChangeWatcher, StateListener, OnDismissListener { - - private Activity mActivity; - private ImageView mStopButton; - private ImageView mVoiceButton; - private Drawable mStopDrawable; - private Drawable mRefreshDrawable; - private View mTabSwitcher; - private View mComboIcon; - private View mTitleContainer; - private View mMore; - private Drawable mTextfieldBgDrawable; - private boolean mMenuShowing; - private boolean mNeedsMenu; - - public TitleBarPhone(Activity activity, UiController controller, PhoneUi ui, - FrameLayout parent) { - super(activity, controller, ui, parent); - mNeedsMenu = !ViewConfiguration.get(activity).hasPermanentMenuKey(); - mActivity = activity; - initLayout(activity, R.layout.title_bar); - } - - @Override - protected void initLayout(Context context, int layoutId) { - super.initLayout(context, layoutId); - mLockIcon = (ImageView) findViewById(R.id.lock); - mFavicon = (ImageView) findViewById(R.id.favicon); - mStopButton = (ImageView) findViewById(R.id.stop); - mStopButton.setOnClickListener(this); - mVoiceButton = (ImageView) findViewById(R.id.voice); - mVoiceButton.setOnClickListener(this); - mTabSwitcher = findViewById(R.id.tab_switcher); - mTabSwitcher.setOnClickListener(this); - mMore = findViewById(R.id.more); - mMore.setOnClickListener(this); - mComboIcon = findViewById(R.id.iconcombo); - mTitleContainer = findViewById(R.id.title_bg); - setFocusState(false); - Resources res = context.getResources(); - mStopDrawable = res.getDrawable(R.drawable.ic_stop_holo_dark); - mRefreshDrawable = res.getDrawable(R.drawable.ic_refresh_holo_dark); - mTextfieldBgDrawable = res.getDrawable(R.drawable.textfield_active_holo_dark); - setUaSwitcher(mComboIcon); - mUrlInput.setContainer(this); - mUrlInput.setStateListener(this); - } - - @Override - public void createContextMenu(ContextMenu menu) { - MenuInflater inflater = mActivity.getMenuInflater(); - inflater.inflate(R.menu.title_context, menu); - mActivity.onCreateContextMenu(menu, this, null); - } - - @Override - public void setInVoiceMode(boolean voicemode, List voiceResults) { - super.setInVoiceMode(voicemode, voiceResults); - } - - @Override - protected void setSearchMode(boolean voiceSearchEnabled) { - boolean showvoicebutton = voiceSearchEnabled && - mUiController.supportsVoiceSearch(); - mVoiceButton.setVisibility(showvoicebutton ? View.VISIBLE : - View.GONE); - } - - @Override - void setProgress(int progress) { - super.setProgress(progress); - if (progress == 100) { - mStopButton.setVisibility(View.GONE); - mStopButton.setImageDrawable(mRefreshDrawable); - if (!isEditingUrl()) { - mComboIcon.setVisibility(View.VISIBLE); - } - } else { - if (mStopButton.getDrawable() != mStopDrawable) { - mStopButton.setImageDrawable(mStopDrawable); - if (mStopButton.getVisibility() != View.VISIBLE) { - mComboIcon.setVisibility(View.GONE); - mStopButton.setVisibility(View.VISIBLE); - } - } - } - } - - /** - * Update the text displayed in the title bar. - * @param title String to display. If null, the new tab string will be - * shown. - */ - @Override - void setDisplayTitle(String title) { - if (!isEditingUrl()) { - if (title == null) { - mUrlInput.setText(R.string.new_tab); - } else { - mUrlInput.setText(title); - } - mUrlInput.setSelection(0); - } - } - - @Override - public void onFocusChange(View v, boolean hasFocus) { - if (v == mUrlInput) { - if (hasFocus) { - mActivity.closeOptionsMenu(); - } - } - super.onFocusChange(v, hasFocus); - } - - @Override - public void onClick(View v) { - if (v == mStopButton) { - if (mInLoad) { - mUiController.stopLoading(); - } else { - WebView web = mBaseUi.getWebView(); - if (web != null) { - stopEditingUrl(); - web.reload(); - } - } - } else if (v == mVoiceButton) { - mUiController.startVoiceSearch(); - } else if (v == mTabSwitcher) { - mBaseUi.onMenuKey(); - } else if (mMore == v) { - showMenu(); - } else { - super.onClick(v); - } - } - - public boolean isMenuShowing() { - return mMenuShowing; - } - - private void showMenu() { - mMenuShowing = true; - PopupMenu popup = new PopupMenu(mContext, mMore); - Menu menu = popup.getMenu(); - popup.getMenuInflater().inflate(R.menu.browser, menu); - menu.setGroupVisible(R.id.NAV_MENU, false); - popup.setOnMenuItemClickListener(this); - popup.setOnDismissListener(this); - popup.show(); - } - - @Override - public void onDismiss(PopupMenu menu) { - onMenuHidden(); - } - - @Override - public boolean onMenuItemClick(MenuItem item) { - onMenuHidden(); - boolean res = mUiController.onOptionsItemSelected(item); - if (!res) { - return super.onMenuItemClick(item); - } - return res; - } - - private void onMenuHidden() { - mMenuShowing = false; - mBaseUi.showTitleBarForDuration(); - } - - @Override - public void onStateChanged(int state) { - switch(state) { - case StateListener.STATE_NORMAL: - mComboIcon.setVisibility(View.VISIBLE); - mStopButton.setVisibility(View.GONE); - setSearchMode(false); - mTabSwitcher.setVisibility(View.VISIBLE); - mTitleContainer.setBackgroundDrawable(null); - mMore.setVisibility(mNeedsMenu ? View.VISIBLE : View.GONE); - break; - case StateListener.STATE_HIGHLIGHTED: - mComboIcon.setVisibility(View.GONE); - mStopButton.setVisibility(View.VISIBLE); - setSearchMode(true); - mTabSwitcher.setVisibility(View.GONE); - mMore.setVisibility(View.GONE); - mTitleContainer.setBackgroundDrawable(mTextfieldBgDrawable); - break; - case StateListener.STATE_EDITED: - mComboIcon.setVisibility(View.GONE); - mStopButton.setVisibility(View.GONE); - setSearchMode(false); - mTabSwitcher.setVisibility(View.GONE); - mMore.setVisibility(View.GONE); - mTitleContainer.setBackgroundDrawable(mTextfieldBgDrawable); - break; - } - } - -} diff --git a/src/com/android/browser/TitleBarXLarge.java b/src/com/android/browser/TitleBarXLarge.java deleted file mode 100644 index 6aed86c4..00000000 --- a/src/com/android/browser/TitleBarXLarge.java +++ /dev/null @@ -1,251 +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 com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher; - -import android.app.Activity; -import android.content.Context; -import android.content.SharedPreferences; -import android.content.SharedPreferences.OnSharedPreferenceChangeListener; -import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.drawable.Drawable; -import android.preference.PreferenceManager; -import android.text.TextUtils; -import android.view.View; -import android.view.View.OnClickListener; -import android.view.View.OnFocusChangeListener; -import android.webkit.WebView; -import android.widget.FrameLayout; -import android.widget.ImageButton; -import android.widget.ImageView; - -import java.util.List; - -/** - * tabbed title bar for xlarge screen browser - */ -public class TitleBarXLarge extends TitleBarBase - implements OnClickListener, OnFocusChangeListener, TextChangeWatcher, - DeviceAccountLogin.AutoLoginCallback { - - private XLargeUi mUi; - - private Drawable mStopDrawable; - private Drawable mReloadDrawable; - - private View mUrlContainer; - private ImageButton mBackButton; - private ImageButton mForwardButton; - private ImageView mStar; - private ImageView mUrlIcon; - private ImageView mSearchButton; - private View mGoButton; - private ImageView mStopButton; - private View mAllButton; - private View mClearButton; - private ImageView mVoiceSearch; - private Drawable mFocusDrawable; - private Drawable mUnfocusDrawable; - - public TitleBarXLarge(Activity activity, UiController controller, - XLargeUi ui, FrameLayout parent) { - super(activity, controller, ui, parent); - mUi = ui; - Resources resources = activity.getResources(); - mStopDrawable = resources.getDrawable(R.drawable.ic_stop_holo_dark); - mReloadDrawable = resources.getDrawable(R.drawable.ic_refresh_holo_dark); - mFocusDrawable = resources.getDrawable( - R.drawable.textfield_active_holo_dark); - mUnfocusDrawable = resources.getDrawable( - R.drawable.textfield_default_holo_dark); - mInVoiceMode = false; - initLayout(activity, R.layout.url_bar); - } - - @Override - protected void initLayout(Context context, int layoutId) { - super.initLayout(context, layoutId); - 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 = (ImageButton) findViewById(R.id.back); - mForwardButton = (ImageButton) findViewById(R.id.forward); - mUrlIcon = (ImageView) findViewById(R.id.url_icon); - mStar = (ImageView) findViewById(R.id.star); - mStopButton = (ImageView) findViewById(R.id.stop); - mSearchButton = (ImageView) findViewById(R.id.search); - mLockIcon = (ImageView) findViewById(R.id.lock); - mGoButton = findViewById(R.id.go); - mClearButton = findViewById(R.id.clear); - mVoiceSearch = (ImageView) findViewById(R.id.voicesearch); - mUrlContainer = findViewById(R.id.urlbar_focused); - mBackButton.setOnClickListener(this); - mForwardButton.setOnClickListener(this); - mStar.setOnClickListener(this); - mAllButton.setOnClickListener(this); - mStopButton.setOnClickListener(this); - mSearchButton.setOnClickListener(this); - mGoButton.setOnClickListener(this); - mClearButton.setOnClickListener(this); - mVoiceSearch.setOnClickListener(this); - setUaSwitcher(mUrlIcon); - mUrlInput.setContainer(mUrlContainer); - setFocusState(false); - } - - void updateNavigationState(Tab tab) { - WebView web = tab.getWebView(); - if (web != null) { - mBackButton.setImageResource(web.canGoBack() - ? R.drawable.ic_back_holo_dark - : R.drawable.ic_back_disabled_holo_dark); - mForwardButton.setImageResource(web.canGoForward() - ? R.drawable.ic_forward_holo_dark - : R.drawable.ic_forward_disabled_holo_dark); - } - updateUrlIcon(); - } - - @Override - public void setCurrentUrlIsBookmark(boolean isBookmark) { - mStar.setActivated(isBookmark); - } - - - @Override - public void onClick(View v) { - if (mBackButton == v) { - mUiController.getCurrentTopWebView().goBack(); - } else if (mForwardButton == v) { - mUiController.getCurrentTopWebView().goForward(); - } else if (mStar == v) { - mUiController.bookmarkCurrentPage(true); - } else if (mAllButton == v) { - mUiController.bookmarksOrHistoryPicker(false); - } else if (mSearchButton == v) { - mUi.editUrl(true); - } else if (mStopButton == v) { - stopOrRefresh(); - } else if (mGoButton == v) { - if (!TextUtils.isEmpty(mUrlInput.getText())) { - onAction(mUrlInput.getText().toString(), null, - UrlInputView.TYPED); - } - } else if (mClearButton == v) { - clearOrClose(); - } else if (mVoiceSearch == v) { - mUiController.startVoiceSearch(); - } else { - super.onClick(v); - } - } - - @Override - void setFavicon(Bitmap icon) { } - - private void clearOrClose() { - if (TextUtils.isEmpty(mUrlInput.getUserText())) { - // close - mUrlInput.clearFocus(); - } else { - // clear - mUrlInput.setText(""); - } - } - - void updateUrlIcon() { - mUrlIcon.setImageResource(mInVoiceMode ? - R.drawable.ic_search_holo_dark - : R.drawable.ic_web_holo_dark); - } - - @Override - protected void setFocusState(boolean focus) { - super.setFocusState(focus); - if (focus) { - mSearchButton.setVisibility(View.GONE); - mStar.setVisibility(View.GONE); - mClearButton.setVisibility(View.VISIBLE); - mUrlIcon.setImageResource(R.drawable.ic_search_holo_dark); - updateSearchMode(false); - } else { - mGoButton.setVisibility(View.GONE); - mVoiceSearch.setVisibility(View.GONE); - mStar.setVisibility(View.VISIBLE); - mClearButton.setVisibility(View.GONE); - if (mUseQuickControls) { - mSearchButton.setVisibility(View.GONE); - } else { - mSearchButton.setVisibility(View.VISIBLE); - } - updateUrlIcon(); - } - mUrlContainer.setBackgroundDrawable(focus - ? mFocusDrawable : mUnfocusDrawable); - } - - private void stopOrRefresh() { - if (mInLoad) { - mUiController.stopLoading(); - } else { - mUiController.getCurrentTopWebView().reload(); - } - } - - @Override - protected void onProgressStarted() { - mStopButton.setImageDrawable(mStopDrawable); - } - - @Override - protected void onProgressStopped() { - mStopButton.setImageDrawable(mReloadDrawable); - } - - protected void updateSearchMode(boolean userEdited) { - setSearchMode(!userEdited || TextUtils.isEmpty(mUrlInput.getUserText())); - } - - @Override - protected void setSearchMode(boolean voiceSearchEnabled) { - boolean showvoicebutton = voiceSearchEnabled && - mUiController.supportsVoiceSearch(); - mVoiceSearch.setVisibility(showvoicebutton ? View.VISIBLE : - View.GONE); - mGoButton.setVisibility(voiceSearchEnabled ? View.GONE : - View.VISIBLE); - } - - @Override - public void setInVoiceMode(boolean voicemode, List voiceResults) { - super.setInVoiceMode(voicemode, voiceResults); - if (voicemode) { - mUrlIcon.setImageDrawable(mSearchButton.getDrawable()); - } - } - - @Override - public View focusSearch(View focused, int dir) { - if (FOCUS_DOWN == dir && hasFocus()) { - return getCurrentWebView(); - } - return super.focusSearch(focused, dir); - } - -} diff --git a/src/com/android/browser/XLargeUi.java b/src/com/android/browser/XLargeUi.java index 290bbf75..a8683314 100644 --- a/src/com/android/browser/XLargeUi.java +++ b/src/com/android/browser/XLargeUi.java @@ -40,7 +40,7 @@ public class XLargeUi extends BaseUi { private ActionBar mActionBar; private TabBar mTabBar; - private TitleBarXLarge mTitleBar; + private NavigationBarTablet mNavBar; private PieControlXLarge mPieControl; private Handler mHandler; @@ -52,9 +52,7 @@ public class XLargeUi extends BaseUi { public XLargeUi(Activity browser, UiController controller) { super(browser, controller); mHandler = new Handler(); - mTitleBar = new TitleBarXLarge(mActivity, mUiController, this, - mContentView); - mTitleBar.setProgress(100); + mNavBar = (NavigationBarTablet) mTitleBar.getNavigationBar(); mTabBar = new TabBar(mActivity, mUiController, this); mActionBar = mActivity.getActionBar(); setupActionBar(); @@ -129,7 +127,7 @@ public class XLargeUi extends BaseUi { public void onResume() { super.onResume(); if (!BrowserSettings.getInstance().useInstantSearch()) { - mTitleBar.clearCompletions(); + mNavBar.clearCompletions(); } } @@ -187,7 +185,7 @@ public class XLargeUi extends BaseUi { mPieControl.forceToTop(mContentView); } else { // check if title bar is already attached by animation - if (mTitleBar.getParent() == null && !tab.isSnapshot()) { + if (mTitleBar.getParent() == null) { view.setEmbeddedTitleBar(mTitleBar); } } @@ -231,13 +229,13 @@ public class XLargeUi extends BaseUi { @Override public void editUrl(boolean clearInput) { if (mUseQuickControls) { - getTitleBar().setShowProgressOnly(false); + mTitleBar.setShowProgressOnly(false); } super.editUrl(clearInput); } void stopEditingUrl() { - mTitleBar.stopEditingUrl(); + mTitleBar.getNavigationBar().stopEditingUrl(); } @Override @@ -254,11 +252,6 @@ public class XLargeUi extends BaseUi { } } - @Override - protected TitleBarBase getTitleBar() { - return mTitleBar; - } - @Override protected void setTitleGravity(int gravity) { if (!mUseQuickControls) { @@ -291,7 +284,7 @@ public class XLargeUi extends BaseUi { @Override protected void updateNavigationState(Tab tab) { - mTitleBar.updateNavigationState(tab); + mNavBar.updateNavigationState(tab); } @Override @@ -307,19 +300,6 @@ public class XLargeUi extends BaseUi { mTabBar.onFavicon(tab, tab.getFavicon()); } - @Override - public void showVoiceTitleBar(String title, List vsresults) { - mTitleBar.setInVoiceMode(true, vsresults); - mTitleBar.setDisplayTitle(title); - } - - @Override - public void revertVoiceTitleBar(Tab tab) { - mTitleBar.setInVoiceMode(false, null); - String url = tab.getUrl(); - mTitleBar.setDisplayTitle(url); - } - @Override public void showCustomView(View view, int requestedOrientation, CustomViewCallback callback) { -- cgit v1.2.3