blob: da18614312028f35efedf4144f6a3a11c44a58ba [file] [log] [blame]
Michael Kolba2b2ba82010-08-04 17:54:03 -07001/*
2 * Copyright (C) 2010 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.android.browser;
18
19import android.content.Context;
20import android.content.res.Resources;
21import android.graphics.Bitmap;
22import android.graphics.Color;
23import android.graphics.drawable.BitmapDrawable;
24import android.graphics.drawable.Drawable;
25import android.graphics.drawable.LayerDrawable;
26import android.graphics.drawable.PaintDrawable;
27import android.view.ContextMenu;
28import android.view.LayoutInflater;
29import android.view.MenuInflater;
30import android.view.View;
31import android.view.View.OnClickListener;
32import android.webkit.WebView;
33import android.widget.ImageView;
34import android.widget.LinearLayout;
35import android.widget.TextView;
36
37import com.android.browser.ScrollWebView.ScrollListener;
38import com.android.browser.TabControl.TabChangeListener;
39
40import java.util.HashMap;
41import java.util.Map;
42
43/**
44 * tabbed title bar for xlarge screen browser
45 */
46public class TabBar extends LinearLayout
47 implements TabChangeListener, ScrollListener, OnClickListener {
48
49 private static final int PROGRESS_MAX = 100;
50
51 private static final int TAB_WIDTH_SELECTED = 300;
52 private static final int TAB_WIDTH_UNSELECTED = 300;
53
54 private BrowserActivity mBrowserActivity;
55
56 private final float mTabWidthSelected;
57 private final float mTabWidthUnselected;
58
59 private TitleBarXLarge mTitleBar;
60
61 private TabScrollView mTabs;
62 private View mNewButton;
63 private View mShowUrlButton;
64 private TabControl mControl;
65
66 private Map<Tab, TabViewData> mTabMap;
67
68 private float mDensityScale;
69 private boolean mUserRequestedUrlbar;
70 private boolean mTitleVisible;
71
72 public TabBar(BrowserActivity context, TabControl tabcontrol, TitleBarXLarge titlebar) {
73 super(context);
74 Resources res = context.getResources();
75 mTabWidthSelected = res.getDimension(R.dimen.tab_width_selected);
76 mTabWidthUnselected = res.getDimension(R.dimen.tab_width_unselected);
77
78 mTitleBar = titlebar;
79 mTitleBar.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT,
80 LayoutParams.WRAP_CONTENT));
81 mDensityScale = context.getResources().getDisplayMetrics().density;
82 mTabMap = new HashMap<Tab, TabViewData>();
83 mBrowserActivity = context;
84 mControl = tabcontrol;
85 Resources resources = context.getResources();
86 LayoutInflater factory = LayoutInflater.from(context);
87 factory.inflate(R.layout.tab_bar, this);
88 mTabs = (TabScrollView) findViewById(R.id.tabs);
89 mNewButton = findViewById(R.id.newtab);
90 mShowUrlButton = findViewById(R.id.showurl);
91
92 // TODO: Change enabled states based on whether you can go
93 // back/forward. Probably should be done inside onPageStarted.
94
95 mNewButton.setOnClickListener(this);
96 mShowUrlButton.setOnClickListener(this);
97
98 // build tabs
99 int tabcount = mControl.getTabCount();
100 for (int i = 0; i < tabcount; i++) {
101 Tab tab = mControl.getTab(i);
102 TabViewData data = buildTab(tab);
103 TabView tv = buildView(data);
104 }
105 mTabs.setSelectedTab(mControl.getCurrentIndex());
106
107 // register the tab change listener
108 mControl.setOnTabChangeListener(this);
109 mUserRequestedUrlbar = false;
110 mTitleVisible = true;
111 }
112
113 public void onClick(View view) {
114 if (mShowUrlButton == view) {
115 mBrowserActivity.stopScrolling();
116 mBrowserActivity.showFakeTitleBar();
117 mUserRequestedUrlbar = true;
118 } else if (mNewButton == view) {
Michael Kolb68792c82010-08-09 16:39:18 -0700119 mBrowserActivity.bookmarksOrHistoryPicker(false, true);
Michael Kolba2b2ba82010-08-04 17:54:03 -0700120 } else if (mTabs.getSelectedTab() == view) {
121 mBrowserActivity.showFakeTitleBar();
122 mTitleBar.requestUrlInputFocus();
123 } else {
124 TabViewData data = (TabViewData) view.getTag();
125 int ix = mControl.getTabIndex(data.mTab);
126 mTabs.setSelectedTab(ix);
127 mBrowserActivity.switchToTab(ix);
128 }
129 }
130
131 void onShowTitleBar() {
132 mShowUrlButton.setVisibility(View.INVISIBLE);
133 }
134
135 void onHideTitleBar() {
136 mShowUrlButton.setVisibility(mTitleVisible ? View.INVISIBLE : View.VISIBLE);
137 Tab tab = mControl.getCurrentTab();
138 tab.getWebView().requestFocus();
139 mUserRequestedUrlbar = false;
140 }
141
142 // UrlInputListener implementation
143
144 @Override
145 public void createContextMenu(ContextMenu menu) {
146 MenuInflater inflater = mBrowserActivity.getMenuInflater();
147 inflater.inflate(R.menu.title_context, menu);
148 mBrowserActivity.onCreateContextMenu(menu, this, null);
149 }
150
151 private TabViewData buildTab(Tab tab) {
152 TabViewData data = new TabViewData(tab);
153 mTabMap.put(tab, data);
154 return data;
155 }
156
157 private TabView buildView(final TabViewData data) {
158 TabView tv = new TabView(mBrowserActivity, data);
159 tv.setTag(data);
160 tv.setOnClickListener(this);
161 mTabs.addTab(tv);
162 return tv;
163 }
164
165 /**
166 * View used in the tab bar
167 */
168 class TabView extends LinearLayout implements OnClickListener {
169
170 TabViewData mTabData;
171 View mTabContent;
172 TextView mTitle;
173 ImageView mIconView;
174 ImageView mLock;
175 ImageView mClose;
176 boolean mSelected;
177 boolean mInLoad;
178
179 /**
180 * @param context
181 */
182 public TabView(Context context, TabViewData tab) {
183 super(context);
184 mTabData = tab;
185 LayoutInflater inflater = LayoutInflater.from(mContext);
186 mTabContent = inflater.inflate(R.layout.tab_title, this);
187 mTitle = (TextView) mTabContent.findViewById(R.id.title);
188 mIconView = (ImageView) mTabContent.findViewById(R.id.favicon);
189 mLock = (ImageView) mTabContent.findViewById(R.id.lock);
190 mClose = (ImageView) mTabContent.findViewById(R.id.close);
191 mClose.setOnClickListener(this);
192 mSelected = false;
193 mInLoad = false;
194 // update the status
195 updateFromData();
196 }
197
198 @Override
199 public void onClick(View v) {
200 if (v == mClose) {
201 closeTab();
202 }
203 }
204
205 private void updateFromData() {
206 mTabData.mTabView = this;
207 if (mTabData.mUrl != null) {
208 setDisplayTitle(mTabData.mUrl);
209 }
210 if (mTabData.mTitle != null) {
211 setDisplayTitle(mTabData.mTitle);
212 }
213 setProgress(mTabData.mProgress);
214 if (mTabData.mIcon != null) {
215 setFavicon(mTabData.mIcon);
216 }
217 if (mTabData.mLock != null) {
218 setLock(mTabData.mLock);
219 }
220 }
221
222 @Override
223 public void setSelected(boolean selected) {
224 mSelected = selected;
225 mClose.setVisibility(mSelected ? View.VISIBLE : View.GONE);
226 mTitle.setTextColor(mSelected ? Color.BLACK : Color.GRAY);
227 super.setSelected(selected);
228 setLayoutParams(new LayoutParams(selected ?
229 (int) (TAB_WIDTH_SELECTED * mDensityScale)
230 : (int) (TAB_WIDTH_UNSELECTED * mDensityScale),
231 LayoutParams.MATCH_PARENT));
232 }
233
234 void setDisplayTitle(String title) {
235 mTitle.setText(title);
236 }
237
238 void setFavicon(Drawable d) {
239 mIconView.setImageDrawable(d);
240 }
241
242 void setLock(Drawable d) {
243 if (null == d) {
244 mLock.setVisibility(View.GONE);
245 } else {
246 mLock.setImageDrawable(d);
247 mLock.setVisibility(View.VISIBLE);
248 }
249 }
250
251 void setTitleCompoundDrawables(Drawable left, Drawable top,
252 Drawable right, Drawable bottom) {
253 mTitle.setCompoundDrawables(left, top, right, bottom);
254 }
255
256 void setProgress(int newProgress) {
257 if (newProgress >= PROGRESS_MAX) {
258 mInLoad = false;
259 } else {
260 if (!mInLoad && getWindowToken() != null) {
261 mInLoad = true;
262 }
263 }
264 }
265
266 private void closeTab() {
267 if (mTabData.mTab == mControl.getCurrentTab()) {
268 mBrowserActivity.closeCurrentWindow();
269 } else {
270 mBrowserActivity.closeTab(mTabData.mTab);
271 }
272 }
273
274 }
275
276 /**
277 * Store tab state within the title bar
278 */
279 class TabViewData {
280
281 Tab mTab;
282 TabView mTabView;
283 int mProgress;
284 Drawable mIcon;
285 Drawable mLock;
286 String mTitle;
287 String mUrl;
288
289 TabViewData(Tab tab) {
290 mTab = tab;
291 }
292
293 void setUrlAndTitle(String url, String title) {
294 mUrl = url;
295 mTitle = title;
296 if (mTabView != null) {
297 if (title != null) {
298 mTabView.setDisplayTitle(title);
299 } else if (url != null) {
300 mTabView.setDisplayTitle(url);
301 }
302 }
303 }
304
305 void setProgress(int newProgress) {
306 mProgress = newProgress;
307 if (mTabView != null) {
308 mTabView.setProgress(mProgress);
309 }
310 }
311
312 void setFavicon(Bitmap icon) {
313 Drawable[] array = new Drawable[3];
314 array[0] = new PaintDrawable(Color.BLACK);
315 array[1] = new PaintDrawable(Color.WHITE);
316 if (icon == null) {
317// array[2] = mGenericFavicon;
318 } else {
319 array[2] = new BitmapDrawable(icon);
320 }
321 LayerDrawable d = new LayerDrawable(array);
322 d.setLayerInset(1, 1, 1, 1, 1);
323 d.setLayerInset(2, 2, 2, 2, 2);
324 mIcon = d;
325 if (mTabView != null) {
326 mTabView.setFavicon(mIcon);
327 }
328 }
329
330 }
331
332 // TabChangeListener implementation
333
334 @Override
335 public void onCurrentTab(Tab tab) {
336 mTabs.setSelectedTab(mControl.getCurrentIndex());
337 TabViewData tvd = mTabMap.get(tab);
338 if (tvd != null) {
339 tvd.setProgress(tvd.mProgress);
340 // update the scroll state
341 WebView webview = tab.getWebView();
342 onScroll(webview.getVisibleTitleHeight() > 0);
343 }
344 }
345
346 @Override
347 public void onFavicon(Tab tab, Bitmap favicon) {
348 TabViewData tvd = mTabMap.get(tab);
349 if (tvd != null) {
350 tvd.setFavicon(favicon);
351 }
352 }
353
354 @Override
355 public void onNewTab(Tab tab) {
356 TabViewData tvd = buildTab(tab);
357 buildView(tvd);
358 mShowUrlButton.setVisibility(View.INVISIBLE);
359 }
360
361 @Override
362 public void onProgress(Tab tab, int progress) {
363 TabViewData tvd = mTabMap.get(tab);
364 if (tvd != null) {
365 tvd.setProgress(progress);
366 }
367 }
368
369 @Override
370 public void onRemoveTab(Tab tab) {
371 TabViewData tvd = mTabMap.get(tab);
372 TabView tv = tvd.mTabView;
373 if (tv != null) {
374 mTabs.removeTab(tv);
375 }
376 mTabMap.remove(tab);
377 }
378
379 @Override
380 public void onUrlAndTitle(Tab tab, String url, String title) {
381 TabViewData tvd = mTabMap.get(tab);
382 if (tvd != null) {
383 tvd.setUrlAndTitle(url, title);
384 }
385 }
386
387 @Override
388 public void onPageFinished(Tab tab) {
389 }
390
391 @Override
392 public void onPageStarted(Tab tab) {
393 }
394
395
396 private boolean isLoading() {
397 return mTabMap.get(mControl.getCurrentTab()).mTabView.mInLoad;
398 }
399
400 // webview scroll listener
401
402 @Override
403 public void onScroll(boolean titleVisible) {
404 mTitleVisible = titleVisible;
405 boolean buttonVisible = (mShowUrlButton.getVisibility() == View.VISIBLE);
406 if (!buttonVisible && !mTitleVisible && !isLoading()) {
407 mShowUrlButton.setVisibility(View.VISIBLE);
408 if (mUserRequestedUrlbar) {
409 mBrowserActivity.hideFakeTitleBar();
410 }
411 } else if (mTitleVisible && !isLoading()) {
412 mShowUrlButton.setVisibility(View.INVISIBLE);
413 }
414 }
415
416}