aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/at/hannibal2/skyhanni/data/NotificationManager.kt
blob: 748e4689286509b6afa5812293897709f1bd2081 (plain)
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
107
108
109
110
111
112
package at.hannibal2.skyhanni.data

import at.hannibal2.skyhanni.api.event.HandleEvent
import at.hannibal2.skyhanni.config.commands.CommandCategory
import at.hannibal2.skyhanni.config.commands.CommandRegistrationEvent
import at.hannibal2.skyhanni.events.GuiRenderEvent
import at.hannibal2.skyhanni.events.LorenzKeyPressEvent
import at.hannibal2.skyhanni.skyhannimodule.SkyHanniModule
import at.hannibal2.skyhanni.utils.GuiRenderUtils
import at.hannibal2.skyhanni.utils.InventoryUtils
import at.hannibal2.skyhanni.utils.SimpleTimeMark
import at.hannibal2.skyhanni.utils.TimeUtils.format
import at.hannibal2.skyhanni.utils.compat.GuiScreenUtils
import io.github.notenoughupdates.moulconfig.internal.RenderUtils
import net.minecraft.client.Minecraft
import net.minecraftforge.fml.common.eventhandler.SubscribeEvent
import org.lwjgl.input.Keyboard
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds

@SkyHanniModule
object NotificationManager {

    private val notificationQueue = mutableListOf<SkyHanniNotification>()

    private var currentNotification: SkyHanniNotification? = null
    private var lastNotificationClosed = SimpleTimeMark.farPast()

    private const val CLOSE_TEXT = "§c[X] Close"

    @SubscribeEvent
    fun onKeyClick(event: LorenzKeyPressEvent) {
        currentNotification ?: return
        if (lastNotificationClosed.passedSince() < 200.milliseconds) return
        if (event.keyCode != Keyboard.KEY_X) return
        currentNotification = null
        lastNotificationClosed = SimpleTimeMark.now()
    }

    @SubscribeEvent
    fun onRenderOverlay(event: GuiRenderEvent) {
        val notification = getCurrentNotification() ?: return

        if (InventoryUtils.inInventory() && !notification.showOverInventory) return

        val midX = GuiScreenUtils.scaledWindowWidth / 2
        val topY = (GuiScreenUtils.scaledWindowHeight * 0.75 - notification.height / 2).toInt()

        RenderUtils.drawFloatingRectDark(midX - notification.width / 2, topY, notification.width, notification.height)
        val closeTextWidth = Minecraft.getMinecraft().fontRendererObj.getStringWidth(CLOSE_TEXT)

        GuiRenderUtils.drawString(CLOSE_TEXT, midX + notification.width / 2 - 3 - closeTextWidth, topY + 4)

        if (notification.length.isFinite()) {
            val remainingTime = "§8" + notification.endTime.timeUntil().format()
            GuiRenderUtils.drawString(remainingTime, midX - notification.width / 2 + 4, topY + 4)
        }

        notification.message.forEachIndexed { index, line ->
            GuiRenderUtils.drawStringCentered("§7$line", midX, topY + 19 + index * 10)
        }
    }

    private fun getCurrentNotification(): SkyHanniNotification? {
        currentNotification?.let {
            if (it.endTime.isInPast()) currentNotification = null
        }
        if (currentNotification == null) {
            currentNotification = notificationQueue.removeFirstOrNull()
            currentNotification?.setEndTime()
        }
        return currentNotification
    }

    fun queueNotification(notification: SkyHanniNotification) {
        notificationQueue.add(notification)
    }

    @HandleEvent
    fun onCommandRegistration(event: CommandRegistrationEvent) {
        event.register("shtestnotification") {
            description = "Shows a test notification"
            category = CommandCategory.DEVELOPER_TEST
            callback {
                val testingText = it.joinToString(" ").replace("\\n", "\n")
                queueNotification(SkyHanniNotification(testingText, Duration.INFINITE))
            }
        }
    }
}

data class SkyHanniNotification(
    val message: List<String>,
    val length: Duration,
    val showOverInventory: Boolean = false,
) {
    constructor(message: String, length: Duration, showOverInventory: Boolean = false) : this(
        message.lines(),
        length,
        showOverInventory,
    )

    var endTime = SimpleTimeMark.farFuture()

    val width by lazy { (message.maxOfOrNull { Minecraft.getMinecraft().fontRendererObj.getStringWidth(it) } ?: 0) + 8 }
    val height by lazy { message.size * 10 + 18 }

    fun setEndTime() {
        if (length.isInfinite()) return
        endTime = SimpleTimeMark.now() + length
    }
}