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

indigo.shared.scenegraph.Graphic.scala Maven / Gradle / Ivy

The newest version!
package indigo.shared.scenegraph

import indigo.shared.BoundaryLocator
import indigo.shared.datatypes.Depth
import indigo.shared.datatypes.Flip
import indigo.shared.datatypes.Point
import indigo.shared.datatypes.Radians
import indigo.shared.datatypes.Rectangle
import indigo.shared.datatypes.Size
import indigo.shared.datatypes.Vector2
import indigo.shared.events.GlobalEvent
import indigo.shared.materials.Material
import indigo.shared.materials.ShaderData

/** Graphics are used to draw images on the screen, in a cheap efficient but expressive way. Graphic's party trick is
  * it's ability to crop images.
  */
final case class Graphic[M <: Material](
    material: M,
    crop: Rectangle,
    eventHandlerEnabled: Boolean,
    eventHandler: ((Graphic[?], GlobalEvent)) => Option[GlobalEvent],
    position: Point,
    rotation: Radians,
    scale: Vector2,
    depth: Depth,
    ref: Point,
    flip: Flip
) extends RenderNode[Graphic[M]]
    with Cloneable
    with SpatialModifiers[Graphic[M]]
    derives CanEqual:

  def bounds: Rectangle =
    BoundaryLocator.findBounds(this, position, crop.size, ref)

  lazy val size: Size =
    crop.size

  lazy val x: Int = position.x
  lazy val y: Int = position.y

  def withMaterial[MB <: Material](newMaterial: MB): Graphic[MB] =
    this.copy(material = newMaterial)

  def modifyMaterial[MB <: Material](alter: M => MB): Graphic[MB] =
    this.copy(material = alter(material))

  def moveTo(pt: Point): Graphic[M] =
    this.copy(position = pt)
  def moveTo(x: Int, y: Int): Graphic[M] =
    moveTo(Point(x, y))
  def withPosition(newPosition: Point): Graphic[M] =
    moveTo(newPosition)

  def moveBy(pt: Point): Graphic[M] =
    this.copy(position = position + pt)
  def moveBy(x: Int, y: Int): Graphic[M] =
    moveBy(Point(x, y))

  def rotateTo(angle: Radians): Graphic[M] =
    this.copy(rotation = angle)
  def rotateBy(angle: Radians): Graphic[M] =
    rotateTo(rotation + angle)
  def withRotation(newRotation: Radians): Graphic[M] =
    rotateTo(newRotation)

  def scaleBy(amount: Vector2): Graphic[M] =
    this.copy(scale = scale * amount)
  def scaleBy(x: Double, y: Double): Graphic[M] =
    scaleBy(Vector2(x, y))
  def withScale(newScale: Vector2): Graphic[M] =
    this.copy(scale = newScale)

  def transformTo(newPosition: Point, newRotation: Radians, newScale: Vector2): Graphic[M] =
    this.copy(position = newPosition, rotation = newRotation, scale = newScale)

  def transformBy(positionDiff: Point, rotationDiff: Radians, scaleDiff: Vector2): Graphic[M] =
    transformTo(position + positionDiff, rotation + rotationDiff, scale * scaleDiff)

  def withDepth(newDepth: Depth): Graphic[M] =
    this.copy(depth = newDepth)

  def flipHorizontal(isFlipped: Boolean): Graphic[M] =
    this.copy(flip = flip.withHorizontalFlip(isFlipped))
  def flipVertical(isFlipped: Boolean): Graphic[M] =
    this.copy(flip = flip.withVerticalFlip(isFlipped))
  def withFlip(newFlip: Flip): Graphic[M] =
    this.copy(flip = newFlip)

  def withRef(newRef: Point): Graphic[M] =
    this.copy(ref = newRef)
  def withRef(x: Int, y: Int): Graphic[M] =
    withRef(Point(x, y))

  def withCrop(newCrop: Rectangle): Graphic[M] =
    this.copy(crop = newCrop)
  def withCrop(x: Int, y: Int, width: Int, height: Int): Graphic[M] =
    withCrop(Rectangle(x, y, width, height))

  lazy val toShaderData: ShaderData =
    material.toShaderData

  def withEventHandler(f: ((Graphic[?], GlobalEvent)) => Option[GlobalEvent]): Graphic[M] =
    this.copy(eventHandler = f, eventHandlerEnabled = true)
  def onEvent(f: PartialFunction[(Graphic[?], GlobalEvent), GlobalEvent]): Graphic[M] =
    withEventHandler(f.lift)
  def enableEvents: Graphic[M] =
    this.copy(eventHandlerEnabled = true)
  def disableEvents: Graphic[M] =
    this.copy(eventHandlerEnabled = false)

object Graphic:

  def apply[M <: Material](x: Int, y: Int, width: Int, height: Int, depth: Int, material: M): Graphic[M] =
    Graphic(
      eventHandlerEnabled = false,
      eventHandler = Function.const(None),
      position = Point(x, y),
      rotation = Radians.zero,
      scale = Vector2.one,
      depth = Depth(depth),
      ref = Point.zero,
      flip = Flip.default,
      crop = Rectangle(0, 0, width, height),
      material = material
    )

  def apply[M <: Material](x: Int, y: Int, width: Int, height: Int, material: M): Graphic[M] =
    Graphic(
      eventHandlerEnabled = false,
      eventHandler = Function.const(None),
      position = Point(x, y),
      rotation = Radians.zero,
      scale = Vector2.one,
      depth = Depth.zero,
      ref = Point.zero,
      flip = Flip.default,
      crop = Rectangle(0, 0, width, height),
      material = material
    )

  def apply[M <: Material](bounds: Rectangle, depth: Int, material: M): Graphic[M] =
    Graphic(
      eventHandlerEnabled = false,
      eventHandler = Function.const(None),
      position = bounds.position,
      rotation = Radians.zero,
      scale = Vector2.one,
      depth = Depth(depth),
      ref = Point.zero,
      flip = Flip.default,
      crop = bounds,
      material = material
    )

  def apply[M <: Material](bounds: Rectangle, material: M): Graphic[M] =
    Graphic(
      eventHandlerEnabled = false,
      eventHandler = Function.const(None),
      position = bounds.position,
      rotation = Radians.zero,
      scale = Vector2.one,
      depth = Depth.zero,
      ref = Point.zero,
      flip = Flip.default,
      crop = bounds,
      material = material
    )

  def apply[M <: Material](width: Int, height: Int, material: M): Graphic[M] =
    Graphic(
      eventHandlerEnabled = false,
      eventHandler = Function.const(None),
      position = Point.zero,
      rotation = Radians.zero,
      scale = Vector2.one,
      depth = Depth.zero,
      ref = Point.zero,
      flip = Flip.default,
      crop = Rectangle(0, 0, width, height),
      material = material
    )

  def apply[M <: Material](size: Size, material: M): Graphic[M] =
    Graphic(
      eventHandlerEnabled = false,
      eventHandler = Function.const(None),
      position = Point.zero,
      rotation = Radians.zero,
      scale = Vector2.one,
      depth = Depth.zero,
      ref = Point.zero,
      flip = Flip.default,
      crop = Rectangle(Point.zero, size),
      material = material
    )




© 2015 - 2024 Weber Informatics LLC | Privacy Policy