Beatmap downloader improvements and fixes.
Updates: - Added some buttons to downloads menu: clear inactive downloads, import beatmaps, reset search, and show/hide unranked maps. - Small changes to OsuParser, OszUnpacker, and OsuGroupList (mostly adding return values) to allow parsing only newly unpacked beatmaps. - Added alpha fade hover effect to MenuButton, as an alternative to expanding (used for 3-part menu buttons). - Added text rendering fields to MenuButton (also for the 3-part menu buttons). - Added sound effects to downloads menu. Fixes: - Check downloads for illegal filename characters, and remove them if necessary. - The number of results and downloads shown now supports all resolutions. - Confirmation dialog no longer appears when restarting the application (since downloads are static). - Do not set a focus node immediately if the theme song will be played. - Always play the theme song if no songs are loaded (even if disabled in settings). Signed-off-by: Jeffrey Han <itdelatrisu@gmail.com>
This commit is contained in:
parent
cfc0449ab2
commit
ec90d6fd03
|
@ -115,7 +115,7 @@ public class Container extends AppGameContainer {
|
||||||
@Override
|
@Override
|
||||||
public void exit() {
|
public void exit() {
|
||||||
// show confirmation dialog if any downloads are active
|
// show confirmation dialog if any downloads are active
|
||||||
if (DownloadList.get().hasActiveDownloads() && DownloadList.showExitConfirmation())
|
if (forceExit && DownloadList.get().hasActiveDownloads() && DownloadList.showExitConfirmation())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
super.exit();
|
super.exit();
|
||||||
|
|
|
@ -441,12 +441,7 @@ public enum GameImage {
|
||||||
return img.getScaledCopy(MENU_LOGO.getImage().getWidth() * 0.66f / img.getWidth());
|
return img.getScaledCopy(MENU_LOGO.getImage().getWidth() * 0.66f / img.getWidth());
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
MENU_BUTTON_MID ("button-middle", "png", false, false) {
|
MENU_BUTTON_MID ("button-middle", "png", false, false),
|
||||||
@Override
|
|
||||||
protected Image process_sub(Image img, int w, int h) {
|
|
||||||
return img.getScaledCopy(w / 2, img.getHeight());
|
|
||||||
}
|
|
||||||
},
|
|
||||||
MENU_BUTTON_LEFT ("button-left", "png", false, false),
|
MENU_BUTTON_LEFT ("button-left", "png", false, false),
|
||||||
MENU_BUTTON_RIGHT ("button-right", "png", false, false),
|
MENU_BUTTON_RIGHT ("button-right", "png", false, false),
|
||||||
MUSIC_PLAY ("music-play", "png", false, false),
|
MUSIC_PLAY ("music-play", "png", false, false),
|
||||||
|
|
|
@ -143,7 +143,7 @@ public enum GameMod {
|
||||||
|
|
||||||
// create button
|
// create button
|
||||||
this.button = new MenuButton(img, x + (offsetX * id), y);
|
this.button = new MenuButton(img, x + (offsetX * id), y);
|
||||||
this.button.setHoverScale(1.15f);
|
this.button.setHoverExpand(1.15f);
|
||||||
|
|
||||||
// reset state
|
// reset state
|
||||||
this.active = false;
|
this.active = false;
|
||||||
|
@ -245,10 +245,9 @@ public enum GameMod {
|
||||||
public boolean contains(float x, float y) { return button.contains(x, y); }
|
public boolean contains(float x, float y) { return button.contains(x, y); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current button scale (for hovering).
|
* Resets the hover fields for the button.
|
||||||
* @param scale the new scale (default 1.0f)
|
|
||||||
*/
|
*/
|
||||||
public void setScale(float scale) { button.setScale(scale); }
|
public void resetHover() { button.resetHover(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the scale of the button depending on whether or not the cursor
|
* Updates the scale of the button depending on whether or not the cursor
|
||||||
|
|
|
@ -20,6 +20,7 @@ package itdelatrisu.opsu;
|
||||||
|
|
||||||
import org.newdawn.slick.Animation;
|
import org.newdawn.slick.Animation;
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
|
import org.newdawn.slick.Font;
|
||||||
import org.newdawn.slick.Image;
|
import org.newdawn.slick.Image;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -43,8 +44,26 @@ public class MenuButton {
|
||||||
/** The x and y radius of the button (scaled). */
|
/** The x and y radius of the button (scaled). */
|
||||||
private float xRadius, yRadius;
|
private float xRadius, yRadius;
|
||||||
|
|
||||||
|
/** The text to draw on the button. */
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
/** The font to draw the text with. */
|
||||||
|
private Font font;
|
||||||
|
|
||||||
|
/** The color to draw the text with. */
|
||||||
|
private Color color;
|
||||||
|
|
||||||
|
/** Hover action types. */
|
||||||
|
private enum HoverAction { NONE, EXPAND, FADE };
|
||||||
|
|
||||||
|
/** The hover action for this button. */
|
||||||
|
private HoverAction hoverAction = HoverAction.NONE;
|
||||||
|
|
||||||
/** The current and max scale of the button (for hovering). */
|
/** The current and max scale of the button (for hovering). */
|
||||||
private float scale, hoverScale = 1.25f;
|
private float scale = 1f, hoverScale = 1.25f;
|
||||||
|
|
||||||
|
/** The current and base alpha level of the button (for hovering). */
|
||||||
|
private float alpha = 1f, baseAlpha = 0.75f;
|
||||||
|
|
||||||
/** The scaled expansion direction for the button (for hovering). */
|
/** The scaled expansion direction for the button (for hovering). */
|
||||||
private Expand dir = Expand.CENTER;
|
private Expand dir = Expand.CENTER;
|
||||||
|
@ -64,7 +83,6 @@ public class MenuButton {
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.xRadius = img.getWidth() / 2f;
|
this.xRadius = img.getWidth() / 2f;
|
||||||
this.yRadius = img.getHeight() / 2f;
|
this.yRadius = img.getHeight() / 2f;
|
||||||
this.scale = 1f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -83,7 +101,6 @@ public class MenuButton {
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.xRadius = (img.getWidth() + imgL.getWidth() + imgR.getWidth()) / 2f;
|
this.xRadius = (img.getWidth() + imgL.getWidth() + imgR.getWidth()) / 2f;
|
||||||
this.yRadius = img.getHeight() / 2f;
|
this.yRadius = img.getHeight() / 2f;
|
||||||
this.scale = 1f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,7 +115,6 @@ public class MenuButton {
|
||||||
this.y = y;
|
this.y = y;
|
||||||
this.xRadius = anim.getWidth() / 2f;
|
this.xRadius = anim.getWidth() / 2f;
|
||||||
this.yRadius = anim.getHeight() / 2f;
|
this.yRadius = anim.getHeight() / 2f;
|
||||||
this.scale = 1f;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -121,6 +137,18 @@ public class MenuButton {
|
||||||
*/
|
*/
|
||||||
public float getY() { return y; }
|
public float getY() { return y; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets text to draw in the middle of the button.
|
||||||
|
* @param text the text to draw
|
||||||
|
* @param font the font to use when drawing
|
||||||
|
* @color the color to draw the text
|
||||||
|
*/
|
||||||
|
public void setText(String text, Font font, Color color) {
|
||||||
|
this.text = text;
|
||||||
|
this.font = font;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the associated image.
|
* Returns the associated image.
|
||||||
*/
|
*/
|
||||||
|
@ -137,16 +165,39 @@ public class MenuButton {
|
||||||
public void draw() {
|
public void draw() {
|
||||||
if (img != null) {
|
if (img != null) {
|
||||||
if (imgL == null) {
|
if (imgL == null) {
|
||||||
|
if (hoverAction == HoverAction.EXPAND) {
|
||||||
Image imgScaled = (scale == 1f) ? img : img.getScaledCopy(scale);
|
Image imgScaled = (scale == 1f) ? img : img.getScaledCopy(scale);
|
||||||
imgScaled.setAlpha(img.getAlpha());
|
imgScaled.setAlpha(img.getAlpha());
|
||||||
imgScaled.draw(x - xRadius, y - yRadius);
|
imgScaled.draw(x - xRadius, y - yRadius);
|
||||||
|
} else if (hoverAction == HoverAction.FADE) {
|
||||||
|
float a = img.getAlpha();
|
||||||
|
img.setAlpha(alpha);
|
||||||
|
img.draw(x - xRadius, y - yRadius);
|
||||||
|
img.setAlpha(a);
|
||||||
|
} else
|
||||||
|
img.draw(x - xRadius, y - yRadius);
|
||||||
|
} else {
|
||||||
|
if (hoverAction == HoverAction.FADE) {
|
||||||
|
float a = img.getAlpha(), aL = imgL.getAlpha(), aR = imgR.getAlpha();
|
||||||
|
img.setAlpha(alpha);
|
||||||
|
imgL.setAlpha(alpha);
|
||||||
|
imgR.setAlpha(alpha);
|
||||||
|
img.draw(x - xRadius + imgL.getWidth(), y - yRadius);
|
||||||
|
imgL.draw(x - xRadius, y - yRadius);
|
||||||
|
imgR.draw(x + xRadius - imgR.getWidth(), y - yRadius);
|
||||||
|
img.setAlpha(a);
|
||||||
|
imgL.setAlpha(aL);
|
||||||
|
imgR.setAlpha(aR);
|
||||||
} else {
|
} else {
|
||||||
img.draw(x - xRadius + imgL.getWidth(), y - yRadius);
|
img.draw(x - xRadius + imgL.getWidth(), y - yRadius);
|
||||||
imgL.draw(x - xRadius, y - yRadius);
|
imgL.draw(x - xRadius, y - yRadius);
|
||||||
imgR.draw(x + xRadius - imgR.getWidth(), y - yRadius);
|
imgR.draw(x + xRadius - imgR.getWidth(), y - yRadius);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
anim.draw(x - xRadius, y - yRadius);
|
anim.draw(x - xRadius, y - yRadius);
|
||||||
|
if (text != null)
|
||||||
|
font.drawString(x - font.getWidth(text) / 2f, y - font.getLineHeight() / 2f, text, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -155,15 +206,40 @@ public class MenuButton {
|
||||||
*/
|
*/
|
||||||
public void draw(Color filter) {
|
public void draw(Color filter) {
|
||||||
if (img != null) {
|
if (img != null) {
|
||||||
if (imgL == null)
|
if (imgL == null) {
|
||||||
img.getScaledCopy(scale).draw(x - xRadius, y - yRadius, filter);
|
if (hoverAction == HoverAction.EXPAND) {
|
||||||
else {
|
Image imgScaled = (scale == 1f) ? img : img.getScaledCopy(scale);
|
||||||
|
imgScaled.setAlpha(img.getAlpha());
|
||||||
|
imgScaled.draw(x - xRadius, y - yRadius, filter);
|
||||||
|
} else if (hoverAction == HoverAction.FADE) {
|
||||||
|
float a = img.getAlpha();
|
||||||
|
img.setAlpha(alpha);
|
||||||
|
img.draw(x - xRadius, y - yRadius, filter);
|
||||||
|
img.setAlpha(a);
|
||||||
|
} else
|
||||||
|
img.draw(x - xRadius, y - yRadius, filter);
|
||||||
|
} else {
|
||||||
|
if (hoverAction == HoverAction.FADE) {
|
||||||
|
float a = img.getAlpha(), aL = imgL.getAlpha(), aR = imgR.getAlpha();
|
||||||
|
img.setAlpha(alpha);
|
||||||
|
imgL.setAlpha(alpha);
|
||||||
|
imgR.setAlpha(alpha);
|
||||||
|
img.draw(x - xRadius + imgL.getWidth(), y - yRadius, filter);
|
||||||
|
imgL.draw(x - xRadius, y - yRadius, filter);
|
||||||
|
imgR.draw(x + xRadius - imgR.getWidth(), y - yRadius, filter);
|
||||||
|
img.setAlpha(a);
|
||||||
|
imgL.setAlpha(aL);
|
||||||
|
imgR.setAlpha(aR);
|
||||||
|
} else {
|
||||||
img.draw(x - xRadius + imgL.getWidth(), y - yRadius, filter);
|
img.draw(x - xRadius + imgL.getWidth(), y - yRadius, filter);
|
||||||
imgL.draw(x - xRadius, y - yRadius, filter);
|
imgL.draw(x - xRadius, y - yRadius, filter);
|
||||||
imgR.draw(x + xRadius - imgR.getWidth(), y - yRadius, filter);
|
imgR.draw(x + xRadius - imgR.getWidth(), y - yRadius, filter);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
anim.draw(x - xRadius, y - yRadius, filter);
|
anim.draw(x - xRadius, y - yRadius, filter);
|
||||||
|
if (text != null)
|
||||||
|
font.drawString(x - font.getWidth(text) / 2f, y - font.getLineHeight() / 2f, text, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,45 +253,91 @@ public class MenuButton {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the current button scale (for hovering).
|
* Resets the hover fields for the button.
|
||||||
* @param scale the new scale (default 1.0f)
|
|
||||||
*/
|
*/
|
||||||
public void setScale(float scale) {
|
public void resetHover() {
|
||||||
this.scale = scale;
|
if (hoverAction == HoverAction.EXPAND) {
|
||||||
|
this.scale = 1f;
|
||||||
setHoverRadius();
|
setHoverRadius();
|
||||||
|
} else if (hoverAction == HoverAction.FADE)
|
||||||
|
this.alpha = baseAlpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the maximum scale factor for the button (for hovering).
|
* Sets the hover action to "expand".
|
||||||
|
*/
|
||||||
|
public void setHoverExpand() { this.hoverAction = HoverAction.EXPAND; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the hover action to "expand".
|
||||||
* @param scale the maximum scale factor (default 1.25f)
|
* @param scale the maximum scale factor (default 1.25f)
|
||||||
*/
|
*/
|
||||||
public void setHoverScale(float scale) { this.hoverScale = scale; }
|
public void setHoverExpand(float scale) { setHoverExpand(scale, this.dir); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the expansion direction when hovering over the button.
|
* Sets the hover action to "expand".
|
||||||
* @param dir the direction
|
* @param dir the expansion direction
|
||||||
*/
|
*/
|
||||||
public void setHoverDir(Expand dir) { this.dir = dir; }
|
public void setHoverExpand(Expand dir) { setHoverExpand(this.hoverScale, dir); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the scale of the button depending on whether or not the cursor
|
* Sets the hover action to "expand".
|
||||||
|
* @param scale the maximum scale factor (default 1.25f)
|
||||||
|
* @param dir the expansion direction
|
||||||
|
*/
|
||||||
|
public void setHoverExpand(float scale, Expand dir) {
|
||||||
|
this.hoverAction = HoverAction.EXPAND;
|
||||||
|
this.hoverScale = scale;
|
||||||
|
this.dir = dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the hover action to "fade".
|
||||||
|
*/
|
||||||
|
public void setHoverFade() { this.hoverAction = HoverAction.FADE; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the hover action to "fade".
|
||||||
|
* @param baseAlpha the base alpha level to fade in from (default 0.7f)
|
||||||
|
*/
|
||||||
|
public void setHoverFade(float baseAlpha) {
|
||||||
|
this.hoverAction = HoverAction.FADE;
|
||||||
|
this.baseAlpha = baseAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a hover action depending on whether or not the cursor
|
||||||
* is hovering over the button.
|
* is hovering over the button.
|
||||||
* @param delta the delta interval
|
* @param delta the delta interval
|
||||||
* @param cx the x coordinate
|
* @param cx the x coordinate
|
||||||
* @param cy the y coordinate
|
* @param cy the y coordinate
|
||||||
*/
|
*/
|
||||||
public void hoverUpdate(int delta, float cx, float cy) {
|
public void hoverUpdate(int delta, float cx, float cy) {
|
||||||
|
if (hoverAction == HoverAction.NONE)
|
||||||
|
return;
|
||||||
|
|
||||||
boolean isHover = contains(cx, cy);
|
boolean isHover = contains(cx, cy);
|
||||||
if (isHover && scale < hoverScale) {
|
if (hoverAction == HoverAction.EXPAND) {
|
||||||
scale += (hoverScale - 1f) * delta / 100f;
|
// scale the button
|
||||||
if (scale > hoverScale)
|
int sign;
|
||||||
scale = hoverScale;
|
if (isHover && scale < hoverScale)
|
||||||
setHoverRadius();
|
sign = 1;
|
||||||
} else if (!isHover && scale > 1f) {
|
else if (!isHover && scale > 1f)
|
||||||
scale -= (hoverScale - 1f) * delta / 100f;
|
sign = -1;
|
||||||
if (scale < 1f)
|
else
|
||||||
scale = 1f;
|
return;
|
||||||
|
scale = Utils.getBoundedValue(scale, sign * (hoverScale - 1f) * delta / 100f, 1, hoverScale);
|
||||||
setHoverRadius();
|
setHoverRadius();
|
||||||
|
} else {
|
||||||
|
// fade the button
|
||||||
|
int sign;
|
||||||
|
if (isHover && alpha < 1f)
|
||||||
|
sign = 1;
|
||||||
|
else if (!isHover && alpha > baseAlpha)
|
||||||
|
sign = -1;
|
||||||
|
else
|
||||||
|
return;
|
||||||
|
alpha = Utils.getBoundedValue(alpha, sign * (1f - baseAlpha) * delta / 200f, baseAlpha, 1f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -89,10 +89,13 @@ public class OsuGroupList {
|
||||||
/**
|
/**
|
||||||
* Adds a song group.
|
* Adds a song group.
|
||||||
* @param osuFiles the list of OsuFile objects in the group
|
* @param osuFiles the list of OsuFile objects in the group
|
||||||
|
* @return the new OsuGroupNode
|
||||||
*/
|
*/
|
||||||
public void addSongGroup(ArrayList<OsuFile> osuFiles) {
|
public OsuGroupNode addSongGroup(ArrayList<OsuFile> osuFiles) {
|
||||||
parsedNodes.add(new OsuGroupNode(osuFiles));
|
OsuGroupNode node = new OsuGroupNode(osuFiles);
|
||||||
|
parsedNodes.add(node);
|
||||||
mapCount += osuFiles.size();
|
mapCount += osuFiles.size();
|
||||||
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -53,23 +53,38 @@ public class OsuParser {
|
||||||
private OsuParser() {}
|
private OsuParser() {}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Invokes parser for each OSU file in a root directory.
|
* Invokes parser for each OSU file in a root directory and
|
||||||
|
* adds the OsuFiles to a new OsuGroupList.
|
||||||
* @param root the root directory (search has depth 1)
|
* @param root the root directory (search has depth 1)
|
||||||
*/
|
*/
|
||||||
public static void parseAllFiles(File root) {
|
public static void parseAllFiles(File root) {
|
||||||
// create a new OsuGroupList
|
// create a new OsuGroupList
|
||||||
OsuGroupList.create();
|
OsuGroupList.create();
|
||||||
|
|
||||||
// progress tracking
|
// parse all directories
|
||||||
File[] folders = root.listFiles();
|
parseDirectories(root.listFiles());
|
||||||
currentDirectoryIndex = 0;
|
}
|
||||||
totalDirectories = folders.length;
|
|
||||||
|
|
||||||
for (File folder : folders) {
|
/**
|
||||||
|
* Invokes parser for each directory in the given array and
|
||||||
|
* adds the OsuFiles to the existing OsuGroupList.
|
||||||
|
* @param dirs the array of directories to parse
|
||||||
|
* @return the last OsuGroupNode parsed
|
||||||
|
*/
|
||||||
|
public static OsuGroupNode parseDirectories(File[] dirs) {
|
||||||
|
// progress tracking
|
||||||
|
currentDirectoryIndex = 0;
|
||||||
|
totalDirectories = dirs.length;
|
||||||
|
|
||||||
|
// parse directories
|
||||||
|
OsuGroupNode lastNode = null;
|
||||||
|
for (File dir : dirs) {
|
||||||
currentDirectoryIndex++;
|
currentDirectoryIndex++;
|
||||||
if (!folder.isDirectory())
|
if (!dir.isDirectory())
|
||||||
continue;
|
continue;
|
||||||
File[] files = folder.listFiles(new FilenameFilter() {
|
|
||||||
|
// find all OSU files
|
||||||
|
File[] files = dir.listFiles(new FilenameFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File dir, String name) {
|
public boolean accept(File dir, String name) {
|
||||||
return name.toLowerCase().endsWith(".osu");
|
return name.toLowerCase().endsWith(".osu");
|
||||||
|
@ -90,10 +105,10 @@ public class OsuParser {
|
||||||
if (!osuFiles.isEmpty()) { // add entry if non-empty
|
if (!osuFiles.isEmpty()) { // add entry if non-empty
|
||||||
osuFiles.trimToSize();
|
osuFiles.trimToSize();
|
||||||
Collections.sort(osuFiles);
|
Collections.sort(osuFiles);
|
||||||
OsuGroupList.get().addSongGroup(osuFiles);
|
lastNode = OsuGroupList.get().addSongGroup(osuFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
// stop parsing files (interrupt sent by Splash)
|
// stop parsing files (interrupted)
|
||||||
if (Thread.interrupted())
|
if (Thread.interrupted())
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -104,6 +119,7 @@ public class OsuParser {
|
||||||
currentFile = null;
|
currentFile = null;
|
||||||
currentDirectoryIndex = -1;
|
currentDirectoryIndex = -1;
|
||||||
totalDirectories = -1;
|
totalDirectories = -1;
|
||||||
|
return lastNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -20,6 +20,8 @@ package itdelatrisu.opsu;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FilenameFilter;
|
import java.io.FilenameFilter;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import net.lingala.zip4j.core.ZipFile;
|
import net.lingala.zip4j.core.ZipFile;
|
||||||
import net.lingala.zip4j.exception.ZipException;
|
import net.lingala.zip4j.exception.ZipException;
|
||||||
|
@ -41,8 +43,13 @@ public class OszUnpacker {
|
||||||
* Invokes the unpacker for each OSZ archive in a root directory.
|
* Invokes the unpacker for each OSZ archive in a root directory.
|
||||||
* @param root the root directory
|
* @param root the root directory
|
||||||
* @param dest the destination directory
|
* @param dest the destination directory
|
||||||
|
* @return an array containing the new (unpacked) directories, or null
|
||||||
|
* if no OSZs found
|
||||||
*/
|
*/
|
||||||
public static void unpackAllFiles(File root, File dest) {
|
public static File[] unpackAllFiles(File root, File dest) {
|
||||||
|
List<File> dirs = new ArrayList<File>();
|
||||||
|
|
||||||
|
// find all OSZ files
|
||||||
files = root.listFiles(new FilenameFilter() {
|
files = root.listFiles(new FilenameFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(File dir, String name) {
|
public boolean accept(File dir, String name) {
|
||||||
|
@ -51,9 +58,10 @@ public class OszUnpacker {
|
||||||
});
|
});
|
||||||
if (files.length < 1) {
|
if (files.length < 1) {
|
||||||
files = null;
|
files = null;
|
||||||
return;
|
return new File[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// unpack OSZs
|
||||||
for (File file : files) {
|
for (File file : files) {
|
||||||
fileIndex++;
|
fileIndex++;
|
||||||
String dirName = file.getName().substring(0, file.getName().lastIndexOf('.'));
|
String dirName = file.getName().substring(0, file.getName().lastIndexOf('.'));
|
||||||
|
@ -62,11 +70,13 @@ public class OszUnpacker {
|
||||||
songDir.mkdir();
|
songDir.mkdir();
|
||||||
unzip(file, songDir);
|
unzip(file, songDir);
|
||||||
file.delete(); // delete the OSZ when finished
|
file.delete(); // delete the OSZ when finished
|
||||||
|
dirs.add(songDir);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fileIndex = -1;
|
fileIndex = -1;
|
||||||
files = null;
|
files = null;
|
||||||
|
return dirs.toArray(new File[dirs.size()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -28,6 +28,7 @@ import java.io.File;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.nio.IntBuffer;
|
import java.nio.IntBuffer;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
@ -109,6 +110,19 @@ public class Utils {
|
||||||
/** Set of all Unicode strings already loaded. */
|
/** Set of all Unicode strings already loaded. */
|
||||||
private static HashSet<String> loadedGlyphs = new HashSet<String>();
|
private static HashSet<String> loadedGlyphs = new HashSet<String>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of illegal filename characters.
|
||||||
|
* @see #cleanFileName(String, char)
|
||||||
|
*/
|
||||||
|
private final static int[] illegalChars = {
|
||||||
|
34, 60, 62, 124, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
|
||||||
|
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
|
||||||
|
24, 25, 26, 27, 28, 29, 30, 31, 58, 42, 63, 92, 47
|
||||||
|
};
|
||||||
|
static {
|
||||||
|
Arrays.sort(illegalChars);
|
||||||
|
}
|
||||||
|
|
||||||
// game-related variables
|
// game-related variables
|
||||||
private static GameContainer container;
|
private static GameContainer container;
|
||||||
private static StateBasedGame game;
|
private static StateBasedGame game;
|
||||||
|
@ -211,7 +225,7 @@ public class Utils {
|
||||||
backButton = new MenuButton(back,
|
backButton = new MenuButton(back,
|
||||||
back.getWidth() / 2f,
|
back.getWidth() / 2f,
|
||||||
height - (back.getHeight() / 2f));
|
height - (back.getHeight() / 2f));
|
||||||
backButton.setHoverDir(MenuButton.Expand.UP_RIGHT);
|
backButton.setHoverExpand(MenuButton.Expand.UP_RIGHT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -704,4 +718,24 @@ public class Utils {
|
||||||
char pre = "KMGTPE".charAt(exp - 1);
|
char pre = "KMGTPE".charAt(exp - 1);
|
||||||
return String.format("%.1f %cB", bytes / Math.pow(1024, exp), pre);
|
return String.format("%.1f %cB", bytes / Math.pow(1024, exp), pre);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cleans a file name.
|
||||||
|
* @param badFileName the original name string
|
||||||
|
* @param replace the character to replace illegal characters with (or 0 if none)
|
||||||
|
* @return the cleaned file name
|
||||||
|
* @author Sarel Botha (http://stackoverflow.com/a/5626340)
|
||||||
|
*/
|
||||||
|
public static String cleanFileName(String badFileName, char replace) {
|
||||||
|
boolean doReplace = (replace > 0 && Arrays.binarySearch(illegalChars, replace) < 0);
|
||||||
|
StringBuilder cleanName = new StringBuilder();
|
||||||
|
for (int i = 0, n = badFileName.length(); i < n; i++) {
|
||||||
|
int c = badFileName.charAt(i);
|
||||||
|
if (Arrays.binarySearch(illegalChars, c) < 0)
|
||||||
|
cleanName.append((char) c);
|
||||||
|
else if (doReplace)
|
||||||
|
cleanName.append(replace);
|
||||||
|
}
|
||||||
|
return cleanName.toString();
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -19,6 +19,7 @@
|
||||||
package itdelatrisu.opsu.downloads;
|
package itdelatrisu.opsu.downloads;
|
||||||
|
|
||||||
import itdelatrisu.opsu.ErrorHandler;
|
import itdelatrisu.opsu.ErrorHandler;
|
||||||
|
import itdelatrisu.opsu.Utils;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
|
@ -155,8 +156,9 @@ public class Download {
|
||||||
rbc.close();
|
rbc.close();
|
||||||
fos.close();
|
fos.close();
|
||||||
if (rename != null) {
|
if (rename != null) {
|
||||||
|
String cleanedName = Utils.cleanFileName(rename, '-');
|
||||||
Path source = new File(localPath).toPath();
|
Path source = new File(localPath).toPath();
|
||||||
Files.move(source, source.resolveSibling(rename), StandardCopyOption.REPLACE_EXISTING);
|
Files.move(source, source.resolveSibling(cleanedName), StandardCopyOption.REPLACE_EXISTING);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import itdelatrisu.opsu.ErrorHandler;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -126,6 +127,21 @@ public class DownloadList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes all inactive downloads from the list.
|
||||||
|
*/
|
||||||
|
public void clearInactiveDownloads() {
|
||||||
|
Iterator<DownloadNode> iter = nodes.iterator();
|
||||||
|
while (iter.hasNext()) {
|
||||||
|
DownloadNode node = iter.next();
|
||||||
|
Download dl = node.getDownload();
|
||||||
|
if (dl != null && !dl.isActive()) {
|
||||||
|
iter.remove();
|
||||||
|
map.remove(node.getID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows a confirmation dialog (used before exiting the game).
|
* Shows a confirmation dialog (used before exiting the game).
|
||||||
* @return true if user selects "yes", false otherwise
|
* @return true if user selects "yes", false otherwise
|
||||||
|
|
|
@ -23,7 +23,6 @@ import itdelatrisu.opsu.GameImage;
|
||||||
import itdelatrisu.opsu.Options;
|
import itdelatrisu.opsu.Options;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.downloads.Download.Status;
|
import itdelatrisu.opsu.downloads.Download.Status;
|
||||||
import itdelatrisu.opsu.states.DownloadsMenu;
|
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
|
@ -59,6 +58,9 @@ public class DownloadNode {
|
||||||
/** Information drawing values. */
|
/** Information drawing values. */
|
||||||
private static float infoBaseX, infoBaseY, infoWidth, infoHeight;
|
private static float infoBaseX, infoBaseY, infoWidth, infoHeight;
|
||||||
|
|
||||||
|
/** Maximum number of results and downloads to display on one screen. */
|
||||||
|
private static int maxResultsShown, maxDownloadsShown;
|
||||||
|
|
||||||
/** Container dimensions. */
|
/** Container dimensions. */
|
||||||
private static int containerWidth, containerHeight;
|
private static int containerWidth, containerHeight;
|
||||||
|
|
||||||
|
@ -89,8 +91,23 @@ public class DownloadNode {
|
||||||
infoBaseY = height * 0.07f + Utils.FONT_LARGE.getLineHeight() * 2f;
|
infoBaseY = height * 0.07f + Utils.FONT_LARGE.getLineHeight() * 2f;
|
||||||
infoWidth = width * 0.25f;
|
infoWidth = width * 0.25f;
|
||||||
infoHeight = Utils.FONT_DEFAULT.getLineHeight() * 2.4f;
|
infoHeight = Utils.FONT_DEFAULT.getLineHeight() * 2.4f;
|
||||||
|
|
||||||
|
float searchY = (height * 0.05f) + Utils.FONT_LARGE.getLineHeight();
|
||||||
|
float buttonHeight = height * 0.038f;
|
||||||
|
maxResultsShown = (int) ((height - buttonBaseY - searchY) / buttonOffset);
|
||||||
|
maxDownloadsShown = (int) ((height - infoBaseY - searchY - buttonHeight) / infoHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the max number of search result buttons to be shown at a time.
|
||||||
|
*/
|
||||||
|
public static int maxResultsShown() { return maxResultsShown; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the max number of downloads to be shown at a time.
|
||||||
|
*/
|
||||||
|
public static int maxDownloadsShown() { return maxDownloadsShown; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns true if the coordinates are within the bounds of the
|
* Returns true if the coordinates are within the bounds of the
|
||||||
* download result button at the given index.
|
* download result button at the given index.
|
||||||
|
@ -112,7 +129,7 @@ public class DownloadNode {
|
||||||
*/
|
*/
|
||||||
public static boolean resultAreaContains(float cx, float cy) {
|
public static boolean resultAreaContains(float cx, float cy) {
|
||||||
return ((cx > buttonBaseX && cx < buttonBaseX + buttonWidth) &&
|
return ((cx > buttonBaseX && cx < buttonBaseX + buttonWidth) &&
|
||||||
(cy > buttonBaseY && cy < buttonBaseY + buttonOffset * DownloadsMenu.MAX_RESULT_BUTTONS));
|
(cy > buttonBaseY && cy < buttonBaseY + buttonOffset * maxResultsShown));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,7 +169,7 @@ public class DownloadNode {
|
||||||
*/
|
*/
|
||||||
public static boolean downloadAreaContains(float cx, float cy) {
|
public static boolean downloadAreaContains(float cx, float cy) {
|
||||||
return ((cx > infoBaseX && cx <= containerWidth) &&
|
return ((cx > infoBaseX && cx <= containerWidth) &&
|
||||||
(cy > infoBaseY && cy < infoBaseY + infoHeight * DownloadsMenu.MAX_DOWNLOADS_SHOWN));
|
(cy > infoBaseY && cy < infoBaseY + infoHeight * maxDownloadsShown));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -165,10 +182,10 @@ public class DownloadNode {
|
||||||
float scrollbarWidth = containerWidth * 0.00347f;
|
float scrollbarWidth = containerWidth * 0.00347f;
|
||||||
float heightRatio = 0.0016f * (total * total) - 0.0705f * total + 0.9965f;
|
float heightRatio = 0.0016f * (total * total) - 0.0705f * total + 0.9965f;
|
||||||
float scrollbarHeight = containerHeight * heightRatio;
|
float scrollbarHeight = containerHeight * heightRatio;
|
||||||
float heightDiff = buttonHeight + buttonOffset * (DownloadsMenu.MAX_RESULT_BUTTONS - 1) - scrollbarHeight;
|
float heightDiff = buttonHeight + buttonOffset * (maxResultsShown - 1) - scrollbarHeight;
|
||||||
float offsetY = heightDiff * ((float) index / (total - DownloadsMenu.MAX_RESULT_BUTTONS));
|
float offsetY = heightDiff * ((float) index / (total - maxResultsShown));
|
||||||
g.setColor(BG_NORMAL);
|
g.setColor(BG_NORMAL);
|
||||||
g.fillRect(buttonBaseX + buttonWidth * 1.005f, buttonBaseY, scrollbarWidth, buttonOffset * DownloadsMenu.MAX_RESULT_BUTTONS);
|
g.fillRect(buttonBaseX + buttonWidth * 1.005f, buttonBaseY, scrollbarWidth, buttonOffset * maxResultsShown);
|
||||||
g.setColor(Color.white);
|
g.setColor(Color.white);
|
||||||
g.fillRect(buttonBaseX + buttonWidth * 1.005f, buttonBaseY + offsetY, scrollbarWidth, scrollbarHeight);
|
g.fillRect(buttonBaseX + buttonWidth * 1.005f, buttonBaseY + offsetY, scrollbarWidth, scrollbarHeight);
|
||||||
}
|
}
|
||||||
|
@ -183,10 +200,10 @@ public class DownloadNode {
|
||||||
float scrollbarWidth = containerWidth * 0.00347f;
|
float scrollbarWidth = containerWidth * 0.00347f;
|
||||||
float heightRatio = 0.0016f * (total * total) - 0.0705f * total + 0.9965f;
|
float heightRatio = 0.0016f * (total * total) - 0.0705f * total + 0.9965f;
|
||||||
float scrollbarHeight = containerHeight * heightRatio;
|
float scrollbarHeight = containerHeight * heightRatio;
|
||||||
float heightDiff = infoHeight + infoHeight * (DownloadsMenu.MAX_DOWNLOADS_SHOWN - 1) - scrollbarHeight;
|
float heightDiff = infoHeight + infoHeight * (maxDownloadsShown - 1) - scrollbarHeight;
|
||||||
float offsetY = heightDiff * ((float) index / (total - DownloadsMenu.MAX_DOWNLOADS_SHOWN));
|
float offsetY = heightDiff * ((float) index / (total - maxDownloadsShown));
|
||||||
g.setColor(BG_NORMAL);
|
g.setColor(BG_NORMAL);
|
||||||
g.fillRect(infoBaseX + infoWidth - scrollbarWidth, infoBaseY, scrollbarWidth, infoHeight * DownloadsMenu.MAX_DOWNLOADS_SHOWN);
|
g.fillRect(infoBaseX + infoWidth - scrollbarWidth, infoBaseY, scrollbarWidth, infoHeight * maxDownloadsShown);
|
||||||
g.setColor(Color.white);
|
g.setColor(Color.white);
|
||||||
g.fillRect(infoBaseX + infoWidth - scrollbarWidth, infoBaseY + offsetY, scrollbarWidth, scrollbarHeight);
|
g.fillRect(infoBaseX + infoWidth - scrollbarWidth, infoBaseY + offsetY, scrollbarWidth, scrollbarHeight);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,11 @@ package itdelatrisu.opsu.states;
|
||||||
import itdelatrisu.opsu.GameImage;
|
import itdelatrisu.opsu.GameImage;
|
||||||
import itdelatrisu.opsu.MenuButton;
|
import itdelatrisu.opsu.MenuButton;
|
||||||
import itdelatrisu.opsu.Opsu;
|
import itdelatrisu.opsu.Opsu;
|
||||||
|
import itdelatrisu.opsu.Options;
|
||||||
|
import itdelatrisu.opsu.OsuGroupList;
|
||||||
|
import itdelatrisu.opsu.OsuGroupNode;
|
||||||
|
import itdelatrisu.opsu.OsuParser;
|
||||||
|
import itdelatrisu.opsu.OszUnpacker;
|
||||||
import itdelatrisu.opsu.Utils;
|
import itdelatrisu.opsu.Utils;
|
||||||
import itdelatrisu.opsu.audio.SoundController;
|
import itdelatrisu.opsu.audio.SoundController;
|
||||||
import itdelatrisu.opsu.audio.SoundEffect;
|
import itdelatrisu.opsu.audio.SoundEffect;
|
||||||
|
@ -30,6 +35,7 @@ import itdelatrisu.opsu.downloads.DownloadList;
|
||||||
import itdelatrisu.opsu.downloads.DownloadNode;
|
import itdelatrisu.opsu.downloads.DownloadNode;
|
||||||
import itdelatrisu.opsu.downloads.DownloadServer;
|
import itdelatrisu.opsu.downloads.DownloadServer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import org.newdawn.slick.Color;
|
import org.newdawn.slick.Color;
|
||||||
|
@ -48,12 +54,6 @@ import org.newdawn.slick.state.transition.FadeOutTransition;
|
||||||
* Downloads menu.
|
* Downloads menu.
|
||||||
*/
|
*/
|
||||||
public class DownloadsMenu extends BasicGameState {
|
public class DownloadsMenu extends BasicGameState {
|
||||||
/** The max number of search result buttons to be shown at a time. */
|
|
||||||
public static final int MAX_RESULT_BUTTONS = 10;
|
|
||||||
|
|
||||||
/** The max number of downloads to be shown at a time. */
|
|
||||||
public static final int MAX_DOWNLOADS_SHOWN = 11;
|
|
||||||
|
|
||||||
/** Delay time, in milliseconds, between each search. */
|
/** Delay time, in milliseconds, between each search. */
|
||||||
private static final int SEARCH_DELAY = 700;
|
private static final int SEARCH_DELAY = 700;
|
||||||
|
|
||||||
|
@ -129,8 +129,11 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
/** Previous and next page buttons. */
|
/** Previous and next page buttons. */
|
||||||
private MenuButton prevPage, nextPage;
|
private MenuButton prevPage, nextPage;
|
||||||
|
|
||||||
/** "Ranked only?" checkbox coordinates. */
|
/** Buttons. */
|
||||||
private float rankedBoxX, rankedBoxY, rankedBoxLength;
|
private MenuButton clearButton, importButton, resetButton, rankedButton;
|
||||||
|
|
||||||
|
/** Beatmap importing thread. */
|
||||||
|
private Thread importThread;
|
||||||
|
|
||||||
// game-related variables
|
// game-related variables
|
||||||
private StateBasedGame game;
|
private StateBasedGame game;
|
||||||
|
@ -150,14 +153,15 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
int width = container.getWidth();
|
int width = container.getWidth();
|
||||||
int height = container.getHeight();
|
int height = container.getHeight();
|
||||||
float baseX = width * 0.024f;
|
float baseX = width * 0.024f;
|
||||||
|
float searchY = (height * 0.05f) + Utils.FONT_LARGE.getLineHeight();
|
||||||
|
float searchWidth = width * 0.35f;
|
||||||
|
|
||||||
// search
|
// search
|
||||||
searchTimer = SEARCH_DELAY;
|
searchTimer = SEARCH_DELAY;
|
||||||
searchResultString = "Type to search!";
|
searchResultString = "Type to search!";
|
||||||
search = new TextField(
|
search = new TextField(
|
||||||
container, Utils.FONT_DEFAULT,
|
container, Utils.FONT_DEFAULT, (int) baseX, (int) searchY,
|
||||||
(int) baseX, (int) (height * 0.05f) + Utils.FONT_LARGE.getLineHeight(),
|
(int) searchWidth, Utils.FONT_MEDIUM.getLineHeight()
|
||||||
(int) (width * 0.35f), Utils.FONT_MEDIUM.getLineHeight()
|
|
||||||
);
|
);
|
||||||
search.setBackgroundColor(DownloadNode.BG_NORMAL);
|
search.setBackgroundColor(DownloadNode.BG_NORMAL);
|
||||||
search.setBorderColor(Color.white);
|
search.setBorderColor(Color.white);
|
||||||
|
@ -165,22 +169,46 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
search.setConsumeEvents(false);
|
search.setConsumeEvents(false);
|
||||||
search.setMaxLength(255);
|
search.setMaxLength(255);
|
||||||
|
|
||||||
// ranked only?
|
|
||||||
rankedBoxX = search.getX() + search.getWidth() * 1.2f;
|
|
||||||
rankedBoxY = search.getY();
|
|
||||||
rankedBoxLength = search.getHeight();
|
|
||||||
|
|
||||||
// page buttons
|
// page buttons
|
||||||
float buttonY = height * 0.2f;
|
float pageButtonY = height * 0.2f;
|
||||||
float buttonWidth = width * 0.7f;
|
float pageButtonWidth = width * 0.7f;
|
||||||
Image prevImg = GameImage.MUSIC_PREVIOUS.getImage();
|
Image prevImg = GameImage.MUSIC_PREVIOUS.getImage();
|
||||||
Image nextImg = GameImage.MUSIC_NEXT.getImage();
|
Image nextImg = GameImage.MUSIC_NEXT.getImage();
|
||||||
prevPage = new MenuButton(prevImg, baseX + prevImg.getWidth() / 2f,
|
prevPage = new MenuButton(prevImg, baseX + prevImg.getWidth() / 2f,
|
||||||
buttonY - prevImg.getHeight() / 2f);
|
pageButtonY - prevImg.getHeight() / 2f);
|
||||||
nextPage = new MenuButton(nextImg, baseX + buttonWidth - nextImg.getWidth() / 2f,
|
nextPage = new MenuButton(nextImg, baseX + pageButtonWidth - nextImg.getWidth() / 2f,
|
||||||
buttonY - nextImg.getHeight() / 2f);
|
pageButtonY - nextImg.getHeight() / 2f);
|
||||||
prevPage.setHoverScale(1.5f);
|
prevPage.setHoverExpand(1.5f);
|
||||||
nextPage.setHoverScale(1.5f);
|
nextPage.setHoverExpand(1.5f);
|
||||||
|
|
||||||
|
// buttons
|
||||||
|
float buttonWidth = width * 0.12f;
|
||||||
|
float buttonMarginX = width * 0.004f;
|
||||||
|
float buttonHeight = height * 0.038f;
|
||||||
|
float topButtonY = searchY + Utils.FONT_MEDIUM.getLineHeight() / 2f;
|
||||||
|
float lowerButtonY = height * 0.995f - searchY - buttonHeight / 2f;
|
||||||
|
Image button = GameImage.MENU_BUTTON_MID.getImage();
|
||||||
|
Image buttonL = GameImage.MENU_BUTTON_LEFT.getImage();
|
||||||
|
Image buttonR = GameImage.MENU_BUTTON_RIGHT.getImage();
|
||||||
|
buttonL = buttonL.getScaledCopy(buttonHeight / buttonL.getHeight());
|
||||||
|
buttonR = buttonR.getScaledCopy(buttonHeight / buttonR.getHeight());
|
||||||
|
button = button.getScaledCopy((int) buttonWidth - buttonL.getWidth() - buttonR.getWidth(), (int) buttonHeight);
|
||||||
|
float fullButtonWidth = button.getWidth() + buttonL.getWidth() + buttonR.getWidth();
|
||||||
|
clearButton = new MenuButton(button, buttonL, buttonR,
|
||||||
|
width * 0.75f + buttonMarginX + fullButtonWidth / 2f, lowerButtonY);
|
||||||
|
importButton = new MenuButton(button, buttonL, buttonR,
|
||||||
|
width - buttonMarginX - fullButtonWidth / 2f, lowerButtonY);
|
||||||
|
resetButton = new MenuButton(button, buttonL, buttonR,
|
||||||
|
baseX + searchWidth + buttonMarginX + fullButtonWidth / 2f, topButtonY);
|
||||||
|
rankedButton = new MenuButton(button, buttonL, buttonR,
|
||||||
|
baseX + searchWidth + buttonMarginX * 2f + fullButtonWidth * 3 / 2f, topButtonY);
|
||||||
|
clearButton.setText("Clear", Utils.FONT_MEDIUM, Color.white);
|
||||||
|
importButton.setText("Import All", Utils.FONT_MEDIUM, Color.white);
|
||||||
|
resetButton.setText("Reset Search", Utils.FONT_MEDIUM, Color.white);
|
||||||
|
clearButton.setHoverFade();
|
||||||
|
importButton.setHoverFade();
|
||||||
|
resetButton.setHoverFade();
|
||||||
|
rankedButton.setHoverFade();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -204,17 +232,11 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
searchResultString, Color.white
|
searchResultString, Color.white
|
||||||
);
|
);
|
||||||
|
|
||||||
// ranked only?
|
|
||||||
if (rankedOnly)
|
|
||||||
g.fillRect(rankedBoxX, rankedBoxY, rankedBoxLength, rankedBoxLength);
|
|
||||||
else
|
|
||||||
g.drawRect(rankedBoxX, rankedBoxY, rankedBoxLength, rankedBoxLength);
|
|
||||||
Utils.FONT_MEDIUM.drawString(rankedBoxX + rankedBoxLength * 1.5f, rankedBoxY, "Show ranked maps only?", Color.white);
|
|
||||||
|
|
||||||
// search results
|
// search results
|
||||||
DownloadNode[] nodes = resultList;
|
DownloadNode[] nodes = resultList;
|
||||||
if (nodes != null) {
|
if (nodes != null) {
|
||||||
for (int i = 0; i < MAX_RESULT_BUTTONS; i++) {
|
int maxResultsShown = DownloadNode.maxResultsShown();
|
||||||
|
for (int i = 0; i < maxResultsShown; i++) {
|
||||||
int index = startResult + i;
|
int index = startResult + i;
|
||||||
if (index >= nodes.length)
|
if (index >= nodes.length)
|
||||||
break;
|
break;
|
||||||
|
@ -222,7 +244,7 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// scroll bar
|
// scroll bar
|
||||||
if (nodes.length > MAX_RESULT_BUTTONS)
|
if (nodes.length > maxResultsShown)
|
||||||
DownloadNode.drawResultScrollbar(g, startResult, nodes.length);
|
DownloadNode.drawResultScrollbar(g, startResult, nodes.length);
|
||||||
|
|
||||||
// pages
|
// pages
|
||||||
|
@ -250,7 +272,8 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
Utils.FONT_LARGE.drawString(downloadsX + width * 0.015f, downloadsY + height * 0.015f, "Downloads", Color.white);
|
Utils.FONT_LARGE.drawString(downloadsX + width * 0.015f, downloadsY + height * 0.015f, "Downloads", Color.white);
|
||||||
int downloadsSize = DownloadList.get().size();
|
int downloadsSize = DownloadList.get().size();
|
||||||
if (downloadsSize > 0) {
|
if (downloadsSize > 0) {
|
||||||
for (int i = 0; i < MAX_DOWNLOADS_SHOWN; i++) {
|
int maxDownloadsShown = DownloadNode.maxDownloadsShown();
|
||||||
|
for (int i = 0; i < maxDownloadsShown; i++) {
|
||||||
int index = startDownloadIndex + i;
|
int index = startDownloadIndex + i;
|
||||||
if (index >= downloadsSize)
|
if (index >= downloadsSize)
|
||||||
break;
|
break;
|
||||||
|
@ -258,11 +281,30 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
// scroll bar
|
// scroll bar
|
||||||
if (downloadsSize > MAX_DOWNLOADS_SHOWN)
|
if (downloadsSize > maxDownloadsShown)
|
||||||
DownloadNode.drawDownloadScrollbar(g, startDownloadIndex, downloadsSize);
|
DownloadNode.drawDownloadScrollbar(g, startDownloadIndex, downloadsSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buttons
|
||||||
|
clearButton.draw(Color.gray);
|
||||||
|
importButton.draw(Color.orange);
|
||||||
|
resetButton.draw(Color.red);
|
||||||
|
rankedButton.setText((rankedOnly) ? "Show Unranked" : "Hide Unranked", Utils.FONT_MEDIUM, Color.white);
|
||||||
|
rankedButton.draw(Color.magenta);
|
||||||
|
|
||||||
|
// importing beatmaps
|
||||||
|
if (importThread != null) {
|
||||||
|
// darken the screen
|
||||||
|
g.setColor(Utils.COLOR_BLACK_ALPHA);
|
||||||
|
g.fillRect(0, 0, width, height);
|
||||||
|
|
||||||
|
Utils.drawLoadingProgress(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
// back button
|
||||||
|
else
|
||||||
Utils.getBackButton().draw();
|
Utils.getBackButton().draw();
|
||||||
|
|
||||||
Utils.drawVolume(g);
|
Utils.drawVolume(g);
|
||||||
Utils.drawFPS();
|
Utils.drawFPS();
|
||||||
Utils.drawCursor();
|
Utils.drawCursor();
|
||||||
|
@ -277,6 +319,10 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
Utils.getBackButton().hoverUpdate(delta, mouseX, mouseY);
|
Utils.getBackButton().hoverUpdate(delta, mouseX, mouseY);
|
||||||
prevPage.hoverUpdate(delta, mouseX, mouseY);
|
prevPage.hoverUpdate(delta, mouseX, mouseY);
|
||||||
nextPage.hoverUpdate(delta, mouseX, mouseY);
|
nextPage.hoverUpdate(delta, mouseX, mouseY);
|
||||||
|
clearButton.hoverUpdate(delta, mouseX, mouseY);
|
||||||
|
importButton.hoverUpdate(delta, mouseX, mouseY);
|
||||||
|
resetButton.hoverUpdate(delta, mouseX, mouseY);
|
||||||
|
rankedButton.hoverUpdate(delta, mouseX, mouseY);
|
||||||
|
|
||||||
// focus timer
|
// focus timer
|
||||||
if (focusResult != -1 && focusTimer < FOCUS_DELAY)
|
if (focusResult != -1 && focusTimer < FOCUS_DELAY)
|
||||||
|
@ -285,7 +331,7 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
// search
|
// search
|
||||||
search.setFocus(true);
|
search.setFocus(true);
|
||||||
searchTimer += delta;
|
searchTimer += delta;
|
||||||
if (searchTimer >= SEARCH_DELAY) {
|
if (searchTimer >= SEARCH_DELAY && importThread == null) {
|
||||||
searchTimer = 0;
|
searchTimer = 0;
|
||||||
searchTimerReset = false;
|
searchTimerReset = false;
|
||||||
|
|
||||||
|
@ -367,6 +413,10 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
if (button != Input.MOUSE_LEFT_BUTTON)
|
if (button != Input.MOUSE_LEFT_BUTTON)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// block input during beatmap importing
|
||||||
|
if (importThread != null)
|
||||||
|
return;
|
||||||
|
|
||||||
// back
|
// back
|
||||||
if (Utils.getBackButton().contains(x, y)) {
|
if (Utils.getBackButton().contains(x, y)) {
|
||||||
SoundController.playSound(SoundEffect.MENUBACK);
|
SoundController.playSound(SoundEffect.MENUBACK);
|
||||||
|
@ -375,25 +425,17 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ranked only?
|
|
||||||
if ((x > rankedBoxX && x < rankedBoxX + rankedBoxLength) &&
|
|
||||||
(y > rankedBoxY && y < rankedBoxY + rankedBoxLength)) {
|
|
||||||
rankedOnly = !rankedOnly;
|
|
||||||
lastQuery = null;
|
|
||||||
pageDir = Page.CURRENT;
|
|
||||||
resetSearchTimer();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// search results
|
// search results
|
||||||
DownloadNode[] nodes = resultList;
|
DownloadNode[] nodes = resultList;
|
||||||
if (nodes != null) {
|
if (nodes != null) {
|
||||||
if (DownloadNode.resultAreaContains(x, y)) {
|
if (DownloadNode.resultAreaContains(x, y)) {
|
||||||
for (int i = 0; i < MAX_RESULT_BUTTONS; i++) {
|
int maxResultsShown = DownloadNode.maxResultsShown();
|
||||||
|
for (int i = 0; i < maxResultsShown; i++) {
|
||||||
int index = startResult + i;
|
int index = startResult + i;
|
||||||
if (index >= nodes.length)
|
if (index >= nodes.length)
|
||||||
break;
|
break;
|
||||||
if (DownloadNode.resultContains(x, y, i)) {
|
if (DownloadNode.resultContains(x, y, i)) {
|
||||||
|
SoundController.playSound(SoundEffect.MENUCLICK);
|
||||||
if (index == focusResult) {
|
if (index == focusResult) {
|
||||||
if (focusTimer >= FOCUS_DELAY) {
|
if (focusTimer >= FOCUS_DELAY) {
|
||||||
// too slow for double-click
|
// too slow for double-click
|
||||||
|
@ -424,6 +466,7 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
if (lastQueryDir == Page.PREVIOUS && queryThread != null && queryThread.isAlive())
|
if (lastQueryDir == Page.PREVIOUS && queryThread != null && queryThread.isAlive())
|
||||||
; // don't send consecutive requests
|
; // don't send consecutive requests
|
||||||
else {
|
else {
|
||||||
|
SoundController.playSound(SoundEffect.MENUCLICK);
|
||||||
pageDir = Page.PREVIOUS;
|
pageDir = Page.PREVIOUS;
|
||||||
lastQuery = null;
|
lastQuery = null;
|
||||||
resetSearchTimer();
|
resetSearchTimer();
|
||||||
|
@ -434,6 +477,7 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
if (lastQueryDir == Page.NEXT && queryThread != null && queryThread.isAlive())
|
if (lastQueryDir == Page.NEXT && queryThread != null && queryThread.isAlive())
|
||||||
; // don't send consecutive requests
|
; // don't send consecutive requests
|
||||||
else {
|
else {
|
||||||
|
SoundController.playSound(SoundEffect.MENUCLICK);
|
||||||
pageDir = Page.NEXT;
|
pageDir = Page.NEXT;
|
||||||
lastQuery = null;
|
lastQuery = null;
|
||||||
resetSearchTimer();
|
resetSearchTimer();
|
||||||
|
@ -443,9 +487,58 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// buttons
|
||||||
|
if (clearButton.contains(x, y)) {
|
||||||
|
SoundController.playSound(SoundEffect.MENUCLICK);
|
||||||
|
DownloadList.get().clearInactiveDownloads();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (importButton.contains(x, y)) {
|
||||||
|
SoundController.playSound(SoundEffect.MENUCLICK);
|
||||||
|
|
||||||
|
// import songs in new thread
|
||||||
|
importThread = new Thread() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
// invoke unpacker and parser
|
||||||
|
File[] dirs = OszUnpacker.unpackAllFiles(Options.getOSZDir(), Options.getBeatmapDir());
|
||||||
|
if (dirs != null && dirs.length > 0) {
|
||||||
|
OsuGroupNode node = OsuParser.parseDirectories(dirs);
|
||||||
|
if (node != null) {
|
||||||
|
// initialize song list
|
||||||
|
OsuGroupList.get().reset();
|
||||||
|
OsuGroupList.get().init();
|
||||||
|
((SongMenu) game.getState(Opsu.STATE_SONGMENU)).setFocus(node, -1, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
importThread = null;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
importThread.start();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (resetButton.contains(x, y)) {
|
||||||
|
SoundController.playSound(SoundEffect.MENUCLICK);
|
||||||
|
search.setText("");
|
||||||
|
lastQuery = null;
|
||||||
|
pageDir = Page.RESET;
|
||||||
|
resetSearchTimer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (rankedButton.contains(x, y)) {
|
||||||
|
SoundController.playSound(SoundEffect.MENUCLICK);
|
||||||
|
rankedOnly = !rankedOnly;
|
||||||
|
lastQuery = null;
|
||||||
|
pageDir = Page.CURRENT;
|
||||||
|
resetSearchTimer();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// downloads
|
// downloads
|
||||||
if (!DownloadList.get().isEmpty() && DownloadNode.downloadAreaContains(x, y)) {
|
if (!DownloadList.get().isEmpty() && DownloadNode.downloadAreaContains(x, y)) {
|
||||||
for (int i = 0, n = DownloadList.get().size(); i < MAX_DOWNLOADS_SHOWN; i++) {
|
int maxDownloadsShown = DownloadNode.maxDownloadsShown();
|
||||||
|
for (int i = 0, n = DownloadList.get().size(); i < maxDownloadsShown; i++) {
|
||||||
int index = startDownloadIndex + i;
|
int index = startDownloadIndex + i;
|
||||||
if (index >= n)
|
if (index >= n)
|
||||||
break;
|
break;
|
||||||
|
@ -472,6 +565,10 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseWheelMoved(int newValue) {
|
public void mouseWheelMoved(int newValue) {
|
||||||
|
// block input during beatmap importing
|
||||||
|
if (importThread != null)
|
||||||
|
return;
|
||||||
|
|
||||||
int shift = (newValue < 0) ? 1 : -1;
|
int shift = (newValue < 0) ? 1 : -1;
|
||||||
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
|
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
|
||||||
scrollLists(mouseX, mouseY, shift);
|
scrollLists(mouseX, mouseY, shift);
|
||||||
|
@ -479,6 +576,10 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void mouseDragged(int oldx, int oldy, int newx, int newy) {
|
public void mouseDragged(int oldx, int oldy, int newx, int newy) {
|
||||||
|
// block input during beatmap importing
|
||||||
|
if (importThread != null)
|
||||||
|
return;
|
||||||
|
|
||||||
// check mouse button
|
// check mouse button
|
||||||
if (!input.isMouseButtonDown(Input.MOUSE_RIGHT_BUTTON) &&
|
if (!input.isMouseButtonDown(Input.MOUSE_RIGHT_BUTTON) &&
|
||||||
!input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON))
|
!input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON))
|
||||||
|
@ -493,9 +594,16 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void keyPressed(int key, char c) {
|
public void keyPressed(int key, char c) {
|
||||||
|
// block input during beatmap importing
|
||||||
|
if (importThread != null && !(key == Input.KEY_ESCAPE || key == Input.KEY_F12))
|
||||||
|
return;
|
||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case Input.KEY_ESCAPE:
|
case Input.KEY_ESCAPE:
|
||||||
if (!search.getText().isEmpty()) {
|
if (importThread != null) {
|
||||||
|
// beatmap importing: stop parsing OsuFiles by sending interrupt to OsuParser
|
||||||
|
importThread.interrupt();
|
||||||
|
} else if (!search.getText().isEmpty()) {
|
||||||
// clear search text
|
// clear search text
|
||||||
search.setText("");
|
search.setText("");
|
||||||
pageDir = Page.RESET;
|
pageDir = Page.RESET;
|
||||||
|
@ -514,6 +622,7 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case Input.KEY_F5:
|
case Input.KEY_F5:
|
||||||
|
SoundController.playSound(SoundEffect.MENUCLICK);
|
||||||
lastQuery = null;
|
lastQuery = null;
|
||||||
pageDir = Page.CURRENT;
|
pageDir = Page.CURRENT;
|
||||||
resetSearchTimer();
|
resetSearchTimer();
|
||||||
|
@ -534,9 +643,13 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
@Override
|
@Override
|
||||||
public void enter(GameContainer container, StateBasedGame game)
|
public void enter(GameContainer container, StateBasedGame game)
|
||||||
throws SlickException {
|
throws SlickException {
|
||||||
Utils.getBackButton().setScale(1f);
|
Utils.getBackButton().resetHover();
|
||||||
prevPage.setScale(1f);
|
prevPage.resetHover();
|
||||||
nextPage.setScale(1f);
|
nextPage.resetHover();
|
||||||
|
clearButton.resetHover();
|
||||||
|
importButton.resetHover();
|
||||||
|
resetButton.resetHover();
|
||||||
|
rankedButton.resetHover();
|
||||||
focusResult = -1;
|
focusResult = -1;
|
||||||
startResult = 0;
|
startResult = 0;
|
||||||
startDownloadIndex = 0;
|
startDownloadIndex = 0;
|
||||||
|
@ -567,18 +680,18 @@ public class DownloadsMenu extends BasicGameState {
|
||||||
// search results
|
// search results
|
||||||
if (DownloadNode.resultAreaContains(cx, cy)) {
|
if (DownloadNode.resultAreaContains(cx, cy)) {
|
||||||
DownloadNode[] nodes = resultList;
|
DownloadNode[] nodes = resultList;
|
||||||
if (nodes != null && nodes.length >= MAX_RESULT_BUTTONS) {
|
if (nodes != null && nodes.length >= DownloadNode.maxResultsShown()) {
|
||||||
int newStartResult = startResult + shift;
|
int newStartResult = startResult + shift;
|
||||||
if (newStartResult >= 0 && newStartResult + MAX_RESULT_BUTTONS <= nodes.length)
|
if (newStartResult >= 0 && newStartResult + DownloadNode.maxResultsShown() <= nodes.length)
|
||||||
startResult = newStartResult;
|
startResult = newStartResult;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// downloads
|
// downloads
|
||||||
else if (DownloadNode.downloadAreaContains(cx, cy)) {
|
else if (DownloadNode.downloadAreaContains(cx, cy)) {
|
||||||
if (DownloadList.get().size() >= MAX_DOWNLOADS_SHOWN) {
|
if (DownloadList.get().size() >= DownloadNode.maxDownloadsShown()) {
|
||||||
int newStartDownloadIndex = startDownloadIndex + shift;
|
int newStartDownloadIndex = startDownloadIndex + shift;
|
||||||
if (newStartDownloadIndex >= 0 && newStartDownloadIndex + MAX_DOWNLOADS_SHOWN <= DownloadList.get().size())
|
if (newStartDownloadIndex >= 0 && newStartDownloadIndex + DownloadNode.maxDownloadsShown() <= DownloadList.get().size())
|
||||||
startDownloadIndex = newStartDownloadIndex;
|
startDownloadIndex = newStartDownloadIndex;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -730,7 +730,7 @@ public class Game extends BasicGameState {
|
||||||
restart = Restart.FALSE;
|
restart = Restart.FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
skipButton.setScale(1f);
|
skipButton.resetHover();
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Override
|
// @Override
|
||||||
|
@ -806,7 +806,7 @@ public class Game extends BasicGameState {
|
||||||
skipButton = new MenuButton(skip,
|
skipButton = new MenuButton(skip,
|
||||||
width - (skip.getWidth() / 2f),
|
width - (skip.getWidth() / 2f),
|
||||||
height - (skip.getHeight() / 2f));
|
height - (skip.getHeight() / 2f));
|
||||||
skipButton.setHoverDir(MenuButton.Expand.UP_LEFT);
|
skipButton.setHoverExpand(MenuButton.Expand.UP_LEFT);
|
||||||
|
|
||||||
// load other images...
|
// load other images...
|
||||||
((GamePauseMenu) game.getState(Opsu.STATE_GAMEPAUSEMENU)).loadImages();
|
((GamePauseMenu) game.getState(Opsu.STATE_GAMEPAUSEMENU)).loadImages();
|
||||||
|
|
|
@ -196,9 +196,9 @@ public class GamePauseMenu extends BasicGameState {
|
||||||
SoundController.playSound(SoundEffect.FAIL);
|
SoundController.playSound(SoundEffect.FAIL);
|
||||||
} else
|
} else
|
||||||
MusicController.pause();
|
MusicController.pause();
|
||||||
continueButton.setScale(1f);
|
continueButton.resetHover();
|
||||||
retryButton.setScale(1f);
|
retryButton.resetHover();
|
||||||
backButton.setScale(1f);
|
backButton.resetHover();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -212,5 +212,8 @@ public class GamePauseMenu extends BasicGameState {
|
||||||
continueButton = new MenuButton(GameImage.PAUSE_CONTINUE.getImage(), width / 2f, height * 0.25f);
|
continueButton = new MenuButton(GameImage.PAUSE_CONTINUE.getImage(), width / 2f, height * 0.25f);
|
||||||
retryButton = new MenuButton(GameImage.PAUSE_RETRY.getImage(), width / 2f, height * 0.5f);
|
retryButton = new MenuButton(GameImage.PAUSE_RETRY.getImage(), width / 2f, height * 0.5f);
|
||||||
backButton = new MenuButton(GameImage.PAUSE_BACK.getImage(), width / 2f, height * 0.75f);
|
backButton = new MenuButton(GameImage.PAUSE_BACK.getImage(), width / 2f, height * 0.75f);
|
||||||
|
continueButton.setHoverExpand();
|
||||||
|
retryButton.setHoverExpand();
|
||||||
|
backButton.setHoverExpand();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,7 +170,7 @@ public class GameRanking extends BasicGameState {
|
||||||
public void enter(GameContainer container, StateBasedGame game)
|
public void enter(GameContainer container, StateBasedGame game)
|
||||||
throws SlickException {
|
throws SlickException {
|
||||||
Display.setTitle(game.getTitle());
|
Display.setTitle(game.getTitle());
|
||||||
Utils.getBackButton().setScale(1f);
|
Utils.getBackButton().resetHover();
|
||||||
if (!data.isGameplay()) {
|
if (!data.isGameplay()) {
|
||||||
if (!MusicController.isTrackDimmed())
|
if (!MusicController.isTrackDimmed())
|
||||||
MusicController.toggleTrackDimmed(0.5f);
|
MusicController.toggleTrackDimmed(0.5f);
|
||||||
|
|
|
@ -126,9 +126,9 @@ public class MainMenu extends BasicGameState {
|
||||||
exitButton = new MenuButton(exitImg,
|
exitButton = new MenuButton(exitImg,
|
||||||
width * 0.75f - exitOffset, (height / 2) + (exitImg.getHeight() / 2f)
|
width * 0.75f - exitOffset, (height / 2) + (exitImg.getHeight() / 2f)
|
||||||
);
|
);
|
||||||
logo.setHoverScale(1.05f);
|
logo.setHoverExpand(1.05f);
|
||||||
playButton.setHoverScale(1.05f);
|
playButton.setHoverExpand(1.05f);
|
||||||
exitButton.setHoverScale(1.05f);
|
exitButton.setHoverExpand(1.05f);
|
||||||
|
|
||||||
// initialize music buttons
|
// initialize music buttons
|
||||||
int musicWidth = 48;
|
int musicWidth = 48;
|
||||||
|
@ -137,16 +137,15 @@ public class MainMenu extends BasicGameState {
|
||||||
musicPause = new MenuButton(GameImage.MUSIC_PAUSE.getImage(), width - (2 * musicWidth), musicHeight);
|
musicPause = new MenuButton(GameImage.MUSIC_PAUSE.getImage(), width - (2 * musicWidth), musicHeight);
|
||||||
musicNext = new MenuButton(GameImage.MUSIC_NEXT.getImage(), width - musicWidth, musicHeight);
|
musicNext = new MenuButton(GameImage.MUSIC_NEXT.getImage(), width - musicWidth, musicHeight);
|
||||||
musicPrevious = new MenuButton(GameImage.MUSIC_PREVIOUS.getImage(), width - (3 * musicWidth), musicHeight);
|
musicPrevious = new MenuButton(GameImage.MUSIC_PREVIOUS.getImage(), width - (3 * musicWidth), musicHeight);
|
||||||
musicPlay.setHoverScale(1.5f);
|
musicPlay.setHoverExpand(1.5f);
|
||||||
musicPause.setHoverScale(1.5f);
|
musicPause.setHoverExpand(1.5f);
|
||||||
musicNext.setHoverScale(1.5f);
|
musicNext.setHoverExpand(1.5f);
|
||||||
musicPrevious.setHoverScale(1.5f);
|
musicPrevious.setHoverExpand(1.5f);
|
||||||
|
|
||||||
// initialize downloads button
|
// initialize downloads button
|
||||||
Image dlImg = GameImage.DOWNLOADS.getImage();
|
Image dlImg = GameImage.DOWNLOADS.getImage();
|
||||||
downloadsButton = new MenuButton(dlImg, width - dlImg.getWidth() / 2f, height / 2f);
|
downloadsButton = new MenuButton(dlImg, width - dlImg.getWidth() / 2f, height / 2f);
|
||||||
downloadsButton.setHoverDir(Expand.LEFT);
|
downloadsButton.setHoverExpand(1.03f, Expand.LEFT);
|
||||||
downloadsButton.setHoverScale(1.05f);
|
|
||||||
|
|
||||||
// initialize repository button
|
// initialize repository button
|
||||||
if (Desktop.isDesktopSupported()) { // only if a webpage can be opened
|
if (Desktop.isDesktopSupported()) { // only if a webpage can be opened
|
||||||
|
@ -154,6 +153,7 @@ public class MainMenu extends BasicGameState {
|
||||||
repoButton = new MenuButton(repoImg,
|
repoButton = new MenuButton(repoImg,
|
||||||
(width * 0.997f) - repoImg.getWidth(), (height * 0.997f) - repoImg.getHeight()
|
(width * 0.997f) - repoImg.getWidth(), (height * 0.997f) - repoImg.getHeight()
|
||||||
);
|
);
|
||||||
|
repoButton.setHoverExpand();
|
||||||
}
|
}
|
||||||
|
|
||||||
reset();
|
reset();
|
||||||
|
@ -318,23 +318,23 @@ public class MainMenu extends BasicGameState {
|
||||||
// reset button hover states if mouse is not currently hovering over the button
|
// reset button hover states if mouse is not currently hovering over the button
|
||||||
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
|
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
|
||||||
if (!logo.contains(mouseX, mouseY))
|
if (!logo.contains(mouseX, mouseY))
|
||||||
logo.setScale(1f);
|
logo.resetHover();
|
||||||
if (!playButton.contains(mouseX, mouseY))
|
if (!playButton.contains(mouseX, mouseY))
|
||||||
playButton.setScale(1f);
|
playButton.resetHover();
|
||||||
if (!exitButton.contains(mouseX, mouseY))
|
if (!exitButton.contains(mouseX, mouseY))
|
||||||
exitButton.setScale(1f);
|
exitButton.resetHover();
|
||||||
if (!musicPlay.contains(mouseX, mouseY))
|
if (!musicPlay.contains(mouseX, mouseY))
|
||||||
musicPlay.setScale(1f);
|
musicPlay.resetHover();
|
||||||
if (!musicPause.contains(mouseX, mouseY))
|
if (!musicPause.contains(mouseX, mouseY))
|
||||||
musicPause.setScale(1f);
|
musicPause.resetHover();
|
||||||
if (!musicNext.contains(mouseX, mouseY))
|
if (!musicNext.contains(mouseX, mouseY))
|
||||||
musicNext.setScale(1f);
|
musicNext.resetHover();
|
||||||
if (!musicPrevious.contains(mouseX, mouseY))
|
if (!musicPrevious.contains(mouseX, mouseY))
|
||||||
musicPrevious.setScale(1f);
|
musicPrevious.resetHover();
|
||||||
if (repoButton != null && !repoButton.contains(mouseX, mouseY))
|
if (repoButton != null && !repoButton.contains(mouseX, mouseY))
|
||||||
repoButton.setScale(1f);
|
repoButton.resetHover();
|
||||||
if (!downloadsButton.contains(mouseX, mouseY))
|
if (!downloadsButton.contains(mouseX, mouseY))
|
||||||
downloadsButton.setScale(1f);
|
downloadsButton.resetHover();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -452,13 +452,13 @@ public class MainMenu extends BasicGameState {
|
||||||
logoClicked = false;
|
logoClicked = false;
|
||||||
logoTimer = 0;
|
logoTimer = 0;
|
||||||
|
|
||||||
logo.setScale(1f);
|
logo.resetHover();
|
||||||
playButton.setScale(1f);
|
playButton.resetHover();
|
||||||
exitButton.setScale(1f);
|
exitButton.resetHover();
|
||||||
musicPlay.setScale(1f);
|
musicPlay.resetHover();
|
||||||
musicPause.setScale(1f);
|
musicPause.resetHover();
|
||||||
musicNext.setScale(1f);
|
musicNext.resetHover();
|
||||||
musicPrevious.setScale(1f);
|
musicPrevious.resetHover();
|
||||||
downloadsButton.setScale(1f);
|
downloadsButton.resetHover();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ public class MainMenuExit extends BasicGameState {
|
||||||
// game-related variables
|
// game-related variables
|
||||||
private GameContainer container;
|
private GameContainer container;
|
||||||
private StateBasedGame game;
|
private StateBasedGame game;
|
||||||
|
private Input input;
|
||||||
private int state;
|
private int state;
|
||||||
|
|
||||||
public MainMenuExit(int state) {
|
public MainMenuExit(int state) {
|
||||||
|
@ -62,6 +63,7 @@ public class MainMenuExit extends BasicGameState {
|
||||||
throws SlickException {
|
throws SlickException {
|
||||||
this.container = container;
|
this.container = container;
|
||||||
this.game = game;
|
this.game = game;
|
||||||
|
this.input = container.getInput();
|
||||||
|
|
||||||
int width = container.getWidth();
|
int width = container.getWidth();
|
||||||
int height = container.getHeight();
|
int height = container.getHeight();
|
||||||
|
@ -70,14 +72,19 @@ public class MainMenuExit extends BasicGameState {
|
||||||
|
|
||||||
// initialize buttons
|
// initialize buttons
|
||||||
Image button = GameImage.MENU_BUTTON_MID.getImage();
|
Image button = GameImage.MENU_BUTTON_MID.getImage();
|
||||||
|
button = button.getScaledCopy(width / 2, button.getHeight());
|
||||||
Image buttonL = GameImage.MENU_BUTTON_LEFT.getImage();
|
Image buttonL = GameImage.MENU_BUTTON_LEFT.getImage();
|
||||||
Image buttonR = GameImage.MENU_BUTTON_RIGHT.getImage();
|
Image buttonR = GameImage.MENU_BUTTON_RIGHT.getImage();
|
||||||
yesButton = new MenuButton(button, buttonL, buttonR,
|
yesButton = new MenuButton(button, buttonL, buttonR,
|
||||||
width / 2f + centerOffset, height * 0.2f
|
width / 2f + centerOffset, height * 0.2f
|
||||||
);
|
);
|
||||||
|
yesButton.setText("1. Yes", Utils.FONT_XLARGE, Color.white);
|
||||||
noButton = new MenuButton(button, buttonL, buttonR,
|
noButton = new MenuButton(button, buttonL, buttonR,
|
||||||
width / 2f - centerOffset, height * 0.2f + (button.getHeight() * 1.25f)
|
width / 2f - centerOffset, height * 0.2f + (button.getHeight() * 1.25f)
|
||||||
);
|
);
|
||||||
|
noButton.setText("2. No", Utils.FONT_XLARGE, Color.white);
|
||||||
|
yesButton.setHoverFade();
|
||||||
|
noButton.setHoverFade();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -92,16 +99,6 @@ public class MainMenuExit extends BasicGameState {
|
||||||
// draw buttons
|
// draw buttons
|
||||||
yesButton.draw(Color.green);
|
yesButton.draw(Color.green);
|
||||||
noButton.draw(Color.red);
|
noButton.draw(Color.red);
|
||||||
Utils.FONT_XLARGE.drawString(
|
|
||||||
yesButton.getX() - (Utils.FONT_XLARGE.getWidth("1. Yes") / 2f),
|
|
||||||
yesButton.getY() - (Utils.FONT_XLARGE.getLineHeight() / 2f),
|
|
||||||
"1. Yes", Color.white
|
|
||||||
);
|
|
||||||
Utils.FONT_XLARGE.drawString(
|
|
||||||
noButton.getX() - (Utils.FONT_XLARGE.getWidth("2. No") / 2f),
|
|
||||||
noButton.getY() - (Utils.FONT_XLARGE.getLineHeight() / 2f),
|
|
||||||
"2. No", Color.white
|
|
||||||
);
|
|
||||||
|
|
||||||
Utils.drawVolume(g);
|
Utils.drawVolume(g);
|
||||||
Utils.drawFPS();
|
Utils.drawFPS();
|
||||||
|
@ -113,6 +110,9 @@ public class MainMenuExit extends BasicGameState {
|
||||||
throws SlickException {
|
throws SlickException {
|
||||||
Utils.updateCursor(delta);
|
Utils.updateCursor(delta);
|
||||||
Utils.updateVolumeDisplay(delta);
|
Utils.updateVolumeDisplay(delta);
|
||||||
|
int mouseX = input.getMouseX(), mouseY = input.getMouseY();
|
||||||
|
yesButton.hoverUpdate(delta, mouseX, mouseY);
|
||||||
|
noButton.hoverUpdate(delta, mouseX, mouseY);
|
||||||
|
|
||||||
// move buttons to center
|
// move buttons to center
|
||||||
float yesX = yesButton.getX(), noX = noButton.getX();
|
float yesX = yesButton.getX(), noX = noButton.getX();
|
||||||
|
@ -160,5 +160,7 @@ public class MainMenuExit extends BasicGameState {
|
||||||
float center = container.getWidth() / 2f;
|
float center = container.getWidth() / 2f;
|
||||||
yesButton.setX(center - centerOffset);
|
yesButton.setX(center - centerOffset);
|
||||||
noButton.setX(center + centerOffset);
|
noButton.setX(center + centerOffset);
|
||||||
|
yesButton.resetHover();
|
||||||
|
noButton.resetHover();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -415,9 +415,9 @@ public class OptionsMenu extends BasicGameState {
|
||||||
public void enter(GameContainer container, StateBasedGame game)
|
public void enter(GameContainer container, StateBasedGame game)
|
||||||
throws SlickException {
|
throws SlickException {
|
||||||
currentTab = OptionTab.DISPLAY;
|
currentTab = OptionTab.DISPLAY;
|
||||||
Utils.getBackButton().setScale(1f);
|
Utils.getBackButton().resetHover();
|
||||||
for (GameMod mod : GameMod.values())
|
for (GameMod mod : GameMod.values())
|
||||||
mod.setScale(1f);
|
mod.resetHover();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -220,7 +220,7 @@ public class SongMenu extends BasicGameState {
|
||||||
// options button
|
// options button
|
||||||
Image optionsIcon = GameImage.MENU_OPTIONS.getImage();
|
Image optionsIcon = GameImage.MENU_OPTIONS.getImage();
|
||||||
optionsButton = new MenuButton(optionsIcon, search.getX() - (optionsIcon.getWidth() * 1.5f), search.getY());
|
optionsButton = new MenuButton(optionsIcon, search.getX() - (optionsIcon.getWidth() * 1.5f), search.getY());
|
||||||
optionsButton.setHoverScale(1.75f);
|
optionsButton.setHoverExpand(1.75f);
|
||||||
|
|
||||||
// loader
|
// loader
|
||||||
int loaderDim = GameImage.MENU_MUSICNOTE.getImage().getWidth();
|
int loaderDim = GameImage.MENU_MUSICNOTE.getImage().getWidth();
|
||||||
|
@ -565,7 +565,6 @@ public class SongMenu extends BasicGameState {
|
||||||
case Input.KEY_ESCAPE:
|
case Input.KEY_ESCAPE:
|
||||||
if (reloadThread != null) {
|
if (reloadThread != null) {
|
||||||
// beatmap reloading: stop parsing OsuFiles by sending interrupt to OsuParser
|
// beatmap reloading: stop parsing OsuFiles by sending interrupt to OsuParser
|
||||||
if (reloadThread != null)
|
|
||||||
reloadThread.interrupt();
|
reloadThread.interrupt();
|
||||||
} else if (!search.getText().isEmpty()) {
|
} else if (!search.getText().isEmpty()) {
|
||||||
// clear search text
|
// clear search text
|
||||||
|
@ -626,7 +625,7 @@ public class SongMenu extends BasicGameState {
|
||||||
if (OsuGroupList.get().size() > 0) {
|
if (OsuGroupList.get().size() > 0) {
|
||||||
OsuGroupList.get().init();
|
OsuGroupList.get().init();
|
||||||
setFocus(OsuGroupList.get().getRandomNode(), -1, true);
|
setFocus(OsuGroupList.get().getRandomNode(), -1, true);
|
||||||
} else if (Options.isThemSongEnabled())
|
} else
|
||||||
MusicController.playThemeSong();
|
MusicController.playThemeSong();
|
||||||
|
|
||||||
reloadThread = null;
|
reloadThread = null;
|
||||||
|
@ -756,15 +755,15 @@ public class SongMenu extends BasicGameState {
|
||||||
public void enter(GameContainer container, StateBasedGame game)
|
public void enter(GameContainer container, StateBasedGame game)
|
||||||
throws SlickException {
|
throws SlickException {
|
||||||
Display.setTitle(game.getTitle());
|
Display.setTitle(game.getTitle());
|
||||||
Utils.getBackButton().setScale(1f);
|
Utils.getBackButton().resetHover();
|
||||||
optionsButton.setScale(1f);
|
optionsButton.resetHover();
|
||||||
hoverOffset = 0f;
|
hoverOffset = 0f;
|
||||||
hoverIndex = -1;
|
hoverIndex = -1;
|
||||||
startScore = 0;
|
startScore = 0;
|
||||||
|
|
||||||
// stop playing the theme song
|
// set focus node if not set (e.g. theme song playing)
|
||||||
if (MusicController.isThemePlaying() && focusNode != null)
|
if (focusNode == null && OsuGroupList.get().size() > 0)
|
||||||
MusicController.play(focusNode.osuFiles.get(focusNode.osuFileIndex), true);
|
setFocus(OsuGroupList.get().getRandomNode(), -1, true);
|
||||||
|
|
||||||
// reset music track
|
// reset music track
|
||||||
else if (resetTrack) {
|
else if (resetTrack) {
|
||||||
|
|
|
@ -126,11 +126,14 @@ public class Splash extends BasicGameState {
|
||||||
// initialize song list
|
// initialize song list
|
||||||
if (OsuGroupList.get().size() > 0) {
|
if (OsuGroupList.get().size() > 0) {
|
||||||
OsuGroupList.get().init();
|
OsuGroupList.get().init();
|
||||||
|
if (Options.isThemSongEnabled())
|
||||||
|
MusicController.playThemeSong();
|
||||||
|
else
|
||||||
((SongMenu) game.getState(Opsu.STATE_SONGMENU)).setFocus(OsuGroupList.get().getRandomNode(), -1, true);
|
((SongMenu) game.getState(Opsu.STATE_SONGMENU)).setFocus(OsuGroupList.get().getRandomNode(), -1, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
// play the theme song
|
// play the theme song
|
||||||
if (Options.isThemSongEnabled())
|
else
|
||||||
MusicController.playThemeSong();
|
MusicController.playThemeSong();
|
||||||
|
|
||||||
game.enterState(Opsu.STATE_MAINMENU);
|
game.enterState(Opsu.STATE_MAINMENU);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user