190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger/* 290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * Copyright (C) 2010 The Android Open Source Project 390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * 490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * Licensed under the Apache License, Version 2.0 (the "License"); 590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * you may not use this file except in compliance with the License. 690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * You may obtain a copy of the License at 790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * 890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * http://www.apache.org/licenses/LICENSE-2.0 990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * 1090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * Unless required by applicable law or agreed to in writing, software 1190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * distributed under the License is distributed on an "AS IS" BASIS, 1290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * See the License for the specific language governing permissions and 1490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * limitations under the License. 1590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger */ 1690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenbergerpackage android.webkit; 1790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 1890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenbergerimport android.content.Context; 1990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenbergerimport android.os.Handler; 2090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenbergerimport android.view.LayoutInflater; 2190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenbergerimport android.view.View; 2290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenbergerimport android.view.ViewConfiguration; 2390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenbergerimport android.view.View.OnClickListener; 2490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenbergerimport android.view.animation.AlphaAnimation; 2590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenbergerimport android.widget.FrameLayout; 2690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 2790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger@Deprecated 2890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenbergerclass ZoomControlExternal implements ZoomControlBase { 2990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 3090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger // The time that the external controls are visible before fading away 3190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger private static final long ZOOM_CONTROLS_TIMEOUT = 3290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger ViewConfiguration.getZoomControlsTimeout(); 3390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger // The view containing the external zoom controls 3490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger private ExtendedZoomControls mZoomControls; 3590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger private Runnable mZoomControlRunnable; 3690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger private final Handler mPrivateHandler = new Handler(); 3790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 3890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger private final WebView mWebView; 3990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 4090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public ZoomControlExternal(WebView webView) { 4190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mWebView = webView; 4290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 4390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 4490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public void show() { 4590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger if(mZoomControlRunnable != null) { 4690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPrivateHandler.removeCallbacks(mZoomControlRunnable); 4790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 4890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger getControls().show(true); 4990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPrivateHandler.postDelayed(mZoomControlRunnable, ZOOM_CONTROLS_TIMEOUT); 5090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 5190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 5290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public void hide() { 5390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger if (mZoomControlRunnable != null) { 5490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPrivateHandler.removeCallbacks(mZoomControlRunnable); 5590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 5690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger if (mZoomControls != null) { 5790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mZoomControls.hide(); 5890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 5990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 6090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 6190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public boolean isVisible() { 6290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger return mZoomControls != null && mZoomControls.isShown(); 6390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 6490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 6590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public void update() { } 6690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 6790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public ExtendedZoomControls getControls() { 6890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger if (mZoomControls == null) { 6990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mZoomControls = createZoomControls(); 7090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 7190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger /* 7290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * need to be set to VISIBLE first so that getMeasuredHeight() in 7390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * {@link #onSizeChanged()} can return the measured value for proper 7490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * layout. 7590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger */ 7690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mZoomControls.setVisibility(View.VISIBLE); 7790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mZoomControlRunnable = new Runnable() { 7890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public void run() { 7990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger /* Don't dismiss the controls if the user has 8090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger * focus on them. Wait and check again later. 8190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger */ 8290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger if (!mZoomControls.hasFocus()) { 8390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mZoomControls.hide(); 8490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } else { 8590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPrivateHandler.removeCallbacks(mZoomControlRunnable); 8690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPrivateHandler.postDelayed(mZoomControlRunnable, 8790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger ZOOM_CONTROLS_TIMEOUT); 8890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 8990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 9090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger }; 9190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 9290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger return mZoomControls; 9390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 9490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 9590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger private ExtendedZoomControls createZoomControls() { 9690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger ExtendedZoomControls zoomControls = new ExtendedZoomControls(mWebView.getContext()); 9790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger zoomControls.setOnZoomInClickListener(new OnClickListener() { 9890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public void onClick(View v) { 9990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger // reset time out 10090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPrivateHandler.removeCallbacks(mZoomControlRunnable); 10190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPrivateHandler.postDelayed(mZoomControlRunnable, ZOOM_CONTROLS_TIMEOUT); 10290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mWebView.zoomIn(); 10390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 10490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger }); 10590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger zoomControls.setOnZoomOutClickListener(new OnClickListener() { 10690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public void onClick(View v) { 10790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger // reset time out 10890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPrivateHandler.removeCallbacks(mZoomControlRunnable); 10990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPrivateHandler.postDelayed(mZoomControlRunnable, ZOOM_CONTROLS_TIMEOUT); 11090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mWebView.zoomOut(); 11190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 11290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger }); 11390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger return zoomControls; 11490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 11590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 11690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger private static class ExtendedZoomControls extends FrameLayout { 11790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 11890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger private android.widget.ZoomControls mPlusMinusZoomControls; 11990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 12090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public ExtendedZoomControls(Context context) { 12190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger super(context, null); 12290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger LayoutInflater inflater = (LayoutInflater) 12390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); 12490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger inflater.inflate(com.android.internal.R.layout.zoom_magnify, this, true); 12590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPlusMinusZoomControls = (android.widget.ZoomControls) findViewById( 12690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger com.android.internal.R.id.zoomControls); 12790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger findViewById(com.android.internal.R.id.zoomMagnify).setVisibility( 12890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger View.GONE); 12990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 13090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 13190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public void show(boolean showZoom) { 13290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPlusMinusZoomControls.setVisibility(showZoom ? View.VISIBLE : View.GONE); 13390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger fade(View.VISIBLE, 0.0f, 1.0f); 13490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 13590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 13690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public void hide() { 13790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger fade(View.GONE, 1.0f, 0.0f); 13890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 13990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 14090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger private void fade(int visibility, float startAlpha, float endAlpha) { 14190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger AlphaAnimation anim = new AlphaAnimation(startAlpha, endAlpha); 14290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger anim.setDuration(500); 14390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger startAnimation(anim); 14490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger setVisibility(visibility); 14590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 14690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 14790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public boolean hasFocus() { 14890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger return mPlusMinusZoomControls.hasFocus(); 14990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 15090b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 15190b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public void setOnZoomInClickListener(OnClickListener listener) { 15290b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPlusMinusZoomControls.setOnZoomInClickListener(listener); 15390b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 15490b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger 15590b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger public void setOnZoomOutClickListener(OnClickListener listener) { 15690b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger mPlusMinusZoomControls.setOnZoomOutClickListener(listener); 15790b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 15890b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger } 15990b6e4879304c6ac8240cdeb9a4aea94a27cda58Derek Sollenberger} 160