blob: 9967f369b67b9071c024d2084c63461b8d18588a [file] [log] [blame]
The Android Open Source Project0c908882009-03-03 19:32:16 -08001/*
2 * Copyright (C) 2008 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;
The Android Open Source Project0c908882009-03-03 19:32:16 -080020import android.view.ContextMenu;
21import android.view.ContextMenu.ContextMenuInfo;
22import android.view.KeyEvent;
23import android.view.MenuInflater;
24import android.view.MenuItem;
25import android.view.View;
26import android.view.View.OnCreateContextMenuListener;
27import android.webkit.WebView;
28import android.widget.AdapterView;
29import android.widget.AdapterView.OnItemClickListener;
30import android.widget.GridView;
31
32/**
33 * This class implements a Grid layout of Views for the Tab picker.
34 */
35class ImageGrid extends GridView implements OnItemClickListener,
36 OnCreateContextMenuListener {
37
38 private Listener mListener;
39 private ImageAdapter mAdapter;
40 private boolean mIsLive;
41 private static final int SPACING = 10;
42 public static final int CANCEL = -99;
43 public static final int NEW_TAB = -1;
44
45 /**
46 * Constructor
47 * @param context Context to use when inflating resources.
48 * @param live TRUE if the view can accept touch or click
49 * @param l Listener to respond to clicks etc.
50 */
51 public ImageGrid(Context context, boolean live, Listener l) {
52 super(context);
53
54 mIsLive = live;
55 if (live) {
56 setFocusable(true);
57 setFocusableInTouchMode(true);
58 setOnItemClickListener(this);
59 setOnCreateContextMenuListener(this);
60 }
61 mListener = l;
62
63 mAdapter = new ImageAdapter(context, this, live);
64 setAdapter(mAdapter);
65
66 setBackgroundColor(0xFF000000);
67
68 setVerticalSpacing(SPACING);
69 setHorizontalSpacing(SPACING);
70 setNumColumns(2);
71 setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
72 setSelector(android.R.drawable.gallery_thumb);
73 }
74
75 @Override
76 public boolean dispatchKeyEvent(KeyEvent event) {
77 // We always consume the BACK key even if mListener is null or the
78 // ImageGrid is not "live." This prevents crashes during tab animations
79 // if the user presses BACK.
80 if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
81 (event.getKeyCode() == KeyEvent.KEYCODE_BACK)) {
82 if (mListener != null && mIsLive) {
83 mListener.onClick(CANCEL);
84 invalidate();
85 }
86 return true;
87 }
88 return super.dispatchKeyEvent(event);
89 }
90
91 /**
92 * Called by BrowserActivity to add a new window to the tab picker.
93 * This does not happen dynamically, this only happens during view
94 * setup.
95 *
96 * @param v Webview of the tab to add
97 * @param name Web page title
98 * @param url URL of the webpage
99 */
100 public void add(TabControl.Tab t) {
101 mAdapter.add(t);
102 }
103
104 /**
105 * Called by BrowserActivity when a window has been removed from the
106 * tab list.
107 *
108 * @param index Window to remove, from 0 to MAX_TABS-1
109 */
110 public void remove(int index) {
Dave Bort31a6d1c2009-04-13 15:56:49 -0700111 if (Browser.DEBUG && (index < 0 || index >= TabControl.MAX_TABS)) {
The Android Open Source Project0c908882009-03-03 19:32:16 -0800112 throw new AssertionError();
113 }
114 mAdapter.remove(index);
115 }
116
117 /**
118 * Request focus to initially set to a particular tab.
119 *
120 * @param startingIndex This is a Tab index from 0 - MAX_TABS-1 and does not
121 * include the "New Tab" cell.
122 */
123 public void setCurrentIndex(int startingIndex) {
124 if (!mAdapter.maxedOut()) {
125 startingIndex++;
126 }
127 setSelection(startingIndex);
128 }
129
130 public Listener getListener() {
131 return mListener;
132 }
133
134 public void setListener(Listener l) {
135 mListener = l;
136 }
137
138 /**
139 * Return true if the ImageGrid is live. This means that tabs can be chosen
140 * and the menu can be invoked.
141 */
142 public boolean isLive() {
143 return mIsLive;
144 }
145
146 /**
147 * Do some internal cleanup of the ImageGrid's adapter.
148 */
149 public void clear() {
150 mAdapter.clear();
151 }
152
153 /* (non-Javadoc)
154 * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
155 */
156 public void onItemClick(AdapterView parent, View v, int position, long id) {
157 if (!mAdapter.maxedOut()) {
158 position--;
159 }
160 // Position will be -1 for the "New Tab" cell.
161 if (mListener != null) {
162 mListener.onClick(position);
163 }
164 }
165
166 /* (non-Javadoc)
167 * @see android.view.View.OnCreateContextMenuListener#onCreateContextMenu(android.view.ContextMenu, android.view.View, java.lang.Object)
168 */
169 public void onCreateContextMenu(ContextMenu menu, View v,
170 ContextMenuInfo menuInfo) {
171 // Do not create the context menu if there is no listener or the Tab
172 // overview is not "live."
173 if (mListener == null || !mIsLive) {
174 return;
175 }
176 AdapterView.AdapterContextMenuInfo info =
177 (AdapterView.AdapterContextMenuInfo) menuInfo;
178 boolean maxed = mAdapter.maxedOut();
179 if (info.position > 0 || maxed) {
180 MenuInflater inflater = new MenuInflater(mContext);
181 inflater.inflate(R.menu.tabscontext, menu);
182 int position = info.position;
183 if (!maxed) {
184 position--;
185 }
186 menu.setHeaderTitle(mAdapter.mItems.get(position).getTitle());
187 }
188 }
189
190 // convert a context menu position to an actual tab position. Since context
191 // menus are not created for the "New Tab" cell, this will always return a
192 // valid tab position.
193 public int getContextMenuPosition(MenuItem menu) {
194 AdapterView.AdapterContextMenuInfo info =
195 (AdapterView.AdapterContextMenuInfo) menu.getMenuInfo();
196 int pos = info.position;
197 if (!mAdapter.maxedOut()) {
198 pos--;
199 }
200 return pos;
201 }
202
203 @Override
204 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
205 // Called when our orientation changes. Tell the adapter about the new
206 // size. Compute the individual tab height by taking the grid height
207 // and subtracting the SPACING. Then subtract the list padding twice
208 // (once for each tab on screen) and divide the remaining height by 2.
209 int tabHeight = (h - SPACING
210 - 2 * (getListPaddingTop() + getListPaddingBottom())) / 2;
211 mAdapter.heightChanged(tabHeight);
212 super.onSizeChanged(w, h, oldw, oldh);
213 }
214
215 /**
216 * Listener to be notified by behavior of ImageGrid.
217 */
218 public interface Listener {
219 /**
220 * Called when enter is pressed on the list.
221 * @param position The index of the selected image when
222 * enter is pressed.
223 */
224 void onClick(int position);
225
226 /**
227 * Called when remove is called on the grid.
228 */
229 void remove(int position);
230 }
231
232}