Skip to content

Commit

Permalink
No longer using SignalButton #11
Browse files Browse the repository at this point in the history
We now use an `effect` block to use Signals.
  • Loading branch information
Matt-MX committed Dec 14, 2023
1 parent 679b4eb commit c1e747d
Show file tree
Hide file tree
Showing 8 changed files with 85 additions and 40 deletions.
16 changes: 16 additions & 0 deletions api/src/main/kotlin/com/mattmx/ktgui/components/EffectBlock.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.mattmx.ktgui.components

import com.mattmx.ktgui.components.screen.GuiScreen
import com.mattmx.ktgui.components.signal.SignalListener
import com.mattmx.ktgui.components.signal.SignalOwner

class EffectBlock<T : GuiScreen>(
val owner: T,
val block: (T) -> Unit
) : SignalListener<Any> {
override fun onChange(value: Any) {
block(owner)
// todo we might want to keep track of what buttons are used exactly inside of the effect block
owner.refresh()
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.mattmx.ktgui.components.button

import com.mattmx.ktgui.components.signal.SignalListener
import com.mattmx.ktgui.utils.not
import org.bukkit.Material
import org.bukkit.inventory.ItemStack

@Deprecated("No longer supported", ReplaceWith("EffectBlock"))
class SignalButton(
val material: Material,
val builder: (SignalButton) -> Unit
Expand Down
38 changes: 27 additions & 11 deletions api/src/main/kotlin/com/mattmx/ktgui/components/screen/GuiScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package com.mattmx.ktgui.components.screen

import com.mattmx.ktgui.GuiManager
import com.mattmx.ktgui.components.ClickCallback
import com.mattmx.ktgui.components.EffectBlock
import com.mattmx.ktgui.components.button.ButtonClickedEvent
import com.mattmx.ktgui.components.button.GuiButton
import com.mattmx.ktgui.components.button.IGuiButton
import com.mattmx.ktgui.components.button.SignalButton
import com.mattmx.ktgui.components.signal.GuiSignalOwner
import com.mattmx.ktgui.event.PreGuiBuildEvent
import com.mattmx.ktgui.event.PreGuiOpenEvent
Expand All @@ -22,6 +22,7 @@ import org.bukkit.event.inventory.InventoryType
import org.bukkit.event.player.PlayerMoveEvent
import org.bukkit.event.player.PlayerQuitEvent
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack
import java.lang.Integer.max
import java.lang.Integer.min
import java.util.UUID
Expand All @@ -31,7 +32,7 @@ open class GuiScreen(
title: Component = Component.empty(),
var rows: Int = 1,
var type: InventoryType? = null
) : IGuiScreen, GuiSignalOwner<SignalButton> {
) : IGuiScreen, GuiSignalOwner<EffectBlock<GuiScreen>> {
var title: Component = title
set(value) {
field = value
Expand All @@ -43,7 +44,7 @@ open class GuiScreen(
// Can be used to identify dsl guis
var id: String = UUID.randomUUID().toString()
var items = hashMapOf<Int, GuiButton<*>>()
override var currentlyProcessing: SignalButton? = null
override var currentlyProcessing: EffectBlock<GuiScreen>? = null

protected lateinit var clickCallback: ClickCallback<*>
protected lateinit var closeCallback: (InventoryCloseEvent) -> Unit
Expand All @@ -68,7 +69,7 @@ open class GuiScreen(
.map { it.key }
}

override fun size(): Int {
override fun numberOfItems(): Int {
return items.size
}

Expand All @@ -93,6 +94,22 @@ open class GuiScreen(
player.closeInventory()
}

fun refresh() {
val inv = arrayOfNulls<ItemStack?>(totalSlots())

items.forEach { (slot, item) ->
if (slot < inv.size)
inv[slot] = item.formatIntoItemStack()
}

GuiManager.getPlayers(this)
.forEach { player ->
for ((index, item) in inv.withIndex()) {
player.openInventory.setItem(index, item)
}
}
}

override fun open(player: Player) {
// format the items
val inv: Inventory =
Expand Down Expand Up @@ -176,14 +193,13 @@ open class GuiScreen(
this.clickCallback = ClickCallback<IGuiButton<*>>().apply(clickCallbackBuilder)
}

override fun addChild(child: IGuiButton<*>) {

if (child is SignalButton) {
currentlyProcessing = child
child.apply(child.builder)
currentlyProcessing = null
}
fun addEffect(effect: EffectBlock<GuiScreen>) {
currentlyProcessing = effect
effect.block.invoke(this)
currentlyProcessing = null
}

override fun addChild(child: IGuiButton<*>) {
child.slots()?.forEach {
items[it] = child as GuiButton<*>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ interface IGuiScreen {

fun totalSlots() : Int

fun size() : Int { return 0 }
fun numberOfItems() : Int { return 0 }

fun setSlot(button: IGuiButton<*>, slot: Int) : IGuiScreen

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ class Signal<T, V>(initial: V, private val owner: SignalOwner) : ReadWriteProper
/**
* Adds a dependency if it isn't already registered.
*
* Will not duplicate dependencies
*
* @param signalListener the [SignalListener] to register.
*/
fun addDependency(signalListener: SignalListener<V>) : Boolean {
Expand Down
8 changes: 7 additions & 1 deletion api/src/main/kotlin/com/mattmx/ktgui/dsl/gui.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.mattmx.ktgui.dsl

import com.mattmx.ktgui.components.EffectBlock
import com.mattmx.ktgui.components.button.GuiButton
import com.mattmx.ktgui.components.button.IGuiButton
import com.mattmx.ktgui.components.button.SignalButton
Expand All @@ -26,5 +27,10 @@ inline fun <reified T : IGuiButton<*>> button(
inline fun button(material: Material, block: GuiButton<*>.() -> Unit) = GuiButton(material).apply(block)
inline fun IGuiScreen.button(material: Material, block: GuiButton<*>.() -> Unit) =
GuiButton(material).apply(block).apply { childOf(this@button) }

@Deprecated("No longer supported, use effect block.", ReplaceWith("effect"))
fun IGuiScreen.signalButton(material: Material, block: SignalButton.() -> Unit) =
SignalButton(material, block).apply { childOf(this@signalButton) }
SignalButton(material, block).apply { childOf(this@signalButton) }

fun GuiScreen.effect(block: GuiScreen.() -> Unit) =
EffectBlock(this, block).apply { this@effect.addEffect(this) }
22 changes: 12 additions & 10 deletions plugin/src/main/kotlin/com/mattmx/ktgui/examples/SignalsExample.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package com.mattmx.ktgui.examples
import com.mattmx.ktgui.components.signal.Signal
import com.mattmx.ktgui.components.signal.signal
import com.mattmx.ktgui.dsl.button
import com.mattmx.ktgui.dsl.effect
import com.mattmx.ktgui.dsl.gui
import com.mattmx.ktgui.dsl.signalButton
import com.mattmx.ktgui.utils.not
import org.bukkit.Material
import org.bukkit.entity.Player
Expand All @@ -23,15 +23,17 @@ class SignalsExample : Example {
var listIndex by signal(0)

// we must use this method instead of the regular button() {} method.
signalButton(Material.KNOWLEDGE_BOOK) {
title = !"Signals &7(item $listIndex)"
// whenever we use the signal variable, ktgui will recognize the usage and automatically
// update your button whenever the variable changes.
named(!"&7'&f${list[listIndex]}&7'")
lore {
add(!"&7Char length: &f${list[listIndex].length}")
}
} slot 2
effect {
button(Material.KNOWLEDGE_BOOK) {
title = !"Signals &7(item $listIndex)"
// whenever we use the signal variable, ktgui will recognize the usage and automatically
// update your button whenever the variable changes.
named(!"&7'&f${list[listIndex]}&7'")
lore {
add(!"&7Char length: &f${list[listIndex].length}")
}
} slot 2
}

button(Material.LIME_DYE) {
named(!"&a&l[CLICK]")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package com.mattmx.ktgui.examples

import com.mattmx.ktgui.components.signal.signal
import com.mattmx.ktgui.dsl.button
import com.mattmx.ktgui.dsl.effect
import com.mattmx.ktgui.dsl.gui
import com.mattmx.ktgui.dsl.signalButton
import com.mattmx.ktgui.utils.not
import org.bukkit.Material
import org.bukkit.entity.Player
import org.bukkit.event.inventory.ClickType
import org.bukkit.event.inventory.InventoryType
import java.util.UUID
import java.util.*

/**
* Unfortunately, we cannot "listen" for something inside a variable being reassigned.
Expand All @@ -20,22 +21,24 @@ class SignalsListExample : Example {
// Instead of using 'by' keyword we just assign the signal
val list = signal<Any, ArrayList<String>>(arrayListOf())

signalButton(Material.KNOWLEDGE_BOOK) {
// To access the variable we invoke it.
named(!"&7This list has &f${list().size} items:")
lore {
addAll(list().map { !"&7- &f$it" })
}
click {
ClickType.LEFT {
// Then to modify it internally we can use a variety of methods
list.mut { add(UUID.randomUUID().toString()) }
effect {
button(Material.KNOWLEDGE_BOOK) {
// To access the variable we invoke it.
named(!"&7This list has &f${list().size} items:")
lore {
addAll(list().map { !"&7- &f$it" })
}
ClickType.DROP {
list.mut { clear() }
click {
ClickType.LEFT {
// Then to modify it internally we can use a variety of methods
list.mut { add(UUID.randomUUID().toString()) }
}
ClickType.DROP {
list.mut { clear() }
}
}
}
} slot 2
} slot 2
}
}

override fun run(player: Player) = gui.open(player)
Expand Down

0 comments on commit c1e747d

Please sign in to comment.