mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 894045 - Add gamepad support for search suggestions. r=lucasr
This commit is contained in:
parent
395e7d2114
commit
771cecaa36
@ -239,6 +239,22 @@ public class BrowserSearch extends HomeFragment
|
||||
}
|
||||
});
|
||||
|
||||
final ListSelectionListener listener = new ListSelectionListener();
|
||||
mList.setOnItemSelectedListener(listener);
|
||||
mList.setOnFocusChangeListener(listener);
|
||||
|
||||
mList.setOnKeyListener(new View.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, android.view.KeyEvent event) {
|
||||
final View selected = mList.getSelectedView();
|
||||
|
||||
if (selected instanceof SearchEngineRow) {
|
||||
return selected.onKeyDown(keyCode, event);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
registerForContextMenu(mList);
|
||||
registerEventListener("SearchEngines:Data");
|
||||
|
||||
@ -434,6 +450,18 @@ public class BrowserSearch extends HomeFragment
|
||||
|
||||
yesButton.setOnClickListener(listener);
|
||||
noButton.setOnClickListener(listener);
|
||||
|
||||
// If the prompt gains focus, automatically pass focus to the
|
||||
// yes button in the prompt.
|
||||
final View prompt = mSuggestionsOptInPrompt.findViewById(R.id.prompt);
|
||||
prompt.setOnFocusChangeListener(new View.OnFocusChangeListener() {
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
yesButton.requestFocus();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setSuggestionsEnabled(final boolean enabled) {
|
||||
@ -632,6 +660,12 @@ public class BrowserSearch extends HomeFragment
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int position) {
|
||||
// If we're using a gamepad or keyboard, allow the row to be
|
||||
// focused so it can pass the focus to its child suggestion views.
|
||||
if (!mList.isInTouchMode()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the suggestion row only contains one item (the user-entered
|
||||
// query), allow the entire row to be clickable; clicking the row
|
||||
// has the same effect as clicking the single suggestion. If the
|
||||
@ -801,4 +835,46 @@ public class BrowserSearch extends HomeFragment
|
||||
setSuggestions(new ArrayList<String>());
|
||||
}
|
||||
}
|
||||
|
||||
private static class ListSelectionListener implements View.OnFocusChangeListener,
|
||||
AdapterView.OnItemSelectedListener {
|
||||
private SearchEngineRow mSelectedEngineRow;
|
||||
|
||||
@Override
|
||||
public void onFocusChange(View v, boolean hasFocus) {
|
||||
if (hasFocus) {
|
||||
View selectedRow = ((ListView) v).getSelectedView();
|
||||
if (selectedRow != null) {
|
||||
selectRow(selectedRow);
|
||||
}
|
||||
} else {
|
||||
deselectRow();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
deselectRow();
|
||||
selectRow(view);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
deselectRow();
|
||||
}
|
||||
|
||||
private void selectRow(View row) {
|
||||
if (row instanceof SearchEngineRow) {
|
||||
mSelectedEngineRow = (SearchEngineRow) row;
|
||||
mSelectedEngineRow.onSelected();
|
||||
}
|
||||
}
|
||||
|
||||
private void deselectRow() {
|
||||
if (mSelectedEngineRow != null) {
|
||||
mSelectedEngineRow.onDeselected();
|
||||
mSelectedEngineRow = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -16,6 +16,7 @@ import org.mozilla.gecko.widget.FaviconView;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.animation.AlphaAnimation;
|
||||
@ -52,6 +53,9 @@ class SearchEngineRow extends AnimatedHeightLayout {
|
||||
// On edit suggestion listener
|
||||
private OnEditSuggestionListener mEditSuggestionListener;
|
||||
|
||||
// Selected suggestion view
|
||||
private int mSelectedView = 0;
|
||||
|
||||
public SearchEngineRow(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
@ -179,5 +183,64 @@ class SearchEngineRow extends AnimatedHeightLayout {
|
||||
for (int i = suggestionCount + 1; i < recycledSuggestionCount; i++) {
|
||||
mSuggestionView.getChildAt(i).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
// Make sure mSelectedView is still valid
|
||||
if (mSelectedView >= mSuggestionView.getChildCount()) {
|
||||
mSelectedView = mSuggestionView.getChildCount() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onKeyDown(int keyCode, android.view.KeyEvent event) {
|
||||
final View suggestion = mSuggestionView.getChildAt(mSelectedView);
|
||||
|
||||
if (event.getAction() != android.view.KeyEvent.ACTION_DOWN) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (event.getKeyCode()) {
|
||||
case KeyEvent.KEYCODE_DPAD_RIGHT:
|
||||
final View nextSuggestion = mSuggestionView.getChildAt(mSelectedView + 1);
|
||||
if (nextSuggestion != null) {
|
||||
changeSelectedSuggestion(suggestion, nextSuggestion);
|
||||
mSelectedView++;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent.KEYCODE_DPAD_LEFT:
|
||||
final View prevSuggestion = mSuggestionView.getChildAt(mSelectedView - 1);
|
||||
if (prevSuggestion != null) {
|
||||
changeSelectedSuggestion(suggestion, prevSuggestion);
|
||||
mSelectedView--;
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent.KEYCODE_BUTTON_A:
|
||||
// TODO: handle long pressing for editing suggestions
|
||||
return suggestion.performClick();
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private void changeSelectedSuggestion(View oldSuggestion, View newSuggestion) {
|
||||
oldSuggestion.setDuplicateParentStateEnabled(false);
|
||||
newSuggestion.setDuplicateParentStateEnabled(true);
|
||||
oldSuggestion.refreshDrawableState();
|
||||
newSuggestion.refreshDrawableState();
|
||||
}
|
||||
|
||||
public void onSelected() {
|
||||
mSelectedView = 0;
|
||||
mUserEnteredView.setDuplicateParentStateEnabled(true);
|
||||
mUserEnteredView.refreshDrawableState();
|
||||
}
|
||||
|
||||
public void onDeselected() {
|
||||
final View suggestion = mSuggestionView.getChildAt(mSelectedView);
|
||||
suggestion.setDuplicateParentStateEnabled(false);
|
||||
suggestion.refreshDrawableState();
|
||||
}
|
||||
}
|
||||
|
@ -7,5 +7,6 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/search_row_height"
|
||||
android:duplicateParentState="true"
|
||||
android:paddingTop="7dp"
|
||||
android:paddingBottom="7dp"/>
|
||||
|
@ -5,24 +5,25 @@
|
||||
|
||||
<merge xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<org.mozilla.gecko.widget.FaviconView android:id="@+id/suggestion_icon"
|
||||
android:layout_width="@dimen/favicon_bg"
|
||||
android:layout_height="@dimen/favicon_bg"
|
||||
android:layout_marginLeft="10dip"
|
||||
android:layout_marginRight="10dip"
|
||||
android:layout_centerVertical="true"
|
||||
android:minWidth="@dimen/favicon_bg"
|
||||
android:minHeight="@dimen/favicon_bg"/>
|
||||
<org.mozilla.gecko.widget.FaviconView android:id="@+id/suggestion_icon"
|
||||
android:layout_width="@dimen/favicon_bg"
|
||||
android:layout_height="@dimen/favicon_bg"
|
||||
android:layout_marginLeft="10dip"
|
||||
android:layout_marginRight="10dip"
|
||||
android:layout_centerVertical="true"
|
||||
android:minWidth="@dimen/favicon_bg"
|
||||
android:minHeight="@dimen/favicon_bg"/>
|
||||
|
||||
<org.mozilla.gecko.FlowLayout android:id="@+id/suggestion_layout"
|
||||
android:layout_toRightOf="@id/suggestion_icon"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:duplicateParentState="true"
|
||||
android:layout_marginRight="10dip">
|
||||
|
||||
<include layout="@layout/suggestion_item"
|
||||
android:id="@+id/suggestion_user_entered"/>
|
||||
<include layout="@layout/suggestion_item"
|
||||
android:id="@+id/suggestion_user_entered"/>
|
||||
|
||||
</org.mozilla.gecko.FlowLayout>
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user