Skip to content

Commit

Permalink
Refactor UI components for flexible layout handling
Browse files Browse the repository at this point in the history
Replaced static stack length management with dynamic gap sizing and layout direction handling in `StackContainer`. Updated `FocusHandler` to remove dependency on `ParentUIComponent`, simplifying the initialization and management of focus. Adjusted screen initialization in `TestScreen` to utilize a vertical layout with a configurable gap, enhancing UI modularity and maintainability.
  • Loading branch information
ThePandaOliver committed Dec 9, 2024
1 parent d2201c5 commit 4c1ac89
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,11 @@

public class TestScreen extends BasePLScreen<StackContainer> {
public TestScreen() {
super(StackContainer::new);
super(() -> {
StackContainer stack = StackContainer.createVerticalLayout();
stack.setGapSize(4);
return stack;
});
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,9 @@
import me.pandamods.pandalib.client.screen.core.UIComponent;
import me.pandamods.pandalib.client.screen.utils.FocusHandler;
import me.pandamods.pandalib.client.screen.utils.RenderContext;
import org.jetbrains.annotations.Nullable;

public abstract class BaseParentUIComponent extends BaseUIComponent implements ParentUIComponent {
protected FocusHandler focusHandler = new FocusHandler(this);
protected FocusHandler focusHandler;

@Override
public void render(RenderContext context, int mouseX, int mouseY, float partialTicks) {
Expand Down Expand Up @@ -55,9 +54,14 @@ public void updateChildState(UIComponent uiComponent) {
protected abstract void addChild(UIComponent UIComponent);
protected abstract void removeChild(UIComponent UIComponent);

@Override
public void mount(ParentUIComponent parent) {
super.mount(parent);
this.focusHandler = parent != null ? parent.getFocusHandler() : new FocusHandler();
}

@Override
public FocusHandler getFocusHandler() {
FocusHandler focusHandler = super.getFocusHandler();
return focusHandler != null ? focusHandler : this.focusHandler;
return this.focusHandler;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,30 +14,34 @@

import me.pandamods.pandalib.client.screen.BaseParentUIComponent;
import me.pandamods.pandalib.client.screen.core.UIComponent;
import me.pandamods.pandalib.client.screen.utils.RenderContext;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.function.Consumer;
import java.util.function.Supplier;

public class StackContainer extends BaseParentUIComponent {
private final List<UIComponent> children = new ArrayList<>();
private final List<UIComponent> viewChildren = Collections.unmodifiableList(children);

private boolean realign = true;
private int stackLength = 0;
protected Direction direction;
protected int gapSize = 0;

@Override
protected void renderChildren(RenderContext context, int mouseX, int mouseY, float partialTicks) {
if (realign) stackLength = 0;
super.renderChildren(context, mouseX, mouseY, partialTicks);
private int contentWidth = 0;
private int contentHeight = 0;

public static StackContainer createHorizontalLayout() {
return new StackContainer(Direction.HORIZONTAL);
}

@Override
public void renderChild(UIComponent child, RenderContext context, int mouseX, int mouseY, float partialTicks) {
if (realign) child.setY(stackLength);
super.renderChild(child, context, mouseX, mouseY, partialTicks);
if (realign) stackLength += child.getHeight();
public static StackContainer createVerticalLayout() {
return new StackContainer(Direction.VERTICAL);
}

public StackContainer(Direction direction) {
this.direction = direction;
}

@Override
Expand All @@ -61,10 +65,64 @@ protected void removeChild(UIComponent UIComponent) {
children.remove(UIComponent);
}

/**
* Realigns children next frame
*/
public void setDirection(Direction direction) {
this.direction = direction;
this.align();
}

public Direction getDirection() {
return direction;
}

public void setGapSize(int gapSize) {
this.gapSize = gapSize;
}

public int getGapSize() {
return gapSize;
}

public void align() {
realign = true;
int contentLength = 0;
int contentSize = 0;

Iterator<UIComponent> iterator = this.children.iterator();
while (iterator.hasNext()) {
UIComponent child = iterator.next();
Consumer<Integer> setPos = this.direction == Direction.HORIZONTAL ? child::setX : child::setY;
Supplier<Integer> getLength = this.direction == Direction.HORIZONTAL ? child::getWidth : child::getHeight;
Supplier<Integer> getSize = this.direction == Direction.HORIZONTAL ? child::getHeight : child::getWidth;

setPos.accept(contentLength);
contentLength += getLength.get();
if (iterator.hasNext()) {
contentLength += gapSize;
}
contentSize = Math.max(contentSize, getSize.get());
}

switch (this.direction) {
case HORIZONTAL -> {
contentWidth = contentLength;
contentHeight = contentSize;
}
case VERTICAL -> {
contentHeight = contentLength;
contentWidth = contentSize;
}
}
}

public int getContentWidth() {
return contentWidth;
}

public int getContentHeight() {
return contentHeight;
}

public enum Direction {
HORIZONTAL,
VERTICAL
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,15 @@

package me.pandamods.pandalib.client.screen.utils;

import me.pandamods.pandalib.client.screen.BaseParentUIComponent;
import me.pandamods.pandalib.client.screen.core.ParentUIComponent;
import me.pandamods.pandalib.client.screen.core.UIComponent;
import org.jetbrains.annotations.Nullable;

public class FocusHandler {
private final ParentUIComponent root;

@Nullable
protected UIComponent focused;

public FocusHandler(ParentUIComponent root) {
this.root = root;
}

public void focus(UIComponent focused) {
if (this.focused == focused) return;
if (this.focused != null) this.focused.onFocusLost();
this.focused = focused;
if (this.focused != null) this.focused.onFocusGained();
Expand All @@ -45,8 +38,4 @@ public UIComponent getFocused() {
public boolean isFocused(UIComponent component) {
return focused == component;
}

public ParentUIComponent getRoot() {
return root;
}
}

0 comments on commit 4c1ac89

Please sign in to comment.