feat(renderer): Introduce HorizontalAlignment and VerticalAlignment enums; refactor alignment handling and scaling in rendering components

This commit is contained in:
extio-de
2025-12-26 14:21:48 +01:00
parent ac8e680195
commit 5f49beec3c
15 changed files with 155 additions and 49 deletions

View File

@@ -10,7 +10,7 @@ public interface RendererControl {
public final static CoordI2 REFERENCE_RESOLUTION = ImmutableCoordI2.create(1920, 1080);
public final static double SCALE_FACTOR_MIN = 2.0 / 3.0;
public final static double SCALE_FACTOR_MIN = 0.5;
public final static double SCALE_FACTOR_MAX = 4.0;

View File

@@ -8,6 +8,9 @@ import de.extio.game_engine.event.EventService;
import de.extio.game_engine.module.AbstractClientModule;
import de.extio.game_engine.module.ModuleService;
import de.extio.game_engine.renderer.RendererControl;
import de.extio.game_engine.renderer.model.RenderingBo;
import de.extio.game_engine.renderer.model.bo.HorizontalAlignment;
import de.extio.game_engine.renderer.model.bo.VerticalAlignment;
import de.extio.game_engine.renderer.model.event.ViewportResizeEvent;
import de.extio.game_engine.renderer.work.RendererWorkingSet;
import de.extio.game_engine.renderer.work.RenderingBoPool;
@@ -20,30 +23,34 @@ import de.extio.game_engine.spatial2.model.MutableCoordI2;
public class Container extends AbstractClientModule implements InitializingBean {
protected final ModuleService moduleService;
protected final RenderingBoPool renderingBoPool;
protected final RendererControl rendererControl;
protected final RendererWorkingSet rendererWorkingSet;
protected final EventService eventService;
protected final Area2 area = new Area2(MutableCoordI2.create(), MutableCoordI2.create());
protected final Area2 normalizedArea = new Area2(MutableCoordI2.create(), MutableCoordI2.create());
protected boolean draggable;
protected boolean dragging;
protected HorizontalAlignment horizontalAlignment = HorizontalAlignment.CENTER;
protected VerticalAlignment verticalAlignment = VerticalAlignment.CENTER;
public Container(final ModuleService moduleService, final RenderingBoPool renderingBoPool, final RendererControl rendererControl, final EventService eventService, final RendererWorkingSet rendererWorkingSet) {
this.moduleService = moduleService;
this.renderingBoPool = renderingBoPool;
this.rendererControl = rendererControl;
this.eventService = eventService;
this.rendererWorkingSet = rendererWorkingSet;
}
@Override
@@ -56,50 +63,78 @@ public class Container extends AbstractClientModule implements InitializingBean
this.eventService.register(ViewportResizeEvent.class, this.id, this::onViewportResize);
this.onViewportResize(null);
}
@Override
public void onShow() {
this.draw();
}
@Override
public void onDeactivate() {
this.eventService.unregister(ViewportResizeEvent.class, this.id);
}
protected void onViewportResize(final ViewportResizeEvent event) {
this.setPosition(this.normalizedArea.getPosition());
this.setDimension(this.normalizedArea.getDimension());
this.setNormalizedPosition(this.normalizedArea.getPosition());
this.setNormalizedDimension(this.normalizedArea.getDimension());
this.draw();
}
protected void draw() {
// Override in subclasses, but make sure to call super.draw() at the end if overridden
/**
* Override in subclasses, but make sure to call super.draw() at the end if overridden
*/
public void draw() {
final var uncommitted = this.rendererWorkingSet.getUncommittedWork(this.id);
for (final RenderingBo bo : uncommitted.values()) {
bo.withPositionAbsoluteAnchorTopLeft(this.area.getPosition()
.toMutableCoordD2()
.add(bo.getLocalX(), bo.getLocalY())
.toImmutableCoordI2());
this.rendererWorkingSet.put(this.id, bo);
}
this.rendererWorkingSet.commit(this.id, true);
}
public void setPosition(final CoordI2 normalizedPosition) {
public void putRenderingBo(final RenderingBo renderingBo) {
this.rendererWorkingSet.put(this.id, renderingBo);
}
public void removeRenderingBo(final String renderingBoId) {
this.rendererWorkingSet.remove(this.id, renderingBoId);
}
public void clearRenderingBos() {
this.rendererWorkingSet.clearNext(this.id);
}
public void setNormalizedPosition(final CoordI2 normalizedPosition) {
this.normalizedArea.getPosition().setXY(normalizedPosition);
this.area.getPosition().setXY(
(int) (normalizedPosition.getX() * ((double) this.rendererControl.getEffectiveViewportDimension().getX() / RendererControl.REFERENCE_RESOLUTION.getX())),
(int) (normalizedPosition.getY() * ((double) this.rendererControl.getEffectiveViewportDimension().getY() / RendererControl.REFERENCE_RESOLUTION.getY())));
switch (this.horizontalAlignment) {
case LEFT -> this.area.getPosition().setX(normalizedPosition.getX());
case CENTER -> this.area.getPosition().setX(normalizedPosition.getX() + (this.rendererControl.getEffectiveViewportDimension().getX() - RendererControl.REFERENCE_RESOLUTION.getX()) / 2);
case RIGHT -> this.area.getPosition().setX(normalizedPosition.getX() + this.rendererControl.getEffectiveViewportDimension().getX() - RendererControl.REFERENCE_RESOLUTION.getX());
}
switch (this.verticalAlignment) {
case TOP -> this.area.getPosition().setY(normalizedPosition.getY());
case CENTER -> this.area.getPosition().setY(normalizedPosition.getY() + (this.rendererControl.getEffectiveViewportDimension().getY() - RendererControl.REFERENCE_RESOLUTION.getY()) / 2);
case BOTTOM -> this.area.getPosition().setY(normalizedPosition.getY() + this.rendererControl.getEffectiveViewportDimension().getY() - RendererControl.REFERENCE_RESOLUTION.getY());
}
this.draw();
this.LOGGER.debug("Effective viewport dimension: {}", this.rendererControl.getEffectiveViewportDimension());
}
public CoordI2 getPosition() {
public CoordI2 getNormalizedPosition() {
return this.normalizedArea.getPosition().toImmutableCoordI2();
}
public void setDimension(final CoordI2 normalizedDimension) {
public void setNormalizedDimension(final CoordI2 normalizedDimension) {
this.normalizedArea.getDimension().setXY(normalizedDimension);
this.area.getDimension().setXY(
(int) (normalizedDimension.getX() * ((double) this.rendererControl.getEffectiveViewportDimension().getX() / RendererControl.REFERENCE_RESOLUTION.getX())),
(int) (normalizedDimension.getY() * ((double) this.rendererControl.getEffectiveViewportDimension().getY() / RendererControl.REFERENCE_RESOLUTION.getY())));
this.area.getDimension().setXY(normalizedDimension);
this.draw();
}
public CoordI2 getDimension() {
public CoordI2 getNormalizedDimension() {
return this.normalizedArea.getDimension().toImmutableCoordI2();
}
@@ -110,4 +145,20 @@ public class Container extends AbstractClientModule implements InitializingBean
public void setDraggable(final boolean draggable) {
this.draggable = draggable;
}
public HorizontalAlignment getHorizontalAlignment() {
return horizontalAlignment;
}
public void setHorizontalAlignment(final HorizontalAlignment horizontalAlignment) {
this.horizontalAlignment = horizontalAlignment;
}
public VerticalAlignment getVerticalAlignment() {
return verticalAlignment;
}
public void setVerticalAlignment(final VerticalAlignment verticalAlignment) {
this.verticalAlignment = verticalAlignment;
}
}

View File

@@ -20,7 +20,7 @@ public class Window extends Container {
}
@Override
protected void draw() {
public void draw() {
if (this.area.getDimension().getX() <= 0 || this.area.getDimension().getY() <= 0) {
return;
}

View File

@@ -19,7 +19,8 @@ public class G2DRendererControl implements RendererControl {
protected static final Logger LOGGER = LoggerFactory.getLogger(G2DRendererControl.class);
private final static CoordI2 NO_SCALING_UPPER_LIMIT = ImmutableCoordI2.create(2560, 1440);
// private final static CoordI2 NO_SCALING_UPPER_LIMIT = ImmutableCoordI2.create(2560, 1440);
private final static CoordI2 NO_SCALING_UPPER_LIMIT = RendererControl.REFERENCE_RESOLUTION;
private final G2DRenderer renderer;

View File

@@ -15,7 +15,7 @@ import de.extio.game_engine.renderer.g2d.G2DRendererCondition;
import de.extio.game_engine.renderer.model.RenderingBo;
import de.extio.game_engine.renderer.model.RenderingBoLayer;
import de.extio.game_engine.renderer.model.bo.DrawFontRenderingBo;
import de.extio.game_engine.renderer.model.bo.DrawFontRenderingBoTextAlignment;
import de.extio.game_engine.renderer.model.bo.HorizontalAlignment;
import de.extio.game_engine.resource.StaticResource;
import de.extio.game_engine.resource.StaticResourceService;
import de.extio.game_engine.spatial2.model.CoordI2;
@@ -55,7 +55,7 @@ public class G2DDrawFont extends G2DAbstractRenderingBo implements DrawFontRende
private int size;
private DrawFontRenderingBoTextAlignment alignment = DrawFontRenderingBoTextAlignment.LEFT;
private HorizontalAlignment alignment = HorizontalAlignment.LEFT;
public G2DDrawFont() {
super(RenderingBoLayer.UI0_0);
@@ -74,7 +74,7 @@ public class G2DDrawFont extends G2DAbstractRenderingBo implements DrawFontRende
}
@Override
public DrawFontRenderingBo setAlignment(final DrawFontRenderingBoTextAlignment alignment) {
public DrawFontRenderingBo setAlignment(final HorizontalAlignment alignment) {
this.alignment = alignment;
return this;
}
@@ -125,7 +125,7 @@ public class G2DDrawFont extends G2DAbstractRenderingBo implements DrawFontRende
super.close();
this.text = null;
this.size = 0;
this.alignment = DrawFontRenderingBoTextAlignment.LEFT;
this.alignment = HorizontalAlignment.LEFT;
}
public static Font getFont(final double scaleFactor, final int size_) {

View File

@@ -27,7 +27,7 @@ import de.extio.game_engine.renderer.g2d.control.impl.G2DWindowCloseButtonContro
import de.extio.game_engine.renderer.model.RenderingBo;
import de.extio.game_engine.renderer.model.RenderingBoLayer;
import de.extio.game_engine.renderer.model.bo.ControlRenderingBo;
import de.extio.game_engine.renderer.model.bo.DrawFontRenderingBoTextAlignment;
import de.extio.game_engine.renderer.model.bo.HorizontalAlignment;
import de.extio.game_engine.renderer.model.color.RgbaColor;
@Conditional(G2DRendererCondition.class)
@@ -236,8 +236,8 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen
if (this.customData instanceof RgbaColor) {
((LabelControl) control).setBackgroundColor((RgbaColor) this.customData);
}
if (this.customData2 instanceof DrawFontRenderingBoTextAlignment) {
((LabelControl) control).setTextAlignment((DrawFontRenderingBoTextAlignment) this.customData2);
if (this.customData2 instanceof HorizontalAlignment) {
((LabelControl) control).setTextAlignment((HorizontalAlignment) this.customData2);
}
}
else if (this.clazz == ToggleButtonControl.class) {

View File

@@ -11,7 +11,7 @@ import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import de.extio.game_engine.renderer.g2d.bo.rendering.G2DDrawFont;
import de.extio.game_engine.renderer.model.bo.DrawFontRenderingBoTextAlignment;
import de.extio.game_engine.renderer.model.bo.HorizontalAlignment;
import de.extio.game_engine.spatial2.model.CoordI2;
import de.extio.game_engine.spatial2.model.ImmutableCoordI2;
@@ -38,7 +38,7 @@ public class CustomLabel extends Component {
protected Color foregroundColor;
private DrawFontRenderingBoTextAlignment textAlignment;
private HorizontalAlignment textAlignment;
protected boolean dirty = true;
@@ -72,11 +72,11 @@ public class CustomLabel extends Component {
this.foregroundColor = color;
}
public DrawFontRenderingBoTextAlignment getTextAlignment() {
public HorizontalAlignment getTextAlignment() {
return this.textAlignment;
}
public void setTextAlignment(final DrawFontRenderingBoTextAlignment textAlignment) {
public void setTextAlignment(final HorizontalAlignment textAlignment) {
this.textAlignment = textAlignment;
}
@@ -183,7 +183,7 @@ public class CustomLabel extends Component {
b = Math.max(0.0f, Math.min(1.0f, b));
g2d.setColor(Color.getHSBColor(h, s, b));
final var alignment = this.textAlignment == null ? DrawFontRenderingBoTextAlignment.CENTER : this.textAlignment;
final var alignment = this.textAlignment == null ? HorizontalAlignment.CENTER : this.textAlignment;
final var textDim = G2DDrawFont.getTextDimensions(this.caption, g2d, this.fontSize, this.scaleFactor);
switch (alignment) {
case LEFT: {

View File

@@ -2,7 +2,7 @@ package de.extio.game_engine.renderer.g2d.control.impl;
import de.extio.game_engine.renderer.g2d.G2DRenderer;
import de.extio.game_engine.renderer.g2d.control.components.CustomLabel;
import de.extio.game_engine.renderer.model.bo.DrawFontRenderingBoTextAlignment;
import de.extio.game_engine.renderer.model.bo.HorizontalAlignment;
import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.LabelControl;
import de.extio.game_engine.renderer.model.color.RgbaColor;
import de.extio.game_engine.renderer.model.event.UiControlEvent;
@@ -15,7 +15,7 @@ public class G2DLabelControlImpl extends G2DBaseControlImpl implements LabelCont
protected RgbaColor foregroundColor;
protected DrawFontRenderingBoTextAlignment textAlignment;
protected HorizontalAlignment textAlignment;
@Override
public RgbaColor getBackgroundColor() {
@@ -40,12 +40,12 @@ public class G2DLabelControlImpl extends G2DBaseControlImpl implements LabelCont
}
@Override
public DrawFontRenderingBoTextAlignment getTextAlignment() {
public HorizontalAlignment getTextAlignment() {
return this.textAlignment;
}
@Override
public void setTextAlignment(final DrawFontRenderingBoTextAlignment alignment) {
public void setTextAlignment(final HorizontalAlignment alignment) {
this.modified |= alignment != this.textAlignment;
this.textAlignment = alignment;
}

View File

@@ -110,9 +110,9 @@ public interface ControlRenderingBo extends RenderingBoHasDimension {
void setForegroundColor(RgbaColor color);
DrawFontRenderingBoTextAlignment getTextAlignment();
HorizontalAlignment getTextAlignment();
void setTextAlignment(DrawFontRenderingBoTextAlignment alignment);
void setTextAlignment(HorizontalAlignment alignment);
}

View File

@@ -11,6 +11,6 @@ public interface DrawFontRenderingBo extends RenderingBoHasDimension {
DrawFontRenderingBo setSize(final int size);
DrawFontRenderingBo setAlignment(DrawFontRenderingBoTextAlignment alignment);
DrawFontRenderingBo setAlignment(HorizontalAlignment alignment);
}

View File

@@ -1,6 +1,6 @@
package de.extio.game_engine.renderer.model.bo;
public enum DrawFontRenderingBoTextAlignment {
public enum HorizontalAlignment {
LEFT,
CENTER,

View File

@@ -0,0 +1,9 @@
package de.extio.game_engine.renderer.model.bo;
public enum VerticalAlignment {
BOTTOM,
CENTER,
TOP
}

View File

@@ -24,6 +24,8 @@ public interface RendererWorkingSet {
Map<String, RenderingBo> commit(String producerId, boolean clone);
void clearNext(String producerId);
void clear(String producerId);
void getLiveSet(List<RenderingBo> combinedLiveSet, Predicate<String> filter);

View File

@@ -116,6 +116,13 @@ public class RendererWorkingSetImpl implements RendererWorkingSet {
return rendererWork.next();
}
@Override
public void clearNext(final String producerId) {
final var next = this.getWorkingSetByProducer(producerId).next();
next.values().forEach(this.rendererBoPool::release);
next.clear();
}
@Override
public void clear(final String producerId) {
final RendererWork rendererWork = this.workingSet.remove(producerId);