From 62b5d574da8237e557717e9c8d45b4e880d84b2e Mon Sep 17 00:00:00 2001 From: yugecin Date: Thu, 2 Feb 2017 01:06:56 +0100 Subject: [PATCH] default back button --- res/menu-back-chevron.png | Bin 0 -> 1306 bytes res/menu-back-slope.png | Bin 0 -> 972 bytes res/menu-back.png | Bin 5014 -> 162 bytes src/itdelatrisu/opsu/GameImage.java | 2 + .../opsu/states/DownloadsMenu.java | 2 +- src/itdelatrisu/opsu/states/GameRanking.java | 2 +- src/itdelatrisu/opsu/states/SongMenu.java | 2 +- src/itdelatrisu/opsu/ui/UI.java | 20 +- .../opsudance/core/DisplayContainer.java | 1 + src/yugecin/opsudance/ui/BackButton.java | 225 ++++++++++++++++++ src/yugecin/opsudance/ui/OptionsOverlay.java | 2 +- 11 files changed, 239 insertions(+), 17 deletions(-) create mode 100644 res/menu-back-chevron.png create mode 100644 res/menu-back-slope.png create mode 100644 src/yugecin/opsudance/ui/BackButton.java diff --git a/res/menu-back-chevron.png b/res/menu-back-chevron.png new file mode 100644 index 0000000000000000000000000000000000000000..0f8d924edf8667dffdc942201c5493591516ab41 GIT binary patch literal 1306 zcmV+#1?BpQP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D02p*dSaefwW^{L9 za%BK;VQFr3E^cLXAT%y8E;t)BPS^kd1dB;TK~z{rwN_n7WMvpWO*RY7M5(Y_Ns%zN zI{uBLb``D~qXuK5sdTlVld=#<7pv)oAkIn`f@CH#364k+p@NDaX6VIUnK$`Yc%h3w zO}c8+=xFX3*z=q@M;zzO%*mz)-r@V+^M3F1%=zB$dyjB&aiPj4CnsOr-roM`;NajJ zuh+YDetzzTUj)Y|Cnu|X#u&!Jt(fP!DLQ3yI2_MSO-+80&v$Lm|-w0gG9L$BOB9Ef8wYBx--QC^qFpdhCi#ah2;tFy! zHa5PpzrR0=u_|ESeT$2WUTGQ<%*oss2Ji(;%F4=gTU%Qr7^}kJ;o-C5;^H5Ylan7o zM8q0lZgOB4EP(qoKR^E|#;QQ_($doJ)6>)MXJus-W@cu7sYb-Y!otI*rl!l95Pw*y z9UUES<0$>Xph%F(Gcqzh1QM#Ms^U#1(|c+}oSvR~y1ToLJv}|*=@13f)YRx!R#t|@ zhzPh!US3}QT4!hH^ZWx96%}zdo2}O6a(SfCkRVrWZLJjzxCQ(h z&G`6u>hbaMjz2Oy$OXv0GT{5FYjXOS!qZ?_*yci%}|YRRr5H>`i=j{VF{U z338B&oS6Cr^!4>=tXAt=X=!Pn%*@QFYN-T8unmL!4Y%7J_9PL^O%8IA6E431T0=v_ zExeX&9F6w5xw$kA!H4ND(ljKPlex)3F1SSAO93==CmmkTyZFfbe0qA?1z%La zT+GSb!C zTipLo{*4gEat+rq2XkHj=duMkWaB=uSXi-1NlDF#iHT15ei|7WajmYddanxN7{~8q zczF1C#xRy^xRyDt?)i07bjrp`<#FMe<;8&u%Z87LM+pfDU+MLFheo6Mnx@m~9Q5%S zV;IXdTq{?5C{uJQ8E-9KoxH!_}WhtKf{ QqyPW_07*qoM6N<$f&_$V&;S4c literal 0 HcmV?d00001 diff --git a/res/menu-back-slope.png b/res/menu-back-slope.png new file mode 100644 index 0000000000000000000000000000000000000000..3385f226534cca1d39965f592b4cb0824ab21781 GIT binary patch literal 972 zcmV;-12g=IP)N2bZe?^J zG%heMI2$xh*Z=?nN=ZaPR9HvNnL9{ZVHk#EYfLmXmy=7A=Bgoy#%qu&3K2oDlN2w5 z9fed09Rh+`q(iqtwoYBD;LypX&@Efzl&LOpkPJZ(B^)$GC1}*X-yu1~<7GYH5AQ$x z)5Dkl`~LSm(bQ@+k*gdIhv0I#41qvEJ2*J_LUYG-U0ht`USoMYp3ZPMtecpa;0t?v ze7xy&I$b`W&lHVDbu%+Fd|?ZP!e@f@`~Aj&fq}M#g$2H_J3Bk?=^6m`)zHw8c4cLy zg)Qv-{CpG*X7_r%2Eewa(`lZt)oQh5Hk*BbwW6}^u~_USjx{V{Pft&?R;$&Ev1JJc zgZlCDalWvJhlk%$RX4_#si&t$nglrJ37gO7KcTmrjY+VywA6xQp0L~7+wV|W2WG4^ z36jYqPuSbr+ZulQpxth_VG?xUnQg@}aq@$`yu2(}EEXTGfdEg?J~A>QH5Z8;tSE}V zZ8n?7?RHy2p^!cvk4w!(Vh39+7Bi^o8}bBweSNyw*;&4@xm@leJb@EepmTV5xNUiP zS!ym4JJ?Jn6GvqoSZjLW( zHkW14uhMS@{j`_hNdKc@_TWF5nO0j^gM{iG4^nP$(Ni1MX zrP4Q4Rf^udy}feuR*D5|bM(f2m7}*(EMT9C-b$$si|Ad2;SM|&y_KR()%9HTR*E)N zSGipNRgd0gW%O2xHdWWb!NFHl_0j096m6=m-QC>;GFQWJ-;3T#(WdI!*w}arSUX^) zFWk-1TPfO9TQ@g1mAZ$Oo>{o9C!32zn`#S_AWvUkFtSWA+&cPW4#y858`6lPxTS{R u2R6^n&VIlP2$%u}JhNIDm}g+`H2(pXRI7H{RNSWk0000NS%G}c0*}aI z1_o|H5N51TiJu4*WH0gbb!ETH!q09bcDd$B5>QB@#5JNMI6tkVJh3R1p&&6cuS72| wwM4;0&p^*Y+Qjb$Pz|rAi(`mHcya;|0J*FTj9tc$feZ!)Pgg&ebxsLQ07Oe9KL7v# literal 5014 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 b&KaCm5mz8%7x%yuGyr)=U#m#NCiMRRz&Np? diff --git a/src/itdelatrisu/opsu/GameImage.java b/src/itdelatrisu/opsu/GameImage.java index f7ce5c83..a30400f7 100644 --- a/src/itdelatrisu/opsu/GameImage.java +++ b/src/itdelatrisu/opsu/GameImage.java @@ -253,6 +253,8 @@ public enum GameImage { } }, MENU_BACK ("menu-back", "menu-back-%d", "png"), + MENU_BACK_CHEVRON ("menu-back-chevron", "png"), + MENU_BACK_SLOPE("menu-back-slope", "png"), MENU_BUTTON_BG ("menu-button-background", "png", false, false), MENU_TAB ("selection-tab", "png", false, false) { @Override diff --git a/src/itdelatrisu/opsu/states/DownloadsMenu.java b/src/itdelatrisu/opsu/states/DownloadsMenu.java index ddb1d5a3..da518b84 100644 --- a/src/itdelatrisu/opsu/states/DownloadsMenu.java +++ b/src/itdelatrisu/opsu/states/DownloadsMenu.java @@ -519,7 +519,7 @@ public class DownloadsMenu extends ComplexOpsuState { // back button else - UI.getBackButton().draw(); + UI.getBackButton().draw(g); UI.draw(g); } diff --git a/src/itdelatrisu/opsu/states/GameRanking.java b/src/itdelatrisu/opsu/states/GameRanking.java index 8c74a4a4..224adadc 100644 --- a/src/itdelatrisu/opsu/states/GameRanking.java +++ b/src/itdelatrisu/opsu/states/GameRanking.java @@ -99,7 +99,7 @@ public class GameRanking extends BaseOpsuState { replayButton.draw(); if (data.isGameplay() && !GameMod.AUTO.isActive()) retryButton.draw(); - UI.getBackButton().draw(); + UI.getBackButton().draw(g); UI.draw(g); diff --git a/src/itdelatrisu/opsu/states/SongMenu.java b/src/itdelatrisu/opsu/states/SongMenu.java index c8f4e666..ec54b372 100644 --- a/src/itdelatrisu/opsu/states/SongMenu.java +++ b/src/itdelatrisu/opsu/states/SongMenu.java @@ -715,7 +715,7 @@ public class SongMenu extends ComplexOpsuState { // back button else - UI.getBackButton().draw(); + UI.getBackButton().draw(g); UI.draw(g); diff --git a/src/itdelatrisu/opsu/ui/UI.java b/src/itdelatrisu/opsu/ui/UI.java index 6b057da8..586075b1 100644 --- a/src/itdelatrisu/opsu/ui/UI.java +++ b/src/itdelatrisu/opsu/ui/UI.java @@ -33,6 +33,8 @@ import org.newdawn.slick.Color; import org.newdawn.slick.Graphics; import org.newdawn.slick.Image; import yugecin.opsudance.core.DisplayContainer; +import yugecin.opsudance.events.ResolutionOrSkinChangedEvent; +import yugecin.opsudance.ui.BackButton; /** * Draws common UI components. @@ -40,7 +42,7 @@ import yugecin.opsudance.core.DisplayContainer; public class UI { /** Back button. */ - private static MenuButton backButton; + private static BackButton backButton; /** Time to show volume image, in milliseconds. */ private static final int VOLUME_DISPLAY_TIME = 1500; @@ -68,18 +70,10 @@ public class UI { */ public static void init(DisplayContainer displayContainer) { UI.displayContainer = displayContainer; + } - // back button - if (GameImage.MENU_BACK.getImages() != null) { - Animation back = GameImage.MENU_BACK.getAnimation(120); - backButton = new MenuButton(back, back.getWidth() / 2f, displayContainer.height - (back.getHeight() / 2f)); - } else { - Image back = GameImage.MENU_BACK.getImage(); - backButton = new MenuButton(back, back.getWidth() / 2f, displayContainer.height - (back.getHeight() / 2f)); - } - backButton.setHoverAnimationDuration(350); - backButton.setHoverAnimationEquation(AnimationEquation.IN_OUT_BACK); - backButton.setHoverExpand(MenuButton.Expand.UP_RIGHT); + public static void revalidate() { + backButton = new BackButton(displayContainer); } /** @@ -110,7 +104,7 @@ public class UI { /** * Returns the 'menu-back' MenuButton. */ - public static MenuButton getBackButton() { return backButton; } + public static BackButton getBackButton() { return backButton; } /** * Draws a tab image and text centered at a location. diff --git a/src/yugecin/opsudance/core/DisplayContainer.java b/src/yugecin/opsudance/core/DisplayContainer.java index 9d019e94..fe7549f0 100644 --- a/src/yugecin/opsudance/core/DisplayContainer.java +++ b/src/yugecin/opsudance/core/DisplayContainer.java @@ -350,6 +350,7 @@ public class DisplayContainer implements ErrorDumpable, KeyListener, MouseListen Fonts.init(); eventBus.post(new ResolutionOrSkinChangedEvent()); + UI.revalidate(); // TODO this shouldn't be here } public void resetCursor() { diff --git a/src/yugecin/opsudance/ui/BackButton.java b/src/yugecin/opsudance/ui/BackButton.java new file mode 100644 index 00000000..3e72d21f --- /dev/null +++ b/src/yugecin/opsudance/ui/BackButton.java @@ -0,0 +1,225 @@ +/* + * opsu!dance - fork of opsu! with cursordance auto + * Copyright (C) 2017 yugecin + * + * opsu!dance is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * opsu!dance is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with opsu!dance. If not, see . + */ +package yugecin.opsudance.ui; + +import itdelatrisu.opsu.GameImage; +import itdelatrisu.opsu.audio.MusicController; +import itdelatrisu.opsu.ui.Fonts; +import itdelatrisu.opsu.ui.MenuButton; +import itdelatrisu.opsu.ui.animations.AnimationEquation; +import org.newdawn.slick.*; +import yugecin.opsudance.core.DisplayContainer; + +public class BackButton { + + /** Skinned back button. */ + private MenuButton backButton; + + /** Colors. */ + private static final Color + COLOR_PINK = new Color(238, 51, 153), + COLOR_DARKPINK = new Color(186, 19, 121); + + /** Target duration, in ms, of the button animations. */ + private static final int ANIMATION_TIME = 500; + + /** How much time passed for the animations. */ + private int animationTime; + + /** The size of the slope image (square shape). */ + private int slopeImageSize; + + /** The width of the slope part in the slope image. */ + private int slopeImageSlopeWidth; + + /** The width of the first part of the button. */ + private int firstButtonWidth; + + /** The width of the second part of the button. */ + private int secondButtonSize; + + /** Variable to hold the hovered state, to not recalculate it twice per frame. */ + private boolean isHovered; + + /** The width of the "back" text to draw. */ + private int textWidth; + + /** Y padding for the text and general positioning. */ + private float paddingY; + + /** X padding for the text. */ + private float paddingX; + + /** Y text offset because getHeight is not so accurate. */ + private float textOffset; + + /** The base size of the chevron. */ + private float chevronBaseSize; + + /** The Y position of where the button starts. */ + private int buttonYpos; + + /** Variable holding the slope image. */ + private Image slopeImage; + + /** The real button with, determined by the size and animations. */ + private int realButtonWidth; + + public BackButton(DisplayContainer container) { + //if (!GameImage.MENU_BACK.hasGameSkinImage()) { + if (GameImage.MENU_BACK.getImage() != null && GameImage.MENU_BACK.getImage().getWidth() < 2) { + backButton = null; + textWidth = Fonts.MEDIUM.getWidth("back"); + paddingY = Fonts.MEDIUM.getHeight("back"); + // getHeight doesn't seem to be so accurate + textOffset = paddingY * 0.264f; + paddingY *= 0.736f; + paddingX = paddingY / 2f; + chevronBaseSize = paddingY * 3f / 2f; + buttonYpos = (int) (container.height - paddingY * 4f); + slopeImageSize = (int) (paddingY * 3f); + slopeImageSlopeWidth = (int) (slopeImageSize * 0.295f); + firstButtonWidth = slopeImageSize; + secondButtonSize = (int) (slopeImageSlopeWidth + paddingX * 2 + textWidth); + slopeImage = GameImage.MENU_BACK_SLOPE.getImage().getScaledCopy(slopeImageSize, slopeImageSize); + return; + } + + if (GameImage.MENU_BACK.getImages() != null) { + Animation back = GameImage.MENU_BACK.getAnimation(120); + backButton = new MenuButton(back, back.getWidth() / 2f, container.height - (back.getHeight() / 2f)); + } else { + Image back = GameImage.MENU_BACK.getImage(); + backButton = new MenuButton(back, back.getWidth() / 2f, container.height - (back.getHeight() / 2f)); + } + backButton.setHoverAnimationDuration(350); + backButton.setHoverAnimationEquation(AnimationEquation.IN_OUT_BACK); + backButton.setHoverExpand(MenuButton.Expand.UP_RIGHT); + } + + /** + * Draws the backbutton. + */ + public void draw(Graphics g) { + // draw image if it's skinned + if (backButton != null) { + backButton.draw(); + return; + } + + // calc chevron size + Float beatProgress = MusicController.getBeatProgress(); + if (beatProgress == null) { + beatProgress = 0f; + } + int chevronSize = (int) (chevronBaseSize - (isHovered ? 6f : 3f) * beatProgress); + + // calc button sizes + AnimationEquation anim; + if (isHovered) { + anim = AnimationEquation.OUT_ELASTIC; + } else { + anim = AnimationEquation.IN_ELASTIC; + } + float progress = anim.calc((float) animationTime / ANIMATION_TIME); + float firstSize = firstButtonWidth + (firstButtonWidth - slopeImageSlopeWidth * 2) * progress; + float secondSize = secondButtonSize + secondButtonSize * 0.25f * progress; + realButtonWidth = (int) (firstSize + secondSize); + + // right part + g.setColor(COLOR_PINK); + g.fillRect(0, buttonYpos, firstSize + secondSize - slopeImageSlopeWidth, slopeImageSize); + slopeImage.draw(firstSize + secondSize - slopeImageSize, buttonYpos, COLOR_PINK); + + // left part + Color hoverColor = new Color(0f, 0f, 0f); + hoverColor.r = COLOR_PINK.r + (COLOR_DARKPINK.r - COLOR_PINK.r) * progress; + hoverColor.g = COLOR_PINK.g + (COLOR_DARKPINK.g - COLOR_PINK.g) * progress; + hoverColor.b = COLOR_PINK.b + (COLOR_DARKPINK.b - COLOR_PINK.b) * progress; + g.setColor(hoverColor); + g.fillRect(0, buttonYpos, firstSize - slopeImageSlopeWidth, slopeImageSize); + slopeImage.draw(firstSize - slopeImageSize, buttonYpos, hoverColor); + + // chevron + GameImage.MENU_BACK_CHEVRON.getImage().getScaledCopy(chevronSize, chevronSize).drawCentered((firstSize - slopeImageSlopeWidth / 2) / 2, buttonYpos + paddingY * 1.5f); + + // text + float textY = buttonYpos + paddingY - textOffset; + float textX = firstSize + (secondSize - paddingX * 2 - textWidth) / 2; + Fonts.MEDIUM.drawString(textX, textY + 1, "back", Color.black); + Fonts.MEDIUM.drawString(textX, textY, "back", Color.white); + } + + /** + * Processes a hover action depending on whether or not the cursor + * is hovering over the button. + * @param delta the delta interval + * @param cx the x coordinate + * @param cy the y coordinate + */ + public void hoverUpdate(int delta, int cx, int cy) { + if (backButton != null) { + backButton.hoverUpdate(delta, cx, cy); + return; + } + boolean wasHovered = isHovered; + isHovered = buttonYpos - paddingY < cy && cx < realButtonWidth; + if (isHovered) { + if (!wasHovered) { + animationTime = 0; + } + animationTime += delta; + if (animationTime > ANIMATION_TIME) { + animationTime = ANIMATION_TIME; + } + } else { + if (wasHovered) { + animationTime = ANIMATION_TIME; + } + animationTime -= delta; + if (animationTime < 0) { + animationTime = 0; + } + } + } + + /** + * Returns true if the coordinates are within the button bounds. + * @param cx the x coordinate + * @param cy the y coordinate + */ + public boolean contains(float cx, float cy) { + if (backButton != null) { + return backButton.contains(cx, cy); + } + return buttonYpos - paddingY < cy && cx < realButtonWidth; + } + + /** + * Resets the hover fields for the button. + */ + public void resetHover() { + if (backButton != null) { + backButton.resetHover(); + return; + } + isHovered = false; + animationTime = 0; + } + +} diff --git a/src/yugecin/opsudance/ui/OptionsOverlay.java b/src/yugecin/opsudance/ui/OptionsOverlay.java index f6e97989..f177c93f 100644 --- a/src/yugecin/opsudance/ui/OptionsOverlay.java +++ b/src/yugecin/opsudance/ui/OptionsOverlay.java @@ -259,7 +259,7 @@ public class OptionsOverlay extends OverlayOpsuState { g.clearClip(); // UI - UI.getBackButton().draw(); + UI.getBackButton().draw(g); // tooltip renderTooltip(g);