Niftygui progressbar and LoadingState

I’ve followed niftygui tutorial to implement a ProgressBar control, I’d like to use it as a LoadingNodeState to show progress of loading process. I’m able to set progressbar value, but I can’t see progressbar changing on screen while loading application.

How to do it?



[xml]

<?xml version=“1.0” encoding=“UTF-8”?>

<nifty xmlns=“http://nifty-gui.sourceforge.net/nifty.xsd” xmlns:xsi=“http://www.w3.org/2001/XMLSchema-instance” xsi:schemaLocation=“http://nifty-gui.sourceforge.net/nifty.xsd http://nifty-gui.sourceforge.net/nifty.xsd”>



<!-- this is our nifty little progressbar control -->

<controlDefinition name=“progressbar” controller=“it.F1Viewer3D.gui.ProgressBar”>

<image filename=“textures/progress-outer.png” imageMode=“resize:15,2,15,15,15,2,15,2,15,2,15,15” childLayout=“absolute”>

<image id=“progress” x=“0” y=“0” filename=“textures/progress-inner.png” width=“32px” height=“100%” imageMode=“resize:15,2,15,15,15,2,15,2,15,2,15,15” />

<text id=“progress-text” font=“verdana-small-regular.fnt” text="" textHAlign=“center” textVAlign=“center” width=“100%” height=“100%” x=“0” y=“0” color="#f00f" />

</image>

</controlDefinition>



<!-- a simple screen -->

<screen id=“start”>

<layer id=“layer” childLayout=“center”>

<control id=“my-progress” name=“progressbar” align=“center” valign=“center” width=“400px” height=“32px” />

</layer>

</screen>

</nifty>

[/xml]



[java]

public class ProgressBar implements Controller {

private Element progressBarElement;

private Element progressTextElement;



public void bind(

final Nifty nifty,

final Screen screenParam,

final Element element,

final Properties parameter,

final ControllerEventListener listener,

final Attributes controlDefinitionAttributes) {

progressBarElement = element.findElementByName(“progress”);

progressTextElement = element.findElementByName(“progress-text”);

}



public void onStartScreen() {

}



public void onFocus(final boolean getFocus) {

}



public boolean inputEvent(final NiftyInputEvent inputEvent) {

return false;

}



public void setProgress(final float progressValue) {

float progress = progressValue;

if (progress < 0.0f) {

progress = 0.0f;

} else if (progress > 1.0f) {

progress = 1.0f;

}

final int MIN_WIDTH = 32;

int pixelWidth = (int)(MIN_WIDTH + (progressBarElement.getParent().getWidth() - MIN_WIDTH) * progress);

progressBarElement.setConstraintWidth(new SizeValue(pixelWidth + “px”));

progressBarElement.getParent().layoutElements();



String progressText = String.format("%3.0f%%", progress * 100);

progressTextElement.getRenderer(TextRenderer.class).setText(progressText);

}





}

[/java]

[java]



private void updateGUI() {

Screen screen = nifty.getScreen(“start”);



// next we use the findControl() method of the screen to find our

// ProgressbarControl using the id “my-progress” as the reference

// and our ProgressbarControl class as the second parameter for the

// method so that we don’t need any casts.

ProgressBar progressbar = screen.findControl(“my-progress”, ProgressBar.class);



// use the setProgress() method to set the progress to 90%

progressbar.setProgress((float)(index/max));





}



[/java]

Its a bit complicated because when you initialize the application the gui is not updated – the update loop is not yet running :). So the solution would be to have a small initialization and then doing all loading etc. after the gui has been loaded without blocking the update loop. Models for example could be loaded on a separate thread (but have to be added to the scene on the OpenGL thread!!!) or you simply load a model and let a frame pass (load model in next update call).

I did it:

[java]

public void update(){

super.update();

if(!started && loading.isRunning()){

initGame();

started=true;

}



// do some animation

float tpf = timer.getTimePerFrame();



stateManager.update(tpf);

stateManager.render(renderManager);



// render the viewports

renderManager.render(tpf);

}

[/java]



I can see gui while loading, I can’t see updates on it.

On state with models to load I do:



[java]



app.enqueue(new LoadingTask(loading,

“Building model”));

app.update();



[/java]



where LoadingTask is a class:



[java]

public class LoadingTask implements Callable {

private final LoadingNodeState loading;

private String status;

private float progress=0;



public LoadingTask(LoadingNodeState loading,String status) {



this.loading = loading;

this.status=status;

}

public Void call() throws Exception {



//Thread.sleep(100);

progress=loading.setIndex(1+progress, status);

System.out.println(status+"="+progress);

if (progress>=100){

loading.setActive(false);

}

//if (loading.) {

//GameTaskQueueManager.getManager().update(new LoadingTask(loading, status));

//}

return null;

}

}

[/java]

1 Like