blob: e0a5c898751e8ad0fa9fbbc297e02b451705ab2a [file] [log] [blame]
The Android Open Source Projectba6d7b82008-10-21 07:00:00 -07001/*
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;
20import android.util.Config;
21import android.view.ContextMenu;
22import android.view.ContextMenu.ContextMenuInfo;
23import android.view.KeyEvent;
24import android.view.MenuInflater;
25import android.view.MenuItem;
26import android.view.View;
27import android.view.View.OnCreateContextMenuListener;
28import android.webkit.WebView;
29import android.widget.AdapterView;
30import android.widget.AdapterView.OnItemClickListener;
31import android.widget.GridView;
32
33/**
34 * This class implements a Grid layout of Views for the Tab picker.
35 */
36class ImageGrid extends GridView implements OnItemClickListener,
37 OnCreateContextMenuListener {
38
39 private Listener mListener;
40 private ImageAdapter mAdapter;
41 private boolean mIsLive;
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 if (Config.DEBUG && l == null) {
62 throw new AssertionError();
63 }
64 mListener = l;
65
66 mAdapter = new ImageAdapter(context, this, null, live);
67 setAdapter(mAdapter);
68
69 // android.R.color.window_background seems to return transparent?
70// setBackgroundColor(android.R.color.window_background);
71 setBackgroundColor(0xFF000000);
72
73 setPadding(0, 10, 0, 10);
74 setVerticalSpacing(10);
75 setHorizontalSpacing(10);
76 setNumColumns(2);
77 setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
78 }
79
80 @Override
81 public boolean dispatchKeyEvent(KeyEvent event) {
82 // We always consume the BACK key even if mListener is null or the
83 // ImageGrid is not "live." This prevents crashes during tab animations
84 // if the user presses BACK.
85 if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
86 (event.getKeyCode() == KeyEvent.KEYCODE_BACK)) {
87 if (mListener != null && mIsLive) {
88 mListener.onClick(CANCEL);
89 invalidate();
90 }
91 return true;
92 }
93 return super.dispatchKeyEvent(event);
94 }
95
96 /**
97 * Called by BrowserActivity to add a new window to the tab picker.
98 * This does not happen dynamically, this only happens during view
99 * setup.
100 *
101 * @param v Webview of the tab to add
102 * @param name Web page title
103 * @param url URL of the webpage
104 */
105 public void add(TabControl.Tab t) {
106 mAdapter.add(t);
107 }
108
109 /**
110 * Called by BrowserActivity when a window has been removed from the
111 * tab list.
112 *
113 * @param index Window to remove, from 0 to MAX_TABS-1
114 */
115 public void remove(int index) {
116 if (Config.DEBUG && (index < 0 || index >= TabControl.MAX_TABS)) {
117 throw new AssertionError();
118 }
119 mAdapter.remove(index);
120 }
121
122 /**
123 * Request focus to initially set to a particular tab.
124 *
125 * @param startingIndex This is a Tab index from 0 - MAX_TABS-1 and does not
126 * include the "New Tab" cell.
127 */
128 public void setCurrentIndex(int startingIndex) {
129 if (!mAdapter.maxedOut()) {
130 startingIndex++;
131 }
132 setSelection(startingIndex);
133 }
134
135 public Listener getListener() {
136 return mListener;
137 }
138
139 public void setListener(Listener l) {
140 mListener = l;
141 }
142
143 /**
144 * Return true if the ImageGrid is live. This means that tabs can be chosen
145 * and the menu can be invoked.
146 */
147 public boolean isLive() {
148 return mIsLive;
149 }
150
151 /**
152 * Do some internal cleanup of the ImageGrid's adapter.
153 */
154 public void clear() {
155 mAdapter.clear();
156 }
157
158 /* (non-Javadoc)
159 * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
160 */
161 public void onItemClick(AdapterView parent, View v, int position, long id) {
162 if (!mAdapter.maxedOut()) {
163 position--;
164 }
165 // Position will be -1 for the "New Tab" cell.
166 if (mListener != null) {
167 mListener.onClick(position);
168 }
169 }
170
171 /* (non-Javadoc)
172 * @see android.view.View.OnCreateContextMenuListener#onCreateContextMenu(android.view.ContextMenu, android.view.View, java.lang.Object)
173 */
174 public void onCreateContextMenu(ContextMenu menu, View v,
175 ContextMenuInfo menuInfo) {
176 // Do not create the context menu if there is no listener or the Tab
177 // overview is not "live."
178 if (mListener == null || !mIsLive) {
179 return;
180 }
181 AdapterView.AdapterContextMenuInfo info =
182 (AdapterView.AdapterContextMenuInfo) menuInfo;
183 boolean maxed = mAdapter.maxedOut();
184 if (info.position > 0 || maxed) {
185 MenuInflater inflater = new MenuInflater(mContext);
186 inflater.inflate(R.menu.tabscontext, menu);
187 int position = info.position;
188 if (!maxed) {
189 position--;
190 }
191 menu.setHeaderTitle(mAdapter.mItems.get(position).getTitle());
192
193 // If we only have one active tab left, don't add the remove option
194 if (mAdapter.mItems.size() <= 1) {
195 menu.findItem(R.id.remove_tab_menu_id).setVisible(false);
196 }
197 }
198 }
199
200 // convert a context menu position to an actual tab position. Since context
201 // menus are not created for the "New Tab" cell, this will always return a
202 // valid tab position.
203 public int getContextMenuPosition(MenuItem menu) {
204 AdapterView.AdapterContextMenuInfo info =
205 (AdapterView.AdapterContextMenuInfo) menu.getMenuInfo();
206 int pos = info.position;
207 if (!mAdapter.maxedOut()) {
208 pos--;
209 }
210 return pos;
211 }
212
213 @Override
214 protected void onSizeChanged(int w, int h, int oldw, int oldh) {
215 // Called when our orientation changes. Replace the adapter with one
216 // that has the appropriate dimensions.
217 mAdapter = new ImageAdapter(mContext, this, mAdapter.mItems, mIsLive);
218 setAdapter(mAdapter);
219 super.onSizeChanged(w, h, oldw, oldh);
220 }
221
222 /**
223 * Listener to be notified by behavior of ImageGrid.
224 */
225 public interface Listener {
226 /**
227 * Called when enter is pressed on the list.
228 * @param position The index of the selected image when
229 * enter is pressed.
230 */
231 void onClick(int position);
232
233 /**
234 * Called when remove is called on the grid.
235 */
236 void remove(int position);
237 }
238
239}