All Downloads are FREE. Search and download functionalities are using the official Maven repository.

examples.Life.src.main.gosu.life.ControlBoard.gs Maven / Gradle / Ivy

The newest version!
package life

uses javax.swing.JPanel
uses java.awt.GridBagLayout
uses java.awt.GridBagConstraints
uses javax.swing.JComboBox
uses javax.swing.JSlider
uses javax.swing.ImageIcon
uses javax.swing.JLabel
uses javax.swing.JToggleButton
uses javax.swing.ButtonGroup
uses javax.swing.border.EmptyBorder
uses java.awt.Point
uses java.awt.Dimension
uses java.awt.EventQueue

class ControlBoard {
  var _board: Board
  var _frame: BoardFrame
  var _topBar: JPanel as TopBar
  var _leftBar: JPanel as LeftBar
  var _btnStartStop: JToggleButton
  var _btnInfinite: JToggleButton
  var _btnMultithreaded: JToggleButton
  var _btnSelection: JToggleButton
  var _btnDraw: JToggleButton
  var _btnScroll: JToggleButton
  var _cbPopulator: JComboBox
  var _sliderCellSize: JSlider
  var _labelDensity: JLabel
  var _sliderDensity: JSlider
  var _frequency: JComboBox
  var _colorScheme: JComboBox

  construct( model: Board, frame: BoardFrame ) {
    _board = model
    _frame = frame
    makeTopBar()
    makeLeftBar()
  }

  function init() {
    _cbPopulator.SelectedItem = Populator.Random
    _sliderCellSize.Value = _board.CellSize
    _frequency.SelectedItem = 100
    _colorScheme.SelectedItem = ColorScheme.Manila
  }

  private function makeTopBar() {
    _topBar = new JPanel()
    _topBar.Border = new EmptyBorder( 0, 0, 4, 0 )
    var layout = new GridBagLayout()
    _topBar.Layout = layout
    var x = 0

    // Start/Stop
    _btnStartStop = new JToggleButton( new ImageIcon( Class.getResource( "/life/images/power.png" ) ) )
      _btnStartStop.ToolTipText = "Start/Stop"
      _btnStartStop.addActionListener( \e -> {toggle() enableControls()} )
      _btnStartStop.PreferredSize = new( _btnStartStop.PreferredSize.height, _btnStartStop.PreferredSize.height )
      _btnStartStop.Selected = true
      var gc = new GridBagConstraints()
      gc.gridx = x x++
      gc.gridwidth = 1
      _topBar.add( _btnStartStop, gc )

    // Populators
    _cbPopulator = new JComboBox( Populator.AllValues.toArray() )
      _cbPopulator.setMaximumRowCount( Populator.values().length )
      _cbPopulator.SelectedItem = Populator.Random
      _cbPopulator.addActionListener( \e -> resetPopulator() )
      _cbPopulator.ToolTipText = "Choose a pattern, go random, or draw your own on a clear board"
      gc.insets = new (0, 10, 0, 0 )
      gc.gridx = x x++
      _topBar.add( _cbPopulator, gc )

    // Infinite
    _btnInfinite = new JToggleButton( new ImageIcon( Class.getResource( "/life/images/infiniti.png" ) ) )
      _btnInfinite.ToolTipText = "Infinite space"
      _btnInfinite.addActionListener( \e -> reset() )
      _btnInfinite.PreferredSize = new( _btnInfinite.PreferredSize.height, _btnInfinite.PreferredSize.height )
      gc.insets = new( 0, 10, 0, 0 )
      gc.gridx = x x++
      _topBar.add( _btnInfinite, gc )

    // Multithreaded
    _btnMultithreaded = new JToggleButton( new ImageIcon( Class.getResource( "/life/images/parallel.png" ) ) )
      _btnMultithreaded.ToolTipText = "Run in multiple threads"
      _btnMultithreaded.addActionListener( \e -> {_board.Model.Multithreaded = _btnMultithreaded.Selected} )
      _btnMultithreaded.PreferredSize = new( _btnMultithreaded.PreferredSize.height, _btnMultithreaded.PreferredSize.height )
      gc.insets = new( 0, 10, 0, 0 )
      gc.gridx = x x++
      _topBar.add( _btnMultithreaded, gc )

    // Selection
    var buttonGroup = new ButtonGroup()
    _btnSelection = new JToggleButton( new ImageIcon( Class.getResource( "/life/images/select.png" ) ) )
      _btnSelection.ToolTipText = "Select patterns, use the clipboard"
      buttonGroup.add( _btnSelection )
      _btnSelection.addActionListener( \e -> enableTools() )
      _btnSelection.PreferredSize = new( _btnSelection.PreferredSize.height, _btnSelection.PreferredSize.height )
      gc.insets = new( 0, 10, 0, 0 )
      gc.gridx = x x++
      _topBar.add( _btnSelection, gc )
    
    // Draw
    _btnDraw = new JToggleButton( new ImageIcon( Class.getResource( "/life/images/pencil.png" ) ) )
      _btnDraw.ToolTipText = "Draw on the board"
      buttonGroup.add( _btnDraw )
      _btnDraw.addActionListener( \e -> {enableTools()} )
      _btnDraw.PreferredSize = new( _btnDraw.PreferredSize.height, _btnDraw.PreferredSize.height )
      gc.insets = new( 0, 2, 0, 0 )
      gc.gridx = x x++
      _topBar.add( _btnDraw, gc )
    
    // Scroll
    _btnScroll = new JToggleButton( new ImageIcon( Class.getResource( "/life/images/scroll.png" ) ) )
      _btnScroll.ToolTipText = "Scroll the board"
      buttonGroup.add( _btnScroll )
      _btnScroll.addActionListener( \e -> {enableTools()} )
      _btnScroll.PreferredSize = new( _btnScroll.PreferredSize.height, _btnScroll.PreferredSize.height )
      gc.insets = new (0, 2, 0, 0 )
      gc.gridx = x x++
      _topBar.add( _btnScroll, gc )

    // Frequency
    var icon = new JLabel( new ImageIcon( Class.getResource( "/life/images/frequency.png" ) ) )
      icon.ToolTipText = "Timer frequency (millis)"
      gc.gridx = x x++
      gc.insets = new( 0, 10, 0, 1 )
      _topBar.add( icon, gc )
    _frequency = new JComboBox( new Integer[] {1, 2, 3, 5, 8, 10, 15, 20, 25, 30, 35, 40, 45, 50, 60, 70, 80, 90, 100, 200, 300, 400, 500, 750, 1000} )
      _frequency.ToolTipText = "Timer frequency (millis)"
      _frequency.addActionListener( \e -> {resetTimer()} )
      gc.insets = new( 0, 0, 0, 0 )
      gc.gridx = x x++
      _topBar.add( _frequency, gc )

    // Color Scheme
    icon = new JLabel( new ImageIcon( Class.getResource( "/life/images/color.png" ) ) )
      icon.ToolTipText = "Color scheme"
      gc.gridx = x x++
      gc.insets = new( 0, 10, 0, 1 )
      _topBar.add( icon, gc )
    _colorScheme = new JComboBox( new ColorScheme[] {Manila, Reagan, Citrine} )
      _colorScheme.ToolTipText = "Color scheme"
      _colorScheme.addActionListener( \e -> {_board.BoardColorScheme = _colorScheme.SelectedItem as ColorScheme} )
      gc.insets = new( 0, 0, 0, 0 )
      gc.gridx = x x++
      _topBar.add( _colorScheme, gc )

    // Padding
    var filler = new JPanel()
      gc.gridx = x x++
      gc.fill = GridBagConstraints.HORIZONTAL
      gc.gridwidth = GridBagConstraints.REMAINDER
      gc.insets = new( 0, 10, 0, 0 )
      gc.weightx = 1
      _topBar.add( filler, gc )

    _board.Model.addGenerationListener( \-> enableControls() )
  }
  
  private function makeLeftBar() {
    _leftBar = new JPanel()
    var layout = new GridBagLayout()
    _leftBar.Layout = layout
    var y = 0
    
    // CellSize
    var icon = new JLabel( new ImageIcon( Class.getResource( "/life/images/resolution.png" ) ) )
      icon.ToolTipText = "Set the cell size"
      var gc = new GridBagConstraints()
      gc.gridy = y y++
      gc.gridheight = 1
      gc.insets = new( 10, 0, 0, 0 )
      _leftBar.add( icon, gc )
    _sliderCellSize = new JSlider( JSlider.VERTICAL, 1, 24, 4 )
      _sliderCellSize.addChangeListener( \e -> resetCellSize() )
      _sliderCellSize.PreferredSize = new( _sliderCellSize.PreferredSize.width, 80 )
      _board.Model.addCellSizeListener( \ size ->  {_sliderCellSize.Value = size} )
      gc.gridy = y y++
      gc.insets = new( 0, 0, 0, 0 )
      _leftBar.add( _sliderCellSize, gc )

    // Density
    _labelDensity = new JLabel( new ImageIcon( Class.getResource( "/life/images/density.png" ) ) )
      _labelDensity.ToolTipText = "Set the initial number of live cells on the board"
      gc.gridy = y y++
      gc.insets = new ( 10, 0, 0, 0 )
      _leftBar.add( _labelDensity, gc )
      _sliderDensity = new JSlider( JSlider.VERTICAL, 1, 100, _board.Density )
      _sliderDensity.addChangeListener( \e -> reset() )
      _sliderDensity.PreferredSize = new( _sliderDensity.PreferredSize.width, 80 )
      gc.gridy = y y++
      gc.insets = new( 0, 0, 0, 0 )
      _leftBar.add( _sliderDensity, gc )

    // Tick Count
    var filler = new JLabel()
      gc.gridy = y y++
      gc.fill = GridBagConstraints.VERTICAL
      gc.gridheight = GridBagConstraints.REMAINDER
      gc.insets = new( 10, 0, 0, 0 )
      gc.weighty = 1
      _leftBar.add( filler, gc )

    _leftBar.PreferredSize = new( _btnStartStop.PreferredSize.width + 4, _leftBar.PreferredSize.height )
  }

  private function toggle() {
    if( _board.Running ) {
      _board.stop()
    }
    else {
      _board.start()
    }
  }

  private function enableControls() {
    _btnStartStop.Selected = _board.Running
    _sliderDensity.Enabled = _cbPopulator.SelectedItem == Populator.Random
    _labelDensity.Enabled = _sliderDensity.Enabled
  }

  private function enableTools() {
    _board.enableSelection( _btnSelection.Selected )
    _board.enableDrawing( _btnDraw.Selected )
    _board.enableScrolling( _btnScroll.Selected )
  }

  private function reset() {
    _board.reset( new( _board.Width/_sliderCellSize.Value, _board.Height/_sliderCellSize.Value ), _btnInfinite.Selected, _btnMultithreaded.Selected, _cbPopulator.SelectedItem as Populator, _sliderCellSize.Value, _frequency.SelectedItem as int, _sliderDensity.Value, _board.Running )
    _board.Model.addGenerationListener( \-> enableControls() )
    _board.Model.addCellSizeListener( \ size ->  {_sliderCellSize.Value = size} )
    _frame.adjustClientArea()
  }

  function resetCellSize() {
    _board.postModelChange( \-> {
      var res = _sliderCellSize.Value
      var size = new Dimension( _board.Width / res, _board.Height / res )
      _board.Model.updateCellSize( res, size )
      EventQueue.invokeLater( \-> _board.repaintBuffer() )
    } )
  }

  private function resetPopulator() {
    var populator = _cbPopulator.SelectedItem as Populator
    var res = populator.CellSize
    if( res > 0 ) {
      res = maybeFinerIfNotFit( populator.LiveCells, res )
      _sliderCellSize.Value = res
    }
    reset()
  }

  private function resetTimer() {
    _board.resetTimer( _frequency.SelectedItem as int )
  }

  function maybeFinerIfNotFit( live: Collection, res: int ) : int {
    while( res > 1 ) {
      var maxX = live.maxBy( \ pt -> pt.x )
      var maxY = live.maxBy( \ pt -> pt.y )
      if( maxX.X >= _board.XCells - _board.XCells/3 ||
          maxY.Y >= _board.YCells - _board.YCells/3 ) {
        res--
      }
      else {
        break
      }
    }
    return res
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy