From 45e1438d4efd92bc42cf4f27ba645ba49e65fdd7 Mon Sep 17 00:00:00 2001 From: yugecin Date: Sun, 1 Jul 2018 22:25:18 +0200 Subject: [PATCH] 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 --- res/music-next.png | Bin 568 -> 306 bytes res/music-pause.png | Bin 238 -> 253 bytes res/music-play.png | Bin 522 -> 346 bytes res/music-previous.png | Bin 572 -> 318 bytes res/music-stop.png | Bin 0 -> 179 bytes src/itdelatrisu/opsu/GameImage.java | 9 ++ src/itdelatrisu/opsu/states/MainMenu.java | 171 +++++++++++++--------- src/itdelatrisu/opsu/ui/Colors.java | 1 + 8 files changed, 110 insertions(+), 71 deletions(-) create mode 100644 res/music-stop.png diff --git a/res/music-next.png b/res/music-next.png index f600ef30d8a9dca97a6f1fb11beeb866152fe390..5838b17d90d1b621ca0f90c50d59dd6f38d2c09c 100644 GIT binary patch literal 306 zcmeAS@N?(olHy`uVBq!ia0vp^N+8U_3?xrvihTr9Ea{HEjtmSN`?>!lvI6;x#X;^) z4C~IxyaaMM3p^r=85sBugD~Uq{1qucLAd~*5LfpCpZ~bQNk)T(AnheVe!&b0g@<|M zyym~(uvTV7$DO0z#eY_oc=IHtxKSeH|_wP|zv|qxr+sbf~)Yl{xRVKqp=1zt}^F4Zw zcp7ysdeXA!$JaRlBL5%xI*9l$R@tjDFU!{|aL?Rne_TIKQ=WME{RGQr+m0(Yer51G W)APsasDA~}O$?r{elF{r5}E+XTZ1P6 literal 568 zcmV-80>}M{P)sEaLmb8a>&MpSp#8V+a!?LOA8*-yRQhZLsS}Ppx+(7f_V`gC= zGeA607UYHO!IimrK>MkPOF@{ovn$6!y(d?$7+|}y(!J=PRwjVAuiOaV0D`?~1PHbu z0K9$rWmN;P1wj&@0Qecql$BY zX%|->-G2R!sO#%IySf*VREEG3Iun9;X&S_gZS+LgM(5_+C;{L~ImmJ+_lSe+19_E5 z&d^AJ6Ee0$FLSAQHJaYR)C8B;xR3Wh>D{Sy^!N25(>e>K_d0MKj1-@}3)Oy@=pjDV z2sL@h(c;NL+yjEz2PdsEM0`pUkn=FBBVGE6z|jJ%WRegFrhQ36@hfF;fcc_`g|5oP zQ32KtkuSD(X~Y@;>}>QB&H`u!(*4gKTOCtjq~06f0t^6#$`TmXiH-~a0000!lvI6;x#X;^) z4C~IxyaaMM3p^r=85sBugD~Uq{1qucL6rcX5ZC|z|GO9X07*PR_4AH+pnC3-Aiv-Q zh95IrWgk~>=Gf(Tc>isnu(zj+V~EE2WPy?d2Bt7a$Ab(4&526QEkY73TwQ97lH8Il zWzCF>7cjIeJfYC5wy7{ArKPLGF{pd-0*;o6Clr!+n4TRF3FS$%WMZh=ualKFueS|o OEQ6=3pUXO@geCy2=3$!v literal 238 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC$r9IylHmNblJdl&R0hYC{G?O` z&)mfH)S%SFl*+=BsWw1G6FglULn>~)xxSaTK|!D`@tnl-0`6${LO$)XLP57e7U|cY z-+Wl#)RJ&df2V-ZgVVuEt6pXG0X4#a!R?ZZb{!ra{1N{7r%QG}pFG>&q3z~ZssERZ zUm2gg+q)WM3mj!lvI6;x#X;^) z4C~IxyaaMM3p^r=85sBugD~Uq{1qucL4yFF5LfpCpZ}x)7rQr1K)w7WL4Lsu^FI~| zc_^{<9$g!A`@TtU$S#mWW_Y?dhG?9xy|hs9kb^+$!?j9cf|L0+ggbdzH2Vu?Dw=gU zF8;VusZGqo=gZtcIM5K6?}VzMg5jdTlCW7;_77?dxO7ph=evS z+O#mEV9~vk<~3@XAfy-lL;m8MCq6GL&Y#$RNny7RBjN8N*D#2LJP%&`!zCN&Mg~t;KbLh*2~7ZMN}Z1Y literal 522 zcmV+l0`>igP)w{_{zvU~%jVz+#DT1~XmLSjZO&&WeTEvtqAycOZe)i+!sxYdF zb%>-MnP3g}?#IQdPFiqGeW4T(?cR^$o&|L1l*$&MaF8-sN+r2E2!N$jX#p{%T4)+M z3y3LoHWQ$X4##eL7a&ThU%qrGYwb9|Ypc%;h+gPgQs}ZD@tx;kixE% z09a}5U5&mhE76$%@PTHq2l6Z+5+D&VlD}G=9FyF@0$LC9vpa=pbGNp(N=~DVqyROL zUkKo|^lIr7k)|(MBKo4aM4TBVF0l2^%*AgsPEa$V2}*-!lvI6;x#X;^) z4C~IxyaaMM3p^r=85sBugD~Uq{1qucLAd~*5ZC|z|GO9X07(7UIl4MUaA2`_o6rAGe;uxZFKJ}6<7qg;3TjK5sMJ%4OY}@>@r(e5gth3~F;5M$; zxyDv)7Wa8>*z6Je$D-8rdu~bIrlvLFzcrRTpOS4I@``a1mshUB$^}>0lsG$7!m5&% zs=K)*rKqgV*wm%AT4c)oKTpr(iCcF{w%+J;dlvI1#pPSw4bT1u^KN#!{D^y_k|vU* l{?YKMtlsDUIl*sg82cl-=C`t?`U2g@;OXk;vd$@?2>`;{gLnV{ literal 572 zcmV-C0>k}@P)P78b}Uwz*veE>i$ z9!vpjDF)_%))WI?;7f&o75ETB`hAfAiytOeP-|Ch)d&az%jW?7xkGSA4Jp_#|WeaA=Bw8??amU8h8h zGUmYJ=jZ-$r2+=D3)&9@zU>pi#}Zu`mVArD87(j>^oO^Mr0 z$M8Ln;9F@wR9Q7`l;It7NktJSQK!f4hp4|DUqPX){+q9kVV8yZa^X0MpI=L5kxT0FPO zYt~mmwdTndAUUlSwBmeUtI}J8iv(y3k!%KP`=Qle2~yX;00RJY(~p!9%Tw9_0000< KMNUMnLSTYHIQO0a diff --git a/res/music-stop.png b/res/music-stop.png new file mode 100644 index 0000000000000000000000000000000000000000..988a42719117f9eadce10413d3ce89d92ab1fc7b GIT binary patch literal 179 zcmeAS@N?(olHy`uVBq!ia0vp^${@_b3?$!tUzY`>I14-?iy0XB4uLSEsD@VqP*5Vk zC&bmgz~?_UAnP5v52%K{B*-tAVSa+oezunzv}P3oh4egK978nDCnp?WYML6*pc!yt zuMF!HhSpOT53IPbLO^U`NytQ_1rru3a0win#>S|?{_^o2*YpmcP6kg`KbLh*2~7Z_ CXG2&3 literal 0 HcmV?d00001 diff --git a/src/itdelatrisu/opsu/GameImage.java b/src/itdelatrisu/opsu/GameImage.java index dfe5dcbb..4a4c393d 100644 --- a/src/itdelatrisu/opsu/GameImage.java +++ b/src/itdelatrisu/opsu/GameImage.java @@ -345,6 +345,7 @@ public enum GameImage { // Music Player Buttons MUSIC_PLAY ("music-play", "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_PREVIOUS ("music-previous", "png", false, false), MUSIC_NOWPLAYING ("music-np", "png", false, false), @@ -654,6 +655,14 @@ public enum GameImage { setDefaultImage(); 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. diff --git a/src/itdelatrisu/opsu/states/MainMenu.java b/src/itdelatrisu/opsu/states/MainMenu.java index 993ecc34..909e78a8 100644 --- a/src/itdelatrisu/opsu/states/MainMenu.java +++ b/src/itdelatrisu/opsu/states/MainMenu.java @@ -51,6 +51,7 @@ import yugecin.opsudance.core.Constants; import yugecin.opsudance.core.state.BaseOpsuState; import yugecin.opsudance.core.state.OpsuState; +import static itdelatrisu.opsu.GameImage.*; import static itdelatrisu.opsu.ui.Colors.*; import static itdelatrisu.opsu.ui.animations.AnimationEquation.*; import static org.lwjgl.input.Keyboard.*; @@ -92,7 +93,8 @@ public class MainMenu extends BaseOpsuState { private MenuButton playButton, exitButton; /** 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. */ private MenuButton downloadsButton; @@ -106,6 +108,11 @@ public class MainMenu extends BaseOpsuState { /** Buttons for installing updates. */ 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. */ private long programStartTime; @@ -119,7 +126,7 @@ public class MainMenu extends BaseOpsuState { private boolean enterNotification = false; /** Music position bar coordinates and dimensions. */ - private float musicBarX, musicBarY, musicBarWidth, musicBarHeight; + private int musicBarX, musicBarY, musicBarWidth, musicBarHeight; /** Last measure progress value. */ private float lastMeasureProgress = 0f; @@ -135,6 +142,14 @@ public class MainMenu extends BaseOpsuState { programStartTime = System.currentTimeMillis(); 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 Image logoImg = GameImage.MENU_LOGO.getImage(); Image playImg = GameImage.MENU_PLAY.getImage(); @@ -161,22 +176,34 @@ public class MainMenu extends BaseOpsuState { exitButton.setHoverExpand(logoHoverScale); // initialize music buttons - int musicWidth = GameImage.MUSIC_PLAY.getImage().getWidth(); - int musicHeight = GameImage.MUSIC_PLAY.getImage().getHeight(); - musicPlay = new MenuButton(GameImage.MUSIC_PLAY.getImage(), displayContainer.width - (2 * musicWidth), musicHeight / 1.5f); - musicPause = new MenuButton(GameImage.MUSIC_PAUSE.getImage(), displayContainer.width - (2 * musicWidth), musicHeight / 1.5f); - musicNext = new MenuButton(GameImage.MUSIC_NEXT.getImage(), displayContainer.width - musicWidth, musicHeight / 1.5f); - musicPrevious = new MenuButton(GameImage.MUSIC_PREVIOUS.getImage(), displayContainer.width - (3 * musicWidth), musicHeight / 1.5f); - musicPlay.setHoverExpand(1.5f); - musicPause.setHoverExpand(1.5f); - musicNext.setHoverExpand(1.5f); - musicPrevious.setHoverExpand(1.5f); + final int musicSize = (int) (this.textLineHeight * 0.8f); + final float musicScale = (float) musicSize / MUSIC_STOP.getImage().getWidth(); + final int musicSpacing = (int) (musicSize * 0.8f) + musicSize; // (center to center) + int x = width - this.textMarginX - musicSize / 2; + int y = this.textLineHeight * 2 + this.textLineHeight / 2; + this.musicNext = new MenuButton(MUSIC_NEXT.getScaledImage(musicScale), x, y); + x -= musicSpacing; + this.musicStop = new MenuButton(MUSIC_STOP.getScaledImage(musicScale), x, y); + x -= musicSpacing; + 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 - musicBarX = displayContainer.width - musicWidth * 3.5f; - musicBarY = musicHeight * 1.25f; - musicBarWidth = musicWidth * 3f; - musicBarHeight = musicHeight * 0.11f; + this.musicBarX = x - musicSize / 2; + this.musicBarY = y + musicSize; + this.musicBarWidth = musicSize + musicSpacing * 4; + this.musicBarHeight = (int) (musicSize * 0.3f); // initialize downloads button Image dlImg = GameImage.DOWNLOADS.getImage(); @@ -233,11 +260,6 @@ public class MainMenu extends BaseOpsuState { int width = displayContainer.width; 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 Beatmap beatmap = MusicController.getBeatmap(); if (OPTION_DYNAMIC_BACKGROUND.state && @@ -328,22 +350,21 @@ public class MainMenu extends BaseOpsuState { Fonts.MEDIUM.drawString(npTextX, 0, trackText); // draw music buttons - if (MusicController.isPlaying()) - musicPause.draw(); - else - musicPlay.draw(); - musicNext.draw(); - musicPrevious.draw(); + for (MenuButton b : this.musicButtons) { + b.draw(); + } // draw music position bar int mouseX = displayContainer.mouseX; int mouseY = displayContainer.mouseY; g.setColor((musicPositionBarContains(mouseX, mouseY)) ? Colors.BLACK_BG_HOVER : Colors.BLACK_BG_NORMAL); - g.fillRoundRect(musicBarX, musicBarY, musicBarWidth, musicBarHeight, 4); - g.setColor(Color.white); + g.fillRect(this.musicBarX, this.musicBarY, this.musicBarWidth, this.musicBarHeight); + g.setColor(Colors.WHITE_ALPHA_75); if (!MusicController.isTrackLoading() && beatmap != null) { - float musicBarPosition = Math.min((float) MusicController.getPosition() / MusicController.getDuration(), 1f); - g.fillRoundRect(musicBarX, musicBarY, musicBarWidth * musicBarPosition, musicBarHeight, 4); + final float trackpos = MusicController.getPosition(); + 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 @@ -420,14 +441,9 @@ public class MainMenu extends BaseOpsuState { restartButton.autoHoverUpdate(delta, false); } downloadsButton.hoverUpdate(delta, mouseX, mouseY); - // ensure only one button is in hover state at once - boolean noHoverUpdate = musicPositionBarContains(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)); + for (MenuButton b : this.musicButtons) { + b.hoverUpdate(delta, b.contains(mouseX, mouseY)); + } starFountain.update(delta); // window focus change: increase/decrease theme song volume @@ -489,12 +505,16 @@ public class MainMenu extends BaseOpsuState { // tooltips if (musicPositionBarContains(mouseX, mouseY)) 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)) - 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)) UI.updateTooltip(delta, "Next track", false); - else if (musicPrevious.contains(mouseX, mouseY)) - UI.updateTooltip(delta, "Previous track", false); else if (updater.showButton()) { Updater.Status status = updater.getStatus(); 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(); if (!exitButton.contains(mouseX, mouseY, 0.25f)) exitButton.resetHover(); - if (!musicPlay.contains(mouseX, mouseY)) - musicPlay.resetHover(); - if (!musicPause.contains(mouseX, mouseY)) - musicPause.resetHover(); - if (!musicNext.contains(mouseX, mouseY)) - musicNext.resetHover(); - if (!musicPrevious.contains(mouseX, mouseY)) - musicPrevious.resetHover(); + for (MenuButton b : this.musicButtons) { + if (!b.contains(mouseX, mouseY)) { + b.resetHover(); + } + } if (repoButton != null && !repoButton.contains(mouseX, mouseY)) repoButton.resetHover(); if (danceRepoButton != null && !danceRepoButton.contains(mouseX, mouseY)) @@ -569,30 +586,15 @@ public class MainMenu extends BaseOpsuState { return false; // music position bar - if (MusicController.isPlaying()) { - if (musicPositionBarContains(x, y)) { - lastMeasureProgress = 0f; - float pos = (x - musicBarX) / musicBarWidth; - MusicController.setPosition((int) (pos * MusicController.getDuration())); - return true; - } + if (MusicController.isPlaying() && musicPositionBarContains(x, y)) { + this.lastMeasureProgress = 0f; + float pos = (float) (x - this.musicBarX) / this.musicBarWidth; + MusicController.setPosition((int) (pos * MusicController.getDuration())); + return true; } // music button actions - if (musicPlay.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)) { + if (musicPrev.contains(x, y)) { lastMeasureProgress = 0f; if (!previous.isEmpty()) { songMenuState.setFocus(BeatmapSetList.get().getBaseNode(previous.pop()), -1, true, false); @@ -604,6 +606,33 @@ public class MainMenu extends BaseOpsuState { } barNotifs.send("<< Previous"); 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 diff --git a/src/itdelatrisu/opsu/ui/Colors.java b/src/itdelatrisu/opsu/ui/Colors.java index 1db4ba7a..51477fc9 100644 --- a/src/itdelatrisu/opsu/ui/Colors.java +++ b/src/itdelatrisu/opsu/ui/Colors.java @@ -28,6 +28,7 @@ public class Colors { BLACK_ALPHA = new Color(0, 0, 0, 0.5f), BLACK_ALPHA_75 = new Color(0, 0, 0, 0.75f), 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), BLUE_DIVIDER = new Color(49, 94, 237), BLUE_BACKGROUND = new Color(74, 130, 255),