opsu-dance/src/itdelatrisu/opsu/beatmap/BeatmapSetNode.java
Jeffrey Han cd3d53336d A couple of API improvements.
Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
2015-09-03 22:16:52 -05:00

183 lines
6.0 KiB
Java

/*
* opsu! - an open-source osu! client
* Copyright (C) 2014, 2015 Jeffrey Han
*
* opsu! is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* opsu! is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with opsu!. If not, see <http://www.gnu.org/licenses/>.
*/
package itdelatrisu.opsu.beatmap;
import itdelatrisu.opsu.GameData.Grade;
import itdelatrisu.opsu.GameImage;
import itdelatrisu.opsu.Options;
import itdelatrisu.opsu.ui.Colors;
import itdelatrisu.opsu.ui.Fonts;
import org.newdawn.slick.Color;
import org.newdawn.slick.Image;
/**
* Node in an BeatmapSetList representing a beatmap set.
*/
public class BeatmapSetNode {
/** The associated beatmap set. */
private final BeatmapSet beatmapSet;
/** Index of the selected beatmap (-1 if not focused). */
public int beatmapIndex = -1;
/** Index of this node. */
public int index = 0;
/** Links to other nodes. */
public BeatmapSetNode prev, next;
/**
* Constructor.
* @param beatmapSet the beatmap set
*/
public BeatmapSetNode(BeatmapSet beatmapSet) {
this.beatmapSet = beatmapSet;
}
/**
* Returns the associated beatmap set.
* @return the beatmap set
*/
public BeatmapSet getBeatmapSet() { return beatmapSet; }
/**
* Returns the selected beatmap (based on {@link #beatmapIndex}).
* @return the beatmap, or null if the index is invalid
*/
public Beatmap getSelectedBeatmap() {
return (beatmapIndex < 0 || beatmapIndex >= beatmapSet.size()) ? null : beatmapSet.get(beatmapIndex);
}
/**
* Draws the button.
* @param x the x coordinate
* @param y the y coordinate
* @param grade the highest grade, if any
* @param focus true if this is the focused node
*/
public void draw(float x, float y, Grade grade, boolean focus) {
Image bg = GameImage.MENU_BUTTON_BG.getImage();
boolean expanded = (beatmapIndex > -1);
Beatmap beatmap;
bg.setAlpha(0.9f);
Color bgColor;
Color textColor = Options.getSkin().getSongSelectInactiveTextColor();
// get drawing parameters
if (expanded) {
x -= bg.getWidth() / 10f;
if (focus) {
bgColor = Color.white;
textColor = Options.getSkin().getSongSelectActiveTextColor();
} else
bgColor = Colors.BLUE_BUTTON;
beatmap = beatmapSet.get(beatmapIndex);
} else {
bgColor = Colors.ORANGE_BUTTON;
beatmap = beatmapSet.get(0);
}
bg.draw(x, y, bgColor);
float cx = x + (bg.getWidth() * 0.043f);
float cy = y + (bg.getHeight() * 0.18f) - 3;
// draw grade
if (grade != Grade.NULL) {
Image gradeImg = grade.getMenuImage();
gradeImg.drawCentered(cx - bg.getWidth() * 0.01f + gradeImg.getWidth() / 2f, y + bg.getHeight() / 2.2f);
cx += gradeImg.getWidth();
}
// draw text
if (Options.useUnicodeMetadata()) { // load glyphs
Fonts.loadGlyphs(Fonts.MEDIUM, beatmap.titleUnicode);
Fonts.loadGlyphs(Fonts.DEFAULT, beatmap.artistUnicode);
}
Fonts.MEDIUM.drawString(cx, cy, beatmap.getTitle(), textColor);
Fonts.DEFAULT.drawString(cx, cy + Fonts.MEDIUM.getLineHeight() - 3,
String.format("%s // %s", beatmap.getArtist(), beatmap.creator), textColor);
if (expanded || beatmapSet.size() == 1)
Fonts.BOLD.drawString(cx, cy + Fonts.MEDIUM.getLineHeight() + Fonts.DEFAULT.getLineHeight() - 6,
beatmap.version, textColor);
// draw stars
// (note: in osu!, stars are also drawn for beatmap sets of size 1)
if (expanded) {
if (beatmap.starRating >= 0) {
Image star = GameImage.STAR.getImage();
float starOffset = star.getWidth() * 1.7f;
float starX = cx + starOffset * 0.04f;
float starY = cy + Fonts.MEDIUM.getLineHeight() + Fonts.DEFAULT.getLineHeight() * 2 - 8f * GameImage.getUIscale();
float starCenterY = starY + star.getHeight() / 2f;
final float baseAlpha = focus ? 1f : 0.8f;
final float smallStarScale = 0.4f;
star.setAlpha(baseAlpha);
int i = 1;
for (; i < beatmap.starRating && i <= 5; i++) {
if (focus)
star.drawFlash(starX + (i - 1) * starOffset, starY, star.getWidth(), star.getHeight(), textColor);
else
star.draw(starX + (i - 1) * starOffset, starY);
}
if (i <= 5) {
float partialStarScale = smallStarScale + (float) (beatmap.starRating - i + 1) * (1f - smallStarScale);
Image partialStar = star.getScaledCopy(partialStarScale);
partialStar.setAlpha(baseAlpha);
float partialStarY = starCenterY - partialStar.getHeight() / 2f;
if (focus)
partialStar.drawFlash(starX + (i - 1) * starOffset, partialStarY, partialStar.getWidth(), partialStar.getHeight(), textColor);
else
partialStar.draw(starX + (i - 1) * starOffset, partialStarY);
}
if (++i <= 5) {
Image smallStar = star.getScaledCopy(smallStarScale);
smallStar.setAlpha(0.5f);
float smallStarY = starCenterY - smallStar.getHeight() / 2f;
for (; i <= 5; i++) {
if (focus)
smallStar.drawFlash(starX + (i - 1) * starOffset, smallStarY, smallStar.getWidth(), smallStar.getHeight(), textColor);
else
smallStar.draw(starX + (i - 1) * starOffset, smallStarY);
}
}
}
}
}
/**
* Returns an array of strings containing beatmap information for the
* selected beatmap, or null if none selected.
* @see BeatmapSet#getInfo(int)
*/
public String[] getInfo() { return (beatmapIndex < 0) ? null : beatmapSet.getInfo(beatmapIndex); }
/**
* Returns a formatted string for the beatmap at {@code beatmapIndex}:
* "Artist - Title [Version]" (version omitted if {@code beatmapIndex} is invalid)
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
if (beatmapIndex == -1)
return beatmapSet.toString();
else
return beatmapSet.get(beatmapIndex).toString();
}
}