Commit bcce553c authored by Mik Amchislavsky's avatar Mik Amchislavsky Committed by Geoffrey Métais
Browse files

focus related resource improvements


Signed-off-by: default avatarGeoffrey Métais <geoffrey.metais@gmail.com>
parent b54f0d40
......@@ -35,6 +35,7 @@
android:paddingBottom="@dimen/listview_bottom_padding"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:nextFocusUp="@+id/ml_menu_search"
android:nextFocusDown="@id/albums"
android:nextFocusLeft="@id/albums"
android:nextFocusRight="@id/albums" />
......@@ -48,6 +49,7 @@
android:paddingBottom="@dimen/listview_bottom_padding"
android:paddingLeft="20dp"
android:paddingRight="20dp"
android:nextFocusUp="@+id/ml_menu_search"
android:nextFocusDown="@id/songs"
android:nextFocusLeft="@id/songs"
android:nextFocusRight="@id/songs" />
......
......@@ -3,7 +3,12 @@
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root_container"
android:layout_width="match_parent"
android:layout_height="match_parent" >
android:layout_height="match_parent"
android:nextFocusLeft="@+id/ml_menu_search"
android:nextFocusRight="@+id/ml_menu_search"
android:nextFocusUp="@+id/ml_menu_search"
android:nextFocusDown="@+id/ml_menu_search"
android:nextFocusForward="@+id/ml_menu_search">
<org.videolan.vlc.widget.SlidingPaneLayout
xmlns:android="http://schemas.android.com/apk/res/android"
......
......@@ -11,7 +11,8 @@
android:cacheColorHint="#0000"
android:fastScrollEnabled="true"
android:background="?attr/background_menu"
android:nextFocusUp="@+id/ml_menu_search"
android:nextFocusForward="@id/sidelist"
android:nextFocusUp="@id/sidelist"
android:nextFocusDown="@id/sidelist"
android:nextFocusLeft="@id/sidelist"
android:nextFocusRight="@id/sidelist" >
......
......@@ -6,11 +6,13 @@
android:id="@+id/ml_menu_search"
android:icon="@drawable/ic_menu_search_wb"
android:title="@string/searchable_hint"
android:nextFocusDown="@id/ml_menu_search"
vlc:showAsAction="ifRoom" />
<item
android:id="@+id/ml_menu_open_mrl"
android:icon="@drawable/ic_menu_goto_wb"
android:title="@string/open_mrl"
android:nextFocusDown="@id/ml_menu_open_mrl"
vlc:showAsAction="ifRoom" />
<item
android:title="@string/sortby"
......@@ -29,11 +31,13 @@
android:id="@+id/ml_menu_last_playlist"
android:icon="@drawable/ic_menu_revert_wb"
android:title="@string/last_playlist"
android:nextFocusDown="@id/ml_menu_last_playlist"
vlc:showAsAction="ifRoom" />
<item
android:id="@+id/ml_menu_refresh"
android:icon="@drawable/ic_menu_refresh_wb"
android:title="@string/refresh"
android:nextFocusDown="@id/ml_menu_refresh"
vlc:showAsAction="ifRoom" />
<item
android:id="@+id/ml_menu_equalizer"
......
......@@ -6,11 +6,13 @@
android:id="@+id/ml_menu_search"
android:icon="@drawable/ic_menu_search"
android:title="@string/searchable_hint"
android:nextFocusDown="@id/ml_menu_search"
vlc:showAsAction="ifRoom" />
<item
android:id="@+id/ml_menu_open_mrl"
android:icon="@drawable/ic_menu_goto"
android:title="@string/open_mrl"
android:nextFocusDown="@id/ml_menu_open_mrl"
vlc:showAsAction="ifRoom" />
<item
android:title="@string/sortby"
......@@ -29,11 +31,13 @@
android:id="@+id/ml_menu_last_playlist"
android:icon="@drawable/ic_menu_revert"
android:title="@string/last_playlist"
android:nextFocusDown="@id/ml_menu_last_playlist"
vlc:showAsAction="ifRoom" />
<item
android:id="@+id/ml_menu_refresh"
android:icon="@drawable/ic_menu_refresh"
android:title="@string/refresh"
android:nextFocusDown="@id/ml_menu_refresh"
vlc:showAsAction="ifRoom" />
<item
android:id="@+id/ml_menu_equalizer"
......
......@@ -6,11 +6,13 @@
android:id="@+id/ml_menu_search"
android:icon="@drawable/ic_menu_search_wb"
android:title="@string/searchable_hint"
android:nextFocusDown="@id/ml_menu_search"
vlc:showAsAction="ifRoom" />
<item
android:id="@+id/ml_menu_open_mrl"
android:icon="@drawable/ic_menu_goto_wb"
android:title="@string/open_mrl"
android:nextFocusDown="@id/ml_menu_open_mrl"
vlc:showAsAction="ifRoom" />
<item
android:title="@string/sortby"
......@@ -29,11 +31,13 @@
android:id="@+id/ml_menu_last_playlist"
android:icon="@drawable/ic_menu_revert_wb"
android:title="@string/last_playlist"
android:nextFocusDown="@id/ml_menu_last_playlist"
vlc:showAsAction="ifRoom" />
<item
android:id="@+id/ml_menu_refresh"
android:icon="@drawable/ic_menu_refresh_wb"
android:title="@string/refresh"
android:nextFocusDown="@id/ml_menu_refresh"
vlc:showAsAction="ifRoom" />
<item
android:id="@+id/ml_menu_equalizer"
......
......@@ -79,6 +79,14 @@ public class DirectoryViewFragment extends ListFragment implements IRefreshable,
getActivity().registerReceiver(messageReceiver, filter);
}
private void focusHelper(boolean idIsEmpty) {
View parent = View.inflate(getActivity(),
R.layout.directory_view, null);
MainActivity main = (MainActivity)getActivity();
main.setMenuFocusDown(idIsEmpty, android.R.id.list);
main.setSearchAsFocusDown(idIsEmpty, parent, android.R.id.list);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
......@@ -87,6 +95,12 @@ public class DirectoryViewFragment extends ListFragment implements IRefreshable,
View v = inflater.inflate(R.layout.directory_view, container, false);
setListAdapter(mDirectoryAdapter);
final ListView listView = (ListView)v.findViewById(android.R.id.list);
listView.setNextFocusUpId(R.id.ml_menu_search);
listView.setNextFocusLeftId(android.R.id.list);
listView.setNextFocusRightId(android.R.id.list);
listView.setNextFocusForwardId(android.R.id.list);
focusHelper(mDirectoryAdapter.getCount() == 0);
listView.requestFocus();
listView.setOnItemLongClickListener(new OnItemLongClickListener() {
@Override
......@@ -204,8 +218,11 @@ public class DirectoryViewFragment extends ListFragment implements IRefreshable,
@Override
public void refresh() {
if (mDirectoryAdapter != null)
if (mDirectoryAdapter != null) {
mDirectoryAdapter.refresh();
focusHelper(mDirectoryAdapter.getCount() == 0);
} else
focusHelper(true);
}
private final BroadcastReceiver messageReceiver = new BroadcastReceiver() {
......
......@@ -55,6 +55,15 @@ public class HistoryFragment extends ListFragment implements IRefreshable {
Log.d(TAG, "HistoryFragment()");
}
private void focusHelper(boolean idIsEmpty) {
View parent = View.inflate(getActivity(), R.layout.history_list,
null);
MainActivity main = (MainActivity)getActivity();
main.setMenuFocusDown(idIsEmpty, android.R.id.list);
main.setSearchAsFocusDown(idIsEmpty, parent,
android.R.id.list);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
......@@ -63,6 +72,12 @@ public class HistoryFragment extends ListFragment implements IRefreshable {
View v = inflater.inflate(R.layout.history_list, container, false);
setListAdapter(mHistoryAdapter);
final ListView listView = (ListView)v.findViewById(android.R.id.list);
listView.setNextFocusUpId(R.id.ml_menu_search);
listView.setNextFocusLeftId(android.R.id.list);
listView.setNextFocusRightId(android.R.id.list);
listView.setNextFocusForwardId(android.R.id.list);
focusHelper(mHistoryAdapter.getCount() == 0);
listView.requestFocus();
registerForContextMenu(listView);
return v;
}
......@@ -108,7 +123,10 @@ public class HistoryFragment extends ListFragment implements IRefreshable {
@Override
public void refresh() {
Log.d(TAG, "Refreshing view!");
if( mHistoryAdapter != null )
if( mHistoryAdapter != null ) {
mHistoryAdapter.refresh();
focusHelper(mHistoryAdapter.getCount() == 0);
} else
focusHelper(true);
}
}
......@@ -134,6 +134,8 @@ public class MainActivity extends ActionBarActivity {
private Handler mHandler = new MainActivityHandler(this);
private int mFocusedPrior = 0;
private int mActionBarIconId = -1;
Menu mMenu;
@Override
protected void onCreate(Bundle savedInstanceState) {
......@@ -565,6 +567,7 @@ public class MainActivity extends ActionBarActivity {
*/
@Override
public boolean onCreateOptionsMenu(Menu menu) {
mMenu = menu;
/* Note: on Android 3.0+ with an action bar this method
* is called while the view is created. This can happen
* any time after onCreate.
......@@ -695,13 +698,99 @@ public class MainActivity extends ActionBarActivity {
}
}
public void setMenuFocusDown(boolean idIsEmpty, int id) {
if (mMenu == null)
return;
//Save menu items ids for focus control
final int[] menu_controls = new int[mMenu.size()+1];
for (int i = 0 ; i < mMenu.size() ; i++){
menu_controls[i] = mMenu.getItem(i).getItemId();
}
menu_controls[mMenu.size()] = mActionBarIconId;
/*menu_controls = new int[]{R.id.ml_menu_search,
R.id.ml_menu_open_mrl, R.id.ml_menu_sortby,
R.id.ml_menu_last_playlist, R.id.ml_menu_refresh,
mActionBarIconId};*/
int pane = mSlidingPane.getState();
for(int r : menu_controls) {
View v = findViewById(r);
if (v != null) {
if (!idIsEmpty)
v.setNextFocusDownId(id);
else {
if (pane == mSlidingPane.STATE_CLOSED) {
v.setNextFocusDownId(R.id.play_pause);
} else if (pane == mSlidingPane.STATE_OPENED) {
v.setNextFocusDownId(R.id.header_play_pause);
} else if (pane ==
mSlidingPane.STATE_OPENED_ENTIRELY) {
v.setNextFocusDownId(r);
}
}
}
}
}
public void setSearchAsFocusDown(boolean idIsEmpty, View parentView,
int id) {
View playPause = findViewById(R.id.header_play_pause);
View v_main = LayoutInflater.from(this).inflate(R.layout.main, null);
if (!idIsEmpty) {
View list = null;
int pane = mSlidingPane.getState();
if (parentView == null)
list = v_main.findViewById(id);
else
list = parentView.findViewById(id);
if (list != null) {
if (pane == mSlidingPane.STATE_OPENED_ENTIRELY) {
list.setNextFocusDownId(id);
} else if (pane == mSlidingPane.STATE_OPENED) {
list.setNextFocusDownId(R.id.header_play_pause);
playPause.setNextFocusUpId(id);
}
}
} else {
playPause.setNextFocusUpId(R.id.ml_menu_search);
}
}
// Note. onKeyDown will not occur while moving within a list
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (mFocusedPrior == 0)
setMenuFocusDown(true, 0);
mFocusedPrior = getCurrentFocus().getId();
return super.onKeyDown(keyCode, event);
}
// Note. onKeyDown will not occur while moving within a list
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
View v = getCurrentFocus();
if ((mActionBarIconId == -1) &&
(v.getId() == -1) &&
(v.getNextFocusDownId() == -1) &&
(v.getNextFocusUpId() == -1) &&
(v.getNextFocusLeftId() == -1) &&
(v.getNextFocusRightId() == -1) &&
(v.getNextFocusForwardId() == -1)) {
mActionBarIconId = Util.generateViewId();
v.setId(mActionBarIconId);
v.setNextFocusUpId(mActionBarIconId);
v.setNextFocusDownId(mActionBarIconId);
v.setNextFocusLeftId(mActionBarIconId);
v.setNextFocusRightId(R.id.ml_menu_search);
v.setNextFocusForwardId(mActionBarIconId);
findViewById(R.id.ml_menu_search).setNextFocusLeftId(
mActionBarIconId);
}
return super.onKeyUp(keyCode, event);
}
private void reloadPreferences() {
SharedPreferences sharedPrefs = getSharedPreferences("MainActivity", MODE_PRIVATE);
mCurrentFragment = sharedPrefs.getString("fragment", "video");
......@@ -846,6 +935,10 @@ public class MainActivity extends ActionBarActivity {
mAudioPlayerFilling.setVisibility(View.VISIBLE);
}
public int getSlidingPaneState() {
return mSlidingPane.getState();
}
/**
* Slide down the audio player.
* @return true on success else false.
......
......@@ -177,6 +177,13 @@ public class AudioBrowserFragment extends Fragment {
mMediaLibrary.addUpdateHandler(mHandler);
}
private void focusHelper(boolean idIsEmpty, int listId) {
View parent = getView();
MainActivity main = (MainActivity)getActivity();
main.setMenuFocusDown(false, R.id.header);
main.setSearchAsFocusDown(idIsEmpty, parent, listId);
}
// Focus support. Start.
View.OnKeyListener keyListener = new View.OnKeyListener() {
@Override
......@@ -227,6 +234,10 @@ public class AudioBrowserFragment extends Fragment {
// assigned in onSwitched following mHeader.scroll
mFlingViewPosition = newPosition;
((MainActivity)getActivity()).setSearchAsFocusDown(
vList.getCount() == 0, getView(),
lists[newPosition]);
}
}
......@@ -442,10 +453,13 @@ public class AudioBrowserFragment extends Fragment {
private void updateLists() {
List<Media> audioList = MediaLibrary.getInstance().getAudioItems();
int listId = MODE_TOTAL;
int i;
if (audioList.isEmpty())
if (audioList.isEmpty()){
mEmptyView.setVisibility(View.VISIBLE);
else
listId = MODE_SONG;
} else
mEmptyView.setVisibility(View.GONE);
mSongsAdapter.clear();
......@@ -454,39 +468,47 @@ public class AudioBrowserFragment extends Fragment {
mGenresAdapter.clear();
Collections.sort(audioList, MediaComparators.byName);
for (int i = 0; i < audioList.size(); i++) {
for (i = 0; i < audioList.size(); i++) {
Media media = audioList.get(i);
mSongsAdapter.add(media.getTitle(), media.getArtist(), media);
}
mSongsAdapter.addScrollSections();
if ((listId == MODE_TOTAL) && (i > 0))
listId = MODE_SONG;
Collections.sort(audioList, MediaComparators.byArtist);
for (int i = 0; i < audioList.size(); i++) {
for (i = 0; i < audioList.size(); i++) {
Media media = audioList.get(i);
mArtistsAdapter.add(media.getArtist(), null, media);
}
mArtistsAdapter.addLetterSeparators();
if (i > 0)
listId = MODE_ARTIST;
Collections.sort(audioList, MediaComparators.byAlbum);
for (int i = 0; i < audioList.size(); i++) {
for (i = 0; i < audioList.size(); i++) {
Media media = audioList.get(i);
mAlbumsAdapter.add(media.getAlbum(), media.getArtist(), media);
}
mAlbumsAdapter.addLetterSeparators();
if ((listId == MODE_TOTAL) && (i > 0))
listId = MODE_ALBUM;
Collections.sort(audioList, MediaComparators.byGenre);
for (int i = 0; i < audioList.size(); i++) {
for (i = 0; i < audioList.size(); i++) {
Media media = audioList.get(i);
mGenresAdapter.add(media.getGenre(), null, media);
}
mGenresAdapter.addLetterSeparators();
if ((listId == MODE_TOTAL) && (i>0))
listId = MODE_GENRE;
mSongsAdapter.notifyDataSetChanged();
mArtistsAdapter.notifyDataSetChanged();
mAlbumsAdapter.notifyDataSetChanged();
mGenresAdapter.notifyDataSetChanged();
// Refresh the fast scroll data, since SectionIndexer doesn't respect notifyDataSetChanged
int[] lists = { R.id.songs_list, R.id.artists_list, R.id.albums_list, R.id.genres_list };
int[] lists = { R.id.artists_list, R.id.albums_list, R.id.songs_list, R.id.genres_list };
if(getView() != null) {
for(int r : lists) {
ListView l = (ListView)getView().findViewById(r);
......@@ -494,6 +516,7 @@ public class AudioBrowserFragment extends Fragment {
l.setFastScrollEnabled(true);
}
}
focusHelper(listId == MODE_TOTAL, lists[listId]);
}
AudioBrowserListAdapter.ContextPopupMenuListener mContextPopupMenuListener
......
......@@ -415,6 +415,14 @@ public class VideoGridFragment extends SherlockGridFragment implements ISortable
}
}
private void focusHelper(boolean idIsEmpty) {
View parent = getView();
MainActivity main = (MainActivity)getActivity();
main.setMenuFocusDown(idIsEmpty, android.R.id.list);
main.setSearchAsFocusDown(idIsEmpty, parent,
android.R.id.list);
}
private void updateList() {
List<Media> itemList = mMediaLibrary.getVideoItems();
......@@ -447,7 +455,9 @@ public class VideoGridFragment extends SherlockGridFragment implements ISortable
mGVFirstVisiblePos = mGridView.getFirstVisiblePosition();
mGridView.setSelection(mGVFirstVisiblePos);
mGridView.requestFocus();
}
focusHelper(false);
} else
focusHelper(true);
}
@Override
......
......@@ -24,6 +24,7 @@ import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.concurrent.atomic.AtomicInteger;
import org.videolan.libvlc.LibVLC;
import org.videolan.libvlc.Media;
......@@ -39,6 +40,8 @@ import android.widget.TextView;
import android.widget.Toast;
public class Util {
private static final AtomicInteger sNextGeneratedId = new AtomicInteger(1);
/** Print an on-screen message to alert the user */
public static void toaster(Context context, int stringId) {
Toast.makeText(context, stringId, Toast.LENGTH_SHORT).show();
......@@ -127,4 +130,22 @@ public class Util {
t.setSelected(true);
}
}
/**
* Generate a value suitable for use in {@link #setId(int)}.
* This value will not collide with ID values generated at build time by aapt for R.id.
*
* @return a generated ID value
*/
public static int generateViewId() {
for (;;) {
final int result = sNextGeneratedId.get();
// aapt-generated IDs have the high byte nonzero; clamp to the range under that.
int newValue = result + 1;
if (newValue > 0x00FFFFFF) newValue = 1; // Roll over to 1, not 0.
if (sNextGeneratedId.compareAndSet(result, newValue)) {
return result;
}
}
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment