Kinectic Scrolling

for SongNodes, Scores, Download Results, Download Info
This commit is contained in:
fd
2015-07-01 19:45:13 -04:00
parent 495a7e7f8b
commit 0562c66531
6 changed files with 482 additions and 207 deletions

View File

@@ -36,6 +36,7 @@ import itdelatrisu.opsu.downloads.servers.BloodcatServer;
import itdelatrisu.opsu.downloads.servers.DownloadServer;
import itdelatrisu.opsu.downloads.servers.HexideServer;
import itdelatrisu.opsu.downloads.servers.OsuMirrorServer;
import itdelatrisu.opsu.ui.KinecticScrolling;
import itdelatrisu.opsu.ui.MenuButton;
import itdelatrisu.opsu.ui.UI;
@@ -89,7 +90,7 @@ public class DownloadsMenu extends BasicGameState {
private int focusTimer = 0;
/** Current start result button (topmost entry). */
private int startResult = 0;
KinecticScrolling startResultPos = new KinecticScrolling();
/** Total number of results for current query. */
private int totalResults = 0;
@@ -110,7 +111,7 @@ public class DownloadsMenu extends BasicGameState {
private boolean rankedOnly = true;
/** Current start download index. */
private int startDownloadIndex = 0;
KinecticScrolling startDownloadIndexPos = new KinecticScrolling();
/** Query thread. */
private Thread queryThread;
@@ -272,18 +273,24 @@ public class DownloadsMenu extends BasicGameState {
if (nodes != null) {
DownloadNode.clipToResultArea(g);
int maxResultsShown = DownloadNode.maxResultsShown();
for (int i = 0; i < maxResultsShown; i++) {
int startResult = (int) (startResultPos.getPosition() / DownloadNode.getButtonOffset());
int offset = (int) (-startResultPos.getPosition() + startResult * DownloadNode.getButtonOffset());
for (int i = 0; i < maxResultsShown + 1; i++) {
int index = startResult + i;
if(index < 0)
continue;
if (index >= nodes.length)
break;
nodes[index].drawResult(g, i, DownloadNode.resultContains(mouseX, mouseY, i),
nodes[index].drawResult(g, offset + i * DownloadNode.getButtonOffset(),
DownloadNode.resultContains(mouseX, mouseY - offset, i),
(index == focusResult), (previewID == nodes[index].getID()));
}
g.clearClip();
// scroll bar
if (nodes.length > maxResultsShown)
DownloadNode.drawResultScrollbar(g, startResult, nodes.length);
DownloadNode.drawResultScrollbar(g, startResultPos.getPosition(), nodes.length * DownloadNode.getButtonOffset());
// pages
if (nodes.length > 0) {
@@ -311,19 +318,26 @@ public class DownloadsMenu extends BasicGameState {
int downloadsSize = DownloadList.get().size();
if (downloadsSize > 0) {
int maxDownloadsShown = DownloadNode.maxDownloadsShown();
for (int i = 0; i < maxDownloadsShown; i++) {
int index = startDownloadIndex + i;
if (index >= downloadsSize)
break;
DownloadNode node = DownloadList.get().getNode(index);
if (node == null)
break;
node.drawDownload(g, i, index, DownloadNode.downloadContains(mouseX, mouseY, i));
}
int startDownloadIndex = (int) (startDownloadIndexPos.getPosition() / DownloadNode.getInfoHeight());
int offset = (int) (-startDownloadIndexPos.getPosition() + startDownloadIndex * DownloadNode.getInfoHeight());
DownloadNode.clipToDownloadArea(g);
for (int i = 0; i < maxDownloadsShown + 1; i++) {
int index = startDownloadIndex + i;
if (index >= downloadsSize)
break;
DownloadNode node = DownloadList.get().getNode(index);
if (node == null)
break;
node.drawDownload(g, i * DownloadNode.getInfoHeight() + offset, index,
DownloadNode.downloadContains(mouseX, mouseY - offset, i));
}
g.clearClip();
// scroll bar
if (downloadsSize > maxDownloadsShown)
DownloadNode.drawDownloadScrollbar(g, startDownloadIndex, downloadsSize);
DownloadNode.drawDownloadScrollbar(g, startDownloadIndexPos.getPosition(), downloadsSize * DownloadNode.getInfoHeight());
}
// buttons
@@ -367,6 +381,13 @@ public class DownloadsMenu extends BasicGameState {
rankedButton.hoverUpdate(delta, mouseX, mouseY);
serverButton.hoverUpdate(delta, mouseX, mouseY);
if (DownloadList.get() != null)
startDownloadIndexPos.setMinMax(0, DownloadNode.getInfoHeight() * (DownloadList.get().size() - DownloadNode.maxDownloadsShown()));
startDownloadIndexPos.update(delta);
if (resultList != null)
startResultPos.setMinMax(0, DownloadNode.getButtonOffset() * (resultList.length - DownloadNode.maxResultsShown()));
startResultPos.update(delta);
// focus timer
if (focusResult != -1 && focusTimer < FOCUS_DELAY)
focusTimer += delta;
@@ -423,7 +444,7 @@ public class DownloadsMenu extends BasicGameState {
resultList = nodes;
totalResults = server.totalResults();
focusResult = -1;
startResult = 0;
startResultPos.setPosition(0);
if (nodes == null)
searchResultString = "An error has occurred.";
else {
@@ -482,19 +503,23 @@ public class DownloadsMenu extends BasicGameState {
DownloadNode[] nodes = resultList;
if (nodes != null) {
if (DownloadNode.resultAreaContains(x, y)) {
startResultPos.pressed();
int maxResultsShown = DownloadNode.maxResultsShown();
for (int i = 0; i < maxResultsShown; i++) {
for (int i = 0; i < maxResultsShown + 1; i++) {
int startResult = (int) (startResultPos.getPosition() / DownloadNode.getButtonOffset());
int offset = (int) (-startResultPos.getPosition() + startResult * DownloadNode.getButtonOffset());
int index = startResult + i;
if (index >= nodes.length)
break;
if (DownloadNode.resultContains(x, y, i)) {
if (DownloadNode.resultContains(x, y - offset, i)) {
final DownloadNode node = nodes[index];
// check if map is already loaded
boolean isLoaded = BeatmapSetList.get().containsBeatmapSetID(node.getID());
// track preview
if (DownloadNode.resultIconContains(x, y, i)) {
if (DownloadNode.resultIconContains(x, y - offset, i)) {
// set focus
if (!isLoaded) {
SoundController.playSound(SoundEffect.MENUCLICK);
@@ -659,7 +684,7 @@ public class DownloadsMenu extends BasicGameState {
if (serverButton.contains(x, y)) {
SoundController.playSound(SoundEffect.MENUCLICK);
resultList = null;
startResult = 0;
startResultPos.setPosition(0);
focusResult = -1;
totalResults = 0;
page = 0;
@@ -675,12 +700,15 @@ public class DownloadsMenu extends BasicGameState {
// downloads
if (!DownloadList.get().isEmpty() && DownloadNode.downloadAreaContains(x, y)) {
startDownloadIndexPos.pressed();
int maxDownloadsShown = DownloadNode.maxDownloadsShown();
for (int i = 0, n = DownloadList.get().size(); i < maxDownloadsShown; i++) {
int startDownloadIndex = (int) (startDownloadIndexPos.getPosition() / DownloadNode.getInfoHeight());
int offset = (int) (-startDownloadIndexPos.getPosition() + startDownloadIndex * DownloadNode.getInfoHeight());
for (int i = 0, n = DownloadList.get().size(); i < maxDownloadsShown + 1; i++) {
int index = startDownloadIndex + i;
if (index >= n)
break;
if (DownloadNode.downloadIconContains(x, y, i)) {
if (DownloadNode.downloadIconContains(x, y - offset, i)) {
SoundController.playSound(SoundEffect.MENUCLICK);
DownloadNode node = DownloadList.get().getNode(index);
if (node == null)
@@ -704,6 +732,12 @@ public class DownloadsMenu extends BasicGameState {
}
}
@Override
public void mouseReleased(int button, int x, int y) {
startDownloadIndexPos.release();
startResultPos.release();
}
@Override
public void mouseWheelMoved(int newValue) {
// change volume
@@ -735,8 +769,8 @@ public class DownloadsMenu extends BasicGameState {
int diff = newy - oldy;
if (diff == 0)
return;
int shift = (diff < 0) ? 1 : -1;
scrollLists(oldx, oldy, shift);
startDownloadIndexPos.dragged(-diff);
startResultPos.dragged(-diff);
}
@Override
@@ -805,8 +839,8 @@ public class DownloadsMenu extends BasicGameState {
rankedButton.resetHover();
serverButton.resetHover();
focusResult = -1;
startResult = 0;
startDownloadIndex = 0;
startResultPos.setPosition(0);
startDownloadIndexPos.setPosition(0);
pageDir = Page.RESET;
previewID = -1;
if (barNotificationOnLoad != null) {
@@ -846,21 +880,12 @@ public class DownloadsMenu extends BasicGameState {
private void scrollLists(int cx, int cy, int shift) {
// search results
if (DownloadNode.resultAreaContains(cx, cy)) {
DownloadNode[] nodes = resultList;
if (nodes != null && nodes.length >= DownloadNode.maxResultsShown()) {
int newStartResult = startResult + shift;
if (newStartResult >= 0 && newStartResult + DownloadNode.maxResultsShown() <= nodes.length)
startResult = newStartResult;
}
startResultPos.scrollOffset(shift * DownloadNode.getButtonOffset());
}
// downloads
else if (DownloadNode.downloadAreaContains(cx, cy)) {
if (DownloadList.get().size() >= DownloadNode.maxDownloadsShown()) {
int newStartDownloadIndex = startDownloadIndex + shift;
if (newStartDownloadIndex >= 0 && newStartDownloadIndex + DownloadNode.maxDownloadsShown() <= DownloadList.get().size())
startDownloadIndex = newStartDownloadIndex;
}
startDownloadIndexPos.scrollOffset(shift * DownloadNode.getInfoHeight());
}
}

View File

@@ -39,6 +39,7 @@ import itdelatrisu.opsu.beatmap.BeatmapSortOrder;
import itdelatrisu.opsu.db.BeatmapDB;
import itdelatrisu.opsu.db.ScoreDB;
import itdelatrisu.opsu.states.ButtonMenu.MenuState;
import itdelatrisu.opsu.ui.KinecticScrolling;
import itdelatrisu.opsu.ui.MenuButton;
import itdelatrisu.opsu.ui.UI;
@@ -123,6 +124,12 @@ public class SongMenu extends BasicGameState {
/** Current start node (topmost menu entry). */
private BeatmapSetNode startNode;
/** The first node is about this high above the header. */
KinecticScrolling songScrolling = new KinecticScrolling();
/** The number of Nodes to offset from the top to the startNode. */
private int startNodeOffset;
/** Current focused (selected) node. */
private BeatmapSetNode focusNode;
@@ -142,7 +149,7 @@ public class SongMenu extends BasicGameState {
private float hoverOffset = 0f;
/** Current index of hovered song button. */
private int hoverIndex = -1;
private BeatmapSetNode hoverIndex = null;
/** The selection buttons. */
private MenuButton selectModsButton, selectRandomButton, selectMapOptionsButton, selectOptionsButton;
@@ -190,8 +197,9 @@ public class SongMenu extends BasicGameState {
private ScoreData[] focusScores;
/** Current start score (topmost score entry). */
private int startScore = 0;
KinecticScrolling startScorePos = new KinecticScrolling();
/** Header and footer end and start y coordinates, respectively. */
private float headerY, footerY;
@@ -239,7 +247,7 @@ public class SongMenu extends BasicGameState {
// song button coordinates
buttonX = width * 0.6f;
buttonY = headerY;
//buttonY = headerY;
buttonWidth = menuBackground.getWidth();
buttonHeight = menuBackground.getHeight();
buttonOffset = (footerY - headerY - DIVIDER_LINE_WIDTH) / MAX_SONG_BUTTONS;
@@ -299,21 +307,61 @@ public class SongMenu extends BasicGameState {
// song buttons
BeatmapSetNode node = startNode;
int songButtonIndex = 0;
if (node != null && node.prev != null) {
node = node.prev;
songButtonIndex = -1;
}
g.setClip(0, (int) (headerY + DIVIDER_LINE_WIDTH / 2), width, (int) (footerY - headerY));
for (int i = songButtonIndex; i <= MAX_SONG_BUTTONS && node != null; i++, node = node.next) {
for (int i = startNodeOffset; i < MAX_SONG_BUTTONS + 1 && node != null; i++, node = node.next) {
// draw the node
float offset = (i == hoverIndex) ? hoverOffset : 0f;
float offset = (node == hoverIndex) ? hoverOffset : 0f;
float ypos = buttonY + (i*buttonOffset) ;
float mid = height/2 - ypos - buttonOffset/2;
final float circleRadi = 1000 * GameImage.getUIscale();
//finds points along a very large circle
// x^2 = h^2 - y^2
float t = circleRadi*circleRadi - (mid*mid);
float xpos = (float)(t>0?Math.sqrt(t):0) - circleRadi + 50 * GameImage.getUIscale();
ScoreData[] scores = getScoreDataForNode(node, false);
node.draw(buttonX - offset, buttonY + (i*buttonOffset) + DIVIDER_LINE_WIDTH / 2,
node.draw(buttonX - offset - xpos, ypos,
(scores == null) ? Grade.NULL : scores[0].getGrade(), (node == focusNode));
}
g.clearClip();
// scroll bar
if (focusNode != null && startNode != null) {
int focusNodes = focusNode.getBeatmapSet().size();
int totalNodes = BeatmapSetList.get().size() + focusNodes - 1;
if (totalNodes > MAX_SONG_BUTTONS) {
UI.drawScrollbar(g,
songScrolling.getPosition(),
totalNodes * buttonOffset,
MAX_SONG_BUTTONS * buttonOffset,
width, headerY + DIVIDER_LINE_WIDTH / 2,
0, MAX_SONG_BUTTONS * buttonOffset,
Utils.COLOR_BLACK_ALPHA, Color.white, true);
}
}
// score buttons
if (focusScores != null) {
ScoreData.clipToDownloadArea(g);
int startScore = (int) (startScorePos.getPosition() / ScoreData.getButtonOffset());
int offset = (int) (-startScorePos.getPosition() + startScore * ScoreData.getButtonOffset());
for (int i = 0; i < MAX_SCORE_BUTTONS + 1; i++) {
int rank = startScore + i;
if (rank < 0)
continue;
if (rank >= focusScores.length)
break;
long prevScore = (rank + 1 < focusScores.length) ? focusScores[rank + 1].score : -1;
focusScores[rank].draw(g, offset + i*ScoreData.getButtonOffset(), rank, prevScore, ScoreData.buttonContains(mouseX, mouseY-offset, i));
}
g.clearClip();
// scroll bar
if (focusScores.length > MAX_SCORE_BUTTONS && ScoreData.areaContains(mouseX, mouseY))
ScoreData.drawScrollbar(g, startScorePos.getPosition() , focusScores.length * ScoreData.getButtonOffset());
}
// top/bottom bars
g.setColor(Utils.COLOR_BLACK_ALPHA);
g.fillRect(0, 0, width, headerY);
@@ -362,21 +410,6 @@ public class SongMenu extends BasicGameState {
Utils.FONT_SMALL.drawString(marginX, headerTextY, songInfo[4], color4);
}
// score buttons
if (focusScores != null) {
for (int i = 0; i < MAX_SCORE_BUTTONS; i++) {
int rank = startScore + i;
if (rank >= focusScores.length)
break;
long prevScore = (rank + 1 < focusScores.length) ? focusScores[rank + 1].score : -1;
focusScores[rank].draw(g, i, rank, prevScore, ScoreData.buttonContains(mouseX, mouseY, i));
}
// scroll bar
if (focusScores.length > MAX_SCORE_BUTTONS && ScoreData.areaContains(mouseX, mouseY))
ScoreData.drawScrollbar(g, startScore, focusScores.length);
}
// selection buttons
GameImage.SELECTION_MODS.getImage().drawCentered(selectModsButton.getX(), selectModsButton.getY());
selectModsButton.draw();
@@ -435,22 +468,6 @@ public class SongMenu extends BasicGameState {
(searchResultString == null) ? "Searching..." : searchResultString, Color.white);
}
// scroll bar
if (focusNode != null) {
int focusNodes = focusNode.getBeatmapSet().size();
int totalNodes = BeatmapSetList.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.beatmapIndex;
UI.drawScrollbar(g, startIndex, totalNodes, MAX_SONG_BUTTONS,
width, headerY + DIVIDER_LINE_WIDTH / 2, 0, buttonOffset - DIVIDER_LINE_WIDTH * 1.5f, buttonOffset,
Utils.COLOR_BLACK_ALPHA, Color.white, true);
}
}
// reloading beatmaps
if (reloadThread != null) {
// darken the screen
@@ -540,34 +557,30 @@ public class SongMenu extends BasicGameState {
searchTransitionTimer = SEARCH_TRANSITION_TIME;
}
// slide buttons
int height = container.getHeight();
if (buttonY > headerY) {
buttonY -= height * delta / 20000f;
if (buttonY < headerY)
buttonY = headerY;
} else if (buttonY < headerY) {
buttonY += height * delta / 20000f;
if (buttonY > headerY)
buttonY = headerY;
// Scores
if (focusScores != null) {
startScorePos.setMinMax(0, (focusScores.length - MAX_SCORE_BUTTONS) * ScoreData.getButtonOffset());
startScorePos.update(delta);
}
// mouse hover
songScrolling.update(delta);
updateDrawnSongPos();
boolean isHover = false;
if (mouseY > headerY && mouseY < footerY) {
BeatmapSetNode node = startNode;
for (int i = 0; i < MAX_SONG_BUTTONS && node != null; i++, node = node.next) {
for (int i = 0; i < MAX_SONG_BUTTONS + 1 && node != null; i++, node = node.next) {
float cx = (node.index == BeatmapSetList.get().getExpandedIndex()) ? buttonX * 0.9f : buttonX;
if ((mouseX > cx && mouseX < cx + buttonWidth) &&
(mouseY > buttonY + (i * buttonOffset) && mouseY < buttonY + (i * buttonOffset) + buttonHeight)) {
if (i == hoverIndex) {
if (node == hoverIndex) {
if (hoverOffset < MAX_HOVER_OFFSET) {
hoverOffset += delta / 3f;
if (hoverOffset > MAX_HOVER_OFFSET)
hoverOffset = MAX_HOVER_OFFSET;
}
} else {
hoverIndex = i;
hoverIndex = node ;
hoverOffset = 0f;
}
isHover = true;
@@ -577,17 +590,21 @@ public class SongMenu extends BasicGameState {
}
if (!isHover) {
hoverOffset = 0f;
hoverIndex = -1;
hoverIndex = null;
} else
return;
// tooltips
if (focusScores != null) {
int startScore = (int) (startScorePos.getPosition() / ScoreData.getButtonOffset());
int offset = (int) (-startScorePos.getPosition() + startScore * ScoreData.getButtonOffset());
for (int i = 0; i < MAX_SCORE_BUTTONS; i++) {
int rank = startScore + i;
if (rank < 0)
continue;
if (rank >= focusScores.length)
break;
if (ScoreData.buttonContains(mouseX, mouseY, i)) {
if (ScoreData.buttonContains(mouseX, mouseY - offset, i)) {
UI.updateTooltip(delta, focusScores[rank].getTooltipString(), true);
break;
}
@@ -600,6 +617,18 @@ public class SongMenu extends BasicGameState {
@Override
public void mousePressed(int button, int x, int y) {
songScrolling.pressed();
startScorePos.pressed();
}
@Override
public void mouseReleased(int button, int x, int y) {
songScrolling.release();
startScorePos.release();
}
@Override
public void mouseClicked(int button, int x, int y, int clickCount) {
// check mouse button
if (button == Input.MOUSE_MIDDLE_BUTTON)
return;
@@ -655,13 +684,13 @@ public class SongMenu extends BasicGameState {
if (y > headerY && y < footerY) {
int expandedIndex = BeatmapSetList.get().getExpandedIndex();
BeatmapSetNode node = startNode;
for (int i = 0; i < MAX_SONG_BUTTONS && node != null; i++, node = node.next) {
for (int i = startNodeOffset; i < MAX_SONG_BUTTONS + 1 && node != null; i++, node = node.next) {
// is button at this index clicked?
float cx = (node.index == expandedIndex) ? buttonX * 0.9f : buttonX;
if ((x > cx && x < cx + buttonWidth) &&
(y > buttonY + (i * buttonOffset) && y < buttonY + (i * buttonOffset) + buttonHeight)) {
float oldHoverOffset = hoverOffset;
int oldHoverIndex = hoverIndex;
BeatmapSetNode oldHoverIndex = hoverIndex;
// clicked node is already expanded
if (node.index == expandedIndex) {
@@ -699,11 +728,13 @@ public class SongMenu extends BasicGameState {
// score buttons
if (focusScores != null && ScoreData.areaContains(x, y)) {
for (int i = 0; i < MAX_SCORE_BUTTONS; i++) {
for (int i = 0; i < MAX_SCORE_BUTTONS + 1; i++) {
int startScore = (int) (startScorePos.getPosition() / ScoreData.getButtonOffset());
int offset = (int) (-startScorePos.getPosition() + startScore * ScoreData.getButtonOffset());
int rank = startScore + i;
if (rank >= focusScores.length)
break;
if (ScoreData.buttonContains(x, y, i)) {
if (ScoreData.buttonContains(x, y - offset, i)) {
SoundController.playSound(SoundEffect.MENUHIT);
if (button != Input.MOUSE_RIGHT_BUTTON) {
// view score
@@ -821,7 +852,7 @@ public class SongMenu extends BasicGameState {
SoundController.playSound(SoundEffect.MENUCLICK);
BeatmapSetNode oldStartNode = startNode;
float oldHoverOffset = hoverOffset;
int oldHoverIndex = hoverIndex;
BeatmapSetNode oldHoverIndex = hoverIndex;
setFocus(next, 0, false, true);
if (startNode == oldStartNode) {
hoverOffset = oldHoverOffset;
@@ -837,7 +868,7 @@ public class SongMenu extends BasicGameState {
SoundController.playSound(SoundEffect.MENUCLICK);
BeatmapSetNode oldStartNode = startNode;
float oldHoverOffset = hoverOffset;
int oldHoverIndex = hoverIndex;
BeatmapSetNode oldHoverIndex = hoverIndex;
setFocus(prev, (prev.index == focusNode.index) ? 0 : prev.getBeatmapSet().size() - 1, false, true);
if (startNode == oldStartNode) {
hoverOffset = oldHoverOffset;
@@ -879,12 +910,11 @@ public class SongMenu extends BasicGameState {
int diff = newy - oldy;
if (diff == 0)
return;
int shift = (diff < 0) ? 1 : -1;
// check mouse button (right click scrolls faster on songs)
int multiplier;
if (input.isMouseButtonDown(Input.MOUSE_RIGHT_BUTTON))
multiplier = 4;
multiplier = 10;
else if (input.isMouseButtonDown(Input.MOUSE_LEFT_BUTTON))
multiplier = 1;
else
@@ -892,14 +922,13 @@ public class SongMenu extends BasicGameState {
// score buttons
if (focusScores != null && focusScores.length >= MAX_SCORE_BUTTONS && ScoreData.areaContains(oldx, oldy)) {
int newStartScore = startScore + shift;
if (newStartScore >= 0 && newStartScore + MAX_SCORE_BUTTONS <= focusScores.length)
startScore = newStartScore;
startScorePos.dragged(-diff * multiplier);
}
// song buttons
else
changeIndex(shift * multiplier);
songScrolling.dragged(-diff * multiplier);
}
@Override
@@ -919,9 +948,7 @@ public class SongMenu extends BasicGameState {
// score buttons
if (focusScores != null && focusScores.length >= MAX_SCORE_BUTTONS && ScoreData.areaContains(mouseX, mouseY)) {
int newStartScore = startScore + shift;
if (newStartScore >= 0 && newStartScore + MAX_SCORE_BUTTONS <= focusScores.length)
startScore = newStartScore;
startScorePos.scrollOffset(ScoreData.getButtonOffset() * shift);
}
// song buttons
@@ -939,8 +966,8 @@ public class SongMenu extends BasicGameState {
selectMapOptionsButton.resetHover();
selectOptionsButton.resetHover();
hoverOffset = 0f;
hoverIndex = -1;
startScore = 0;
hoverIndex = null;
startScorePos.setPosition(0);
beatmapMenuTimer = -1;
searchTransitionTimer = SEARCH_TRANSITION_TIME;
songInfo = null;
@@ -1008,7 +1035,7 @@ public class SongMenu extends BasicGameState {
ScoreDB.deleteScore(stateActionScore);
scoreMap = ScoreDB.getMapSetScores(focusNode.getBeatmapSet().get(focusNode.beatmapIndex));
focusScores = getScoreDataForNode(focusNode, true);
startScore = 0;
startScorePos.setPosition(0);
break;
case BEATMAP_DELETE_CONFIRM: // delete song group
if (stateActionNode == null)
@@ -1077,7 +1104,7 @@ public class SongMenu extends BasicGameState {
randomStack = new Stack<SongNode>();
songInfo = null;
hoverOffset = 0f;
hoverIndex = -1;
hoverIndex = null;
search.setText("");
searchTimer = SEARCH_DELAY;
searchTransitionTimer = SEARCH_TRANSITION_TIME;
@@ -1131,38 +1158,46 @@ public class SongMenu extends BasicGameState {
if (shift == 0)
return;
int n = shift;
boolean shifted = false;
while (n != 0) {
if (startNode == null)
break;
int height = container.getHeight();
if (n < 0 && startNode.prev != null) {
startNode = startNode.prev;
buttonY += buttonOffset / 4;
if (buttonY > headerY + height * 0.02f)
buttonY = headerY + height * 0.02f;
n++;
shifted = true;
} else if (n > 0 && startNode.next != null &&
BeatmapSetList.get().getNode(startNode, MAX_SONG_BUTTONS) != null) {
startNode = startNode.next;
buttonY -= buttonOffset / 4;
if (buttonY < headerY - height * 0.02f)
buttonY = headerY - height * 0.02f;
n--;
shifted = true;
} else
break;
}
if (shifted) {
hoverOffset = 0f;
hoverIndex = -1;
}
return;
songScrolling.scrollOffset(shift * buttonOffset);
}
/**
* Updates the song list data required for drawing.
*/
private void updateDrawnSongPos() {
float songNodePosDrawn = songScrolling.getPosition();
int startNodeIndex = (int) (songNodePosDrawn / buttonOffset);
buttonY = -songNodePosDrawn + buttonOffset * startNodeIndex + headerY - DIVIDER_LINE_WIDTH;
float max = (BeatmapSetList.get().size() + (focusNode != null ? focusNode.getBeatmapSet().size() : 0));
songScrolling.setMinMax(0 - buttonOffset * 3, (max - MAX_SONG_BUTTONS- 1 + 3) * buttonOffset);
//negative startNodeIndex means the first Node is below the header so offset it.
if (startNodeIndex <= 0) {
startNodeOffset = -startNodeIndex;
startNodeIndex = 0;
} else {
startNodeOffset = 0;
}
// Finds the start node with the expanded focus node in mind.
if (focusNode != null && startNodeIndex >= focusNode.index) {
//below the focus node.
if (startNodeIndex <= focusNode.index + focusNode.getBeatmapSet().size()) {
//inside the focus nodes expanded nodes.
int nodeIndex = startNodeIndex - focusNode.index;
startNode = BeatmapSetList.get().getBaseNode(focusNode.index);
startNode = startNode.next;
for (int i = 0; i < nodeIndex; i++)
startNode = startNode.next;
} else {
startNodeIndex -= focusNode.getBeatmapSet().size() - 1;
startNode = BeatmapSetList.get().getBaseNode(startNodeIndex);
}
} else
startNode = BeatmapSetList.get().getBaseNode(startNodeIndex);
}
/**
* Sets a new focus node.
* @param node the base node; it will be expanded if it isn't already
@@ -1176,7 +1211,7 @@ public class SongMenu extends BasicGameState {
return null;
hoverOffset = 0f;
hoverIndex = -1;
hoverIndex = null;
songInfo = null;
BeatmapSetNode oldFocus = focusNode;
@@ -1184,10 +1219,6 @@ public class SongMenu extends BasicGameState {
int expandedIndex = BeatmapSetList.get().getExpandedIndex();
if (node.index != expandedIndex) {
node = BeatmapSetList.get().expand(node.index);
// if start node was previously expanded, move it
if (startNode != null && startNode.index == expandedIndex)
startNode = BeatmapSetList.get().getBaseNode(startNode.index);
}
// check beatmapIndex bounds
@@ -1195,9 +1226,6 @@ public class SongMenu extends BasicGameState {
if (beatmapIndex < 0 || beatmapIndex > length - 1) // set a random index
beatmapIndex = (int) (Math.random() * length);
// change the focus node
if (changeStartNode || (startNode.index == 0 && startNode.beatmapIndex == -1 && startNode.prev == null))
startNode = node;
focusNode = BeatmapSetList.get().getNode(node, beatmapIndex);
Beatmap beatmap = focusNode.getBeatmapSet().get(focusNode.beatmapIndex);
MusicController.play(beatmap, false, preview);
@@ -1205,32 +1233,59 @@ public class SongMenu extends BasicGameState {
// load scores
scoreMap = ScoreDB.getMapSetScores(beatmap);
focusScores = getScoreDataForNode(focusNode, true);
startScore = 0;
startScorePos.setPosition(0);
if (oldFocus != null && oldFocus.getBeatmapSet() != node.getBeatmapSet()){
//Close previous node
if(node.index > oldFocus.index){
float offset = (oldFocus.getBeatmapSet().size() - 1) * buttonOffset;
//updateSongPos(-offset);
songScrolling.addOffset(-offset);
}
// check startNode bounds
while (startNode.index >= BeatmapSetList.get().size() + length - MAX_SONG_BUTTONS && startNode.prev != null)
startNode = startNode.prev;
// make sure focusNode is on the screen (TODO: cleanup...)
int val = focusNode.index + focusNode.beatmapIndex - (startNode.index + MAX_SONG_BUTTONS) + 1;
if (val > 0) // below screen
changeIndex(val);
else { // above screen
if (focusNode.index == startNode.index) {
val = focusNode.index + focusNode.beatmapIndex - (startNode.index + startNode.beatmapIndex);
if (val < 0)
changeIndex(val);
} else if (startNode.index > focusNode.index) {
val = focusNode.index - focusNode.getBeatmapSet().size() + focusNode.beatmapIndex - startNode.index + 1;
if (val < 0)
changeIndex(val);
if (Math.abs(node.index - oldFocus.index) > MAX_SONG_BUTTONS) {
// open from the middle
float offset = ((node.getBeatmapSet().size() - 1) * buttonOffset) / 2f;
songScrolling.addOffset(offset);
} else if (node.index > oldFocus.index) {
// open from the bottom
float offset = (node.getBeatmapSet().size() - 1) * buttonOffset;
songScrolling.addOffset(offset);
} else {
// open from the top
}
}
// change the focus node
if (changeStartNode || (startNode.index == 0 && startNode.beatmapIndex == -1 && startNode.prev == null)){
songScrolling.setPosition((node.index - 1) * buttonOffset);
updateDrawnSongPos();
}
// if start node is expanded and on group node, move it
if (startNode.index == focusNode.index && startNode.beatmapIndex == -1)
changeIndex(1);
updateDrawnSongPos();
// make sure focusNode is on the screen
int val = focusNode.index + focusNode.beatmapIndex;
if (val <= startNode.index)
songScrolling.scrollToPosition(val * buttonOffset);
else if (val > startNode.index + MAX_SONG_BUTTONS - 1)
songScrolling.scrollToPosition((val - MAX_SONG_BUTTONS + 1) * buttonOffset);
/*
//Centers selected node
int val = focusNode.index + focusNode.beatmapIndex - MAX_SONG_BUTTONS/2;
songScrolling.scrollToPosition(val * buttonOffset);
//*/
/*
//Attempts to make all nodes in the set at least visible
if( focusNode.index * buttonOffset < songScrolling.getPosition())
songScrolling.scrollToPosition(focusNode.index * buttonOffset);
if ( ( focusNode.index + focusNode.getBeatmapSet().size() ) * buttonOffset > songScrolling.getPosition() + footerY - headerY)
songScrolling.scrollToPosition((focusNode.index + focusNode.getBeatmapSet().size() ) * buttonOffset - (footerY - headerY));
//*/
return oldFocus;
}