Added fade effects for tooltips.
Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
a66133c605
commit
a7390f7c1d
|
@ -74,8 +74,8 @@ public class ScoreData implements Comparable<ScoreData> {
|
||||||
/** A formatted string of the timestamp. */
|
/** A formatted string of the timestamp. */
|
||||||
private String timeString;
|
private String timeString;
|
||||||
|
|
||||||
/** A formatted string of the mods. */
|
/** The tooltip string. */
|
||||||
private String modString;
|
private String tooltip;
|
||||||
|
|
||||||
/** Drawing values. */
|
/** Drawing values. */
|
||||||
private static float baseX, baseY, buttonWidth, buttonHeight, buttonOffset;
|
private static float baseX, baseY, buttonWidth, buttonHeight, buttonOffset;
|
||||||
|
@ -215,15 +215,6 @@ public class ScoreData implements Comparable<ScoreData> {
|
||||||
return (timeSince.isEmpty()) ? null : timeSince;
|
return (timeSince.isEmpty()) ? null : timeSince;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a comma-separated string of mod names.
|
|
||||||
*/
|
|
||||||
private String getModString() {
|
|
||||||
if (modString == null)
|
|
||||||
modString = GameMod.getModString(mods);
|
|
||||||
return modString;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the score data as a rectangular button.
|
* Draws the score data as a rectangular button.
|
||||||
* @param g the graphics context
|
* @param g the graphics context
|
||||||
|
@ -318,15 +309,14 @@ public class ScoreData implements Comparable<ScoreData> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the a tooltip containing the score information.
|
* Returns the tooltip string for this score.
|
||||||
* @param g the graphics context
|
|
||||||
*/
|
*/
|
||||||
public void drawTooltip(Graphics g) {
|
public String getTooltipString() {
|
||||||
String text = String.format(
|
if (tooltip == null)
|
||||||
|
tooltip = String.format(
|
||||||
"Achieved on %s\n300:%d 100:%d 50:%d Miss:%d\nAccuracy: %.2f%%\nMods: %s",
|
"Achieved on %s\n300:%d 100:%d 50:%d Miss:%d\nAccuracy: %.2f%%\nMods: %s",
|
||||||
getTimeString(), hit300, hit100, hit50, miss,
|
getTimeString(), hit300, hit100, hit50, miss, getScorePercent(), GameMod.getModString(mods));
|
||||||
getScorePercent(), getModString());
|
return tooltip;
|
||||||
UI.drawTooltip(g, text, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -335,7 +325,7 @@ public class ScoreData implements Comparable<ScoreData> {
|
||||||
"%s | ID: (%d, %d) | %s - %s [%s] (by %s) | " +
|
"%s | ID: (%d, %d) | %s - %s [%s] (by %s) | " +
|
||||||
"Hits: (%d, %d, %d, %d, %d, %d) | Score: %d (%d combo%s) | Mods: %s",
|
"Hits: (%d, %d, %d, %d, %d, %d) | Score: %d (%d combo%s) | Mods: %s",
|
||||||
getTimeString(), MID, MSID, artist, title, version, creator,
|
getTimeString(), MID, MSID, artist, title, version, creator,
|
||||||
hit300, hit100, hit50, geki, katu, miss, score, combo, perfect ? ", FC" : "", getModString()
|
hit300, hit100, hit50, geki, katu, miss, score, combo, perfect ? ", FC" : "", GameMod.getModString(mods)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -75,6 +75,18 @@ public class UI {
|
||||||
/** Duration, in milliseconds, to display bar notifications. */
|
/** Duration, in milliseconds, to display bar notifications. */
|
||||||
private static final int BAR_NOTIFICATION_TIME = 1250;
|
private static final int BAR_NOTIFICATION_TIME = 1250;
|
||||||
|
|
||||||
|
/** The current tooltip. */
|
||||||
|
private static String tooltip;
|
||||||
|
|
||||||
|
/** Whether or not to check the current tooltip for line breaks. */
|
||||||
|
private static boolean tooltipNewlines;
|
||||||
|
|
||||||
|
/** The current tooltip timer. */
|
||||||
|
private static int tooltipTimer = -1;
|
||||||
|
|
||||||
|
/** Duration, in milliseconds, to fade tooltips. */
|
||||||
|
private static final int TOOLTIP_FADE_TIME = 200;
|
||||||
|
|
||||||
// game-related variables
|
// game-related variables
|
||||||
private static GameContainer container;
|
private static GameContainer container;
|
||||||
private static StateBasedGame game;
|
private static StateBasedGame game;
|
||||||
|
@ -124,6 +136,8 @@ public class UI {
|
||||||
updateCursor(delta);
|
updateCursor(delta);
|
||||||
updateVolumeDisplay(delta);
|
updateVolumeDisplay(delta);
|
||||||
updateBarNotification(delta);
|
updateBarNotification(delta);
|
||||||
|
if (tooltipTimer > 0)
|
||||||
|
tooltipTimer -= delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -135,6 +149,7 @@ public class UI {
|
||||||
drawVolume(g);
|
drawVolume(g);
|
||||||
drawFPS();
|
drawFPS();
|
||||||
drawCursor();
|
drawCursor();
|
||||||
|
drawTooltip(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -149,6 +164,7 @@ public class UI {
|
||||||
drawVolume(g);
|
drawVolume(g);
|
||||||
drawFPS();
|
drawFPS();
|
||||||
drawCursor(mouseX, mouseY, mousePressed);
|
drawCursor(mouseX, mouseY, mousePressed);
|
||||||
|
drawTooltip(g);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -157,6 +173,7 @@ public class UI {
|
||||||
public static void enter() {
|
public static void enter() {
|
||||||
backButton.resetHover();
|
backButton.resetHover();
|
||||||
resetBarNotification();
|
resetBarNotification();
|
||||||
|
resetTooltip();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -535,20 +552,41 @@ public class UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws a tooltip near the current mouse coordinates, bounded by the
|
* Sets or updates a tooltip for drawing.
|
||||||
* container dimensions.
|
* Must be called with {@link #drawTooltip(Graphics)}.
|
||||||
* @param g the graphics context
|
* @param delta the delta interval since the last call
|
||||||
* @param text the tooltip text
|
* @param s the tooltip text
|
||||||
* @param newlines whether to check for line breaks ('\n')
|
* @param newlines whether to check for line breaks ('\n')
|
||||||
*/
|
*/
|
||||||
public static void drawTooltip(Graphics g, String text, boolean newlines) {
|
public static void updateTooltip(int delta, String s, boolean newlines) {
|
||||||
|
if (s != null) {
|
||||||
|
tooltip = s;
|
||||||
|
tooltipNewlines = newlines;
|
||||||
|
if (tooltipTimer <= 0)
|
||||||
|
tooltipTimer = delta;
|
||||||
|
else
|
||||||
|
tooltipTimer += delta * 2;
|
||||||
|
if (tooltipTimer > TOOLTIP_FADE_TIME)
|
||||||
|
tooltipTimer = TOOLTIP_FADE_TIME;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws a tooltip, if any, near the current mouse coordinates,
|
||||||
|
* bounded by the container dimensions.
|
||||||
|
* @param g the graphics context
|
||||||
|
*/
|
||||||
|
public static void drawTooltip(Graphics g) {
|
||||||
|
if (tooltipTimer <= 0 || tooltip == null)
|
||||||
|
return;
|
||||||
|
|
||||||
int containerWidth = container.getWidth(), containerHeight = container.getHeight();
|
int containerWidth = container.getWidth(), containerHeight = container.getHeight();
|
||||||
int margin = containerWidth / 100, textMarginX = 2;
|
int margin = containerWidth / 100, textMarginX = 2;
|
||||||
int offset = GameImage.CURSOR_MIDDLE.getImage().getWidth() / 2;
|
int offset = GameImage.CURSOR_MIDDLE.getImage().getWidth() / 2;
|
||||||
int lineHeight = Utils.FONT_SMALL.getLineHeight();
|
int lineHeight = Utils.FONT_SMALL.getLineHeight();
|
||||||
int textWidth = textMarginX * 2, textHeight = lineHeight;
|
int textWidth = textMarginX * 2, textHeight = lineHeight;
|
||||||
if (newlines) {
|
if (tooltipNewlines) {
|
||||||
String[] lines = text.split("\\n");
|
String[] lines = tooltip.split("\\n");
|
||||||
int maxWidth = Utils.FONT_SMALL.getWidth(lines[0]);
|
int maxWidth = Utils.FONT_SMALL.getWidth(lines[0]);
|
||||||
for (int i = 1; i < lines.length; i++) {
|
for (int i = 1; i < lines.length; i++) {
|
||||||
int w = Utils.FONT_SMALL.getWidth(lines[i]);
|
int w = Utils.FONT_SMALL.getWidth(lines[i]);
|
||||||
|
@ -558,7 +596,7 @@ public class UI {
|
||||||
textWidth += maxWidth;
|
textWidth += maxWidth;
|
||||||
textHeight += lineHeight * (lines.length - 1);
|
textHeight += lineHeight * (lines.length - 1);
|
||||||
} else
|
} else
|
||||||
textWidth += Utils.FONT_SMALL.getWidth(text);
|
textWidth += Utils.FONT_SMALL.getWidth(tooltip);
|
||||||
|
|
||||||
// get drawing coordinates
|
// get drawing coordinates
|
||||||
int x = input.getMouseX() + offset, y = input.getMouseY() + offset;
|
int x = input.getMouseX() + offset, y = input.getMouseY() + offset;
|
||||||
|
@ -572,12 +610,30 @@ public class UI {
|
||||||
y = margin;
|
y = margin;
|
||||||
|
|
||||||
// draw tooltip text inside a filled rectangle
|
// draw tooltip text inside a filled rectangle
|
||||||
g.setColor(Color.black);
|
float alpha = (float) tooltipTimer / TOOLTIP_FADE_TIME;
|
||||||
|
float oldAlpha = Utils.COLOR_BLACK_ALPHA.a;
|
||||||
|
Utils.COLOR_BLACK_ALPHA.a = alpha;
|
||||||
|
g.setColor(Utils.COLOR_BLACK_ALPHA);
|
||||||
|
Utils.COLOR_BLACK_ALPHA.a = oldAlpha;
|
||||||
g.fillRect(x, y, textWidth, textHeight);
|
g.fillRect(x, y, textWidth, textHeight);
|
||||||
g.setColor(Color.darkGray);
|
oldAlpha = Utils.COLOR_DARK_GRAY.a;
|
||||||
|
Utils.COLOR_DARK_GRAY.a = alpha;
|
||||||
|
g.setColor(Utils.COLOR_DARK_GRAY);
|
||||||
g.setLineWidth(1);
|
g.setLineWidth(1);
|
||||||
g.drawRect(x, y, textWidth, textHeight);
|
g.drawRect(x, y, textWidth, textHeight);
|
||||||
Utils.FONT_SMALL.drawString(x + textMarginX, y, text, Color.white);
|
Utils.COLOR_DARK_GRAY.a = oldAlpha;
|
||||||
|
oldAlpha = Utils.COLOR_WHITE_ALPHA.a;
|
||||||
|
Utils.COLOR_WHITE_ALPHA.a = alpha;
|
||||||
|
Utils.FONT_SMALL.drawString(x + textMarginX, y, tooltip, Utils.COLOR_WHITE_ALPHA);
|
||||||
|
Utils.COLOR_WHITE_ALPHA.a = oldAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the tooltip.
|
||||||
|
*/
|
||||||
|
public static void resetTooltip() {
|
||||||
|
tooltipTimer = -1;
|
||||||
|
tooltip = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -84,7 +84,8 @@ public class Utils {
|
||||||
COLOR_LIGHT_ORANGE = new Color(255,192,128),
|
COLOR_LIGHT_ORANGE = new Color(255,192,128),
|
||||||
COLOR_LIGHT_GREEN = new Color(128,255,128),
|
COLOR_LIGHT_GREEN = new Color(128,255,128),
|
||||||
COLOR_LIGHT_BLUE = new Color(128,128,255),
|
COLOR_LIGHT_BLUE = new Color(128,128,255),
|
||||||
COLOR_GREEN_SEARCH = new Color(173, 255, 47);
|
COLOR_GREEN_SEARCH = new Color(173, 255, 47),
|
||||||
|
COLOR_DARK_GRAY = new Color(0.3f, 0.3f, 0.3f, 1f);
|
||||||
|
|
||||||
/** The default map colors, used when a map does not provide custom colors. */
|
/** The default map colors, used when a map does not provide custom colors. */
|
||||||
public static final Color[] DEFAULT_COMBO = {
|
public static final Color[] DEFAULT_COMBO = {
|
||||||
|
|
|
@ -173,27 +173,25 @@ public class ButtonMenu extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// buttons
|
// buttons
|
||||||
Input input = container.getInput();
|
for (GameMod mod : GameMod.values())
|
||||||
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
|
|
||||||
GameMod hoverMod = null;
|
|
||||||
for (GameMod mod : GameMod.values()) {
|
|
||||||
mod.draw();
|
mod.draw();
|
||||||
if (hoverMod == null && mod.contains(mouseX, mouseY))
|
|
||||||
hoverMod = mod;
|
|
||||||
}
|
|
||||||
|
|
||||||
super.draw(container, game, g);
|
super.draw(container, game, g);
|
||||||
|
|
||||||
// tooltips
|
|
||||||
if (hoverMod != null && hoverMod.isImplemented())
|
|
||||||
UI.drawTooltip(g, hoverMod.getDescription(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update(GameContainer container, int delta, int mouseX, int mouseY) {
|
public void update(GameContainer container, int delta, int mouseX, int mouseY) {
|
||||||
super.update(container, delta, mouseX, mouseY);
|
super.update(container, delta, mouseX, mouseY);
|
||||||
for (GameMod mod : GameMod.values())
|
GameMod hoverMod = null;
|
||||||
|
for (GameMod mod : GameMod.values()) {
|
||||||
mod.hoverUpdate(delta, mod.isActive());
|
mod.hoverUpdate(delta, mod.isActive());
|
||||||
|
if (hoverMod == null && mod.contains(mouseX, mouseY))
|
||||||
|
hoverMod = mod;
|
||||||
|
}
|
||||||
|
|
||||||
|
// tooltips
|
||||||
|
if (hoverMod != null && hoverMod.isImplemented())
|
||||||
|
UI.updateTooltip(delta, hoverMod.getDescription(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -248,7 +248,6 @@ public class MainMenu extends BasicGameState {
|
||||||
repoButton.draw();
|
repoButton.draw();
|
||||||
|
|
||||||
// draw update button
|
// draw update button
|
||||||
boolean showUpdateButton = Updater.get().showButton();
|
|
||||||
if (Updater.get().showButton()) {
|
if (Updater.get().showButton()) {
|
||||||
Color updateColor = null;
|
Color updateColor = null;
|
||||||
switch (Updater.get().getStatus()) {
|
switch (Updater.get().getStatus()) {
|
||||||
|
@ -294,18 +293,6 @@ public class MainMenu extends BasicGameState {
|
||||||
marginX, height - marginY - lineHeight);
|
marginX, height - marginY - lineHeight);
|
||||||
|
|
||||||
UI.draw(g);
|
UI.draw(g);
|
||||||
|
|
||||||
// tooltips
|
|
||||||
if (musicPositionBarContains(mouseX, mouseY))
|
|
||||||
UI.drawTooltip(g, "Click to seek to a specific point in the song.", false);
|
|
||||||
else if (musicPlay.contains(mouseX, mouseY))
|
|
||||||
UI.drawTooltip(g, (MusicController.isPlaying()) ? "Pause" : "Play", false);
|
|
||||||
else if (musicNext.contains(mouseX, mouseY))
|
|
||||||
UI.drawTooltip(g, "Next track", false);
|
|
||||||
else if (musicPrevious.contains(mouseX, mouseY))
|
|
||||||
UI.drawTooltip(g, "Previous track", false);
|
|
||||||
else if (showUpdateButton && updateButton.contains(mouseX, mouseY))
|
|
||||||
UI.drawTooltip(g, Updater.get().getStatus().getDescription(), true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -323,14 +310,13 @@ public class MainMenu extends BasicGameState {
|
||||||
updateButton.hoverUpdate(delta, mouseX, mouseY);
|
updateButton.hoverUpdate(delta, mouseX, mouseY);
|
||||||
downloadsButton.hoverUpdate(delta, mouseX, mouseY);
|
downloadsButton.hoverUpdate(delta, mouseX, mouseY);
|
||||||
// ensure only one button is in hover state at once
|
// ensure only one button is in hover state at once
|
||||||
if (musicPositionBarContains(mouseX, mouseY))
|
boolean noHoverUpdate = musicPositionBarContains(mouseX, mouseY);
|
||||||
mouseX = mouseY = -1;
|
boolean contains = musicPlay.contains(mouseX, mouseY);
|
||||||
musicPlay.hoverUpdate(delta, mouseX, mouseY);
|
musicPlay.hoverUpdate(delta, !noHoverUpdate && contains);
|
||||||
musicPause.hoverUpdate(delta, mouseX, mouseY);
|
musicPause.hoverUpdate(delta, !noHoverUpdate && contains);
|
||||||
if (musicPlay.contains(mouseX, mouseY))
|
noHoverUpdate |= contains;
|
||||||
mouseX = mouseY = -1;
|
musicNext.hoverUpdate(delta, !noHoverUpdate && musicNext.contains(mouseX, mouseY));
|
||||||
musicNext.hoverUpdate(delta, mouseX, mouseY);
|
musicPrevious.hoverUpdate(delta, !noHoverUpdate && musicPrevious.contains(mouseX, mouseY));
|
||||||
musicPrevious.hoverUpdate(delta, mouseX, mouseY);
|
|
||||||
|
|
||||||
// window focus change: increase/decrease theme song volume
|
// window focus change: increase/decrease theme song volume
|
||||||
if (MusicController.isThemePlaying() &&
|
if (MusicController.isThemePlaying() &&
|
||||||
|
@ -379,6 +365,18 @@ public class MainMenu extends BasicGameState {
|
||||||
logo.setX(container.getWidth() / 2);
|
logo.setX(container.getWidth() / 2);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tooltips
|
||||||
|
if (musicPositionBarContains(mouseX, mouseY))
|
||||||
|
UI.updateTooltip(delta, "Click to seek to a specific point in the song.", false);
|
||||||
|
else if (musicPlay.contains(mouseX, mouseY))
|
||||||
|
UI.updateTooltip(delta, (MusicController.isPlaying()) ? "Pause" : "Play", 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.get().showButton() && updateButton.contains(mouseX, mouseY))
|
||||||
|
UI.updateTooltip(delta, Updater.get().getStatus().getDescription(), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -353,17 +353,13 @@ public class SongMenu extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// score buttons
|
// score buttons
|
||||||
ScoreData hoverScore = null;
|
|
||||||
if (focusScores != null) {
|
if (focusScores != null) {
|
||||||
for (int i = 0; i < MAX_SCORE_BUTTONS; i++) {
|
for (int i = 0; i < MAX_SCORE_BUTTONS; i++) {
|
||||||
int rank = startScore + i;
|
int rank = startScore + i;
|
||||||
if (rank >= focusScores.length)
|
if (rank >= focusScores.length)
|
||||||
break;
|
break;
|
||||||
long prevScore = (rank + 1 < focusScores.length) ? focusScores[rank + 1].score : -1;
|
long prevScore = (rank + 1 < focusScores.length) ? focusScores[rank + 1].score : -1;
|
||||||
boolean contains = ScoreData.buttonContains(mouseX, mouseY, i);
|
focusScores[rank].draw(g, i, rank, prevScore, ScoreData.buttonContains(mouseX, mouseY, i));
|
||||||
focusScores[rank].draw(g, i, rank, prevScore, contains);
|
|
||||||
if (contains)
|
|
||||||
hoverScore = focusScores[rank];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// scroll bar
|
// scroll bar
|
||||||
|
@ -459,10 +455,6 @@ public class SongMenu extends BasicGameState {
|
||||||
UI.getBackButton().draw();
|
UI.getBackButton().draw();
|
||||||
|
|
||||||
UI.draw(g);
|
UI.draw(g);
|
||||||
|
|
||||||
// tooltips
|
|
||||||
if (hoverScore != null)
|
|
||||||
hoverScore.drawTooltip(g);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -575,6 +567,20 @@ public class SongMenu extends BasicGameState {
|
||||||
if (!isHover) {
|
if (!isHover) {
|
||||||
hoverOffset = 0f;
|
hoverOffset = 0f;
|
||||||
hoverIndex = -1;
|
hoverIndex = -1;
|
||||||
|
} else
|
||||||
|
return;
|
||||||
|
|
||||||
|
// tooltips
|
||||||
|
if (focusScores != null) {
|
||||||
|
for (int i = 0; i < MAX_SCORE_BUTTONS; i++) {
|
||||||
|
int rank = startScore + i;
|
||||||
|
if (rank >= focusScores.length)
|
||||||
|
break;
|
||||||
|
if (ScoreData.buttonContains(mouseX, mouseY, i)) {
|
||||||
|
UI.updateTooltip(delta, focusScores[rank].getTooltipString(), true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user