1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
|
package at.hannibal2.skyhanni.utils.renderables
import at.hannibal2.skyhanni.events.GuiContainerEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.KeyboardManager.isKeyHeld
import net.minecraft.client.renderer.GlStateManager
import net.minecraft.init.Blocks
import net.minecraft.item.ItemStack
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
@SkyHanniModule
object DragNDrop {
private var currentDrag: DragItem<*>? = null
private var isInvalidDrop = false
private const val BUTTON = 0
private const val BUTTON_MAPPED = BUTTON - 100
private val invalidItem = Renderable.itemStack(ItemStack(Blocks.barrier), 1.0)
@SubscribeEvent
fun onGuiContainerBeforeDraw(event: GuiContainerEvent.PreDraw) {
isInvalidDrop = false
}
@SubscribeEvent
fun onGuiContainerAfterDraw(event: GuiContainerEvent.PostDraw) {
val item = currentDrag ?: return
if (!BUTTON_MAPPED.isKeyHeld()) {
currentDrag = null
return
}
GlStateManager.translate(event.mouseX.toFloat(), event.mouseY.toFloat(), 0f)
if (isInvalidDrop) {
invalidItem.render(event.mouseX, event.mouseY)
} else {
item.onRender(event.mouseX, event.mouseY)
}
GlStateManager.translate(-event.mouseX.toFloat(), -event.mouseY.toFloat(), 0f)
}
fun draggable(
display: Renderable,
item: () -> DragItem<*>,
bypassChecks: Boolean = false,
condition: () -> Boolean = { true },
) = Renderable.clickable(
display,
onClick = { currentDrag = item() },
button = BUTTON,
bypassChecks = bypassChecks,
condition = condition,
)
fun droppable(
display: Renderable,
drop: Droppable,
bypassChecks: Boolean = false,
condition: () -> Boolean = { true },
): Renderable = object : RenderableWrapper(display) {
override fun render(posX: Int, posY: Int) {
if (isHovered(posX, posY) && condition() && Renderable.shouldAllowLink(true, bypassChecks)) {
handelDroppable(drop)
}
content.render(posX, posY)
}
}
private fun handelDroppable(drop: Droppable) {
val item = currentDrag ?: return
if (drop.validTarget(item.get())) {
if (!BUTTON_MAPPED.isKeyHeld()) {
drop.handle(item.get())
currentDrag = null
}
} else {
isInvalidDrop = true
}
}
}
fun ItemStack.toDragItem(scale: Double = 1.0) = object : DragItem<ItemStack> {
val render = Renderable.itemStack(this@toDragItem, scale, 0)
override fun get(): ItemStack = this@toDragItem
override fun onRender(mouseX: Int, mouseY: Int) = render.render(mouseX, mouseY)
}
interface DragItem<T> {
fun get(): T
fun onRender(mouseX: Int, mouseY: Int)
}
interface Droppable {
fun handle(drop: Any?)
fun validTarget(item: Any?): Boolean
}
|