Display time since achieving recent scores.

- Added history icon by Google: https://www.iconfinder.com/icons/326655/
- Draw history icon and elapsed time next to score buttons if they were achieved within 24 hours.  Conforming to osu! behavior, the elapsed time is not updated in real-time.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
Jeffrey Han 2015-01-29 03:05:09 -05:00
parent 0165abde56
commit f0858f657b
4 changed files with 55 additions and 8 deletions

BIN
res/history.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View File

@ -465,6 +465,12 @@ public enum GameImage {
return img.getScaledCopy((h * 0.15f) / img.getHeight()); return img.getScaledCopy((h * 0.15f) / img.getHeight());
} }
}, },
HISTORY ("history", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.0278f) / img.getHeight());
}
},
REPOSITORY ("repo", "png", false, false) { REPOSITORY ("repo", "png", false, false) {
@Override @Override
protected Image process_sub(Image img, int w, int h) { protected Image process_sub(Image img, int w, int h) {

View File

@ -59,6 +59,9 @@ public class ScoreData implements Comparable<ScoreData> {
/** Game mod bitmask. */ /** Game mod bitmask. */
public int mods; public int mods;
/** Time since the score was achieved. */
private String timeSince;
/** The grade. */ /** The grade. */
private Grade grade; private Grade grade;
@ -191,6 +194,26 @@ public class ScoreData implements Comparable<ScoreData> {
return grade; return grade;
} }
/**
* Returns the time since achieving the score, or null if over 24 hours.
* This value will not change after the first call.
* @return a string: {number}{s|m|h}
*/
public String getTimeSince() {
if (timeSince == null) {
long seconds = (System.currentTimeMillis() / 1000L) - timestamp;
if (seconds < 60)
timeSince = String.format("%ds", seconds);
else if (seconds < 3600)
timeSince = String.format("%dm", seconds / 60L);
else if (seconds < 86400)
timeSince = String.format("%dh", seconds / 3600L);
else
timeSince = "";
}
return (timeSince.isEmpty()) ? null : timeSince;
}
/** /**
* 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
@ -201,8 +224,10 @@ public class ScoreData implements Comparable<ScoreData> {
*/ */
public void draw(Graphics g, int index, int rank, long prevScore, boolean focus) { public void draw(Graphics g, int index, int rank, long prevScore, boolean focus) {
Image img = getGrade().getMenuImage(); Image img = getGrade().getMenuImage();
float textX = baseX + buttonWidth * 0.24f;
float edgeX = baseX + buttonWidth * 0.98f;
float y = baseY + index * (buttonOffset); float y = baseY + index * (buttonOffset);
float textX = baseX + buttonWidth * 0.24f, edgeX = baseX + buttonWidth * 0.98f; float midY = y + buttonHeight / 2f;
float marginY = Utils.FONT_DEFAULT.getLineHeight() * 0.01f; float marginY = Utils.FONT_DEFAULT.getLineHeight() * 0.01f;
// rectangle outline // rectangle outline
@ -219,7 +244,7 @@ public class ScoreData implements Comparable<ScoreData> {
} }
// grade image // grade image
img.drawCentered(baseX + buttonWidth * 0.15f, y + buttonHeight / 2f); img.drawCentered(baseX + buttonWidth * 0.15f, midY);
// score // score
float textOffset = (buttonHeight - Utils.FONT_MEDIUM.getLineHeight() - Utils.FONT_SMALL.getLineHeight()) / 2f; float textOffset = (buttonHeight - Utils.FONT_MEDIUM.getLineHeight() - Utils.FONT_SMALL.getLineHeight()) / 2f;
@ -269,6 +294,17 @@ public class ScoreData implements Comparable<ScoreData> {
y + marginY + Utils.FONT_DEFAULT.getLineHeight() * 2, y + marginY + Utils.FONT_DEFAULT.getLineHeight() * 2,
diff, Color.white diff, Color.white
); );
// time since
if (getTimeSince() != null) {
Image clock = GameImage.HISTORY.getImage();
clock.drawCentered(baseX + buttonWidth * 1.02f + clock.getWidth() / 2f, midY);
Utils.FONT_DEFAULT.drawString(
baseX + buttonWidth * 1.03f + clock.getWidth(),
midY - Utils.FONT_DEFAULT.getLineHeight() / 2f,
getTimeSince(), Color.white
);
}
} }
@Override @Override

View File

@ -280,7 +280,7 @@ public class SongMenu extends BasicGameState {
for (int i = 0; i < MAX_SONG_BUTTONS && node != null; i++, node = node.next) { for (int i = 0; i < MAX_SONG_BUTTONS && node != null; i++, node = node.next) {
// draw the node // draw the node
float offset = (i == hoverIndex) ? hoverOffset : 0f; float offset = (i == hoverIndex) ? hoverOffset : 0f;
ScoreData[] scores = getScoreDataForNode(node); ScoreData[] scores = getScoreDataForNode(node, false);
node.draw( node.draw(
buttonX - offset, buttonY + (i*buttonOffset), buttonX - offset, buttonY + (i*buttonOffset),
(scores == null) ? Grade.NULL : scores[0].getGrade(), (scores == null) ? Grade.NULL : scores[0].getGrade(),
@ -797,7 +797,7 @@ public class SongMenu extends BasicGameState {
// reload scores // reload scores
if (focusNode != null) { if (focusNode != null) {
scoreMap = ScoreDB.getMapSetScores(focusNode.osuFiles.get(focusNode.osuFileIndex)); scoreMap = ScoreDB.getMapSetScores(focusNode.osuFiles.get(focusNode.osuFileIndex));
focusScores = getScoreDataForNode(focusNode); focusScores = getScoreDataForNode(focusNode, true);
} }
resetGame = false; resetGame = false;
@ -892,7 +892,7 @@ public class SongMenu extends BasicGameState {
// load scores // load scores
scoreMap = ScoreDB.getMapSetScores(osu); scoreMap = ScoreDB.getMapSetScores(osu);
focusScores = getScoreDataForNode(focusNode); focusScores = getScoreDataForNode(focusNode, true);
startScore = 0; startScore = 0;
// check startNode bounds // check startNode bounds
@ -936,9 +936,10 @@ public class SongMenu extends BasicGameState {
* Returns all the score data for an OsuGroupNode from scoreMap. * Returns all the score data for an OsuGroupNode from scoreMap.
* If no score data is available for the node, return null. * If no score data is available for the node, return null.
* @param node the OsuGroupNode * @param node the OsuGroupNode
* @param setTimeSince whether or not to set the "time since" field for the scores
* @return the ScoreData array * @return the ScoreData array
*/ */
private ScoreData[] getScoreDataForNode(OsuGroupNode node) { private ScoreData[] getScoreDataForNode(OsuGroupNode node, boolean setTimeSince) {
if (scoreMap == null || scoreMap.isEmpty() || node.osuFileIndex == -1) // node not expanded if (scoreMap == null || scoreMap.isEmpty() || node.osuFileIndex == -1) // node not expanded
return null; return null;
@ -950,9 +951,13 @@ public class SongMenu extends BasicGameState {
ScoreData s = scores[0]; ScoreData s = scores[0];
if (osu.beatmapID == s.MID && osu.beatmapSetID == s.MSID && if (osu.beatmapID == s.MID && osu.beatmapSetID == s.MSID &&
osu.title.equals(s.title) && osu.artist.equals(s.artist) && osu.title.equals(s.title) && osu.artist.equals(s.artist) &&
osu.creator.equals(s.creator)) osu.creator.equals(s.creator)) {
if (setTimeSince) {
for (int i = 0; i < scores.length; i++)
scores[i].getTimeSince();
}
return scores; return scores;
else } else
return null; // incorrect map return null; // incorrect map
} }