OLD | NEW |
(Empty) | |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package org.chromium.chrome.browser.ntp; |
| 6 |
| 7 import android.app.Activity; |
| 8 import android.graphics.Canvas; |
| 9 import android.graphics.Color; |
| 10 import android.view.ContextMenu; |
| 11 import android.view.ContextMenu.ContextMenuInfo; |
| 12 import android.view.LayoutInflater; |
| 13 import android.view.View; |
| 14 import android.view.ViewGroup; |
| 15 import android.widget.ExpandableListView; |
| 16 |
| 17 import com.google.android.apps.chrome.R; |
| 18 |
| 19 import org.chromium.chrome.browser.NativePage; |
| 20 import org.chromium.chrome.browser.UrlConstants; |
| 21 import org.chromium.chrome.browser.compositor.layouts.content.InvalidationAwareT
humbnailProvider; |
| 22 import org.chromium.chrome.browser.util.ViewUtils; |
| 23 |
| 24 /** |
| 25 * The native recent tabs page. Lists recently closed tabs, open windows and tab
s from the user's |
| 26 * synced devices, and snapshot documents sent from Chrome to Mobile in an expan
dable list view. |
| 27 */ |
| 28 public class RecentTabsPage implements NativePage, |
| 29 ExpandableListView.OnChildClickListener, ExpandableListView.OnGroupColla
pseListener, |
| 30 ExpandableListView.OnGroupExpandListener, RecentTabsManager.UpdatedCallb
ack, |
| 31 View.OnCreateContextMenuListener, InvalidationAwareThumbnailProvider { |
| 32 |
| 33 private final Activity mActivity; |
| 34 private final ExpandableListView mListView; |
| 35 private final String mTitle; |
| 36 private final ViewGroup mView; |
| 37 |
| 38 private RecentTabsManager mRecentTabsManager; |
| 39 private RecentTabsRowAdapter mAdapter; |
| 40 |
| 41 private boolean mSnapshotContentChanged; |
| 42 private int mSnapshotListPosition; |
| 43 private int mSnapshotListTop; |
| 44 private int mSnapshotWidth; |
| 45 private int mSnapshotHeight; |
| 46 |
| 47 /** |
| 48 * Constructor returns an instance of RecentTabsPage. |
| 49 * |
| 50 * @param activity The activity this view belongs to. |
| 51 * @param recentTabsManager The RecentTabsManager which provides the model d
ata. |
| 52 */ |
| 53 public RecentTabsPage(Activity activity, RecentTabsManager recentTabsManager
) { |
| 54 mActivity = activity; |
| 55 mRecentTabsManager = recentTabsManager; |
| 56 |
| 57 mTitle = activity.getResources().getString(R.string.recent_tabs); |
| 58 mRecentTabsManager.setUpdatedCallback(this); |
| 59 LayoutInflater inflater = LayoutInflater.from(activity); |
| 60 mView = (ViewGroup) inflater.inflate(R.layout.recent_tabs_page, null); |
| 61 mListView = (ExpandableListView) mView.findViewById(R.id.odp_listview); |
| 62 mAdapter = buildAdapter(activity, recentTabsManager); |
| 63 mListView.setAdapter(mAdapter); |
| 64 mListView.setOnChildClickListener(this); |
| 65 mListView.setGroupIndicator(null); |
| 66 mListView.setOnGroupCollapseListener(this); |
| 67 mListView.setOnGroupExpandListener(this); |
| 68 mListView.setOnCreateContextMenuListener(this); |
| 69 |
| 70 onUpdated(); |
| 71 } |
| 72 |
| 73 private static RecentTabsRowAdapter buildAdapter(Activity activity, |
| 74 RecentTabsManager recentTabsManager) { |
| 75 return new RecentTabsRowAdapter(activity, recentTabsManager); |
| 76 } |
| 77 |
| 78 // NativePage overrides |
| 79 |
| 80 @Override |
| 81 public String getUrl() { |
| 82 return UrlConstants.RECENT_TABS_URL; |
| 83 } |
| 84 |
| 85 @Override |
| 86 public String getTitle() { |
| 87 return mTitle; |
| 88 } |
| 89 |
| 90 @Override |
| 91 public int getBackgroundColor() { |
| 92 return Color.WHITE; |
| 93 } |
| 94 |
| 95 @Override |
| 96 public View getView() { |
| 97 return mView; |
| 98 } |
| 99 |
| 100 @Override |
| 101 public String getHost() { |
| 102 return UrlConstants.RECENT_TABS_HOST; |
| 103 } |
| 104 |
| 105 @Override |
| 106 public void destroy() { |
| 107 assert getView().getParent() == null : "Destroy called before removed fr
om window"; |
| 108 mRecentTabsManager.destroy(); |
| 109 mRecentTabsManager = null; |
| 110 mAdapter.notifyDataSetInvalidated(); |
| 111 mAdapter = null; |
| 112 mListView.setAdapter((RecentTabsRowAdapter) null); |
| 113 } |
| 114 |
| 115 @Override |
| 116 public void updateForUrl(String url) { |
| 117 } |
| 118 |
| 119 // ExpandableListView.OnChildClickedListener |
| 120 @Override |
| 121 public boolean onChildClick(ExpandableListView parent, View v, int groupPosi
tion, |
| 122 int childPosition, long id) { |
| 123 return mAdapter.getGroup(groupPosition).onChildClick(childPosition); |
| 124 } |
| 125 |
| 126 // ExpandableListView.OnGroupExpandedListener |
| 127 @Override |
| 128 public void onGroupExpand(int groupPosition) { |
| 129 mAdapter.getGroup(groupPosition).setCollapsed(false); |
| 130 mSnapshotContentChanged = true; |
| 131 } |
| 132 |
| 133 // ExpandableListView.OnGroupCollapsedListener |
| 134 @Override |
| 135 public void onGroupCollapse(int groupPosition) { |
| 136 mAdapter.getGroup(groupPosition).setCollapsed(true); |
| 137 mSnapshotContentChanged = true; |
| 138 } |
| 139 |
| 140 // RecentTabsManager.UpdatedCallback |
| 141 @Override |
| 142 public void onUpdated() { |
| 143 mAdapter.notifyDataSetChanged(); |
| 144 for (int i = 0; i < mAdapter.getGroupCount(); i++) { |
| 145 if (mAdapter.getGroup(i).isCollapsed()) { |
| 146 mListView.collapseGroup(i); |
| 147 } else { |
| 148 mListView.expandGroup(i); |
| 149 } |
| 150 } |
| 151 mSnapshotContentChanged = true; |
| 152 } |
| 153 |
| 154 @Override |
| 155 public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo me
nuInfo) { |
| 156 // Would prefer to have this context menu view managed internal to Recen
tTabsGroupView |
| 157 // Unfortunately, setting either onCreateContextMenuListener or onLongCl
ickListener |
| 158 // disables the native onClick (expand/collapse) behaviour of the group
view. |
| 159 ExpandableListView.ExpandableListContextMenuInfo info = |
| 160 (ExpandableListView.ExpandableListContextMenuInfo) menuInfo; |
| 161 |
| 162 int type = ExpandableListView.getPackedPositionType(info.packedPosition)
; |
| 163 int groupPosition = ExpandableListView.getPackedPositionGroup(info.packe
dPosition); |
| 164 |
| 165 if (type == ExpandableListView.PACKED_POSITION_TYPE_GROUP) { |
| 166 mAdapter.getGroup(groupPosition).onCreateContextMenuForGroup(menu, m
Activity); |
| 167 } else if (type == ExpandableListView.PACKED_POSITION_TYPE_CHILD) { |
| 168 int childPosition = ExpandableListView.getPackedPositionChild(info.p
ackedPosition); |
| 169 mAdapter.getGroup(groupPosition).onCreateContextMenuForChild(childPo
sition, menu, |
| 170 mActivity); |
| 171 } |
| 172 } |
| 173 |
| 174 // InvalidationAwareThumbnailProvider |
| 175 |
| 176 @Override |
| 177 public boolean shouldCaptureThumbnail() { |
| 178 if (mView.getWidth() == 0 || mView.getHeight() == 0) return false; |
| 179 |
| 180 View topItem = mListView.getChildAt(0); |
| 181 return mSnapshotContentChanged |
| 182 || mSnapshotListPosition != mListView.getFirstVisiblePosition() |
| 183 || mSnapshotListTop != (topItem == null ? 0 : topItem.getTop()) |
| 184 || mView.getWidth() != mSnapshotWidth |
| 185 || mView.getHeight() != mSnapshotHeight; |
| 186 } |
| 187 |
| 188 @Override |
| 189 public void captureThumbnail(Canvas canvas) { |
| 190 ViewUtils.captureBitmap(mView, canvas); |
| 191 mSnapshotContentChanged = false; |
| 192 mSnapshotListPosition = mListView.getFirstVisiblePosition(); |
| 193 View topItem = mListView.getChildAt(0); |
| 194 mSnapshotListTop = topItem == null ? 0 : topItem.getTop(); |
| 195 mSnapshotWidth = mView.getWidth(); |
| 196 mSnapshotHeight = mView.getHeight(); |
| 197 } |
| 198 } |
OLD | NEW |