Merge pull request #9 from bluefireoly/guispace
Added GUI Space functionality
This commit is contained in:
@@ -58,7 +58,7 @@ dependencies {
|
||||
testCompileOnly("org.spigotmc", "spigot", "1.16.3-R0.1-SNAPSHOT")
|
||||
|
||||
// KHTTP
|
||||
implementation("khttp", "khttp", "1.0.0")
|
||||
api("khttp", "khttp", "1.0.0")
|
||||
|
||||
}
|
||||
|
||||
|
@@ -2,7 +2,7 @@
|
||||
|
||||
package net.axay.kspigot.config
|
||||
|
||||
import net.axay.kspigot.languageextensions.createIfNotExists
|
||||
import net.axay.kspigot.languageextensions.kotlinextensions.createIfNotExists
|
||||
import net.axay.kspigot.main.ValueHolder.getGson
|
||||
import java.io.File
|
||||
import java.io.FileReader
|
||||
|
@@ -2,76 +2,9 @@
|
||||
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
import net.axay.kspigot.event.listen
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.inventory.Inventory
|
||||
import org.bukkit.inventory.InventoryView
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
// EXTENSIONS
|
||||
|
||||
fun HumanEntity.openGUI(gui: InventoryGUI<*>, page: Int? = null): InventoryView? {
|
||||
|
||||
closeInventory()
|
||||
|
||||
if (page != null)
|
||||
gui.loadPageUnsafe(page)
|
||||
|
||||
return openInventory(gui.bukkitInventory)
|
||||
|
||||
}
|
||||
|
||||
// GUI HOLDER
|
||||
|
||||
object InventoryGUIHolder : AutoCloseable {
|
||||
|
||||
private val registered = HashSet<InventoryGUI<ForInventory>>()
|
||||
|
||||
fun register(inventoryGUI: InventoryGUI<ForInventory>) {
|
||||
registered.add(inventoryGUI)
|
||||
}
|
||||
|
||||
fun unregister(inventoryGUI: InventoryGUI<ForInventory>) {
|
||||
registered.remove(inventoryGUI)
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
listen<InventoryClickEvent> {
|
||||
|
||||
val clickedInv = it.clickedInventory ?: return@listen
|
||||
|
||||
val inv = registered.find { search -> search.isThisInv(clickedInv) } ?: return@listen
|
||||
val invPage = inv.currentPageInt
|
||||
|
||||
val slot = inv.data.pages[invPage]?.slots?.get(it.slot)
|
||||
if (slot != null)
|
||||
slot.onClick(InventoryGUIClickEvent(it, inv))
|
||||
else
|
||||
it.isCancelled = true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
registered.forEach { inv -> inv.bukkitInventory.viewers.forEach { it.closeInventory() } }
|
||||
registered.clear()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// EVENT
|
||||
|
||||
class InventoryGUIClickEvent<T : ForInventory>(
|
||||
val bukkitEvent: InventoryClickEvent,
|
||||
val gui: InventoryGUI<T>
|
||||
)
|
||||
|
||||
/*
|
||||
* INVENTORY GUI
|
||||
*/
|
||||
|
||||
private const val DEFAULT_PAGE = 1
|
||||
|
||||
class InventoryGUIData<T : ForInventory>(
|
||||
@@ -94,13 +27,25 @@ abstract class InventoryGUI<T : ForInventory>(
|
||||
|
||||
internal abstract val bukkitInventory: Inventory
|
||||
|
||||
internal var isInMove: Boolean = false
|
||||
|
||||
internal abstract fun loadPageUnsafe(
|
||||
page: Int,
|
||||
offsetHorizontally: Int = 0,
|
||||
offsetVertically: Int = 0
|
||||
)
|
||||
|
||||
internal abstract fun loadPageUnsafe(
|
||||
page: InventoryGUIPage<*>,
|
||||
offsetHorizontally: Int = 0,
|
||||
offsetVertically: Int = 0
|
||||
)
|
||||
|
||||
internal abstract fun loadPageUnsafe(page: Int, offsetHorizontally: Int = 0, offsetVertically: Int = 0)
|
||||
internal abstract fun loadContent(
|
||||
content: Map<Int, InventoryGUISlot<*>>,
|
||||
offsetHorizontally: Int = 0,
|
||||
offsetVertically: Int = 0
|
||||
)
|
||||
|
||||
/**
|
||||
* @return True, if the [inventory] belongs to this GUI.
|
||||
@@ -136,6 +81,14 @@ abstract class InventoryGUI<T : ForInventory>(
|
||||
*/
|
||||
fun getPage(page: Int?) = data.pages[page]
|
||||
|
||||
/**
|
||||
* Reloads the current page.
|
||||
*/
|
||||
fun reloadCurrentPage() {
|
||||
if (!isInMove)
|
||||
loadPage(currentPage)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Inventory GUI implementations
|
||||
@@ -152,43 +105,59 @@ class InventoryGUIShared<T : ForInventory>(
|
||||
|
||||
override fun isThisInv(inventory: Inventory) = inventory == bukkitInventory
|
||||
|
||||
override fun loadPageUnsafe(page: Int, offsetHorizontally: Int, offsetVertically: Int) {
|
||||
data.pages[page]?.let { loadPageUnsafe(it, offsetHorizontally, offsetVertically) }
|
||||
}
|
||||
|
||||
override fun loadPageUnsafe(page: InventoryGUIPage<*>, offsetHorizontally: Int, offsetVertically: Int) {
|
||||
|
||||
val ifOffset = offsetHorizontally != 0 || offsetVertically != 0
|
||||
|
||||
if (!ifOffset)
|
||||
if (!ifOffset) {
|
||||
|
||||
// unregister this inv from all elements on the previous page
|
||||
HashSet(currentPage.slots.values).forEach { if (it is InventoryGUIElement) it.stopUsing(this) }
|
||||
|
||||
currentPageInt = page.number
|
||||
|
||||
page.slots.let { slots ->
|
||||
}
|
||||
|
||||
val dimensions = data.inventoryType.dimensions
|
||||
loadContent(page.slots, offsetHorizontally, offsetVertically)
|
||||
|
||||
if (ifOffset) {
|
||||
dimensions.invSlots.forEach {
|
||||
dimensions.invSlotsWithRealSlots[it.add(offsetHorizontally, offsetVertically)]?.let { slotToClear ->
|
||||
if (dimensions.realSlots.contains(slotToClear))
|
||||
bukkitInventory.clear(slotToClear)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
bukkitInventory.clear()
|
||||
}
|
||||
|
||||
override fun loadContent(
|
||||
content: Map<Int, InventoryGUISlot<*>>,
|
||||
offsetHorizontally: Int,
|
||||
offsetVertically: Int
|
||||
) {
|
||||
|
||||
val ifOffset = offsetHorizontally != 0 || offsetVertically != 0
|
||||
|
||||
val dimensions = data.inventoryType.dimensions
|
||||
|
||||
// clear the space which will be redefined
|
||||
if (ifOffset) {
|
||||
dimensions.invSlots.forEach {
|
||||
val slotToClear = dimensions.invSlotsWithRealSlots[it.add(offsetHorizontally, offsetVertically)]
|
||||
if (slotToClear != null) bukkitInventory.clear(slotToClear)
|
||||
}
|
||||
} else bukkitInventory.clear()
|
||||
|
||||
slots.forEach {
|
||||
val slot = it.value
|
||||
if (slot is InventoryGUIElement) {
|
||||
content.forEach {
|
||||
|
||||
if (ifOffset) {
|
||||
val invSlot = InventorySlot.fromRealSlot(it.key, dimensions)
|
||||
if (invSlot != null) {
|
||||
val offsetSlot = invSlot.add(offsetHorizontally, offsetVertically).realSlotIn(dimensions)
|
||||
if (offsetSlot != null)
|
||||
bukkitInventory.setItem(offsetSlot, slot.inventoryGUIElementData.itemStack)
|
||||
}
|
||||
} else {
|
||||
bukkitInventory.setItem(it.key, slot.inventoryGUIElementData.itemStack)
|
||||
val slot = it.value
|
||||
if (slot is InventoryGUIElement) {
|
||||
|
||||
if (ifOffset) {
|
||||
val invSlot = InventorySlot.fromRealSlot(it.key, dimensions)
|
||||
if (invSlot != null) {
|
||||
val offsetSlot = invSlot.add(offsetHorizontally, offsetVertically).realSlotIn(dimensions)
|
||||
if (offsetSlot != null) bukkitInventory.setItem(offsetSlot, slot.getItemStack(offsetSlot))
|
||||
}
|
||||
|
||||
} else {
|
||||
bukkitInventory.setItem(it.key, slot.getItemStack(it.key))
|
||||
slot.startUsing(this)
|
||||
}
|
||||
|
||||
}
|
||||
@@ -197,21 +166,10 @@ class InventoryGUIShared<T : ForInventory>(
|
||||
|
||||
}
|
||||
|
||||
override fun loadPageUnsafe(page: Int, offsetHorizontally: Int, offsetVertically: Int) {
|
||||
data.pages[page]?.let { loadPageUnsafe(it, offsetHorizontally, offsetVertically) }
|
||||
}
|
||||
|
||||
override operator fun set(slot: InventorySlotCompound<T>, value: ItemStack) {
|
||||
slot.realSlotsWithInvType(data.inventoryType).forEach {
|
||||
bukkitInventory.setItem(it, value)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class InventoryGUIPage<T : ForInventory>(
|
||||
val number: Int,
|
||||
internal val slots: Map<Int, InventoryGUISlot<T>>,
|
||||
val transitionTo: PageChangeEffect?,
|
||||
val transitionFrom: PageChangeEffect?
|
||||
)
|
||||
}
|
@@ -5,13 +5,15 @@ package net.axay.kspigot.inventory
|
||||
import net.axay.kspigot.inventory.elements.*
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
fun <T : ForInventory> inventoryGUI(
|
||||
fun <T : ForInventory> kSpigotGUI(
|
||||
type: InventoryType<T>,
|
||||
shared: Boolean = true,
|
||||
builder: InventoryGUIBuilder<T>.() -> Unit,
|
||||
) = InventoryGUIBuilder(type).apply(builder).build()
|
||||
) = InventoryGUIBuilder(type, shared).apply(builder).build()
|
||||
|
||||
class InventoryGUIBuilder<T : ForInventory>(
|
||||
val type: InventoryType<T>
|
||||
val type: InventoryType<T>,
|
||||
val shared: Boolean
|
||||
) {
|
||||
|
||||
var title: String = ""
|
||||
@@ -36,14 +38,17 @@ class InventoryGUIBuilder<T : ForInventory>(
|
||||
onClickElement = onClick
|
||||
}
|
||||
|
||||
internal fun build() = InventoryGUIShared(
|
||||
InventoryGUIData(type, title, guiSlots, transitionTo, transitionFrom, onClickElement)
|
||||
).apply { register() }
|
||||
internal fun build(): InventoryGUI<T> {
|
||||
val guiData = InventoryGUIData(type, title, guiSlots, transitionTo, transitionFrom, onClickElement)
|
||||
val gui =
|
||||
if (shared) InventoryGUIShared(guiData) else TODO("Currently, there is no non-shared GUI implementation available.")
|
||||
return gui.apply { register() }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class InventoryGUIPageBuilder<T : ForInventory>(
|
||||
val type: InventoryType<T>,
|
||||
private val type: InventoryType<T>,
|
||||
val page: Int
|
||||
) {
|
||||
|
||||
@@ -60,14 +65,14 @@ class InventoryGUIPageBuilder<T : ForInventory>(
|
||||
* function is invoked.
|
||||
*/
|
||||
fun button(slots: InventorySlotCompound<T>, itemStack: ItemStack, onClick: (InventoryGUIClickEvent<T>) -> Unit) =
|
||||
defineSlots(slots, InventoryGUIButton(InventoryGUIElementData(itemStack), onClick))
|
||||
defineSlots(slots, InventoryGUIButton(itemStack, onClick))
|
||||
|
||||
/**
|
||||
* An item protected from any player actions.
|
||||
* This is not a button.
|
||||
*/
|
||||
fun placeholder(slots: InventorySlotCompound<T>, itemStack: ItemStack) =
|
||||
defineSlots(slots, InventoryGUIPlaceholder(InventoryGUIElementData(itemStack)))
|
||||
defineSlots(slots, InventoryGUIPlaceholder(itemStack))
|
||||
|
||||
/**
|
||||
* A free slot does not block any player actions.
|
||||
@@ -87,7 +92,7 @@ class InventoryGUIPageBuilder<T : ForInventory>(
|
||||
onChange: ((InventoryGUIClickEvent<T>) -> Unit)? = null
|
||||
) = defineSlots(
|
||||
slots, InventoryGUIButtonPageChange(
|
||||
InventoryGUIElementData(itemStack),
|
||||
itemStack,
|
||||
InventoryGUIPageChangeCalculator.InventoryGUIConsistentPageCalculator(toPage),
|
||||
onChange
|
||||
)
|
||||
@@ -104,7 +109,7 @@ class InventoryGUIPageBuilder<T : ForInventory>(
|
||||
onChange: ((InventoryGUIClickEvent<T>) -> Unit)? = null
|
||||
) = defineSlots(
|
||||
slots, InventoryGUIButtonPageChange(
|
||||
InventoryGUIElementData(itemStack),
|
||||
itemStack,
|
||||
InventoryGUIPageChangeCalculator.InventoryGUIPreviousPageCalculator,
|
||||
onChange
|
||||
)
|
||||
@@ -121,7 +126,7 @@ class InventoryGUIPageBuilder<T : ForInventory>(
|
||||
onChange: ((InventoryGUIClickEvent<T>) -> Unit)? = null
|
||||
) = defineSlots(
|
||||
slots, InventoryGUIButtonPageChange(
|
||||
InventoryGUIElementData(itemStack),
|
||||
itemStack,
|
||||
InventoryGUIPageChangeCalculator.InventoryGUINextPageCalculator,
|
||||
onChange
|
||||
)
|
||||
@@ -139,13 +144,37 @@ class InventoryGUIPageBuilder<T : ForInventory>(
|
||||
onChange: ((InventoryGUIClickEvent<T>) -> Unit)? = null
|
||||
) = defineSlots(
|
||||
slots, InventoryGUIButtonInventoryChange(
|
||||
InventoryGUIElementData(itemStack),
|
||||
itemStack,
|
||||
newGUI,
|
||||
newPage,
|
||||
onChange
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* Defines an area where the content of the given compound
|
||||
* is displayed.
|
||||
*/
|
||||
fun <E> compoundSpace(
|
||||
slots: InventorySlotCompound<T>,
|
||||
compound: InventoryGUISpaceCompound<T, E>
|
||||
) {
|
||||
compound.addSlots(slots)
|
||||
defineSlots(
|
||||
slots,
|
||||
InventoryGUISpaceCompoundElement(compound)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new compound, holding data which can be displayed
|
||||
* in any compound space.
|
||||
*/
|
||||
fun <E> createCompound(
|
||||
iconGenerator: (E) -> ItemStack,
|
||||
onClick: (clickEvent: InventoryGUIClickEvent<T>, element: E) -> Unit
|
||||
) = InventoryGUISpaceCompound(type, iconGenerator, onClick)
|
||||
|
||||
private fun defineSlots(slots: InventorySlotCompound<T>, element: InventoryGUISlot<T>) =
|
||||
slots.withInvType(type).forEach { curSlot ->
|
||||
curSlot.realSlotIn(type.dimensions)?.let { guiSlots[it] = element }
|
||||
|
@@ -0,0 +1,8 @@
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
|
||||
class InventoryGUIClickEvent<T : ForInventory>(
|
||||
val bukkitEvent: InventoryClickEvent,
|
||||
val gui: InventoryGUI<T>
|
||||
)
|
@@ -8,13 +8,9 @@ abstract class InventoryGUISlot<T : ForInventory> {
|
||||
|
||||
// ELEMENT
|
||||
|
||||
class InventoryGUIElementData(
|
||||
val itemStack: ItemStack
|
||||
)
|
||||
abstract class InventoryGUIElement<T : ForInventory> : InventoryGUISlot<T>() {
|
||||
|
||||
abstract class InventoryGUIElement<T : ForInventory>(
|
||||
val inventoryGUIElementData: InventoryGUIElementData
|
||||
) : InventoryGUISlot<T>() {
|
||||
abstract fun getItemStack(slot: Int): ItemStack
|
||||
|
||||
final override fun onClick(clickEvent: InventoryGUIClickEvent<T>) {
|
||||
clickEvent.gui.data.generalOnClick?.invoke(clickEvent)
|
||||
@@ -23,4 +19,7 @@ abstract class InventoryGUIElement<T : ForInventory>(
|
||||
|
||||
protected abstract fun onClickElement(clickEvent: InventoryGUIClickEvent<T>)
|
||||
|
||||
internal open fun startUsing(gui: InventoryGUI<*>) { }
|
||||
internal open fun stopUsing(gui: InventoryGUI<*>) { }
|
||||
|
||||
}
|
@@ -0,0 +1,15 @@
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
import org.bukkit.entity.HumanEntity
|
||||
import org.bukkit.inventory.InventoryView
|
||||
|
||||
fun HumanEntity.openGUI(gui: InventoryGUI<*>, page: Int? = null): InventoryView? {
|
||||
|
||||
closeInventory()
|
||||
|
||||
if (page != null)
|
||||
gui.loadPageUnsafe(page)
|
||||
|
||||
return openInventory(gui.bukkitInventory)
|
||||
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
import net.axay.kspigot.event.listen
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
|
||||
object InventoryGUIHolder : AutoCloseable {
|
||||
|
||||
private val registered = HashSet<InventoryGUI<ForInventory>>()
|
||||
|
||||
fun register(inventoryGUI: InventoryGUI<ForInventory>) {
|
||||
registered.add(inventoryGUI)
|
||||
}
|
||||
|
||||
fun unregister(inventoryGUI: InventoryGUI<ForInventory>) {
|
||||
registered.remove(inventoryGUI)
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
listen<InventoryClickEvent> {
|
||||
|
||||
val clickedInv = it.clickedInventory ?: return@listen
|
||||
|
||||
val inv = registered.find { search -> search.isThisInv(clickedInv) } ?: return@listen
|
||||
|
||||
if (inv.isInMove) {
|
||||
it.isCancelled = true
|
||||
return@listen
|
||||
}
|
||||
|
||||
val invPage = inv.currentPageInt
|
||||
|
||||
val slot = inv.data.pages[invPage]?.slots?.get(it.slot)
|
||||
if (slot != null)
|
||||
slot.onClick(InventoryGUIClickEvent(it, inv))
|
||||
else
|
||||
it.isCancelled = true
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
override fun close() {
|
||||
registered.forEach { inv -> inv.bukkitInventory.viewers.forEach { it.closeInventory() } }
|
||||
registered.clear()
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,8 @@
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
class InventoryGUIPage<T : ForInventory>(
|
||||
val number: Int,
|
||||
internal val slots: Map<Int, InventoryGUISlot<T>>,
|
||||
val transitionTo: PageChangeEffect?,
|
||||
val transitionFrom: PageChangeEffect?
|
||||
)
|
@@ -67,7 +67,7 @@ internal fun InventoryGUI<*>.changePage(
|
||||
|
||||
PageChangeEffect.SLIDE_VERTICALLY -> {
|
||||
|
||||
val height = data.inventoryType.dimensions.heigth
|
||||
val height = data.inventoryType.dimensions.height
|
||||
|
||||
changePageEffect(fromPageInt, toPageInt, height) { currentOffset, ifInverted ->
|
||||
if (ifInverted) {
|
||||
@@ -97,7 +97,7 @@ internal fun InventoryGUI<*>.changePage(
|
||||
|
||||
PageChangeEffect.SWIPE_VERTICALLY -> {
|
||||
|
||||
val height = data.inventoryType.dimensions.heigth
|
||||
val height = data.inventoryType.dimensions.height
|
||||
|
||||
changePageEffect(fromPageInt, toPageInt, height) { currentOffset, ifInverted ->
|
||||
if (ifInverted) {
|
||||
|
@@ -2,15 +2,17 @@
|
||||
|
||||
package net.axay.kspigot.inventory
|
||||
|
||||
import net.axay.kspigot.languageextensions.MinMaxPair
|
||||
import net.axay.kspigot.languageextensions.kotlinextensions.MinMaxPair
|
||||
|
||||
// INVENTORY
|
||||
|
||||
data class InventoryDimensions(val width: Int, val heigth: Int) {
|
||||
data class InventoryDimensions(val width: Int, val height: Int) {
|
||||
|
||||
val slotAmount = width * height
|
||||
|
||||
val invSlots by lazy {
|
||||
ArrayList<InventorySlot>().apply {
|
||||
(1..heigth).forEach { row ->
|
||||
(1..height).forEach { row ->
|
||||
(1..width).forEach { slotInRow ->
|
||||
this += InventorySlot(row, slotInRow)
|
||||
}
|
||||
@@ -18,14 +20,6 @@ data class InventoryDimensions(val width: Int, val heigth: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
val realSlots by lazy {
|
||||
ArrayList<Int>().apply {
|
||||
invSlots.forEach { curSlot ->
|
||||
curSlot.realSlotIn(this@InventoryDimensions)?.let { this += it }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val invSlotsWithRealSlots by lazy {
|
||||
HashMap<InventorySlot, Int>().apply {
|
||||
invSlots.forEach { curSlot ->
|
||||
@@ -34,6 +28,8 @@ data class InventoryDimensions(val width: Int, val heigth: Int) {
|
||||
}
|
||||
}
|
||||
|
||||
val realSlots by lazy { invSlotsWithRealSlots.values }
|
||||
|
||||
}
|
||||
|
||||
// SLOTS
|
||||
@@ -57,13 +53,13 @@ data class InventorySlot(val row: Int, val slotInRow: Int) : Comparable<Inventor
|
||||
|
||||
fun realSlotIn(inventoryDimensions: InventoryDimensions): Int? {
|
||||
if (!isInDimension(inventoryDimensions)) return null
|
||||
val realRow = inventoryDimensions.heigth - (row - 1)
|
||||
val realRow = inventoryDimensions.height - (row - 1)
|
||||
val rowsUnder = if (realRow - 1 >= 0) realRow - 1 else 0
|
||||
return ((rowsUnder * inventoryDimensions.width) + slotInRow) - 1
|
||||
}
|
||||
|
||||
fun isInDimension(inventoryDimensions: InventoryDimensions) =
|
||||
(1..inventoryDimensions.width).contains(slotInRow) && (1..inventoryDimensions.heigth).contains(row)
|
||||
(1..inventoryDimensions.width).contains(slotInRow) && (1..inventoryDimensions.height).contains(row)
|
||||
|
||||
fun add(offsetHorizontally: Int, offsetVertically: Int) = InventorySlot(
|
||||
row + offsetVertically,
|
||||
@@ -182,7 +178,7 @@ class InventoryColumnSlots<T : ForInventory> internal constructor(
|
||||
) : InventorySlotCompound<T> {
|
||||
|
||||
override fun withInvType(invType: InventoryType<T>) = HashSet<InventorySlot>().apply {
|
||||
for (row in 1..invType.dimensions.heigth)
|
||||
for (row in 1..invType.dimensions.height)
|
||||
this += InventorySlot(row, column)
|
||||
}
|
||||
|
||||
@@ -199,9 +195,9 @@ class InventoryBorderSlots<T : ForInventory> internal constructor(
|
||||
for (currentPadding in 0 until padding) {
|
||||
for (slotInRow in 1 + currentPadding..dimensions.width - currentPadding) {
|
||||
this += InventorySlot(1, slotInRow)
|
||||
this += InventorySlot(dimensions.heigth, slotInRow)
|
||||
this += InventorySlot(dimensions.height, slotInRow)
|
||||
}
|
||||
for (row in 2 + currentPadding until dimensions.heigth - currentPadding) {
|
||||
for (row in 2 + currentPadding until dimensions.height - currentPadding) {
|
||||
this += InventorySlot(row, 1)
|
||||
this += InventorySlot(row, dimensions.width)
|
||||
}
|
||||
@@ -224,8 +220,8 @@ class InventoryCornerSlots<T : ForInventory> internal constructor(
|
||||
|
||||
if (ifBottomLeft) this += InventorySlot(1, 1)
|
||||
if (ifBottomRight) this += InventorySlot(1, dimensions.width)
|
||||
if (ifTopLeft) this += InventorySlot(dimensions.heigth, 1)
|
||||
if (ifTopRight) this += InventorySlot(dimensions.heigth, dimensions.width)
|
||||
if (ifTopLeft) this += InventorySlot(dimensions.height, 1)
|
||||
if (ifTopRight) this += InventorySlot(dimensions.height, dimensions.width)
|
||||
|
||||
}
|
||||
|
||||
|
@@ -12,8 +12,6 @@ class InventoryType<in T : ForInventory>(
|
||||
val bukkitType: InventoryType? = null
|
||||
) {
|
||||
|
||||
private val size = dimensions.width * dimensions.heigth
|
||||
|
||||
companion object {
|
||||
|
||||
val ONE_BY_NINE = InventoryType<ForInventoryOneByNine>(InventoryDimensions(9, 1))
|
||||
@@ -33,7 +31,7 @@ class InventoryType<in T : ForInventory>(
|
||||
val realTitle = title ?: ""
|
||||
return when {
|
||||
bukkitType != null -> Bukkit.createInventory(holder, bukkitType, realTitle)
|
||||
else -> Bukkit.createInventory(holder, size, realTitle)
|
||||
else -> Bukkit.createInventory(holder, dimensions.slotAmount, realTitle)
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,14 +1,14 @@
|
||||
package net.axay.kspigot.inventory.elements
|
||||
|
||||
import net.axay.kspigot.inventory.ForInventory
|
||||
import net.axay.kspigot.inventory.InventoryGUIClickEvent
|
||||
import net.axay.kspigot.inventory.InventoryGUIElement
|
||||
import net.axay.kspigot.inventory.InventoryGUIElementData
|
||||
import net.axay.kspigot.inventory.*
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
open class InventoryGUIButton<T : ForInventory>(
|
||||
inventoryGUIElementData: InventoryGUIElementData,
|
||||
private val icon: ItemStack,
|
||||
val action: (InventoryGUIClickEvent<T>) -> Unit,
|
||||
) : InventoryGUIElement<T>(inventoryGUIElementData) {
|
||||
) : InventoryGUIElement<T>() {
|
||||
|
||||
override fun getItemStack(slot: Int) = icon
|
||||
|
||||
override fun onClickElement(clickEvent: InventoryGUIClickEvent<T>) {
|
||||
clickEvent.bukkitEvent.isCancelled = true
|
||||
|
@@ -1,13 +1,14 @@
|
||||
package net.axay.kspigot.inventory.elements
|
||||
|
||||
import net.axay.kspigot.inventory.*
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class InventoryGUIButtonInventoryChange<T : ForInventory>(
|
||||
inventoryGUIElementData: InventoryGUIElementData,
|
||||
icon: ItemStack,
|
||||
changeToGUICallback: () -> InventoryGUI<*>,
|
||||
changeToPageInt: Int?,
|
||||
onChange: ((InventoryGUIClickEvent<T>) -> Unit)?
|
||||
) : InventoryGUIButton<T>(inventoryGUIElementData, {
|
||||
) : InventoryGUIButton<T>(icon, {
|
||||
|
||||
val changeToGUI = changeToGUICallback.invoke()
|
||||
|
||||
|
@@ -1,12 +1,13 @@
|
||||
package net.axay.kspigot.inventory.elements
|
||||
|
||||
import net.axay.kspigot.inventory.*
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class InventoryGUIButtonPageChange<T : ForInventory>(
|
||||
inventoryGUIElementData: InventoryGUIElementData,
|
||||
icon: ItemStack,
|
||||
calculator: InventoryGUIPageChangeCalculator,
|
||||
onChange: ((InventoryGUIClickEvent<T>) -> Unit)?
|
||||
) : InventoryGUIButton<T>(inventoryGUIElementData, {
|
||||
) : InventoryGUIButton<T>(icon, {
|
||||
|
||||
val currentPage = it.gui.currentPage
|
||||
val newPage = it.gui.getPage(calculator.calculateNewPage(it.gui.currentPageInt, it.gui.data.pages.keys))
|
||||
|
@@ -1,13 +1,13 @@
|
||||
package net.axay.kspigot.inventory.elements
|
||||
|
||||
import net.axay.kspigot.inventory.ForInventory
|
||||
import net.axay.kspigot.inventory.InventoryGUIClickEvent
|
||||
import net.axay.kspigot.inventory.InventoryGUIElement
|
||||
import net.axay.kspigot.inventory.InventoryGUIElementData
|
||||
import net.axay.kspigot.inventory.*
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class InventoryGUIPlaceholder<T : ForInventory>(
|
||||
inventoryGUIElementData: InventoryGUIElementData
|
||||
) : InventoryGUIElement<T>(inventoryGUIElementData) {
|
||||
private val icon: ItemStack
|
||||
) : InventoryGUIElement<T>() {
|
||||
|
||||
override fun getItemStack(slot: Int) = icon
|
||||
|
||||
override fun onClickElement(clickEvent: InventoryGUIClickEvent<T>) {
|
||||
clickEvent.bukkitEvent.isCancelled = true
|
||||
|
@@ -0,0 +1,114 @@
|
||||
@file:Suppress("MemberVisibilityCanBePrivate", "unused")
|
||||
|
||||
package net.axay.kspigot.inventory.elements
|
||||
|
||||
import net.axay.kspigot.inventory.*
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class InventoryGUISpaceCompoundElement<T : ForInventory, E>(
|
||||
private val compound: InventoryGUISpaceCompound<T, E>
|
||||
) : InventoryGUIElement<T>() {
|
||||
|
||||
override fun getItemStack(slot: Int) = compound.getItemStack(slot)
|
||||
|
||||
override fun onClickElement(clickEvent: InventoryGUIClickEvent<T>) {
|
||||
compound.onClickElement(clickEvent)
|
||||
}
|
||||
|
||||
override fun startUsing(gui: InventoryGUI<*>) = compound.registerGUI(gui)
|
||||
|
||||
override fun stopUsing(gui: InventoryGUI<*>) = compound.unregisterGUI(gui)
|
||||
|
||||
}
|
||||
|
||||
class InventoryGUISpaceCompound<T : ForInventory, E>(
|
||||
private val invType: InventoryType<T>,
|
||||
private val iconGenerator: (E) -> ItemStack,
|
||||
private val onClick: (InventoryGUIClickEvent<T>, E) -> Unit
|
||||
) {
|
||||
|
||||
private val content = ArrayList<E>()
|
||||
|
||||
private val realInternalSlots = ArrayList<Int>()
|
||||
|
||||
private val currentInternalSlots: List<Int> get() {
|
||||
|
||||
val result = ArrayList(realInternalSlots)
|
||||
|
||||
var more = 1
|
||||
while (content.size > result.size) {
|
||||
result += realInternalSlots.mapTo(ArrayList()) { it + (more * invType.dimensions.slotAmount) }
|
||||
more++
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
}
|
||||
|
||||
private var scrolledLines: Int = 0
|
||||
|
||||
private var contentSort: () -> Unit = { }
|
||||
|
||||
private val registeredGUIs = HashSet<InventoryGUI<*>>()
|
||||
|
||||
private fun translateSlot(slot: Int) = (scrolledLines * invType.dimensions.width) + slot
|
||||
|
||||
private fun contentAtSlot(slot: Int) = content.getOrNull(
|
||||
realInternalSlots.indexOf(translateSlot(slot))
|
||||
)
|
||||
|
||||
internal fun getItemStack(slot: Int): ItemStack {
|
||||
return contentAtSlot(slot)?.let { return@let iconGenerator.invoke(it) }
|
||||
?: ItemStack(Material.AIR)
|
||||
}
|
||||
|
||||
internal fun onClickElement(clickEvent: InventoryGUIClickEvent<T>) {
|
||||
val element = contentAtSlot(clickEvent.bukkitEvent.slot) ?: return
|
||||
onClick.invoke(clickEvent, element)
|
||||
}
|
||||
|
||||
internal fun addSlots(slots: InventorySlotCompound<T>) {
|
||||
slots.realSlotsWithInvType(invType).forEach {
|
||||
if (!realInternalSlots.contains(it))
|
||||
realInternalSlots.add(it)
|
||||
}
|
||||
realInternalSlots.sort()
|
||||
}
|
||||
|
||||
internal fun registerGUI(gui: InventoryGUI<*>) {
|
||||
registeredGUIs += gui
|
||||
}
|
||||
|
||||
internal fun unregisterGUI(gui: InventoryGUI<*>) {
|
||||
registeredGUIs -= gui
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines the sort behaviour which gets applied to the content
|
||||
* automatically.
|
||||
*/
|
||||
fun <R : Comparable<R>> sortContentBy(reverse: Boolean = false, selector: (E) -> R?) {
|
||||
contentSort = {
|
||||
if (!reverse) content.sortBy(selector) else content.sortByDescending(selector)
|
||||
}
|
||||
contentSort.invoke()
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new element to the compound.
|
||||
*/
|
||||
fun addContent(element: E) {
|
||||
addContent(listOf(element))
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds new elements to the compound.
|
||||
*/
|
||||
fun addContent(elements: Collection<E>) {
|
||||
content += elements
|
||||
contentSort.invoke()
|
||||
registeredGUIs.forEach { it.reloadCurrentPage() }
|
||||
}
|
||||
|
||||
}
|
@@ -1,7 +1,7 @@
|
||||
package net.axay.kspigot.main
|
||||
|
||||
import net.axay.kspigot.inventory.InventoryGUIHolder
|
||||
import net.axay.kspigot.languageextensions.closeIfInitialized
|
||||
import net.axay.kspigot.languageextensions.kotlinextensions.closeIfInitialized
|
||||
import net.axay.kspigot.runnables.KRunnableHolder
|
||||
import org.bukkit.plugin.java.JavaPlugin
|
||||
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package net.axay.kspigot.particles
|
||||
|
||||
import net.axay.kspigot.extensions.bukkit.worldOrException
|
||||
import net.axay.kspigot.languageextensions.applyIfNotNull
|
||||
import net.axay.kspigot.languageextensions.kotlinextensions.applyIfNotNull
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Particle
|
||||
import org.bukkit.entity.Player
|
||||
|
@@ -1,7 +1,7 @@
|
||||
package net.axay.kspigot.sound
|
||||
|
||||
import net.axay.kspigot.extensions.bukkit.worldOrException
|
||||
import net.axay.kspigot.languageextensions.applyIfNotNull
|
||||
import net.axay.kspigot.languageextensions.kotlinextensions.applyIfNotNull
|
||||
import org.bukkit.Location
|
||||
import org.bukkit.Sound
|
||||
import org.bukkit.SoundCategory
|
||||
|
Reference in New Issue
Block a user