aboutsummaryrefslogtreecommitdiff
path: root/src/main/kotlin/features/items/recipes/RecipeScreen.kt
diff options
context:
space:
mode:
Diffstat (limited to 'src/main/kotlin/features/items/recipes/RecipeScreen.kt')
-rw-r--r--src/main/kotlin/features/items/recipes/RecipeScreen.kt122
1 files changed, 111 insertions, 11 deletions
diff --git a/src/main/kotlin/features/items/recipes/RecipeScreen.kt b/src/main/kotlin/features/items/recipes/RecipeScreen.kt
index c94839d..d365c0e 100644
--- a/src/main/kotlin/features/items/recipes/RecipeScreen.kt
+++ b/src/main/kotlin/features/items/recipes/RecipeScreen.kt
@@ -1,29 +1,129 @@
package moe.nea.firmament.features.items.recipes
+import me.shedaniel.math.Point
import me.shedaniel.math.Rectangle
+import net.minecraft.client.gui.GuiGraphics
import net.minecraft.client.gui.screens.Screen
-import moe.nea.firmament.repo.SBItemStack
+import net.minecraft.client.renderer.RenderPipelines
+import moe.nea.firmament.util.mc.CommonTextures
+import moe.nea.firmament.util.render.enableScissorWithTranslation
import moe.nea.firmament.util.tr
class RecipeScreen(
- val recipes: RenderableRecipe<*>,
+ val recipes: List<RenderableRecipe<*>>,
) : Screen(tr("firmament.recipe.screen", "SkyBlock Recipe")) {
- lateinit var layoutedRecipe: StandaloneRecipeRenderer
+ data class PlacedRecipe(
+ val bounds: Rectangle,
+ val layoutedRecipe: StandaloneRecipeRenderer,
+ ) {
+ fun moveTo(position: Point) {
+ val Δx = position.x - bounds.x
+ val Δy = position.y - bounds.y
+ bounds.translate(Δx, Δy)
+ layoutedRecipe.widgets.forEach { widget ->
+ widget.position = widget.position.clone().also {
+ it.translate(Δx, Δy)
+ }
+ }
+ }
+ }
+
+ lateinit var placedRecipes: List<PlacedRecipe>
+ var scrollViewport: Int = 0
+ var scrollOffset: Int = 0
+ var scrollPortWidth: Int = 0
+ var heightEstimate: Int = 0
+ val gutter = 10
override fun init() {// TODO: wrap all of this in a scroll layout
super.init()
- val bounds = Rectangle(
- width / 2 - recipes.renderer.displayWidth / 2,
- height / 2 - recipes.renderer.displayHeight / 2,
- recipes.renderer.displayWidth,
- recipes.renderer.displayHeight
+ scrollViewport = minOf(height - 20, 250)
+ scrollPortWidth = 0
+ heightEstimate = 0
+ var offset = height / 2 - scrollViewport / 2
+ placedRecipes = recipes.map {
+ val effectiveWidth = minOf(it.renderer.displayWidth, width - 20)
+ val bounds = Rectangle(
+ width / 2 - effectiveWidth / 2,
+ offset,
+ effectiveWidth,
+ it.renderer.displayHeight
+ )
+ if (heightEstimate > 0)
+ heightEstimate += gutter
+ heightEstimate += bounds.height
+ scrollPortWidth = maxOf(effectiveWidth, scrollPortWidth)
+ offset += bounds.height + gutter
+ val layoutedRecipe = it.render(bounds)
+ layoutedRecipe.widgets.forEach(this::addRenderableWidget)
+ PlacedRecipe(bounds, layoutedRecipe)
+ }
+ }
+
+ fun scrollRect() =
+ Rectangle(
+ width / 2 - scrollPortWidth / 2, height / 2 - scrollViewport / 2,
+ scrollPortWidth, scrollViewport
+ )
+
+ fun scissorScrollPort(guiGraphics: GuiGraphics) {
+ guiGraphics.enableScissorWithTranslation(scrollRect())
+ }
+
+ override fun mouseScrolled(mouseX: Double, mouseY: Double, scrollX: Double, scrollY: Double): Boolean {
+ if (!scrollRect().contains(mouseX, mouseY))
+ return false
+ scrollOffset = (scrollOffset + scrollY * -4)
+ .coerceAtMost(heightEstimate - scrollViewport.toDouble())
+ .coerceAtLeast(.0)
+ .toInt()
+ var offset = height / 2 - scrollViewport / 2 - scrollOffset
+ placedRecipes.forEach {
+ it.moveTo(Point(it.bounds.x, offset))
+ offset += it.bounds.height + gutter
+ }
+ return true
+ }
+
+ override fun renderBackground(
+ guiGraphics: GuiGraphics,
+ mouseX: Int,
+ mouseY: Int,
+ partialTick: Float
+ ) {
+ super.renderBackground(guiGraphics, mouseX, mouseY, partialTick)
+
+ val srect = scrollRect()
+ srect.grow(8, 8)
+ guiGraphics.blitSprite(
+ RenderPipelines.GUI_TEXTURED,
+ CommonTextures.genericWidget(),
+ srect.x, srect.y,
+ srect.width, srect.height
)
- layoutedRecipe = recipes.render(bounds)
- layoutedRecipe.widgets.forEach(this::addRenderableWidget)
+
+ scissorScrollPort(guiGraphics)
+ placedRecipes.forEach {
+ guiGraphics.blitSprite(
+ RenderPipelines.GUI_TEXTURED,
+ CommonTextures.genericWidget(),
+ it.bounds.x, it.bounds.y,
+ it.bounds.width, it.bounds.height
+ )
+ }
+ guiGraphics.disableScissor()
+ }
+
+ override fun render(guiGraphics: GuiGraphics, mouseX: Int, mouseY: Int, partialTick: Float) {
+ scissorScrollPort(guiGraphics)
+ super.render(guiGraphics, mouseX, mouseY, partialTick)
+ guiGraphics.disableScissor()
}
override fun tick() {
super.tick()
- layoutedRecipe.tick()
+ placedRecipes.forEach {
+ it.layoutedRecipe.tick()
+ }
}
}