UIProgressBar

Hi all,

I am making VolatileZapper3, and basically, i needed a progress bar. So in ture jme style, I have made it very customisable and very easy to use IMO.



Basically, its made up of two quads. The first one is the progress bar, the second is the, what i call, "overlay". Its a little quad that sits on top with a nice little outline border to show the extents of the progress bar. Anyways, both of those textures are changable…heres the code:



UIProgressBar


/*
 * Copyright (c) 2003-2005, jMonkeyEngine - Mojo Monkey Coding All rights
 * reserved. Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer. Redistributions in binary
 * form must reproduce the above copyright notice, this list of conditions and
 * the following disclaimer in the documentation and/or other materials provided
 * with the distribution. Neither the name of the Mojo Monkey Coding, jME,
 * jMonkey Engine, nor the names of its contributors may be used to endorse or
 * promote products derived from this software without specific prior written
 * permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.volatile7.vz3.ui;

import java.net.URL;

import com.jme.image.Texture;
import com.jme.math.Vector2f;
import com.jme.math.Vector3f;
import com.jme.renderer.Renderer;
import com.jme.scene.shape.Quad;
import com.jme.scene.state.LightState;
import com.jme.scene.state.TextureState;
import com.jme.system.DisplaySystem;
import com.jme.ui.UIObject;
import com.jme.util.TextureManager;

/**
 *
 * A Progress bar for the UI library. It has a value between 0 and 100 and
 * does not feature any user interactions at all
 *
 * @author Ahmed
 * @version: $Id: UIProgressBar.java, Feb 3, 2005 8:17:07 PM
 */
public class UIProgressBar extends UIObject {
   
   // Whether the progress bar is horizontal or vertical
   public static final int VERTICAL = 0;
   public static final int HORIZONTAL = 1;
   
   // the mode it represents, like above, either horizontal or vertical
   private int mode;
   
   // the initial value of the progress bar. Its is fully on
   private int value = 100;
   
   private Vector2f bottomLeft, topLeft, topRight, bottomRight;

   /**
    *
    * Constructor for the progress bar. Most parameters from the constructor
    * are taken from the parent UIObject, but others are created here. The
    * description
    *
    * @param name the name of the progress bar
    * @param xpos the x position on screen
    * @param ypos the y position on screen
    * @param width the width of the bar
    * @param height the height of the bar
    * @param texture the texture for the progress bar that moves
    * @param texture2 the overlay texture, i.e. border
    * @param mode either horizontal or vertical
    */
   public UIProgressBar(String name,
         int xPos,
         int yPos,
         int width,
         int height,
         String barTex,
         String overlayTex,
         int mode) {
      // set a texture flag
      super(name, xPos, yPos, width, height, null, UIObject.TEXTURE);
      
      // set the mode
      this.mode = mode;
      
      // init the texture coordinates for the vertices
      bottomLeft = new Vector2f(0, 1);
      topLeft = new Vector2f(0, 0);
      topRight = new Vector2f(1, 0);
      bottomRight = new Vector2f(1, 1);
      
      // create the texture state for the actual progress bar
      URL urlToTexture = UIProgressBar.class.getClassLoader()
            .getResource(barTex);
      Texture tex = TextureManager.loadTexture(urlToTexture,
            Texture.MM_LINEAR,
            Texture.FM_LINEAR,
            false);
      // clamp the S and Ts to 0 (the slack variables)
      tex.setWrap(Texture.WM_CLAMP_S_CLAMP_T);
      
      TextureState ts = DisplaySystem.getDisplaySystem().getRenderer()
            .createTextureState();
      ts.setEnabled(true);
      ts.setTexture(tex);
      
      // add the texture states to the vector
      _textureStates.add(0, ts);
      
      // create the quad from super
      setup();
      
      // after initing the quad, turn off ALL lighting from it
      _quad.setLightCombineMode(LightState.OFF);
      _quad.setZOrder(0);
      
      // create another texture state
      URL urlToOverlay = UIProgressBar.class.getClassLoader()
            .getResource(overlayTex);
      Texture tex2 = TextureManager.loadTexture(urlToOverlay,
            Texture.MM_LINEAR,
            Texture.FM_LINEAR,
            false);
      // also clamp the slack variables
      tex2.setWrap(Texture.WM_CLAMP_S_CLAMP_T);
      
      // create another texture state and add it to the vector list
      TextureState ts2 = DisplaySystem.getDisplaySystem().getRenderer()
            .createTextureState();
      ts2.setEnabled(true);
      ts2.setTexture(tex2);
      _textureStates.add(1, ts2);

      // create the overlay quad
      Quad overlay = new Quad(name + "_overlay", _width, _height);
      overlay.setZOrder(1);
      overlay.setLightCombineMode(LightState.OFF);
      overlay.setRenderQueueMode(Renderer.QUEUE_INHERIT);
      overlay.setRenderState((TextureState)_textureStates.get(1));
      
      // move it away from its centre
      overlay.setLocalTranslation( new Vector3f( _x + (_width / 2), _y + (_height / 2), 0.0f) );
      
      // if vertical, set the overlay texture coordinates
      if (mode == VERTICAL) {
         Vector2f topLeftOverlay = new Vector2f(1, 0);
         Vector2f topRightOverlay = new Vector2f(1, 1);
         Vector2f bottomLeftOverlay = new Vector2f(0, 0);
         Vector2f bottomRightOverlay = new Vector2f(0, 1);
         
         overlay.setTextureCoord(0, 0, topRightOverlay);
         overlay.setTextureCoord(0, 1, bottomRightOverlay);
         overlay.setTextureCoord(0, 2, bottomLeftOverlay);
         overlay.setTextureCoord(0, 3, topLeftOverlay);
         overlay.updateTextureBuffer();
      }
      
      
      // attach the overlay to this
      this.attachChild(overlay);
      
      setValue(100);
   }
   
   /**
    * Sets a value for the progress bar. A value between 0 and 100 are valid only
    * whereby 0 is the minimum and 100 is the maximum.
    * @param inputValue
    */
   public void setValue(int inputValue) {
      // constrict value between 0 and 100
      if (inputValue < 0)
         inputValue = 0;
      if (inputValue > 100)
         inputValue = 100;
      
      // set the current value to the modified input value
      value = inputValue;
      
      // obtain a number between 0 and 1 for the value
      float multiplier = value / 100f;
      
      if (mode == HORIZONTAL) {
         // if the mode is horizontal, then modify vertex 3 and 4
         _quad.getVertices()[2].x = (multiplier * (_width) - (_width/2));
         _quad.getVertices()[3].x = (multiplier * (_width) - (_width/2));
      } else if (mode == VERTICAL) {
         // else if the mode is vertical, modify vertex 1 and 4
         _quad.getVertices()[0].y = (multiplier * (_height) - (_height/2));
         _quad.getVertices()[3].y = (multiplier * (_height) - (_height/2));
      }
      _quad.updateVertexBuffer();
      
      // now set the texture coordinates so that if you have a gradient
      // the gradient can be seen.      
      if (mode == HORIZONTAL) {
         topRight.x = multiplier;
         bottomRight.x = multiplier;
         _quad.setTextureCoord(0, 2, topRight);
         _quad.setTextureCoord(0, 3, bottomRight);
      } else if (mode == VERTICAL) {
         topLeft.x = multiplier;
         topLeft.y = 0;
         
         topRight.x = multiplier;
         topRight.y = 1;
         
         bottomLeft.x = 0;
         bottomLeft.y = 0;
         
         bottomRight.x = 0;
         bottomRight.y = 1;
         
         _quad.setTextureCoord(0, 0, topRight);
         _quad.setTextureCoord(0, 1, bottomRight);
         _quad.setTextureCoord(0, 2, bottomLeft);
         _quad.setTextureCoord(0, 3, topLeft);

      }
      _quad.updateTextureBuffer();
   }
   
   /**
    * Returns the value of the progress bar. Between 0 and 100
    * @return
    */
   public int getValue() {
      return value;
   }
}




And here is the test case:
TestUIProgressBar


package com.volatile7.vz3.test;

import com.jme.app.SimpleGame;
import com.jme.renderer.ColorRGBA;
import com.volatile7.vz3.ui.UIProgressBar;

/**
 * @author Ahmed
 * @version: $Id: TestUIProgressBar.java, Feb 3, 2005 8:35:40 PM
 */
public class TestUIProgressBar extends SimpleGame {

   private UIProgressBar progress;

   private float time;

   public void simpleUpdate() {
      time += tpf;

      if (time >= 0.5f) {
         progress.setValue((int) (Math.random() * 100));
         time = 0;
      }
   }

   protected void simpleInitGame() {
      
      display.getRenderer().setBackgroundColor(ColorRGBA.white);

      progress = new UIProgressBar("Progress", 10, 50, 100, 50,
            "com/data/images/progress_bar.tga", "com/data/images/progress_bar_overlay.png", UIProgressBar.HORIZONTAL);

      rootNode.attachChild(progress);
   }

   public static void main(String args[]) {
      TestUIProgressBar app = new TestUIProgressBar();
      app.setDialogBehaviour(ALWAYS_SHOW_PROPS_DIALOG);
      app.start();
   }




Hope its of any use to anyone someday somewhere...

Edit, I managed to get Texture Coordinate shifting in as well. So that you can use gradients in now..Il post the images below

DP

Cool… UIProgressBar was on the GUI TODO list, so one down :)… a few left to go :?

What others are on the "todo" list? This was fun, so i might have a bash at the others :smiley:



DP

Great :slight_smile:

"guurk" wrote:
ComboBox (Editable and non-editable)
Layout manager
Scroll Bar
Slider
Progress Bar
Moveable/Resizeable Window with frame

Any other's that I should do?

And, the textfield doesn’t work properly (registering arrow keys etc.) and I can’t get the dimension of the UIText, making it impossible to have it centered.

Il start on a slider :slight_smile: (the easiest from the list)



But first, i would like to check if this is ok with the developers because the outlines of the progress bar are textures and dont comply with the UIColorScheme…



DP



Edit, i should really learn how to spell!

DP can you provide some sample textures?

DP, as far as I can remember there used to be a problem with focus management in the UI components, ie. handling which component currently receives input, especially if an input-aware UI component is shown while input handlers for a game are currently registered. There needs to be a well defined way to make UI components receive all input in such a case.



You may find it useful to spend some minutes thinking about this, too.

about the problem with key inputs. I’l look into it, but I cant promise anything :slight_smile:



But about the sample textures, definetly!



This is actual progress bar:







and this is the overlay: (btw the middle is transperant)





Enjoy!

That looks really cool. I’m gonna have to figure out a need for a progress bar now. heh.

Ive fixed some bugs in the z ordering and texture coord shifting of the overlay quad.



I think this is it guys. A fully fledged progress bar!



DP

Great work DarkProphet!!

yer, and in exactly 5 days time (if everything goes to plan), you will see this in a game!



Hurray!



DP

DP, thanks for adding on!



Just so y’all know, I haven’t stopped working. The last two weeks I’ve worked pretty much full time on getting the UI code whipped into shape.



Here’s a quick tease.







from:







Here’s what I’ve got working:

    - Generic Window based FrameWindows (Work as Dialogs too) and Controls
    - Moving, Resizing, Minimizing, Maximizing.. etc.
    - Full event drivers with cascading notifications based on flags.
    - Window (control) creation also based on flags.
    - Layout managers (right now just Absolute and Grid)
    - Texture and non-Texture based creation.
    - All UI scheme information is laid out in a *.xml file.
    [/list:u]

    So, stay tuned...

Sweet! 8-O

- All UI scheme information is laid out in a *.xml file.


Thank you!

Impressive !

Can’t wait to see it in action…



Have you seen the Irrlicht engine’s GUI ? Very nice too, you could get some help there if you need !



Soem screenies for those who don’t know about it :



screenshot 1

screenshot 2



Chman

beautiful…

I’ve taken some hints from Irrlicht and Crazy Eddie as well as MFC and SWT :).

Uhh… seriously: WOW!



This GUI is gonna own everything! :smiley: