1+ package br.com.devsrsouza.kotlinbukkitapi.tooling.menu
2+
3+ import com.intellij.util.ImageLoader
4+ import org.jetbrains.kotlin.utils.keysToMap
5+ import java.awt.*
6+ import javax.swing.JPanel
7+
8+ class InventoryComponent (
9+ val declaration : MenuDeclaration
10+ ) : JPanel() {
11+ companion object {
12+ val CHEST_SCALE = 2
13+ val CHEST_SINGLE_LINE_HEIGHT = 42
14+ val CHEST_LINE_DIFF = 18
15+ val CHEST_WIDTH = 176
16+
17+ private val minecraftFontResource = " /assets/fonts/Minecraftia-Regular.ttf"
18+ private val spritesFolder = " /assets/sprites"
19+ private val itemsSpriteFolder = " /assets/items"
20+ private val items13SpriteFolder = " /assets/items-13"
21+
22+ // the selected-border is 36x36 and not 32x32
23+ private val selectedBorderSizeDiff = 2
24+ }
25+
26+ private val lines = when {
27+ declaration.lines > 6 -> 6
28+ declaration.lines < 1 -> 1
29+ else -> declaration.lines
30+ }
31+
32+ private val spriteImage = ImageLoader .loadFromResource(
33+ " $spritesFolder /chest-${lines} .png"
34+ )!!
35+ private val itemsImage = declaration.slots.filter {
36+ it.line in 1 .. declaration.lines && it.slot in 1 .. 9
37+ }.keysToMap {
38+ // TODO: Support data
39+ val item13 = runCatching { MinecraftItem13 .valueOf(it.item) }.getOrNull()
40+
41+ if (item13 != null ) {
42+ ImageLoader .loadFromResource(" $items13SpriteFolder /${item13.name.toLowerCase()} .png" )
43+ } else {
44+ val item = runCatching { MinecraftItem .valueOf(it.item) }.getOrNull()
45+
46+ if (item != null ) {
47+ ImageLoader .loadFromResource(" $itemsSpriteFolder /${item.id} -0.png" )
48+ } else {
49+ null
50+ }
51+ }
52+ }
53+ private val selectionImage = if (declaration.slots.any { it.isSelected })
54+ ImageLoader .loadFromResource(" $spritesFolder /selected-border.png" )
55+ else null
56+
57+ private val minecraftFont = Font .createFont(
58+ Font .TRUETYPE_FONT ,
59+ this ::class .java.getResource(minecraftFontResource).openStream()
60+ ).deriveFont(18.5f )
61+
62+ init {
63+ isVisible = true
64+ minimumSize = calculateDimension()
65+ }
66+ override fun paintComponent (g : Graphics ) {
67+ val g = g as Graphics2D
68+ val oldTransform = g.transform
69+
70+ // drawing menu
71+ g.scale(CHEST_SCALE .toDouble(), CHEST_SCALE .toDouble())
72+ g.drawImage(spriteImage, 0 , 0 ,this )
73+
74+ g.transform = oldTransform
75+
76+ // drawing items
77+ for ((slot, texture) in itemsImage) {
78+ val (x, y) = calculateXYForSlot(slot)
79+
80+ g.drawImage(texture ? : continue , x, y, this )
81+
82+ // if is selected draw selection border
83+ if (slot.isSelected) {
84+ g.drawImage(
85+ selectionImage ? : continue ,
86+ x- selectedBorderSizeDiff,
87+ y- selectedBorderSizeDiff,
88+ this
89+ )
90+ }
91+ }
92+
93+ // drawing displayname
94+ g.font = minecraftFont
95+ g.color = Color .DARK_GRAY
96+ g.drawString(declaration.displayname, 16 , 40 )
97+ }
98+
99+ fun calculateXYForSlot (menuSlotDeclaration : MenuSlotDeclaration ): Pair <Int , Int > {
100+ val topXPadding = 18 * CHEST_SCALE
101+ val leftYPadding = 8 * CHEST_SCALE
102+ val itemSize = 16 * CHEST_SCALE
103+ val rightYPadding = 2 * CHEST_SCALE
104+ val bottomXPadding = 2 * CHEST_SCALE
105+
106+ val itemXPos = menuSlotDeclaration.line - 1
107+ val itemYPos = menuSlotDeclaration.slot - 1
108+
109+ val x = leftYPadding + (itemYPos * rightYPadding) + (itemYPos * itemSize)
110+ val y = topXPadding + (itemXPos * bottomXPadding) + (itemXPos * itemSize)
111+
112+ return x to y
113+ }
114+
115+ private fun calculateDimension (): Dimension {
116+ val height = CHEST_SINGLE_LINE_HEIGHT + (lines - 1 ) * CHEST_LINE_DIFF
117+
118+ return Dimension ((CHEST_WIDTH * CHEST_SCALE ).toInt(), (height * CHEST_SCALE ).toInt())
119+ }
120+ }
0 commit comments