blob: 6cdc063772d3af78df28de88f92e43440e8a0ac2 [file] [log] [blame]
Michael Kolba2b2ba82010-08-04 17:54:03 -07001/*
2 * Copyright (C) 2010 The Android Open Source Project
3 *
Michael Kolb377ea312011-02-17 14:36:56 -08004 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5 * use this file except in compliance with the License. You may obtain a copy of
6 * the License at
Michael Kolba2b2ba82010-08-04 17:54:03 -07007 *
Michael Kolb377ea312011-02-17 14:36:56 -08008 * http://www.apache.org/licenses/LICENSE-2.0
Michael Kolba2b2ba82010-08-04 17:54:03 -07009 *
10 * Unless required by applicable law or agreed to in writing, software
Michael Kolb377ea312011-02-17 14:36:56 -080011 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13 * License for the specific language governing permissions and limitations under
14 * the License.
Michael Kolba2b2ba82010-08-04 17:54:03 -070015 */
16
17package com.android.browser;
18
19import android.content.Context;
Michael Kolb08a687a2011-04-22 16:13:02 -070020import android.graphics.Bitmap;
21import android.graphics.Canvas;
Michael Kolba2b2ba82010-08-04 17:54:03 -070022import android.util.AttributeSet;
Michael Kolb5ee018e2011-02-18 15:47:21 -080023import android.view.MotionEvent;
Michael Kolba2b2ba82010-08-04 17:54:03 -070024import android.view.View;
Michael Kolb2814a362011-05-19 15:49:41 -070025import android.view.ViewConfiguration;
Michael Kolba2b2ba82010-08-04 17:54:03 -070026import android.webkit.WebView;
27
28import java.util.Map;
29
30/**
Michael Kolb377ea312011-02-17 14:36:56 -080031 * Manage WebView scroll events
Michael Kolba2b2ba82010-08-04 17:54:03 -070032 */
John Reckb9a051b2011-03-18 11:55:48 -070033public class BrowserWebView extends WebView implements Runnable {
Michael Kolba2b2ba82010-08-04 17:54:03 -070034
35 private ScrollListener mScrollListener;
36 private boolean mIsCancelled;
Romain Guy860662a2011-01-10 12:57:22 -080037 private boolean mBackgroundRemoved = false;
Michael Kolb5ee018e2011-02-18 15:47:21 -080038 private boolean mUserInitiated = false;
Michael Kolb29ccf8a2011-02-23 16:13:24 -080039 private TitleBarBase mTitleBar;
Michael Kolba4261fd2011-05-05 11:27:37 -070040 private int mCaptureSize;
Michael Kolb08a687a2011-04-22 16:13:02 -070041 private Bitmap mCapture;
Michael Kolb2814a362011-05-19 15:49:41 -070042 private boolean mNavMode;
43 private boolean mTracking;
44 private int mSlop;
45 float mDownX, mDownY;
Michael Kolba2b2ba82010-08-04 17:54:03 -070046
47 /**
48 * @param context
49 * @param attrs
50 * @param defStyle
51 * @param javascriptInterfaces
52 */
John Reckb9a051b2011-03-18 11:55:48 -070053 public BrowserWebView(Context context, AttributeSet attrs, int defStyle,
Michael Kolba2b2ba82010-08-04 17:54:03 -070054 Map<String, Object> javascriptInterfaces, boolean privateBrowsing) {
55 super(context, attrs, defStyle, javascriptInterfaces, privateBrowsing);
56 }
57
58 /**
59 * @param context
60 * @param attrs
61 * @param defStyle
62 */
John Reckb9a051b2011-03-18 11:55:48 -070063 public BrowserWebView(
Michael Kolb377ea312011-02-17 14:36:56 -080064 Context context, AttributeSet attrs, int defStyle, boolean privateBrowsing) {
Michael Kolba2b2ba82010-08-04 17:54:03 -070065 super(context, attrs, defStyle, privateBrowsing);
Michael Kolba4261fd2011-05-05 11:27:37 -070066 init();
Michael Kolba2b2ba82010-08-04 17:54:03 -070067 }
68
69 /**
70 * @param context
71 * @param attrs
72 */
John Reckb9a051b2011-03-18 11:55:48 -070073 public BrowserWebView(Context context, AttributeSet attrs) {
Michael Kolba2b2ba82010-08-04 17:54:03 -070074 super(context, attrs);
Michael Kolba4261fd2011-05-05 11:27:37 -070075 init();
Michael Kolba2b2ba82010-08-04 17:54:03 -070076 }
77
78 /**
79 * @param context
80 */
John Reckb9a051b2011-03-18 11:55:48 -070081 public BrowserWebView(Context context) {
Michael Kolba2b2ba82010-08-04 17:54:03 -070082 super(context);
Michael Kolba4261fd2011-05-05 11:27:37 -070083 init();
Michael Kolba2b2ba82010-08-04 17:54:03 -070084 }
85
Michael Kolba4261fd2011-05-05 11:27:37 -070086 private void init() {
Michael Kolb2814a362011-05-19 15:49:41 -070087 mNavMode = false;
88 mSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
Michael Kolba4261fd2011-05-05 11:27:37 -070089 mCaptureSize = mContext.getResources().getDimensionPixelSize(R.dimen.tab_capture_size);
90 mCapture = Bitmap.createBitmap(mCaptureSize, mCaptureSize,
91 Bitmap.Config.RGB_565);
Michael Kolb08a687a2011-04-22 16:13:02 -070092 }
93
Michael Kolb2814a362011-05-19 15:49:41 -070094 protected void setNavMode(boolean enabled) {
95 mNavMode = enabled;
96 }
97
Michael Kolb08a687a2011-04-22 16:13:02 -070098 @Override
Michael Kolb29ccf8a2011-02-23 16:13:24 -080099 protected int getTitleHeight() {
100 return (mTitleBar != null) ? mTitleBar.getEmbeddedHeight() : 0;
101 }
102
Michael Kolba0e2a752010-12-12 15:27:56 -0800103 // scroll runnable implementation
104 public void run() {
105 if (!mIsCancelled && (mScrollListener != null)) {
Michael Kolb5ee018e2011-02-18 15:47:21 -0800106 mScrollListener.onScroll(getVisibleTitleHeight(), mUserInitiated);
Michael Kolba0e2a752010-12-12 15:27:56 -0800107 }
108 }
109
Michael Kolbed217742010-08-10 17:52:34 -0700110 void hideEmbeddedTitleBar() {
111 scrollBy(0, getVisibleTitleHeight());
112 }
113
Michael Kolba2b2ba82010-08-04 17:54:03 -0700114 @Override
115 public void setEmbeddedTitleBar(final View title) {
116 super.setEmbeddedTitleBar(title);
Michael Kolb29ccf8a2011-02-23 16:13:24 -0800117 mTitleBar = (TitleBarBase) title;
Michael Kolba2b2ba82010-08-04 17:54:03 -0700118 if (title != null && mScrollListener != null) {
119 // allow the scroll listener to initialize its state
Michael Kolba0e2a752010-12-12 15:27:56 -0800120 post(this);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700121 }
122 }
123
Michael Kolb377ea312011-02-17 14:36:56 -0800124 public boolean hasTitleBar() {
125 return (mTitleBar != null);
126 }
127
Michael Kolba2b2ba82010-08-04 17:54:03 -0700128 @Override
Michael Kolb5ee018e2011-02-18 15:47:21 -0800129 public boolean onTouchEvent(MotionEvent evt) {
Michael Kolb2814a362011-05-19 15:49:41 -0700130 if (mNavMode) {
131 if (MotionEvent.ACTION_DOWN == evt.getActionMasked()) {
132 mDownX = evt.getX();
133 mDownY = evt.getY();
134 mTracking = true;
135 return true;
136 } else if (mTracking && MotionEvent.ACTION_MOVE == evt.getActionMasked()) {
137 if (mSlop < Math.abs(evt.getX() - mDownX)
138 || mSlop < Math.abs(evt.getY() - mDownY)) {
139 mTracking = false;
140 }
141 return mTracking;
142 } else if (mTracking && MotionEvent.ACTION_UP == evt.getActionMasked()) {
143 performClick();
144 mTracking = false;
145 return true;
146 } else if (mTracking && MotionEvent.ACTION_CANCEL == evt.getActionMasked()) {
147 mTracking = false;
148 return true;
149 }
150 return super.onTouchEvent(evt);
151 } else {
152 if (MotionEvent.ACTION_DOWN == evt.getActionMasked()) {
153 mUserInitiated = true;
154 } else if (MotionEvent.ACTION_UP == evt.getActionMasked()
155 || (MotionEvent.ACTION_CANCEL == evt.getActionMasked())) {
156 mUserInitiated = false;
157 }
158 return super.onTouchEvent(evt);
Michael Kolb5ee018e2011-02-18 15:47:21 -0800159 }
Michael Kolb5ee018e2011-02-18 15:47:21 -0800160 }
161
162 @Override
Michael Kolba2b2ba82010-08-04 17:54:03 -0700163 public void stopScroll() {
164 mIsCancelled = true;
165 super.stopScroll();
166 }
167
168 @Override
169 protected void onScrollChanged(int l, final int t, int ol, int ot) {
170 super.onScrollChanged(l, t, ol, ot);
171 if (!mIsCancelled) {
Michael Kolba0e2a752010-12-12 15:27:56 -0800172 post(this);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700173 } else {
174 mIsCancelled = false;
175 }
176 }
177
178 void setScrollListener(ScrollListener l) {
179 mScrollListener = l;
Michael Kolba2b2ba82010-08-04 17:54:03 -0700180 }
181
182 // callback for scroll events
183
184 interface ScrollListener {
Michael Kolb5ee018e2011-02-18 15:47:21 -0800185 public void onScroll(int visibleTitleHeight, boolean userInitiated);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700186 }
187
Michael Kolb08a687a2011-04-22 16:13:02 -0700188 protected Bitmap capture() {
189 if (mCapture == null) return null;
190 Canvas c = new Canvas(mCapture);
Michael Kolba4261fd2011-05-05 11:27:37 -0700191 final int left = getScrollX();
192 final int top = getScrollY() + getVisibleTitleHeight();
193 c.translate(-left, -top);
194 float scale = mCaptureSize / (float) Math.max(getWidth(), getHeight());
195 c.scale(scale, scale, left, top);
Michael Kolb08a687a2011-04-22 16:13:02 -0700196 onDraw(c);
197 return mCapture;
198 }
199
Michael Kolb377ea312011-02-17 14:36:56 -0800200 @Override
201 protected void onDraw(android.graphics.Canvas c) {
Michael Kolbf2628922011-03-09 17:15:28 -0800202 super.onDraw(c);
203 if (!mBackgroundRemoved && getRootView().getBackground() != null) {
204 mBackgroundRemoved = true;
205 post(new Runnable() {
206 public void run() {
207 getRootView().setBackgroundDrawable(null);
208 }
209 });
Michael Kolb377ea312011-02-17 14:36:56 -0800210 }
211 }
212
Michael Kolba2b2ba82010-08-04 17:54:03 -0700213}