mainmenu music bar tweaks
Make it work like in osu: separate play/pause button stop button pressing play either resumes or start from beginning pressing pause pauses and unpauses pressing stop pauses and sets position at the start Less aggressive expand scale Icons from fontawesome, like osu Seek bar: correct size, non-rounded corners and less white color Positioning tweaks
Before Width: | Height: | Size: 568 B After Width: | Height: | Size: 306 B |
Before Width: | Height: | Size: 238 B After Width: | Height: | Size: 253 B |
Before Width: | Height: | Size: 522 B After Width: | Height: | Size: 346 B |
Before Width: | Height: | Size: 572 B After Width: | Height: | Size: 318 B |
BIN
res/music-stop.png
Normal file
After Width: | Height: | Size: 179 B |
|
@ -345,6 +345,7 @@ public enum GameImage {
|
||||||
// Music Player Buttons
|
// Music Player Buttons
|
||||||
MUSIC_PLAY ("music-play", "png", false, false),
|
MUSIC_PLAY ("music-play", "png", false, false),
|
||||||
MUSIC_PAUSE ("music-pause", "png", false, false),
|
MUSIC_PAUSE ("music-pause", "png", false, false),
|
||||||
|
MUSIC_STOP ("music-stop", "png", false, false),
|
||||||
MUSIC_NEXT ("music-next", "png", false, false),
|
MUSIC_NEXT ("music-next", "png", false, false),
|
||||||
MUSIC_PREVIOUS ("music-previous", "png", false, false),
|
MUSIC_PREVIOUS ("music-previous", "png", false, false),
|
||||||
MUSIC_NOWPLAYING ("music-np", "png", false, false),
|
MUSIC_NOWPLAYING ("music-np", "png", false, false),
|
||||||
|
@ -654,6 +655,14 @@ public enum GameImage {
|
||||||
setDefaultImage();
|
setDefaultImage();
|
||||||
return (skinImage != null) ? skinImage : defaultImage;
|
return (skinImage != null) ? skinImage : defaultImage;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the image associated with this resource, with a scale applied.
|
||||||
|
* The beatmap skin image takes priority over the default image.
|
||||||
|
*/
|
||||||
|
public Image getScaledImage(float scale) {
|
||||||
|
return this.getImage().getScaledCopy(scale);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns an Animation based on the image array.
|
* Returns an Animation based on the image array.
|
||||||
|
|
|
@ -51,6 +51,7 @@ import yugecin.opsudance.core.Constants;
|
||||||
import yugecin.opsudance.core.state.BaseOpsuState;
|
import yugecin.opsudance.core.state.BaseOpsuState;
|
||||||
import yugecin.opsudance.core.state.OpsuState;
|
import yugecin.opsudance.core.state.OpsuState;
|
||||||
|
|
||||||
|
import static itdelatrisu.opsu.GameImage.*;
|
||||||
import static itdelatrisu.opsu.ui.Colors.*;
|
import static itdelatrisu.opsu.ui.Colors.*;
|
||||||
import static itdelatrisu.opsu.ui.animations.AnimationEquation.*;
|
import static itdelatrisu.opsu.ui.animations.AnimationEquation.*;
|
||||||
import static org.lwjgl.input.Keyboard.*;
|
import static org.lwjgl.input.Keyboard.*;
|
||||||
|
@ -92,7 +93,8 @@ public class MainMenu extends BaseOpsuState {
|
||||||
private MenuButton playButton, exitButton;
|
private MenuButton playButton, exitButton;
|
||||||
|
|
||||||
/** Music control buttons. */
|
/** Music control buttons. */
|
||||||
private MenuButton musicPlay, musicPause, musicNext, musicPrevious;
|
private MenuButton musicPlay, musicPause, musicStop, musicNext, musicPrev;
|
||||||
|
private MenuButton[] musicButtons = new MenuButton[5];
|
||||||
|
|
||||||
/** Button linking to Downloads menu. */
|
/** Button linking to Downloads menu. */
|
||||||
private MenuButton downloadsButton;
|
private MenuButton downloadsButton;
|
||||||
|
@ -106,6 +108,11 @@ public class MainMenu extends BaseOpsuState {
|
||||||
/** Buttons for installing updates. */
|
/** Buttons for installing updates. */
|
||||||
private MenuButton updateButton, restartButton;
|
private MenuButton updateButton, restartButton;
|
||||||
|
|
||||||
|
private int textMarginX;
|
||||||
|
private int textTopMarginY;
|
||||||
|
private int textBottomMarginY;
|
||||||
|
private int textLineHeight;
|
||||||
|
|
||||||
/** Application start time, for drawing the total running time. */
|
/** Application start time, for drawing the total running time. */
|
||||||
private long programStartTime;
|
private long programStartTime;
|
||||||
|
|
||||||
|
@ -119,7 +126,7 @@ public class MainMenu extends BaseOpsuState {
|
||||||
private boolean enterNotification = false;
|
private boolean enterNotification = false;
|
||||||
|
|
||||||
/** Music position bar coordinates and dimensions. */
|
/** Music position bar coordinates and dimensions. */
|
||||||
private float musicBarX, musicBarY, musicBarWidth, musicBarHeight;
|
private int musicBarX, musicBarY, musicBarWidth, musicBarHeight;
|
||||||
|
|
||||||
/** Last measure progress value. */
|
/** Last measure progress value. */
|
||||||
private float lastMeasureProgress = 0f;
|
private float lastMeasureProgress = 0f;
|
||||||
|
@ -135,6 +142,14 @@ public class MainMenu extends BaseOpsuState {
|
||||||
programStartTime = System.currentTimeMillis();
|
programStartTime = System.currentTimeMillis();
|
||||||
previous = new Stack<>();
|
previous = new Stack<>();
|
||||||
|
|
||||||
|
final int width = displayContainer.width;
|
||||||
|
final int height = displayContainer.height;
|
||||||
|
|
||||||
|
this.textMarginX = (int) (width * 0.015f);
|
||||||
|
this.textTopMarginY = (int) (height * 0.01f);
|
||||||
|
this.textBottomMarginY = (int) (height * 0.015f);
|
||||||
|
this.textLineHeight = (int) (Fonts.MEDIUM.getLineHeight() * 0.925f);
|
||||||
|
|
||||||
// initialize menu buttons
|
// initialize menu buttons
|
||||||
Image logoImg = GameImage.MENU_LOGO.getImage();
|
Image logoImg = GameImage.MENU_LOGO.getImage();
|
||||||
Image playImg = GameImage.MENU_PLAY.getImage();
|
Image playImg = GameImage.MENU_PLAY.getImage();
|
||||||
|
@ -161,22 +176,34 @@ public class MainMenu extends BaseOpsuState {
|
||||||
exitButton.setHoverExpand(logoHoverScale);
|
exitButton.setHoverExpand(logoHoverScale);
|
||||||
|
|
||||||
// initialize music buttons
|
// initialize music buttons
|
||||||
int musicWidth = GameImage.MUSIC_PLAY.getImage().getWidth();
|
final int musicSize = (int) (this.textLineHeight * 0.8f);
|
||||||
int musicHeight = GameImage.MUSIC_PLAY.getImage().getHeight();
|
final float musicScale = (float) musicSize / MUSIC_STOP.getImage().getWidth();
|
||||||
musicPlay = new MenuButton(GameImage.MUSIC_PLAY.getImage(), displayContainer.width - (2 * musicWidth), musicHeight / 1.5f);
|
final int musicSpacing = (int) (musicSize * 0.8f) + musicSize; // (center to center)
|
||||||
musicPause = new MenuButton(GameImage.MUSIC_PAUSE.getImage(), displayContainer.width - (2 * musicWidth), musicHeight / 1.5f);
|
int x = width - this.textMarginX - musicSize / 2;
|
||||||
musicNext = new MenuButton(GameImage.MUSIC_NEXT.getImage(), displayContainer.width - musicWidth, musicHeight / 1.5f);
|
int y = this.textLineHeight * 2 + this.textLineHeight / 2;
|
||||||
musicPrevious = new MenuButton(GameImage.MUSIC_PREVIOUS.getImage(), displayContainer.width - (3 * musicWidth), musicHeight / 1.5f);
|
this.musicNext = new MenuButton(MUSIC_NEXT.getScaledImage(musicScale), x, y);
|
||||||
musicPlay.setHoverExpand(1.5f);
|
x -= musicSpacing;
|
||||||
musicPause.setHoverExpand(1.5f);
|
this.musicStop = new MenuButton(MUSIC_STOP.getScaledImage(musicScale), x, y);
|
||||||
musicNext.setHoverExpand(1.5f);
|
x -= musicSpacing;
|
||||||
musicPrevious.setHoverExpand(1.5f);
|
this.musicPause = new MenuButton(MUSIC_PAUSE.getScaledImage(musicScale), x, y);
|
||||||
|
x -= musicSpacing;
|
||||||
|
this.musicPlay = new MenuButton(MUSIC_PLAY.getScaledImage(musicScale), x, y);
|
||||||
|
x -= musicSpacing;
|
||||||
|
this.musicPrev = new MenuButton(MUSIC_PREVIOUS.getScaledImage(musicScale), x, y);
|
||||||
|
this.musicButtons[0] = this.musicPrev;
|
||||||
|
this.musicButtons[1] = this.musicPlay;
|
||||||
|
this.musicButtons[2] = this.musicPause;
|
||||||
|
this.musicButtons[3] = this.musicStop;
|
||||||
|
this.musicButtons[4] = this.musicNext;
|
||||||
|
for (MenuButton b : this.musicButtons) {
|
||||||
|
b.setHoverExpand(1.15f);
|
||||||
|
}
|
||||||
|
|
||||||
// initialize music position bar location
|
// initialize music position bar location
|
||||||
musicBarX = displayContainer.width - musicWidth * 3.5f;
|
this.musicBarX = x - musicSize / 2;
|
||||||
musicBarY = musicHeight * 1.25f;
|
this.musicBarY = y + musicSize;
|
||||||
musicBarWidth = musicWidth * 3f;
|
this.musicBarWidth = musicSize + musicSpacing * 4;
|
||||||
musicBarHeight = musicHeight * 0.11f;
|
this.musicBarHeight = (int) (musicSize * 0.3f);
|
||||||
|
|
||||||
// initialize downloads button
|
// initialize downloads button
|
||||||
Image dlImg = GameImage.DOWNLOADS.getImage();
|
Image dlImg = GameImage.DOWNLOADS.getImage();
|
||||||
|
@ -233,11 +260,6 @@ public class MainMenu extends BaseOpsuState {
|
||||||
int width = displayContainer.width;
|
int width = displayContainer.width;
|
||||||
int height = displayContainer.height;
|
int height = displayContainer.height;
|
||||||
|
|
||||||
final float textMarginX = width * 0.015f;
|
|
||||||
final float textTopMarginY = height * 0.01f;
|
|
||||||
final float textBottomMarginY = height * 0.015f;
|
|
||||||
final float textLineHeight = Fonts.MEDIUM.getLineHeight() * 0.925f;
|
|
||||||
|
|
||||||
// draw background
|
// draw background
|
||||||
Beatmap beatmap = MusicController.getBeatmap();
|
Beatmap beatmap = MusicController.getBeatmap();
|
||||||
if (OPTION_DYNAMIC_BACKGROUND.state &&
|
if (OPTION_DYNAMIC_BACKGROUND.state &&
|
||||||
|
@ -328,22 +350,21 @@ public class MainMenu extends BaseOpsuState {
|
||||||
Fonts.MEDIUM.drawString(npTextX, 0, trackText);
|
Fonts.MEDIUM.drawString(npTextX, 0, trackText);
|
||||||
|
|
||||||
// draw music buttons
|
// draw music buttons
|
||||||
if (MusicController.isPlaying())
|
for (MenuButton b : this.musicButtons) {
|
||||||
musicPause.draw();
|
b.draw();
|
||||||
else
|
}
|
||||||
musicPlay.draw();
|
|
||||||
musicNext.draw();
|
|
||||||
musicPrevious.draw();
|
|
||||||
|
|
||||||
// draw music position bar
|
// draw music position bar
|
||||||
int mouseX = displayContainer.mouseX;
|
int mouseX = displayContainer.mouseX;
|
||||||
int mouseY = displayContainer.mouseY;
|
int mouseY = displayContainer.mouseY;
|
||||||
g.setColor((musicPositionBarContains(mouseX, mouseY)) ? Colors.BLACK_BG_HOVER : Colors.BLACK_BG_NORMAL);
|
g.setColor((musicPositionBarContains(mouseX, mouseY)) ? Colors.BLACK_BG_HOVER : Colors.BLACK_BG_NORMAL);
|
||||||
g.fillRoundRect(musicBarX, musicBarY, musicBarWidth, musicBarHeight, 4);
|
g.fillRect(this.musicBarX, this.musicBarY, this.musicBarWidth, this.musicBarHeight);
|
||||||
g.setColor(Color.white);
|
g.setColor(Colors.WHITE_ALPHA_75);
|
||||||
if (!MusicController.isTrackLoading() && beatmap != null) {
|
if (!MusicController.isTrackLoading() && beatmap != null) {
|
||||||
float musicBarPosition = Math.min((float) MusicController.getPosition() / MusicController.getDuration(), 1f);
|
final float trackpos = MusicController.getPosition();
|
||||||
g.fillRoundRect(musicBarX, musicBarY, musicBarWidth * musicBarPosition, musicBarHeight, 4);
|
final float tracklen = MusicController.getDuration();
|
||||||
|
final float barwidth = musicBarWidth * Math.min(trackpos / tracklen, 1f);
|
||||||
|
g.fillRect(this.musicBarX, this.musicBarY, barwidth, this.musicBarHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw repository buttons
|
// draw repository buttons
|
||||||
|
@ -420,14 +441,9 @@ public class MainMenu extends BaseOpsuState {
|
||||||
restartButton.autoHoverUpdate(delta, false);
|
restartButton.autoHoverUpdate(delta, false);
|
||||||
}
|
}
|
||||||
downloadsButton.hoverUpdate(delta, mouseX, mouseY);
|
downloadsButton.hoverUpdate(delta, mouseX, mouseY);
|
||||||
// ensure only one button is in hover state at once
|
for (MenuButton b : this.musicButtons) {
|
||||||
boolean noHoverUpdate = musicPositionBarContains(mouseX, mouseY);
|
b.hoverUpdate(delta, b.contains(mouseX, mouseY));
|
||||||
boolean contains = musicPlay.contains(mouseX, mouseY);
|
}
|
||||||
musicPlay.hoverUpdate(delta, !noHoverUpdate && contains);
|
|
||||||
musicPause.hoverUpdate(delta, !noHoverUpdate && contains);
|
|
||||||
noHoverUpdate |= contains;
|
|
||||||
musicNext.hoverUpdate(delta, !noHoverUpdate && musicNext.contains(mouseX, mouseY));
|
|
||||||
musicPrevious.hoverUpdate(delta, !noHoverUpdate && musicPrevious.contains(mouseX, mouseY));
|
|
||||||
starFountain.update(delta);
|
starFountain.update(delta);
|
||||||
|
|
||||||
// window focus change: increase/decrease theme song volume
|
// window focus change: increase/decrease theme song volume
|
||||||
|
@ -489,12 +505,16 @@ public class MainMenu extends BaseOpsuState {
|
||||||
// tooltips
|
// tooltips
|
||||||
if (musicPositionBarContains(mouseX, mouseY))
|
if (musicPositionBarContains(mouseX, mouseY))
|
||||||
UI.updateTooltip(delta, "Click to seek to a specific point in the song.", false);
|
UI.updateTooltip(delta, "Click to seek to a specific point in the song.", false);
|
||||||
|
else if (musicPrev.contains(mouseX, mouseY))
|
||||||
|
UI.updateTooltip(delta, "Previous track", false);
|
||||||
else if (musicPlay.contains(mouseX, mouseY))
|
else if (musicPlay.contains(mouseX, mouseY))
|
||||||
UI.updateTooltip(delta, (MusicController.isPlaying()) ? "Pause" : "Play", false);
|
UI.updateTooltip(delta, "Play", false);
|
||||||
|
else if (musicPause.contains(mouseX, mouseY))
|
||||||
|
UI.updateTooltip(delta, "Pause", false);
|
||||||
|
else if (musicStop.contains(mouseX, mouseY))
|
||||||
|
UI.updateTooltip(delta, "Stop", false);
|
||||||
else if (musicNext.contains(mouseX, mouseY))
|
else if (musicNext.contains(mouseX, mouseY))
|
||||||
UI.updateTooltip(delta, "Next track", false);
|
UI.updateTooltip(delta, "Next track", false);
|
||||||
else if (musicPrevious.contains(mouseX, mouseY))
|
|
||||||
UI.updateTooltip(delta, "Previous track", false);
|
|
||||||
else if (updater.showButton()) {
|
else if (updater.showButton()) {
|
||||||
Updater.Status status = updater.getStatus();
|
Updater.Status status = updater.getStatus();
|
||||||
if (((status == Updater.Status.UPDATE_AVAILABLE || status == Updater.Status.UPDATE_DOWNLOADING) && updateButton.contains(mouseX, mouseY)) ||
|
if (((status == Updater.Status.UPDATE_AVAILABLE || status == Updater.Status.UPDATE_DOWNLOADING) && updateButton.contains(mouseX, mouseY)) ||
|
||||||
|
@ -537,14 +557,11 @@ public class MainMenu extends BaseOpsuState {
|
||||||
playButton.resetHover();
|
playButton.resetHover();
|
||||||
if (!exitButton.contains(mouseX, mouseY, 0.25f))
|
if (!exitButton.contains(mouseX, mouseY, 0.25f))
|
||||||
exitButton.resetHover();
|
exitButton.resetHover();
|
||||||
if (!musicPlay.contains(mouseX, mouseY))
|
for (MenuButton b : this.musicButtons) {
|
||||||
musicPlay.resetHover();
|
if (!b.contains(mouseX, mouseY)) {
|
||||||
if (!musicPause.contains(mouseX, mouseY))
|
b.resetHover();
|
||||||
musicPause.resetHover();
|
}
|
||||||
if (!musicNext.contains(mouseX, mouseY))
|
}
|
||||||
musicNext.resetHover();
|
|
||||||
if (!musicPrevious.contains(mouseX, mouseY))
|
|
||||||
musicPrevious.resetHover();
|
|
||||||
if (repoButton != null && !repoButton.contains(mouseX, mouseY))
|
if (repoButton != null && !repoButton.contains(mouseX, mouseY))
|
||||||
repoButton.resetHover();
|
repoButton.resetHover();
|
||||||
if (danceRepoButton != null && !danceRepoButton.contains(mouseX, mouseY))
|
if (danceRepoButton != null && !danceRepoButton.contains(mouseX, mouseY))
|
||||||
|
@ -569,30 +586,15 @@ public class MainMenu extends BaseOpsuState {
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// music position bar
|
// music position bar
|
||||||
if (MusicController.isPlaying()) {
|
if (MusicController.isPlaying() && musicPositionBarContains(x, y)) {
|
||||||
if (musicPositionBarContains(x, y)) {
|
this.lastMeasureProgress = 0f;
|
||||||
lastMeasureProgress = 0f;
|
float pos = (float) (x - this.musicBarX) / this.musicBarWidth;
|
||||||
float pos = (x - musicBarX) / musicBarWidth;
|
MusicController.setPosition((int) (pos * MusicController.getDuration()));
|
||||||
MusicController.setPosition((int) (pos * MusicController.getDuration()));
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// music button actions
|
// music button actions
|
||||||
if (musicPlay.contains(x, y)) {
|
if (musicPrev.contains(x, y)) {
|
||||||
if (MusicController.isPlaying()) {
|
|
||||||
MusicController.pause();
|
|
||||||
barNotifs.send("Pause");
|
|
||||||
} else if (!MusicController.isTrackLoading()) {
|
|
||||||
MusicController.resume();
|
|
||||||
barNotifs.send("Play");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
} else if (musicNext.contains(x, y)) {
|
|
||||||
nextTrack(true);
|
|
||||||
barNotifs.send(">> Next");
|
|
||||||
return true;
|
|
||||||
} else if (musicPrevious.contains(x, y)) {
|
|
||||||
lastMeasureProgress = 0f;
|
lastMeasureProgress = 0f;
|
||||||
if (!previous.isEmpty()) {
|
if (!previous.isEmpty()) {
|
||||||
songMenuState.setFocus(BeatmapSetList.get().getBaseNode(previous.pop()), -1, true, false);
|
songMenuState.setFocus(BeatmapSetList.get().getBaseNode(previous.pop()), -1, true, false);
|
||||||
|
@ -604,6 +606,33 @@ public class MainMenu extends BaseOpsuState {
|
||||||
}
|
}
|
||||||
barNotifs.send("<< Previous");
|
barNotifs.send("<< Previous");
|
||||||
return true;
|
return true;
|
||||||
|
} else if (musicPlay.contains(x, y)) {
|
||||||
|
if (MusicController.isPlaying()) {
|
||||||
|
lastMeasureProgress = 0f;
|
||||||
|
MusicController.setPosition(0);
|
||||||
|
} else if (!MusicController.isTrackLoading()) {
|
||||||
|
MusicController.resume();
|
||||||
|
}
|
||||||
|
barNotifs.send("Play");
|
||||||
|
return true;
|
||||||
|
} else if (musicPause.contains(x, y)) {
|
||||||
|
if (MusicController.isPlaying()) {
|
||||||
|
MusicController.pause();
|
||||||
|
barNotifs.send("Pause");
|
||||||
|
} else if (!MusicController.isTrackLoading()) {
|
||||||
|
MusicController.resume();
|
||||||
|
barNotifs.send("Unpause");
|
||||||
|
}
|
||||||
|
} else if (musicStop.contains(x, y)) {
|
||||||
|
if (MusicController.isPlaying()) {
|
||||||
|
MusicController.setPosition(0);
|
||||||
|
MusicController.pause();
|
||||||
|
}
|
||||||
|
barNotifs.send("Stop Playing");
|
||||||
|
} else if (musicNext.contains(x, y)) {
|
||||||
|
nextTrack(true);
|
||||||
|
barNotifs.send(">> Next");
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// downloads button actions
|
// downloads button actions
|
||||||
|
|
|
@ -28,6 +28,7 @@ public class Colors {
|
||||||
BLACK_ALPHA = new Color(0, 0, 0, 0.5f),
|
BLACK_ALPHA = new Color(0, 0, 0, 0.5f),
|
||||||
BLACK_ALPHA_75 = new Color(0, 0, 0, 0.75f),
|
BLACK_ALPHA_75 = new Color(0, 0, 0, 0.75f),
|
||||||
BLACK_ALPHA_85 = new Color(0, 0, 0, 0.85f),
|
BLACK_ALPHA_85 = new Color(0, 0, 0, 0.85f),
|
||||||
|
WHITE_ALPHA_75 = new Color(1, 1, 1, 0.75f),
|
||||||
WHITE_ALPHA = new Color(255, 255, 255, 0.5f),
|
WHITE_ALPHA = new Color(255, 255, 255, 0.5f),
|
||||||
BLUE_DIVIDER = new Color(49, 94, 237),
|
BLUE_DIVIDER = new Color(49, 94, 237),
|
||||||
BLUE_BACKGROUND = new Color(74, 130, 255),
|
BLUE_BACKGROUND = new Color(74, 130, 255),
|
||||||
|
|