[SOLVED] Mixing a ProgressBar Effect With a Button

Anything libgdx related goes here!

[SOLVED] Mixing a ProgressBar Effect With a Button

Postby shatterblast » Sat Jan 13, 2018 7:58 pm

I recently discovered the awesomeness known as a "loading bar". It basically involves layering two NinePatch images on top of each other as the top NinePatch stretches in unison with "manager.getProgress()". I desire to use a similar concept with the Button class of Scene2D. I believe it will require the Cell class to properly stretch something like a NinePatchDrawable.

At the core, I am mixing the concept of a loading bar with a Button. With my limited knowledge, I do not know if I could even animate a ProgressBar inside a Button. Layering at least two items over each other could provide the illusion of a single button. For the purpose of presenting an individual "button" in code, the visuals could stay together in a single Table object. I will test the idea soon, but I believe one Table can hold another Table. Thus, a Table object revealing multiple "fake buttons" should work.

Would anyone have a better idea? Thank you for bearing with me.
Last edited by shatterblast on Sat Jan 20, 2018 8:51 pm, edited 1 time in total.
shatterblast
 
Posts: 87
Joined: Sun Jul 06, 2014 1:14 pm

Re: Mixing a ProgressBar Effect With a Button

Postby evilentity » Sat Jan 13, 2018 8:13 pm

Eh?
Code: Select all
progress = new ProgressBar(0, 1, .01f, false, skin, "horizontal");
progress.addListener(new ClickListener(){
            @Override public void clicked (InputEvent event, float x, float y) {
                Gdx.app.log(TAG, "welp");
            }
        });
Looking for a freelancer? PM me!
evilentity
 
Posts: 4324
Joined: Wed Aug 24, 2011 11:37 am

Re: Mixing a ProgressBar Effect With a Button

Postby shatterblast » Sat Jan 13, 2018 8:23 pm

evilentity wrote:Eh?
Code: Select all
progress = new ProgressBar(0, 1, .01f, false, skin, "horizontal");
progress.addListener(new ClickListener(){
            @Override public void clicked (InputEvent event, float x, float y) {
                Gdx.app.log(TAG, "welp");
            }
        });


True, and a ProgressBar could be shaped to look like a specific Button. Even the Actions class could be used for a ".fadeOut()" effect to another Button, and a separate Label could be kept over them so that the text does not fade.

Thank you.
shatterblast
 
Posts: 87
Joined: Sun Jul 06, 2014 1:14 pm

Re: Mixing a ProgressBar Effect With a Button

Postby tenfour04 » Sun Jan 14, 2018 2:42 am

A button is a Table, so make a button with an empty style and add your progress bar to it.
tenfour04
 
Posts: 1186
Joined: Sat Jun 18, 2011 3:24 pm

Re: Mixing a ProgressBar Effect With a Button

Postby shatterblast » Sun Jan 14, 2018 8:04 am

tenfour04 wrote:A button is a Table, so make a button with an empty style and add your progress bar to it.


Please excuse my mis-understanding. I thought that "Button.ButtonStyle" would not accept an Actor.
shatterblast
 
Posts: 87
Joined: Sun Jul 06, 2014 1:14 pm

Re: Mixing a ProgressBar Effect With a Button

Postby DranikProgrammer » Sun Jan 14, 2018 10:16 am

The actual Button class is a widget group by itself, so you can add widgets to it like you would normally add them to windows, tables etc.
DranikProgrammer
 
Posts: 96
Joined: Mon Feb 20, 2017 2:51 pm

Re: Mixing a ProgressBar Effect With a Button

Postby tenfour04 » Sun Jan 14, 2018 8:08 pm

Sorry, bad wording. Use a style with no background on the Button. Add your Progress Bar to the button.

Although the ClickListener on a ProgresBar may be fine. The downside is it won't support disabled state and toggling without you coding it yourself. Amd with the button, you could give it a nine patch background that surrounds your progress bar and reacts to touches with color changes.
tenfour04
 
Posts: 1186
Joined: Sat Jun 18, 2011 3:24 pm

Re: Mixing a ProgressBar Effect With a Button

Postby evilentity » Sun Jan 14, 2018 8:30 pm

It really depends on what you want to achieve, mixing progress bar with a button isnt very specific.
Looking for a freelancer? PM me!
evilentity
 
Posts: 4324
Joined: Wed Aug 24, 2011 11:37 am

Re: Mixing a ProgressBar Effect With a Button

Postby shatterblast » Mon Jan 15, 2018 1:48 pm

(@tenfour04) and (@DranikProgrammer)

Thank you for the clarity. Due to the suggestions, I believe I understand finally the "java.lang.String styleName" part of ProgressBar's second constructor. It functions along with the "Style" heading in the top-right of Raeleus's Skin Composer. I think this path should serve well for modifying the height of a horizontally placed ProgressBar. Otherwise, my attempts at changing just the height in code fail. (My current "skin" has a few extra choices for the size in it.)

I think this is enough information to point me in the right direction. Thank you again all for contributing!
shatterblast
 
Posts: 87
Joined: Sun Jul 06, 2014 1:14 pm

Re: Mixing a ProgressBar Effect With a Button

Postby shatterblast » Sat Jan 20, 2018 4:47 pm

Second Edit: Success! I will post the code in the message of my next reply.

First Edit: It seems that a single Cell will accept only one Actor. Stack should work, and apparently, I missed that part in the wiki. I guess a Cell is required for easy changes of an Actor in a Table or Button.

Old Message:
I could use some insight on how to center a Label within a Button, please. Modifying the Cell affects the ProgressBar but not the Label. Several methods for directly re-sizing the Label do not seem to work either.

Thank you for your time.


Here is a Runnable JAR with the test code.

Source code:


SSSTest.java
Code: Select all
package secondarySSSTest;


import java.util.concurrent.ScheduledThreadPoolExecutor;

import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.assets.AssetManager;
import com.badlogic.gdx.backends.lwjgl.LwjglApplication;
import com.badlogic.gdx.backends.lwjgl.LwjglApplicationConfiguration;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;


public class SSSTest implements ApplicationListener {
   
   static float renderDelta;
   



   
    float temporaryGenericTimer_Unifying_Bar_And_Animation = 4f;
    float delay = 0;
   
   private Stage stage;
   private Skin skin;
   private Texture textureForUI;
   TextureRegion saphirelAvatarImage;
      
   OrthographicCamera orthoCamera;
   SpriteBatch spriteBatchTest;
      
   private AssetManager manager = new AssetManager();
      

   int keyCodeDownCycle_OldSaphirel = 0;
   int keyCodeDownCycle_scorpibot = 0;

   
   //Counters for mouse input.
   int saphirelMouseCounter = 0;
   

   
   SSSTest_Attempt_to_Separate separation;
   
   Boolean allow_FirstLoad_in_RenderMethod = true;
   private ScheduledThreadPoolExecutor scheduledThreadPoolExecutor;
         
   Integer current_LoadingProgress = 0;
   Integer previous_LoadingProgress = 0;
   
   NinePatch emptyLoading_NinePatch;
   NinePatch fullLoading_NinePatch;
   Texture emptyLoadingTexture;
   Texture fullLoadingTexture;
   BitmapFont font_LoadingBar;
   
   Integer loadingBar_Measure = 0;
   SpriteBatch loading_SpriteBatch;
   
   NinePatch ninePatch_for_Button_ReloadingBar;
   NinePatchDrawable button_ReloadingBar;
   Texture testTexture;
   Button buttonTest;
   Table testTable;
   
   
   ProgressBar progress;
   Drawable drawProgressTest;
         

   @Override
   public void create () {
      
      
      orthoCamera = new OrthographicCamera();
      spriteBatchTest = new SpriteBatch( 5000 );
      
      manager.load( "Clean_Crispy_UI_Mach_Vier/Clean_Crispy_UI_Mach_Vier.json", Skin.class );
      manager.load( "avatars/Saphirel Work, Black and White.png", Texture.class );
      
      //----------------------------------------------------------------------------------------------------
      //Stuff for the loading screen.
      emptyLoadingTexture = new Texture( Gdx.files.internal( "Loading_Bar/empty.png" ));
      fullLoadingTexture = new Texture( Gdx.files.internal( "Loading_Bar/full.png" ));
            
      emptyLoading_NinePatch = new NinePatch( new TextureRegion( emptyLoadingTexture, 24, 24 ), 8, 8, 8, 8 );
      fullLoading_NinePatch = new NinePatch( new TextureRegion( fullLoadingTexture, 24, 24 ), 8, 8, 8, 8 );
      font_LoadingBar = new BitmapFont();
            
      //----------------------------------------------------------------------------------------------------
            
      stage = new Stage();
                   
   }
   

   @Override
   public void render () {
      
      Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
      renderDelta = Gdx.graphics.getRawDeltaTime();
      
      //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      //For the loading bar.
      while( !manager.update() ) {
            
         //************************************************************************
         float loadingProgress = ( manager.getProgress() );
         current_LoadingProgress = new Float( loadingProgress * 100 ).intValue();
         
         if ( !( current_LoadingProgress == previous_LoadingProgress ) ) {
            
            loadingBar_Measure = current_LoadingProgress;
            System.out.println( "Loading ... " + current_LoadingProgress  + "%" );
         
         }
         
         previous_LoadingProgress = current_LoadingProgress;
         //************************************************************************
      
         
         orthoCamera.update();
         spriteBatchTest.getProjectionMatrix().set( orthoCamera.combined );
         
         spriteBatchTest.begin();
         emptyLoading_NinePatch.draw( spriteBatchTest, 50, 325, 900, 50 );
         fullLoading_NinePatch.draw( spriteBatchTest, 50, 325, ( loadingProgress * 900 ), 50 );
         
         font_LoadingBar.setColor( Color.RED );
         font_LoadingBar.draw( spriteBatchTest, current_LoadingProgress + "% loaded", 540, 355,
               0,         //targeted font width?
               0,         //font height?
               false      //text wrap around?
            );
         
         spriteBatchTest.end();
                  
         //Without the below line, this code block for the loading bar will not proceed correctly.
         return;
                              
      }
      //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
      
      
      if ( allow_FirstLoad_in_RenderMethod ) {
         
         skin = manager.get( "Clean_Crispy_UI_Mach_Vier/Clean_Crispy_UI_Mach_Vier.json", Skin.class );
         textureForUI = manager.get( "avatars/Saphirel Work, Black and White.png", Texture.class);
         saphirelAvatarImage = new TextureRegion( textureForUI );
         
           //------------------------------------------------------------------------------------------------------------------------
           //This is for stuffing as much as possible from the "create()" method of this class into a different class file.
           //Hopefully in the future, this will allow the creation and disposal of battle sequences without exiting the main program.
           separation = new SSSTest_Attempt_to_Separate( stage, skin, this );
           separation.decouple_From_Rear_First();
           //------------------------------------------------------------------------------------------------------------------------
         
         allow_FirstLoad_in_RenderMethod = false;
         
         scheduledThreadPoolExecutor = new ScheduledThreadPoolExecutor( 1 );
            
      }

      
      orthoCamera.update();
      
      //The animation seems to still run even with the following line disabled.
      spriteBatchTest.getProjectionMatrix().set( orthoCamera.combined );
            
      
      //________________________________________________________________________________________________________________________________________
      //The following code is necessary for animations.  "AssetManager" DOES NOT HANDLE "SpriteBatch".
      spriteBatchTest.begin();

      //The below line is necessary for the correct rendering of animation colors.
      spriteBatchTest.setBlendFunction( 770, 771 );
      
      //... Spine stuff ...
   
      
      spriteBatchTest.end();

      separation.barMove( renderDelta );
      
      stage.act();
        stage.draw();
      
   }

   
   @Override
   public void resize ( int width, int height ) {
      
      //The below line seems to necessary at least for the Spine animations to render.
      orthoCamera.setToOrtho( false );
      
      //I am not sure what the below line is for, but the Spine animations do not seem to require it.
      stage.getViewport().setScreenSize( width, height );
      
   }

   
   //Might cause a memory leak if left out.
   @Override
   public void dispose() {

      stage.dispose();
      spriteBatchTest.dispose();
      manager.dispose();
      emptyLoadingTexture.dispose();
      fullLoadingTexture.dispose();
      font_LoadingBar.dispose();
      
   }
   
   
   //MAIN!!!
   public static void main (String[] args) throws Exception {

      LwjglApplicationConfiguration config = new LwjglApplicationConfiguration();
      config.title = "SSS Test";
      config.width = 1000;
      config.height = 650;
      config.resizable = false;
      new LwjglApplication(new SSSTest(), config);
      
   }


   public TextureRegion getSaphirelAvatarImage() {
      return saphirelAvatarImage;
   }

   
   public float getTemporaryGenericTimer_Unifying_Bar_And_Animation() {
      return temporaryGenericTimer_Unifying_Bar_And_Animation;
   }
   
   
   public AssetManager getManager() {
      return this.manager;
   }

   
   public ScheduledThreadPoolExecutor getScheduledThreadPoolExecutor() {
      return this.scheduledThreadPoolExecutor;
   }


   @Override
   public void pause() {
      //Auto-generated method stub.
   }


   @Override
   public void resume() {
      //Auto-generated method stub.
   }

}



SSSTest_Attempt_to_Separate.java
Code: Select all
package secondarySSSTest;


import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.actions.Actions;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.ProgressBar;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextTooltip;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;


public class SSSTest_Attempt_to_Separate {
   
   private Stage stage;
   private Skin skin;
   private SSSTest sssTest;
   private ProgressBar timeCount_ProgressBar;
   
   float barMoveTime = 0;
      
   
   NinePatch ninePatch_for_Button_ReloadingBar;
   NinePatch ninePatch_for_Button_Up;   
   NinePatchDrawable button_ReloadingBar;
   NinePatchDrawable button_ReloadingBar_Down;   
   Texture testTexture;
   Texture testTextureDown;
   Button buttonTest;
   Table testTable;
   
   
   ProgressBar progress;
    Label progressLabel;
    Button progressButtonTest;
            
   
   SSSTest_Attempt_to_Separate( Stage stage, Skin skin, SSSTest sssTest ) {
      
      this.stage = stage;
      this.skin = skin;
      this.sssTest = sssTest;
      
   }

   
   void decouple_From_Rear_First() {
      
      Image saphirelPortrait = new Image( sssTest.getSaphirelAvatarImage());
      //saphirelPortrait.setScaleX( 2f );
            
      timeCount_ProgressBar =  new ProgressBar( 0, sssTest.getTemporaryGenericTimer_Unifying_Bar_And_Animation(), 1, false, skin,
            "glassy-progressbar-horizontal" );
      
      Table table = new Table();
      Button saphirelNameButton = new TextButton( "Saphirel", skin );
        Button saphirelPortraitButton = new Button( saphirelPortrait, skin );
        Button saphirelMenuButton01 = new TextButton( "Ability Test 1", skin );
        Button saphirelMenuButton02 = new TextButton( "Ability Test 2", skin );
        Button saphirelMenuButton03 = new TextButton( "Ability Test 3", skin );       
       
       
       
       
       
       
       
        //TODO  Just "test code".
        //*************************************************************************************************
        //*************************************************************************************************

        progress = new ProgressBar( 0, 1, .01f, false, skin, "glassy-progressbar-horizontal" );
        progressLabel = new Label( "Mystery Thing", skin );
        progressButtonTest = new Button( progress, skin );
       
        progress.setAnimateInterpolation( com.badlogic.gdx.math.Interpolation.linear );      //linear
       
        progressButtonTest.setWidth( 200 );
      progressButtonTest.getCell( progress ).width( 180 );
      
      progressButtonTest.addActor( progressLabel );
   
      
        progressButtonTest.setWidth( 200 );
        progressButtonTest.layout();
       
      
      progressButtonTest.addListener( new ClickListener() {
         @Override
            public void clicked (InputEvent event, float x, float y) {
                   
            System.out.println( "++++++++++++++++++++++" );
            System.out.println( "The cow mooeth at you!" );      //Because it is silly.
            System.out.println( "++++++++++++++++++++++" );
            
            System.out.println( progressButtonTest.getCells() );
            System.out.println();
            
         }
      });
            
            
      progressButtonTest.setPosition( 300, 500 );
      stage.addActor( progressButtonTest );
      
      //*************************************************************************************************
      //*************************************************************************************************
       
      
      
      
      
      
      //TODO Next thing for modification.  A timer like the ".barMove()" method should be used for the future ProgressBar.
      //-----------------------------------------------------------------------------------------------------
        saphirelMenuButton01.addListener( new TextTooltip( "Graphics only for now.", skin ));
        saphirelMenuButton01.addListener( new ChangeListener() {
         public void changed ( ChangeEvent event, Actor actor ) {
            
            System.out.println( "Why, hello there!" );
            
         }
      });
        //-----------------------------------------------------------------------------------------------------
               
       
       
       
        saphirelMenuButton02.addListener( new TextTooltip( "Graphics only for now.", skin ));
        saphirelMenuButton02.addListener( new ChangeListener() {
         public void changed ( ChangeEvent event, Actor actor ) {
            
            System.out.println( "Blargh!!!" );
               
         }
      });
       
       
        saphirelMenuButton03.addListener( new TextTooltip( "Graphics only for now.", skin ));
        saphirelMenuButton03.addListener( new ChangeListener() {
         public void changed ( ChangeEvent event, Actor actor ) {
            
            System.out.println( "Arrr, matey!  Walk da plank!" );
   
         }
      });
        //-----------------------------------------------------------------------------------------------------

       
      Gdx.input.setInputProcessor( stage );
      
      //__________________________________________________________________________________
        table.setPosition( 850, 225 );
       
        //"layout()" checks "validation".
        table.layout();
       
        //The ".alpha()" method starts invisible.  The ".fadeIn()" method specifies how many
        //seconds it will take to arrive at full visibility.
        table.addAction( Actions.alpha( 0f ));
        table.addAction( Actions.fadeIn( 5f ));
               
       
        table.row();
        table.add( saphirelNameButton );
        table.row();
        table.add( saphirelPortraitButton );
       
       
        table.row();
        table.add( saphirelMenuButton01 ).width( 200f );
        table.row();
      table.add( saphirelMenuButton02 ).width( 200f );
      table.row();
      table.add( saphirelMenuButton03 ).width( 200f );
        //__________________________________________________________________________________
            
      
      //This adjusts the width and height of the progress bar.
      timeCount_ProgressBar.setSize( 400, 50 );
      timeCount_ProgressBar.setPosition( 20, 20 );
       
        //This affects the animation of the ProgressBar movement.
      timeCount_ProgressBar.setAnimateInterpolation( com.badlogic.gdx.math.Interpolation.swing );
       
        //The line below is just for testing the ".alpha()" method of "Actions".  The method is available for
        //scene2d stuff generally.  The variable sets the desired alpha level.  There is an
        //overloaded version also available that allows an animation to change to a different value over
        //time.
      timeCount_ProgressBar.addAction( Actions.alpha( 0.7f ) );
      
            
      //These are some of the root visual stuff.
      stage.addActor( table );
        stage.addActor( timeCount_ProgressBar );
      
        //When worked out, this "setVisible" method might work with the "draw" method
        //to create a fade effect.  The buttons don't function when ".setVisable()" is "false".
        table.setVisible(true);
      
      stage.addAction(
           Actions.sequence(
            Actions.alpha( 0 ),
            Actions.fadeIn(5f)
         )
       );
             
   }

   
   public void barMove( float deltaTimer ){
      
      barMoveTime += deltaTimer;
      
      //While this "setAnimateDuration" of "1f" is redundant, it overwrites the ".001f"
      //inside the following "if" statement, so it will react at a normal pace.
      timeCount_ProgressBar.setAnimateDuration( 0.5f );
      progress.setAnimateDuration( 0.01f );
            
      timeCount_ProgressBar.setValue( barMoveTime );
      progress.setValue( barMoveTime );
      
      if ( barMoveTime >= sssTest.getTemporaryGenericTimer_Unifying_Bar_And_Animation() ) {
         
         timeCount_ProgressBar.setAnimateDuration( 0.5f );
         progress.setAnimateDuration( 0.01f );
         
         barMoveTime = 0;
         
         timeCount_ProgressBar.setValue( 0 );
         progress.setValue( 0 );
      }
      
   }

}


While a different topic, the "loading bar" code has been included.
shatterblast
 
Posts: 87
Joined: Sun Jul 06, 2014 1:14 pm

Next

Return to Libgdx

Who is online

Users browsing this forum: Google [Bot], Majestic-12 [Bot], obigu and 1 guest