Commit 11d1978d authored by Michael Kolb's avatar Michael Kolb
Browse files

fix title bar

    Merge code from TitleBarXLarge down into base
    to support omnibox in both tablet and phone
    browser

Change-Id: If54f3b162725411236f0b0676887bbcbdabadd25
parent 71791a09
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2009, The Android Open Source Project
Copyright 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.
......@@ -14,12 +14,11 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/titlebar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/taburlbar"
android:layout_width="match_parent"
......@@ -29,71 +28,111 @@
android:paddingLeft="4dip"
android:paddingRight="4dip"
android:paddingTop="2dip"
android:paddingBottom="1dip"
>
<LinearLayout android:id="@+id/title_bg"
android:paddingBottom="2dip">
<LinearLayout
android:id="@+id/title_bg"
android:layout_width="0dip"
android:layout_weight="1.0"
android:layout_height="48dip"
android:layout_marginBottom="4dip"
android:layout_height="40dip"
android:gravity="center_vertical"
android:orientation="horizontal"
android:background="@drawable/url_background"
>
<ImageView android:id="@+id/favicon"
android:layout_width="20dip"
android:layout_height="20dip"
/>
<ImageView android:id="@+id/lock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="3dip"
android:visibility="gone"
/>
<com.android.browser.UrlInputView
android:id="@+id/url_input"
android:focusable="true"
android:layout_width="0dip"
android:layout_weight="1.0"
android:layout_height="match_parent"
android:layout_marginLeft="3dip"
android:paddingLeft="0dip"
android:paddingRight="0dip"
android:background="@null"
android:textAppearance="?android:attr/textAppearanceMedium"
android:hint="@string/search_hint"
android:singleLine="true"
android:ellipsize="end"
android:lines="1"
android:scrollHorizontally="true"
android:inputType="textUri"
android:imeOptions="actionGo"
style="@style/Suggestions" />
android:orientation="horizontal">
<ImageView
android:id="@+id/favicon"
android:layout_width="20dip"
android:layout_height="20dip" />
<ImageView
android:id="@+id/lock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="2dip"
android:visibility="gone" />
<com.android.browser.UrlInputView
android:id="@+id/url"
android:focusable="true"
android:layout_width="0dip"
android:layout_weight="1.0"
android:layout_height="match_parent"
android:layout_marginLeft="2dip"
android:paddingLeft="0dip"
android:paddingRight="0dip"
android:background="@null"
android:textAppearance="?android:attr/textAppearanceMedium"
android:hint="@string/search_hint"
android:singleLine="true"
android:ellipsize="end"
android:lines="1"
android:scrollHorizontally="true"
android:inputType="textUri"
android:imeOptions="actionGo"
style="@style/Suggestions" />
</LinearLayout>
<ImageButton
<ImageView
android:id="@+id/voice"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:src="@drawable/ic_voice_search_holo_dark"
android:visibility="gone" />
<com.android.browser.view.StopProgressView
style="?android:attr/progressBarStyleLarge"
android:id="@+id/stop"
android:layout_width="36dip"
android:layout_height="36dip"
android:layout_gravity="center_vertical"
android:visibility="gone" />
</LinearLayout>
<LinearLayout
android:id="@+id/autologin"
android:background="#FBF0A0"
android:gravity="center_vertical"
android:paddingTop="3dip"
android:visibility="gone"
android:layout_below="@+id/taburlbar"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:text="@string/autologin_bar_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/primary_text_light"
android:paddingLeft="15dip"
android:paddingRight="15dip"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Spinner
android:id="@+id/autologin_account"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
style="@android:style/Widget.Holo.Light.Spinner" />
<Button
android:id="@+id/autologin_login"
android:text="@string/autologin_bar_login_text"
style="@android:style/Widget.Holo.Light.Button"
android:layout_marginRight="15dip"
android:layout_height="wrap_content"
android:layout_width="wrap_content" />
<ProgressBar
android:id="@+id/autologin_progress"
android:indeterminateOnly="true"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:visibility="gone" />
<TextView
android:id="@+id/autologin_error"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:textColor="#dd6826"
android:text="@string/autologin_bar_error"
android:textAppearance="?android:attr/textAppearanceMedium"
android:visibility="gone" />
<View
android:layout_width="2dip"
android:layout_height="match_parent"
style="@style/HoloButton"
android:src="@drawable/ic_stop_holo_dark"
android:visibility="gone"
/>
android:layout_weight="1" />
<ImageButton
android:id="@+id/bookmark"
android:id="@+id/autologin_close"
android:layout_width="wrap_content"
android:layout_height="match_parent"
style="@style/HoloButton"
android:src="@drawable/btn_imageview_star"
/>
android:layout_height="wrap_content"
android:paddingRight="15dip"
android:background="@null"
android:src="@*android:drawable/btn_close" />
</LinearLayout>
<com.android.browser.PageProgressView
android:id="@+id/progress_horizontal"
android:layout_width="match_parent"
android:layout_height="22dip"
android:background="@null"
android:src="@drawable/progress"
android:layout_marginTop="-11dip"
android:visibility="gone" />
</LinearLayout>
</RelativeLayout>
\ No newline at end of file
......@@ -118,7 +118,7 @@
style="@style/HoloIcon"
android:visibility="gone" />
<com.android.browser.UrlInputView
android:id="@+id/url_focused"
android:id="@+id/url"
android:layout_width="0dip"
android:layout_weight="1.0"
android:layout_height="match_parent"
......
......@@ -42,6 +42,7 @@ import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.view.inputmethod.InputMethodManager;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings.ZoomDensity;
import android.webkit.WebView;
import android.widget.FrameLayout;
import android.widget.ImageButton;
......@@ -322,8 +323,6 @@ public abstract class BaseUi implements UI, WebViewFactory {
Log.w(LOGTAG, "mContainer is already attached to content in"
+ " attachTabToContentView!");
}
mainView.setNextFocusUpId(R.id.url_focused);
mainView.setNextFocusDownId(R.id.url_focused);
mUiController.attachSubWindow(tab);
}
......@@ -417,6 +416,13 @@ public abstract class BaseUi implements UI, WebViewFactory {
mContentView.addView(container, COVER_SCREEN_PARAMS);
}
protected void refreshWebView() {
Tab tab = getActiveTab();
if ((tab != null) && (tab.getWebView() != null)) {
tab.getWebView().invalidate();
}
}
boolean canShowTitleBar() {
return !isTitleBarShowing()
&& !isActivityPaused()
......@@ -448,18 +454,23 @@ public abstract class BaseUi implements UI, WebViewFactory {
}
@Override
public void showVoiceTitleBar(String title) {
getTitleBar().setInVoiceMode(true);
public void showVoiceTitleBar(String title, List<String> results) {
getTitleBar().setInVoiceMode(true, results);
getTitleBar().setDisplayTitle(title);
}
@Override
public void revertVoiceTitleBar(Tab tab) {
getTitleBar().setInVoiceMode(false);
getTitleBar().setInVoiceMode(false, null);
String url = tab.getUrl();
getTitleBar().setDisplayTitle(url);
}
@Override
public void registerDropdownChangeListener(DropdownChangeListener d) {
getTitleBar().registerDropdownChangeListener(d);
}
@Override
public void showComboView(boolean startWithHistory, Bundle extras) {
if (mComboView != null) {
......@@ -581,7 +592,9 @@ public abstract class BaseUi implements UI, WebViewFactory {
protected void updateNavigationState(Tab tab) {
}
protected void updateAutoLogin(Tab tab, boolean animate) {}
protected void updateAutoLogin(Tab tab, boolean animate) {
getTitleBar().updateAutoLogin(tab, animate);
}
/**
* Update the lock icon to correspond to our latest state.
......@@ -735,7 +748,4 @@ public abstract class BaseUi implements UI, WebViewFactory {
warning.show();
}
@Override
public void registerDropdownChangeListener(DropdownChangeListener d) {
}
}
......@@ -1056,8 +1056,9 @@ public class Controller
mActivity.startActivity(intent);
}
public void activateVoiceSearchMode(String title) {
mUi.showVoiceTitleBar(title);
@Override
public void activateVoiceSearchMode(String title, List<String> results) {
mUi.showVoiceTitleBar(title, results);
}
public void revertVoiceSearchMode(Tab tab) {
......
......@@ -39,7 +39,7 @@ public class PhoneUi extends BaseUi {
private static final String LOGTAG = "PhoneUi";
private TitleBar mTitleBar;
private TitleBarPhone mTitleBar;
private ActiveTabsPage mActiveTabsPage;
private TouchProxy mTitleOverlay;
......@@ -52,7 +52,7 @@ public class PhoneUi extends BaseUi {
*/
public PhoneUi(Activity browser, UiController controller) {
super(browser, controller);
mTitleBar = new TitleBar(mActivity, mUiController, this);
mTitleBar = new TitleBarPhone(mActivity, mUiController, this);
// mTitleBar will be always be shown in the fully loaded mode on
// phone
mTitleBar.setProgress(100);
......@@ -130,7 +130,8 @@ public class PhoneUi extends BaseUi {
}
view.setEmbeddedTitleBar(getTitleBar());
if (tab.isInVoiceSearchMode()) {
showVoiceTitleBar(tab.getVoiceDisplayTitle());
showVoiceTitleBar(tab.getVoiceDisplayTitle(),
tab.getVoiceSearchResults());
} else {
revertVoiceTitleBar(tab);
}
......@@ -298,4 +299,5 @@ public class PhoneUi extends BaseUi {
return params;
}
}
}
......@@ -313,7 +313,9 @@ class Tab {
mVoiceSearchData.mLastVoiceSearchTitle
= mVoiceSearchData.mVoiceSearchResults.get(index);
if (mInForeground) {
mWebViewController.activateVoiceSearchMode(mVoiceSearchData.mLastVoiceSearchTitle);
mWebViewController.activateVoiceSearchMode(
mVoiceSearchData.mLastVoiceSearchTitle,
mVoiceSearchData.mVoiceSearchResults);
}
if (mVoiceSearchData.mVoiceSearchHtmls != null) {
// When index was found it was already ensured that it was valid
......
......@@ -16,7 +16,9 @@
package com.android.browser;
import com.android.browser.UI.DropdownChangeListener;
import com.android.browser.UrlInputView.UrlInputListener;
import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
import android.app.SearchManager;
import android.content.Context;
......@@ -29,16 +31,36 @@ import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.PaintDrawable;
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.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.webkit.WebView;
import android.widget.AbsoluteLayout;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ProgressBar;
import android.widget.RelativeLayout;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.List;
/**
* Base class for a title bar used by the browser.
*/
public class TitleBarBase extends LinearLayout implements UrlInputListener {
public class TitleBarBase extends RelativeLayout
implements OnClickListener, OnFocusChangeListener, UrlInputListener,
TextChangeWatcher, DeviceAccountLogin.AutoLoginCallback {
protected static final int PROGRESS_MAX = 100;
......@@ -49,9 +71,21 @@ public class TitleBarBase extends LinearLayout implements UrlInputListener {
protected Drawable mGenericFavicon;
protected UiController mUiController;
protected BaseUi mBaseUi;
protected UrlInputView mUrlInput;
protected boolean mInVoiceMode;
// Auto-login UI
protected View mAutoLogin;
protected Spinner mAutoLoginAccount;
protected Button mAutoLoginLogin;
protected ProgressBar mAutoLoginProgress;
protected TextView mAutoLoginError;
protected ImageButton mAutoLoginCancel;
protected DeviceAccountLogin mAutoLoginHandler;
protected ArrayAdapter<String> mAccountsAdapter;
public TitleBarBase(Context context, UiController controller, BaseUi ui) {
super(context, null);
mUiController = controller;
......@@ -60,8 +94,31 @@ public class TitleBarBase extends LinearLayout implements UrlInputListener {
R.drawable.app_web_browser_sm);
}
protected void initLayout(Context context, int layoutId) {
LayoutInflater factory = LayoutInflater.from(context);
factory.inflate(layoutId, this);
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 = (ImageButton) mAutoLogin.findViewById(R.id.autologin_close);
mAutoLoginCancel.setOnClickListener(this);
}
protected void setupUrlInput() {
}
/* package */ void setProgress(int newProgress) {}
/* package */ void setDisplayTitle(String title) {}
/* package */ void setLock(Drawable d) {
assert mLockIcon != null;
......@@ -90,10 +147,6 @@ public class TitleBarBase extends LinearLayout implements UrlInputListener {
mFavicon.setImageDrawable(d);
}
/* package */ void setInVoiceMode(boolean inVoiceMode) {}
/* package */ void setIncognitoMode(boolean incognito) {}
void setTitleGravity(int gravity) {
int newTop = 0;
if (gravity != Gravity.NO_GRAVITY) {
......@@ -117,6 +170,179 @@ public class TitleBarBase extends LinearLayout implements UrlInputListener {
return getHeight();
}
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<String>(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.GONE);
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.GONE);
mAutoLoginError.setVisibility(View.VISIBLE);
break;
case DeviceAccountLogin.INITIAL:
break;
default:
throw new IllegalStateException();
}
showAutoLogin(animate);
}
}
protected void showAutoLogin(boolean animate) {
mAutoLogin.setVisibility(View.VISIBLE);
if (animate) {
mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
getContext(), R.anim.autologin_enter));
}
}
protected void hideAutoLogin(boolean animate) {
mAutoLoginHandler = null;
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.GONE);
mAutoLoginError.setVisibility(View.VISIBLE);
}
protected boolean inAutoLogin() {
return mAutoLoginHandler != null;
}
@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);
}
}
}
@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) {
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);
}
}
}
mUrlInput.clearNeedsUpdate();
}
protected void setFocusState(boolean focus) {
if (focus) {
updateSearchMode(false);
}
}
protected void updateSearchMode(boolean userEdited) {
setSearchMode(!userEdited || TextUtils.isEmpty(mUrlInput.getUserText()));
}
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()) {
// check if input field is empty and adjust voice search state
updateSearchMode(true);
// clear voice mode when user types
setInVoiceMode(false, null);
}
}
// voicesearch
public void setInVoiceMode(boolean voicemode, List<String> voiceResults) {
mInVoiceMode = voicemode;
mUrlInput.setVoiceResults(voiceResults);
}
void setIncognitoMode(boolean incognito) {
mUrlInput.setIncognitoMode(incognito);
}
void clearCompletions() {
mUrlInput.setSuggestedText(null);
}
// UrlInputListener implementation
/**
......@@ -178,4 +404,27 @@ public class TitleBarBase extends LinearLayout implements UrlInputListener {
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);
}
}
......@@ -16,69 +16,51 @@
package com.android.browser;
import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
import com.android.browser.view.StopProgressView;
import android.app.Activity;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.TextUtils;
import android.text.style.ImageSpan;
import android.content.Context;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.MenuInflater;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import java.util.List;
/**
* This class represents a title bar for a particular "tab" or "window" in the
* browser.
*/
public class TitleBar extends TitleBarBase implements OnFocusChangeListener,
OnClickListener {
public class TitleBarPhone extends TitleBarBase implements OnFocusChangeListener,
OnClickListener, TextChangeWatcher {
private Activity mActivity;
private ImageButton mBookmarkButton;
private PageProgressView mHorizontalProgress;
private ImageButton mStopButton;
private Drawable mBookmarkDrawable;
private Drawable mVoiceDrawable;
private StopProgressView mStopButton;
private ImageView mVoiceButton;
private boolean mInLoad;
private ImageSpan mArcsSpan;
private View mContainer;
private boolean mHasLockIcon;
public TitleBar(Activity activity, UiController controller, PhoneUi ui) {
public TitleBarPhone(Activity activity, UiController controller, PhoneUi ui) {
super(activity, controller, ui);
LayoutInflater factory = LayoutInflater.from(activity);
factory.inflate(R.layout.title_bar, this);
mActivity = activity;
initLayout(activity, R.layout.title_bar);
}
@Override
protected void initLayout(Context context, int layoutId) {
super.initLayout(context, layoutId);
mContainer = findViewById(R.id.taburlbar);
mUrlInput = (UrlInputView) findViewById(R.id.url_input);
mUrlInput.setCompoundDrawablePadding(5);
mUrlInput.setContainer(this);
mUrlInput.setSelectAllOnFocus(true);
mUrlInput.setController(mUiController);
mUrlInput.setUrlInputListener(this);
mUrlInput.setOnFocusChangeListener(this);
mLockIcon = (ImageView) findViewById(R.id.lock);
mFavicon = (ImageView) findViewById(R.id.favicon);
mStopButton = (ImageButton) findViewById(R.id.stop);
mBookmarkButton = (ImageButton) findViewById(R.id.bookmark);
mStopButton = (StopProgressView) findViewById(R.id.stop);
mStopButton.setOnClickListener(this);
mBookmarkButton.setOnClickListener(this);
mHorizontalProgress = (PageProgressView) findViewById(
R.id.progress_horizontal);
Resources resources = getResources();
mVoiceDrawable = resources.getDrawable(
android.R.drawable.ic_btn_speak_now);
mBookmarkDrawable = mBookmarkButton.getDrawable();
mArcsSpan = new ImageSpan(activity, R.drawable.arcs,
ImageSpan.ALIGN_BASELINE);
mVoiceButton = (ImageView) findViewById(R.id.voice);
mVoiceButton.setOnClickListener(this);
setFocusState(false);
}
@Override
......@@ -94,32 +76,38 @@ public class TitleBar extends TitleBarBase implements OnFocusChangeListener,
mActivity.onCreateContextMenu(menu, this, null);
}
/**
* Change the TitleBar to or from voice mode. If there is no package to
* handle voice search, the TitleBar cannot be set to voice mode.
*/
@Override
void setInVoiceMode(boolean inVoiceMode) {
if (mInVoiceMode == inVoiceMode) return;
mInVoiceMode = inVoiceMode && mUiController.supportsVoiceSearch();
Drawable titleDrawable;
if (mInVoiceMode) {
mBookmarkButton.setImageDrawable(mVoiceDrawable);
mUrlInput.setEllipsize(null);
mBookmarkButton.setVisibility(View.VISIBLE);
public void setInVoiceMode(boolean voicemode, List<String> voiceResults) {
super.setInVoiceMode(voicemode, voiceResults);
}
@Override
protected void setSearchMode(boolean voiceSearchEnabled) {
boolean showvoicebutton = voiceSearchEnabled &&
mUiController.supportsVoiceSearch();
mVoiceButton.setVisibility(showvoicebutton ? View.VISIBLE :
View.GONE);
}
@Override
protected void setFocusState(boolean focus) {
super.setFocusState(focus);
if (focus) {
mHasLockIcon = (mLockIcon.getVisibility() == View.VISIBLE);
mFavicon.setVisibility(View.GONE);
mLockIcon.setVisibility(View.GONE);
mStopButton.setVisibility(View.GONE);
mVoiceButton.setVisibility(View.VISIBLE);
} else {
mFavicon.setVisibility(View.VISIBLE);
mLockIcon.setVisibility(mHasLockIcon ? View.VISIBLE : View.GONE);
if (mInLoad) {
mBookmarkButton.setVisibility(View.GONE);
mStopButton.setVisibility(View.VISIBLE);
} else {
mBookmarkButton.setVisibility(View.VISIBLE);
mStopButton.setVisibility(View.GONE);
mBookmarkButton.setImageDrawable(mBookmarkDrawable);
}
mUrlInput.setEllipsize(TextUtils.TruncateAt.END);
mVoiceButton.setVisibility(View.GONE);
}
mUrlInput.setSingleLine(!mInVoiceMode);
}
/**
......@@ -128,23 +116,12 @@ public class TitleBar extends TitleBarBase implements OnFocusChangeListener,
@Override
void setProgress(int newProgress) {
if (newProgress >= PROGRESS_MAX) {
mHorizontalProgress.setVisibility(View.GONE);
if (!mInVoiceMode) {
mBookmarkButton.setImageDrawable(mBookmarkDrawable);
mBookmarkButton.setVisibility(View.VISIBLE);
mStopButton.setVisibility(View.GONE);
}
mInLoad = false;
setFocusState(mUrlInput.hasFocus());
} else {
mHorizontalProgress.setProgress(newProgress * PageProgressView.MAX_PROGRESS
/ PROGRESS_MAX);
if (!mInLoad) {
mHorizontalProgress.setVisibility(View.VISIBLE);
if (!mInVoiceMode) {
mBookmarkButton.setVisibility(View.GONE);
mStopButton.setVisibility(View.VISIBLE);
}
mInLoad = true;
setFocusState(mUrlInput.hasFocus());
}
}
}
......@@ -159,40 +136,29 @@ public class TitleBar extends TitleBarBase implements OnFocusChangeListener,
if (title == null) {
mUrlInput.setText(R.string.new_tab);
} else {
if (mInVoiceMode) {
// Add two spaces. The second one will be replaced with an
// image, and the first one will put space between it and the
// text
SpannableString spannable = new SpannableString(title + " ");
int end = spannable.length();
spannable.setSpan(mArcsSpan, end - 1, end,
Spanned.SPAN_MARK_POINT);
mUrlInput.setText(spannable);
} else {
mUrlInput.setText(title);
}
mUrlInput.setText(title);
}
}
@Override
public void onFocusChange(View v, boolean hasFocus) {
if (v == mUrlInput && hasFocus) {
mActivity.closeOptionsMenu();
if (v == mUrlInput) {
if (hasFocus) {
mActivity.closeOptionsMenu();
}
}
super.onFocusChange(v, hasFocus);
}
@Override
public void onClick(View v) {
if (v == mStopButton) {
mUiController.stopLoading();
} else if (v == mBookmarkButton) {
mUiController.bookmarkCurrentPage(AddBookmarkPage.DEFAULT_FOLDER_ID,
true);
} else if (v == mVoiceButton) {
mUiController.startVoiceSearch();
} else {
super.onClick(v);
}
}
@Override
public void setCurrentUrlIsBookmark(boolean isBookmark) {
mBookmarkButton.setActivated(isBookmark);
}
}
......@@ -16,7 +16,6 @@
package com.android.browser;
import com.android.browser.UI.DropdownChangeListener;
import com.android.browser.autocomplete.SuggestedTextController.TextChangeWatcher;
import android.app.Activity;
......@@ -25,26 +24,15 @@ import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.view.ContextThemeWrapper;
import android.view.KeyEvent;
import android.view.LayoutInflater;
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.webkit.WebView;
import android.widget.AbsoluteLayout;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.Spinner;
import android.widget.TextView;
import java.util.List;
......@@ -60,13 +48,13 @@ public class TitleBarXLarge extends TitleBarBase
private Drawable mStopDrawable;
private Drawable mReloadDrawable;
private View mContainer;
private View mUrlContainer;
private ImageButton mBackButton;
private ImageButton mForwardButton;
private ImageView mStar;
private ImageView mUrlIcon;
private ImageView mSearchButton;
private View mUrlContainer;
private View mContainer;
private View mGoButton;
private ImageView mStopButton;
private View mAllButton;
......@@ -75,15 +63,6 @@ public class TitleBarXLarge extends TitleBarBase
private PageProgressView mProgressView;
private Drawable mFocusDrawable;
private Drawable mUnfocusDrawable;
// Auto-login UI
private View mAutoLogin;
private Spinner mAutoLoginAccount;
private Button mAutoLoginLogin;
private ProgressBar mAutoLoginProgress;
private TextView mAutoLoginError;
private ImageButton mAutoLoginCancel;
private DeviceAccountLogin mAutoLoginHandler;
private ArrayAdapter<String> mAccountsAdapter;
private boolean mInLoad;
private boolean mUseQuickControls;
......@@ -100,7 +79,7 @@ public class TitleBarXLarge extends TitleBarBase
mUnfocusDrawable = resources.getDrawable(
R.drawable.textfield_default_holo_dark);
mInVoiceMode = false;
initLayout(activity);
initLayout(activity, R.layout.url_bar);
}
@Override
......@@ -115,12 +94,11 @@ public class TitleBarXLarge extends TitleBarBase
}
}
private void initLayout(Context context) {
LayoutInflater factory = LayoutInflater.from(context);
factory.inflate(R.layout.url_bar, this);
@Override
protected void initLayout(Context context, int layoutId) {
super.initLayout(context, layoutId);
mContainer = findViewById(R.id.taburlbar);
mUrlInput = (UrlInputView) findViewById(R.id.url_focused);
mAllButton = findViewById(R.id.all_btn);
// TODO: Change enabled states based on whether you can go
// back/forward. Probably should be done inside onPageStarted.
......@@ -145,23 +123,7 @@ public class TitleBarXLarge extends TitleBarBase
mGoButton.setOnClickListener(this);
mClearButton.setOnClickListener(this);
mVoiceSearch.setOnClickListener(this);
mUrlInput.setUrlInputListener(this);
mUrlInput.setContainer(mUrlContainer);
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 =
(ImageButton) mAutoLogin.findViewById(R.id.autologin_close);
mAutoLoginCancel.setOnClickListener(this);
setFocusState(false);
}
......@@ -177,67 +139,6 @@ public class TitleBarXLarge extends TitleBarBase
}
}
void updateAutoLogin(Tab tab, boolean animate) {
DeviceAccountLogin login = tab.getDeviceAccountLogin();
if (login != null) {
mAutoLoginHandler = login;
mAutoLogin.setVisibility(View.VISIBLE);
ContextThemeWrapper wrapper = new ContextThemeWrapper(mContext,
android.R.style.Theme_Holo_Light);
mAccountsAdapter = new ArrayAdapter<String>(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.GONE);
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.GONE);
mAutoLoginError.setVisibility(View.VISIBLE);
break;
case DeviceAccountLogin.INITIAL:
break;
default:
throw new IllegalStateException();
}
if (mUseQuickControls) {
mUi.showTitleBar();
} else {
if (animate) {
mAutoLogin.startAnimation(AnimationUtils.loadAnimation(
getContext(), R.anim.autologin_enter));
}
}
} else {
mAutoLoginHandler = null;
if (mUseQuickControls) {
mUi.hideTitleBar();
mAutoLogin.setVisibility(View.GONE);
mUi.refreshWebView();
} else {
if (animate) {
hideAutoLogin();
} else if (mAutoLogin.getAnimation() == null) {
mAutoLogin.setVisibility(View.GONE);
mUi.refreshWebView();
}
}
}
}
boolean inAutoLogin() {
return mAutoLoginHandler != null;
}
private ViewGroup.LayoutParams makeLayoutParams() {
if (mUseQuickControls) {
return new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
......@@ -326,26 +227,24 @@ public class TitleBarXLarge extends TitleBarBase
}
}
boolean isEditingUrl() {
return mUrlInput.hasFocus();
}
void stopEditingUrl() {
mUrlInput.clearFocus();
@Override
protected void showAutoLogin(boolean animate) {
if (mUseQuickControls) {
mUi.showTitleBar();
}
super.showAutoLogin(animate);
}
private void hideAutoLogin() {
Animation anim = AnimationUtils.loadAnimation(
getContext(), R.anim.autologin_exit);
anim.setAnimationListener(new AnimationListener() {
@Override public void onAnimationEnd(Animation a) {
mAutoLogin.setVisibility(View.GONE);
mUi.refreshWebView();
}
@Override public void onAnimationStart(Animation a) {}
@Override public void onAnimationRepeat(Animation a) {}
});
mAutoLogin.startAnimation(anim);
@Override
protected void hideAutoLogin(boolean animate) {
mAutoLoginHandler = null;
if (mUseQuickControls) {
mUi.hideTitleBar();
mAutoLogin.setVisibility(View.GONE);
mUi.refreshWebView();
} else {
super.hideAutoLogin(animate);
}
}
@Override
......@@ -372,32 +271,11 @@ public class TitleBarXLarge extends TitleBarBase
clearOrClose();
} else if (mVoiceSearch == v) {
mUiController.startVoiceSearch();
} else if (mAutoLoginCancel == v) {
if (mAutoLoginHandler != null) {
mAutoLoginHandler.cancel();
mAutoLoginHandler = null;
}
hideAutoLogin();
} 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 {
super.onClick(v);
}
}
@Override
public void loginFailed() {
mAutoLoginAccount.setEnabled(true);
mAutoLoginLogin.setEnabled(true);
mAutoLoginProgress.setVisibility(View.GONE);
mAutoLoginError.setVisibility(View.VISIBLE);
}
@Override
void setFavicon(Bitmap icon) { }
......@@ -411,10 +289,10 @@ public class TitleBarXLarge extends TitleBarBase
}
}
private void setFocusState(boolean focus) {
@Override
protected void setFocusState(boolean focus) {
super.setFocusState(focus);
if (focus) {
mUrlInput.setDropDownWidth(mUrlContainer.getWidth());
mUrlInput.setDropDownHorizontalOffset(-mUrlInput.getLeft());
mSearchButton.setVisibility(View.GONE);
mStar.setVisibility(View.GONE);
mClearButton.setVisibility(View.VISIBLE);
......@@ -470,11 +348,13 @@ public class TitleBarXLarge extends TitleBarBase
}
}
private void updateSearchMode(boolean userEdited) {
@Override
protected void updateSearchMode(boolean userEdited) {
setSearchMode(!userEdited || TextUtils.isEmpty(mUrlInput.getUserText()));
}
private void setSearchMode(boolean voiceSearchEnabled) {
@Override
protected void setSearchMode(boolean voiceSearchEnabled) {
boolean showvoicebutton = voiceSearchEnabled &&
mUiController.supportsVoiceSearch();
mVoiceSearch.setVisibility(showvoicebutton ? View.VISIBLE :
......@@ -484,44 +364,13 @@ public class TitleBarXLarge extends TitleBarBase
}
@Override
/* package */ void setDisplayTitle(String title) {
if (!isEditingUrl()) {
mUrlInput.setText(title, false);
}
}
// UrlInput text watcher
@Override
public void onTextChanged(String newText) {
if (mUrlInput.hasFocus()) {
// check if input field is empty and adjust voice search state
updateSearchMode(true);
// clear voice mode when user types
setInVoiceMode(false, null);
}
}
// voicesearch
@Override
public void setInVoiceMode(boolean voicemode) {
setInVoiceMode(voicemode, null);
}
public void setInVoiceMode(boolean voicemode, List<String> voiceResults) {
mInVoiceMode = voicemode;
mUrlInput.setVoiceResults(voiceResults);
super.setInVoiceMode(voicemode, voiceResults);
if (voicemode) {
mUrlIcon.setImageDrawable(mSearchButton.getDrawable());
}
}
@Override
void setIncognitoMode(boolean incognito) {
mUrlInput.setIncognitoMode(incognito);
}
@Override
public View focusSearch(View focused, int dir) {
if (FOCUS_DOWN == dir && hasFocus()) {
......@@ -530,30 +379,4 @@ public class TitleBarXLarge extends TitleBarBase
return super.focusSearch(focused, dir);
}
void clearCompletions() {
mUrlInput.setSuggestedText(null);
}
@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);
}
private WebView getCurrentWebView() {
Tab t = mUi.getActiveTab();
if (t != null) {
return t.getWebView();
} else {
return null;
}
}
void registerDropdownChangeListener(DropdownChangeListener d) {
mUrlInput.registerDropdownChangeListener(d);
}
}
......@@ -85,7 +85,7 @@ public interface UI {
public boolean isCustomViewShowing();
public void showVoiceTitleBar(String title);
public void showVoiceTitleBar(String title, List<String> results);
public void revertVoiceTitleBar(Tab tab);
......
......@@ -31,6 +31,8 @@ import android.webkit.ValueCallback;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import java.util.List;
/**
* WebView aspect of the controller
*/
......@@ -85,7 +87,7 @@ public interface WebViewController {
void onUserCanceledSsl(Tab tab);
void activateVoiceSearchMode(String title);
void activateVoiceSearchMode(String title, List<String> results);
void revertVoiceSearchMode(Tab tab);
......
......@@ -23,7 +23,6 @@ import android.animation.Animator.AnimatorListener;
import android.animation.ObjectAnimator;
import android.app.ActionBar;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
......@@ -249,7 +248,7 @@ public class XLargeUi extends BaseUi implements ScrollListener {
}
mTabBar.onSetActiveTab(tab);
if (tab.isInVoiceSearchMode()) {
showVoiceTitleBar(tab.getVoiceDisplayTitle());
showVoiceTitleBar(tab.getVoiceDisplayTitle(), tab.getVoiceSearchResults());
} else {
revertVoiceTitleBar(tab);
}
......@@ -449,18 +448,6 @@ public class XLargeUi extends BaseUi implements ScrollListener {
mTitleBar.updateNavigationState(tab);
}
@Override
protected void updateAutoLogin(Tab tab, boolean animate) {
mTitleBar.updateAutoLogin(tab, animate);
}
protected void refreshWebView() {
Tab tab = getActiveTab();
if ((tab != null) && (tab.getWebView() != null)) {
tab.getWebView().invalidate();
}
}
@Override
public void setUrlTitle(Tab tab) {
super.setUrlTitle(tab);
......@@ -475,11 +462,7 @@ public class XLargeUi extends BaseUi implements ScrollListener {
}
@Override
public void showVoiceTitleBar(String title) {
List<String> vsresults = null;
if (getActiveTab() != null) {
vsresults = getActiveTab().getVoiceSearchResults();
}
public void showVoiceTitleBar(String title, List<String> vsresults) {
mTitleBar.setInVoiceMode(true, vsresults);
mTitleBar.setDisplayTitle(title);
}
......@@ -539,11 +522,6 @@ public class XLargeUi extends BaseUi implements ScrollListener {
return mTabBar;
}
@Override
public void registerDropdownChangeListener(DropdownChangeListener d) {
mTitleBar.registerDropdownChangeListener(d);
}
@Override
public boolean onPrepareOptionsMenu(Menu menu) {
if (mUseQuickControls) {
......
package com.android.browser.view;
import com.android.browser.R;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.widget.ProgressBar;
public class StopProgressView extends ProgressBar {
Drawable mOverlayDrawable;
Drawable mProgressDrawable;
int mWidth;
int mHeight;
/**
* @param context
* @param attrs
* @param defStyle
* @param styleRes
*/
public StopProgressView(Context context, AttributeSet attrs, int defStyle, int styleRes) {
super(context, attrs, defStyle, styleRes);
init(attrs);
}
/**
* @param context
* @param attrs
* @param defStyle
*/
public StopProgressView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init(attrs);
}
/**
* @param context
* @param attrs
*/
public StopProgressView(Context context, AttributeSet attrs) {
super(context, attrs);
init(attrs);
}
/**
* @param context
*/
public StopProgressView(Context context) {
super(context);
init(null);
}
private void init(AttributeSet attrs) {
mProgressDrawable = getIndeterminateDrawable();
setImageDrawable(mContext.getResources()
.getDrawable(R.drawable.ic_stop_holo_dark));
}
public void hideProgress() {
setIndeterminateDrawable(null);
}
public void showProgress() {
setIndeterminateDrawable(mProgressDrawable);
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mOverlayDrawable != null) {
int l = (getWidth() - mWidth) / 2;
int t = (getHeight() - mHeight) / 2;
mOverlayDrawable.setBounds(l, t, l + mWidth, t + mHeight);
mOverlayDrawable.draw(canvas);
}
}
public Drawable getDrawable() {
return mOverlayDrawable;
}
public void setImageDrawable(Drawable d) {
mOverlayDrawable = d;
if (d != null) {
mWidth = d.getIntrinsicWidth();
mHeight = d.getIntrinsicHeight();
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment