Package com.bitfire.postprocessing.demo

Source Code of com.bitfire.postprocessing.demo.UI

/*******************************************************************************
* Copyright 2012 bmanuel
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*   http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
******************************************************************************/

package com.bitfire.postprocessing.demo;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputMultiplexer;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.g2d.NinePatch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.Rectangle;
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.CheckBox;
import com.badlogic.gdx.scenes.scene2d.ui.Label;
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox;
import com.badlogic.gdx.scenes.scene2d.ui.Slider;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.utils.Align;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.scenes.scene2d.utils.NinePatchDrawable;
import com.badlogic.gdx.utils.Array;

/**
* Implements the UI creation and event handling.
*
* Notes on the panel animator: some very simple expedients help in determining whenever the
* user is voluntarily leaving the panel area to make it to hide itself or it's just due to
* the fact combobox widgets are higher than the panel, thus the user *needs* to move out of
* the panel to make a selection: the latter case is being tracked by
*
* @author bmanuel
*/
public final class UI {
  public boolean drawBackground, backgroundAffected, drawSprite;
  public Sprite background;

  private Stage stage;
  private Label singleMessage, fps;

  // panel animator
  private boolean comboBoxFlag, panelShown, usePanelAnimator;
  private TopPanelAnimator panelAnimator;

  private static final boolean DebugUI = false;
  private static final int DefaultBackground = 2;
  private static final int DefaultGradientMap = 0;
  private PostProcessing post;
  private Array<SelectBox> selectBoxes = new Array<SelectBox>();

  public UI( InputMultiplexer inputMultiplexer, PostProcessing postProcessing, boolean panelAutoShow ) {
    float width = Gdx.graphics.getWidth();
    float height = Gdx.graphics.getHeight();

    ResourceFactory.DebugUI = DebugUI;

    post = postProcessing;
    drawBackground = true;
    drawSprite = false;
    backgroundAffected = true;
    comboBoxFlag = false;
    usePanelAnimator = panelAutoShow;
    post.zoomRadialBlur = true;

    stage = new Stage();
    inputMultiplexer.addProcessor( stage );
    if( DebugUI ) {
      stage.setDebugAll( true );
    }

    // selectable screen background
    background = ResourceFactory.newSprite( "bgnd.jpg" );
    background.setSize( width, height );

    // panel background
    NinePatch np = new NinePatch( ResourceFactory.newTexture( "brushed.png", false ), 0, 0, 0, 0 );
    np.setColor( new Color( 0.3f, 0.3f, 0.3f, 1f ) );
    NinePatchDrawable npBack = new NinePatchDrawable( np );

    // build the top panel and add all of its widgets
    Table topPanel = buildTopPanel( npBack, width, height );
    topPanel.add( buildGlobalSettingsWidgets() );
    topPanel.add( buildBloomWidgets() );
    topPanel.add( buildCurvatureWidgets() );
    topPanel.add( buildCrtEmulationWidgets() );
    topPanel.add( buildVignettingWidgets() );

    // the zoomer widgets group is somewhat "special": if we are going
    // to NOT use a panel animator then one more button will be added
    // to permit the user to show/hide the panel manually
    Table tZoomer = buildZoomerWidgets();

    // compute the panel's opened/closed position
    final float yWhenShown = height - topPanel.getHeight() + 13;
    final float yWhenHidden = height - 60 + 13;

    if( usePanelAnimator ) {
      panelShown = false;
      panelAnimator = new TopPanelAnimator( topPanel, new Rectangle( 10, 5, width - 20, 60 ), yWhenShown, yWhenHidden );
      topPanel.setY( yWhenHidden );
      topPanel.add( tZoomer ).expandX();
      topPanel.setColor( 1f, 1f, 1f, 0.5f );
    } else {
      panelShown = true;
      topPanel.setY( yWhenShown );
      topPanel.add( tZoomer ).expandX();
      tZoomer.row();
      tZoomer.add( buildPanelActionButtons( topPanel, yWhenShown, yWhenHidden ) ).align( Align.right );
    }

    // build the bottom panel
    Table bottomPanel = buildBottomPanel( npBack, width, height );
    bottomPanel.add( ResourceFactory.newLabel( "Press \"Q\" or \"Esc\" to quit" ) );

    // fps label
    fps = ResourceFactory.newLabel( "fps: " );
    bottomPanel.add( fps ).width( 200 ).padLeft( 50 );

    // general-purpose single message
    singleMessage = ResourceFactory.newLabel( "" );
    bottomPanel.add( singleMessage ).expandX().right();

    // UI is quite ready at this point, just add the containers to the stage
    stage.addActor( topPanel );
    stage.addActor( bottomPanel );

    // perform some processing on the SelectBox widgets
    for( int i = 0; i < selectBoxes.size; i++ ) {
      // fire a change event on selected SelectBoxes to
      // update the default selection and initialize accordingly
      selectBoxes.get( i ).fire( new ChangeListener.ChangeEvent() );

      if( usePanelAnimator ) {
        // track clicks on the comboboxes, this imply the widget is
        // opening giving the user some choices
        selectBoxes.get( i ).addListener( new ClickListener() {
          @Override
          public void clicked( InputEvent event, float x, float y ) {
            comboBoxFlag = true;
            panelAnimator.suspend();
          }
        } );

        // track changes, user performed a selection
        selectBoxes.get( i ).addListener( new ChangeListener() {
          @Override
          public void changed( ChangeEvent event, Actor actor ) {
            comboBoxFlag = false;
          }
        } );
      }
    }

    // finally, track clicks on the stage, whenever the user cancel an
    // opened combobox selection by clicking away it will cause the widgets
    // to close (no ChangeListener will be notified)
    stage.addListener( new ClickListener() {
      @Override
      public void clicked( InputEvent event, float x, float y ) {
        if( !comboBoxFlag ) {
          panelAnimator.resume();
        }

        comboBoxFlag = false;
      }
    } );
  }

  private Table buildTopPanel( NinePatchDrawable back, float width, float height ) {

    Table p = ResourceFactory.newTable();
    p.setSize( width, 155 );
    p.defaults().pad( 5, 25, 5, 0 ).align( Align.top );
    p.left();
    p.setBackground( back );

    return p;
  }

  private Table buildGlobalSettingsWidgets() {
    // post-processing
    final CheckBox cbPost = ResourceFactory.newCheckBox( " Post-processing", post.isEnabled(), new ClickListener() {
      @Override
      public void clicked( InputEvent event, float x, float y ) {
        CheckBox source = (CheckBox)event.getListenerActor();
        post.setEnabled( source.isChecked() );
      }
    } );

    final SelectBox<String> sbBackground = ResourceFactory.newSelectBox( new String[] { "None ", "Scratches ", "Mountains ",
        "Lake ", "Checker board ", "Solid white " }, new ChangeListener() {
      @Override
      public void changed( ChangeEvent event, Actor actor ) {
        @SuppressWarnings( "unchecked" )
        SelectBox<String> source = (SelectBox<String>)actor;
        drawBackground = true;

        switch( source.getSelectedIndex() ) {
        case 0:
          drawBackground = false;
          break;
        case 1:
          background.setTexture( ResourceFactory.newTexture( "bgnd.jpg", false ) );
          break;
        case 2:
          background.setTexture( ResourceFactory.newTexture( "bgnd2.jpg", false ) );
          break;
        case 3:
          background.setTexture( ResourceFactory.newTexture( "bgnd3.jpg", false ) );
          break;
        case 4:
          background.setTexture( ResourceFactory.newTexture( "bgnd4.jpg", false ) );
          break;
        case 5:
          background.setTexture( ResourceFactory.newTexture( "bgnd5.jpg", false ) );
          break;
        }
      }
    } );

    // background affected by post-processing
    final CheckBox cbBackgroundAffected = ResourceFactory.newCheckBox( " Background affected\n by post-processing",
        backgroundAffected, new ClickListener() {
          @Override
          public void clicked( InputEvent event, float x, float y ) {
            CheckBox source = (CheckBox)event.getListenerActor();
            backgroundAffected = source.isChecked();
            // if( backgroundAffected ) {
            // post.enableBlending();
            // } else {
            // post.disableBlending();
            // }
          }
        } );

    // sprite
    final CheckBox cbSprite = ResourceFactory.newCheckBox( " Show sprite", drawSprite, new ClickListener() {
      @Override
      public void clicked( InputEvent event, float x, float y ) {
        CheckBox source = (CheckBox)event.getListenerActor();
        drawSprite = source.isChecked();
      }
    } );

    sbBackground.setSelectedIndex( DefaultBackground );
    selectBoxes.add( sbBackground );

    Table t = ResourceFactory.newTable();
    t.add( cbPost ).colspan( 2 ).left();
    t.row();
    t.add( ResourceFactory.newLabel( "Background " ) );
    t.add( sbBackground );
    t.row();
    t.add( cbBackgroundAffected ).colspan( 2 ).left();
    t.row();
    t.add( cbSprite ).colspan( 2 ).left();

    return t;
  }

  private Table buildBloomWidgets() {
    final CheckBox cbBloom = ResourceFactory.newCheckBox( " Bloom", post.bloom.isEnabled(), new ClickListener() {
      @Override
      public void clicked( InputEvent event, float x, float y ) {
        CheckBox source = (CheckBox)event.getListenerActor();
        post.bloom.setEnabled( source.isChecked() );
      }
    } );

    final Slider slBloomThreshold = ResourceFactory.newSlider( 0, 1, 0.01f, post.bloom.getThreshold(), new ChangeListener() {
      @Override
      public void changed( ChangeEvent event, Actor actor ) {
        Slider source = (Slider)event.getListenerActor();
        post.bloom.setThreshold( source.getValue() );
      }
    } );

    final Slider slBloomBaseI = ResourceFactory.newSlider( 0, 2, 0.01f, post.bloom.getBaseIntensity(), new ChangeListener() {
      @Override
      public void changed( ChangeEvent event, Actor actor ) {
        Slider source = (Slider)event.getListenerActor();
        post.bloom.setBaseIntesity( source.getValue() );
      }
    } );

    final Slider slBloomBaseS = ResourceFactory.newSlider( 0, 2, 0.01f, post.bloom.getBaseSaturation(), new ChangeListener() {
      @Override
      public void changed( ChangeEvent event, Actor actor ) {
        Slider source = (Slider)event.getListenerActor();
        post.bloom.setBaseSaturation( source.getValue() );
      }
    } );

    final Slider slBloomBloomI = ResourceFactory.newSlider( 0, 2, 0.01f, post.bloom.getBloomIntensity(),
        new ChangeListener() {
          @Override
          public void changed( ChangeEvent event, Actor actor ) {
            Slider source = (Slider)event.getListenerActor();
            post.bloom.setBloomIntesity( source.getValue() );
          }
        } );

    final Slider slBloomBloomS = ResourceFactory.newSlider( 0, 2, 0.01f, post.bloom.getBloomSaturation(),
        new ChangeListener() {
          @Override
          public void changed( ChangeEvent event, Actor actor ) {
            Slider source = (Slider)event.getListenerActor();
            post.bloom.setBloomSaturation( source.getValue() );
          }
        } );

    Table t = ResourceFactory.newTable();
    t.add( cbBloom ).colspan( 2 ).center();
    t.row();
    t.add( ResourceFactory.newLabel( "threshold " ) ).left();
    t.add( slBloomThreshold );
    t.row();
    t.add( ResourceFactory.newLabel( "base int " ) ).left();
    t.add( slBloomBaseI );
    t.row();
    t.add( ResourceFactory.newLabel( "base sat " ) ).left();
    t.add( slBloomBaseS );
    t.row();
    t.add( ResourceFactory.newLabel( "bloom int " ) ).left();
    t.add( slBloomBloomI );
    t.row();
    t.add( ResourceFactory.newLabel( "bloom sat " ) ).left();
    t.add( slBloomBloomS );

    return t;
  }

  private Table buildCurvatureWidgets() {
    final CheckBox cbCurvature = ResourceFactory.newCheckBox( " Curvature", post.curvature.isEnabled(), new ClickListener() {
      @Override
      public void clicked( InputEvent event, float x, float y ) {
        CheckBox source = (CheckBox)event.getListenerActor();
        post.curvature.setEnabled( source.isChecked() );

      }
    } );

    final Slider slCurvatureDist = ResourceFactory.newSlider( 0, 2, 0.01f, post.curvature.getDistortion(),
        new ChangeListener() {
          @Override
          public void changed( ChangeEvent event, Actor actor ) {
            Slider source = (Slider)event.getListenerActor();
            post.curvature.setDistortion( source.getValue() );
          }
        } );

    final Slider slCurvatureZoom = ResourceFactory.newSlider( 0, 2, 0.01f, 2f - post.curvature.getZoom(),
        new ChangeListener() {
          @Override
          public void changed( ChangeEvent event, Actor actor ) {
            Slider source = (Slider)event.getListenerActor();
            post.curvature.setZoom( 2f - source.getValue() );
          }
        } );

    Table t = ResourceFactory.newTable();
    t.add( cbCurvature ).colspan( 2 ).center();
    t.row();
    t.add( ResourceFactory.newLabel( "Distortion " ) ).left();
    t.add( slCurvatureDist );
    t.row();
    t.add( ResourceFactory.newLabel( "Zoom " ) ).left();
    t.add( slCurvatureZoom );

    return t;
  }

  private Table buildCrtEmulationWidgets() {
    final CheckBox cbCrt = ResourceFactory.newCheckBox( " Old CRT emulation", post.crt.isEnabled(), new ClickListener() {
      @Override
      public void clicked( InputEvent event, float x, float y ) {
        CheckBox source = (CheckBox)event.getListenerActor();
        post.crt.setEnabled( source.isChecked() );
      }
    } );

    final Slider slCrtDispersionRC = ResourceFactory.newSlider( -1f, 1f, 0.001f, post.crt.getChromaticDispersion().x,
        new ChangeListener() {
          @Override
          public void changed( ChangeEvent event, Actor actor ) {
            Slider source = (Slider)event.getListenerActor();
            post.crt.setChromaticDispersionRC( source.getValue() );
          }
        } );

    final Slider slCrtDispersionBY = ResourceFactory.newSlider( -1f, 1f, 0.001f, post.crt.getChromaticDispersion().y,
        new ChangeListener() {
          @Override
          public void changed( ChangeEvent event, Actor actor ) {
            Slider source = (Slider)event.getListenerActor();
            post.crt.setChromaticDispersionBY( source.getValue() );
          }
        } );

    slCrtDispersionRC.setSnapToValues( new float[] { 0 }, 0.05f );
    slCrtDispersionBY.setSnapToValues( new float[] { 0 }, 0.05f );

    final Slider slCrtTintR = ResourceFactory.newSlider( 0, 1f, 0.01f, post.crt.getTint().r, new ChangeListener() {
      @Override
      public void changed( ChangeEvent event, Actor actor ) {
        Slider source = (Slider)event.getListenerActor();
        Color tint = post.crt.getTint();
        tint.r = source.getValue();
        post.crt.setTint( tint );
      }
    } );

    final Slider slCrtTintG = ResourceFactory.newSlider( 0, 1f, 0.01f, post.crt.getTint().g, new ChangeListener() {
      @Override
      public void changed( ChangeEvent event, Actor actor ) {
        Slider source = (Slider)event.getListenerActor();
        Color tint = post.crt.getTint();
        tint.g = source.getValue();
        post.crt.setTint( tint );
      }
    } );

    final Slider slCrtTintB = ResourceFactory.newSlider( 0, 1f, 0.01f, post.crt.getTint().b, new ChangeListener() {
      @Override
      public void changed( ChangeEvent event, Actor actor ) {
        Slider source = (Slider)event.getListenerActor();
        Color tint = post.crt.getTint();
        tint.b = source.getValue();
        post.crt.setTint( tint );
      }
    } );

    Table t = ResourceFactory.newTable();
    t.add( cbCrt ).colspan( 2 ).center();
    t.row();
    t.add( ResourceFactory.newLabel( "Chromatic dispersion R/C " ) ).left();
    t.add( slCrtDispersionRC );
    t.row();
    t.add( ResourceFactory.newLabel( "Chromatic dispersion B/Y " ) ).left();
    t.add( slCrtDispersionBY );
    t.row();
    t.add( ResourceFactory.newLabel( "Tint (R) " ) ).left();
    t.add( slCrtTintR );
    t.row();
    t.add( ResourceFactory.newLabel( "Tint (G) " ) ).left();
    t.add( slCrtTintG );
    t.row();
    t.add( ResourceFactory.newLabel( "Tint (B) " ) ).left();
    t.add( slCrtTintB );

    return t;
  }

  private Table buildVignettingWidgets() {
    final CheckBox cbVignette = ResourceFactory.newCheckBox( " Vignetting", post.vignette.isEnabled(), new ClickListener() {
      @Override
      public void clicked( InputEvent event, float x, float y ) {
        CheckBox source = (CheckBox)event.getListenerActor();
        post.vignette.setEnabled( source.isChecked() );

      }
    } );

    final Slider slVignetteI = ResourceFactory.newSlider( 0, 1f, 0.01f, post.vignette.getIntensity(), new ChangeListener() {
      @Override
      public void changed( ChangeEvent event, Actor actor ) {
        Slider source = (Slider)event.getListenerActor();
        post.vignette.setIntensity( source.getValue() );
      }
    } );

    final SelectBox<String> sbGradientMap = ResourceFactory.newSelectBox( new String[] { "Cross processing ", "Sunset ",
        "Mars", "Vivid ", "Greenland ", "Cloudy ", "Muddy " }, new ChangeListener() {
      @Override
      public void changed( ChangeEvent event, Actor actor ) {
        if( post.vignette.isGradientMappingEnabled() ) {
          SelectBox<String> source = (SelectBox)actor;
          switch( source.getSelectedIndex() ) {
          case 0:
            post.vignette.setLutIndexVal( 0, 16 );
            break;
          case 1:
            post.vignette.setLutIndexVal( 0, 5 );
            break;
          case 2:
            post.vignette.setLutIndexVal( 0, 7 );
            break;
          case 3:
            post.vignette.setLutIndexVal( 0, 6 );
            break;
          case 4:
            post.vignette.setLutIndexVal( 0, 8 );
            break;
          case 5:
            post.vignette.setLutIndexVal( 0, 3 );
            break;
          case 6:
            post.vignette.setLutIndexVal( 0, 0 );
            break;
          }
        }
      }
    } );

    sbGradientMap.setSelectedIndex( DefaultGradientMap );
    selectBoxes.add( sbGradientMap );

    final CheckBox cbGradientMapping = ResourceFactory.newCheckBox( " Perform gradient mapping",
        post.vignette.isGradientMappingEnabled(), new ClickListener() {
          @Override
          public void clicked( InputEvent event, float x, float y ) {
            CheckBox source = (CheckBox)event.getListenerActor();
            if( source.isChecked() ) {
              post.vignette.setLutTexture( ResourceFactory.newTexture( "gradient-mapping.png", false ) );
              sbGradientMap.fire( new ChangeListener.ChangeEvent() );
            } else {
              post.vignette.setLutTexture( null );
              post.vignette.setLutIndexVal( 0, -1 );
            }
          }
        } );

    Table t = ResourceFactory.newTable();
    t.add( cbVignette ).colspan( 2 ).center();
    t.row();
    t.add( ResourceFactory.newLabel( "Intensity " ) ).left();
    t.add( slVignetteI );
    t.row();
    t.add( cbGradientMapping ).padTop( 10 ).colspan( 2 ).center();
    t.row();
    t.add( ResourceFactory.newLabel( "Gradient " ) ).center().padTop( 10 );
    t.add( sbGradientMap ).padTop( 10 );

    return t;
  }

  private Table buildZoomerWidgets() {
    final CheckBox cbZoomer = ResourceFactory.newCheckBox( " Zoomer", post.zoomer.isEnabled(), new ClickListener() {
      @Override
      public void clicked( InputEvent event, float x, float y ) {
        CheckBox source = (CheckBox)event.getListenerActor();
        post.zoomer.setEnabled( source.isChecked() );
        if( post.isEnabled() ) {
          if( post.zoomer.isEnabled() ) {
            post.zoomAmount = 0;
            post.zoomFactor = 0;
            singleMessage.setText( "Use the mousewheel to zoom in/out" );
          } else {
            singleMessage.setText( "" );
          }
        }

      }
    } );

    final CheckBox cbZoomerDoBlur = ResourceFactory.newCheckBox( " Radial blur", post.zoomRadialBlur, new ClickListener() {
      @Override
      public void clicked( InputEvent event, float x, float y ) {
        CheckBox source = (CheckBox)event.getListenerActor();
        if( source.isChecked() ) {
          post.zoomRadialBlur = true;
        } else {
          post.zoomer.setBlurStrength( 0 );
          post.zoomRadialBlur = false;
        }
      }
    } );

    Table t = ResourceFactory.newTable();
    t.add( cbZoomer );
    t.row();
    t.add( cbZoomerDoBlur );

    return t;
  }

  private Table buildPanelActionButtons( final Table topPanel, final float yWhenShown, final float yWhenHidden ) {
    TextButton btnShowHide = ResourceFactory.newButton( "Show/hide panel", new ClickListener() {
      @Override
      public void clicked( InputEvent event, float x, float y ) {
        if( !panelShown ) {
          topPanel.addAction( Actions.moveTo( topPanel.getX(), yWhenShown, 0.5f, Interpolation.exp10 ) );
          topPanel.addAction( Actions.alpha( 1f, 0.5f, Interpolation.exp10 ) );
          panelShown = true;
        } else {
          topPanel.addAction( Actions.moveTo( topPanel.getX(), yWhenHidden, 0.5f, Interpolation.exp10 ) );
          topPanel.addAction( Actions.alpha( 0.5f, 0.5f, Interpolation.exp10 ) );
          panelShown = false;
        }
      }
    } );

    Table t = ResourceFactory.newTable();
    t.row().padTop( 55 );
    t.add( btnShowHide );

    return t;
  }

  private Table buildBottomPanel( NinePatchDrawable back, float width, float height ) {
    Table t = ResourceFactory.newTable();
    t.setSize( width, 130 );
    t.defaults().pad( 10, 15, 0, 15 ).align( Align.top ).expandY();
    t.setY( -98 );
    t.left();
    t.setBackground( back );

    return t;
  }

  public void update( float deltaTimeSecs ) {
    stage.act( deltaTimeSecs );
    fps.setText( "fps: " + Gdx.graphics.getFramesPerSecond() );
    if( usePanelAnimator ) {
      panelAnimator.update();
    }
  }

  public void draw() {
    stage.draw();
  }

  public void mouseMoved( int x, int y ) {
    if( usePanelAnimator ) {
      panelAnimator.mouseMoved( x, y );
    }
  }
}
TOP

Related Classes of com.bitfire.postprocessing.demo.UI

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.