opsu-dance/src/itdelatrisu/opsu/GameImage.java
Jeffrey Han 66016160a4 Song menu graphical updates.
- Added "selection-*" images from Xiaounlimited's "Nexus Ivory" skin.  These do the same thing as the F1-F3 keyboard buttons in the song menu.
- Removed the old wrench icon and replaced it with an "Other Options" button. F1 no longer opens the options menu.
- Moved the search bar to under the tabs and better simulate osu! behavior.  Removed the old search icon.
- Added solid black bars at the top and bottom of the song menu.  Moved the top divider closer to the end of the information text.  Cropped song button images to fit between the bars.

Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
2015-02-15 21:38:54 -05:00

920 lines
26 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;
import itdelatrisu.opsu.states.SongMenu;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
/**
* Game images.
*/
public enum GameImage {
// Cursor
CURSOR ("cursor", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(1 + ((h - 600) / 1000f));
}
},
CURSOR_MIDDLE ("cursormiddle", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(1 + ((h - 600) / 1000f));
}
},
CURSOR_TRAIL ("cursortrail", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(1 + ((h - 600) / 1000f));
}
},
CURSOR_OLD ("cursor2", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(1 + ((h - 600) / 1000f));
}
},
CURSOR_TRAIL_OLD ("cursortrail2", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(1 + ((h - 600) / 1000f));
}
},
// Game
SECTION_PASS ("section-pass", "png"),
SECTION_FAIL ("section-fail", "png"),
WARNINGARROW ("play-warningarrow", "png"),
SKIP ("play-skip", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.1f) / img.getHeight());
}
},
COUNTDOWN_READY ("ready", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 3f) / img.getHeight());
}
},
COUNTDOWN_3 ("count3", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 3f) / img.getHeight());
}
},
COUNTDOWN_2 ("count2", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 3f) / img.getHeight());
}
},
COUNTDOWN_1 ("count1", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 3f) / img.getHeight());
}
},
COUNTDOWN_GO ("go", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 3f) / img.getHeight());
}
},
HITCIRCLE_SELECT ("hitcircleselect", "png"),
UNRANKED ("play-unranked", "png"),
PLAYFIELD ("playfield", "png|jpg", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
img.setAlpha(0.7f);
return img.getScaledCopy(w, h);
}
},
// Game Pause/Fail
PAUSE_CONTINUE ("pause-continue", "png"),
PAUSE_RETRY ("pause-retry", "png"),
PAUSE_BACK ("pause-back", "png"),
PAUSE_OVERLAY ("pause-overlay", "png|jpg") {
@Override
protected Image process_sub(Image img, int w, int h) {
img.setAlpha(0.7f);
return img.getScaledCopy(w, h);
}
},
FAIL_BACKGROUND ("fail-background", "png|jpg") {
@Override
protected Image process_sub(Image img, int w, int h) {
img.setAlpha(0.7f);
return img.getScaledCopy(w, h);
}
},
// Circle
HITCIRCLE ("hitcircle", "png"),
HITCIRCLE_OVERLAY ("hitcircleoverlay", "png"),
APPROACHCIRCLE ("approachcircle", "png"),
// Slider
SLIDER_BALL ("sliderb", "sliderb%d", "png"),
SLIDER_FOLLOWCIRCLE ("sliderfollowcircle", "png"),
REVERSEARROW ("reversearrow", "png"),
SLIDER_TICK ("sliderscorepoint", "png"),
// Spinner
SPINNER_CIRCLE ("spinner-circle", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(h * 9 / 10, h * 9 / 10);
}
},
SPINNER_APPROACHCIRCLE ("spinner-approachcircle", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(h * 9 / 10, h * 9 / 10);
}
},
SPINNER_METRE ("spinner-metre", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(w, h);
}
},
SPINNER_SPIN ("spinner-spin", "png"),
SPINNER_CLEAR ("spinner-clear", "png"),
SPINNER_OSU ("spinner-osu", "png"),
// Score Data
COMBO_BURST ("comboburst", "comboburst-%d", "png"),
SCOREBAR_BG ("scorebar-bg", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((w * 0.565f) / img.getWidth());
}
},
SCOREBAR_COLOUR ("scorebar-colour", "scorebar-colour-%d", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((w * 0.521f) / img.getWidth());
}
},
SCOREBAR_KI ("scorebar-ki", "png"),
SCOREBAR_KI_DANGER ("scorebar-kidanger", "png"),
SCOREBAR_KI_DANGER2 ("scorebar-kidanger2", "png"),
HIT_MISS ("hit0", "png"),
HIT_50 ("hit50", "png"),
HIT_100 ("hit100", "png"),
HIT_300 ("hit300", "png"),
HIT_100K ("hit100k", "png"),
HIT_300K ("hit300k", "png"),
HIT_300G ("hit300g", "png"),
HIT_SLIDER10 ("sliderpoint10", "png"),
HIT_SLIDER30 ("sliderpoint30", "png"),
RANKING_SS ("ranking-X", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 2f) / img.getHeight());
}
},
RANKING_SS_SMALL ("ranking-X-small", "png"),
RANKING_SSH ("ranking-XH", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 2f) / img.getHeight());
}
},
RANKING_SSH_SMALL ("ranking-XH-small", "png"),
RANKING_S ("ranking-S", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 2f) / img.getHeight());
}
},
RANKING_S_SMALL ("ranking-S-small", "png"),
RANKING_SH ("ranking-SH", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 2f) / img.getHeight());
}
},
RANKING_SH_SMALL ("ranking-SH-small", "png"),
RANKING_A ("ranking-A", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 2f) / img.getHeight());
}
},
RANKING_A_SMALL ("ranking-A-small", "png"),
RANKING_B ("ranking-B", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 2f) / img.getHeight());
}
},
RANKING_B_SMALL ("ranking-B-small", "png"),
RANKING_C ("ranking-C", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 2f) / img.getHeight());
}
},
RANKING_C_SMALL ("ranking-C-small", "png"),
RANKING_D ("ranking-D", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 2f) / img.getHeight());
}
},
RANKING_D_SMALL ("ranking-D-small", "png"),
RANKING_PANEL ("ranking-panel", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.63f) / img.getHeight());
}
},
RANKING_PERFECT ("ranking-perfect", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.16f) / img.getHeight());
}
},
RANKING_TITLE ("ranking-title", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.15f) / img.getHeight());
}
},
RANKING_MAXCOMBO ("ranking-maxcombo", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.05f) / img.getHeight());
}
},
RANKING_ACCURACY ("ranking-accuracy", "png") {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.05f) / img.getHeight());
}
},
DEFAULT_0 ("default-0", "png"),
DEFAULT_1 ("default-1", "png"),
DEFAULT_2 ("default-2", "png"),
DEFAULT_3 ("default-3", "png"),
DEFAULT_4 ("default-4", "png"),
DEFAULT_5 ("default-5", "png"),
DEFAULT_6 ("default-6", "png"),
DEFAULT_7 ("default-7", "png"),
DEFAULT_8 ("default-8", "png"),
DEFAULT_9 ("default-9", "png"),
SCORE_0 ("score-0", "png"),
SCORE_1 ("score-1", "png"),
SCORE_2 ("score-2", "png"),
SCORE_3 ("score-3", "png"),
SCORE_4 ("score-4", "png"),
SCORE_5 ("score-5", "png"),
SCORE_6 ("score-6", "png"),
SCORE_7 ("score-7", "png"),
SCORE_8 ("score-8", "png"),
SCORE_9 ("score-9", "png"),
SCORE_COMMA ("score-comma", "png"),
SCORE_DOT ("score-dot", "png"),
SCORE_PERCENT ("score-percent", "png"),
SCORE_X ("score-x", "png"),
LIGHTING ("lighting", "png"),
LIGHTING1 ("lighting1", "png"),
// Game Mods
MOD_EASY ("selection-mod-easy", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.12f) / img.getHeight());
}
},
MOD_NO_FAIL ("selection-mod-nofail", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.12f) / img.getHeight());
}
},
MOD_HARD_ROCK ("selection-mod-hardrock", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.12f) / img.getHeight());
}
},
MOD_SUDDEN_DEATH ("selection-mod-suddendeath", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.12f) / img.getHeight());
}
},
MOD_SPUN_OUT ("selection-mod-spunout", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.12f) / img.getHeight());
}
},
MOD_AUTO ("selection-mod-autoplay", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.12f) / img.getHeight());
}
},
MOD_HALF_TIME ("selection-mod-halftime", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.12f) / img.getHeight());
}
},
MOD_DOUBLE_TIME ("selection-mod-doubletime", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.12f) / img.getHeight());
}
},
MOD_HIDDEN ("selection-mod-hidden", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.12f) / img.getHeight());
}
},
MOD_FLASHLIGHT ("selection-mod-flashlight", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.12f) / img.getHeight());
}
},
// Non-Game Components
SELECTION_MODS ("selection-mods", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.115f) / img.getHeight());
}
},
SELECTION_MODS_OVERLAY ("selection-mods-over", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.115f) / img.getHeight());
}
},
SELECTION_RANDOM ("selection-random", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.115f) / img.getHeight());
}
},
SELECTION_RANDOM_OVERLAY ("selection-random-over", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.115f) / img.getHeight());
}
},
SELECTION_OPTIONS ("selection-options", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.115f) / img.getHeight());
}
},
SELECTION_OPTIONS_OVERLAY ("selection-options-over", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.115f) / img.getHeight());
}
},
SELECTION_OTHER_OPTIONS ("selection-selectoptions", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.115f) / img.getHeight());
}
},
SELECTION_OTHER_OPTIONS_OVERLAY ("selection-selectoptions-over", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.115f) / img.getHeight());
}
},
VOLUME ("volume-bg", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.3f) / img.getHeight());
}
},
MENU_BACK ("menu-back", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.1f) / img.getHeight());
}
},
MENU_BUTTON_BG ("menu-button-background", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
// TODO: scale these properly (messy due to non-cropped images)
return img.getScaledCopy(w / 2, (int) (h * 0.95f) / SongMenu.MAX_SONG_BUTTONS);
}
},
MENU_TAB ("selection-tab", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.033f) / img.getHeight());
}
},
MENU_MUSICNOTE ("music-note", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
int r = (int) (Utils.FONT_LARGE.getLineHeight() * 0.75f + Utils.FONT_DEFAULT.getLineHeight());
return img.getScaledCopy(r, r);
}
},
MENU_LOADER ("loader", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
int r = (int) (Utils.FONT_LARGE.getLineHeight() * 0.75f + Utils.FONT_DEFAULT.getLineHeight());
return img.getScaledCopy(r / 48f);
}
},
MENU_BG ("menu-background", "png|jpg", false, true) {
@Override
protected Image process_sub(Image img, int w, int h) {
img.setAlpha(0.9f);
return img.getScaledCopy(w, h);
}
},
MENU_LOGO ("logo", "png", false, true) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 1.2f) / img.getHeight());
}
},
MENU_PlAY ("menu-play", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(MENU_LOGO.getImage().getWidth() * 0.83f / img.getWidth());
}
},
MENU_EXIT ("menu-exit", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy(MENU_LOGO.getImage().getWidth() * 0.66f / img.getWidth());
}
},
MENU_BUTTON_MID ("button-middle", "png", false, false),
MENU_BUTTON_LEFT ("button-left", "png", false, false),
MENU_BUTTON_RIGHT ("button-right", "png", false, false),
MUSIC_PLAY ("music-play", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 18f) / img.getHeight());
}
},
MUSIC_PAUSE ("music-pause", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 18f) / img.getHeight());
}
},
MUSIC_NEXT ("music-next", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 18f) / img.getHeight());
}
},
MUSIC_PREVIOUS ("music-previous", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 18f) / img.getHeight());
}
},
RANKING_RETRY ("ranking-retry", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.15f) / img.getHeight());
}
},
RANKING_EXIT ("ranking-back", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.15f) / img.getHeight());
}
},
DOWNLOADS ("downloads", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h * 0.45f) / img.getHeight());
}
},
SEARCH_BG ("search-background", "png|jpg", false, true) {
@Override
protected Image process_sub(Image img, int w, int h) {
img.setAlpha(0.8f);
return img.getScaledCopy(w, h);
}
},
DELETE ("delete", "png", false, false) {
@Override
protected Image process_sub(Image img, int w, int h) {
int lineHeight = Utils.FONT_DEFAULT.getLineHeight();
return img.getScaledCopy(lineHeight, lineHeight);
}
},
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) {
@Override
protected Image process_sub(Image img, int w, int h) {
return img.getScaledCopy((h / 17f) / img.getHeight());
}
};
/** Image file types. */
private static final byte
IMG_PNG = 1,
IMG_JPG = 2;
/** The file name. */
private String filename;
/** The formatted file name string (for loading multiple images). */
private String filenameFormat;
/** Image file type. */
private byte type;
/**
* Whether or not the image is skinnable by a beatmap.
* These images are typically related to gameplay.
*/
private boolean skinnable;
/** Whether or not to preload the image when the program starts. */
private boolean preload;
/** The default image. */
private Image defaultImage;
/** The default image array. */
private Image[] defaultImages;
/** The beatmap skin image (optional, temporary). */
private Image skinImage;
/** The beatmap skin image array (optional, temporary). */
private Image[] skinImages;
/** Container dimensions. */
private static int containerWidth, containerHeight;
/**
* Initializes the GameImage class with container dimensions.
* @param width the container width
* @param height the container height
*/
public static void init(int width, int height) {
containerWidth = width;
containerHeight = height;
}
/**
* Clears all image references.
* This does NOT destroy images, so be careful of memory leaks!
*/
public static void clearReferences() {
for (GameImage img : GameImage.values()) {
img.defaultImage = img.skinImage = null;
img.defaultImages = img.skinImages = null;
}
}
/**
* Returns the bitmask image type from a type string.
* @param type the type string
* @return the byte bitmask
*/
private static byte getType(String type) {
byte b = 0;
String[] s = type.split("\\|");
for (int i = 0; i < s.length; i++) {
if (s[i].equals("png"))
b |= IMG_PNG;
else if (s[i].equals("jpg"))
b |= IMG_JPG;
}
return b;
}
/**
* Returns a list of possible filenames (with extensions).
* @return filename list
*/
private static List<String> getFileNames(String filename, byte type) {
List<String> list = new ArrayList<String>(2);
if ((type & IMG_PNG) != 0)
list.add(String.format("%s.png", filename));
if ((type & IMG_JPG) != 0)
list.add(String.format("%s.jpg", filename));
return list;
}
/**
* Constructor for game-related images (skinnable and preloaded).
* @param filename the image file name
* @param type the file types (separated by '|')
*/
GameImage(String filename, String type) {
this(filename, type, true, true);
}
/**
* Constructor for an array of game-related images (skinnable and preloaded).
* @param filename the image file name
* @param filenameFormat the formatted file name string (for loading multiple images)
* @param type the file types (separated by '|')
*/
GameImage(String filename, String filenameFormat, String type) {
this(filename, type, true, true);
this.filenameFormat = filenameFormat;
}
/**
* Constructor for general images.
* @param filename the image file name
* @param type the file types (separated by '|')
* @param skinnable whether or not the image is skinnable
* @param preload whether or not to preload the image
*/
GameImage(String filename, String type, boolean skinnable, boolean preload) {
this.filename = filename;
this.type = getType(type);
this.skinnable = skinnable;
this.preload = preload;
}
/**
* Returns whether or not the image is skinnable.
* @return true if skinnable
*/
public boolean isSkinnable() { return skinnable; }
/**
* Returns whether or not to preload the image when the program starts.
* @return true if preload
*/
public boolean isPreload() { return preload; }
/**
* Returns the image associated with this resource.
* The skin image takes priority over the default image.
*/
public Image getImage() {
setDefaultImage();
return (skinImage != null) ? skinImage : defaultImage;
}
/**
* Returns the image array associated with this resource.
* The skin images takes priority over the default images.
*/
public Image[] getImages() {
setDefaultImage();
return (skinImages != null) ? skinImages : defaultImages;
}
/**
* Sets the image associated with this resource to another image.
* The skin image takes priority over the default image.
*/
public void setImage(Image img) {
if (skinImage != null)
this.skinImage = img;
else
this.defaultImage = img;
}
/**
* Sets an image associated with this resource to another image.
* The skin image takes priority over the default image.
*/
public void setImage(Image img, int index) {
if (skinImages != null) {
if (index < skinImages.length)
this.skinImages[index] = img;
} else {
if (index < defaultImages.length)
this.defaultImages[index] = img;
}
}
/**
* Sets the default image for this resource.
* If the default image has already been loaded, this will do nothing.
*/
public void setDefaultImage() {
if (defaultImage != null || defaultImages != null)
return;
// load image array
if (filenameFormat != null) {
List<Image> list = new ArrayList<Image>();
int i = 0;
boolean loaded;
do {
loaded = false;
for (String name : getFileNames(String.format(filenameFormat, i), type)) {
try {
// try loading the image
Image img = new Image(name);
// image successfully loaded
list.add(img);
loaded = true;
break;
} catch (SlickException | RuntimeException e) {
continue;
}
}
i++;
} while (loaded);
if (!list.isEmpty()) {
this.defaultImages = list.toArray(new Image[list.size()]);
process();
return;
}
}
// load single image
for (String name : getFileNames(filename, type)) {
try {
// try loading the image
Image img = new Image(name);
// image successfully loaded
this.defaultImage = img;
process();
return;
} catch (SlickException | RuntimeException e) {
continue;
}
}
ErrorHandler.error(String.format("Failed to set default image '%s'.", filename), null, false);
}
/**
* Sets the associated skin image.
* If the path does not contain the image, the default image is used.
* @return true if a new skin image is loaded, false otherwise
*/
public boolean setSkinImage(File dir) {
if (dir == null)
return false;
// destroy the existing images, if any
destroySkinImage();
// beatmap skins disabled
if (Options.isBeatmapSkinIgnored())
return false;
// look for multiple skin images
if (filenameFormat != null) {
List<Image> list = new ArrayList<Image>();
int i = 0;
boolean loaded;
do {
loaded = false;
for (String name : getFileNames(String.format(filenameFormat, i), type)) {
File file = new File(dir, name);
if (!file.isFile())
continue;
try {
// try loading the image
Image img = new Image(file.getAbsolutePath());
// image successfully loaded
list.add(img);
loaded = true;
break;
} catch (SlickException | RuntimeException e) {
continue;
}
}
i++;
} while (loaded);
if (!list.isEmpty()) {
this.skinImages = list.toArray(new Image[list.size()]);
process();
return true;
}
}
// look for a skin image
String errorFile = null;
for (String name : getFileNames(filename, type)) {
File file = new File(dir, name);
if (!file.isFile())
continue;
try {
// try loading the image
Image img = new Image(file.getAbsolutePath());
// image successfully loaded
this.skinImage = img;
process();
return true;
} catch (SlickException | RuntimeException e) {
errorFile = file.getAbsolutePath();
continue;
}
}
skinImage = null;
if (errorFile != null)
ErrorHandler.error(String.format("Failed to set skin image '%s'.", errorFile), null, false);
return false;
}
/**
* Returns whether a skin image is currently loaded.
* @return true if skin image exists
*/
public boolean hasSkinImage() { return (skinImage != null && !skinImage.isDestroyed()); }
/**
* Returns whether skin images are currently loaded.
* @return true if any skin image exists
*/
public boolean hasSkinImages() { return (skinImages != null); }
/**
* Destroys the associated skin image(s), if any.
*/
public void destroySkinImage() {
if (skinImage == null && skinImages == null)
return;
try {
if (skinImage != null) {
if (!skinImage.isDestroyed())
skinImage.destroy();
skinImage = null;
}
if (skinImages != null) {
for (int i = 0; i < skinImages.length; i++) {
if (!skinImages[i].isDestroyed())
skinImages[i].destroy();
}
skinImages = null;
}
} catch (SlickException e) {
ErrorHandler.error(String.format("Failed to destroy skin images for '%s'.", this.name()), e, true);
}
}
/**
* Sub-method for image processing actions (via an override).
* @param img the image to process
* @param w the container width
* @param h the container height
* @return the processed image
*/
protected Image process_sub(Image img, int w, int h) {
return img;
}
/**
* Performs individual post-loading actions on the image.
*/
private void process() {
if (skinImages != null) {
for (int i = 0; i < skinImages.length; i++)
setImage(process_sub(getImages()[i], containerWidth, containerHeight), i);
} else if (defaultImages != null && skinImage == null) {
for (int i = 0; i < defaultImages.length; i++)
setImage(process_sub(getImages()[i], containerWidth, containerHeight), i);
} else
setImage(process_sub(getImage(), containerWidth, containerHeight));
}
}