Skip to content

Commit 40ba1e9

Browse files
committed
fix: Support animating inventory on title change
chore: Add example showcasing animated title
1 parent 1843bfc commit 40ba1e9

File tree

7 files changed

+73
-31
lines changed

7 files changed

+73
-31
lines changed

build.gradle.kts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,11 @@
1-
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2-
31
val idofrontVersion: String by project
42

53
plugins {
64
alias(idofrontLibs.plugins.mia.kotlin.jvm)
75
alias(idofrontLibs.plugins.mia.papermc)
8-
alias(idofrontLibs.plugins.mia.nms)
96
alias(idofrontLibs.plugins.mia.copyjar)
107
alias(idofrontLibs.plugins.mia.publication)
118
alias(idofrontLibs.plugins.mia.autoversion)
12-
alias(idofrontLibs.plugins.mia.testing)
139
alias(idofrontLibs.plugins.jetbrainsCompose)
1410
alias(idofrontLibs.plugins.compose.compiler)
1511
}

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
kotlin.code.style=official
22
group=com.mineinabyss
33
version=0.10
4-
idofrontVersion=0.24.0
4+
idofrontVersion=0.24.1
Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,41 @@
11
package com.mineinabyss.guiy.example
22

3+
import com.mineinabyss.guiy.example.gui.AnimatedTitle
34
import com.mineinabyss.guiy.example.gui.MainMenu
45
import com.mineinabyss.guiy.inventory.guiy
56
import com.mineinabyss.idofront.commands.execution.IdofrontCommandExecutor
67
import com.mineinabyss.idofront.commands.extensions.actions.playerAction
8+
import org.bukkit.command.Command
9+
import org.bukkit.command.CommandSender
10+
import org.bukkit.command.TabCompleter
711

8-
class GuiyCommands(val plugin: GuiyExamplePlugin) : IdofrontCommandExecutor() {
12+
class GuiyCommands(val plugin: GuiyExamplePlugin) : IdofrontCommandExecutor(), TabCompleter {
913
override val commands = commands(plugin) {
1014
"guiyexample" {
11-
playerAction {
12-
guiy {
13-
MainMenu(player)
15+
"creative" {
16+
playerAction {
17+
guiy {
18+
MainMenu(player)
19+
}
20+
}
21+
}
22+
"animated" {
23+
playerAction {
24+
guiy {
25+
AnimatedTitle(player)
26+
}
1427
}
1528
}
1629
}
1730
}
31+
32+
override fun onTabComplete(
33+
sender: CommandSender,
34+
command: Command,
35+
label: String,
36+
args: Array<out String>?
37+
): List<String> =
38+
if (command.name == "guiyexample")
39+
listOf("creative", "animated")
40+
else listOf()
1841
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package com.mineinabyss.guiy.example.gui
2+
3+
import androidx.compose.runtime.*
4+
import com.mineinabyss.guiy.components.canvases.Chest
5+
import com.mineinabyss.guiy.inventory.LocalGuiyOwner
6+
import com.mineinabyss.guiy.modifiers.Modifier
7+
import com.mineinabyss.guiy.modifiers.fillMaxHeight
8+
import kotlinx.coroutines.delay
9+
import org.bukkit.entity.Player
10+
11+
@Composable
12+
fun AnimatedTitle(player: Player) {
13+
val owner = LocalGuiyOwner.current
14+
var seconds by remember { mutableStateOf(0) }
15+
LaunchedEffect(Unit) {
16+
while (true) {
17+
delay(1000)
18+
seconds++
19+
}
20+
}
21+
Chest(
22+
setOf(player),
23+
"<red>${seconds}s have passed!",
24+
onClose = { owner.exit() },
25+
modifier = Modifier.fillMaxHeight()
26+
) {
27+
}
28+
}

guiy-example/src/main/kotlin/com/mineinabyss/guiy/example/gui/MainMenu.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
package com.mineinabyss.guiy.example.gui
22

3-
import androidx.compose.runtime.*
3+
import androidx.compose.runtime.Composable
44
import com.mineinabyss.guiy.components.CreativeItem
55
import com.mineinabyss.guiy.components.Item
66
import com.mineinabyss.guiy.components.canvases.Chest
7-
import com.mineinabyss.guiy.components.state.ItemPositions
87
import com.mineinabyss.guiy.inventory.LocalGuiyOwner
98
import com.mineinabyss.guiy.layout.Row
109
import com.mineinabyss.guiy.modifiers.Modifier
1110
import com.mineinabyss.guiy.modifiers.fillMaxWidth
12-
import com.mineinabyss.guiy.modifiers.size
1311
import org.bukkit.Material
1412
import org.bukkit.entity.Player
1513
import org.bukkit.inventory.ItemStack

src/main/kotlin/com/mineinabyss/guiy/components/canvases/Chest.kt

Lines changed: 13 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,22 @@
11
package com.mineinabyss.guiy.components.canvases
22

3-
import androidx.compose.runtime.Composable
4-
import androidx.compose.runtime.CompositionLocalProvider
5-
import androidx.compose.runtime.remember
3+
import androidx.compose.runtime.*
64
import com.mineinabyss.guiy.inventory.GuiyCanvas
7-
import com.mineinabyss.guiy.inventory.GuiyOwner
85
import com.mineinabyss.guiy.inventory.LocalCanvas
96
import com.mineinabyss.guiy.layout.Layout
107
import com.mineinabyss.guiy.layout.Size
118
import com.mineinabyss.guiy.modifiers.Modifier
12-
import com.mineinabyss.guiy.modifiers.SizeModifier
9+
import com.mineinabyss.guiy.modifiers.onSizeChanged
1310
import com.mineinabyss.guiy.modifiers.sizeIn
1411
import com.mineinabyss.guiy.nodes.InventoryCloseScope
1512
import com.mineinabyss.guiy.nodes.StaticMeasurePolicy
13+
import com.mineinabyss.idofront.entities.title
1614
import com.mineinabyss.idofront.textcomponents.miniMsg
1715
import net.kyori.adventure.text.Component
1816
import org.bukkit.Bukkit
1917
import org.bukkit.entity.Player
2018
import org.bukkit.inventory.Inventory
2119
import org.bukkit.inventory.ItemStack
22-
import java.lang.Integer.max
2320

2421
const val CHEST_WIDTH = 9
2522
const val MIN_CHEST_HEIGHT = 1
@@ -58,18 +55,9 @@ fun Chest(
5855
onClose: (InventoryCloseScope.(player: Player) -> Unit) = {},
5956
content: @Composable () -> Unit,
6057
) {
58+
var size by remember { mutableStateOf(Size()) }
6159
val constrainedModifier = modifier.sizeIn(CHEST_WIDTH, CHEST_WIDTH, MIN_CHEST_HEIGHT, MAX_CHEST_HEIGHT)
62-
//TODO a proper way of reading size (onSizeChange recomposes twice when both title and size change.)
63-
val size = remember(constrainedModifier) {
64-
constrainedModifier.foldOut(Size()) { element, acc ->
65-
if (element is SizeModifier)
66-
acc.copy(
67-
width = max(element.constraints.minWidth, acc.width),
68-
height = max(element.constraints.minHeight, acc.height)
69-
)
70-
else acc
71-
}
72-
}
60+
.onSizeChanged { if (size != it) size = it }
7361

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

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

90+
LaunchedEffect(title) {
91+
// This just sends a packet, doesn't need to be on sync thread
92+
inventory.viewers.forEach { it.openInventory.title(title) }
93+
}
94+
95+
//TODO handle sending correct title when player list changes
96+
10297
CompositionLocalProvider(LocalCanvas provides canvas) {
10398
Inventory(
10499
inventory = inventory,

src/main/kotlin/com/mineinabyss/guiy/components/canvases/Inventory.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package com.mineinabyss.guiy.components.canvases
22

33
import androidx.compose.runtime.*
44
import com.github.shynixn.mccoroutine.bukkit.launch
5+
import com.github.shynixn.mccoroutine.bukkit.minecraftDispatcher
56
import com.mineinabyss.guiy.guiyPlugin
67
import com.mineinabyss.guiy.inventory.GuiyInventoryHolder
78
import com.mineinabyss.guiy.inventory.LocalClickHandler
@@ -13,6 +14,7 @@ import com.mineinabyss.guiy.nodes.InventoryCloseScope
1314
import com.mineinabyss.guiy.nodes.StaticMeasurePolicy
1415
import com.mineinabyss.idofront.time.ticks
1516
import kotlinx.coroutines.delay
17+
import kotlinx.coroutines.withContext
1618
import org.bukkit.entity.Player
1719
import org.bukkit.event.Cancellable
1820
import org.bukkit.event.inventory.InventoryCloseEvent
@@ -47,7 +49,7 @@ fun Inventory(
4749
LaunchedEffect(viewers, inventory) {
4850
val oldViewers = inventory.viewers.toSet()
4951

50-
guiyPlugin.launch {
52+
withContext(guiyPlugin.minecraftDispatcher){
5153
// Close inventory for removed viewers
5254
(oldViewers - viewers).forEach {
5355
it.closeInventory(InventoryCloseEvent.Reason.PLUGIN)

0 commit comments

Comments
 (0)