mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 876765 - Part 3: Enable navigating to search suggestions with gamepad. r=lucasr
This commit is contained in:
parent
29f9c4f4cb
commit
19bfc66f26
@ -6,12 +6,14 @@
|
||||
package org.mozilla.gecko;
|
||||
|
||||
import org.mozilla.gecko.AwesomeBarTabs.OnUrlOpenListener;
|
||||
import org.mozilla.gecko.util.GamepadUtils;
|
||||
import org.mozilla.gecko.util.StringUtils;
|
||||
import org.mozilla.gecko.widget.FaviconView;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.TypedArray;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
@ -37,6 +39,9 @@ class SearchEngineRow extends AnimatedHeightLayout {
|
||||
// Search engine associated with this view
|
||||
private SearchEngine mSearchEngine;
|
||||
|
||||
// Selected suggestion view
|
||||
private int mSelectedView = 0;
|
||||
|
||||
// Event listeners for suggestion views
|
||||
private final OnClickListener mClickListener;
|
||||
private final OnLongClickListener mLongClickListener;
|
||||
@ -163,5 +168,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();
|
||||
}
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
||||
mView = (LinearLayout) (LayoutInflater.from(mContext).inflate(R.layout.awesomebar_allpages_list, null));
|
||||
mView.setTag(TAG);
|
||||
|
||||
ListView list = getListView();
|
||||
final ListView list = getListView();
|
||||
list.setTag(TAG);
|
||||
((Activity)mContext).registerForContextMenu(list);
|
||||
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@ -136,6 +136,23 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
||||
AwesomeBarCursorAdapter adapter = getCursorAdapter();
|
||||
list.setAdapter(adapter);
|
||||
list.setOnTouchListener(mListListener);
|
||||
|
||||
final ListSelectionListener listener = new ListSelectionListener();
|
||||
list.setOnItemSelectedListener(listener);
|
||||
list.setOnFocusChangeListener(listener);
|
||||
|
||||
list.setOnKeyListener(new View.OnKeyListener() {
|
||||
@Override
|
||||
public boolean onKey(View v, int keyCode, android.view.KeyEvent event) {
|
||||
View selected = list.getSelectedView();
|
||||
|
||||
if (selected instanceof SearchEngineRow) {
|
||||
return ((SearchEngineRow) selected).onKeyDown(keyCode, event);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return mView;
|
||||
@ -461,6 +478,12 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
||||
|
||||
@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 (!getListView().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
|
||||
@ -879,4 +902,46 @@ public class AllPagesTab extends AwesomeBarTab implements GeckoEventListener {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,4 +7,5 @@
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="@dimen/awesomebar_row_height"
|
||||
android:duplicateParentState="true"
|
||||
android:padding="7dp"/>
|
||||
|
@ -17,6 +17,7 @@
|
||||
<org.mozilla.gecko.FlowLayout android:id="@+id/suggestion_layout"
|
||||
android:layout_toRightOf="@id/suggestion_icon"
|
||||
android:layout_width="wrap_content"
|
||||
android:duplicateParentState="true"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<include layout="@layout/suggestion_item"
|
||||
|
@ -10,7 +10,6 @@
|
||||
android:background="@drawable/suggestion_selector"
|
||||
android:gravity="center_vertical"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:padding="7dp">
|
||||
|
||||
<ImageView android:id="@+id/suggestion_magnifier"
|
||||
|
Loading…
Reference in New Issue
Block a user