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

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

There is a newer version: 1.18.1
Show newest version
package life

uses java.awt.event.MouseEvent
uses java.awt.Point
uses javax.swing.JPopupMenu
uses javax.swing.JMenuItem
uses java.awt.Toolkit
uses java.awt.datatransfer.StringSelection
uses java.awt.datatransfer.DataFlavor
uses java.awt.EventQueue

class SelectionHandler extends AbstractHandler {
  var _anchorCell: Point
  var _dragCell: Point
  var _dragging: Boolean as Dragging

  construct( board: Board ) {
    super( board )
  }

  override property set Enabled( enabled: boolean ) {
    _anchorCell = null
    super.Enabled = enabled
  }

  property get Selection() : Collection {
    if( _anchorCell == null || _dragCell == null ) {
      return Collections.emptyList()
    }

    var selection = new HashSet()
    for( x in _anchorCell.x.._dragCell.x ) {
      selection.add( Board.Model.getCell( x, _anchorCell.y ) )
      selection.add( Board.Model.getCell( x, _dragCell.y ) )
    }
    for( y in _anchorCell.y.._dragCell.y ) {
      selection.add( Board.Model.getCell( _anchorCell.x, y ) )
      selection.add( Board.Model.getCell( _dragCell.x, y ) )
    }
    return selection
  }

  property get SelectedLiveCells() : Collection  {
    var selected = new ArrayList()
    for( x in _anchorCell.x.._dragCell.x ) {
      for( y in _anchorCell.y.._dragCell.y ) {
        var cell = Board.Model.getCell( x, y )
        if( Board.Model.LiveCells.contains( cell ) ) {
          selected.add( cell )
        }
      }
    }
    return selected
  }

  function clearSelection() {
    _anchorCell = null
    _dragCell = null
    Board.repaintBuffer()
  }

  override function mousePressed( e: MouseEvent ) {
    _anchorCell = findCellAt( e.Point )
    _dragCell = _anchorCell
    Board.repaintBuffer()
  }

  override function mouseDragged( e: MouseEvent ) {
    _dragging = true
    Board.repaintBuffer()
    var cell = findCellAt( e.Point )
    _dragCell = cell?:_dragCell
    _dragging = false
    Board.repaintBuffer()
  }

  override function mouseReleased( e: MouseEvent ) {
    if( _anchorCell == _dragCell ) {
      clearSelection()
    }
    else {
      var popup = new JPopupMenu()
      var item = new JMenuItem( "Cut" )
        item.addActionListener( \ev -> cut() )
        popup.add( item )
      item = new JMenuItem( "Copy" )
        item.addActionListener( \ev -> copy() )
        popup.add( item )
      item = new JMenuItem( "Paste" )
        item.addActionListener( \ev -> paste() )
        popup.add( item )
      popup.show( Board, e.X, e.Y )
    }
  }

  function findCellAt( loc: Point ) : Point {
    loc = Board.translate( loc )
    var x = loc.x / Board.CellSize
    var y = loc.y / Board.CellSize
    try {
      if( Board.Model.Infinite ) {
        return new Point( x, y )
      }
      return new Point( x >= Board.XCells ? Board.XCells-1 : x < 0 ? 0 : x,
                        y >= Board.YCells ? Board.YCells-1 : y < 0 ? 0 : y )
    }
    catch( e: ArrayIndexOutOfBoundsException ) {
      return null
    }
  }

  function cut() {
    copy()
    var cells = SelectedLiveCells
    Board.postModelChange( \-> Board.Model.killLiveCells( cells ) )
    clearSelection()
  }

  function copy() {
    var offsetCell = _anchorCell.x < _dragCell.x ? _anchorCell : _dragCell
    var copy = "new HashSet() {"
    var first = true
    for( cell in SelectedLiveCells ) {
      copy += (first ? "" : ",") + "new(${cell.X-offsetCell.x}, ${cell.Y-offsetCell.y})"
      first = false
    }
    copy += "}"
    Toolkit.DefaultToolkit.SystemClipboard.setContents( new StringSelection( copy ), null )
    EventQueue.invokeLater( \-> clearSelection() )
  }

  function paste() {
    var contents = Toolkit.DefaultToolkit.SystemClipboard.getContents( null )
    var value = contents.getTransferData( DataFlavor.stringFlavor ) as String
    if( value.startsWith( "new HashSet" ) ) {
      var points = eval( value ) as HashSet
      var cells = mapCellsToSelection( points )
      Board.postModelChange( \-> {
          Board.Model.addLiveCells( cells )
        } )
    }
    clearSelection()
  }

  private function mapCellsToSelection( points: Collection ): Collection {
    var offsetCell = _anchorCell.x < _dragCell.x ? _anchorCell : _dragCell
    return points.map( \pt -> Board.Model.getCell( pt.x + offsetCell.x, pt.y + offsetCell.y ) )
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy