Removed "Inventory" from the GUI API names
This commit is contained in:
254
src/main/kotlin/net/axay/kspigot/gui/GUIBuilder.kt
Normal file
254
src/main/kotlin/net/axay/kspigot/gui/GUIBuilder.kt
Normal file
@@ -0,0 +1,254 @@
|
||||
@file:Suppress("MemberVisibilityCanBePrivate", "unused")
|
||||
|
||||
package net.axay.kspigot.gui
|
||||
|
||||
import net.axay.kspigot.gui.elements.*
|
||||
import org.bukkit.inventory.ItemStack
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
fun <T : ForInventory> kSpigotGUI(
|
||||
type: GUIType<T>,
|
||||
shared: Boolean = true,
|
||||
builder: GUIBuilder<T>.() -> Unit,
|
||||
) = GUIBuilder(type, shared).apply(builder).build()
|
||||
|
||||
class GUIBuilder<T : ForInventory>(
|
||||
val type: GUIType<T>,
|
||||
val shared: Boolean
|
||||
) {
|
||||
|
||||
var title: String = ""
|
||||
|
||||
var transitionTo: InventoryChangeEffect? = null
|
||||
var transitionFrom: InventoryChangeEffect? = null
|
||||
|
||||
private val guiSlots = HashMap<Int, GUIPage<T>>()
|
||||
|
||||
private var onClickElement: ((GUIClickEvent<T>) -> Unit)? = null
|
||||
|
||||
/**
|
||||
* Opens the builder for a new page and adds
|
||||
* the new page to the GUI.
|
||||
* @param page The index of the page.
|
||||
*/
|
||||
fun page(page: Int, builder: GUIPageBuilder<T>.() -> Unit) {
|
||||
guiSlots[page] = GUIPageBuilder(type, page).apply(builder).build()
|
||||
}
|
||||
|
||||
fun onClickElement(onClick: (GUIClickEvent<T>) -> Unit) {
|
||||
onClickElement = onClick
|
||||
}
|
||||
|
||||
internal fun build(): GUI<T> {
|
||||
val guiData = GUIData(type, title, guiSlots, transitionTo, transitionFrom, onClickElement)
|
||||
val gui =
|
||||
if (shared) GUIShared(guiData) else TODO("Currently, there is no non-shared GUI implementation available.")
|
||||
return gui.apply { register() }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class GUIPageBuilder<T : ForInventory>(
|
||||
private val type: GUIType<T>,
|
||||
val page: Int
|
||||
) {
|
||||
|
||||
private val guiSlots = HashMap<Int, GUISlot<T>>()
|
||||
|
||||
var transitionTo: PageChangeEffect? = null
|
||||
var transitionFrom: PageChangeEffect? = null
|
||||
|
||||
internal fun build() = GUIPage(page, guiSlots, transitionTo, transitionFrom)
|
||||
|
||||
private fun defineSlots(slots: InventorySlotCompound<T>, element: GUISlot<T>) =
|
||||
slots.withInvType(type).forEach { curSlot ->
|
||||
curSlot.realSlotIn(type.dimensions)?.let { guiSlots[it] = element }
|
||||
}
|
||||
|
||||
/**
|
||||
* A button is an item protected from any player
|
||||
* actions. If clicked, the specified [onClick]
|
||||
* function is invoked.
|
||||
*/
|
||||
fun button(slots: InventorySlotCompound<T>, itemStack: ItemStack, onClick: (GUIClickEvent<T>) -> Unit) =
|
||||
defineSlots(slots, GUIButton(itemStack, onClick))
|
||||
|
||||
/**
|
||||
* An item protected from any player actions.
|
||||
* This is not a button.
|
||||
*/
|
||||
fun placeholder(slots: InventorySlotCompound<T>, itemStack: ItemStack) =
|
||||
defineSlots(slots, GUIPlaceholder(itemStack))
|
||||
|
||||
/**
|
||||
* A free slot does not block any player actions.
|
||||
* The player can put items in this slot or take
|
||||
* items out of it.
|
||||
*/
|
||||
fun freeSlot(slots: InventorySlotCompound<T>) = defineSlots(slots, GUIFreeSlot())
|
||||
|
||||
/**
|
||||
* This is a button which loads the specified
|
||||
* [toPage] if clicked.
|
||||
*/
|
||||
fun pageChanger(
|
||||
slots: InventorySlotCompound<T>,
|
||||
icon: ItemStack,
|
||||
toPage: Int,
|
||||
onChange: ((GUIClickEvent<T>) -> Unit)? = null
|
||||
) = defineSlots(
|
||||
slots, GUIButtonPageChange(
|
||||
icon,
|
||||
GUIPageChangeCalculator.GUIConsistentPageCalculator(toPage),
|
||||
onChange
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* This button always tries to find the previous
|
||||
* page if clicked, and if a previous page
|
||||
* exists it is loaded.
|
||||
*/
|
||||
fun previousPage(
|
||||
slots: InventorySlotCompound<T>,
|
||||
icon: ItemStack,
|
||||
onChange: ((GUIClickEvent<T>) -> Unit)? = null
|
||||
) = defineSlots(
|
||||
slots, GUIButtonPageChange(
|
||||
icon,
|
||||
GUIPageChangeCalculator.GUIPreviousPageCalculator,
|
||||
onChange
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* This button always tries to find the next
|
||||
* page if clicked, and if a next page
|
||||
* exists it is loaded.
|
||||
*/
|
||||
fun nextPage(
|
||||
slots: InventorySlotCompound<T>,
|
||||
icon: ItemStack,
|
||||
onChange: ((GUIClickEvent<T>) -> Unit)? = null
|
||||
) = defineSlots(
|
||||
slots, GUIButtonPageChange(
|
||||
icon,
|
||||
GUIPageChangeCalculator.GUINextPageCalculator,
|
||||
onChange
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* By pressing this button, the player switches to another
|
||||
* GUI. The transition effect is applied.
|
||||
*/
|
||||
fun changeGUI(
|
||||
slots: InventorySlotCompound<T>,
|
||||
icon: ItemStack,
|
||||
newGUI: () -> GUI<*>,
|
||||
newPage: Int? = null,
|
||||
onChange: ((GUIClickEvent<T>) -> Unit)? = null
|
||||
) = defineSlots(
|
||||
slots, GUIButtonInventoryChange(
|
||||
icon,
|
||||
newGUI,
|
||||
newPage,
|
||||
onChange
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* Creates a new compound, holding data which can be displayed
|
||||
* in any compound space.
|
||||
*/
|
||||
fun <E> createCompound(
|
||||
iconGenerator: (E) -> ItemStack,
|
||||
onClick: (clickEvent: GUIClickEvent<T>, element: E) -> Unit
|
||||
) = GUISpaceCompound(type, iconGenerator, onClick)
|
||||
|
||||
/**
|
||||
* Creates a new compound, holding data which can be displayed
|
||||
* in any compound space.
|
||||
* This compound is strictly a rectangle.
|
||||
* The space is automatically defined.
|
||||
*/
|
||||
fun <E> createCompound(
|
||||
fromSlot: SingleInventorySlot<out T>,
|
||||
toSlot: SingleInventorySlot<out T>,
|
||||
iconGenerator: (E) -> ItemStack,
|
||||
onClick: (clickEvent: GUIClickEvent<T>, element: E) -> Unit
|
||||
): GUIRectSpaceCompound<T, E> {
|
||||
val rectSlotCompound = fromSlot rectTo toSlot
|
||||
return GUIRectSpaceCompound(
|
||||
type,
|
||||
iconGenerator,
|
||||
onClick,
|
||||
(rectSlotCompound.endInclusive.slotInRow - rectSlotCompound.start.slotInRow) + 1
|
||||
).apply {
|
||||
addSlots(rectSlotCompound)
|
||||
defineSlots(
|
||||
rectSlotCompound,
|
||||
GUISpaceCompoundElement(this)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an area where the content of the given compound
|
||||
* is displayed.
|
||||
*/
|
||||
fun <E> compoundSpace(
|
||||
slots: InventorySlotCompound<T>,
|
||||
compound: AbstractGUISpaceCompound<T, E>
|
||||
) {
|
||||
compound.addSlots(slots)
|
||||
defineSlots(
|
||||
slots,
|
||||
GUISpaceCompoundElement(compound)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* By pressing this button,
|
||||
* the user scrolls forwards or backwards in the compound.
|
||||
*/
|
||||
fun compoundScroll(
|
||||
slots: InventorySlotCompound<T>,
|
||||
icon: ItemStack,
|
||||
compound: GUISpaceCompound<T, *>,
|
||||
scrollDistance: Int = 1,
|
||||
scrollTimes: Int = 1,
|
||||
reverse: Boolean = false
|
||||
) = defineSlots(
|
||||
slots,
|
||||
GUISpaceCompoundScrollButton(
|
||||
icon,
|
||||
compound,
|
||||
scrollDistance.absoluteValue,
|
||||
scrollTimes,
|
||||
reverse
|
||||
)
|
||||
)
|
||||
|
||||
/**
|
||||
* By pressing this button,
|
||||
* the user scrolls forwards or backwards in the compound.
|
||||
*/
|
||||
fun compoundScroll(
|
||||
slots: InventorySlotCompound<T>,
|
||||
icon: ItemStack,
|
||||
compound: GUIRectSpaceCompound<T, *>,
|
||||
scrollTimes: Int = 1,
|
||||
reverse: Boolean = false
|
||||
) = defineSlots(
|
||||
slots,
|
||||
GUISpaceCompoundScrollButton(
|
||||
icon,
|
||||
compound,
|
||||
compound.compoundWidth,
|
||||
scrollTimes,
|
||||
reverse
|
||||
)
|
||||
)
|
||||
|
||||
}
|
Reference in New Issue
Block a user