OSDN Git Service

Eleven: Add the context menu items to the 2nd layer
[android-x86/packages-apps-Eleven.git] / src / com / cyngn / eleven / ui / fragments / profile / BasicSongFragment.java
index 549024e..4ff9882 100644 (file)
 
 package com.cyngn.eleven.ui.fragments.profile;
 
+import android.app.Activity;
 import android.os.Bundle;
+import android.os.SystemClock;
 import android.support.v4.app.Fragment;
 import android.support.v4.app.LoaderManager.LoaderCallbacks;
 import android.support.v4.content.Loader;
-import android.view.ContextMenu;
-import android.view.ContextMenu.ContextMenuInfo;
 import android.view.LayoutInflater;
-import android.view.Menu;
-import android.view.SubMenu;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.AbsListView;
 import android.widget.AdapterView;
-import android.widget.AdapterView.AdapterContextMenuInfo;
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.ListView;
-import android.widget.TextView;
 
+import com.cyngn.eleven.MusicStateListener;
 import com.cyngn.eleven.R;
 import com.cyngn.eleven.adapters.SongAdapter;
-import com.cyngn.eleven.menu.CreateNewPlaylist;
-import com.cyngn.eleven.menu.DeleteDialog;
-import com.cyngn.eleven.menu.FragmentMenuItems;
 import com.cyngn.eleven.model.Song;
 import com.cyngn.eleven.recycler.RecycleHolder;
-import com.cyngn.eleven.utils.MusicUtils;
-import com.cyngn.eleven.utils.NavUtils;
+import com.cyngn.eleven.sectionadapter.SectionAdapter;
+import com.cyngn.eleven.sectionadapter.SectionListContainer;
+import com.cyngn.eleven.ui.activities.BaseActivity;
+import com.cyngn.eleven.utils.PopupMenuHelper;
+import com.cyngn.eleven.utils.SongPopupMenuHelper;
+import com.cyngn.eleven.widgets.IPopupMenuCallback;
 import com.cyngn.eleven.widgets.NoResultsContainer;
 
-import java.util.List;
+import java.util.TreeSet;
 
 /**
  * This class is used to display all of the songs
  *
  * @author Andrew Neal (andrewdneal@gmail.com)
  */
-public abstract class BasicSongFragment extends Fragment implements LoaderCallbacks<List<Song>>,
-        OnItemClickListener {
+public abstract class BasicSongFragment extends Fragment implements
+        LoaderCallbacks<SectionListContainer<Song>>, OnItemClickListener, MusicStateListener {
 
     /**
      * Fragment UI
@@ -58,7 +56,7 @@ public abstract class BasicSongFragment extends Fragment implements LoaderCallba
     /**
      * The adapter for the list
      */
-    protected SongAdapter mAdapter;
+    protected SectionAdapter<Song, SongAdapter> mAdapter;
 
     /**
      * The list view
@@ -66,29 +64,24 @@ public abstract class BasicSongFragment extends Fragment implements LoaderCallba
     protected ListView mListView;
 
     /**
-     * Represents a song
+     * Pop up menu helper
      */
-    protected Song mSong;
+    private PopupMenuHelper mPopupMenuHelper;
 
     /**
-     * Position of a context menu item
-     */
-    protected int mSelectedPosition;
-
-    /**
-     * Id of a context menu item
-     */
-    protected long mSelectedId;
-
-    /**
-     * Song, album, and artist name used in the context menu
+     * Empty constructor as per the {@link Fragment} documentation
      */
-    protected String mSongName, mAlbumName, mArtistName;
+    public BasicSongFragment() {
+    }
 
     /**
-     * Empty constructor as per the {@link Fragment} documentation
+     * {@inheritDoc}
      */
-    public BasicSongFragment() {
+    @Override
+    public void onAttach(final Activity activity) {
+        super.onAttach(activity);
+        // Register the music status listener
+        ((BaseActivity)activity).setMusicStateListenerListener(this);
     }
 
     /**
@@ -97,8 +90,31 @@ public abstract class BasicSongFragment extends Fragment implements LoaderCallba
     @Override
     public void onCreate(final Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
-        // Create the adpater
+        mPopupMenuHelper = new SongPopupMenuHelper(getActivity(), getFragmentManager()) {
+            @Override
+            public Song getSong(int position) {
+                return mAdapter.getTItem(position);
+            }
+
+            @Override
+            protected void updateMenuIds(PopupMenuType type, TreeSet<Integer> set) {
+                super.updateMenuIds(type, set);
+                BasicSongFragment.this.updateMenuIds(set);
+            }
+        };
+
+        // Create the adapter
         mAdapter = createAdapter();
+        mAdapter.setPopupMenuClickedListener(new IPopupMenuCallback.IListener() {
+            @Override
+            public void onPopupMenuClicked(View v, int position) {
+                mPopupMenuHelper.showPopupMenu(v, position);
+            }
+        });
+    }
+
+    protected void updateMenuIds(TreeSet<Integer> set) {
+        // do nothing - let subclasses override
     }
 
     /**
@@ -115,8 +131,6 @@ public abstract class BasicSongFragment extends Fragment implements LoaderCallba
         mListView.setAdapter(mAdapter);
         // Release any references to the recycled Views
         mListView.setRecyclerListener(new RecycleHolder());
-        // Listen for ContextMenus to be created
-        mListView.setOnCreateContextMenuListener(this);
         // Play the selected song
         mListView.setOnItemClickListener(this);
         // To help make scrolling smooth
@@ -126,9 +140,9 @@ public abstract class BasicSongFragment extends Fragment implements LoaderCallba
                 // Pause disk cache access to ensure smoother scrolling
                 if (scrollState == AbsListView.OnScrollListener.SCROLL_STATE_FLING
                         || scrollState == AbsListView.OnScrollListener.SCROLL_STATE_TOUCH_SCROLL) {
-                    mAdapter.setPauseDiskCache(true);
+                    mAdapter.getUnderlyingAdapter().setPauseDiskCache(true);
                 } else {
-                    mAdapter.setPauseDiskCache(false);
+                    mAdapter.getUnderlyingAdapter().setPauseDiskCache(false);
                     mAdapter.notifyDataSetChanged();
                 }
             }
@@ -156,8 +170,6 @@ public abstract class BasicSongFragment extends Fragment implements LoaderCallba
     @Override
     public void onActivityCreated(final Bundle savedInstanceState) {
         super.onActivityCreated(savedInstanceState);
-        // Enable the options menu
-        setHasOptionsMenu(true);
         // Start the loader
         getLoaderManager().initLoader(getLoaderId(), null, this);
     }
@@ -166,102 +178,6 @@ public abstract class BasicSongFragment extends Fragment implements LoaderCallba
      * {@inheritDoc}
      */
     @Override
-    public void onCreateContextMenu(final ContextMenu menu, final View v,
-                                    final ContextMenuInfo menuInfo) {
-        super.onCreateContextMenu(menu, v, menuInfo);
-        // Get the position of the selected item
-        final AdapterContextMenuInfo info = (AdapterContextMenuInfo) menuInfo;
-        mSelectedPosition = info.position;
-        // Creat a new song
-        mSong = mAdapter.getItem(mSelectedPosition);
-        mSelectedId = mSong.mSongId;
-        mSongName = mSong.mSongName;
-        mAlbumName = mSong.mAlbumName;
-        mArtistName = mSong.mArtistName;
-
-        // Play the song
-        menu.add(getGroupId(), FragmentMenuItems.PLAY_SELECTION, Menu.NONE,
-                getString(R.string.context_menu_play_selection));
-
-        // Play next
-        menu.add(getGroupId(), FragmentMenuItems.PLAY_NEXT, Menu.NONE,
-                getString(R.string.context_menu_play_next));
-
-        // Add the song to the queue
-        menu.add(getGroupId(), FragmentMenuItems.ADD_TO_QUEUE, Menu.NONE,
-                getString(R.string.add_to_queue));
-
-        // Add the song to a playlist
-        final SubMenu subMenu = menu.addSubMenu(getGroupId(), FragmentMenuItems.ADD_TO_PLAYLIST,
-                Menu.NONE, R.string.add_to_playlist);
-        MusicUtils.makePlaylistMenu(getActivity(), getGroupId(), subMenu);
-
-        // View more content by the song artist
-        menu.add(getGroupId(), FragmentMenuItems.MORE_BY_ARTIST, Menu.NONE,
-                getString(R.string.context_menu_more_by_artist));
-
-        // Make the song a ringtone
-        menu.add(getGroupId(), FragmentMenuItems.USE_AS_RINGTONE, Menu.NONE,
-                getString(R.string.context_menu_use_as_ringtone));
-
-        // Delete the song
-        menu.add(getGroupId(), FragmentMenuItems.DELETE, Menu.NONE,
-                getString(R.string.context_menu_delete));
-    }
-
-    @Override
-    public boolean onContextItemSelected(final android.view.MenuItem item) {
-        if (item.getGroupId() == getGroupId()) {
-            switch (item.getItemId()) {
-                case FragmentMenuItems.PLAY_SELECTION:
-                    MusicUtils.playAll(getActivity(), new long[]{
-                            mSelectedId
-                    }, 0, false);
-                    return true;
-                case FragmentMenuItems.PLAY_NEXT:
-                    MusicUtils.playNext(new long[]{
-                            mSelectedId
-                    });
-                    return true;
-                case FragmentMenuItems.ADD_TO_QUEUE:
-                    MusicUtils.addToQueue(getActivity(), new long[]{
-                            mSelectedId
-                    });
-                    return true;
-                case FragmentMenuItems.NEW_PLAYLIST:
-                    CreateNewPlaylist.getInstance(new long[]{
-                            mSelectedId
-                    }).show(getFragmentManager(), "CreatePlaylist");
-                    return true;
-                case FragmentMenuItems.PLAYLIST_SELECTED:
-                    final long mPlaylistId = item.getIntent().getLongExtra("playlist", 0);
-                    MusicUtils.addToPlaylist(getActivity(), new long[]{
-                            mSelectedId
-                    }, mPlaylistId);
-                    return true;
-                case FragmentMenuItems.MORE_BY_ARTIST:
-                    NavUtils.openArtistProfile(getActivity(), mArtistName);
-                    return true;
-                case FragmentMenuItems.USE_AS_RINGTONE:
-                    MusicUtils.setRingtone(getActivity(), mSelectedId);
-                    return true;
-                case FragmentMenuItems.DELETE:
-                    // TODO: Smarter refresh
-                    DeleteDialog.newInstance(mSong.mSongName, new long[]{
-                            mSelectedId
-                    }, null).show(getFragmentManager(), "DeleteDialog");
-                    return true;
-                default:
-                    break;
-            }
-        }
-        return super.onContextItemSelected(item);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
     public void onItemClick(final AdapterView<?> parent, final View view, final int position,
                             final long id) {
         playAll(position);
@@ -271,27 +187,39 @@ public abstract class BasicSongFragment extends Fragment implements LoaderCallba
      * {@inheritDoc}
      */
     @Override
-    public void onLoadFinished(final Loader<List<Song>> loader, final List<Song> data) {
+    public void onLoadFinished(final Loader<SectionListContainer<Song>> loader,
+                               final SectionListContainer<Song> data) {
         // Check for any errors
-        if (data.isEmpty()) {
+        if (data.mListResults.isEmpty()) {
             // Set the empty text
-            final NoResultsContainer empty = (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
+            final NoResultsContainer empty =
+                    (NoResultsContainer)mRootView.findViewById(R.id.no_results_container);
+            // Setup the container strings
+            setupNoResultsContainer(empty);
+            // set the empty view into the list view
             mListView.setEmptyView(empty);
             return;
         }
 
         // Start fresh
-        mAdapter.unload();
-        // Add the data to the adpater
-        for (final Song song : data) {
-            mAdapter.add(song);
-        }
+        mAdapter.setData(data);
+    }
 
-        // Build the cache
-        mAdapter.buildCache();
+    /**
+     * Restarts the loader.
+     */
+    public void refresh() {
+        // Wait a moment for the preference to change.
+        SystemClock.sleep(10);
+        getLoaderManager().restartLoader(getLoaderId(), null, this);
     }
 
+    /**
+     * {@inheritDoc}
+     */
+    @Override
     public void restartLoader() {
+        // Update the list when the user deletes any items
         getLoaderManager().restartLoader(getLoaderId(), null, this);
     }
 
@@ -299,27 +227,28 @@ public abstract class BasicSongFragment extends Fragment implements LoaderCallba
      * {@inheritDoc}
      */
     @Override
-    public void onLoaderReset(final Loader<List<Song>> loader) {
+    public void onLoaderReset(final Loader<SectionListContainer<Song>> loader) {
         // Clear the data in the adapter
         mAdapter.unload();
     }
 
     /**
-     * If the subclasses want to use a customized SongADapter
+     * If the subclasses want to use a customized SongAdapter they can override this method
      * @return the Song adapter
      */
-    protected SongAdapter createAdapter() {
-        return new SongAdapter(
-                getActivity(),
-                R.layout.list_item_normal
+    protected SectionAdapter<Song, SongAdapter> createAdapter() {
+        return new SectionAdapter(getActivity(),
+                new SongAdapter(
+                    getActivity(),
+                    R.layout.list_item_normal
+                )
         );
     }
 
-
-    /**
-     * Used to keep context menu items from bleeding into other fragments
-     */
-    public abstract int getGroupId();
+    @Override
+    public void onMetaChanged() {
+        // do nothing
+    }
 
     /**
      * LoaderCallbacks identifier