OSDN Git Service

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