diff --git a/src/itdelatrisu/opsu/GameImage.java b/src/itdelatrisu/opsu/GameImage.java index c5b8ddf1..ec6a3ff3 100644 --- a/src/itdelatrisu/opsu/GameImage.java +++ b/src/itdelatrisu/opsu/GameImage.java @@ -446,10 +446,30 @@ public enum GameImage { 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), - MUSIC_PAUSE ("music-pause", "png", false, false), - MUSIC_NEXT ("music-next", "png", false, false), - MUSIC_PREVIOUS ("music-previous", "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) { diff --git a/src/itdelatrisu/opsu/ScoreData.java b/src/itdelatrisu/opsu/ScoreData.java index 992543fa..5ad238a1 100644 --- a/src/itdelatrisu/opsu/ScoreData.java +++ b/src/itdelatrisu/opsu/ScoreData.java @@ -71,9 +71,6 @@ public class ScoreData implements Comparable { /** Drawing values. */ private static float baseX, baseY, buttonWidth, buttonHeight, buttonOffset; - /** Container dimensions. */ - private static int containerWidth, containerHeight; - /** Button background colors. */ private static final Color BG_NORMAL = new Color(0, 0, 0, 0.25f), @@ -85,9 +82,6 @@ public class ScoreData implements Comparable { * @param height the container height */ public static void init(int width, int height) { - containerWidth = width; - containerHeight = height; - baseX = width * 0.01f; baseY = height * 0.16f; buttonWidth = width * 0.4f; @@ -127,13 +121,8 @@ public class ScoreData implements Comparable { * @param total the total number of buttons */ public static void drawScrollbar(Graphics g, int index, int total) { - float scorebarWidth = containerWidth * 0.00347f; - float heightRatio = 0.0016f * (total * total) - 0.0705f * total + 0.9965f; - float scorebarHeight = containerHeight * heightRatio; - float heightDiff = buttonHeight + buttonOffset * (SongMenu.MAX_SCORE_BUTTONS - 1) - scorebarHeight; - float offsetY = heightDiff * ((float) index / (total - SongMenu.MAX_SCORE_BUTTONS)); - g.setColor(Color.white); - g.fillRect(0, baseY + offsetY, scorebarWidth, scorebarHeight); + Utils.drawScrollbar(g, index, total, SongMenu.MAX_SCORE_BUTTONS, 0, baseY, + 0, buttonHeight, buttonOffset, null, Color.white, false); } /** diff --git a/src/itdelatrisu/opsu/Utils.java b/src/itdelatrisu/opsu/Utils.java index 1914c9c2..25bfd245 100644 --- a/src/itdelatrisu/opsu/Utils.java +++ b/src/itdelatrisu/opsu/Utils.java @@ -608,6 +608,40 @@ public class Utils { } } + /** + * Draws a scroll bar. + * @param g the graphics context + * @param unitIndex the unit index + * @param totalUnits the total number of units + * @param maxShown the maximum number of units shown at one time + * @param unitBaseX the base x coordinate of the units + * @param unitBaseY the base y coordinate of the units + * @param unitWidth the width of a unit + * @param unitHeight the height of a unit + * @param unitOffsetY the y offset between units + * @param bgColor the scroll bar area background color (null if none) + * @param scrollbarColor the scroll bar color + * @param right whether or not to place the scroll bar on the right side of the unit + */ + public static void drawScrollbar( + Graphics g, int unitIndex, int totalUnits, int maxShown, + float unitBaseX, float unitBaseY, float unitWidth, float unitHeight, float unitOffsetY, + Color bgColor, Color scrollbarColor, boolean right + ) { + float scrollbarWidth = container.getWidth() * 0.00347f; + float heightRatio = (float) (2.6701f * Math.exp(-0.81 * Math.log(totalUnits))); + float scrollbarHeight = container.getHeight() * heightRatio; + float scrollAreaHeight = unitHeight + unitOffsetY * (maxShown - 1); + float offsetY = (scrollAreaHeight - scrollbarHeight) * ((float) unitIndex / (totalUnits - maxShown)); + float scrollbarX = unitBaseX + unitWidth - ((right) ? scrollbarWidth : 0); + if (bgColor != null) { + g.setColor(bgColor); + g.fillRect(scrollbarX, unitBaseY, scrollbarWidth, scrollAreaHeight); + } + g.setColor(scrollbarColor); + g.fillRect(scrollbarX, unitBaseY + offsetY, scrollbarWidth, scrollbarHeight); + } + /** * Takes a screenshot. * @author http://wiki.lwjgl.org/index.php?title=Taking_Screen_Shots diff --git a/src/itdelatrisu/opsu/downloads/DownloadNode.java b/src/itdelatrisu/opsu/downloads/DownloadNode.java index 28ec1ee1..89b207d8 100644 --- a/src/itdelatrisu/opsu/downloads/DownloadNode.java +++ b/src/itdelatrisu/opsu/downloads/DownloadNode.java @@ -62,8 +62,8 @@ public class DownloadNode { /** Maximum number of results and downloads to display on one screen. */ private static int maxResultsShown, maxDownloadsShown; - /** Container dimensions. */ - private static int containerWidth, containerHeight; + /** Container width. */ + private static int containerWidth; /** Button background colors. */ public static final Color @@ -78,7 +78,6 @@ public class DownloadNode { */ public static void init(int width, int height) { containerWidth = width; - containerHeight = height; // download result buttons buttonBaseX = width * 0.024f; @@ -180,15 +179,8 @@ public class DownloadNode { * @param total the total number of buttons */ public static void drawResultScrollbar(Graphics g, int index, int total) { - float scrollbarWidth = containerWidth * 0.00347f; - float heightRatio = 0.0016f * (total * total) - 0.0705f * total + 0.9965f; - float scrollbarHeight = containerHeight * heightRatio; - float heightDiff = buttonHeight + buttonOffset * (maxResultsShown - 1) - scrollbarHeight; - float offsetY = heightDiff * ((float) index / (total - maxResultsShown)); - g.setColor(BG_NORMAL); - g.fillRect(buttonBaseX + buttonWidth * 1.005f, buttonBaseY, scrollbarWidth, buttonOffset * maxResultsShown); - g.setColor(Color.white); - g.fillRect(buttonBaseX + buttonWidth * 1.005f, buttonBaseY + offsetY, scrollbarWidth, scrollbarHeight); + Utils.drawScrollbar(g, index, total, maxResultsShown, buttonBaseX, buttonBaseY, + buttonWidth * 1.01f, buttonHeight, buttonOffset, BG_NORMAL, Color.white, true); } /** @@ -198,15 +190,8 @@ public class DownloadNode { * @param total the total number of downloads */ public static void drawDownloadScrollbar(Graphics g, int index, int total) { - float scrollbarWidth = containerWidth * 0.00347f; - float heightRatio = 0.0016f * (total * total) - 0.0705f * total + 0.9965f; - float scrollbarHeight = containerHeight * heightRatio; - float heightDiff = infoHeight + infoHeight * (maxDownloadsShown - 1) - scrollbarHeight; - float offsetY = heightDiff * ((float) index / (total - maxDownloadsShown)); - g.setColor(BG_NORMAL); - g.fillRect(infoBaseX + infoWidth - scrollbarWidth, infoBaseY, scrollbarWidth, infoHeight * maxDownloadsShown); - g.setColor(Color.white); - g.fillRect(infoBaseX + infoWidth - scrollbarWidth, infoBaseY + offsetY, scrollbarWidth, scrollbarHeight); + Utils.drawScrollbar(g, index, total, maxDownloadsShown, infoBaseX, infoBaseY, + infoWidth, infoHeight, infoHeight, BG_NORMAL, Color.white, true); } /** diff --git a/src/itdelatrisu/opsu/states/MainMenu.java b/src/itdelatrisu/opsu/states/MainMenu.java index 3e5a95f5..2ff569fd 100644 --- a/src/itdelatrisu/opsu/states/MainMenu.java +++ b/src/itdelatrisu/opsu/states/MainMenu.java @@ -92,6 +92,14 @@ public class MainMenu extends BasicGameState { /** Background alpha level (for fade-in effect). */ private float bgAlpha = 0f; + /** Music position bar coordinates and dimensions. */ + private float musicBarX, musicBarY, musicBarWidth, musicBarHeight; + + /** Music position bar background colors. */ + private static final Color + BG_NORMAL = new Color(0, 0, 0, 0.25f), + BG_HOVER = new Color(0, 0, 0, 0.5f); + // game-related variables private GameContainer container; private StateBasedGame game; @@ -132,17 +140,23 @@ public class MainMenu extends BasicGameState { exitButton.setHoverExpand(1.05f); // initialize music buttons - int musicWidth = 48; - int musicHeight = 30; - musicPlay = new MenuButton(GameImage.MUSIC_PLAY.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); - musicPrevious = new MenuButton(GameImage.MUSIC_PREVIOUS.getImage(), width - (3 * musicWidth), musicHeight); + int musicWidth = GameImage.MUSIC_PLAY.getImage().getWidth(); + int musicHeight = GameImage.MUSIC_PLAY.getImage().getHeight(); + musicPlay = new MenuButton(GameImage.MUSIC_PLAY.getImage(), width - (2 * musicWidth), musicHeight / 1.5f); + musicPause = new MenuButton(GameImage.MUSIC_PAUSE.getImage(), width - (2 * musicWidth), musicHeight / 1.5f); + musicNext = new MenuButton(GameImage.MUSIC_NEXT.getImage(), width - musicWidth, musicHeight / 1.5f); + musicPrevious = new MenuButton(GameImage.MUSIC_PREVIOUS.getImage(), width - (3 * musicWidth), musicHeight / 1.5f); musicPlay.setHoverExpand(1.5f); musicPause.setHoverExpand(1.5f); musicNext.setHoverExpand(1.5f); musicPrevious.setHoverExpand(1.5f); + // initialize music position bar location + musicBarX = width - musicWidth * 3.5f; + musicBarY = musicHeight * 1.25f; + musicBarWidth = musicWidth * 3f; + musicBarHeight = musicHeight * 0.11f; + // initialize downloads button Image dlImg = GameImage.DOWNLOADS.getImage(); downloadsButton = new MenuButton(dlImg, width - dlImg.getWidth() / 2f, height / 2f); @@ -177,6 +191,7 @@ public class MainMenu extends BasicGameState { bg.draw(); } + // top/bottom horizontal bars float oldAlpha = Utils.COLOR_BLACK_ALPHA.a; Utils.COLOR_BLACK_ALPHA.a = 0.2f; g.setColor(Utils.COLOR_BLACK_ALPHA); @@ -201,12 +216,16 @@ public class MainMenu extends BasicGameState { musicPlay.draw(); musicNext.draw(); musicPrevious.draw(); - g.setColor(Utils.COLOR_BLACK_ALPHA); - g.fillRoundRect(width - 168, 54, 148, 5, 4); + + // draw music position bar + int mouseX = input.getMouseX(), mouseY = input.getMouseY(); + g.setColor((musicPositionBarContains(mouseX, mouseY)) ? BG_HOVER : BG_NORMAL); + g.fillRoundRect(musicBarX, musicBarY, musicBarWidth, musicBarHeight, 4); g.setColor(Color.white); - if (!MusicController.isTrackLoading() && osu != null) - g.fillRoundRect(width - 168, 54, - 148f * MusicController.getPosition() / osu.endTime, 5, 4); + if (!MusicController.isTrackLoading() && osu != null) { + float musicBarPosition = Math.min((float) MusicController.getPosition() / osu.endTime, 1f); + g.fillRoundRect(musicBarX, musicBarY, musicBarWidth * musicBarPosition, musicBarHeight, 4); + } // draw repository button if (repoButton != null) @@ -344,6 +363,16 @@ public class MainMenu extends BasicGameState { if (button == Input.MOUSE_MIDDLE_BUTTON) return; + // music position bar + if (MusicController.isPlaying()) { + if (musicPositionBarContains(x, y)) { + float pos = (x - musicBarX) / musicBarWidth; + OsuFile osu = MusicController.getOsuFile(); + MusicController.setPosition((int) (pos * osu.endTime)); + return; + } + } + // music button actions if (musicPlay.contains(x, y)) { if (MusicController.isPlaying()) @@ -445,6 +474,16 @@ public class MainMenu extends BasicGameState { } } + /** + * Returns true if the coordinates are within the music position bar bounds. + * @param cx the x coordinate + * @param cy the y coordinate + */ + private boolean musicPositionBarContains(float cx, float cy) { + return ((cx > musicBarX && cx < musicBarX + musicBarWidth) && + (cy > musicBarY && cy < musicBarY + musicBarHeight)); + } + /** * Resets the button states. */ diff --git a/src/itdelatrisu/opsu/states/SongMenu.java b/src/itdelatrisu/opsu/states/SongMenu.java index dd1a712c..be4d93be 100644 --- a/src/itdelatrisu/opsu/states/SongMenu.java +++ b/src/itdelatrisu/opsu/states/SongMenu.java @@ -128,9 +128,7 @@ public class SongMenu extends BasicGameState { private String[] songInfo; /** Button coordinate values. */ - private float - buttonX, buttonY, buttonOffset, - buttonWidth, buttonHeight; + private float buttonX, buttonY, buttonOffset, buttonWidth, buttonHeight; /** Current x offset of song buttons for mouse hover, in pixels. */ private float hoverOffset = 0f; @@ -357,12 +355,18 @@ public class SongMenu extends BasicGameState { // scroll bar if (focusNode != null) { - float scrollStartY = height * 0.16f; - float scrollEndY = height * 0.82f; - g.setColor(Utils.COLOR_BLACK_ALPHA); - g.fillRoundRect(width - 10, scrollStartY, 5, scrollEndY, 4); - g.setColor(Color.white); - g.fillRoundRect(width - 10, scrollStartY + (scrollEndY * startNode.index / OsuGroupList.get().size()), 5, 20, 4); + int focusNodes = focusNode.osuFiles.size(); + int totalNodes = OsuGroupList.get().size() + focusNodes - 1; + if (totalNodes > MAX_SONG_BUTTONS) { + int startIndex = startNode.index; + if (startNode.index > focusNode.index) + startIndex += focusNodes; + else if (startNode.index == focusNode.index) + startIndex += startNode.osuFileIndex; + Utils.drawScrollbar(g, startIndex, totalNodes, MAX_SONG_BUTTONS, + width, height * 0.16f, 0, buttonHeight, buttonOffset, + Utils.COLOR_BLACK_ALPHA, Color.white, true); + } } // reloading beatmaps