Skip to content

Commit

Permalink
fix: Support animating inventory on title change
Browse files Browse the repository at this point in the history
chore: Add example showcasing animated title
  • Loading branch information
0ffz committed May 31, 2024
1 parent 1843bfc commit 40ba1e9
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 31 deletions.
4 changes: 0 additions & 4 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile

val idofrontVersion: String by project

plugins {
alias(idofrontLibs.plugins.mia.kotlin.jvm)
alias(idofrontLibs.plugins.mia.papermc)
alias(idofrontLibs.plugins.mia.nms)
alias(idofrontLibs.plugins.mia.copyjar)
alias(idofrontLibs.plugins.mia.publication)
alias(idofrontLibs.plugins.mia.autoversion)
alias(idofrontLibs.plugins.mia.testing)
alias(idofrontLibs.plugins.jetbrainsCompose)
alias(idofrontLibs.plugins.compose.compiler)
}
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
kotlin.code.style=official
group=com.mineinabyss
version=0.10
idofrontVersion=0.24.0
idofrontVersion=0.24.1
Original file line number Diff line number Diff line change
@@ -1,18 +1,41 @@
package com.mineinabyss.guiy.example

import com.mineinabyss.guiy.example.gui.AnimatedTitle
import com.mineinabyss.guiy.example.gui.MainMenu
import com.mineinabyss.guiy.inventory.guiy
import com.mineinabyss.idofront.commands.execution.IdofrontCommandExecutor
import com.mineinabyss.idofront.commands.extensions.actions.playerAction
import org.bukkit.command.Command
import org.bukkit.command.CommandSender
import org.bukkit.command.TabCompleter

class GuiyCommands(val plugin: GuiyExamplePlugin) : IdofrontCommandExecutor() {
class GuiyCommands(val plugin: GuiyExamplePlugin) : IdofrontCommandExecutor(), TabCompleter {
override val commands = commands(plugin) {
"guiyexample" {
playerAction {
guiy {
MainMenu(player)
"creative" {
playerAction {
guiy {
MainMenu(player)
}
}
}
"animated" {
playerAction {
guiy {
AnimatedTitle(player)
}
}
}
}
}

override fun onTabComplete(
sender: CommandSender,
command: Command,
label: String,
args: Array<out String>?
): List<String> =
if (command.name == "guiyexample")
listOf("creative", "animated")
else listOf()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.mineinabyss.guiy.example.gui

import androidx.compose.runtime.*
import com.mineinabyss.guiy.components.canvases.Chest
import com.mineinabyss.guiy.inventory.LocalGuiyOwner
import com.mineinabyss.guiy.modifiers.Modifier
import com.mineinabyss.guiy.modifiers.fillMaxHeight
import kotlinx.coroutines.delay
import org.bukkit.entity.Player

@Composable
fun AnimatedTitle(player: Player) {
val owner = LocalGuiyOwner.current
var seconds by remember { mutableStateOf(0) }
LaunchedEffect(Unit) {
while (true) {
delay(1000)
seconds++
}
}
Chest(
setOf(player),
"<red>${seconds}s have passed!",
onClose = { owner.exit() },
modifier = Modifier.fillMaxHeight()
) {
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
package com.mineinabyss.guiy.example.gui

import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import com.mineinabyss.guiy.components.CreativeItem
import com.mineinabyss.guiy.components.Item
import com.mineinabyss.guiy.components.canvases.Chest
import com.mineinabyss.guiy.components.state.ItemPositions
import com.mineinabyss.guiy.inventory.LocalGuiyOwner
import com.mineinabyss.guiy.layout.Row
import com.mineinabyss.guiy.modifiers.Modifier
import com.mineinabyss.guiy.modifiers.fillMaxWidth
import com.mineinabyss.guiy.modifiers.size
import org.bukkit.Material
import org.bukkit.entity.Player
import org.bukkit.inventory.ItemStack
Expand Down
31 changes: 13 additions & 18 deletions src/main/kotlin/com/mineinabyss/guiy/components/canvases/Chest.kt
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
package com.mineinabyss.guiy.components.canvases

import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.remember
import androidx.compose.runtime.*
import com.mineinabyss.guiy.inventory.GuiyCanvas
import com.mineinabyss.guiy.inventory.GuiyOwner
import com.mineinabyss.guiy.inventory.LocalCanvas
import com.mineinabyss.guiy.layout.Layout
import com.mineinabyss.guiy.layout.Size
import com.mineinabyss.guiy.modifiers.Modifier
import com.mineinabyss.guiy.modifiers.SizeModifier
import com.mineinabyss.guiy.modifiers.onSizeChanged
import com.mineinabyss.guiy.modifiers.sizeIn
import com.mineinabyss.guiy.nodes.InventoryCloseScope
import com.mineinabyss.guiy.nodes.StaticMeasurePolicy
import com.mineinabyss.idofront.entities.title
import com.mineinabyss.idofront.textcomponents.miniMsg
import net.kyori.adventure.text.Component
import org.bukkit.Bukkit
import org.bukkit.entity.Player
import org.bukkit.inventory.Inventory
import org.bukkit.inventory.ItemStack
import java.lang.Integer.max

const val CHEST_WIDTH = 9
const val MIN_CHEST_HEIGHT = 1
Expand Down Expand Up @@ -58,18 +55,9 @@ fun Chest(
onClose: (InventoryCloseScope.(player: Player) -> Unit) = {},
content: @Composable () -> Unit,
) {
var size by remember { mutableStateOf(Size()) }
val constrainedModifier = modifier.sizeIn(CHEST_WIDTH, CHEST_WIDTH, MIN_CHEST_HEIGHT, MAX_CHEST_HEIGHT)
//TODO a proper way of reading size (onSizeChange recomposes twice when both title and size change.)
val size = remember(constrainedModifier) {
constrainedModifier.foldOut(Size()) { element, acc ->
if (element is SizeModifier)
acc.copy(
width = max(element.constraints.minWidth, acc.width),
height = max(element.constraints.minHeight, acc.height)
)
else acc
}
}
.onSizeChanged { if (size != it) size = it }

val canvas = remember(size) {
object : GuiyCanvas {
Expand All @@ -86,7 +74,7 @@ fun Chest(
val holder = rememberInventoryHolder(viewers, onClose)

// Create new inventory when any appropriate value changes
val inventory: Inventory = remember(title, size) {
val inventory: Inventory = remember(size) {
if (size == Size()) return@remember null
Bukkit.createInventory(holder, CHEST_WIDTH * size.height, title).also {
holder.activeInventory = it
Expand All @@ -99,6 +87,13 @@ fun Chest(
return
}

LaunchedEffect(title) {
// This just sends a packet, doesn't need to be on sync thread
inventory.viewers.forEach { it.openInventory.title(title) }
}

//TODO handle sending correct title when player list changes

CompositionLocalProvider(LocalCanvas provides canvas) {
Inventory(
inventory = inventory,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.mineinabyss.guiy.components.canvases

import androidx.compose.runtime.*
import com.github.shynixn.mccoroutine.bukkit.launch
import com.github.shynixn.mccoroutine.bukkit.minecraftDispatcher
import com.mineinabyss.guiy.guiyPlugin
import com.mineinabyss.guiy.inventory.GuiyInventoryHolder
import com.mineinabyss.guiy.inventory.LocalClickHandler
Expand All @@ -13,6 +14,7 @@ import com.mineinabyss.guiy.nodes.InventoryCloseScope
import com.mineinabyss.guiy.nodes.StaticMeasurePolicy
import com.mineinabyss.idofront.time.ticks
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import org.bukkit.entity.Player
import org.bukkit.event.Cancellable
import org.bukkit.event.inventory.InventoryCloseEvent
Expand Down Expand Up @@ -47,7 +49,7 @@ fun Inventory(
LaunchedEffect(viewers, inventory) {
val oldViewers = inventory.viewers.toSet()

guiyPlugin.launch {
withContext(guiyPlugin.minecraftDispatcher){
// Close inventory for removed viewers
(oldViewers - viewers).forEach {
it.closeInventory(InventoryCloseEvent.Reason.PLUGIN)
Expand Down

0 comments on commit 40ba1e9

Please sign in to comment.