main menu now displays current song name; visualizer made slightly more efficient
This commit is contained in:
parent
f345e1de8c
commit
160f87b801
@ -386,3 +386,11 @@ rect-disabled
|
||||
orig: 14, 14
|
||||
offset: 0, 0
|
||||
index: -1
|
||||
side-bars
|
||||
rotate: false
|
||||
xy: 221, 35
|
||||
size: 5, 14
|
||||
split: 2, 2, 0, 0
|
||||
orig: 5, 14
|
||||
offset: 0, 0
|
||||
index: -1
|
Binary file not shown.
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
@ -47,9 +47,10 @@ public class Mp3Manager implements MusicManager {
|
||||
|
||||
private ExecutorService exec;
|
||||
|
||||
private String basicSongName;
|
||||
public Mp3Manager(FileHandle audioFile) {
|
||||
lock = new ReentrantLock();
|
||||
|
||||
this.basicSongName = audioFile.name();
|
||||
exec = Executors.newSingleThreadExecutor();
|
||||
exec.submit(() -> {
|
||||
lock.lock();
|
||||
@ -230,11 +231,23 @@ public class Mp3Manager implements MusicManager {
|
||||
|
||||
@Override
|
||||
public boolean isFinishedLoading() {
|
||||
if (lock.isHeldByCurrentThread()) {
|
||||
return true;
|
||||
} else {
|
||||
try {
|
||||
return lock.tryLock(0, TimeUnit.SECONDS);
|
||||
if (lock.tryLock(0, TimeUnit.SECONDS)) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBasicSongName() {
|
||||
return basicSongName;
|
||||
}
|
||||
}
|
||||
|
@ -74,4 +74,11 @@ public interface MusicManager extends Disposable {
|
||||
* @return whether its done loading
|
||||
*/
|
||||
public boolean isFinishedLoading();
|
||||
|
||||
/**
|
||||
* Basic song name is the name of the file of the song, meaning we do not check tags for proper song name.
|
||||
* Thats left up to the song info object.
|
||||
* @return basic song name
|
||||
*/
|
||||
public String getBasicSongName();
|
||||
}
|
||||
|
@ -32,12 +32,15 @@ public class SongInfo implements Disposable {
|
||||
|
||||
private FileHandle musicFile;
|
||||
private Preferences musicAnnotation;
|
||||
|
||||
public SongInfo(FileHandle musicFile, Preferences musicData) {
|
||||
this.musicFile = musicFile;
|
||||
this.musicAnnotation = musicData;
|
||||
}
|
||||
|
||||
/**
|
||||
* loads the information for this song.
|
||||
* should be called in non-render thread as is blocking and depends on IO speed.
|
||||
*/
|
||||
public void loadInfo() {
|
||||
if (musicFile.extension().toLowerCase().equals("mp3")) {
|
||||
MP3File mp3File;
|
||||
|
@ -30,8 +30,8 @@ public class SongListController implements OnCompletionListener {
|
||||
this.prefs = prefs;
|
||||
listeners = new Array<>();
|
||||
this.songList = songList;
|
||||
changeSong();
|
||||
rand = new Random();
|
||||
changeSong();
|
||||
}
|
||||
|
||||
public void play() {
|
||||
@ -105,7 +105,11 @@ public class SongListController implements OnCompletionListener {
|
||||
}
|
||||
|
||||
if (shuffle) {
|
||||
if (songList.getAmountOfSongs() == 0) {
|
||||
currentPlaybackID = 0;
|
||||
} else {
|
||||
currentPlaybackID = rand.nextInt(songList.getAmountOfSongs());
|
||||
}
|
||||
} else {
|
||||
if (currentPlaybackID > songList.getAmountOfSongs() -1) {
|
||||
currentPlaybackID = 0;
|
||||
|
@ -20,7 +20,9 @@ public class WAVManager implements MusicManager {
|
||||
private Music playbackMusic;
|
||||
WavDecoder decoder;
|
||||
|
||||
private String basicSongName;
|
||||
public WAVManager(FileHandle file) {
|
||||
basicSongName = file.name();
|
||||
try {
|
||||
decoder = new WavDecoder(file);
|
||||
} catch (InvalidParameterException | IOException e) {
|
||||
@ -127,4 +129,9 @@ public class WAVManager implements MusicManager {
|
||||
public boolean isFinishedLoading() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBasicSongName() {
|
||||
return basicSongName;
|
||||
}
|
||||
}
|
||||
|
@ -29,13 +29,15 @@ public class VisualizerCore implements Disposable {
|
||||
public void calculate() {
|
||||
if (mm != null) {
|
||||
mm.playbackIndexUpdate();
|
||||
while (calc && mm.isPlaying() && mm.getPlaybackIndexPosition() > mm.getCurrentReadWindowIndex()) {
|
||||
lock.lock();
|
||||
while (calc && mm.isPlaying() && mm.getPlaybackIndexPosition() > mm.getCurrentReadWindowIndex()) {
|
||||
mm.readSamples(audioPCM);
|
||||
if (mm.getPlaybackIndexPosition() == mm.getCurrentReadWindowIndex()) {
|
||||
fft.realForward(audioPCM);
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
lock.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
public void setMM(MusicManager mm) {
|
||||
@ -90,4 +92,7 @@ public class VisualizerCore implements Disposable {
|
||||
return height;
|
||||
}
|
||||
|
||||
public MusicManager getMm() {
|
||||
return mm;
|
||||
}
|
||||
}
|
||||
|
@ -98,6 +98,7 @@ public class MusicControls extends HorizontalGroup {
|
||||
if (disableTimer <= 0) {
|
||||
forward.setDisabled(false);
|
||||
reverse.setDisabled(false);
|
||||
disableTimer = 0;
|
||||
}
|
||||
}
|
||||
super.act(delta);
|
||||
|
@ -41,7 +41,7 @@ public class MusicSelectable extends Widget implements Disposable {
|
||||
imageIcon = new Image(albumCover);
|
||||
table.add(imageIcon);
|
||||
|
||||
displayName = new ScrollText(musicFile.name(), skin, true);
|
||||
displayName = new ScrollText(musicFile.name(), null, skin, true, false);
|
||||
table.add(displayName);
|
||||
|
||||
table.row();
|
||||
@ -54,6 +54,10 @@ public class MusicSelectable extends Widget implements Disposable {
|
||||
table.defaults().pad(10f);
|
||||
}
|
||||
|
||||
/**
|
||||
* updates the UI side of information.
|
||||
* needs to be called in thread with gl context.
|
||||
*/
|
||||
public void updateInfo() {
|
||||
durationLabel.setText("Runtime: "
|
||||
+ ((songInfo.getDurationInSeconds() / 60 < 1) ? "00" : songInfo.getDurationInSeconds() / 60) + ":"
|
||||
|
@ -1,9 +1,11 @@
|
||||
package zero1hd.rhythmbullet.graphics.ui.components;
|
||||
|
||||
import com.badlogic.gdx.Gdx;
|
||||
import com.badlogic.gdx.graphics.Color;
|
||||
import com.badlogic.gdx.graphics.g2d.Batch;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.GlyphLayout;
|
||||
import com.badlogic.gdx.graphics.g2d.NinePatch;
|
||||
import com.badlogic.gdx.math.Rectangle;
|
||||
import com.badlogic.gdx.math.Vector2;
|
||||
import com.badlogic.gdx.scenes.scene2d.Actor;
|
||||
@ -18,63 +20,46 @@ public class ScrollText extends Widget {
|
||||
Rectangle clipBounds = new Rectangle();
|
||||
|
||||
GlyphLayout gLayout;
|
||||
String text;
|
||||
String text1;
|
||||
String text2;
|
||||
BitmapFont font;
|
||||
private float fontHeight;
|
||||
private float fontWidth;
|
||||
private float textHeight;
|
||||
private float text1Width;
|
||||
private float text2Width;
|
||||
|
||||
private boolean scrollOnHover;
|
||||
private boolean scroll;
|
||||
|
||||
private float textOffset;
|
||||
private float text1Offset, text2Offset;
|
||||
|
||||
private NinePatch background;
|
||||
|
||||
private Vector2 coords;
|
||||
public ScrollText(String text, Skin skin, boolean scrollOnHover) {
|
||||
public ScrollText(String text, String text2, Skin skin, boolean scrollOnHover, boolean useBackground) {
|
||||
super();
|
||||
setName(text);
|
||||
this.scrollOnHover = scrollOnHover;
|
||||
|
||||
this.text = text;
|
||||
font = skin.getFont("default-font");
|
||||
font.setColor(skin.getColor("default"));
|
||||
gLayout = new GlyphLayout(font, text);
|
||||
|
||||
fontHeight = gLayout.height;
|
||||
fontWidth = gLayout.width;
|
||||
|
||||
coords = new Vector2();
|
||||
|
||||
addListener(new ClickListener() {
|
||||
@Override
|
||||
public void enter(InputEvent event, float x, float y, int pointer, Actor fromActor) {
|
||||
scroll = true;
|
||||
super.enter(event, x, y, pointer, fromActor);
|
||||
init(text, text2, skin, scrollOnHover, useBackground);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exit(InputEvent event, float x, float y, int pointer, Actor toActor) {
|
||||
scroll = false;
|
||||
super.exit(event, x, y, pointer, toActor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clicked(InputEvent event, float x, float y) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public ScrollText(String text, Skin skin, String fontName, Color color, boolean scrollOnHover) {
|
||||
public ScrollText(String text, String text2, Skin skin, String fontName, Color color, boolean scrollOnHover, boolean useBackground) {
|
||||
super();
|
||||
setName(text);
|
||||
this.scrollOnHover = scrollOnHover;
|
||||
|
||||
this.text = text;
|
||||
font = skin.getFont(fontName);
|
||||
font.setColor(color);
|
||||
gLayout = new GlyphLayout(font, text);
|
||||
init(text, text2, skin, scrollOnHover, useBackground);
|
||||
}
|
||||
|
||||
fontHeight = gLayout.height;
|
||||
fontWidth = gLayout.width;
|
||||
private void init(String text1, String text2, Skin skin, boolean scrollOnHover, boolean useBackground) {
|
||||
setName(text1);
|
||||
if (useBackground) {
|
||||
this.background = skin.getPatch("side-bars");
|
||||
}
|
||||
|
||||
this.scrollOnHover = scrollOnHover;
|
||||
|
||||
if (text1 == null) {
|
||||
text1 = "";
|
||||
}
|
||||
setText(text1, text2);
|
||||
|
||||
coords = new Vector2();
|
||||
|
||||
@ -98,55 +83,74 @@ public class ScrollText extends Widget {
|
||||
}
|
||||
|
||||
public float getFontHeight() {
|
||||
return fontHeight;
|
||||
return textHeight;
|
||||
}
|
||||
|
||||
public float getFontWidth() {
|
||||
return fontWidth;
|
||||
return text1Width;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void layout() {
|
||||
setHeight(fontHeight+4);
|
||||
clipBounds.setSize(getWidth(), getHeight()*1.5f);
|
||||
if (getHeight() < (textHeight+4)) {
|
||||
setHeight(textHeight + 4);
|
||||
}
|
||||
clipBounds.setSize(getWidth()-1, getHeight()*1.5f);
|
||||
super.layout();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
if (fontWidth > clipBounds.getWidth()) {
|
||||
validate();
|
||||
if (text1Width + text2Width > clipBounds.getWidth()) {
|
||||
if (scrollOnHover) {
|
||||
if ((int) textOffset != 0 || scroll) {
|
||||
if (textOffset < -fontWidth) {
|
||||
textOffset = clipBounds.getWidth();
|
||||
}
|
||||
textOffset -= 60*delta;
|
||||
if (scroll) {
|
||||
scroll(delta);
|
||||
}
|
||||
} else {
|
||||
if (textOffset < -fontWidth) {
|
||||
textOffset = clipBounds.getWidth();
|
||||
}
|
||||
textOffset -= 60*delta;
|
||||
scroll(delta);
|
||||
}
|
||||
}
|
||||
super.act(delta);
|
||||
}
|
||||
|
||||
public void scroll(float delta) {
|
||||
if (text1Offset >= -text1Width) {
|
||||
text1Offset -= 60*delta;
|
||||
|
||||
|
||||
if ((text1Offset < - Math.abs((text1Width - clipBounds.getWidth())) - 50) || text2Offset != clipBounds.getWidth()) {
|
||||
text2Offset -= 60*delta;
|
||||
if (text2Offset <= -text2Width) {
|
||||
text2Offset = clipBounds.getWidth();
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
text2Offset -= 60*delta;
|
||||
if (text2Offset < - Math.abs((text2Width - clipBounds.getWidth())) - 50) {
|
||||
text1Offset = clipBounds.getWidth();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void draw(Batch batch, float parentAlpha) {
|
||||
|
||||
if (background != null) {
|
||||
background.draw(batch, getX(), getY(), getWidth(), getHeight());
|
||||
}
|
||||
coords.x = getX();
|
||||
coords.y = getY();
|
||||
|
||||
clipBounds.setX(coords.x);
|
||||
clipBounds.setX(coords.x+1);
|
||||
clipBounds.setY(coords.y - 0.5f*getHeight());
|
||||
|
||||
getStage().calculateScissors(clipBounds, scissors);
|
||||
|
||||
batch.flush();
|
||||
if (ScissorStack.pushScissors(scissors)) {
|
||||
font.draw(batch, text, coords.x + textOffset, coords.y + getFontHeight());
|
||||
font.draw(batch, text1, coords.x + text1Offset, coords.y + getFontHeight() + getHeight()/4f);
|
||||
font.draw(batch, text2, coords.x + text2Offset, coords.y + getFontHeight() + getHeight()/4f);
|
||||
batch.flush();
|
||||
ScissorStack.popScissors();
|
||||
};
|
||||
@ -154,6 +158,30 @@ public class ScrollText extends Widget {
|
||||
|
||||
@Override
|
||||
public float getMinHeight() {
|
||||
return fontHeight;
|
||||
return textHeight;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the two strings that will be scrolling.
|
||||
* @param text1 cannot be null.
|
||||
* @param text2 can be null.
|
||||
*/
|
||||
public void setText(String text1, String text2) {
|
||||
this.text1 = text1;
|
||||
gLayout = new GlyphLayout(font, text1);
|
||||
text1Width = gLayout.width;
|
||||
textHeight = gLayout.height;
|
||||
text2Offset = clipBounds.getWidth();
|
||||
if (text1Width < clipBounds.getWidth()) {
|
||||
text1Offset = (clipBounds.getWidth()-text1Width)/2f;
|
||||
}
|
||||
if (text2 != null) {
|
||||
this.text2 = text2;
|
||||
gLayout = new GlyphLayout(font, text2);
|
||||
text2Width = gLayout.width;
|
||||
} else {
|
||||
this.text2 = text1;
|
||||
this.text2Width = text1Width;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,7 +33,7 @@ public class TitleBarVisualizer extends Group implements Disposable {
|
||||
public TitleBarVisualizer(AssetManager assets) {
|
||||
if (assets == null) throw new NullPointerException("TitleBarVisualizer requires assets manager... ITS NULL YOU FOOL");
|
||||
visual = new Visualizer();
|
||||
visual.getVis().setSpaceBetweenBars(visual.getVis().getBarWidth()-2);
|
||||
visual.getVis().setSpaceBetweenBars(visual.getVis().getBarWidth()- 2);
|
||||
addActor(visual);
|
||||
|
||||
setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()*0.2f);
|
||||
@ -85,11 +85,10 @@ public class TitleBarVisualizer extends Group implements Disposable {
|
||||
@Override
|
||||
public void act(float delta) {
|
||||
if (!lastEffect) {
|
||||
if (visual.getVis().getCurrentAvg() > visual.getVis().getMaxAvgHeight()*0.55f) {
|
||||
if (visual.getVis().getMm() != null && visual.getVis().getMm().isPlaying() && visual.getVis().getCurrentAvg() > visual.getVis().getMaxAvgHeight()*0.55f) {
|
||||
PooledEffect effect = beatEffectPool.obtain();
|
||||
effect.setPosition(0, 0);
|
||||
effects.add(effect);
|
||||
|
||||
lastEffect = true;
|
||||
}
|
||||
} else {
|
||||
|
@ -70,8 +70,6 @@ public class Visualizer extends Widget {
|
||||
}
|
||||
|
||||
public void setUpdatePositioning(boolean updatePositioning) {
|
||||
updateVisualPosition();
|
||||
vis.setxPos(((vis.getWidth() - vis.getActualWidth())/2f));
|
||||
updateVisualPosition();
|
||||
this.updatePositioning = updatePositioning;
|
||||
}
|
||||
@ -79,6 +77,9 @@ public class Visualizer extends Widget {
|
||||
public void updateVisualPosition() {
|
||||
setVisualizerPosProp();
|
||||
vis.updatePositionInfo();
|
||||
vis.setxPos(((vis.getWidth() - vis.getActualWidth())/2f));
|
||||
Gdx.app.debug("Visualizer", "currently offseting visualizer by (px): " + vis.getxPos());
|
||||
vis.updatePositionInfo();
|
||||
}
|
||||
|
||||
public boolean isUpdatePositioning() {
|
||||
|
@ -201,7 +201,7 @@ public class AnalyzePage extends Page implements MiniListener, Disposable {
|
||||
audioAnalyzer.sender.addListener(this);
|
||||
|
||||
|
||||
songInfo.add(new ScrollText(audioInfo.getSongName(), skin, true)).expandX().fillX().spaceBottom(20f);
|
||||
songInfo.add(new ScrollText(audioInfo.getSongName(), null, skin, true, false)).expandX().fillX().spaceBottom(20f);
|
||||
|
||||
for (int i = 0; i < info.length; i++) {
|
||||
info[i].setColor(1f, 1f, 1f, 0f);
|
||||
|
@ -15,6 +15,7 @@ import zero1hd.rhythmbullet.audio.MusicManager;
|
||||
import zero1hd.rhythmbullet.audio.SongListController;
|
||||
import zero1hd.rhythmbullet.events.OnDifferentSongListener;
|
||||
import zero1hd.rhythmbullet.graphics.ui.components.MusicControls;
|
||||
import zero1hd.rhythmbullet.graphics.ui.components.ScrollText;
|
||||
import zero1hd.rhythmbullet.graphics.ui.components.TitleBarVisualizer;
|
||||
|
||||
public class MainPage extends Page implements OnDifferentSongListener {
|
||||
@ -28,13 +29,13 @@ public class MainPage extends Page implements OnDifferentSongListener {
|
||||
private TextButton quitButton;
|
||||
|
||||
private MusicControls musicControls;
|
||||
|
||||
private ScrollText scrollText;
|
||||
public MainPage(RhythmBullet core, Vector3 targetPosition, SongListController sc) {
|
||||
this.sc = sc;
|
||||
|
||||
titleBar = new TitleBarVisualizer(core.getAssetManager());
|
||||
addActor(titleBar);
|
||||
|
||||
titleBar.getHvisual().setMM(sc.getCurrentSong());
|
||||
sc.addOnDifferentSongListener(this);
|
||||
|
||||
versionLabel = new Label("Version: " + RhythmBullet.VERSION, core.getDefaultSkin(), "sub-font",
|
||||
@ -81,7 +82,17 @@ public class MainPage extends Page implements OnDifferentSongListener {
|
||||
|
||||
musicControls = new MusicControls(core.getDefaultSkin(), sc);
|
||||
musicControls.setPosition((getWidth()-musicControls.getMinWidth() - 20f), getHeight()-musicControls.getMinHeight());
|
||||
musicControls.invalidate();
|
||||
addActor(musicControls);
|
||||
|
||||
scrollText = new ScrollText("...", "...", core.getDefaultSkin(), false, true);
|
||||
scrollText.setWidth(0.5f*getWidth());
|
||||
scrollText.setHeight(musicControls.getMinHeight());
|
||||
scrollText.setPosition((getWidth() - scrollText.getWidth())/2f, musicControls.getY() - 22f);
|
||||
scrollText.invalidate();
|
||||
addActor(scrollText);
|
||||
|
||||
onDifferentSong(sc.getCurrentSong());
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -97,6 +108,7 @@ public class MainPage extends Page implements OnDifferentSongListener {
|
||||
@Override
|
||||
public void onDifferentSong(MusicManager mdp) {
|
||||
titleBar.getHvisual().setMM(mdp);
|
||||
scrollText.setText(mdp.getBasicSongName(), null);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
Loading…
Reference in New Issue
Block a user