blob: 8cc2271c738be1830330c99173ea3ead2d04558d [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;
21import android.graphics.Bitmap;
22import android.view.LayoutInflater;
23import android.view.Menu;
24import android.view.MenuItem;
25import android.view.View;
26import android.view.View.OnClickListener;
27import android.view.ViewGroup;
28import android.webkit.WebView;
29import android.widget.AdapterView;
30import android.widget.AdapterView.OnItemClickListener;
31import android.widget.AdapterView.OnItemSelectedListener;
32import android.widget.BaseAdapter;
33import android.widget.FrameLayout;
34import android.widget.Gallery;
35import android.widget.ImageButton;
36import android.widget.ImageView;
Michael Kolbf2055602011-04-09 17:20:03 -070037import android.widget.LinearLayout;
38import android.widget.ListPopupWindow;
39import android.widget.TextView;
40
41import java.util.ArrayList;
42import java.util.List;
Michael Kolb08a687a2011-04-22 16:13:02 -070043import java.util.concurrent.Semaphore;
Michael Kolbf2055602011-04-09 17:20:03 -070044
45public class NavScreen extends LinearLayout implements OnClickListener {
46
47 UiController mUiController;
48 PhoneUi mUi;
49 Tab mTab;
50 Activity mActivity;
51
52 View mTopPanel;
53 ImageButton mBack;
54 ImageButton mRefresh;
55 ImageButton mForward;
56 ImageButton mTabs;
57 ImageButton mBookmarks;
58 ImageButton mMore;
59 ImageButton mNewTab;
60 ImageButton mNewIncognito;
61 FrameLayout mHolder;
62
63 Gallery mFlipper;
64 int mTabWidth;
65 int mTabHeight;
66 TabAdapter mAdapter;
67 ListPopupWindow mPopup;
Michael Kolb08a687a2011-04-22 16:13:02 -070068 Semaphore mLock;
Michael Kolbf2055602011-04-09 17:20:03 -070069
70 public NavScreen(Activity activity, UiController ctl, PhoneUi ui) {
71 super(activity);
72 mActivity = activity;
73 mUiController = ctl;
74 mUi = ui;
75 init();
76 }
77
78 protected Tab getSelectedTab() {
79 return (Tab) mFlipper.getSelectedItem();
80 }
81
82 protected void setTabDimensions(int w, int h) {
83 mTabWidth = w;
84 mTabHeight = h;
85 requestLayout();
86 }
87
Michael Kolb08a687a2011-04-22 16:13:02 -070088 protected synchronized void startTask(Runnable r) {
89 Thread task = new Thread(r);
90 mLock = new Semaphore(1);
91 try {
92 mLock.acquire();
93 } catch (InterruptedException e) {
94 }
95 task.start();
96 }
97
98 protected synchronized void finishTask() {
99 mLock.release();
100 }
101
102 protected synchronized void waitForTask() {
103 if (mLock != null) {
104 try {
105 mLock.acquire();
106 } catch (InterruptedException e) {
107 }
108 }
109 mLock = null;
110 }
111
Michael Kolbfedb4922011-04-20 16:45:33 -0700112 protected void showMenu() {
113 Menu menu = mUi.getMenu();
114 menu.setGroupVisible(R.id.NAV_MENU, false);
115
Michael Kolbf2055602011-04-09 17:20:03 -0700116 MenuAdapter menuAdapter = new MenuAdapter(mContext);
117 menuAdapter.setMenu(menu);
118 ListPopupWindow popup = new ListPopupWindow(mContext);
119 popup.setInputMethodMode(ListPopupWindow.INPUT_METHOD_NOT_NEEDED);
120 popup.setAdapter(menuAdapter);
121 popup.setModal(true);
122 popup.setAnchorView(mMore);
123 popup.setWidth((int) mContext.getResources().getDimension(
124 R.dimen.menu_width));
125 popup.show();
126 mPopup = popup;
127 }
128
129 protected void dismissMenu() {
130 if (mPopup != null) {
131 mPopup.dismiss();
132 }
133 }
134
135 private void init() {
136 LayoutInflater.from(mContext).inflate(R.layout.nav_screen, this);
137 LinearLayout content = (LinearLayout) findViewById(R.id.nav_screen);
138 mTopPanel = findViewById(R.id.navtop);
139 mBack = (ImageButton) findViewById(R.id.back);
140 mForward = (ImageButton) findViewById(R.id.forward);
141 mRefresh = (ImageButton) findViewById(R.id.refresh);
142 mTabs = (ImageButton) findViewById(R.id.tabs);
143 mBookmarks = (ImageButton) findViewById(R.id.bookmarks);
144 mNewTab = (ImageButton) findViewById(R.id.newtab);
145 mNewIncognito = (ImageButton) findViewById(R.id.newincognito);
146 mMore = (ImageButton) findViewById(R.id.more);
147 mBack.setOnClickListener(this);
148 mForward.setOnClickListener(this);
149 mRefresh.setOnClickListener(this);
150 mTabs.setOnClickListener(this);
151 mBookmarks.setOnClickListener(this);
152 mNewTab.setOnClickListener(this);
153 mNewIncognito.setOnClickListener(this);
154 mMore.setOnClickListener(this);
155 mHolder = (FrameLayout) findViewById(R.id.galleryholder);
156 FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(
157 LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT);
158 mFlipper = new TabGallery(mContext);
159 mFlipper.setSpacing((int)(mContext.getResources()
160 .getDimension(R.dimen.nav_tab_spacing)));
161 mFlipper.setLayoutParams(lp);
162 mHolder.addView(mFlipper, 0);
163 mAdapter = new TabAdapter(mContext, mUiController.getTabControl());
164 mFlipper.setAdapter(mAdapter);
165 setTab(mUi.getActiveTab(), true);
166 mFlipper.setOnItemClickListener(new OnItemClickListener() {
167 @Override
168 public void onItemClick(AdapterView<?> parent, View view,
169 int position, long id) {
170 // post as runnable to prevent bug in gesturedetector
171 // when view is removed in click handler
172 // sends action_cancel before action_up
173 mFlipper.post(new Runnable() {
174 public void run() {
175 close();
176 }
177 });
178 }
179 });
180 mFlipper.setOnItemSelectedListener(new OnItemSelectedListener() {
181 @Override
182 public void onItemSelected(AdapterView<?> parent, View view,
183 int position, long id) {
184 final Tab tab = mAdapter.getItem(position);
185 setTab(tab, false);
186 }
187
188 @Override
189 public void onNothingSelected(AdapterView<?> parent) {
190 }
191 });
192 }
193
194 private void setTab(Tab tab, boolean updateFlipper) {
195 mTab = tab;
196 // refresh state from tab
197 WebView web = tab.getWebView();
198 if (web != null) {
199 mBack.setImageResource(web.canGoBack()
200 ? R.drawable.ic_back_holo_dark
201 : R.drawable.ic_back_disabled_holo_dark);
202 mForward.setImageResource(web.canGoForward()
203 ? R.drawable.ic_forward_holo_dark
204 : R.drawable.ic_forward_disabled_holo_dark);
205 }
206 if (updateFlipper) {
207 mFlipper.setSelection(mUiController.getTabControl().getTabIndex(tab));
208 }
209 }
210
211 @Override
212 public void onClick(View v) {
213 WebView web = (mTab != null) ? mTab.getWebView() : null;
214 if (web != null) {
215 if (mBack == v) {
216 mUi.hideNavScreen(true);
217 web.goBack();
218 } else if (mForward == v) {
219 mUi.hideNavScreen(true);
220 web.goForward();
221 } else if (mRefresh == v) {
222 mUi.hideNavScreen(true);
223 web.reload();
224 }
225 }
226 if (mBookmarks == v) {
227 mUi.hideNavScreen(false);
228 mUiController.bookmarksOrHistoryPicker(false);
229 } else if (mTabs == v) {
230 mUi.hideNavScreen(false);
231 mUi.showActiveTabsPage();
232 } else if (mNewTab == v) {
233 mUi.hideNavScreen(true);
234 mUiController.openTabToHomePage();
235 } else if (mMore == v) {
Michael Kolbfedb4922011-04-20 16:45:33 -0700236 showMenu();
Michael Kolbf2055602011-04-09 17:20:03 -0700237 } else if (mNewIncognito == v) {
238 mUi.hideNavScreen(true);
239 mUiController.openIncognitoTab();
240 }
241 }
242
243 protected void close() {
244 close(true);
245 }
246
247 protected void close(boolean animate) {
248 mUi.hideNavScreen(animate);
249 Tab tab = (Tab) mFlipper.getSelectedItem();
250 if (tab != mUi.getActiveTab()) {
251 mUiController.setActiveTab(tab);
252 }
253 }
254
255 class TabGallery extends Gallery {
256
257 public TabGallery(Context ctx) {
258 super(ctx);
259 setUnselectedAlpha(0.3f);
260 }
261
262 @Override
263 protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
264 return new Gallery.LayoutParams(
265 LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
266 }
267
268 @Override
269 protected ViewGroup.LayoutParams generateLayoutParams(ViewGroup.LayoutParams lp) {
270 return generateDefaultLayoutParams();
271 }
272
273 }
274
275 class TabAdapter extends BaseAdapter {
276
277 Context context;
278 TabControl tabControl;
279
280 public TabAdapter(Context ctx, TabControl tc) {
281 context = ctx;
282 tabControl = tc;
283 }
284
285 void onCloseTab(Tab tab) {
286 if (tab != null) {
287 mUiController.closeTab(tab);
288 if (tabControl.getTabCount() == 0) {
289 mUiController.openTabToHomePage();
290 mUi.hideNavScreen(false);
291 } else {
292 notifyDataSetChanged();
293 }
294 }
295 }
296
297 @Override
298 public int getCount() {
299 return tabControl.getTabCount();
300 }
301
302 @Override
303 public Tab getItem(int position) {
304 return tabControl.getTab(position);
305 }
306
307 public long getItemId(int position) {
308 return position;
309 }
310
311 @Override
312 public View getView(int position, View convertView, ViewGroup parent) {
313 ImageView content = null;
314 if (convertView == null) {
315 convertView = LayoutInflater.from(context).inflate(R.layout.nav_tab_view,
316 null);
317 content = (ImageView) convertView.findViewById(R.id.content);
318 content.setLayoutParams(new LayoutParams(mTabWidth, mTabHeight));
319 } else {
320 content = (ImageView) convertView.findViewById(R.id.content);
321 }
322 TextView title = (TextView) convertView.findViewById(R.id.title);
323 ImageView icon = (ImageView) convertView.findViewById(R.id.favicon);
324 ImageButton close = (ImageButton) convertView.findViewById(R.id.closetab);
325 final Tab tab = getItem(position);
326 if (tab.getFavicon() != null) {
327 icon.setImageBitmap(tab.getFavicon());
328 }
329 title.setText(tab.getUrl());
330 Bitmap screen = tab.getScreenshot();
331 content.setImageBitmap(screen);
332 close.setOnClickListener(new OnClickListener() {
333 @Override
334 public void onClick(View v) {
335 onCloseTab(tab);
336 }
337 });
338 title.setOnClickListener(new OnClickListener() {
339 @Override
340 public void onClick(View v) {
341 close(false);
342 mUi.editUrl(false);
343 }
344 });
345 return convertView;
346 }
347 }
348
349 private class MenuAdapter extends BaseAdapter implements OnClickListener {
350
351 List<MenuItem> mItems;
352 LayoutInflater mInflater;
353
354 public MenuAdapter(Context ctx) {
355 mInflater = LayoutInflater.from(ctx);
356 mItems = new ArrayList<MenuItem>();
357 }
358
359 public void setMenu(Menu menu) {
360 mItems.clear();
361 for (int i = 0; i < menu.size(); i++) {
362 MenuItem item = menu.getItem(i);
363 if (item.isEnabled() && item.isVisible()) {
364 mItems.add(item);
365 }
366 }
367 notifyDataSetChanged();
368 }
369
370 @Override
371 public int getCount() {
372 return mItems.size();
373 }
374
375 @Override
376 public MenuItem getItem(int position) {
377 return mItems.get(position);
378 }
379
380 @Override
381 public long getItemId(int position) {
382 return position;
383 }
384
385 @Override
386 public void onClick(View v) {
387 if (v.getTag() != null) {
388 dismissMenu();
389 mActivity.closeOptionsMenu();
390 mUi.hideNavScreen(false);
391 mUiController.onOptionsItemSelected((MenuItem) v.getTag());
392 }
393 }
394
395 @Override
396 public View getView(int position, View convertView, ViewGroup parent) {
397 final MenuItem item = mItems.get(position);
398 View view = mInflater.inflate(R.layout.qc_menu_item, null);
399 TextView label = (TextView) view.findViewById(R.id.title);
400 label.setText(item.getTitle());
401 label.setTag(item);
402 label.setOnClickListener(this);
403 return label;
404 }
405
406 }
407
408}