Chromium Code Reviews| OLD | NEW |
|---|---|
| 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.infobar.translate; | 5 package org.chromium.chrome.browser.infobar.translate; |
| 6 | 6 |
| 7 import android.content.Context; | 7 import android.content.Context; |
| 8 import android.support.v4.content.ContextCompat; | 8 import android.support.v4.content.ContextCompat; |
| 9 import android.view.ContextThemeWrapper; | 9 import android.view.ContextThemeWrapper; |
| 10 import android.view.LayoutInflater; | 10 import android.view.LayoutInflater; |
| 11 import android.view.View; | 11 import android.view.View; |
| 12 import android.view.ViewGroup; | 12 import android.view.ViewGroup; |
| 13 import android.widget.AdapterView; | 13 import android.widget.AdapterView; |
| 14 import android.widget.ArrayAdapter; | 14 import android.widget.ArrayAdapter; |
| 15 import android.widget.ListPopupWindow; | 15 import android.widget.ListPopupWindow; |
| 16 import android.widget.PopupWindow; | 16 import android.widget.PopupWindow; |
| 17 import android.widget.TextView; | 17 import android.widget.TextView; |
| 18 | 18 |
| 19 import org.chromium.chrome.R; | 19 import org.chromium.chrome.R; |
| 20 import org.chromium.chrome.browser.infobar.TranslateOptions; | |
| 20 | 21 |
| 22 import java.util.ArrayList; | |
| 21 import java.util.List; | 23 import java.util.List; |
| 22 | 24 |
| 23 /** | 25 /** |
| 24 * A Helper class for managing the Translate Overflow Menu. | 26 * A Helper class for managing the Translate Overflow Menu. |
| 25 */ | 27 */ |
| 26 public class TranslateMenuHelper implements AdapterView.OnItemClickListener { | 28 public class TranslateMenuHelper implements AdapterView.OnItemClickListener { |
| 27 private static final String EMPTY_STRING = ""; | 29 private final TranslateMenuListener mMenuListener; |
| 28 private final TranslateMenuItemListener mItemListener; | 30 private final TranslateOptions mOptions; |
| 29 private ContextThemeWrapper mWrapper; | 31 |
| 32 private ContextThemeWrapper mContextWrapper; | |
| 33 private TranslateMenuAdapter mAdapter; | |
| 30 private View mAnchorView; | 34 private View mAnchorView; |
| 31 private TranslateMenuAdapter mAdapter; | 35 |
| 32 private ListPopupWindow mPopup; | 36 private ListPopupWindow mPopup; |
| 33 | 37 |
| 34 /** | 38 /** |
| 35 * Add a divider menu item to list. | |
| 36 * @param list The list of items to show in the menu. | |
| 37 */ | |
| 38 public static void addDivider(List<TranslateMenuElement> list) { | |
| 39 list.add(new TranslateMenuElement( | |
| 40 EMPTY_STRING, EMPTY_STRING, TranslateMenuAdapter.MENU_DIVIDER)); | |
| 41 } | |
| 42 | |
| 43 /** | |
| 44 * Add an overflow menu item to list. | |
| 45 * @param title Title of the menu item | |
| 46 * @param code Code of the menu item | |
| 47 * @param list The list of items to show in the menu. | |
| 48 */ | |
| 49 public static void addOverflowMenuItem( | |
| 50 String title, String code, List<TranslateMenuElement> list) { | |
| 51 list.add(new TranslateMenuElement(title, code, TranslateMenuAdapter.OVER FLOW_MENU_ITEM)); | |
| 52 } | |
| 53 | |
| 54 /** | |
| 55 * Add a source language menu item to list. | |
| 56 * @param title Title of the language | |
| 57 * @param code ISO code of the language | |
| 58 * @param list The list of items to show in the menu. | |
| 59 */ | |
| 60 public static void addSourceLanguageMenuItem( | |
| 61 String title, String code, List<TranslateMenuElement> list) { | |
| 62 list.add(new TranslateMenuElement( | |
| 63 title, code, TranslateMenuAdapter.SOURCE_LANGUAGE_MENU_ITEM)); | |
| 64 } | |
| 65 | |
| 66 /** | |
| 67 * Add a target language menu item to list. | |
| 68 * @param title Title of the language | |
| 69 * @param code ISO code of the language | |
| 70 * @param list The list of items to show in the menu. | |
| 71 */ | |
| 72 public static void addTargetLanguageMenuItem( | |
| 73 String title, String code, List<TranslateMenuElement> list) { | |
| 74 list.add(new TranslateMenuElement( | |
| 75 title, code, TranslateMenuAdapter.TARGET_LANGUAGE_MENU_ITEM)); | |
| 76 } | |
| 77 | |
| 78 /** | |
| 79 * Interface for receiving the click event of menu item. | 39 * Interface for receiving the click event of menu item. |
| 80 */ | 40 */ |
| 81 public interface TranslateMenuItemListener { | 41 public interface TranslateMenuListener { |
| 82 // return true if the menu is dismissed after clicking on the item; ret urn false otherwise. | 42 void onOverflowMenuItemClicked(int itemId); |
| 83 // (when clicking on 'More languages' or 'Page not in this language', we show the language | 43 void onTargetMenuItemClicked(String code); |
| 84 // menu by keeping the menu but replace the items inside.) | 44 void onSourceMenuItemClicked(String code); |
| 85 boolean onTranslateMenuItemClicked(String code, int type); | |
| 86 } | 45 } |
| 87 | 46 |
| 88 public TranslateMenuHelper( | 47 public TranslateMenuHelper(Context context, View anchorView, TranslateOption s options, |
| 89 Context context, View anchorView, TranslateMenuItemListener itemList ener) { | 48 TranslateMenuListener itemListener) { |
| 90 mWrapper = new ContextThemeWrapper(context, R.style.OverflowMenuTheme); | 49 mContextWrapper = new ContextThemeWrapper(context, R.style.OverflowMenuT heme); |
| 91 mAnchorView = anchorView; | 50 mAnchorView = anchorView; |
| 92 mItemListener = itemListener; | 51 mOptions = options; |
| 52 mMenuListener = itemListener; | |
| 53 } | |
| 54 | |
| 55 /** | |
| 56 * Build transalte menu by menu type. | |
| 57 */ | |
| 58 private List<TranslateMenu.MenuItem> getMenuList(int menuType) { | |
| 59 List<TranslateMenu.MenuItem> menuList = new ArrayList<TranslateMenu.Menu Item>(); | |
| 60 if (menuType == TranslateMenu.MENU_OVERFLOW) { | |
| 61 // TODO(googleo): Add language short list above static menu after it s data is ready. | |
| 62 menuList.addAll(TranslateMenu.getOverflowMenu()); | |
| 63 } else { | |
| 64 for (int i = 0; i < mOptions.allLanguages().size(); ++i) { | |
| 65 String code = mOptions.allLanguages().get(i).mLanguageCode; | |
| 66 // Don't show target or source language in the menu list. | |
| 67 if (code.equals(mOptions.targetLanguageCode()) | |
| 68 || code.equals(mOptions.sourceLanguageCode())) { | |
| 69 continue; | |
| 70 } | |
| 71 menuList.add(new TranslateMenu.MenuItem(TranslateMenu.ITEM_LANGU AGE, i, code)); | |
| 72 } | |
| 73 } | |
| 74 return menuList; | |
| 93 } | 75 } |
| 94 | 76 |
| 95 /** | 77 /** |
| 96 * Show the overflow menu. | 78 * Show the overflow menu. |
| 97 * @param list List of menuitems. | |
| 98 */ | 79 */ |
| 99 public void show(List<TranslateMenuElement> list) { | 80 public void show(int menuType) { |
| 100 if (mPopup == null) { | 81 if (mPopup == null) { |
| 101 mPopup = new ListPopupWindow(mWrapper, null, android.R.attr.popupMen uStyle); | 82 mPopup = new ListPopupWindow(mContextWrapper, null, android.R.attr.p opupMenuStyle); |
| 102 mPopup.setModal(true); | 83 mPopup.setModal(true); |
| 103 mPopup.setAnchorView(mAnchorView); | 84 mPopup.setAnchorView(mAnchorView); |
| 104 mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); | 85 mPopup.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED); |
| 105 | 86 |
| 106 // Need to explicitly set the background here. Relying on it being set in the style | 87 // Need to explicitly set the background here. Relying on it being set in the style |
| 107 // caused an incorrectly drawn background. | 88 // caused an incorrectly drawn background. |
| 108 mPopup.setBackgroundDrawable( | 89 mPopup.setBackgroundDrawable( |
| 109 ContextCompat.getDrawable(mWrapper, R.drawable.edge_menu_bg) ); | 90 ContextCompat.getDrawable(mContextWrapper, R.drawable.edge_m enu_bg)); |
| 110 | 91 |
| 111 int popupWidth = mWrapper.getResources().getDimensionPixelSize( | 92 mPopup.setOnItemClickListener(this); |
| 93 | |
| 94 int popupWidth = mContextWrapper.getResources().getDimensionPixelSiz e( | |
| 112 R.dimen.infobar_translate_menu_width); | 95 R.dimen.infobar_translate_menu_width); |
| 113 | |
| 114 // TODO (martiw) make the width dynamic to handle longer items. | 96 // TODO (martiw) make the width dynamic to handle longer items. |
| 115 mPopup.setWidth(popupWidth); | 97 mPopup.setWidth(popupWidth); |
| 116 | 98 |
| 117 mAdapter = new TranslateMenuAdapter( | 99 mAdapter = new TranslateMenuAdapter(menuType); |
| 118 mWrapper, R.id.menu_item_text, list, LayoutInflater.from(mWr apper)); | |
| 119 mPopup.setAdapter(mAdapter); | 100 mPopup.setAdapter(mAdapter); |
| 120 | |
| 121 mPopup.setOnItemClickListener(this); | |
| 122 } else { | 101 } else { |
| 123 mAdapter.clear(); | 102 mAdapter.refreshMenu(menuType); |
| 124 mAdapter.addAll(list); | |
| 125 } | 103 } |
| 126 | 104 |
| 127 if (!mPopup.isShowing()) { | 105 if (!mPopup.isShowing()) { |
| 128 mPopup.show(); | 106 mPopup.show(); |
| 129 mPopup.getListView().setItemsCanFocus(true); | 107 mPopup.getListView().setItemsCanFocus(true); |
| 130 } | 108 } |
| 131 } | 109 } |
| 132 | 110 |
| 133 @Override | 111 @Override |
| 134 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { | 112 public void onItemClick(AdapterView<?> parent, View view, int position, long id) { |
| 135 if (mItemListener.onTranslateMenuItemClicked( | 113 dismiss(); |
| 136 mAdapter.getItem(position).getCode(), mAdapter.getItemViewTy pe(position))) { | 114 |
| 137 dismiss(); | 115 TranslateMenu.MenuItem item = mAdapter.getItem(position); |
| 116 switch (mAdapter.mMenuType) { | |
| 117 case TranslateMenu.MENU_OVERFLOW: | |
| 118 mMenuListener.onOverflowMenuItemClicked(item.mId); | |
| 119 return; | |
| 120 case TranslateMenu.MENU_TARGET_LANGUAGE: | |
| 121 mMenuListener.onTargetMenuItemClicked(item.mCode); | |
| 122 return; | |
| 123 case TranslateMenu.MENU_SOURCE_LANGUAGE: | |
| 124 mMenuListener.onSourceMenuItemClicked(item.mCode); | |
| 125 return; | |
| 126 default: | |
| 127 assert false : "Unsupported Menu Item Id"; | |
| 138 } | 128 } |
| 139 } | 129 } |
| 140 | 130 |
| 141 /** | 131 /** |
| 142 * Dismisses the app menu. | 132 * Dismisses the translate option menu. |
| 143 */ | 133 */ |
| 144 void dismiss() { | 134 private void dismiss() { |
| 145 if (isShowing()) { | 135 if (isShowing()) { |
| 146 mPopup.dismiss(); | 136 mPopup.dismiss(); |
| 147 } | 137 } |
| 148 } | 138 } |
| 149 | 139 |
| 150 /** | 140 /** |
| 151 * @return Whether the app menu is currently showing. | 141 * @return Whether the app menu is currently showing. |
| 152 */ | 142 */ |
| 153 boolean isShowing() { | 143 private boolean isShowing() { |
| 154 if (mPopup == null) { | 144 if (mPopup == null) { |
| 155 return false; | 145 return false; |
| 156 } | 146 } |
| 157 return mPopup.isShowing(); | 147 return mPopup.isShowing(); |
| 158 } | 148 } |
| 159 | 149 |
| 160 /** | 150 /** |
| 161 * The provides the views of the menu items and dividers. | 151 * The provides the views of the menu items and dividers. |
| 162 */ | 152 */ |
| 163 public static final class TranslateMenuAdapter extends ArrayAdapter<Translat eMenuElement> { | 153 private final class TranslateMenuAdapter extends ArrayAdapter<TranslateMenu. MenuItem> { |
| 164 public static final int MENU_DIVIDER = 0; | |
| 165 public static final int OVERFLOW_MENU_ITEM = 1; | |
| 166 public static final int SOURCE_LANGUAGE_MENU_ITEM = 2; | |
| 167 public static final int TARGET_LANGUAGE_MENU_ITEM = 3; | |
| 168 // TODO(martiw) create OVERFLOW_MENU_ITEM_WITH_CHECKBOX_CHECKED and | 154 // TODO(martiw) create OVERFLOW_MENU_ITEM_WITH_CHECKBOX_CHECKED and |
| 169 // OVERFLOW_MENU_ITEM_WITH_CHECKBOX_UNCHECKED for "Always Translate Lang uage" | 155 // OVERFLOW_MENU_ITEM_WITH_CHECKBOX_UNCHECKED for "Always Translate Lang uage" |
| 170 | 156 |
| 171 LayoutInflater mInflater; | 157 private final LayoutInflater mInflater; |
| 158 private int mMenuType; | |
| 172 | 159 |
| 173 public TranslateMenuAdapter(Context context, int textViewResourceId, | 160 public TranslateMenuAdapter(int menuType) { |
| 174 List<TranslateMenuElement> items, LayoutInflater inflater) { | 161 super(mContextWrapper, R.layout.translate_menu_item, getMenuList(men uType)); |
| 175 super(context, textViewResourceId, items); | 162 mInflater = LayoutInflater.from(mContextWrapper); |
| 176 mInflater = inflater; | 163 mMenuType = menuType; |
| 164 } | |
| 165 | |
| 166 private void refreshMenu(int menuType) { | |
| 167 // Don't refresh if the type is same as previous. | |
| 168 if (menuType == mMenuType) { | |
|
gone
2017/04/24 20:12:19
for simple conditionals in java, you can put it on
Leo
2017/04/25 14:08:05
Acknowledged.
| |
| 169 return; | |
| 170 } | |
| 171 | |
| 172 clear(); | |
| 173 | |
| 174 mMenuType = menuType; | |
| 175 addAll(getMenuList(menuType)); | |
| 176 notifyDataSetChanged(); | |
| 177 } | |
| 178 | |
| 179 private String getItemViewText(TranslateMenu.MenuItem item) { | |
| 180 if (mMenuType == TranslateMenu.MENU_OVERFLOW) { | |
| 181 // Overflow menu items are manually defined one by one. | |
| 182 String source = mOptions.sourceLanguageName(); | |
| 183 switch (item.mId) { | |
| 184 case TranslateMenu.ID_OVERFLOW_ALWAYS_TRANSLATE: | |
| 185 return mContextWrapper.getString(R.string.translate_alwa ys_text, source); | |
| 186 case TranslateMenu.ID_OVERFLOW_MORE_LANGUAGE: | |
| 187 return mContextWrapper.getString(R.string.translate_info bar_more_language); | |
| 188 case TranslateMenu.ID_OVERFLOW_NEVER_SITE: | |
| 189 return mContextWrapper.getString(R.string.translate_neve r_translate_site); | |
| 190 case TranslateMenu.ID_OVERFLOW_NEVER_LANGUAGE: | |
| 191 return mContextWrapper.getString( | |
| 192 R.string.translate_never_translate_language, sou rce); | |
| 193 case TranslateMenu.ID_OVERFLOW_NOT_THIS_LANGUAGE: | |
| 194 return mContextWrapper.getString( | |
| 195 R.string.translate_infobar_not_source_language, source); | |
| 196 default: | |
| 197 assert false : "Unexpected Overflow Item Id"; | |
| 198 } | |
| 199 } else { | |
| 200 // Get source and tagert language menu items text by language co de. | |
| 201 return mOptions.getRepresentationByCode(item.mCode); | |
| 202 } | |
| 203 return ""; | |
| 177 } | 204 } |
| 178 | 205 |
| 179 @Override | 206 @Override |
| 180 public int getItemViewType(int position) { | 207 public int getItemViewType(int position) { |
| 181 return getItem(position).getType(); | 208 return getItem(position).mType; |
| 209 } | |
| 210 | |
| 211 @Override | |
| 212 public int getViewTypeCount() { | |
| 213 return TranslateMenu.MENU_ITEM_TYPE_COUNT; | |
| 182 } | 214 } |
| 183 | 215 |
| 184 @Override | 216 @Override |
| 185 public boolean isEnabled(int position) { | 217 public boolean isEnabled(int position) { |
| 186 return getItemViewType(position) != MENU_DIVIDER; | 218 return getItem(position).mId != TranslateMenu.ID_UNDEFINED; |
| 187 } | 219 } |
| 188 | 220 |
| 189 @Override | 221 @Override |
| 190 public View getView(int position, View convertView, ViewGroup parent) { | 222 public View getView(int position, View convertView, ViewGroup parent) { |
| 223 View menuItemView = convertView; | |
| 191 switch (getItemViewType(position)) { | 224 switch (getItemViewType(position)) { |
| 192 case MENU_DIVIDER: | 225 case TranslateMenu.ITEM_DIVIDER: |
| 193 convertView = mInflater.inflate(R.layout.translate_menu_divi der, parent, false); | 226 if (menuItemView == null) { |
| 227 menuItemView = | |
| 228 mInflater.inflate(R.layout.translate_menu_divide r, parent, false); | |
| 229 } | |
| 194 break; | 230 break; |
| 195 case OVERFLOW_MENU_ITEM: | 231 case TranslateMenu.ITEM_CHECKBOX_OPTION: |
| 196 case SOURCE_LANGUAGE_MENU_ITEM: | 232 case TranslateMenu.ITEM_TEXT_OPTION: |
| 197 case TARGET_LANGUAGE_MENU_ITEM: | 233 // TODO(martiw) create the layout for ITEM_TEXT_OPTION and ITEM_ CHECKBOX_OPTION |
| 198 convertView = mInflater.inflate(R.layout.translate_menu_item , parent, false); | 234 case TranslateMenu.ITEM_LANGUAGE: |
| 199 ((TextView) convertView.findViewById(R.id.menu_item_text)) | 235 if (menuItemView == null) { |
| 200 .setText(getItem(position).toString()); | 236 menuItemView = |
| 237 mInflater.inflate(R.layout.translate_menu_item, parent, false); | |
| 238 } | |
| 239 ((TextView) menuItemView.findViewById(R.id.menu_item_text)) | |
| 240 .setText(getItemViewText(getItem(position))); | |
| 201 break; | 241 break; |
| 202 // TODO(martiw) create the layout for OVERFLOW_MENU_ITEM_WITH_CH ECKBOX_CHECKED and | |
| 203 // OVERFLOW_MENU_ITEM_WITH_CHECKBOX_UNCHECKED for "Always Transl ate Language" | |
| 204 default: | 242 default: |
| 205 assert false : "Unexpected MenuItem type"; | 243 assert false : "Unexpected MenuItem type"; |
| 206 } | 244 } |
| 207 return convertView; | 245 return menuItemView; |
| 208 } | |
| 209 } | |
| 210 | |
| 211 /** | |
| 212 * The element that goes inside the menu. | |
| 213 */ | |
| 214 public static final class TranslateMenuElement { | |
| 215 private final String mTitle; | |
| 216 private final String mCode; | |
| 217 private final int mType; | |
| 218 | |
| 219 public TranslateMenuElement(String title, String code, int type) { | |
| 220 mTitle = title; | |
| 221 mCode = code; | |
| 222 mType = type; | |
| 223 } | |
| 224 | |
| 225 public String getCode() { | |
| 226 return mCode; | |
| 227 } | |
| 228 | |
| 229 public int getType() { | |
| 230 return mType; | |
| 231 } | |
| 232 | |
| 233 /** | |
| 234 * This is the text displayed in the menu item. | |
| 235 */ | |
| 236 public String toString() { | |
| 237 return mTitle; | |
| 238 } | 246 } |
| 239 } | 247 } |
| 240 } | 248 } |
| OLD | NEW |