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. */
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 = {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user