diff options
-rw-r--r-- | res/anim/dialog_enter.xml (renamed from res/anim/find_dialog_enter.xml) | 4 | ||||
-rw-r--r-- | res/anim/dialog_exit.xml (renamed from res/anim/find_dialog_exit.xml) | 4 | ||||
-rw-r--r-- | res/drawable-hdpi/ic_btn_copy.png | bin | 0 -> 1128 bytes | |||
-rwxr-xr-x | res/drawable-hdpi/ic_btn_find.png | bin | 0 -> 3610 bytes | |||
-rw-r--r-- | res/drawable-hdpi/ic_btn_select_all.png | bin | 0 -> 1991 bytes | |||
-rw-r--r-- | res/drawable-hdpi/ic_btn_share.png | bin | 0 -> 2194 bytes | |||
-rw-r--r-- | res/layout/browser_select.xml | 67 | ||||
-rw-r--r-- | res/layout/browser_subwindow.xml | 1 | ||||
-rw-r--r-- | res/values/styles.xml | 5 | ||||
-rw-r--r-- | res/values/themes.xml | 28 | ||||
-rw-r--r-- | src/com/android/browser/BrowserActivity.java | 90 | ||||
-rw-r--r-- | src/com/android/browser/FindDialog.java | 161 | ||||
-rw-r--r-- | src/com/android/browser/SelectDialog.java | 85 | ||||
-rw-r--r-- | src/com/android/browser/Tab.java | 64 | ||||
-rw-r--r-- | src/com/android/browser/WebDialog.java | 79 |
15 files changed, 473 insertions, 115 deletions
diff --git a/res/anim/find_dialog_enter.xml b/res/anim/dialog_enter.xml index 5e597a4..f98d845 100644 --- a/res/anim/find_dialog_enter.xml +++ b/res/anim/dialog_enter.xml @@ -16,6 +16,6 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/decelerate_interpolator"> - <translate android:fromYDelta="25%" android:toYDelta="0" android:duration="75"/> - <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="75" /> + <translate android:fromYDelta="25%" android:toYDelta="0" android:duration="75"/> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" android:duration="75" /> </set> diff --git a/res/anim/find_dialog_exit.xml b/res/anim/dialog_exit.xml index 854abd0..dacb5c3 100644 --- a/res/anim/find_dialog_exit.xml +++ b/res/anim/dialog_exit.xml @@ -16,7 +16,7 @@ <set xmlns:android="http://schemas.android.com/apk/res/android" android:interpolator="@android:anim/accelerate_interpolator"> - <translate android:fromYDelta="0" android:toYDelta="50%" android:duration="50"/> - <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="50" /> + <translate android:fromYDelta="0" android:toYDelta="50%" android:duration="50"/> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" android:duration="50" /> </set> diff --git a/res/drawable-hdpi/ic_btn_copy.png b/res/drawable-hdpi/ic_btn_copy.png Binary files differnew file mode 100644 index 0000000..04fda7f --- /dev/null +++ b/res/drawable-hdpi/ic_btn_copy.png diff --git a/res/drawable-hdpi/ic_btn_find.png b/res/drawable-hdpi/ic_btn_find.png Binary files differnew file mode 100755 index 0000000..20e1fbc --- /dev/null +++ b/res/drawable-hdpi/ic_btn_find.png diff --git a/res/drawable-hdpi/ic_btn_select_all.png b/res/drawable-hdpi/ic_btn_select_all.png Binary files differnew file mode 100644 index 0000000..839915b --- /dev/null +++ b/res/drawable-hdpi/ic_btn_select_all.png diff --git a/res/drawable-hdpi/ic_btn_share.png b/res/drawable-hdpi/ic_btn_share.png Binary files differnew file mode 100644 index 0000000..44db9b1 --- /dev/null +++ b/res/drawable-hdpi/ic_btn_share.png diff --git a/res/layout/browser_select.xml b/res/layout/browser_select.xml new file mode 100644 index 0000000..b30be8d --- /dev/null +++ b/res/layout/browser_select.xml @@ -0,0 +1,67 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:id="@+id/selectControls" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:paddingTop="5dip" + android:paddingLeft="4dip" + android:paddingRight="4dip" + android:paddingBottom="1dip" + android:background="@android:drawable/bottom_bar"> + <ImageButton + android:src="@drawable/ic_btn_copy" + android:id="@+id/copy" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> + + <ImageButton + android:src="@drawable/ic_btn_share" + android:id="@+id/share" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> + + <ImageButton + android:src="@drawable/ic_btn_select_all" + android:id="@+id/select_all" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> + + <ImageButton + android:src="@drawable/ic_btn_find" + android:id="@+id/find" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> + + <LinearLayout + android:layout_height="fill_parent" + android:layout_width="fill_parent" + android:layout_weight="1" + /> + + <ImageButton + android:src="@drawable/ic_btn_close_panel" + android:id="@+id/done" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> +</LinearLayout> + diff --git a/res/layout/browser_subwindow.xml b/res/layout/browser_subwindow.xml index 76d72d5..adf3284 100644 --- a/res/layout/browser_subwindow.xml +++ b/res/layout/browser_subwindow.xml @@ -23,6 +23,7 @@ android:layout_height="match_parent" android:padding="10dip" > <LinearLayout + android:id="@+id/inner_container" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" diff --git a/res/values/styles.xml b/res/values/styles.xml index 4779aa1..2e8510a 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -30,11 +30,6 @@ <item name="android:windowContentOverlay">@null</item> </style> - <style name="FindDialog"> - <item name="android:windowEnterAnimation">@anim/find_dialog_enter</item> - <item name="android:windowExitAnimation">@anim/find_dialog_exit</item> - </style> - <style name="TitleBar"> <item name="android:windowEnterAnimation">@anim/title_bar_enter</item> <item name="android:windowExitAnimation">@anim/title_bar_exit</item> diff --git a/res/values/themes.xml b/res/values/themes.xml deleted file mode 100644 index bb922dd..0000000 --- a/res/values/themes.xml +++ /dev/null @@ -1,28 +0,0 @@ -<?xml version="1.0" encoding="utf-8"?> -<!-- Copyright (C) 2008 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. ---> - -<resources> - <style name="FindDialogTheme"> - <item name="android:windowFrame">@null</item> - <item name="android:windowIsFloating">true</item> - <item name="android:windowIsTranslucent">true</item> - <item name="android:windowNoTitle">true</item> - <item name="android:background">@null</item> - <item name="android:windowBackground">@null</item> - <item name="android:windowAnimationStyle">@style/FindDialog</item> - <item name="android:backgroundDimEnabled">false</item> - </style> -</resources> diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java index 5e55789..8db4436 100644 --- a/src/com/android/browser/BrowserActivity.java +++ b/src/com/android/browser/BrowserActivity.java @@ -834,6 +834,13 @@ public class BrowserActivity extends Activity if (mainView == null) { return; } + // Do not need to check for null, since the current tab will have + // at least a main WebView, or we would have returned above. + if (dialogIsUp()) { + // Do not show the fake title bar, which would cover up the + // find or select dialog. + return; + } WindowManager manager = (WindowManager) getSystemService(Context.WINDOW_SERVICE); @@ -1271,6 +1278,22 @@ public class BrowserActivity extends Activity getTopWindow().requestFocus(); } + private WebView showDialog(WebDialog dialog) { + // Need to do something special for Tablet + Tab tab = mTabControl.getCurrentTab(); + if (tab.getSubWebView() == null) { + // If the find or select is being performed on the main webview, + // remove the embedded title bar. + WebView mainView = tab.getWebView(); + if (mainView != null) { + mainView.setEmbeddedTitleBar(null); + } + } + hideFakeTitleBar(); + mMenuState = EMPTY_MENU; + return tab.showDialog(dialog); + } + @Override public boolean onOptionsItemSelected(MenuItem item) { if (!mCanChord) { @@ -1364,18 +1387,13 @@ public class BrowserActivity extends Activity break; case R.id.find_menu_id: - if (null == mFindDialog) { - mFindDialog = new FindDialog(this); - } - mFindDialog.setWebView(getTopWindow()); - mFindDialog.show(); - getTopWindow().setFindIsUp(true); - mMenuState = EMPTY_MENU; + showFindDialog(); break; case R.id.select_text_id: - getTopWindow().emulateShiftHeld(); + showSelectDialog(); break; + case R.id.page_info_menu_id: showPageInfo(mTabControl.getCurrentTab(), false); break; @@ -1450,8 +1468,59 @@ public class BrowserActivity extends Activity return true; } - public void closeFind() { + private boolean dialogIsUp() { + return null != mFindDialog && mFindDialog.isVisible() || + null != mSelectDialog && mSelectDialog.isVisible(); + } + + private boolean closeDialog(WebDialog dialog) { + if (null == dialog || !dialog.isVisible()) return false; + Tab currentTab = mTabControl.getCurrentTab(); + currentTab.closeDialog(dialog); + dialog.dismiss(); + return true; + } + + /* + * Remove the find dialog or select dialog. + */ + public void closeDialogs() { + if (!(closeDialog(mFindDialog) || closeDialog(mSelectDialog))) return; + // If the Find was being performed in the main WebView, replace the + // embedded title bar. + Tab currentTab = mTabControl.getCurrentTab(); + if (currentTab.getSubWebView() == null) { + WebView mainView = currentTab.getWebView(); + if (mainView != null) { + mainView.setEmbeddedTitleBar(mTitleBar); + } + } mMenuState = R.id.MAIN_MENU; + if (mInLoad) { + // The title bar was hidden, because otherwise it would cover up the + // find or select dialog. Now that the dialog has been removed, + // show the fake title bar once again. + showFakeTitleBar(); + } + } + + public void showFindDialog() { + if (null == mFindDialog) { + mFindDialog = new FindDialog(this); + } + showDialog(mFindDialog).setFindIsUp(true); + } + + public void setFindDialogText(String text) { + mFindDialog.setText(text); + } + + public void showSelectDialog() { + if (null == mSelectDialog) { + mSelectDialog = new SelectDialog(this); + } + showDialog(mSelectDialog).setUpSelect(); + mSelectDialog.hideSoftInput(); } @Override @@ -2462,7 +2531,7 @@ public class BrowserActivity extends Activity onProgressChanged(view, INITIAL_PROGRESS); mDidStopLoad = false; if (!mIsNetworkUp) createAndShowNetworkDialog(); - + closeDialogs(); if (mSettings.isTracing()) { String host; try { @@ -3770,6 +3839,7 @@ public class BrowserActivity extends Activity private Menu mMenu; private FindDialog mFindDialog; + private SelectDialog mSelectDialog; // Used to prevent chording to result in firing two shortcuts immediately // one after another. Fixes bug 1211714. boolean mCanChord; diff --git a/src/com/android/browser/FindDialog.java b/src/com/android/browser/FindDialog.java index 45c8016..726138e 100644 --- a/src/com/android/browser/FindDialog.java +++ b/src/com/android/browser/FindDialog.java @@ -16,27 +16,25 @@ package com.android.browser; -import android.app.Dialog; import android.content.Context; -import android.os.Bundle; import android.text.Editable; +import android.text.Selection; import android.text.Spannable; import android.text.TextWatcher; import android.view.Gravity; import android.view.KeyEvent; +import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.view.Window; -import android.view.WindowManager; +import android.view.animation.AnimationUtils; import android.view.inputmethod.InputMethodManager; import android.webkit.WebView; import android.widget.EditText; +import android.widget.LinearLayout; import android.widget.TextView; -/* package */ class FindDialog extends Dialog implements TextWatcher { - private WebView mWebView; +/* package */ class FindDialog extends WebDialog implements TextWatcher { private TextView mMatches; - private BrowserActivity mBrowserActivity; // Views with which the user can interact. private EditText mEditText; @@ -44,39 +42,30 @@ import android.widget.TextView; private View mPrevButton; private View mMatchesView; + // When the dialog is opened up with old text, enter needs to be pressed + // (or the text needs to be changed) before WebView.findAll can be called. + // Once it has been called, enter should move to the next match. + private boolean mMatchesFound; + private int mNumberOfMatches; + private View.OnClickListener mFindListener = new View.OnClickListener() { public void onClick(View v) { findNext(); } }; - private View.OnClickListener mFindCancelListener = - new View.OnClickListener() { - public void onClick(View v) { - dismiss(); - } - }; - - private View.OnClickListener mFindPreviousListener = + private View.OnClickListener mFindPreviousListener = new View.OnClickListener() { public void onClick(View v) { if (mWebView == null) { throw new AssertionError("No WebView for FindDialog::onClick"); } mWebView.findNext(false); + updateMatchesString(); hideSoftInput(); } }; - /* - * Remove the soft keyboard from the screen. - */ - private void hideSoftInput() { - InputMethodManager imm = (InputMethodManager) - mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0); - } - private void disableButtons() { mPrevButton.setEnabled(false); mNextButton.setEnabled(false); @@ -84,28 +73,13 @@ import android.widget.TextView; mNextButton.setFocusable(false); } - /* package */ void setWebView(WebView webview) { - mWebView = webview; - } - /* package */ FindDialog(BrowserActivity context) { - super(context, R.style.FindDialogTheme); - mBrowserActivity = context; - setCanceledOnTouchOutside(true); - } - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); + super(context); - Window theWindow = getWindow(); - theWindow.setGravity(Gravity.BOTTOM|Gravity.FILL_HORIZONTAL); - - setContentView(R.layout.browser_find); - - theWindow.setLayout(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.WRAP_CONTENT); + LayoutInflater factory = LayoutInflater.from(context); + factory.inflate(R.layout.browser_find, this); + addCancel(); mEditText = (EditText) findViewById(R.id.edit); View button = findViewById(R.id.next); @@ -116,29 +90,59 @@ import android.widget.TextView; button.setOnClickListener(mFindPreviousListener); mPrevButton = button; - button = findViewById(R.id.done); - button.setOnClickListener(mFindCancelListener); - mMatches = (TextView) findViewById(R.id.matches); mMatchesView = findViewById(R.id.matches_view); disableButtons(); - theWindow.setSoftInputMode( - WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE); + } - + + /** + * Called by BrowserActivity.closeDialog. Start the animation to hide + * the dialog, inform the WebView that the dialog is being dismissed, + * and hide the soft keyboard. + */ public void dismiss() { super.dismiss(); - mBrowserActivity.closeFind(); mWebView.notifyFindDialogDismissed(); + hideSoftInput(); + } + + @Override + public boolean dispatchKeyEventPreIme(KeyEvent event) { + if (event.getKeyCode() == KeyEvent.KEYCODE_BACK) { + KeyEvent.DispatcherState state = getKeyDispatcherState(); + if (state != null) { + int action = event.getAction(); + if (KeyEvent.ACTION_DOWN == action + && event.getRepeatCount() == 0) { + state.startTracking(event, this); + return true; + } else if (KeyEvent.ACTION_UP == action + && !event.isCanceled() && state.isTracking(event)) { + mBrowserActivity.closeDialogs(); + return true; + } + } + } + return super.dispatchKeyEventPreIme(event); } @Override public boolean dispatchKeyEvent(KeyEvent event) { - if (event.getKeyCode() == KeyEvent.KEYCODE_ENTER - && event.getAction() == KeyEvent.ACTION_UP - && mEditText.hasFocus()) { - findNext(); - return true; + int keyCode = event.getKeyCode(); + if (event.getAction() == KeyEvent.ACTION_UP) { + if (keyCode == KeyEvent.KEYCODE_ENTER + && mEditText.hasFocus()) { + if (mMatchesFound) { + findNext(); + } else { + findAll(); + // Set the selection to the end. + Spannable span = (Spannable) mEditText.getText(); + Selection.setSelection(span, span.length()); + } + return true; + } } return super.dispatchKeyEvent(event); } @@ -148,18 +152,26 @@ import android.widget.TextView; throw new AssertionError("No WebView for FindDialog::findNext"); } mWebView.findNext(true); + updateMatchesString(); hideSoftInput(); } public void show() { super.show(); + // In case the matches view is showing from a previous search + mMatchesView.setVisibility(View.INVISIBLE); + mMatchesFound = false; + // This text is only here to ensure that mMatches has a height. + mMatches.setText("0"); mEditText.requestFocus(); - mEditText.setText(""); Spannable span = (Spannable) mEditText.getText(); - span.setSpan(this, 0, span.length(), - Spannable.SPAN_INCLUSIVE_INCLUSIVE); - setMatchesFound(0); + int length = span.length(); + Selection.setSelection(span, 0, length); + span.setSpan(this, 0, length, Spannable.SPAN_INCLUSIVE_INCLUSIVE); disableButtons(); + InputMethodManager imm = (InputMethodManager) + mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.showSoftInput(mEditText, 0); } // TextWatcher methods @@ -173,9 +185,13 @@ import android.widget.TextView; int start, int before, int count) { + findAll(); + } + + private void findAll() { if (mWebView == null) { throw new AssertionError( - "No WebView for FindDialog::onTextChanged"); + "No WebView for FindDialog::findAll"); } CharSequence find = mEditText.getText(); if (0 == find.length()) { @@ -184,14 +200,18 @@ import android.widget.TextView; mMatchesView.setVisibility(View.INVISIBLE); } else { mMatchesView.setVisibility(View.VISIBLE); - mWebView.setFindDialogHeight( - getWindow().getDecorView().getHeight()); int found = mWebView.findAll(find.toString()); + mMatchesFound = true; setMatchesFound(found); if (found < 2) { disableButtons(); if (found == 0) { - setMatchesFound(0); + // Cannot use getQuantityString, which ignores the "zero" + // quantity. + // FIXME: is this fix is beyond the scope + // of adding touch selection to gingerbread? + // mMatches.setText(mBrowserActivity.getResources().getString( + // R.string.no_matches)); } } else { mPrevButton.setFocusable(true); @@ -203,8 +223,21 @@ import android.widget.TextView; } private void setMatchesFound(int found) { + mNumberOfMatches = found; + updateMatchesString(); + } + + public void setText(String text) { + mEditText.setText(text); + findAll(); + } + + private void updateMatchesString() { + // Note: updateMatchesString is only called by methods that have already + // checked mWebView for null. String template = mBrowserActivity.getResources(). - getQuantityString(R.plurals.matches_found, found, found); + getQuantityString(R.plurals.matches_found, mNumberOfMatches, + mWebView.findIndex() + 1, mNumberOfMatches); mMatches.setText(template); } diff --git a/src/com/android/browser/SelectDialog.java b/src/com/android/browser/SelectDialog.java new file mode 100644 index 0000000..461127a --- /dev/null +++ b/src/com/android/browser/SelectDialog.java @@ -0,0 +1,85 @@ +/* + * 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.provider.Browser; +import android.view.LayoutInflater; +import android.view.View; + +/* package */ class SelectDialog extends WebDialog { + private View mCopyButton; + private View mSelectAllButton; + private View mShareButton; + private View mFindButton; + + SelectDialog(BrowserActivity context) { + super(context); + LayoutInflater factory = LayoutInflater.from(context); + factory.inflate(R.layout.browser_select, this); + addCancel(); + + mCopyButton = findViewById(R.id.copy); + mCopyButton.setOnClickListener(mCopyListener); + mSelectAllButton = findViewById(R.id.select_all); + mSelectAllButton.setOnClickListener(mSelectAllListener); + mShareButton = findViewById(R.id.share); + mShareButton.setOnClickListener(mShareListener); + mFindButton = findViewById(R.id.find); + mFindButton.setOnClickListener(mFindListener); + } + + private View.OnClickListener mCopyListener = new View.OnClickListener() { + public void onClick(View v) { + mWebView.copySelection(); + mBrowserActivity.closeDialogs(); + } + }; + + private View.OnClickListener mSelectAllListener = new View.OnClickListener() { + public void onClick(View v) { + mWebView.selectAll(); + } + }; + + private View.OnClickListener mShareListener = new View.OnClickListener() { + public void onClick(View v) { + String selection = mWebView.getSelection(); + Browser.sendString(mBrowserActivity, selection); + mBrowserActivity.closeDialogs(); + } + }; + + private View.OnClickListener mFindListener = new View.OnClickListener() { + public void onClick(View v) { + String selection = mWebView.getSelection(); + mBrowserActivity.closeDialogs(); + mBrowserActivity.showFindDialog(); + mBrowserActivity.setFindDialogText(selection); + } + }; + + /** + * Called by BrowserActivity.closeDialog. Start the animation to hide + * the dialog, and inform the WebView that the dialog is being dismissed. + */ + @Override + public void dismiss() { + super.dismiss(); + mWebView.notifySelectDialogDismissed(); + } + +} diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java index d2fed22..dd66f2e 100644 --- a/src/com/android/browser/Tab.java +++ b/src/com/android/browser/Tab.java @@ -87,7 +87,7 @@ class Tab { // The Geolocation permissions prompt private GeolocationPermissionsPrompt mGeolocationPermissionsPrompt; // Main WebView wrapper - private View mContainer; + private LinearLayout mContainer; // Main WebView private WebView mMainView; // Subwindow container @@ -1041,6 +1041,16 @@ class Tab { } @Override + public void onSelectionDone(WebView view) { + if (mInForeground) mActivity.closeDialogs(); + } + + @Override + public void onSelectionStart(WebView view) { + if (mInForeground) mActivity.showSelectDialog(); + } + + @Override public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) { if (mInForeground) mActivity.onShowCustomView(view, callback); @@ -1220,9 +1230,18 @@ class Tab { private static class SubWindowClient extends WebViewClient { // The main WebViewClient. private final WebViewClient mClient; + private final BrowserActivity mBrowserActivity; - SubWindowClient(WebViewClient client) { + SubWindowClient(WebViewClient client, BrowserActivity activity) { mClient = client; + mBrowserActivity = activity; + } + @Override + public void onPageStarted(WebView view, String url, Bitmap favicon) { + // Unlike the others, do not call mClient's version, which would + // change the progress bar. However, we do want to remove the + // find or select dialog. + mBrowserActivity.closeDialogs(); } @Override public void doUpdateVisitedHistory(WebView view, String url, @@ -1312,7 +1331,7 @@ class Tab { // The tab consists of a container view, which contains the main // WebView, as well as any other UI elements associated with the tab. - mContainer = mInflateService.inflate(R.layout.tab, null); + mContainer = (LinearLayout) mInflateService.inflate(R.layout.tab, null); mDownloadListener = new DownloadListener() { public void onDownloadStart(String url, String userAgent, @@ -1423,6 +1442,7 @@ class Tab { */ boolean createSubWindow() { if (mSubView == null) { + mActivity.closeDialogs(); mSubViewContainer = mInflateService.inflate( R.layout.browser_subwindow, null); mSubView = (WebView) mSubViewContainer.findViewById(R.id.webview); @@ -1431,7 +1451,8 @@ class Tab { mSubView.setMapTrackballToArrowKeys(false); // Enable the built-in zoom mSubView.getSettings().setBuiltInZoomControls(true); - mSubView.setWebViewClient(new SubWindowClient(mWebViewClient)); + mSubView.setWebViewClient(new SubWindowClient(mWebViewClient, + mActivity)); mSubView.setWebChromeClient(new SubWindowChromeClient( mWebChromeClient)); // Set a different DownloadListener for the mSubView, since it will @@ -1469,6 +1490,7 @@ class Tab { */ void dismissSubWindow() { if (mSubView != null) { + mActivity.closeDialogs(); BrowserSettings.getInstance().deleteObserver( mSubView.getSettings()); mSubView.destroy(); @@ -1493,6 +1515,7 @@ class Tab { void removeSubWindow(ViewGroup content) { if (mSubView != null) { content.removeView(mSubViewContainer); + mActivity.closeDialogs(); } } @@ -1551,6 +1574,7 @@ class Tab { (FrameLayout) mContainer.findViewById(R.id.webview_wrapper); wrapper.removeView(mMainView); content.removeView(mContainer); + mActivity.closeDialogs(); removeSubWindow(content); } @@ -1946,4 +1970,36 @@ class Tab { } return true; } + + /* + * Opens the find and select text dialogs. Called by BrowserActivity. + */ + WebView showDialog(WebDialog dialog) { + LinearLayout container; + WebView view; + if (mSubView != null) { + view = mSubView; + container = (LinearLayout) mSubViewContainer.findViewById( + R.id.inner_container); + } else { + view = mMainView; + container = mContainer; + } + dialog.show(); + container.addView(dialog, 0, new LinearLayout.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT)); + dialog.setWebView(view); + return view; + } + + /* + * Close the find or select dialog. Called by BrowserActivity.closeDialog. + */ + void closeDialog(WebDialog dialog) { + // The dialog may be attached to the subwindow. Ensure that the + // correct parent has it removed. + LinearLayout parent = (LinearLayout) dialog.getParent(); + if (parent != null) parent.removeView(dialog); + } } diff --git a/src/com/android/browser/WebDialog.java b/src/com/android/browser/WebDialog.java new file mode 100644 index 0000000..9995e8f --- /dev/null +++ b/src/com/android/browser/WebDialog.java @@ -0,0 +1,79 @@ +/* + * 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.content.Context; +import android.view.View; +import android.view.animation.AnimationUtils; +import android.view.inputmethod.InputMethodManager; +import android.webkit.WebView; +import android.widget.LinearLayout; + +/* package */ class WebDialog extends LinearLayout { + protected WebView mWebView; + protected BrowserActivity mBrowserActivity; + private boolean mIsVisible; + + /* package */ WebDialog(BrowserActivity context) { + super(context); + mBrowserActivity = context; + } + + /* dialogs that have cancel buttons can optionally share code by including a + * view with an id of 'done'. + */ + protected void addCancel() { + View button = findViewById(R.id.done); + if (button != null) button.setOnClickListener(mCancelListener); + } + + private View.OnClickListener mCancelListener = new View.OnClickListener() { + public void onClick(View v) { + mBrowserActivity.closeDialogs(); + } + }; + + protected void dismiss() { + startAnimation(AnimationUtils.loadAnimation(mBrowserActivity, + R.anim.dialog_exit)); + mIsVisible = false; + } + + /* + * Remove the soft keyboard from the screen. + */ + protected void hideSoftInput() { + InputMethodManager imm = (InputMethodManager) + mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE); + imm.hideSoftInputFromWindow(mWebView.getWindowToken(), 0); + } + + protected boolean isVisible() { + return mIsVisible; + } + + /* package */ void setWebView(WebView webview) { + mWebView = webview; + } + + protected void show() { + startAnimation(AnimationUtils.loadAnimation(mBrowserActivity, + R.anim.dialog_enter)); + mIsVisible = true; + } + +} |