blob: a5090fa3eab05215c81183706f0edc5388494eed [file] [log] [blame]
Michael Kolbf2055602011-04-09 17:20:03 -07001/*
2 * Copyright (C) 2011 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.app.Activity;
20import android.content.Context;
Michael Kolba4261fd2011-05-05 11:27:37 -070021import android.content.res.Configuration;
Michael Kolbf2055602011-04-09 17:20:03 -070022import android.graphics.Bitmap;
Michael Kolba4261fd2011-05-05 11:27:37 -070023import android.graphics.Matrix;
Michael Kolbf2055602011-04-09 17:20:03 -070024import android.view.LayoutInflater;
25import android.view.Menu;
26import android.view.MenuItem;
27import android.view.View;
28import android.view.View.OnClickListener;
29import android.view.ViewGroup;
30import android.webkit.WebView;
31import android.widget.AdapterView;
32import android.widget.AdapterView.OnItemClickListener;
33import android.widget.AdapterView.OnItemSelectedListener;
34import android.widget.BaseAdapter;
35import android.widget.FrameLayout;
Michael Kolba4261fd2011-05-05 11:27:37 -070036import android.widget.FrameLayout.LayoutParams;
Michael Kolbf2055602011-04-09 17:20:03 -070037import android.widget.Gallery;
38import android.widget.ImageButton;
39import android.widget.ImageView;
Michael Kolba4261fd2011-05-05 11:27:37 -070040import android.widget.ImageView.ScaleType;
Michael Kolbf2055602011-04-09 17:20:03 -070041import android.widget.LinearLayout;
42import android.widget.ListPopupWindow;
43import android.widget.TextView;
44
45import java.util.ArrayList;
46import java.util.List;
47
48public class NavScreen extends LinearLayout implements OnClickListener {
49
50 UiController mUiController;
51 PhoneUi mUi;
52 Tab mTab;
53 Activity mActivity;
54
55 View mTopPanel;
56 ImageButton mBack;
57 ImageButton mRefresh;
58 ImageButton mForward;
59 ImageButton mTabs;
60 ImageButton mBookmarks;
61 ImageButton mMore;
62 ImageButton mNewTab;
63 ImageButton mNewIncognito;
64 FrameLayout mHolder;
65
66 Gallery mFlipper;
Michael Kolba4261fd2011-05-05 11:27:37 -070067 float mTabAspect = 0.66f;
Michael Kolbf2055602011-04-09 17:20:03 -070068 int mTabWidth;
69 int mTabHeight;
70 TabAdapter mAdapter;
71 ListPopupWindow mPopup;
Michael Kolba4261fd2011-05-05 11:27:37 -070072 int mOrientation;
Michael Kolbf2055602011-04-09 17:20:03 -070073
74 public NavScreen(Activity activity, UiController ctl, PhoneUi ui) {
75 super(activity);
76 mActivity = activity;
77 mUiController = ctl;
78 mUi = ui;
Michael Kolba4261fd2011-05-05 11:27:37 -070079 mOrientation = activity.getResources().getConfiguration().orientation;
Michael Kolbf2055602011-04-09 17:20:03 -070080 init();
81 }
82
Michael Kolba4261fd2011-05-05 11:27:37 -070083 @Override
84 public void onMeasure(int wspec, int hspec) {
85 super.onMeasure(wspec, hspec);
86 mTabHeight = mFlipper.getMeasuredHeight();
87 mTabWidth = (int) (mTabHeight * mTabAspect);
88 if (mAdapter != null) {
89 mAdapter.notifyDataSetChanged();
90 }
91 }
92
Michael Kolbf2055602011-04-09 17:20:03 -070093 protected Tab getSelectedTab() {
94 return (Tab) mFlipper.getSelectedItem();
95 }
96
Michael Kolbfedb4922011-04-20 16:45:33 -070097 protected void showMenu() {
98 Menu menu = mUi.getMenu();
99 menu.setGroupVisible(R.id.NAV_MENU, false);
100
Michael Kolbf2055602011-04-09 17:20:03 -0700101 MenuAdapter menuAdapter = new MenuAdapter(mContext);
102 menuAdapter.setMenu(menu);
103 ListPopupWindow popup = new ListPopupWindow(mContext);
104 popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
105 popup.setAdapter(menuAdapter);
106 popup.setModal(true);
107 popup.setAnchorView(mMore);
108 popup.setWidth((int) mContext.getResources().getDimension(
109 R.dimen.menu_width));
110 popup.show();
111 mPopup = popup;
112 }
113
John Reckadc921f2011-04-27 10:11:03 -0700114 protected float getToolbarHeight() {
115 return mActivity.getResources().getDimension(R.dimen.toolbar_height);
116 }
117
Michael Kolbf2055602011-04-09 17:20:03 -0700118 protected void dismissMenu() {
119 if (mPopup != null) {
120 mPopup.dismiss();
121 }
122 }
123
Michael Kolba4261fd2011-05-05 11:27:37 -0700124 // for configuration changes
125 @Override
126 protected void onConfigurationChanged(Configuration newconfig) {
127 if (newconfig.orientation != mOrientation) {
128 int selIx = mFlipper.getSelectedItemPosition();
129 removeAllViews();
130 init();
131 mFlipper.setSelection(selIx);
132 mOrientation = newconfig.orientation;
133 }
134 }
135
Michael Kolbf2055602011-04-09 17:20:03 -0700136 private void init() {
137 LayoutInflater.from(mContext).inflate(R.layout.nav_screen, this);
138 LinearLayout content = (LinearLayout) findViewById(R.id.nav_screen);
139 mTopPanel = findViewById(R.id.navtop);
140 mBack = (ImageButton) findViewById(R.id.back);
141 mForward = (ImageButton) findViewById(R.id.forward);
142 mRefresh = (ImageButton) findViewById(R.id.refresh);
143 mTabs = (ImageButton) findViewById(R.id.tabs);
144 mBookmarks = (ImageButton) findViewById(R.id.bookmarks);
145 mNewTab = (ImageButton) findViewById(R.id.newtab);
146 mNewIncognito = (ImageButton) findViewById(R.id.newincognito);
147 mMore = (ImageButton) findViewById(R.id.more);
148 mBack.setOnClickListener(this);
149 mForward.setOnClickListener(this);
150 mRefresh.setOnClickListener(this);
151 mTabs.setOnClickListener(this);
152 mBookmarks.setOnClickListener(this);
153 mNewTab.setOnClickListener(this);
154 mNewIncognito.setOnClickListener(this);
155 mMore.setOnClickListener(this);
156 mHolder = (FrameLayout) findViewById(R.id.galleryholder);
157 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
158 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
159 mFlipper = new TabGallery(mContext);
160 mFlipper.setSpacing((int)(mContext.getResources()
161 .getDimension(R.dimen.nav_tab_spacing)));
Michael Kolba4261fd2011-05-05 11:27:37 -0700162 mFlipper.setUnselectedAlpha(0.8f);
Michael Kolbf2055602011-04-09 17:20:03 -0700163 mFlipper.setLayoutParams(lp);
164 mHolder.addView(mFlipper, 0);
165 mAdapter = new TabAdapter(mContext, mUiController.getTabControl());
166 mFlipper.setAdapter(mAdapter);
167 setTab(mUi.getActiveTab(), true);
168 mFlipper.setOnItemClickListener(new OnItemClickListener() {
169 @Override
170 public void onItemClick(AdapterView<?> parent, View view,
171 int position, long id) {
172 // post as runnable to prevent bug in gesturedetector
173 // when view is removed in click handler
174 // sends action_cancel before action_up
175 mFlipper.post(new Runnable() {
176 public void run() {
177 close();
178 }
179 });
180 }
181 });
182 mFlipper.setOnItemSelectedListener(new OnItemSelectedListener() {
183 @Override
184 public void onItemSelected(AdapterView<?> parent, View view,
185 int position, long id) {
186 final Tab tab = mAdapter.getItem(position);
187 setTab(tab, false);
188 }
189
190 @Override
191 public void onNothingSelected(AdapterView<?> parent) {
192 }
193 });
194 }
195
196 private void setTab(Tab tab, boolean updateFlipper) {
197 mTab = tab;
198 // refresh state from tab
199 WebView web = tab.getWebView();
200 if (web != null) {
201 mBack.setImageResource(web.canGoBack()
202 ? R.drawable.ic_back_holo_dark
203 : R.drawable.ic_back_disabled_holo_dark);
204 mForward.setImageResource(web.canGoForward()
205 ? R.drawable.ic_forward_holo_dark
206 : R.drawable.ic_forward_disabled_holo_dark);
207 }
208 if (updateFlipper) {
Michael Kolbc831b632011-05-11 09:30:34 -0700209 mFlipper.setSelection(mUiController.getTabControl().getTabPosition(tab));
Michael Kolbf2055602011-04-09 17:20:03 -0700210 }
211 }
212
213 @Override
214 public void onClick(View v) {
215 WebView web = (mTab != null) ? mTab.getWebView() : null;
216 if (web != null) {
217 if (mBack == v) {
218 mUi.hideNavScreen(true);
Michael Kolba4261fd2011-05-05 11:27:37 -0700219 switchToSelected();
Michael Kolbf2055602011-04-09 17:20:03 -0700220 web.goBack();
221 } else if (mForward == v) {
222 mUi.hideNavScreen(true);
Michael Kolba4261fd2011-05-05 11:27:37 -0700223 switchToSelected();
Michael Kolbf2055602011-04-09 17:20:03 -0700224 web.goForward();
225 } else if (mRefresh == v) {
226 mUi.hideNavScreen(true);
Michael Kolba4261fd2011-05-05 11:27:37 -0700227 switchToSelected();
Michael Kolbf2055602011-04-09 17:20:03 -0700228 web.reload();
229 }
230 }
231 if (mBookmarks == v) {
232 mUi.hideNavScreen(false);
Michael Kolba4261fd2011-05-05 11:27:37 -0700233 switchToSelected();
Michael Kolbf2055602011-04-09 17:20:03 -0700234 mUiController.bookmarksOrHistoryPicker(false);
235 } else if (mTabs == v) {
Michael Kolbf2055602011-04-09 17:20:03 -0700236 } else if (mNewTab == v) {
Michael Kolba4261fd2011-05-05 11:27:37 -0700237 openNewTab();
Michael Kolbf2055602011-04-09 17:20:03 -0700238 } else if (mMore == v) {
Michael Kolbfedb4922011-04-20 16:45:33 -0700239 showMenu();
Michael Kolbf2055602011-04-09 17:20:03 -0700240 } else if (mNewIncognito == v) {
241 mUi.hideNavScreen(true);
Michael Kolb519d2282011-05-09 17:03:19 -0700242 mUiController.openIncognitoTab();
Michael Kolbf2055602011-04-09 17:20:03 -0700243 }
244 }
245
Michael Kolba4261fd2011-05-05 11:27:37 -0700246 private void openNewTab() {
Michael Kolb7bcafde2011-05-09 13:55:59 -0700247 Tab tab = mUiController.openTabToHomePage();
Michael Kolba4261fd2011-05-05 11:27:37 -0700248 mAdapter.notifyDataSetChanged();
249
250 if (tab != null) {
251 // set tab as the selected in flipper, then hide
Michael Kolbc831b632011-05-11 09:30:34 -0700252 final int tix = mUi.mTabControl.getTabPosition(tab);
Michael Kolba4261fd2011-05-05 11:27:37 -0700253 post(new Runnable() {
254 public void run() {
255 if (tix != -1) {
256 for (int i = mFlipper.getSelectedItemPosition();
257 i <= tix; i++) {
258 mFlipper.setSelection(i, true);
259 mFlipper.invalidate();
260 try {
261 Thread.sleep(100);
262 } catch (InterruptedException e) {
263 e.printStackTrace();
264 }
265 }
266 }
267 mUi.hideNavScreen(true);
268 switchToSelected();
269 }
270 });
271 }
272 }
273
274 private void switchToSelected() {
275 Tab tab = (Tab) mFlipper.getSelectedItem();
276 if (tab != mUi.getActiveTab()) {
277 mUiController.setActiveTab(tab);
278 }
279 }
280
Michael Kolbf2055602011-04-09 17:20:03 -0700281 protected void close() {
282 close(true);
283 }
284
285 protected void close(boolean animate) {
286 mUi.hideNavScreen(animate);
Michael Kolba4261fd2011-05-05 11:27:37 -0700287 switchToSelected();
Michael Kolbf2055602011-04-09 17:20:03 -0700288 }
289
290 class TabGallery extends Gallery {
291
292 public TabGallery(Context ctx) {
293 super(ctx);
294 setUnselectedAlpha(0.3f);
295 }
296
297 @Override
298 protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
299 return new Gallery.LayoutParams(
300 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
301 }
302
303 @Override
304 protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
305 return generateDefaultLayoutParams();
306 }
307
308 }
309
310 class TabAdapter extends BaseAdapter {
311
312 Context context;
313 TabControl tabControl;
314
315 public TabAdapter(Context ctx, TabControl tc) {
316 context = ctx;
317 tabControl = tc;
318 }
319
320 void onCloseTab(Tab tab) {
321 if (tab != null) {
322 mUiController.closeTab(tab);
323 if (tabControl.getTabCount() == 0) {
324 mUiController.openTabToHomePage();
325 mUi.hideNavScreen(false);
326 } else {
327 notifyDataSetChanged();
328 }
329 }
330 }
331
332 @Override
333 public int getCount() {
334 return tabControl.getTabCount();
335 }
336
337 @Override
338 public Tab getItem(int position) {
339 return tabControl.getTab(position);
340 }
341
342 public long getItemId(int position) {
343 return position;
344 }
345
346 @Override
347 public View getView(int position, View convertView, ViewGroup parent) {
348 ImageView content = null;
349 if (convertView == null) {
350 convertView = LayoutInflater.from(context).inflate(R.layout.nav_tab_view,
351 null);
352 content = (ImageView) convertView.findViewById(R.id.content);
353 content.setLayoutParams(new LayoutParams(mTabWidth, mTabHeight));
354 } else {
355 content = (ImageView) convertView.findViewById(R.id.content);
Michael Kolba4261fd2011-05-05 11:27:37 -0700356 content.setLayoutParams(new LayoutParams(mTabWidth, mTabHeight));
Michael Kolbf2055602011-04-09 17:20:03 -0700357 }
Michael Kolb5a4372f2011-04-29 13:53:10 -0700358 View tbar = convertView.findViewById(R.id.titlebar);
Michael Kolbf2055602011-04-09 17:20:03 -0700359 TextView title = (TextView) convertView.findViewById(R.id.title);
360 ImageView icon = (ImageView) convertView.findViewById(R.id.favicon);
361 ImageButton close = (ImageButton) convertView.findViewById(R.id.closetab);
362 final Tab tab = getItem(position);
Michael Kolb5a4372f2011-04-29 13:53:10 -0700363 icon.setImageDrawable(mUi.getFaviconDrawable(tab.getFavicon()));
Michael Kolbf2055602011-04-09 17:20:03 -0700364 title.setText(tab.getUrl());
Michael Kolba4261fd2011-05-05 11:27:37 -0700365 content.setScaleType(ScaleType.MATRIX);
366 Matrix matrix = new Matrix();
Michael Kolbf2055602011-04-09 17:20:03 -0700367 Bitmap screen = tab.getScreenshot();
Michael Kolba4261fd2011-05-05 11:27:37 -0700368 if (screen != null) {
369 float scale = 1.0f;
370 if (mTabWidth > mTabHeight) {
371 scale = mTabWidth / (float) screen.getWidth();
372 } else {
373 scale = mTabHeight / (float) screen.getHeight();
374 }
375 matrix.setScale(scale, scale);
376 content.setImageMatrix(matrix);
377 content.setImageBitmap(screen);
378 }
Michael Kolbf2055602011-04-09 17:20:03 -0700379 close.setOnClickListener(new OnClickListener() {
380 @Override
381 public void onClick(View v) {
382 onCloseTab(tab);
383 }
384 });
Michael Kolb5a4372f2011-04-29 13:53:10 -0700385 tbar.setOnClickListener(new OnClickListener() {
Michael Kolbf2055602011-04-09 17:20:03 -0700386 @Override
387 public void onClick(View v) {
388 close(false);
Michael Kolbff6c36b2011-05-04 14:21:34 -0700389 mUi.getTitleBar().setSkipTitleBarAnimations(true);
Michael Kolbf2055602011-04-09 17:20:03 -0700390 mUi.editUrl(false);
Michael Kolbff6c36b2011-05-04 14:21:34 -0700391 mUi.getTitleBar().setSkipTitleBarAnimations(false);
Michael Kolbf2055602011-04-09 17:20:03 -0700392 }
393 });
394 return convertView;
395 }
396 }
397
398 private class MenuAdapter extends BaseAdapter implements OnClickListener {
399
400 List<MenuItem> mItems;
401 LayoutInflater mInflater;
402
403 public MenuAdapter(Context ctx) {
404 mInflater = LayoutInflater.from(ctx);
405 mItems = new ArrayList<MenuItem>();
406 }
407
408 public void setMenu(Menu menu) {
409 mItems.clear();
410 for (int i = 0; i < menu.size(); i++) {
411 MenuItem item = menu.getItem(i);
412 if (item.isEnabled() && item.isVisible()) {
413 mItems.add(item);
414 }
415 }
416 notifyDataSetChanged();
417 }
418
419 @Override
420 public int getCount() {
421 return mItems.size();
422 }
423
424 @Override
425 public MenuItem getItem(int position) {
426 return mItems.get(position);
427 }
428
429 @Override
430 public long getItemId(int position) {
431 return position;
432 }
433
434 @Override
435 public void onClick(View v) {
436 if (v.getTag() != null) {
437 dismissMenu();
438 mActivity.closeOptionsMenu();
439 mUi.hideNavScreen(false);
440 mUiController.onOptionsItemSelected((MenuItem) v.getTag());
441 }
442 }
443
444 @Override
445 public View getView(int position, View convertView, ViewGroup parent) {
446 final MenuItem item = mItems.get(position);
447 View view = mInflater.inflate(R.layout.qc_menu_item, null);
448 TextView label = (TextView) view.findViewById(R.id.title);
449 label.setText(item.getTitle());
450 label.setTag(item);
451 label.setOnClickListener(this);
452 return label;
453 }
454
455 }
456
457}