add navigation to optionmenu
This commit is contained in:
parent
2deef7c3a9
commit
6413392f1e
|
@ -465,6 +465,10 @@ public class DisplayContainer implements ErrorDumpable, ResolutionChangedListene
|
||||||
return (Sys.getTime() * 1000) / Sys.getTimerResolution();
|
return (Sys.getTime() * 1000) / Sys.getTimerResolution();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isWidescreen() {
|
||||||
|
return width * 1000 / height == 1777; // 16:9
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeErrorDump(StringWriter dump) {
|
public void writeErrorDump(StringWriter dump) {
|
||||||
dump.append("> DisplayContainer dump\n");
|
dump.append("> DisplayContainer dump\n");
|
||||||
|
|
|
@ -18,12 +18,14 @@
|
||||||
|
|
||||||
package yugecin.opsudance.options;
|
package yugecin.opsudance.options;
|
||||||
|
|
||||||
|
import itdelatrisu.opsu.GameImage;
|
||||||
|
|
||||||
import static yugecin.opsudance.options.Options.*;
|
import static yugecin.opsudance.options.Options.*;
|
||||||
|
|
||||||
public class OptionGroups {
|
public class OptionGroups {
|
||||||
|
|
||||||
public static final OptionTab[] normalOptions = new OptionTab[] {
|
public static final OptionTab[] normalOptions = new OptionTab[] {
|
||||||
new OptionTab("GENERAL", null),
|
new OptionTab("General", GameImage.SEARCH),
|
||||||
new OptionTab("GENERAL", new Option[]{
|
new OptionTab("GENERAL", new Option[]{
|
||||||
OPTION_DISABLE_UPDATER,
|
OPTION_DISABLE_UPDATER,
|
||||||
OPTION_ENABLE_WATCH_SERVICE
|
OPTION_ENABLE_WATCH_SERVICE
|
||||||
|
@ -31,7 +33,7 @@ public class OptionGroups {
|
||||||
new OptionTab("LANGUAGE", new Option[]{
|
new OptionTab("LANGUAGE", new Option[]{
|
||||||
OPTION_SHOW_UNICODE,
|
OPTION_SHOW_UNICODE,
|
||||||
}),
|
}),
|
||||||
new OptionTab("GRAPHICS", null),
|
new OptionTab("Graphics", GameImage.SEARCH),
|
||||||
new OptionTab("RENDERER", new Option[] {
|
new OptionTab("RENDERER", new Option[] {
|
||||||
OPTION_SCREEN_RESOLUTION,
|
OPTION_SCREEN_RESOLUTION,
|
||||||
OPTION_ALLOW_LARGER_RESOLUTIONS,
|
OPTION_ALLOW_LARGER_RESOLUTIONS,
|
||||||
|
@ -54,7 +56,7 @@ public class OptionGroups {
|
||||||
OPTION_DANCING_CIRCLES,
|
OPTION_DANCING_CIRCLES,
|
||||||
OPTION_DANCING_CIRCLES_MULTIPLIER,
|
OPTION_DANCING_CIRCLES_MULTIPLIER,
|
||||||
}),
|
}),
|
||||||
new OptionTab("SKIN", null),
|
new OptionTab("Skin", GameImage.SEARCH),
|
||||||
new OptionTab("SKIN", new Option[]{
|
new OptionTab("SKIN", new Option[]{
|
||||||
OPTION_SKIN,
|
OPTION_SKIN,
|
||||||
OPTION_IGNORE_BEATMAP_SKINS,
|
OPTION_IGNORE_BEATMAP_SKINS,
|
||||||
|
@ -69,7 +71,7 @@ public class OptionGroups {
|
||||||
OPTION_DISABLE_CURSOR
|
OPTION_DISABLE_CURSOR
|
||||||
// TODO use combo colour as tint for slider ball option
|
// TODO use combo colour as tint for slider ball option
|
||||||
}),
|
}),
|
||||||
new OptionTab("AUDIO", null),
|
new OptionTab("Audio", GameImage.SEARCH),
|
||||||
new OptionTab("VOLUME", new Option[]{
|
new OptionTab("VOLUME", new Option[]{
|
||||||
OPTION_MASTER_VOLUME,
|
OPTION_MASTER_VOLUME,
|
||||||
OPTION_MUSIC_VOLUME,
|
OPTION_MUSIC_VOLUME,
|
||||||
|
@ -82,7 +84,7 @@ public class OptionGroups {
|
||||||
OPTION_DISABLE_SOUNDS,
|
OPTION_DISABLE_SOUNDS,
|
||||||
OPTION_ENABLE_THEME_SONG
|
OPTION_ENABLE_THEME_SONG
|
||||||
}),
|
}),
|
||||||
new OptionTab("GAMEPLAY", null),
|
new OptionTab("Gameplay", GameImage.SEARCH),
|
||||||
new OptionTab("GENERAL", new Option[] {
|
new OptionTab("GENERAL", new Option[] {
|
||||||
OPTION_BACKGROUND_DIM,
|
OPTION_BACKGROUND_DIM,
|
||||||
OPTION_FORCE_DEFAULT_PLAYFIELD,
|
OPTION_FORCE_DEFAULT_PLAYFIELD,
|
||||||
|
@ -96,7 +98,7 @@ public class OptionGroups {
|
||||||
OPTION_MAP_END_DELAY,
|
OPTION_MAP_END_DELAY,
|
||||||
OPTION_EPILEPSY_WARNING,
|
OPTION_EPILEPSY_WARNING,
|
||||||
}),
|
}),
|
||||||
new OptionTab("INPUT", null),
|
new OptionTab("Input", GameImage.SEARCH),
|
||||||
new OptionTab("KEY MAPPING", new Option[]{
|
new OptionTab("KEY MAPPING", new Option[]{
|
||||||
OPTION_KEY_LEFT,
|
OPTION_KEY_LEFT,
|
||||||
OPTION_KEY_RIGHT,
|
OPTION_KEY_RIGHT,
|
||||||
|
@ -105,7 +107,7 @@ public class OptionGroups {
|
||||||
OPTION_DISABLE_MOUSE_WHEEL,
|
OPTION_DISABLE_MOUSE_WHEEL,
|
||||||
OPTION_DISABLE_MOUSE_BUTTONS,
|
OPTION_DISABLE_MOUSE_BUTTONS,
|
||||||
}),
|
}),
|
||||||
new OptionTab("CUSTOM", null),
|
new OptionTab("Custom", GameImage.SEARCH),
|
||||||
new OptionTab("DIFFICULTY", new Option[]{
|
new OptionTab("DIFFICULTY", new Option[]{
|
||||||
OPTION_FIXED_CS,
|
OPTION_FIXED_CS,
|
||||||
OPTION_FIXED_HP,
|
OPTION_FIXED_HP,
|
||||||
|
@ -116,7 +118,7 @@ public class OptionGroups {
|
||||||
OPTION_CHECKPOINT,
|
OPTION_CHECKPOINT,
|
||||||
OPTION_REPLAY_SEEKING,
|
OPTION_REPLAY_SEEKING,
|
||||||
}),
|
}),
|
||||||
new OptionTab("DANCE", null),
|
new OptionTab("Dance", GameImage.SEARCH),
|
||||||
new OptionTab("MOVER", new Option[]{
|
new OptionTab("MOVER", new Option[]{
|
||||||
OPTION_DANCE_MOVER,
|
OPTION_DANCE_MOVER,
|
||||||
OPTION_DANCE_EXGON_DELAY,
|
OPTION_DANCE_EXGON_DELAY,
|
||||||
|
@ -143,7 +145,7 @@ public class OptionGroups {
|
||||||
new OptionTab("MIRROR", new Option[] {
|
new OptionTab("MIRROR", new Option[] {
|
||||||
OPTION_DANCE_MIRROR,
|
OPTION_DANCE_MIRROR,
|
||||||
}),
|
}),
|
||||||
new OptionTab("ADVANCED DISPLAY", null),
|
new OptionTab("Advanced Display", GameImage.SEARCH),
|
||||||
new OptionTab("OBJECTS", new Option[]{
|
new OptionTab("OBJECTS", new Option[]{
|
||||||
OPTION_DANCE_DRAW_APPROACH,
|
OPTION_DANCE_DRAW_APPROACH,
|
||||||
OPTION_DANCE_OBJECT_COLOR_OVERRIDE,
|
OPTION_DANCE_OBJECT_COLOR_OVERRIDE,
|
||||||
|
@ -163,7 +165,7 @@ public class OptionGroups {
|
||||||
OPTION_DANCE_REMOVE_BG,
|
OPTION_DANCE_REMOVE_BG,
|
||||||
OPTION_DANCE_ENABLE_SB,
|
OPTION_DANCE_ENABLE_SB,
|
||||||
}),
|
}),
|
||||||
new OptionTab ("PIPPI", null),
|
new OptionTab ("Pippi", GameImage.SEARCH),
|
||||||
new OptionTab ("GENERAL", new Option[]{
|
new OptionTab ("GENERAL", new Option[]{
|
||||||
OPTION_PIPPI_ENABLE,
|
OPTION_PIPPI_ENABLE,
|
||||||
OPTION_PIPPI_RADIUS_PERCENT,
|
OPTION_PIPPI_RADIUS_PERCENT,
|
||||||
|
|
|
@ -17,15 +17,25 @@
|
||||||
*/
|
*/
|
||||||
package yugecin.opsudance.options;
|
package yugecin.opsudance.options;
|
||||||
|
|
||||||
|
import itdelatrisu.opsu.GameImage;
|
||||||
|
|
||||||
public class OptionTab {
|
public class OptionTab {
|
||||||
|
|
||||||
public final String name;
|
public final String name;
|
||||||
public final Option[] options;
|
public final Option[] options;
|
||||||
|
public final GameImage icon;
|
||||||
public boolean filtered;
|
public boolean filtered;
|
||||||
|
|
||||||
|
public OptionTab(String name, GameImage icon) {
|
||||||
|
this.name = name;
|
||||||
|
this.icon = icon;
|
||||||
|
this.options = null;
|
||||||
|
}
|
||||||
|
|
||||||
public OptionTab(String name, Option[] options) {
|
public OptionTab(String name, Option[] options) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
this.icon = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,12 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
private static final Color COL_GREY = new Color(55, 55, 57);
|
private static final Color COL_GREY = new Color(55, 55, 57);
|
||||||
private static final Color COL_BLUE = new Color(Colors.BLUE_BACKGROUND);
|
private static final Color COL_BLUE = new Color(Colors.BLUE_BACKGROUND);
|
||||||
private static final Color COL_COMBOBOX_HOVER = new Color(185, 19, 121);
|
private static final Color COL_COMBOBOX_HOVER = new Color(185, 19, 121);
|
||||||
|
private static final Color COL_NAV_BG = new Color(COL_BG);
|
||||||
|
private static final Color COL_NAV_INDICATOR = new Color(COL_PINK);
|
||||||
|
private static final Color COL_NAV_WHITE = new Color(COL_WHITE);
|
||||||
|
private static final Color COL_NAV_FILTERED = new Color(37, 37, 37);
|
||||||
|
private static final Color COL_NAV_INACTIVE = new Color(153, 153, 153);
|
||||||
|
private static final Color COL_NAV_FILTERED_HOVERED = new Color(58, 58, 58);
|
||||||
|
|
||||||
private static final float INDICATOR_ALPHA = 0.8f;
|
private static final float INDICATOR_ALPHA = 0.8f;
|
||||||
private static final Color COL_INDICATOR = new Color(Color.black);
|
private static final Color COL_INDICATOR = new Color(Color.black);
|
||||||
|
@ -84,6 +90,8 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
private Image searchImg;
|
private Image searchImg;
|
||||||
|
|
||||||
private OptionTab[] sections;
|
private OptionTab[] sections;
|
||||||
|
private OptionTab activeSection;
|
||||||
|
private OptionTab hoveredNavigationEntry;
|
||||||
|
|
||||||
private Option hoverOption;
|
private Option hoverOption;
|
||||||
private Option selectedOption;
|
private Option selectedOption;
|
||||||
|
@ -102,6 +110,13 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
private int width;
|
private int width;
|
||||||
private int height;
|
private int height;
|
||||||
|
|
||||||
|
private int navButtonSize;
|
||||||
|
private int navStartY;
|
||||||
|
private int navExpadedWidth;
|
||||||
|
private int navWidth;
|
||||||
|
private int navHoverTime;
|
||||||
|
private int navIndicatorSize;
|
||||||
|
|
||||||
private int optionWidth;
|
private int optionWidth;
|
||||||
private int optionStartX;
|
private int optionStartX;
|
||||||
private int optionStartY;
|
private int optionStartY;
|
||||||
|
@ -166,8 +181,13 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
height = displayContainer.height;
|
height = displayContainer.height;
|
||||||
|
|
||||||
// calculate positions
|
// calculate positions
|
||||||
|
float navIconWidthRatio = displayContainer.isWidescreen() ? 0.046875f : 0.065f;
|
||||||
|
// non-widescreen ratio is not accurate
|
||||||
|
navButtonSize = (int) (displayContainer.width * navIconWidthRatio);
|
||||||
|
navIndicatorSize = navButtonSize / 10;
|
||||||
|
navExpadedWidth = (int) (finalWidth * 0.45f) - navButtonSize;
|
||||||
paddingRight = (int) (displayContainer.width * 0.009375f); // not so accurate
|
paddingRight = (int) (displayContainer.width * 0.009375f); // not so accurate
|
||||||
paddingLeft = (int) (displayContainer.width * 0.0180f); // not so accurate
|
paddingLeft = navButtonSize + (int) (displayContainer.width * 0.0180f); // not so accurate
|
||||||
paddingTextLeft = paddingLeft + LINEWIDTH + (int) (displayContainer.width * 0.00625f); // not so accurate
|
paddingTextLeft = paddingLeft + LINEWIDTH + (int) (displayContainer.width * 0.00625f); // not so accurate
|
||||||
optionStartX = paddingTextLeft;
|
optionStartX = paddingTextLeft;
|
||||||
textOptionsY = Fonts.LARGE.getLineHeight() * 2;
|
textOptionsY = Fonts.LARGE.getLineHeight() * 2;
|
||||||
|
@ -191,9 +211,11 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
checkOnImg = GameImage.CONTROL_CHECK_ON.getImage().getScaledCopy(controlImageSize, controlImageSize);
|
checkOnImg = GameImage.CONTROL_CHECK_ON.getImage().getScaledCopy(controlImageSize, controlImageSize);
|
||||||
checkOffImg = GameImage.CONTROL_CHECK_OFF.getImage().getScaledCopy(controlImageSize, controlImageSize);
|
checkOffImg = GameImage.CONTROL_CHECK_OFF.getImage().getScaledCopy(controlImageSize, controlImageSize);
|
||||||
|
|
||||||
|
int navTotalHeight = 0;
|
||||||
dropdownMenus.clear();
|
dropdownMenus.clear();
|
||||||
for (OptionTab section : sections) {
|
for (OptionTab section : sections) {
|
||||||
if (section.options == null) {
|
if (section.options == null) {
|
||||||
|
navTotalHeight += navButtonSize;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for (final Option option : section.options) {
|
for (final Option option : section.options) {
|
||||||
|
@ -229,6 +251,7 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
dropdownMenus.put(listOption, menu);
|
dropdownMenus.put(listOption, menu);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
navStartY = (height - navTotalHeight) / 2;
|
||||||
|
|
||||||
int searchImgSize = (int) (Fonts.LARGE.getLineHeight() * 0.75f);
|
int searchImgSize = (int) (Fonts.LARGE.getLineHeight() * 0.75f);
|
||||||
searchImg = GameImage.SEARCH.getImage().getScaledCopy(searchImgSize, searchImgSize);
|
searchImg = GameImage.SEARCH.getImage().getScaledCopy(searchImgSize, searchImgSize);
|
||||||
|
@ -236,11 +259,11 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onRender(Graphics g) {
|
public void onRender(Graphics g) {
|
||||||
g.setClip(0, 0, width, height);
|
g.setClip(navButtonSize, 0, width - navButtonSize, height);
|
||||||
|
|
||||||
// bg
|
// bg
|
||||||
g.setColor(COL_BG);
|
g.setColor(COL_BG);
|
||||||
g.fillRect(0, 0, width, height);
|
g.fillRect(navButtonSize, 0, width, height);
|
||||||
|
|
||||||
// title
|
// title
|
||||||
renderTitle();
|
renderTitle();
|
||||||
|
@ -263,6 +286,8 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
g.fillRect(width - 5, scrollHandler.getPosition() / maxScrollOffset * (height - 45), 5, 45);
|
g.fillRect(width - 5, scrollHandler.getPosition() / maxScrollOffset * (height - 45), 5, 45);
|
||||||
g.clearClip();
|
g.clearClip();
|
||||||
|
|
||||||
|
renderNavigation(g);
|
||||||
|
|
||||||
// UI
|
// UI
|
||||||
UI.getBackButton().draw(g);
|
UI.getBackButton().draw(g);
|
||||||
|
|
||||||
|
@ -275,6 +300,57 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void renderNavigation(Graphics g) {
|
||||||
|
navWidth = navButtonSize;
|
||||||
|
if (navHoverTime >= 600) {
|
||||||
|
navWidth += navExpadedWidth;
|
||||||
|
} else if (navHoverTime > 300) {
|
||||||
|
AnimationEquation anim = AnimationEquation.IN_EXPO;
|
||||||
|
if (displayContainer.mouseX < navWidth) {
|
||||||
|
anim = AnimationEquation.OUT_EXPO;
|
||||||
|
}
|
||||||
|
float progress = anim.calc((navHoverTime - 300f) / 300f);
|
||||||
|
navWidth += (int) (progress * navExpadedWidth);
|
||||||
|
}
|
||||||
|
|
||||||
|
g.setClip(0, 0, navWidth, height);
|
||||||
|
g.setColor(COL_NAV_BG);
|
||||||
|
g.fillRect(0, 0, navWidth, displayContainer.height);
|
||||||
|
int y = navStartY;
|
||||||
|
float iconSize = navButtonSize / 2.5f;
|
||||||
|
float iconPadding = iconSize * 0.75f;
|
||||||
|
int fontOffsetX = navButtonSize + navIndicatorSize;
|
||||||
|
int fontOffsetY = (navButtonSize - Fonts.MEDIUM.getLineHeight()) / 2;
|
||||||
|
for (OptionTab section : sections) {
|
||||||
|
if (section.icon == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Color iconCol = COL_NAV_INACTIVE;
|
||||||
|
Color fontCol = COL_NAV_WHITE;
|
||||||
|
if (section == activeSection) {
|
||||||
|
iconCol = COL_NAV_WHITE;
|
||||||
|
g.fillRect(0, y, navWidth, navButtonSize);
|
||||||
|
g.setColor(COL_NAV_INDICATOR);
|
||||||
|
g.fillRect(navWidth - navIndicatorSize, y, navIndicatorSize, navButtonSize);
|
||||||
|
} else if (section == hoveredNavigationEntry) {
|
||||||
|
iconCol = COL_NAV_WHITE;
|
||||||
|
}
|
||||||
|
if (section.filtered) {
|
||||||
|
iconCol = fontCol = COL_NAV_FILTERED;
|
||||||
|
if (section == hoveredNavigationEntry) {
|
||||||
|
iconCol = COL_NAV_FILTERED_HOVERED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
section.icon.getImage().draw(iconPadding, y + iconPadding, iconSize, iconSize, iconCol);
|
||||||
|
if (navHoverTime > 0) {
|
||||||
|
Fonts.MEDIUM.drawString(fontOffsetX, y + fontOffsetY, section.name, fontCol);
|
||||||
|
}
|
||||||
|
y += navButtonSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
g.clearClip();
|
||||||
|
}
|
||||||
|
|
||||||
private void renderIndicator(Graphics g) {
|
private void renderIndicator(Graphics g) {
|
||||||
g.setColor(COL_INDICATOR);
|
g.setColor(COL_INDICATOR);
|
||||||
int indicatorPos = this.indicatorPos;
|
int indicatorPos = this.indicatorPos;
|
||||||
|
@ -289,7 +365,7 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
indicatorPos += AnimationEquation.OUT_BACK.calc((float) indicatorMoveAnimationTime / INDICATORMOVEANIMATIONTIME) * indicatorOffsetToNextPos;
|
indicatorPos += AnimationEquation.OUT_BACK.calc((float) indicatorMoveAnimationTime / INDICATORMOVEANIMATIONTIME) * indicatorOffsetToNextPos;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
g.fillRect(0, indicatorPos - scrollHandler.getPosition(), width, optionHeight);
|
g.fillRect(navButtonSize, indicatorPos - scrollHandler.getPosition(), width, optionHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderKeyEntry(Graphics g) {
|
private void renderKeyEntry(Graphics g) {
|
||||||
|
@ -324,12 +400,12 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
int lineStartY = (int) (y + Fonts.LARGE.getLineHeight() * 0.6f);
|
int lineStartY = (int) (y + Fonts.LARGE.getLineHeight() * 0.6f);
|
||||||
if (render) {
|
if (section.options == null) {
|
||||||
if (section.options == null) {
|
FontUtil.drawRightAligned(Fonts.XLARGE, width, -paddingRight,
|
||||||
FontUtil.drawRightAligned(Fonts.XLARGE, width, -paddingRight, (int) (y + Fonts.XLARGE.getLineHeight() * 0.3f), section.name, COL_CYAN);
|
(int) (y + Fonts.XLARGE.getLineHeight() * 0.3f), section.name.toUpperCase(),
|
||||||
} else {
|
COL_CYAN);
|
||||||
Fonts.MEDIUMBOLD.drawString(paddingTextLeft, lineStartY, section.name, COL_WHITE);
|
} else {
|
||||||
}
|
Fonts.MEDIUMBOLD.drawString(paddingTextLeft, lineStartY, section.name, COL_WHITE);
|
||||||
}
|
}
|
||||||
y += sectionLineHeight;
|
y += sectionLineHeight;
|
||||||
maxScrollOffset += sectionLineHeight;
|
maxScrollOffset += sectionLineHeight;
|
||||||
|
@ -479,8 +555,11 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderTitle() {
|
private void renderTitle() {
|
||||||
FontUtil.drawCentered(Fonts.LARGE, width, 0, textOptionsY - scrollHandler.getIntPosition(), "Options", COL_WHITE);
|
int textWidth = width - navButtonSize;
|
||||||
FontUtil.drawCentered(Fonts.MEDIUM, width, 0, textChangeY - scrollHandler.getIntPosition(), "Change the way opsu! behaves", COL_PINK);
|
FontUtil.drawCentered(Fonts.LARGE, textWidth, navButtonSize,
|
||||||
|
textOptionsY - scrollHandler.getIntPosition(), "Options", COL_WHITE);
|
||||||
|
FontUtil.drawCentered(Fonts.MEDIUM, textWidth, navButtonSize,
|
||||||
|
textChangeY - scrollHandler.getIntPosition(), "Change the way opsu! behaves", COL_PINK);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void renderSearch(Graphics g) {
|
private void renderSearch(Graphics g) {
|
||||||
|
@ -488,14 +567,14 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
if (scrollHandler.getIntPosition() > posSearchY) {
|
if (scrollHandler.getIntPosition() > posSearchY) {
|
||||||
ypos = textSearchYOffset;
|
ypos = textSearchYOffset;
|
||||||
g.setColor(COL_BG);
|
g.setColor(COL_BG);
|
||||||
g.fillRect(0, 0, width, textSearchYOffset * 2 + Fonts.LARGE.getLineHeight());
|
g.fillRect(navButtonSize, 0, width, textSearchYOffset * 2 + Fonts.LARGE.getLineHeight());
|
||||||
}
|
}
|
||||||
String searchText = "Type to search!";
|
String searchText = "Type to search!";
|
||||||
if (lastSearchText.length() > 0) {
|
if (lastSearchText.length() > 0) {
|
||||||
searchText = lastSearchText;
|
searchText = lastSearchText;
|
||||||
}
|
}
|
||||||
FontUtil.drawCentered(Fonts.LARGE, width, 0, ypos, searchText, COL_WHITE);
|
FontUtil.drawCentered(Fonts.LARGE, width, navButtonSize, ypos, searchText, COL_WHITE);
|
||||||
int imgPosX = (width - Fonts.LARGE.getWidth(searchText)) / 2 - searchImg.getWidth() - 10;
|
int imgPosX = navButtonSize + (width - Fonts.LARGE.getWidth(searchText)) / 2 - searchImg.getWidth() - 10;
|
||||||
searchImg.draw(imgPosX, ypos + Fonts.LARGE.getLineHeight() * 0.25f, COL_WHITE);
|
searchImg.draw(imgPosX, ypos + Fonts.LARGE.getLineHeight() * 0.25f, COL_WHITE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,6 +589,7 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void show() {
|
public void show() {
|
||||||
|
navHoverTime = 0;
|
||||||
indicatorPos = -optionHeight;
|
indicatorPos = -optionHeight;
|
||||||
indicatorOffsetToNextPos = 0;
|
indicatorOffsetToNextPos = 0;
|
||||||
indicatorMoveAnimationTime = 0;
|
indicatorMoveAnimationTime = 0;
|
||||||
|
@ -546,10 +626,20 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
sliderSoundDelay -= delta;
|
sliderSoundDelay -= delta;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mouseX < navWidth) {
|
||||||
|
if (navHoverTime < 600) {
|
||||||
|
navHoverTime += delta;
|
||||||
|
}
|
||||||
|
} else if (navHoverTime > 0) {
|
||||||
|
navHoverTime -= delta;
|
||||||
|
}
|
||||||
|
|
||||||
if (mouseX - prevMouseX == 0 && mouseY - prevMouseY == 0) {
|
if (mouseX - prevMouseX == 0 && mouseY - prevMouseY == 0) {
|
||||||
updateIndicatorAlpha();
|
updateIndicatorAlpha();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
updateActiveSection();
|
||||||
|
updateHoverNavigation(mouseX, mouseY);
|
||||||
prevMouseX = mouseX;
|
prevMouseX = mouseX;
|
||||||
prevMouseY = mouseY;
|
prevMouseY = mouseY;
|
||||||
updateHoverOption(mouseX, mouseY);
|
updateHoverOption(mouseX, mouseY);
|
||||||
|
@ -565,6 +655,24 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateHoverNavigation(int mouseX, int mouseY) {
|
||||||
|
hoveredNavigationEntry = null;
|
||||||
|
if (mouseX >= navWidth) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int y = navStartY;
|
||||||
|
for (OptionTab section : sections) {
|
||||||
|
if (section.options != null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
int nextY = y + navButtonSize;
|
||||||
|
if (y <= mouseY && mouseY < nextY) {
|
||||||
|
hoveredNavigationEntry = section;
|
||||||
|
}
|
||||||
|
y = nextY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateIndicatorAlpha() {
|
private void updateIndicatorAlpha() {
|
||||||
if (hoverOption == null) {
|
if (hoverOption == null) {
|
||||||
if (indicatorHideAnimationTime < INDICATORHIDEANIMATIONTIME) {
|
if (indicatorHideAnimationTime < INDICATORHIDEANIMATIONTIME) {
|
||||||
|
@ -594,20 +702,28 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
|
|
||||||
// if acceptInput is false, it means that we're currently hiding ourselves
|
// if acceptInput is false, it means that we're currently hiding ourselves
|
||||||
float progress;
|
float progress;
|
||||||
|
// navigation elemenst fade out with a different animation
|
||||||
|
float navProgress;
|
||||||
if (acceptInput) {
|
if (acceptInput) {
|
||||||
animationtime += delta;
|
animationtime += delta;
|
||||||
if (animationtime >= SHOWANIMATIONTIME) {
|
if (animationtime >= SHOWANIMATIONTIME) {
|
||||||
animationtime = SHOWANIMATIONTIME;
|
animationtime = SHOWANIMATIONTIME;
|
||||||
}
|
}
|
||||||
progress = AnimationEquation.OUT_EXPO.calc((float) animationtime / SHOWANIMATIONTIME);
|
progress = (float) animationtime / SHOWANIMATIONTIME;
|
||||||
|
navProgress = Utils.clamp(progress * 10f, 0f, 1f);
|
||||||
|
progress = AnimationEquation.OUT_EXPO.calc(progress);
|
||||||
} else {
|
} else {
|
||||||
animationtime -= delta;
|
animationtime -= delta;
|
||||||
if (animationtime < 0) {
|
if (animationtime < 0) {
|
||||||
animationtime = 0;
|
animationtime = 0;
|
||||||
}
|
}
|
||||||
progress = hideAnimationStartProgress * AnimationEquation.IN_EXPO.calc((float) animationtime / hideAnimationTime);
|
progress = (float) animationtime / hideAnimationTime;
|
||||||
|
navProgress = hideAnimationStartProgress * AnimationEquation.IN_CIRC.calc(progress);
|
||||||
|
progress = hideAnimationStartProgress * AnimationEquation.IN_EXPO.calc(progress);
|
||||||
}
|
}
|
||||||
width = (int) (progress * finalWidth);
|
width = navButtonSize + (int) (progress * (finalWidth - navButtonSize));
|
||||||
|
COL_NAV_FILTERED.a = COL_NAV_INACTIVE.a = COL_NAV_FILTERED_HOVERED.a = COL_NAV_INDICATOR.a =
|
||||||
|
COL_NAV_WHITE.a = COL_NAV_BG.a = navProgress;
|
||||||
COL_BG.a = BG_ALPHA * progress;
|
COL_BG.a = BG_ALPHA * progress;
|
||||||
COL_WHITE.a = progress;
|
COL_WHITE.a = progress;
|
||||||
COL_PINK.a = progress;
|
COL_PINK.a = progress;
|
||||||
|
@ -692,6 +808,28 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (hoveredNavigationEntry != null && !hoveredNavigationEntry.filtered) {
|
||||||
|
int sectionPosition = 0;
|
||||||
|
for (OptionTab section : sections) {
|
||||||
|
if (section == hoveredNavigationEntry) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (section.filtered) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
sectionPosition += sectionLineHeight;
|
||||||
|
if (section.options == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (Option option : section.options) {
|
||||||
|
if (!option.isFiltered() && option.showCondition()) {
|
||||||
|
sectionPosition += optionHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
scrollHandler.scrollToPosition(sectionPosition);
|
||||||
|
}
|
||||||
|
|
||||||
if (UI.getBackButton().contains(x, y)){
|
if (UI.getBackButton().contains(x, y)){
|
||||||
hide();
|
hide();
|
||||||
if (listener != null) {
|
if (listener != null) {
|
||||||
|
@ -776,6 +914,33 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
o.setValue(Utils.clamp(value, o.min, o.max));
|
o.setValue(Utils.clamp(value, o.min, o.max));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void updateActiveSection() {
|
||||||
|
// active section is the one that is visible in the top half of the screen
|
||||||
|
activeSection = sections[0];
|
||||||
|
int virtualY = optionStartY;
|
||||||
|
for (int sectionIndex = 0; sectionIndex < sections.length; sectionIndex++) {
|
||||||
|
OptionTab section = sections[sectionIndex];
|
||||||
|
if (section.filtered) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
virtualY += sectionLineHeight;
|
||||||
|
if (virtualY > scrollHandler.getPosition() + height / 2) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (section.options == null) {
|
||||||
|
activeSection = section;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
for (int optionIndex = 0; optionIndex < section.options.length; optionIndex++) {
|
||||||
|
Option option = section.options[optionIndex];
|
||||||
|
if (option.isFiltered() || !option.showCondition()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
virtualY += optionHeight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void updateHoverOption(int mouseX, int mouseY) {
|
private void updateHoverOption(int mouseX, int mouseY) {
|
||||||
if (openDropdownMenu != null || keyEntryLeft || keyEntryRight) {
|
if (openDropdownMenu != null || keyEntryLeft || keyEntryRight) {
|
||||||
return;
|
return;
|
||||||
|
@ -805,7 +970,7 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (mouseVirtualY <= optionHeight) {
|
if (mouseVirtualY <= optionHeight) {
|
||||||
if (mouseVirtualY >= 0) {
|
if (mouseX > navWidth && mouseVirtualY >= 0) {
|
||||||
int indicatorPos = scrollHandler.getIntPosition() + mouseY - mouseVirtualY;
|
int indicatorPos = scrollHandler.getIntPosition() + mouseY - mouseVirtualY;
|
||||||
if (indicatorPos != this.indicatorPos + indicatorOffsetToNextPos) {
|
if (indicatorPos != this.indicatorPos + indicatorOffsetToNextPos) {
|
||||||
this.indicatorPos += indicatorOffsetToNextPos; // finish the current moving animation
|
this.indicatorPos += indicatorOffsetToNextPos; // finish the current moving animation
|
||||||
|
@ -843,7 +1008,9 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
if (section.options == null) {
|
if (section.options == null) {
|
||||||
lastBigSectionMatches = sectionMatches;
|
lastBigSectionMatches = sectionMatches;
|
||||||
lastBigSection = section;
|
lastBigSection = section;
|
||||||
section.filtered = true;
|
if (!lastBigSectionMatches) {
|
||||||
|
section.filtered = true;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
section.filtered = true;
|
section.filtered = true;
|
||||||
|
@ -855,6 +1022,7 @@ public class OptionsOverlay extends OverlayOpsuState {
|
||||||
}
|
}
|
||||||
if (!option.filter(lastSearchText)) {
|
if (!option.filter(lastSearchText)) {
|
||||||
section.filtered = false;
|
section.filtered = false;
|
||||||
|
//noinspection ConstantConditions
|
||||||
lastBigSection.filtered = false;
|
lastBigSection.filtered = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user