Skip to content

Instantly share code, notes, and snippets.

@nikclayton
Created July 11, 2015 16:48
Show Gist options
  • Save nikclayton/f85d4fdec347d6ecfc44 to your computer and use it in GitHub Desktop.
Save nikclayton/f85d4fdec347d6ecfc44 to your computer and use it in GitHub Desktop.
diff --git a/Squeezer/src/main/java/uk/org/ngo/squeezer/NowPlayingFragment.java b/Squeezer/src/main/java/uk/org/ngo/squeezer/NowPlayingFragment.java
index 92c53eb..f527064 100644
--- a/Squeezer/src/main/java/uk/org/ngo/squeezer/NowPlayingFragment.java
+++ b/Squeezer/src/main/java/uk/org/ngo/squeezer/NowPlayingFragment.java
@@ -49,6 +49,7 @@ import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.ImageButton;
import android.widget.ImageView;
+import android.widget.PopupMenu;
import android.widget.ProgressBar;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
@@ -66,6 +67,7 @@ import uk.org.ngo.squeezer.itemlist.AlarmsActivity;
import uk.org.ngo.squeezer.itemlist.AlbumListActivity;
import uk.org.ngo.squeezer.itemlist.CurrentPlaylistActivity;
import uk.org.ngo.squeezer.itemlist.PlayerListActivity;
+import uk.org.ngo.squeezer.itemlist.PlayerView;
import uk.org.ngo.squeezer.itemlist.SongListActivity;
import uk.org.ngo.squeezer.model.Artist;
import uk.org.ngo.squeezer.model.Player;
@@ -298,6 +300,44 @@ public class NowPlayingFragment extends Fragment implements View.OnCreateContext
}
});
+ playPauseButton.setOnLongClickListener(new View.OnLongClickListener() {
+ @Override
+ public boolean onLongClick(View v) {
+ if (mService != null) {
+ PlayerState activePlayerState = mService.getActivePlayerState();
+
+ if (activePlayerState != null) {
+ PopupMenu popupMenu = new PopupMenu(mActivity, v);
+ Menu menu = popupMenu.getMenu();
+ MenuInflater inflater = popupMenu.getMenuInflater();
+ inflater.inflate(R.menu.player_sleep, menu);
+
+ PlayerView.setSleepMenuItemText(menu, mActivity.getServerString(ServerString.X_MINUTES));
+
+ // If the player is currently counting down to sleep then add a "cancel sleep"
+ // option.
+ if (activePlayerState.getSleepDuration() != 0) {
+ popupMenu.getMenu().add(Menu.NONE, R.id.cancel_sleep, 0,
+ mActivity.getServerString(ServerString.SLEEP_CANCEL));
+ }
+
+ popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
+ @Override
+ public boolean onMenuItemClick(MenuItem item) {
+ return PlayerView.handleSleepMenuItems(mService,
+ mService.getActivePlayer(), item.getItemId());
+ }
+ });
+
+ popupMenu.show();
+
+ return true;
+ }
+ }
+ return false;
+ }
+ });
+
if (mFullHeightLayout) {
/*
* TODO: Simplify these following the notes at
diff --git a/Squeezer/src/main/java/uk/org/ngo/squeezer/itemlist/PlayerView.java b/Squeezer/src/main/java/uk/org/ngo/squeezer/itemlist/PlayerView.java
index bb18b44..fa24ea5 100644
--- a/Squeezer/src/main/java/uk/org/ngo/squeezer/itemlist/PlayerView.java
+++ b/Squeezer/src/main/java/uk/org/ngo/squeezer/itemlist/PlayerView.java
@@ -16,7 +16,9 @@
package uk.org.ngo.squeezer.itemlist;
+import android.support.annotation.NonNull;
import android.view.ContextMenu;
+import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
@@ -100,13 +102,10 @@ public class PlayerView extends BaseItemView<Player> {
super.onCreateContextMenu(menu, v, menuInfo);
menuInfo.menuInflater.inflate(R.menu.playercontextmenu, menu);
- menu.findItem(R.id.sleep).setTitle(activity.getServerString(ServerString.SLEEP));
- String xMinutes = activity.getServerString(ServerString.X_MINUTES);
- menu.findItem(R.id.in_15_minutes).setTitle(String.format(xMinutes, "15"));
- menu.findItem(R.id.in_30_minutes).setTitle(String.format(xMinutes, "30"));
- menu.findItem(R.id.in_45_minutes).setTitle(String.format(xMinutes, "45"));
- menu.findItem(R.id.in_60_minutes).setTitle(String.format(xMinutes, "60"));
- menu.findItem(R.id.in_90_minutes).setTitle(String.format(xMinutes, "90"));
+ MenuItem sleep = menu.findItem(R.id.sleep);
+ sleep.setTitle(activity.getServerString(ServerString.SLEEP));
+ menuInfo.menuInflater.inflate(R.menu.player_sleep, sleep.getSubMenu());
+ setSleepMenuItemText(menu, activity.getServerString(ServerString.X_MINUTES));
PlayerState playerState = activity.getPlayerState(menuInfo.item.getId());
if (playerState != null) {
@@ -132,6 +131,21 @@ public class PlayerView extends BaseItemView<Player> {
}
}
+ /**
+ * Set the text of the menu items to correct text for sleep timers of the specific
+ * duration.
+ *
+ * @param menu the menu that contains the sleep menu items
+ * @param xMinutes format string for the item, the duration will be interpolated in to this
+ */
+ public static void setSleepMenuItemText(Menu menu, String xMinutes) {
+ menu.findItem(R.id.in_15_minutes).setTitle(String.format(xMinutes, "15"));
+ menu.findItem(R.id.in_30_minutes).setTitle(String.format(xMinutes, "30"));
+ menu.findItem(R.id.in_45_minutes).setTitle(String.format(xMinutes, "45"));
+ menu.findItem(R.id.in_60_minutes).setTitle(String.format(xMinutes, "60"));
+ menu.findItem(R.id.in_90_minutes).setTitle(String.format(xMinutes, "90"));
+ }
+
@Override
public boolean doItemContext(MenuItem menuItem, int index, Player selectedItem) {
activity.setCurrentPlayer(selectedItem);
@@ -171,7 +185,8 @@ public class PlayerView extends BaseItemView<Player> {
}
Player currentPlayer = activity.getCurrentPlayer();
- switch (menuItem.getItemId()) {
+ int itemId = menuItem.getItemId();
+ switch (itemId) {
case R.id.end_of_song:
PlayerState playerState = activity.getPlayerState(currentPlayer.getId());
if (playerState != null) {
@@ -185,23 +200,48 @@ public class PlayerView extends BaseItemView<Player> {
}
return true;
+ }
+
+ if (handleSleepMenuItems(service, currentPlayer, itemId)) {
+ return true;
+ }
+
+ return super.doItemContext(menuItem);
+ }
+
+ /**
+ * Sends player commands to sleep for the duration specified by the selected menu item.
+ *
+ * @param service a connected service
+ * @param player the player to send the commands to
+ * @param itemId the ID of the selected menu item
+ * @return True if itemId was a known sleep menu item and the player command was sent, else
+ * false
+ */
+ public static boolean handleSleepMenuItems(@NonNull ISqueezeService service,
+ @NonNull Player player, int itemId) {
+ switch (itemId) {
case R.id.in_15_minutes:
- service.sleep(currentPlayer, 15*60);
+ service.sleep(player, 15 * 60);
return true;
case R.id.in_30_minutes:
- service.sleep(currentPlayer, 30*60);
+ service.sleep(player, 30 * 60);
return true;
case R.id.in_45_minutes:
- service.sleep(currentPlayer, 45*60);
+ service.sleep(player, 45 * 60);
return true;
case R.id.in_60_minutes:
- service.sleep(currentPlayer, 60*60);
+ service.sleep(player, 60 * 60);
return true;
case R.id.in_90_minutes:
- service.sleep(currentPlayer, 90*60);
+ service.sleep(player, 90 * 60);
+ return true;
+ case R.id.cancel_sleep:
+ service.sleep(player, 0);
return true;
}
- return super.doItemContext(menuItem);
+
+ return false;
}
@Override
diff --git a/Squeezer/src/main/res/menu/player_sleep.xml b/Squeezer/src/main/res/menu/player_sleep.xml
new file mode 100644
index 0000000..cb40a36
--- /dev/null
+++ b/Squeezer/src/main/res/menu/player_sleep.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (c) 2015 Google Inc. All Rights Reserved.
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:id="@+id/end_of_song" android:visible="false"/>
+ <item android:id="@+id/in_15_minutes" android:title=""/>
+ <item android:id="@+id/in_30_minutes" android:title=""/>
+ <item android:id="@+id/in_45_minutes" android:title=""/>
+ <item android:id="@+id/in_60_minutes" android:title=""/>
+ <item android:id="@+id/in_90_minutes" android:title=""/>
+</menu>
\ No newline at end of file
diff --git a/Squeezer/src/main/res/menu/playercontextmenu.xml b/Squeezer/src/main/res/menu/playercontextmenu.xml
index c488d47..0346eb0 100644
--- a/Squeezer/src/main/res/menu/playercontextmenu.xml
+++ b/Squeezer/src/main/res/menu/playercontextmenu.xml
@@ -20,14 +20,9 @@
<!-- Note some items use server texts -->
<item android:id="@+id/sleep" android:title="">
- <menu>
- <item android:id="@+id/end_of_song" android:visible="false"/>
- <item android:id="@+id/in_15_minutes" android:title=""/>
- <item android:id="@+id/in_30_minutes" android:title=""/>
- <item android:id="@+id/in_45_minutes" android:title=""/>
- <item android:id="@+id/in_60_minutes" android:title=""/>
- <item android:id="@+id/in_90_minutes" android:title=""/>
- </menu>
+ <!-- Deliberately empty, Android doesn't support including one menu file in another
+ in XML. The sub-menu that will go here (player_sleep.xml) is inflated in code. -->
+ <menu></menu>
</item>
<item android:id="@+id/cancel_sleep" android:visible="false"/>
<item android:id="@+id/rename" android:title="@string/menu_item_rename"/>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment