/WebVox/src/com/marvin/webvox/TitleBar.java
Java | 274 lines | 203 code | 21 blank | 50 comment | 37 complexity | 8174a3335618e22b8a5ab814c8c9d874 MD5 | raw file
1/* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.marvin.webvox; 18 19import com.marvin.webvox.R; 20 21import android.content.Context; 22import android.content.res.Resources; 23import android.graphics.Bitmap; 24import android.graphics.Color; 25import android.graphics.Rect; 26import android.graphics.drawable.Animatable; 27import android.graphics.drawable.BitmapDrawable; 28import android.graphics.drawable.Drawable; 29import android.graphics.drawable.LayerDrawable; 30import android.graphics.drawable.PaintDrawable; 31import android.os.Handler; 32import android.os.Message; 33import android.util.TypedValue; 34import android.view.ContextMenu; 35import android.view.LayoutInflater; 36import android.view.MenuInflater; 37import android.view.MotionEvent; 38import android.view.View; 39import android.view.ViewConfiguration; 40import android.widget.ImageView; 41import android.widget.LinearLayout; 42import android.widget.ProgressBar; 43import android.widget.TextView; 44 45/** 46 * This class represents a title bar for a particular "tab" or "window" in the 47 * browser. 48 */ 49public class TitleBar extends LinearLayout { 50 private TextView mTitle; 51 private Drawable mCloseDrawable; 52 private ImageView mRtButton; 53 private Drawable mCircularProgress; 54 private ProgressBar mHorizontalProgress; 55 private ImageView mFavicon; 56 private ImageView mLockIcon; 57 private Drawable mStopDrawable; 58 private Drawable mBookmarkDrawable; 59 private boolean mInLoad; 60 private BrowserActivity mBrowserActivity; 61 private Drawable mGenericFavicon; 62 private int mIconDimension; 63 private View mTitleBg; 64 private MyHandler mHandler; 65 66 private static int LONG_PRESS = 1; 67 68 public TitleBar(BrowserActivity context) { 69 super(context, null); 70 mHandler = new MyHandler(); 71 LayoutInflater factory = LayoutInflater.from(context); 72 factory.inflate(R.layout.title_bar, this); 73 mBrowserActivity = context; 74 75 mTitle = (TextView) findViewById(R.id.title); 76 mTitle.setCompoundDrawablePadding(5); 77 78 mTitleBg = findViewById(R.id.title_bg); 79 mLockIcon = (ImageView) findViewById(R.id.lock); 80 mFavicon = (ImageView) findViewById(R.id.favicon); 81 82 mRtButton = (ImageView) findViewById(R.id.rt_btn); 83 Resources resources = context.getResources(); 84 85 mCircularProgress = (Drawable) resources.getDrawable( 86 android.R.drawable.progress_indeterminate_horizontal); 87 88 89 mIconDimension = (int) TypedValue.applyDimension( 90 TypedValue.COMPLEX_UNIT_DIP, 20f, 91 resources.getDisplayMetrics()); 92 mCircularProgress.setBounds(0, 0, mIconDimension, mIconDimension); 93 mHorizontalProgress = (ProgressBar) findViewById( 94 R.id.progress_horizontal); 95 mGenericFavicon = context.getResources().getDrawable( 96 R.drawable.app_web_browser_sm); 97 } 98 99 private class MyHandler extends Handler { 100 public void handleMessage(Message msg) { 101 if (msg.what == LONG_PRESS) { 102 // Prevent the normal action from happening by setting the title 103 // bar's state to false. 104 mTitleBg.setPressed(false); 105 // Need to call a special method on BrowserActivity for when the 106 // fake title bar is up, because its ViewGroup does not show a 107 // context menu. 108 mBrowserActivity.showTitleBarContextMenu(); 109 } 110 } 111 }; 112 113 @Override 114 protected void onCreateContextMenu(ContextMenu menu) { 115 MenuInflater inflater = mBrowserActivity.getMenuInflater(); 116 inflater.inflate(R.menu.title_context, menu); 117 } 118 119 @Override 120 public boolean onTouchEvent(MotionEvent event) { 121 switch (event.getAction()) { 122 case MotionEvent.ACTION_DOWN: 123 // Make all touches hit either the textfield or the button, 124 // depending on which side of the right edge of the textfield 125 // they hit. 126 if ((int) event.getX() > mTitleBg.getRight()) { 127 mRtButton.setPressed(true); 128 } else { 129 mTitleBg.setPressed(true); 130 mHandler.sendMessageDelayed(mHandler.obtainMessage( 131 LONG_PRESS), 132 ViewConfiguration.getLongPressTimeout()); 133 } 134 break; 135 case MotionEvent.ACTION_MOVE: 136 int slop = ViewConfiguration.get(mBrowserActivity) 137 .getScaledTouchSlop(); 138 if ((int) event.getY() > getHeight() + slop) { 139 // We only trigger the actions in ACTION_UP if one or the 140 // other is pressed. Since the user moved off the title 141 // bar, mark both as not pressed. 142 mTitleBg.setPressed(false); 143 mRtButton.setPressed(false); 144 mHandler.removeMessages(LONG_PRESS); 145 break; 146 } 147 int x = (int) event.getX(); 148 int titleRight = mTitleBg.getRight(); 149 if (mTitleBg.isPressed() && x > titleRight + slop) { 150 mTitleBg.setPressed(false); 151 mHandler.removeMessages(LONG_PRESS); 152 } else if (mRtButton.isPressed() && x < titleRight - slop) { 153 mRtButton.setPressed(false); 154 } 155 break; 156 case MotionEvent.ACTION_CANCEL: 157 mRtButton.setPressed(false); 158 mTitleBg.setPressed(false); 159 mHandler.removeMessages(LONG_PRESS); 160 break; 161 case MotionEvent.ACTION_UP: 162 if (mRtButton.isPressed()) { 163 if (mInLoad) { 164 mBrowserActivity.stopLoading(); 165 } else { 166 mBrowserActivity.bookmarksOrHistoryPicker(false); 167 } 168 mRtButton.setPressed(false); 169 } else if (mTitleBg.isPressed()) { 170 mHandler.removeMessages(LONG_PRESS); 171 mBrowserActivity.onSearchRequested(); 172 mTitleBg.setPressed(false); 173 } 174 break; 175 default: 176 break; 177 } 178 return true; 179 } 180 181 /** 182 * Return whether the associated WebView is currently loading. Needed to 183 * determine whether a click should stop the load or close the tab. 184 */ 185 /* package */ boolean isInLoad() { 186 return mInLoad; 187 } 188 189 /** 190 * Set a new Bitmap for the Favicon. 191 */ 192 /* package */ void setFavicon(Bitmap icon) { 193 Drawable[] array = new Drawable[3]; 194 array[0] = new PaintDrawable(Color.BLACK); 195 PaintDrawable p = new PaintDrawable(Color.WHITE); 196 array[1] = p; 197 if (icon == null) { 198 array[2] = mGenericFavicon; 199 } else { 200 array[2] = new BitmapDrawable(icon); 201 } 202 LayerDrawable d = new LayerDrawable(array); 203 d.setLayerInset(1, 1, 1, 1, 1); 204 d.setLayerInset(2, 2, 2, 2, 2); 205 mFavicon.setImageDrawable(d); 206 } 207 208 /** 209 * Set the Drawable for the lock icon, or null to hide it. 210 */ 211 /* package */ void setLock(Drawable d) { 212 if (null == d) { 213 mLockIcon.setVisibility(View.GONE); 214 } else { 215 mLockIcon.setImageDrawable(d); 216 mLockIcon.setVisibility(View.VISIBLE); 217 } 218 } 219 220 /** 221 * Update the progress, from 0 to 100. 222 */ 223 /* package */ void setProgress(int newProgress) { 224 if (newProgress >= mHorizontalProgress.getMax()) { 225 mTitle.setCompoundDrawables(null, null, null, null); 226 ((Animatable) mCircularProgress).stop(); 227 mHorizontalProgress.setVisibility(View.INVISIBLE); 228 if (mBookmarkDrawable != null) { 229 mRtButton.setImageDrawable(mBookmarkDrawable); 230 } 231 mInLoad = false; 232 } else { 233 mHorizontalProgress.setProgress(newProgress); 234 if (!mInLoad && getWindowToken() != null) { 235 // checking the window token lets us be sure that we 236 // are attached to a window before starting the animation, 237 // preventing a potential race condition 238 // (fix for bug http://b/2115736) 239 mTitle.setCompoundDrawables(null, null, mCircularProgress, 240 null); 241 ((Animatable) mCircularProgress).start(); 242 mHorizontalProgress.setVisibility(View.VISIBLE); 243 if (mBookmarkDrawable == null) { 244 mBookmarkDrawable = mRtButton.getDrawable(); 245 } 246 if (mStopDrawable == null) { 247 mRtButton.setImageResource(R.drawable.ic_btn_stop_v2); 248 mStopDrawable = mRtButton.getDrawable(); 249 } else { 250 mRtButton.setImageDrawable(mStopDrawable); 251 } 252 mInLoad = true; 253 } 254 } 255 } 256 257 /** 258 * Update the title and url. 259 */ 260 /* package */ void setTitleAndUrl(CharSequence title, CharSequence url) { 261 if (url == null) { 262 mTitle.setText(R.string.title_bar_loading); 263 } else { 264 mTitle.setText(url.toString()); 265 } 266 } 267 268 /* package */ void setToTabPicker() { 269 mTitle.setText(R.string.tab_picker_title); 270 setFavicon(null); 271 setLock(null); 272 mHorizontalProgress.setVisibility(View.GONE); 273 } 274}