Added fade effects for tooltips.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2015-03-13 02:52:18 -04:00
parent a66133c605
commit a7390f7c1d
6 changed files with 123 additions and 74 deletions

View File

@ -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)
); );
} }

View File

@ -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;
} }
/** /**

View File

@ -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 = {

View File

@ -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

View File

@ -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

View File

@ -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;
}
}
} }
} }