Implemented various keyboard shortcuts.

- Main menu:
-- 'd': opens downloads menu
-- 'r': plays random track
- Song menu:
-- SHIFT+DEL: opens beatmap deletion menu

Other changes:
- In the main menu, tracks now play from the beginning instead of the preview time.
- Fixed "next page" icon sometimes showing in the downloads menu when a next page didn't exist.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2015-03-06 01:29:50 -05:00
parent 0a1b10fbdb
commit 81601d41aa
5 changed files with 69 additions and 42 deletions

View File

@ -67,8 +67,11 @@ public class MusicController {
/** /**
* Plays an audio file at the preview position. * Plays an audio file at the preview position.
* If the audio file is already playing, then nothing will happen. * If the audio file is already playing, then nothing will happen.
* @param osu the OsuFile to play
* @param loop whether or not to loop the track
* @param preview whether to start at the preview time (true) or beginning (false)
*/ */
public static void play(final OsuFile osu, final boolean loop) { public static void play(final OsuFile osu, final boolean loop, final boolean preview) {
// new track: load and play // new track: load and play
if (lastOsu == null || !osu.audioFilename.equals(lastOsu.audioFilename)) { if (lastOsu == null || !osu.audioFilename.equals(lastOsu.audioFilename)) {
reset(); reset();
@ -80,7 +83,7 @@ public class MusicController {
trackLoader = new Thread() { trackLoader = new Thread() {
@Override @Override
public void run() { public void run() {
loadTrack(osu.audioFilename, osu.previewTime, loop); loadTrack(osu.audioFilename, (preview) ? osu.previewTime : 0, loop);
} }
}; };
trackLoader.start(); trackLoader.start();
@ -279,7 +282,7 @@ public class MusicController {
public static void playThemeSong() { public static void playThemeSong() {
OsuFile osu = Options.getOsuTheme(); OsuFile osu = Options.getOsuTheme();
if (osu != null) { if (osu != null) {
play(osu, true); play(osu, true, false);
themePlaying = true; themePlaying = true;
} }
} }

View File

@ -517,7 +517,7 @@ public class DownloadsMenu extends BasicGameState {
// initialize song list // initialize song list
OsuGroupList.get().reset(); OsuGroupList.get().reset();
OsuGroupList.get().init(); OsuGroupList.get().init();
((SongMenu) game.getState(Opsu.STATE_SONGMENU)).setFocus(node, -1, true); ((SongMenu) game.getState(Opsu.STATE_SONGMENU)).setFocus(node, -1, true, true);
// send notification // send notification
UI.sendBarNotification((dirs.length == 1) ? "Imported 1 new song." : UI.sendBarNotification((dirs.length == 1) ? "Imported 1 new song." :
@ -544,7 +544,7 @@ public class DownloadsMenu extends BasicGameState {
SoundController.playSound(SoundEffect.MENUCLICK); SoundController.playSound(SoundEffect.MENUCLICK);
rankedOnly = !rankedOnly; rankedOnly = !rankedOnly;
lastQuery = null; lastQuery = null;
pageDir = Page.CURRENT; pageDir = Page.RESET;
resetSearchTimer(); resetSearchTimer();
return; return;
} }

View File

@ -396,22 +396,12 @@ public class MainMenu extends BasicGameState {
UI.sendBarNotification("Play"); UI.sendBarNotification("Play");
} }
} else if (musicNext.contains(x, y)) { } else if (musicNext.contains(x, y)) {
boolean isTheme = MusicController.isThemePlaying(); nextTrack();
SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU);
OsuGroupNode node = menu.setFocus(OsuGroupList.get().getRandomNode(), -1, true);
boolean sameAudio = false;
if (node != null) {
sameAudio = MusicController.getOsuFile().audioFilename.equals(node.osuFiles.get(0).audioFilename);
if (!isTheme && !sameAudio)
previous.add(node.index);
}
if (Options.isDynamicBackgroundEnabled() && !sameAudio && !MusicController.isThemePlaying())
bgAlpha = 0f;
UI.sendBarNotification(">> Next"); UI.sendBarNotification(">> Next");
} else if (musicPrevious.contains(x, y)) { } else if (musicPrevious.contains(x, y)) {
if (!previous.isEmpty()) { if (!previous.isEmpty()) {
SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU); SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU);
menu.setFocus(OsuGroupList.get().getBaseNode(previous.pop()), -1, true); menu.setFocus(OsuGroupList.get().getBaseNode(previous.pop()), -1, true, false);
if (Options.isDynamicBackgroundEnabled()) if (Options.isDynamicBackgroundEnabled())
bgAlpha = 0f; bgAlpha = 0f;
} else } else
@ -469,16 +459,21 @@ public class MainMenu extends BasicGameState {
game.enterState(Opsu.STATE_BUTTONMENU); game.enterState(Opsu.STATE_BUTTONMENU);
break; break;
case Input.KEY_P: case Input.KEY_P:
SoundController.playSound(SoundEffect.MENUHIT);
if (!logoClicked) { if (!logoClicked) {
logoClicked = true; logoClicked = true;
logoTimer = 0; logoTimer = 0;
playButton.getImage().setAlpha(0f); playButton.getImage().setAlpha(0f);
exitButton.getImage().setAlpha(0f); exitButton.getImage().setAlpha(0f);
SoundController.playSound(SoundEffect.MENUHIT); } else
} else {
SoundController.playSound(SoundEffect.MENUHIT);
game.enterState(Opsu.STATE_SONGMENU, new FadeOutTransition(Color.black), new FadeInTransition(Color.black)); game.enterState(Opsu.STATE_SONGMENU, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
} break;
case Input.KEY_D:
SoundController.playSound(SoundEffect.MENUHIT);
game.enterState(Opsu.STATE_DOWNLOADSMENU, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
break;
case Input.KEY_R:
nextTrack();
break; break;
case Input.KEY_UP: case Input.KEY_UP:
UI.changeVolume(1); UI.changeVolume(1);
@ -526,4 +521,21 @@ public class MainMenu extends BasicGameState {
musicPrevious.resetHover(); musicPrevious.resetHover();
downloadsButton.resetHover(); downloadsButton.resetHover();
} }
/**
* Plays the next track, and adds the previous one to the stack.
*/
private void nextTrack() {
boolean isTheme = MusicController.isThemePlaying();
SongMenu menu = (SongMenu) game.getState(Opsu.STATE_SONGMENU);
OsuGroupNode node = menu.setFocus(OsuGroupList.get().getRandomNode(), -1, true, false);
boolean sameAudio = false;
if (node != null) {
sameAudio = MusicController.getOsuFile().audioFilename.equals(node.osuFiles.get(0).audioFilename);
if (!isTheme && !sameAudio)
previous.add(node.index);
}
if (Options.isDynamicBackgroundEnabled() && !sameAudio && !MusicController.isThemePlaying())
bgAlpha = 0f;
}
} }

View File

@ -507,14 +507,14 @@ public class SongMenu extends BasicGameState {
if (search.getText().isEmpty()) { // cleared search if (search.getText().isEmpty()) { // cleared search
// use previous start/focus if possible // use previous start/focus if possible
if (oldFocusNode != null) if (oldFocusNode != null)
setFocus(oldFocusNode.getNode(), oldFocusNode.getIndex(), true); setFocus(oldFocusNode.getNode(), oldFocusNode.getIndex(), true, true);
else else
setFocus(OsuGroupList.get().getRandomNode(), -1, true); setFocus(OsuGroupList.get().getRandomNode(), -1, true, true);
} else { } else {
int size = OsuGroupList.get().size(); int size = OsuGroupList.get().size();
searchResultString = String.format("%d match%s found!", searchResultString = String.format("%d match%s found!",
size, (size == 1) ? "" : "es"); size, (size == 1) ? "" : "es");
setFocus(OsuGroupList.get().getRandomNode(), -1, true); setFocus(OsuGroupList.get().getRandomNode(), -1, true, true);
} }
oldFocusNode = null; oldFocusNode = null;
} else if (!search.getText().isEmpty()) } else if (!search.getText().isEmpty())
@ -618,7 +618,7 @@ public class SongMenu extends BasicGameState {
int oldFocusFileIndex = focusNode.osuFileIndex; int oldFocusFileIndex = focusNode.osuFileIndex;
focusNode = null; focusNode = null;
OsuGroupList.get().init(); OsuGroupList.get().init();
setFocus(oldFocusBase, oldFocusFileIndex, true); setFocus(oldFocusBase, oldFocusFileIndex, true, true);
} }
return; return;
} }
@ -647,14 +647,14 @@ public class SongMenu extends BasicGameState {
} else { } else {
// focus the node // focus the node
SoundController.playSound(SoundEffect.MENUCLICK); SoundController.playSound(SoundEffect.MENUCLICK);
setFocus(node, 0, false); setFocus(node, 0, false, true);
} }
} }
// clicked node is a new group // clicked node is a new group
else { else {
SoundController.playSound(SoundEffect.MENUCLICK); SoundController.playSound(SoundEffect.MENUCLICK);
setFocus(node, -1, false); setFocus(node, -1, false, true);
} }
// restore hover data // restore hover data
@ -731,11 +731,11 @@ public class SongMenu extends BasicGameState {
SongNode prev; SongNode prev;
if (randomStack.isEmpty() || (prev = randomStack.pop()) == null) if (randomStack.isEmpty() || (prev = randomStack.pop()) == null)
break; break;
setFocus(prev.getNode(), prev.getIndex(), true); setFocus(prev.getNode(), prev.getIndex(), true, true);
} else { } else {
// random track, add previous to stack // random track, add previous to stack
randomStack.push(new SongNode(OsuGroupList.get().getBaseNode(focusNode.index), focusNode.osuFileIndex)); randomStack.push(new SongNode(OsuGroupList.get().getBaseNode(focusNode.index), focusNode.osuFileIndex));
setFocus(OsuGroupList.get().getRandomNode(), -1, true); setFocus(OsuGroupList.get().getRandomNode(), -1, true, true);
} }
break; break;
case Input.KEY_F3: case Input.KEY_F3:
@ -750,6 +750,17 @@ public class SongMenu extends BasicGameState {
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(MenuState.RELOAD); ((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(MenuState.RELOAD);
game.enterState(Opsu.STATE_BUTTONMENU); game.enterState(Opsu.STATE_BUTTONMENU);
break; break;
case Input.KEY_DELETE:
if (focusNode == null)
break;
if (input.isKeyDown(Input.KEY_RSHIFT) || input.isKeyDown(Input.KEY_LSHIFT)) {
SoundController.playSound(SoundEffect.MENUHIT);
MenuState ms = (focusNode.osuFileIndex == -1 || focusNode.osuFiles.size() == 1) ?
MenuState.BEATMAP_DELETE_CONFIRM : MenuState.BEATMAP_DELETE_SELECT;
((ButtonMenu) game.getState(Opsu.STATE_BUTTONMENU)).setMenuState(ms, focusNode);
game.enterState(Opsu.STATE_BUTTONMENU);
}
break;
case Input.KEY_F7: case Input.KEY_F7:
Options.setNextFPS(container); Options.setNextFPS(container);
break; break;
@ -784,7 +795,7 @@ public class SongMenu extends BasicGameState {
OsuGroupNode oldStartNode = startNode; OsuGroupNode oldStartNode = startNode;
float oldHoverOffset = hoverOffset; float oldHoverOffset = hoverOffset;
int oldHoverIndex = hoverIndex; int oldHoverIndex = hoverIndex;
setFocus(next, 0, false); setFocus(next, 0, false, true);
if (startNode == oldStartNode) { if (startNode == oldStartNode) {
hoverOffset = oldHoverOffset; hoverOffset = oldHoverOffset;
hoverIndex = oldHoverIndex; hoverIndex = oldHoverIndex;
@ -800,7 +811,7 @@ public class SongMenu extends BasicGameState {
OsuGroupNode oldStartNode = startNode; OsuGroupNode oldStartNode = startNode;
float oldHoverOffset = hoverOffset; float oldHoverOffset = hoverOffset;
int oldHoverIndex = hoverIndex; int oldHoverIndex = hoverIndex;
setFocus(prev, (prev.index == focusNode.index) ? 0 : prev.osuFiles.size() - 1, false); setFocus(prev, (prev.index == focusNode.index) ? 0 : prev.osuFiles.size() - 1, false, true);
if (startNode == oldStartNode) { if (startNode == oldStartNode) {
hoverOffset = oldHoverOffset; hoverOffset = oldHoverOffset;
hoverIndex = oldHoverIndex; hoverIndex = oldHoverIndex;
@ -902,7 +913,7 @@ public class SongMenu extends BasicGameState {
// set focus node if not set (e.g. theme song playing) // set focus node if not set (e.g. theme song playing)
if (focusNode == null && OsuGroupList.get().size() > 0) if (focusNode == null && OsuGroupList.get().size() > 0)
setFocus(OsuGroupList.get().getRandomNode(), -1, true); setFocus(OsuGroupList.get().getRandomNode(), -1, true, true);
// reset music track // reset music track
else if (resetTrack) { else if (resetTrack) {
@ -972,9 +983,9 @@ public class SongMenu extends BasicGameState {
OsuGroupList.get().deleteSongGroup(stateActionNode); OsuGroupList.get().deleteSongGroup(stateActionNode);
if (oldIndex == focusNodeIndex) { if (oldIndex == focusNodeIndex) {
if (prev != null) if (prev != null)
setFocus(prev, -1, true); setFocus(prev, -1, true, true);
else if (next != null) else if (next != null)
setFocus(next, -1, true); setFocus(next, -1, true, true);
else { else {
startNode = focusNode = null; startNode = focusNode = null;
oldFocusNode = null; oldFocusNode = null;
@ -1003,14 +1014,14 @@ public class SongMenu extends BasicGameState {
if (stateActionNode.prev != null && if (stateActionNode.prev != null &&
!(stateActionNode.next != null && stateActionNode.next.index == index)) { !(stateActionNode.next != null && stateActionNode.next.index == index)) {
if (stateActionNode.prev.index == index) if (stateActionNode.prev.index == index)
setFocus(stateActionNode.prev, 0, true); setFocus(stateActionNode.prev, 0, true, true);
else else
setFocus(stateActionNode.prev, -1, true); setFocus(stateActionNode.prev, -1, true, true);
} else if (stateActionNode.next != null) { } else if (stateActionNode.next != null) {
if (stateActionNode.next.index == index) if (stateActionNode.next.index == index)
setFocus(stateActionNode.next, 0, true); setFocus(stateActionNode.next, 0, true, true);
else else
setFocus(stateActionNode.next, -1, true); setFocus(stateActionNode.next, -1, true, true);
} }
} else if (stateActionNode == startNode) { } else if (stateActionNode == startNode) {
if (startNode.prev != null) if (startNode.prev != null)
@ -1050,7 +1061,7 @@ public class SongMenu extends BasicGameState {
// initialize song list // initialize song list
if (OsuGroupList.get().size() > 0) { if (OsuGroupList.get().size() > 0) {
OsuGroupList.get().init(); OsuGroupList.get().init();
setFocus(OsuGroupList.get().getRandomNode(), -1, true); setFocus(OsuGroupList.get().getRandomNode(), -1, true, true);
} else } else
MusicController.playThemeSong(); MusicController.playThemeSong();
@ -1120,9 +1131,10 @@ public class SongMenu extends BasicGameState {
* @param node the base node; it will be expanded if it isn't already * @param node the base node; it will be expanded if it isn't already
* @param osuFileIndex the OsuFile element to focus; if out of bounds, it will be randomly chosen * @param osuFileIndex the OsuFile element to focus; if out of bounds, it will be randomly chosen
* @param changeStartNode if true, startNode will be set to the first node in the group * @param changeStartNode if true, startNode will be set to the first node in the group
* @param preview whether to start at the preview time (true) or beginning (false)
* @return the old focus node * @return the old focus node
*/ */
public OsuGroupNode setFocus(OsuGroupNode node, int osuFileIndex, boolean changeStartNode) { public OsuGroupNode setFocus(OsuGroupNode node, int osuFileIndex, boolean changeStartNode, boolean preview) {
if (node == null) if (node == null)
return null; return null;
@ -1151,7 +1163,7 @@ public class SongMenu extends BasicGameState {
startNode = node; startNode = node;
focusNode = OsuGroupList.get().getNode(node, osuFileIndex); focusNode = OsuGroupList.get().getNode(node, osuFileIndex);
OsuFile osu = focusNode.osuFiles.get(focusNode.osuFileIndex); OsuFile osu = focusNode.osuFiles.get(focusNode.osuFileIndex);
MusicController.play(osu, true); MusicController.play(osu, true, preview);
Utils.loadGlyphs(osu); Utils.loadGlyphs(osu);
// load scores // load scores

View File

@ -130,7 +130,7 @@ public class Splash extends BasicGameState {
if (Options.isThemeSongEnabled()) if (Options.isThemeSongEnabled())
MusicController.playThemeSong(); MusicController.playThemeSong();
else else
((SongMenu) game.getState(Opsu.STATE_SONGMENU)).setFocus(OsuGroupList.get().getRandomNode(), -1, true); ((SongMenu) game.getState(Opsu.STATE_SONGMENU)).setFocus(OsuGroupList.get().getRandomNode(), -1, true, true);
} }
// play the theme song // play the theme song