ScrollableColumn
Zone à hauteur fixe qui scrolle son contenu en interne (molette + mini scrollbar). Idéale pour une liste de boutons ou d'éléments dont le nombre peut dépasser l'espace visible.
package ca.tawess123.apocalyinterface.api.layout;
Builder
ScrollableColumn sc = ScrollableColumn.builder()
.fixedHeight(int px) // hauteur fixe (requis)
.gap(int px) // gap entre enfants (défaut : 4 px)
.visibleIf(boolean) // visibilité conditionnelle (défaut : true)
.build();
Options du builder
| Option | Type | Défaut | Description |
|---|---|---|---|
.fixedHeight(int) | int | — | Hauteur retournée au layout parent, en pixels. Requis. |
.gap(int) | int | 4 | Gap vertical entre les enfants, en px. |
.visibleIf(boolean) | boolean | true | Masque la zone si false (0 px). |
Méthodes d'instance (après build())
sc.add(Widget widget) // ajouter un enfant (retourne void)
Hauteur retournée
fixedHeight — constante, indépendante du nombre d'enfants.
Le scrollbar interne apparaît automatiquement si le contenu dépasse fixedHeight.
Calcul recommandé de fixedHeight
Pour que les boutons ne soient jamais coupés :
// N boutons visibles × hauteur bouton + (N-1) × gap entre boutons
int h = N * ApocalyDimensions.BUTTON_HEIGHT + (N - 1) * Column.DEFAULT_GAP;
// 5 × 20 + 4 × 4 = 116 px
Règle de construction
Construire dans le constructeur, jamais dans buildLayout
Si la ScrollableColumn est créée dans buildLayout, l'offset de scroll est remis à zéro à chaque update() ou redimensionnement. Construis-la dans le constructeur de l'écran et ajoute-la à root dans buildLayout.
// Correct ✓
public class MonEcran extends ApocalyScreen {
private final ScrollableColumn buttonScroll;
public MonEcran() {
super(Component.translatable("monmod.screen.hub"), 260);
buttonScroll = ScrollableColumn.builder().fixedHeight(116).build();
buttonScroll.add(Button.builder().text("monmod.btn.a").command("cmd a").build());
buttonScroll.add(Button.builder().text("monmod.btn.b").command("cmd b").build());
// ...
}
@Override
protected void buildLayout(Column root) {
root.add(buttonScroll); // ajouter (pas recréer)
}
}
// Incorrect ✗ — scroll remis à zéro à chaque update()
@Override
protected void buildLayout(Column root) {
ScrollableColumn sc = ScrollableColumn.builder().fixedHeight(116).build();
// ↑ recréé à chaque buildLayout → offset de scroll perdu
root.add(sc);
}
Exemple complet
import ca.tawess123.apocalyinterface.api.layout.Column;
import ca.tawess123.apocalyinterface.api.layout.ScrollableColumn;
import ca.tawess123.apocalyinterface.api.screen.ApocalyScreen;
import ca.tawess123.apocalyinterface.api.theme.ApocalyDimensions;
import ca.tawess123.apocalyinterface.api.widget.Button;
import net.minecraft.network.chat.Component;
public final class JobsHubScreen extends ApocalyScreen {
private static final int SCROLL_H =
5 * ApocalyDimensions.BUTTON_HEIGHT + 4 * Column.DEFAULT_GAP;
private final ScrollableColumn jobsScroll;
public JobsHubScreen() {
super(Component.translatable("monmod.screen.jobs"), 240);
jobsScroll = ScrollableColumn.builder().fixedHeight(SCROLL_H).build();
jobsScroll.add(Button.builder().text("monmod.btn.mineur").command("job mineur").build());
jobsScroll.add(Button.builder().text("monmod.btn.bucheron").command("job bucheron").build());
jobsScroll.add(Button.builder().text("monmod.btn.fermier").command("job fermier").build());
jobsScroll.add(Button.builder().text("monmod.btn.chasseur").command("job chasseur").build());
jobsScroll.add(Button.builder().text("monmod.btn.forgeron").command("job forgeron").build());
jobsScroll.add(Button.builder().text("monmod.btn.marchand").command("job marchand").build());
jobsScroll.add(Button.builder().text("monmod.btn.alchimiste").command("job alchimiste").build());
}
@Override
protected void buildLayout(Column root) {
root.add(jobsScroll);
}
}