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. */
private String timeString;
/** A formatted string of the mods. */
private String modString;
/** The tooltip string. */
private String tooltip;
/** Drawing values. */
private static float baseX, baseY, buttonWidth, buttonHeight, buttonOffset;
@ -215,15 +215,6 @@ public class ScoreData implements Comparable<ScoreData> {
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.
* @param g the graphics context
@ -318,15 +309,14 @@ public class ScoreData implements Comparable<ScoreData> {
}
/**
* Draws the a tooltip containing the score information.
* @param g the graphics context
* Returns the tooltip string for this score.
*/
public void drawTooltip(Graphics g) {
String text = String.format(
"Achieved on %s\n300:%d 100:%d 50:%d Miss:%d\nAccuracy: %.2f%%\nMods: %s",
getTimeString(), hit300, hit100, hit50, miss,
getScorePercent(), getModString());
UI.drawTooltip(g, text, true);
public String getTooltipString() {
if (tooltip == null)
tooltip = String.format(
"Achieved on %s\n300:%d 100:%d 50:%d Miss:%d\nAccuracy: %.2f%%\nMods: %s",
getTimeString(), hit300, hit100, hit50, miss, getScorePercent(), GameMod.getModString(mods));
return tooltip;
}
@Override
@ -335,7 +325,7 @@ public class ScoreData implements Comparable<ScoreData> {
"%s | ID: (%d, %d) | %s - %s [%s] (by %s) | " +
"Hits: (%d, %d, %d, %d, %d, %d) | Score: %d (%d combo%s) | Mods: %s",
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. */
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
private static GameContainer container;
private static StateBasedGame game;
@ -124,6 +136,8 @@ public class UI {
updateCursor(delta);
updateVolumeDisplay(delta);
updateBarNotification(delta);
if (tooltipTimer > 0)
tooltipTimer -= delta;
}
/**
@ -135,6 +149,7 @@ public class UI {
drawVolume(g);
drawFPS();
drawCursor();
drawTooltip(g);
}
/**
@ -149,6 +164,7 @@ public class UI {
drawVolume(g);
drawFPS();
drawCursor(mouseX, mouseY, mousePressed);
drawTooltip(g);
}
/**
@ -157,6 +173,7 @@ public class UI {
public static void enter() {
backButton.resetHover();
resetBarNotification();
resetTooltip();
}
/**
@ -535,20 +552,41 @@ public class UI {
}
/**
* Draws a tooltip near the current mouse coordinates, bounded by the
* container dimensions.
* @param g the graphics context
* @param text the tooltip text
* Sets or updates a tooltip for drawing.
* Must be called with {@link #drawTooltip(Graphics)}.
* @param delta the delta interval since the last call
* @param s the tooltip text
* @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 margin = containerWidth / 100, textMarginX = 2;
int offset = GameImage.CURSOR_MIDDLE.getImage().getWidth() / 2;
int lineHeight = Utils.FONT_SMALL.getLineHeight();
int textWidth = textMarginX * 2, textHeight = lineHeight;
if (newlines) {
String[] lines = text.split("\\n");
if (tooltipNewlines) {
String[] lines = tooltip.split("\\n");
int maxWidth = Utils.FONT_SMALL.getWidth(lines[0]);
for (int i = 1; i < lines.length; i++) {
int w = Utils.FONT_SMALL.getWidth(lines[i]);
@ -558,7 +596,7 @@ public class UI {
textWidth += maxWidth;
textHeight += lineHeight * (lines.length - 1);
} else
textWidth += Utils.FONT_SMALL.getWidth(text);
textWidth += Utils.FONT_SMALL.getWidth(tooltip);
// get drawing coordinates
int x = input.getMouseX() + offset, y = input.getMouseY() + offset;
@ -572,12 +610,30 @@ public class UI {
y = margin;
// 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.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.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_GREEN = new Color(128,255,128),
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. */
public static final Color[] DEFAULT_COMBO = {

View File

@ -173,27 +173,25 @@ public class ButtonMenu extends BasicGameState {
}
// buttons
Input input = container.getInput();
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
GameMod hoverMod = null;
for (GameMod mod : GameMod.values()) {
for (GameMod mod : GameMod.values())
mod.draw();
if (hoverMod == null && mod.contains(mouseX, mouseY))
hoverMod = mod;
}
super.draw(container, game, g);
// tooltips
if (hoverMod != null && hoverMod.isImplemented())
UI.drawTooltip(g, hoverMod.getDescription(), true);
}
@Override
public void update(GameContainer container, int delta, int mouseX, int 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());
if (hoverMod == null && mod.contains(mouseX, mouseY))
hoverMod = mod;
}
// tooltips
if (hoverMod != null && hoverMod.isImplemented())
UI.updateTooltip(delta, hoverMod.getDescription(), true);
}
@Override

View File

@ -248,7 +248,6 @@ public class MainMenu extends BasicGameState {
repoButton.draw();
// draw update button
boolean showUpdateButton = Updater.get().showButton();
if (Updater.get().showButton()) {
Color updateColor = null;
switch (Updater.get().getStatus()) {
@ -294,18 +293,6 @@ public class MainMenu extends BasicGameState {
marginX, height - marginY - lineHeight);
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
@ -323,14 +310,13 @@ public class MainMenu extends BasicGameState {
updateButton.hoverUpdate(delta, mouseX, mouseY);
downloadsButton.hoverUpdate(delta, mouseX, mouseY);
// ensure only one button is in hover state at once
if (musicPositionBarContains(mouseX, mouseY))
mouseX = mouseY = -1;
musicPlay.hoverUpdate(delta, mouseX, mouseY);
musicPause.hoverUpdate(delta, mouseX, mouseY);
if (musicPlay.contains(mouseX, mouseY))
mouseX = mouseY = -1;
musicNext.hoverUpdate(delta, mouseX, mouseY);
musicPrevious.hoverUpdate(delta, mouseX, mouseY);
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));
// window focus change: increase/decrease theme song volume
if (MusicController.isThemePlaying() &&
@ -379,6 +365,18 @@ public class MainMenu extends BasicGameState {
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

View File

@ -353,17 +353,13 @@ public class SongMenu extends BasicGameState {
}
// score buttons
ScoreData hoverScore = null;
if (focusScores != null) {
for (int i = 0; i < MAX_SCORE_BUTTONS; i++) {
int rank = startScore + i;
if (rank >= focusScores.length)
break;
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, contains);
if (contains)
hoverScore = focusScores[rank];
focusScores[rank].draw(g, i, rank, prevScore, ScoreData.buttonContains(mouseX, mouseY, i));
}
// scroll bar
@ -459,10 +455,6 @@ public class SongMenu extends BasicGameState {
UI.getBackButton().draw();
UI.draw(g);
// tooltips
if (hoverScore != null)
hoverScore.drawTooltip(g);
}
@Override
@ -575,6 +567,20 @@ public class SongMenu extends BasicGameState {
if (!isHover) {
hoverOffset = 0f;
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;
}
}
}
}