Home | History | Annotate | Download | only in browser
      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 }
    192