Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(533)

Side by Side Diff: chrome/android/java/src/org/chromium/chrome/browser/contextmenu/TabularContextMenuUi.java

Issue 2777773002: Show the image header for the Context Menu (Closed)
Patch Set: Fixed based of tedchoc's comments Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 package org.chromium.chrome.browser.contextmenu; 5 package org.chromium.chrome.browser.contextmenu;
6 6
7 import android.app.Dialog; 7 import android.app.Dialog;
8 import android.content.Context; 8 import android.content.Context;
9 import android.content.DialogInterface; 9 import android.content.DialogInterface;
10 import android.content.res.Resources;
11 import android.graphics.Bitmap;
12 import android.graphics.Canvas;
13 import android.graphics.Shader;
14 import android.graphics.drawable.BitmapDrawable;
15 import android.graphics.drawable.Drawable;
10 import android.support.design.widget.TabLayout; 16 import android.support.design.widget.TabLayout;
11 import android.support.v4.view.ViewPager; 17 import android.support.v4.view.ViewPager;
12 import android.support.v7.app.AlertDialog; 18 import android.support.v7.app.AlertDialog;
13 import android.text.TextUtils; 19 import android.text.TextUtils;
14 import android.util.Pair; 20 import android.util.Pair;
15 import android.view.LayoutInflater; 21 import android.view.LayoutInflater;
16 import android.view.View; 22 import android.view.View;
17 import android.view.ViewGroup; 23 import android.view.ViewGroup;
18 import android.widget.AdapterView; 24 import android.widget.AdapterView;
19 import android.widget.BaseAdapter; 25 import android.widget.BaseAdapter;
26 import android.widget.ImageView;
20 import android.widget.ListView; 27 import android.widget.ListView;
21 import android.widget.TextView; 28 import android.widget.TextView;
22 29
23 import org.chromium.base.ApiCompatibilityUtils; 30 import org.chromium.base.ApiCompatibilityUtils;
24 import org.chromium.base.Callback; 31 import org.chromium.base.Callback;
25 import org.chromium.base.VisibleForTesting; 32 import org.chromium.base.VisibleForTesting;
26 import org.chromium.chrome.R; 33 import org.chromium.chrome.R;
27 34
28 import java.util.ArrayList; 35 import java.util.ArrayList;
29 import java.util.List; 36 import java.util.List;
30 37
31 /** 38 /**
32 * A custom dialog that separates each group into separate tabs. It uses a dialo g instead. 39 * A custom dialog that separates each group into separate tabs. It uses a dialo g instead.
33 */ 40 */
34 public class TabularContextMenuUi implements ContextMenuUi, AdapterView.OnItemCl ickListener { 41 public class TabularContextMenuUi implements ContextMenuUi, AdapterView.OnItemCl ickListener {
35 private Dialog mDialog; 42 private Dialog mDialog;
36 private Callback<Integer> mCallback; 43 private Callback<Integer> mCallback;
37 private int mMenuItemHeight; 44 private int mMenuItemHeight;
45 private ImageView mHeaderImageView;
38 46
39 @Override 47 @Override
40 public void displayMenu(Context context, ContextMenuParams params, 48 public void displayMenu(Context context, ContextMenuParams params,
41 List<Pair<Integer, List<ContextMenuItem>>> items, Callback<Integer> onItemClicked, 49 List<Pair<Integer, List<ContextMenuItem>>> items, Callback<Integer> onItemClicked,
42 final Runnable onMenuShown, final Runnable onMenuClosed) { 50 final Runnable onMenuShown, final Runnable onMenuClosed) {
43 mCallback = onItemClicked; 51 mCallback = onItemClicked;
44 mDialog = createDialog(context, params, items); 52 mDialog = createDialog(context, params, items);
45 mDialog.getWindow().setBackgroundDrawable(ApiCompatibilityUtils.getDrawa ble( 53 mDialog.getWindow().setBackgroundDrawable(ApiCompatibilityUtils.getDrawa ble(
46 context.getResources(), R.drawable.bg_find_toolbar_popup)); 54 context.getResources(), R.drawable.bg_find_toolbar_popup));
47 55
(...skipping 28 matching lines...) Expand all
76 dialog.setContentView(createPagerView(context, params, itemGroups)); 84 dialog.setContentView(createPagerView(context, params, itemGroups));
77 return dialog; 85 return dialog;
78 } 86 }
79 87
80 /** 88 /**
81 * Creates the view of a context menu. Based off the Context Type, it'll adj ust the list of 89 * Creates the view of a context menu. Based off the Context Type, it'll adj ust the list of
82 * items and display only the ones that'll be on that specific group. 90 * items and display only the ones that'll be on that specific group.
83 * @param context Used to get the resources of an item. 91 * @param context Used to get the resources of an item.
84 * @param params used to create the header text. 92 * @param params used to create the header text.
85 * @param items A set of Items to display in a context menu. Filtered based off the type. 93 * @param items A set of Items to display in a context menu. Filtered based off the type.
86 * @return Returns a filled LinearLayout with all the context menu items 94 * @param isImage Whether or not the view should have an image layout or not .
95 * @param maxCount The maximum amount of {@link ContextMenuItem}s that could exist in this view
96 * or any other views calculated in the context menu. Used t o estimate the size
97 * of the list.
98 * @return Returns a filled LinearLayout with all the context menu items.
87 */ 99 */
88 @VisibleForTesting 100 @VisibleForTesting
89 ViewGroup createContextMenuPageUi( 101 ViewGroup createContextMenuPageUi(Context context, ContextMenuParams params,
90 Context context, ContextMenuParams params, List<ContextMenuItem> ite ms, int maxCount) { 102 List<ContextMenuItem> items, boolean isImage, int maxCount) {
91 ViewGroup baseLayout = (ViewGroup) LayoutInflater.from(context).inflate( 103 ViewGroup baseLayout = (ViewGroup) LayoutInflater.from(context).inflate(
92 R.layout.tabular_context_menu_page, null); 104 R.layout.tabular_context_menu_page, null);
93 ListView listView = (ListView) baseLayout.findViewById(R.id.selectable_i tems); 105 ListView listView = (ListView) baseLayout.findViewById(R.id.selectable_i tems);
94 displayHeaderIfVisibleItems(params, baseLayout); 106
107 if (isImage) {
108 displayImageHeader(baseLayout, params, context.getResources());
109 } else {
110 displayHeaderIfVisibleItems(params, baseLayout);
111 }
95 112
96 // Set the list adapter and get the height to display it appropriately i n a dialog. 113 // Set the list adapter and get the height to display it appropriately i n a dialog.
97 TabularContextMenuListAdapter listAdapter = 114 TabularContextMenuListAdapter listAdapter =
98 new TabularContextMenuListAdapter(items, context); 115 new TabularContextMenuListAdapter(items, context);
99 ViewGroup.LayoutParams layoutParams = listView.getLayoutParams(); 116 ViewGroup.LayoutParams layoutParams = listView.getLayoutParams();
100 layoutParams.height = measureApproximateListViewHeight(listView, listAda pter, maxCount); 117 layoutParams.height = measureApproximateListViewHeight(listView, listAda pter, maxCount);
101 listView.setLayoutParams(layoutParams); 118 listView.setLayoutParams(layoutParams);
102 listView.setAdapter(listAdapter); 119 listView.setAdapter(listAdapter);
103 listView.setOnItemClickListener(this); 120 listView.setOnItemClickListener(this);
104 121
105 return baseLayout; 122 return baseLayout;
106 } 123 }
107 124
108 private void displayHeaderIfVisibleItems(ContextMenuParams params, ViewGroup baseLayout) { 125 private void displayHeaderIfVisibleItems(ContextMenuParams params, ViewGroup baseLayout) {
109 String headerText = ChromeContextMenuPopulator.createHeaderText(params); 126 String headerText = ChromeContextMenuPopulator.createHeaderText(params);
110 final TextView headerTextView = 127 final TextView headerTextView =
111 (TextView) baseLayout.findViewById(R.id.context_header_text); 128 (TextView) baseLayout.findViewById(R.id.context_header_text);
112 if (TextUtils.isEmpty(headerText)) { 129 if (TextUtils.isEmpty(headerText)) {
130 baseLayout.findViewById(R.id.context_header_layout).setVisibility(Vi ew.GONE);
113 headerTextView.setVisibility(View.GONE); 131 headerTextView.setVisibility(View.GONE);
114 baseLayout.findViewById(R.id.context_divider).setVisibility(View.GON E); 132 baseLayout.findViewById(R.id.context_divider).setVisibility(View.GON E);
115 return; 133 return;
116 } 134 }
117 headerTextView.setVisibility(View.VISIBLE); 135 headerTextView.setVisibility(View.VISIBLE);
118 headerTextView.setText(headerText); 136 headerTextView.setText(headerText);
119 headerTextView.setOnClickListener(new View.OnClickListener() { 137 headerTextView.setOnClickListener(new View.OnClickListener() {
120 @Override 138 @Override
121 public void onClick(View view) { 139 public void onClick(View view) {
122 if (headerTextView.getMaxLines() == Integer.MAX_VALUE) { 140 if (headerTextView.getMaxLines() == Integer.MAX_VALUE) {
123 headerTextView.setMaxLines(1); 141 headerTextView.setMaxLines(1);
124 headerTextView.setEllipsize(TextUtils.TruncateAt.END); 142 headerTextView.setEllipsize(TextUtils.TruncateAt.END);
125 } else { 143 } else {
126 headerTextView.setMaxLines(Integer.MAX_VALUE); 144 headerTextView.setMaxLines(Integer.MAX_VALUE);
127 headerTextView.setEllipsize(null); 145 headerTextView.setEllipsize(null);
128 } 146 }
129 } 147 }
130 }); 148 });
131 } 149 }
132 150
151 private void displayImageHeader(
152 ViewGroup baseLayout, ContextMenuParams params, Resources resources) {
153 displayHeaderIfVisibleItems(params, baseLayout);
154 // #displayHeaderIfVisibleItems() sets these two views to GONE if the he ader text is
155 // empty but they should still be visible because we have an image to di splay.
156 baseLayout.findViewById(R.id.context_header_layout).setVisibility(View.V ISIBLE);
157 baseLayout.findViewById(R.id.context_divider).setVisibility(View.VISIBLE );
158
159 mHeaderImageView = (ImageView) baseLayout.findViewById(R.id.context_head er_image);
160 TextView headerTextView = (TextView) baseLayout.findViewById(R.id.contex t_header_text);
161 // We'd prefer the header text is the title text instead of the link tex t for images.
162 String headerText = params.getTitleText();
163 if (!TextUtils.isEmpty(headerText)) {
164 headerTextView.setText(headerText);
165 }
166 setBackgroundForImageView(mHeaderImageView, resources);
167 }
168
169 /**
170 * This creates a checkerboard style background displayed before the image i s shown.
171 */
172 private void setBackgroundForImageView(ImageView imageView, Resources resour ces) {
173 Drawable drawable =
174 ApiCompatibilityUtils.getDrawable(resources, R.drawable.checkerb oard_background);
175 Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
176 drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
177 Canvas canvas = new Canvas(bitmap);
178 drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
179 drawable.draw(canvas);
180 BitmapDrawable bm = new BitmapDrawable(resources, bitmap);
181 bm.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
182 imageView.setVisibility(View.VISIBLE);
183 imageView.setBackground(bm);
184 }
185
133 /** 186 /**
134 * To save time measuring the height, this method gets an item if the height has not been 187 * To save time measuring the height, this method gets an item if the height has not been
135 * previous measured and multiplies it by count of the total amount of items . It is fine if the 188 * previous measured and multiplies it by count of the total amount of items . It is fine if the
136 * height too small as the ListView will scroll through the other values. 189 * height too small as the ListView will scroll through the other values.
137 * @param listView The ListView to measure the surrounding padding. 190 * @param listView The ListView to measure the surrounding padding.
138 * @param listAdapter The adapter which contains the items within the list. 191 * @param listAdapter The adapter which contains the items within the list.
139 * @return Returns the combined height of the padding of the ListView and th e approximate height 192 * @return Returns the combined height of the padding of the ListView and th e approximate height
140 * of the ListView based off the an item. 193 * of the ListView based off the an item.
141 */ 194 */
142 private int measureApproximateListViewHeight( 195 private int measureApproximateListViewHeight(
(...skipping 22 matching lines...) Expand all
165 View view = LayoutInflater.from(context).inflate(R.layout.tabular_contex t_menu, null); 218 View view = LayoutInflater.from(context).inflate(R.layout.tabular_contex t_menu, null);
166 219
167 List<Pair<String, ViewGroup>> viewGroups = new ArrayList<>(); 220 List<Pair<String, ViewGroup>> viewGroups = new ArrayList<>();
168 int maxCount = 0; 221 int maxCount = 0;
169 for (int i = 0; i < itemGroups.size(); i++) { 222 for (int i = 0; i < itemGroups.size(); i++) {
170 Pair<Integer, List<ContextMenuItem>> itemGroup = itemGroups.get(i); 223 Pair<Integer, List<ContextMenuItem>> itemGroup = itemGroups.get(i);
171 maxCount = Math.max(maxCount, itemGroup.second.size()); 224 maxCount = Math.max(maxCount, itemGroup.second.size());
172 } 225 }
173 for (int i = 0; i < itemGroups.size(); i++) { 226 for (int i = 0; i < itemGroups.size(); i++) {
174 Pair<Integer, List<ContextMenuItem>> itemGroup = itemGroups.get(i); 227 Pair<Integer, List<ContextMenuItem>> itemGroup = itemGroups.get(i);
228 // TODO(tedchoc): Pass the ContextMenuGroup identifier to determine if it's an image.
229 boolean isImageTab = itemGroup.first == R.string.contextmenu_image_t itle;
175 viewGroups.add(new Pair<>(context.getString(itemGroup.first), 230 viewGroups.add(new Pair<>(context.getString(itemGroup.first),
176 createContextMenuPageUi(context, params, itemGroup.second, m axCount))); 231 createContextMenuPageUi(
232 context, params, itemGroup.second, isImageTab, maxCo unt)));
177 } 233 }
178 TabularContextMenuViewPager pager = 234 TabularContextMenuViewPager pager =
179 (TabularContextMenuViewPager) view.findViewById(R.id.custom_page r); 235 (TabularContextMenuViewPager) view.findViewById(R.id.custom_page r);
180 pager.setAdapter(new TabularContextMenuPagerAdapter(viewGroups)); 236 pager.setAdapter(new TabularContextMenuPagerAdapter(viewGroups));
181 237
182 TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout); 238 TabLayout tabLayout = (TabLayout) view.findViewById(R.id.tab_layout);
183 if (itemGroups.size() <= 1) { 239 if (itemGroups.size() <= 1) {
184 tabLayout.setVisibility(View.GONE); 240 tabLayout.setVisibility(View.GONE);
185 } 241 }
186 tabLayout.setupWithViewPager((ViewPager) view.findViewById(R.id.custom_p ager)); 242 tabLayout.setupWithViewPager((ViewPager) view.findViewById(R.id.custom_p ager));
187 243
188 return view; 244 return view;
189 } 245 }
190 246
247 public void onImageThumbnailRetrieved(Bitmap bitmap) {
Ted C 2017/03/31 18:48:32 add javadoc
JJ 2017/03/31 19:01:20 Done.
248 if (mHeaderImageView != null) {
249 mHeaderImageView.setImageBitmap(bitmap);
250 }
251 }
252
191 @Override 253 @Override
192 public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) { 254 public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
193 mDialog.dismiss(); 255 mDialog.dismiss();
194 mCallback.onResult((int) id); 256 mCallback.onResult((int) id);
195 } 257 }
196 } 258 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698