OSDN Git Service

Deprecate fill_parent and introduce match_parent.
[android-x86/packages-apps-Browser.git] / src / com / android / browser / ActiveTabsPage.java
1 /*
2  * Copyright (C) 2009 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
17 package com.android.browser;
18
19 import android.content.Context;
20 import android.graphics.Bitmap;
21 import android.os.Handler;
22 import android.util.AttributeSet;
23 import android.view.KeyEvent;
24 import android.view.LayoutInflater;
25 import android.view.View;
26 import android.view.ViewGroup;
27 import android.widget.AdapterView;
28 import android.widget.BaseAdapter;
29 import android.widget.ImageView;
30 import android.widget.LinearLayout;
31 import android.widget.ListView;
32 import android.widget.TextView;
33
34 public class ActiveTabsPage extends LinearLayout {
35     private final BrowserActivity   mBrowserActivity;
36     private final LayoutInflater    mFactory;
37     private final TabControl        mControl;
38     private final TabsListAdapter   mAdapter;
39     private final ListView          mListView;
40
41     public ActiveTabsPage(BrowserActivity context, TabControl control) {
42         super(context);
43         mBrowserActivity = context;
44         mControl = control;
45         mFactory = LayoutInflater.from(context);
46         mFactory.inflate(R.layout.active_tabs, this);
47         mListView = (ListView) findViewById(R.id.list);
48         mAdapter = new TabsListAdapter();
49         mListView.setAdapter(mAdapter);
50         mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
51                 public void onItemClick(AdapterView<?> parent, View view,
52                         int position, long id) {
53                     if (mControl.canCreateNewTab()) {
54                         position--;
55                     }
56                     boolean needToAttach = false;
57                     if (position == -1) {
58                         // Create a new tab
59                         mBrowserActivity.openTabToHomePage();
60                     } else {
61                         // Open the corresponding tab
62                         // If the tab is the current one, switchToTab will
63                         // do nothing and return, so we need to make sure
64                         // it gets attached back to its mContentView in
65                         // removeActiveTabPage
66                         needToAttach = !mBrowserActivity.switchToTab(position);
67                     }
68                     mBrowserActivity.removeActiveTabPage(needToAttach);
69                 }
70         });
71     }
72
73     /**
74      * Special class to hold the close drawable.  Its sole purpose is to allow
75      * the parent to be pressed without being pressed itself.  This way the line
76      * of a tab can be pressed, but the close button itself is not.
77      */
78     private static class CloseHolder extends ImageView {
79         public CloseHolder(Context context, AttributeSet attrs) {
80             super(context, attrs);
81         }
82
83         @Override
84         public void setPressed(boolean pressed) {
85             // If the parent is pressed, do not set to pressed.
86             if (pressed && ((View) getParent()).isPressed()) {
87                 return;
88             }
89             super.setPressed(pressed);
90         }
91     }
92
93     private class TabsListAdapter extends BaseAdapter {
94         private boolean mNotified = true;
95         private int mReturnedCount;
96         private Handler mHandler = new Handler();
97
98         public int getCount() {
99             int count = mControl.getTabCount();
100             if (mControl.canCreateNewTab()) {
101                 count++;
102             }
103             // XXX: This is a workaround to be more like a real adapter. Most
104             // adapters call notifyDataSetChanged() whenever the internal data
105             // has changed. Since TabControl is our internal data, we don't
106             // know when that changes.
107             //
108             // Keep track of the last count we returned and whether we called
109             // notifyDataSetChanged(). If we did not initiate a data set
110             // change, and the count is different, send the notify and return
111             // the old count.
112             if (!mNotified && count != mReturnedCount) {
113                 notifyChange();
114                 return mReturnedCount;
115             }
116             mReturnedCount = count;
117             mNotified = false;
118             return count;
119         }
120         public Object getItem(int position) {
121             return null;
122         }
123         public long getItemId(int position) {
124             return position;
125         }
126         public int getViewTypeCount() {
127             return 2;
128         }
129         public int getItemViewType(int position) {
130             if (mControl.canCreateNewTab()) {
131                 position--;
132             }
133             // Do not recycle the "add new tab" item.
134             return position == -1 ? IGNORE_ITEM_VIEW_TYPE : 1;
135         }
136         public View getView(int position, View convertView, ViewGroup parent) {
137             final int tabCount = mControl.getTabCount();
138             if (mControl.canCreateNewTab()) {
139                 position--;
140             }
141
142             if (convertView == null) {
143                 convertView = mFactory.inflate(position == -1 ?
144                         R.layout.tab_view_add_tab : R.layout.tab_view, null);
145             }
146
147             if (position != -1) {
148                 TextView title =
149                         (TextView) convertView.findViewById(R.id.title);
150                 TextView url = (TextView) convertView.findViewById(R.id.url);
151                 ImageView favicon =
152                         (ImageView) convertView.findViewById(R.id.favicon);
153                 View close = convertView.findViewById(R.id.close);
154                 Tab tab = mControl.getTab(position);
155                 tab.populatePickerData();
156                 title.setText(tab.getTitle());
157                 url.setText(tab.getUrl());
158                 Bitmap icon = tab.getFavicon();
159                 if (icon != null) {
160                     favicon.setImageBitmap(icon);
161                 } else {
162                     favicon.setImageResource(R.drawable.app_web_browser_sm);
163                 }
164                 final int closePosition = position;
165                 close.setOnClickListener(new View.OnClickListener() {
166                         public void onClick(View v) {
167                             mBrowserActivity.closeTab(
168                                     mControl.getTab(closePosition));
169                             if (tabCount == 1) {
170                                 mBrowserActivity.openTabToHomePage();
171                                 mBrowserActivity.removeActiveTabPage(false);
172                             } else {
173                                 mNotified = true;
174                                 notifyDataSetChanged();
175                             }
176                         }
177                 });
178             }
179             return convertView;
180         }
181
182         void notifyChange() {
183             mHandler.post(new Runnable() {
184                 public void run() {
185                     mNotified = true;
186                     notifyDataSetChanged();
187                 }
188             });
189         }
190     }
191 }