add navigation to optionmenu

This commit is contained in:
yugecin 2017-05-28 16:11:05 +02:00
parent 2deef7c3a9
commit 6413392f1e
4 changed files with 214 additions and 30 deletions

View File

@ -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");

View File

@ -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,

View File

@ -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;
} }
} }

View File

@ -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,13 +400,13 @@ 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, (int) (y + Fonts.XLARGE.getLineHeight() * 0.3f), section.name, COL_CYAN); FontUtil.drawRightAligned(Fonts.XLARGE, width, -paddingRight,
(int) (y + Fonts.XLARGE.getLineHeight() * 0.3f), section.name.toUpperCase(),
COL_CYAN);
} else { } else {
Fonts.MEDIUMBOLD.drawString(paddingTextLeft, lineStartY, section.name, COL_WHITE); Fonts.MEDIUMBOLD.drawString(paddingTextLeft, lineStartY, section.name, COL_WHITE);
} }
}
y += sectionLineHeight; y += sectionLineHeight;
maxScrollOffset += sectionLineHeight; maxScrollOffset += sectionLineHeight;
if (section.options == null) { if (section.options == null) {
@ -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;
if (!lastBigSectionMatches) {
section.filtered = true; 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;
} }
} }