default back button

This commit is contained in:
yugecin 2017-02-02 01:06:56 +01:00
parent 61340eb9ee
commit 62b5d574da
11 changed files with 239 additions and 17 deletions

BIN
res/menu-back-chevron.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

BIN
res/menu-back-slope.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 972 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

After

Width:  |  Height:  |  Size: 162 B

View File

@ -253,6 +253,8 @@ public enum GameImage {
} }
}, },
MENU_BACK ("menu-back", "menu-back-%d", "png"), 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_BUTTON_BG ("menu-button-background", "png", false, false),
MENU_TAB ("selection-tab", "png", false, false) { MENU_TAB ("selection-tab", "png", false, false) {
@Override @Override

View File

@ -519,7 +519,7 @@ public class DownloadsMenu extends ComplexOpsuState {
// back button // back button
else else
UI.getBackButton().draw(); UI.getBackButton().draw(g);
UI.draw(g); UI.draw(g);
} }

View File

@ -99,7 +99,7 @@ public class GameRanking extends BaseOpsuState {
replayButton.draw(); replayButton.draw();
if (data.isGameplay() && !GameMod.AUTO.isActive()) if (data.isGameplay() && !GameMod.AUTO.isActive())
retryButton.draw(); retryButton.draw();
UI.getBackButton().draw(); UI.getBackButton().draw(g);
UI.draw(g); UI.draw(g);

View File

@ -715,7 +715,7 @@ public class SongMenu extends ComplexOpsuState {
// back button // back button
else else
UI.getBackButton().draw(); UI.getBackButton().draw(g);
UI.draw(g); UI.draw(g);

View File

@ -33,6 +33,8 @@ import org.newdawn.slick.Color;
import org.newdawn.slick.Graphics; import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image; import org.newdawn.slick.Image;
import yugecin.opsudance.core.DisplayContainer; import yugecin.opsudance.core.DisplayContainer;
import yugecin.opsudance.events.ResolutionOrSkinChangedEvent;
import yugecin.opsudance.ui.BackButton;
/** /**
* Draws common UI components. * Draws common UI components.
@ -40,7 +42,7 @@ import yugecin.opsudance.core.DisplayContainer;
public class UI { public class UI {
/** Back button. */ /** Back button. */
private static MenuButton backButton; private static BackButton backButton;
/** Time to show volume image, in milliseconds. */ /** Time to show volume image, in milliseconds. */
private static final int VOLUME_DISPLAY_TIME = 1500; private static final int VOLUME_DISPLAY_TIME = 1500;
@ -68,18 +70,10 @@ public class UI {
*/ */
public static void init(DisplayContainer displayContainer) { public static void init(DisplayContainer displayContainer) {
UI.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); public static void revalidate() {
backButton.setHoverExpand(MenuButton.Expand.UP_RIGHT); backButton = new BackButton(displayContainer);
} }
/** /**
@ -110,7 +104,7 @@ public class UI {
/** /**
* Returns the 'menu-back' MenuButton. * 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. * Draws a tab image and text centered at a location.

View File

@ -350,6 +350,7 @@ public class DisplayContainer implements ErrorDumpable, KeyListener, MouseListen
Fonts.init(); Fonts.init();
eventBus.post(new ResolutionOrSkinChangedEvent()); eventBus.post(new ResolutionOrSkinChangedEvent());
UI.revalidate(); // TODO this shouldn't be here
} }
public void resetCursor() { public void resetCursor() {

View File

@ -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 <http://www.gnu.org/licenses/>.
*/
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;
}
}

View File

@ -259,7 +259,7 @@ public class OptionsOverlay extends OverlayOpsuState {
g.clearClip(); g.clearClip();
// UI // UI
UI.getBackButton().draw(); UI.getBackButton().draw(g);
// tooltip // tooltip
renderTooltip(g); renderTooltip(g);