138 lines
3.4 KiB
Kotlin
138 lines
3.4 KiB
Kotlin
package nl.kallestruik.dlib.gui
|
|
|
|
import kotlinx.coroutines.runBlocking
|
|
import net.kyori.adventure.text.Component
|
|
import org.bukkit.Material
|
|
import org.bukkit.entity.Player
|
|
import org.bukkit.event.EventHandler
|
|
import org.bukkit.event.HandlerList
|
|
import org.bukkit.event.Listener
|
|
import org.bukkit.event.inventory.*
|
|
import org.bukkit.inventory.InventoryView
|
|
import org.bukkit.inventory.ItemStack
|
|
import org.bukkit.plugin.Plugin
|
|
|
|
fun textInputDialog(player: Player, plugin: Plugin, configure: suspend TextInputDialog.() -> Unit) {
|
|
val textInputDialog = TextInputDialog()
|
|
runBlocking {
|
|
textInputDialog.configure()
|
|
}
|
|
|
|
textInputDialog.display(player, plugin)
|
|
}
|
|
|
|
class TextInputDialog: Listener {
|
|
private data class Configuration(
|
|
var item: suspend TextInputDialogItem.() -> Unit = {},
|
|
var onFinish: suspend (value: String) -> Unit = {},
|
|
var onCancel: suspend () -> Unit = {}
|
|
)
|
|
|
|
private val configuration = Configuration()
|
|
var prompt: Component = Component.empty()
|
|
|
|
private lateinit var view: InventoryView
|
|
private lateinit var plugin: Plugin
|
|
|
|
|
|
fun item(entry: suspend TextInputDialogItem.() -> Unit) {
|
|
configuration.item = entry
|
|
}
|
|
|
|
fun onFinish(onFinish: suspend (value: String) -> Unit) {
|
|
configuration.onFinish = onFinish
|
|
}
|
|
|
|
fun onCancel(onCancel: suspend () -> Unit) {
|
|
configuration.onCancel = onCancel
|
|
}
|
|
|
|
fun display(player: Player, plugin: Plugin) {
|
|
player.closeInventory()
|
|
this.plugin = plugin
|
|
view = player.openAnvil(null, true) ?: return
|
|
|
|
val entry = TextInputDialogItem()
|
|
runBlocking {
|
|
configuration.item.invoke(entry)
|
|
}
|
|
|
|
val itemStack = ItemStack(entry.material, entry.amount)
|
|
val itemMeta = itemStack.itemMeta
|
|
itemMeta.displayName(prompt)
|
|
itemStack.itemMeta = itemMeta
|
|
|
|
view.setItem(0, itemStack)
|
|
|
|
plugin.server.pluginManager.registerEvents(this, plugin)
|
|
}
|
|
|
|
private fun cleanup() {
|
|
view.close()
|
|
HandlerList.unregisterAll(this)
|
|
}
|
|
|
|
/*
|
|
Bukkit event handlers
|
|
*/
|
|
@EventHandler
|
|
fun onInventoryClose(event: InventoryCloseEvent) {
|
|
if (event.view != this.view)
|
|
return
|
|
|
|
if (event.reason == InventoryCloseEvent.Reason.PLUGIN) {
|
|
return
|
|
}
|
|
|
|
runBlocking {
|
|
configuration.onCancel.invoke()
|
|
cleanup()
|
|
}
|
|
}
|
|
|
|
@EventHandler
|
|
fun onAnvilPrepare(event: PrepareAnvilEvent) {
|
|
if (event.view != view)
|
|
return
|
|
|
|
// Always keep the cost at 1. 0 Causes the client to not be able to click it.
|
|
event.inventory.repairCost = 1
|
|
}
|
|
|
|
@EventHandler
|
|
fun onOperationFinish(event: InventoryClickEvent) {
|
|
if (event.view != view) {
|
|
return
|
|
}
|
|
|
|
if (event.action != InventoryAction.PICKUP_ALL) {
|
|
event.isCancelled = true
|
|
return
|
|
}
|
|
|
|
if (view.convertSlot(event.rawSlot) != 2) {
|
|
event.isCancelled = true
|
|
return
|
|
}
|
|
|
|
val item = event.currentItem
|
|
val name = item?.itemMeta?.displayName ?: ""
|
|
|
|
if (name == "") {
|
|
event.isCancelled = true
|
|
return
|
|
}
|
|
|
|
event.isCancelled = true
|
|
|
|
runBlocking {
|
|
configuration.onFinish.invoke(name)
|
|
cleanup()
|
|
}
|
|
}
|
|
}
|
|
|
|
data class TextInputDialogItem(
|
|
var material: Material = Material.AIR,
|
|
var amount: Int = 1,
|
|
) |