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