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

ktx.scene2d.widget.kt Maven / Gradle / Ivy

There is a newer version: 1.12.1-rc2
Show newest version
package ktx.scene2d

import com.badlogic.gdx.scenes.scene2d.Actor
import com.badlogic.gdx.scenes.scene2d.Group
import com.badlogic.gdx.scenes.scene2d.ui.*
import com.badlogic.gdx.scenes.scene2d.ui.Tree.Node
import com.badlogic.gdx.scenes.scene2d.utils.Drawable
import com.badlogic.gdx.utils.Array as GdxArray

/* Implementations of actors and widget interfaces required to set up type-safe GUI builders. */

/**
 * Common interface applied to so-called "parental" widgets.
 */
@Scene2dDsl
interface KWidget {
  /**
   * Internal utility method for adding actors to the group. Assumes the actor is stored in a container.
   * @param actor will be added to this group.
   * @return storage object, wrapping around the actor or the actor itself if there is no storage object.
   * @see Node
   * @see Cell
   */
  fun storeActor(actor: Actor): Storage

  /**
   * Internal utility method for adding actors to the group.
   * @param actor will be added to this group.
   * @return actor passed as the parameter.
   */
  fun  appendActor(actor: T): T
}

/**
 * Common interface applied to widgets that extend the original [Table] and keep their children in [Cell] instances.
 */
@Scene2dDsl
interface KTable : KWidget> {
  /**
   * @param actor will be added to this widget.
   * @return [Cell] instance wrapping around the actor.
   * @see [Table.add]
   */
  fun  add(actor: T): Cell

  override fun storeActor(actor: Actor): Cell<*> {
    val cell = add(actor)
    actor.userObject = cell
    return cell
  }

  override fun  appendActor(actor: T): T {
    val cell = add(actor)
    actor.userObject = cell
    return actor
  }

  /**
   * Allows to customize properties of the [Cell] storing this actor.
   * @param grow if true, expands and fills the cell vertically and horizontally. Defaults to false.
   * @param growX if true, expands and fills the cell horizontally. Defaults to false. Overrides [grow].
   * @param growY if true, expands and fills the cell vertically. Defaults to false. Overrides [grow].
   * @param expand if true, expands the cell vertically and horizontally. Overrides [growX], [growY].
   * @param expandX if true, expands the cell horizontally. Overrides [expand].
   * @param expandY if true, expands the cell vertically. Overrides [expand].
   * @param fill if true, the actor will fill the whole cell area vertically and horizontally. Overrides [growX], [growY].
   * @param fillX if true, the actor will fill the whole cell area horizontally. Overrides [fill].
   * @param fillY if true, the actor will fill the whole cell area vertically. Overrides [fill].
   * @param uniform see [Cell.uniform].
   * @param uniformX see [Cell.uniformX]. Overrides [uniform].
   * @param uniformY see [Cell.uniformY]. Overrides [uniform].
   * @param align actor alignment in the cell. See [com.badlogic.gdx.utils.Align].
   * @param colspan amount of columns taken by the cell.
   * @param width sets maximum, preferred and minimum width of the cell in viewport units.
   * @param minWidth sets minimum width of the cell. Overrides [width].
   * @param preferredWidth sets preferred width of the cell. Overrides [width].
   * @param maxWidth sets maximum width of the cell. Overrides [width].
   * @param height sets maximum, preferred and minimum height of the cell in viewport units.
   * @param minHeight sets minimum height of the cell. Overrides [height].
   * @param preferredHeight sets preferred height of the cell. Overrides [height].
   * @param maxHeight sets maximum height of the cell. Overrides [height].
   * @param pad top, left, right and bottom padding value in viewport units. Contrary to [space], paddings are summed.
   * @param padTop top padding value. Overrides [pad].
   * @param padLeft left padding value. Overrides [pad].
   * @param padRight right padding value. Overrides [pad].
   * @param padBottom bottom padding value. Overrides [pad].
   * @param space top, left, right and bottom spacing value in viewport units. Contrary to [pad], spacings are not summed.
   * @param spaceTop top spacing value. Overrides [space].
   * @param spaceLeft left spacing value. Overrides [space].
   * @param spaceRight right spacing value. Overrides [space].
   * @param spaceBottom bottom spacing value. Overrides [space].
   * @param row if true, another row of actors will be started after this cell. Defaults to false.
   * @return this actor.
   * @see inCell
   */
  fun  T.cell(grow: Boolean = false,
                         growX: Boolean = false,
                         growY: Boolean = false,
                         expand: Boolean? = null,
                         expandX: Boolean? = null,
                         expandY: Boolean? = null,
                         fill: Boolean? = null,
                         fillX: Boolean? = null,
                         fillY: Boolean? = null,
                         uniform: Boolean? = null,
                         uniformX: Boolean? = null,
                         uniformY: Boolean? = null,
                         align: Int? = null,
                         colspan: Int? = null,
                         width: Float? = null,
                         minWidth: Float? = null,
                         preferredWidth: Float? = null,
                         maxWidth: Float? = null,
                         height: Float? = null,
                         minHeight: Float? = null,
                         preferredHeight: Float? = null,
                         maxHeight: Float? = null,
                         pad: Float? = null,
                         padTop: Float? = null,
                         padLeft: Float? = null,
                         padRight: Float? = null,
                         padBottom: Float? = null,
                         space: Float? = null,
                         spaceTop: Float? = null,
                         spaceLeft: Float? = null,
                         spaceRight: Float? = null,
                         spaceBottom: Float? = null,
                         row: Boolean = false): T {
    val cell = this.inCell
    if (grow) cell.grow()
    if (growX) cell.growX()
    if (growY) cell.growY()
    expand?.let { cell.expand(it, it) }
    expandX?.let { cell.expand(it, expandY ?: expand ?: false) }
    expandY?.let { cell.expand(expandX ?: expand ?: false, it) }
    fill?.let { cell.fill(it, it) }
    fillX?.let { cell.fill(it, fillY ?: fill ?: false) }
    fillY?.let { cell.fill(fillX ?: fill ?: false, it) }
    uniform?.let { cell.uniform(it, it) }
    uniformX?.let { cell.uniform(it, uniformY ?: uniform ?: false) }
    uniformY?.let { cell.uniform(uniformX ?: uniform ?: false, it) }
    align?.let { cell.align(it) }
    colspan?.let { cell.colspan(colspan) }
    width?.let { cell.width(it) }
    minWidth?.let { cell.minWidth(it) }
    preferredWidth?.let { cell.prefWidth(it) }
    maxWidth?.let { cell.maxWidth(it) }
    height?.let { cell.height(it) }
    minHeight?.let { cell.minHeight(it) }
    preferredHeight?.let { cell.prefHeight(it) }
    maxHeight?.let { cell.maxHeight(it) }
    pad?.let { cell.pad(it) }
    padTop?.let { cell.padTop(it) }
    padLeft?.let { cell.padLeft(it) }
    padRight?.let { cell.padRight(it) }
    padBottom?.let { cell.padBottom(it) }
    space?.let { cell.space(it) }
    spaceTop?.let { cell.spaceTop(it) }
    spaceLeft?.let { cell.spaceLeft(it) }
    spaceRight?.let { cell.spaceRight(it) }
    spaceBottom?.let { cell.spaceBottom(it) }
    if (row) cell.row()
    return this
  }

  /**
   * Allows to access [Cell] in this actor is stored in the [Table]. Relies on the [Actor.userObject] mechanism.
   * @throws IllegalStateException if actor was improperly added to the [Table] or does not have its [Cell] instance
   *    assigned as user object.
   * @see cell
   */
  @Suppress("UNCHECKED_CAST")
  val  T.inCell: Cell get() = userObject as? Cell ?:
      throw IllegalStateException("This actor has no declared Cell. " +
          "Was it properly added to the table? Was its user object cleared?")
}

/**
 * Common interface applied to widgets that extend [WidgetGroup] or [Group] and keep their children in an internal
 * collection.
 */
@Scene2dDsl
interface KGroup : KWidget {
  /**
   * @param actor will be added to this group.
   * @see [Group.addActor]
   * @see [WidgetGroup.addActor]
   */
  fun addActor(actor: Actor?)

  /**
   * Utility method that allows to add actors to the group with fluent API.
   * @param actor will be added to this group.
   * @return passed actor instance.
   * @see [Group.addActor]
   * @see [WidgetGroup.addActor]
   */
  fun  add(actor: T): T {
    addActor(actor)
    return actor
  }

  override fun storeActor(actor: Actor) = add(actor)
  override fun  appendActor(actor: T): T {
    addActor(actor)
    return actor
  }
}

/** Common interface applied to widgets that keep their children in [Tree] [Node] instances. */
@Scene2dDsl
interface KTree : KWidget {
  /**
   * @param actor will be placed in a [Node] inside this widget.
   * @return [Node] instance containing the actor.
   */
  fun add(actor: Actor): KNode

  override fun storeActor(actor: Actor): KNode {
    val node = add(actor)
    actor.userObject = node
    return node
  }

  override fun  appendActor(actor: T): T {
    val node = add(actor)
    actor.userObject = node
    return actor
  }

  /**
   * Allows to customize properties of the [Node] storing this actor .
   * @param icon will be drawn next to the actor.
   * @param expanded true to expand the node, false to hide its children.
   * @param selectable if false, this node cannot be selected.
   * @param userObject custom object assigned to the node.
   * @return this actor.
   * @see inNode
   */
  fun  T.node(icon: Drawable? = null,
                         expanded: Boolean? = null,
                         selectable: Boolean? = null,
                         userObject: Any? = null): T {
    val node = inNode
    icon?.let { node.icon = icon }
    expanded?.let { node.isExpanded = expanded }
    selectable?.let { node.isSelectable = selectable }
    node.`object` = userObject
    return this
  }

  /**
   * Allows to access [Node] in this actor is stored in the [Tree]. Relies on the [Actor.userObject] mechanism.
   * @throws IllegalStateException if actor was improperly added to the [Tree] or does not have its [Node] instance
   *    assigned as user object.
   * @see node
   */
  val  T.inNode: KNode get() = userObject as? KNode ?:
      throw IllegalStateException("This actor has no declared Node. " +
          "Was it properly added to the tree? Was its user object cleared?")
}

/** Extends [Button] API with type-safe widget builders. */
@Scene2dDsl
class KButton(skin: Skin, style: String) : Button(skin, style), KTable

/**
 * Extends [Table] API with type-safe widget builders. All [Button] instances added to this table will be automatically
 * included in an internal [ButtonGroup].
 * @see ButtonGroup
 * @param minCheckCount minimum amount of checked buttons.
 * @param maxCheckCount maximum amount of checked buttons.
 */
@Scene2dDsl
class KButtonTable(minCheckCount: Int, maxCheckCount: Int, skin: Skin) : Table(skin), KTable {
  val buttonGroup = ButtonGroup




© 2015 - 2025 Weber Informatics LLC | Privacy Policy