Implement support for displaying chapters with varying content height

This commit is contained in:
Sollace 2024-01-29 20:30:58 +00:00
parent d4e698fa56
commit e15d64ff3d
No known key found for this signature in database
GPG key ID: E52FACE7B5C773DB
3 changed files with 91 additions and 19 deletions

View file

@ -160,7 +160,6 @@ public class SpellbookScreen extends HandledScreen<SpellbookScreenHandler> imple
tabs.getAllTabs().forEach(tab -> { tabs.getAllTabs().forEach(tab -> {
Bounds bounds = tab.bounds(); Bounds bounds = tab.bounds();
chapters.getCurrentChapter();
boolean hover = bounds.contains(mouseX, mouseY); boolean hover = bounds.contains(mouseX, mouseY);
int color = tab.chapter().color() & 0xFFFFFF; int color = tab.chapter().color() & 0xFFFFFF;

View file

@ -21,13 +21,17 @@ import net.minecraft.util.*;
public class DynamicContent implements Content { public class DynamicContent implements Content {
private static final Text UNKNOWN = Text.of("???"); private static final Text UNKNOWN = Text.of("???");
private static final Text UNKNOWN_LEVEL = Text.literal("Level: ???").formatted(Formatting.DARK_GREEN);
private SpellbookState.PageState state = new SpellbookState.PageState(); private SpellbookState.PageState state = new SpellbookState.PageState();
private final List<Page> pages; private final List<Page> pages;
private Bounds bounds = Bounds.empty(); private Bounds bounds = Bounds.empty();
private final Panel leftPanel = new Panel(this);
private final Panel rightPanel = new Panel(this);
private int headerColor;
public DynamicContent(PacketByteBuf buffer) { public DynamicContent(PacketByteBuf buffer) {
pages = buffer.readList(Page::new); pages = buffer.readList(Page::new);
} }
@ -35,32 +39,26 @@ public class DynamicContent implements Content {
@Override @Override
public void draw(DrawContext context, int mouseX, int mouseY, IViewRoot container) { public void draw(DrawContext context, int mouseX, int mouseY, IViewRoot container) {
int pageIndex = state.getOffset() * 2; int pageIndex = state.getOffset() * 2;
getPage(pageIndex).ifPresent(page -> page.draw(context, mouseX, mouseY, container));
context.getMatrices().push();
getPage(pageIndex + 1).ifPresent(page -> {
page.bounds.left = bounds.left + bounds.width / 2 + 20;
page.draw(context, mouseX, mouseY, container);
});
context.getMatrices().pop();
TextRenderer font = MinecraftClient.getInstance().textRenderer; TextRenderer font = MinecraftClient.getInstance().textRenderer;
int headerColor = mouseY % 255; headerColor = mouseY % 255;
Text pageText = Text.translatable("%s/%s", (pageIndex / 2) + 1, pages.size() / 2); Text pageText = Text.translatable("%s/%s", (pageIndex / 2) + 1, (int)Math.ceil(pages.size() / 2F));
context.drawText(font, pageText, (int)(337 - font.getWidth(pageText) / 2F), 190, headerColor, false); context.drawText(font, pageText, (int)(337 - font.getWidth(pageText) / 2F), 190, headerColor, false);
} }
@Override @Override
public void copyStateFrom(Content old) { public void copyStateFrom(Content old) {
if (old instanceof DynamicContent o) { if (old instanceof DynamicContent o) {
if (state.getOffset() == o.state.getOffset()) {
leftPanel.verticalScrollbar.getScrubber().scrollTo(o.leftPanel.verticalScrollbar.getScrubber().getPosition(), false);
rightPanel.verticalScrollbar.getScrubber().scrollTo(o.rightPanel.verticalScrollbar.getScrubber().getPosition(), false);
}
state = o.state; state = o.state;
setBounds(o.bounds); setBounds(o.bounds);
} }
} }
private Optional<Page> getPage(int index) { Optional<Page> getPage(int index) {
if (index < 0 || index >= pages.size()) { if (index < 0 || index >= pages.size()) {
return Optional.empty(); return Optional.empty();
} }
@ -71,9 +69,15 @@ public class DynamicContent implements Content {
this.bounds = bounds; this.bounds = bounds;
pages.forEach(page -> { pages.forEach(page -> {
page.reset(); page.reset();
int oldHeight = page.bounds.height;
page.bounds.copy(bounds); page.bounds.copy(bounds);
page.bounds.left = 0;
page.bounds.top = 0;
page.bounds.width /= 2; page.bounds.width /= 2;
page.bounds.height = oldHeight;
}); });
leftPanel.setBounds(bounds);
} }
@Override @Override
@ -83,6 +87,10 @@ public class DynamicContent implements Content {
screen.addPageButtons(187, 30, 350, incr -> { screen.addPageButtons(187, 30, 350, incr -> {
state.swap(incr, (int)Math.ceil(pages.size() / 2F)); state.swap(incr, (int)Math.ceil(pages.size() / 2F));
}); });
int pageIndex = state.getOffset() * 2;
leftPanel.init(screen, pageIndex);
rightPanel.init(screen, pageIndex + 1);
} }
class Page implements Drawable { class Page implements Drawable {
@ -145,18 +153,17 @@ public class DynamicContent implements Content {
element.compile(relativeY, container); element.compile(relativeY, container);
relativeY += element.bounds().height; relativeY += element.bounds().height;
} }
bounds.height = relativeY;
} }
boolean needsMoreXp = level < 0 || Pony.of(MinecraftClient.getInstance().player).getLevel().get() < level; boolean needsMoreXp = level < 0 || Pony.of(MinecraftClient.getInstance().player).getLevel().get() < level;
int headerColor = mouseY % 255;
MatrixStack matrices = context.getMatrices(); MatrixStack matrices = context.getMatrices();
DrawableUtil.drawScaledText(context, needsMoreXp ? UNKNOWN : title, bounds.left, bounds.top - 10, 1.3F, headerColor); DrawableUtil.drawScaledText(context, needsMoreXp ? UNKNOWN : title, bounds.left, bounds.top - 10, 1.3F, headerColor);
DrawableUtil.drawScaledText(context, level < 0 ? UNKNOWN_LEVEL : Text.literal("Level: " + (level + 1)).formatted(Formatting.DARK_GREEN), bounds.left, bounds.top - 10 + 12, 0.8F, headerColor); DrawableUtil.drawScaledText(context, Text.translatable("gui.unicopia.spellbook.page.level_requirement", level < 0 ? "???" : "" + (level + 1)).formatted(Formatting.DARK_GREEN), bounds.left, bounds.top - 10 + 12, 0.8F, headerColor);
matrices.push(); matrices.push();
matrices.translate(bounds.left, bounds.top + 16, 0); matrices.translate(0, 16, 0);
elements.stream().filter(PageElement::isFloating).forEach(element -> { elements.stream().filter(PageElement::isFloating).forEach(element -> {
Bounds bounds = element.bounds(); Bounds bounds = element.bounds();
matrices.push(); matrices.push();

View file

@ -0,0 +1,66 @@
package com.minelittlepony.unicopia.client.gui.spellbook.element;
import java.util.Optional;
import com.minelittlepony.common.client.gui.IViewRoot;
import com.minelittlepony.common.client.gui.ScrollContainer;
import com.minelittlepony.common.client.gui.dimension.Bounds;
import com.minelittlepony.unicopia.client.gui.spellbook.SpellbookScreen;
import com.minelittlepony.unicopia.client.gui.spellbook.element.DynamicContent.Page;
import net.minecraft.client.gui.DrawContext;
class Panel extends ScrollContainer {
private final DynamicContent content;
Panel(DynamicContent content) {
this.content = content;
}
private Optional<Page> page = Optional.empty();
public void init(SpellbookScreen screen, int pageIndex) {
verticalScrollbar.layoutToEnd = true;
getContentPadding().top = 15;
page = content.getPage(pageIndex);
margin.left = screen.getX() + 30;
margin.top = screen.getY() + 15;
margin.right = screen.width - screen.getBackgroundWidth() - screen.getX() + 20;
margin.bottom = screen.height - screen.getBackgroundHeight() - screen.getY() + 40;
if (pageIndex % 2 == 1) {
margin.left += screen.getBackgroundWidth() / 2 - 10;
} else {
margin.right += screen.getBackgroundWidth() / 2;
}
init(() -> {});
screen.addDrawable(this);
((IViewRoot)screen).getChildElements().add(this);
}
@Override
protected void renderContents(DrawContext context, int mouseX, int mouseY, float partialTicks) {
page.ifPresent(p -> {
int oldHeight = p.getBounds().height;
p.draw(context, mouseX, mouseY, this);
if (p.getBounds().height != oldHeight) {
verticalScrollbar.reposition();
}
});
super.renderContents(context, mouseX, mouseY, partialTicks);
}
@Override
public Bounds getContentBounds() {
return page == null ? Bounds.empty() : page.map(page -> {
return new Bounds(0, 0, 1, page.getBounds().height);
}).orElse(Bounds.empty());
}
@Override
protected void drawBackground(DrawContext context, int mouseX, int mouseY, float partialTicks) { }
@Override
protected void drawDecorations(DrawContext context, int mouseX, int mouseY, float partialTicks) { }
}