blob: e6eaa75ad9e98b5985ff9e1b7a21929ae3ef298e [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.app.AlertDialog;
20import android.content.DialogInterface;
21import android.database.DataSetObserver;
22import android.graphics.Color;
23import android.view.KeyEvent;
24import android.view.View;
25import android.view.ViewGroup;
26import android.view.LayoutInflater;
27import android.content.Context;
28import android.content.res.Configuration;
29import android.content.res.Resources;
30import android.webkit.WebView;
31import android.widget.*;
32
33import java.util.ArrayList;
34
35/**
36 * Adapter used by ImageGrid.
37 */
38public class ImageAdapter implements ListAdapter {
39
40 ArrayList<TabControl.Tab> mItems; // Items shown in the grid
41 ArrayList<DataSetObserver> mDataObservers; // Data change listeners
42 Context mContext; // Context to use to inflate views
43 boolean mMaxedOut;
44 boolean mLandScape;
45 ImageGrid mImageGrid;
46 boolean mIsLive;
47
48 ImageAdapter(Context context, ImageGrid grid,
49 ArrayList<TabControl.Tab> items, boolean live) {
50 mContext = context;
51 mIsLive = live;
52 if (items == null) {
53 mItems = new ArrayList<TabControl.Tab>();
54 } else {
55 mItems = items;
56 if (items.size() == TabControl.MAX_TABS) {
57 mMaxedOut = true;
58 }
59 }
60 mImageGrid = grid;
61 mDataObservers = new ArrayList<DataSetObserver>();
62 mLandScape = context.getResources().getConfiguration().orientation ==
63 Configuration.ORIENTATION_LANDSCAPE;
64 }
65
66 /**
67 * Whether the adapter is at its limit, determined by TabControl.MAX_TABS
68 *
69 * @return True if the number of Tabs represented in this Adapter is at its
70 * maximum.
71 */
72 public boolean maxedOut() {
73 return mMaxedOut;
74 }
75
76 /**
77 * Clear the internal WebViews and remove their picture listeners.
78 */
79 public void clear() {
80 for (TabControl.Tab t : mItems) {
81 clearPictureListeners(t);
82 }
83 mItems.clear();
84 notifyObservers();
85 }
86
87 private void clearPictureListeners(TabControl.Tab t) {
88 if (t.getWebView() != null) {
89 t.getWebView().setPictureListener(null);
90 if (t.getSubWebView() != null) {
91 t.getSubWebView().setPictureListener(null);
92 }
93 }
94 }
95
96 /**
97 * Add a new window web page to the grid
98 *
99 * @param t The tab to display
100 */
101 public void add(TabControl.Tab t) {
102 if (mMaxedOut) {
103 return;
104 }
105 mItems.add(t);
106 notifyObservers();
107 if (mItems.size() == TabControl.MAX_TABS) {
108 mMaxedOut = true;
109 }
110 }
111
112 /**
113 * Remove a window from the list. At this point, the window
114 * has already gone. It just needs to be removed from the screen
115 *
116 * @param index window to remove
117 */
118 public void remove(int index) {
119 if (index >= 0 && index < mItems.size()) {
120 clearPictureListeners(mItems.remove(index));
121 notifyObservers();
122 mMaxedOut = false;
123 }
124 }
125
126 /* (non-Javadoc)
127 * @see android.widget.ListAdapter#areAllItemsSelectable()
128 */
129 public boolean areAllItemsEnabled() {
130 return true;
131 }
132
133 /* (non-Javadoc)
134 * @see android.widget.ListAdapter#isSelectable(int)
135 */
136 public boolean isEnabled(int position) {
137 if (position >= 0 && position <= mItems.size()) {
138 return true;
139 }
140 return false;
141 }
142
143 /* (non-Javadoc)
144 * @see android.widget.Adapter#getCount()
145 */
146 public int getCount() {
147 // Include the New Window button if we have not reached the tab limit
148 if (!mMaxedOut) {
149 return mItems.size()+1;
150 }
151 return mItems.size();
152 }
153
154 /* (non-Javadoc)
155 * @see android.widget.Adapter#getItem(int)
156 */
157 public Object getItem(int position) {
158 if (!mMaxedOut) {
159 if (0 == position) {
160 return null;
161 }
162 return mItems.get(position);
163 }
164 return mItems.get(position);
165 }
166
167 /* (non-Javadoc)
168 * @see android.widget.Adapter#getItemId(int)
169 */
170 public long getItemId(int position) {
171 return position;
172 }
173
174 /* (non-Javadoc)
175 * @see android.widget.Adapter#getView(int, android.view.View,
176 * android.view.ViewGroup)
177 */
178 public View getView(int position, View convertView, ViewGroup parent) {
179 View v = null;
180 if (convertView != null) {
181 v = convertView;
182 } else {
183 LayoutInflater factory = LayoutInflater.from(mContext);
184 v = factory.inflate(R.layout.tabitem, null);
185 }
186 FakeWebView img = (FakeWebView) v.findViewById(R.id.icon);
187 ImageView close = (ImageView) v.findViewById(R.id.close);
188 TextView tv = (TextView) v.findViewById(R.id.label);
189
190 // position needs to be in the range of Tab indices.
191 if (!mMaxedOut) {
192 position--;
193 }
194
195 // Create the View for actual tabs
196 if (position != ImageGrid.NEW_TAB) {
197 TabControl.Tab t = mItems.get(position);
198 img.setTab(t);
199 tv.setText(t.getTitle());
200 // Do not put the 'X' for a single tab or if the tab picker isn't
201 // "live" (meaning the user cannot click on a tab)
202 if (mItems.size() == 1 || !mIsLive) {
203 close.setVisibility(View.GONE);
204 } else {
205 close.setVisibility(View.VISIBLE);
206 final int pos = position;
207 close.setOnClickListener(new View.OnClickListener() {
208 public void onClick(View v) {
209 ImageAdapter.this.confirmClose(pos);
210 }
211 });
212 }
213 } else {
214 img.setBackgroundColor(Color.BLACK);
215 img.setImageResource(R.drawable.ic_new_window);
216 img.setScaleType(ImageView.ScaleType.CENTER);
217 img.setPadding(0, 0, 0, 34);
218 tv.setText(R.string.new_window);
219 close.setVisibility(View.GONE);
220 }
221 if (mLandScape) {
222 ViewGroup.LayoutParams lp = img.getLayoutParams();
223 lp.width = 225;
224 lp.height = 120;
225 img.requestLayout();
226 }
227 return v;
228 }
229
230 /*
231 * Pop a confirmation dialog to the user asking if they want to close this
232 * tab.
233 */
234 private void confirmClose(final int position) {
235 final ImageGrid.Listener l = mImageGrid.getListener();
236 if (l == null) {
237 return;
238 }
239 DialogInterface.OnClickListener confirm =
240 new DialogInterface.OnClickListener() {
241 public void onClick(DialogInterface dialog,
242 int whichButton) {
243 l.remove(position);
244 }
245 };
246 new AlertDialog.Builder(mContext)
247 .setTitle(R.string.close)
248 .setIcon(R.drawable.ssl_icon)
249 .setMessage(R.string.close_window)
250 .setPositiveButton(R.string.ok, confirm)
251 .setNegativeButton(R.string.cancel, null)
252 .show();
253 }
254
255 /* (non-Javadoc)
256 * @see android.widget.Adapter#registerDataSetObserver(android.database.DataSetObserver)
257 */
258 public void registerDataSetObserver(DataSetObserver observer) {
259 mDataObservers.add(observer);
260
261 }
262
263 /* (non-Javadoc)
264 * @see android.widget.Adapter#hasStableIds()
265 */
266 public boolean hasStableIds() {
267 return true;
268 }
269
270 /* (non-Javadoc)
271 * @see android.widget.Adapter#unregisterDataSetObserver(android.database.DataSetObserver)
272 */
273 public void unregisterDataSetObserver(DataSetObserver observer) {
274 mDataObservers.remove(observer);
275
276 }
277
278 /**
279 * Notify all the observers that a change has happened.
280 */
281 void notifyObservers() {
282 for (DataSetObserver observer : mDataObservers) {
283 observer.onChanged();
284 }
285 }
286
287 public int getItemViewType(int position) {
288 return 0;
289 }
290
291 public int getViewTypeCount() {
292 return 1;
293 }
294
295 public boolean isEmpty() {
296 return getCount() == 0;
297 }
298}