/WebVox/src/com/marvin/webvox/TitleBar.java

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