diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/G2DDrawControl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/G2DDrawControl.java index 4da24c5..d6237ee 100644 --- a/src/main/java/de/extio/game_engine/renderer/g2d/control/G2DDrawControl.java +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/G2DDrawControl.java @@ -14,6 +14,7 @@ import de.extio.game_engine.renderer.g2d.bo.rendering.G2DDrawFont; import de.extio.game_engine.renderer.g2d.control.impl.G2DBaseControlImpl; import de.extio.game_engine.renderer.g2d.control.impl.G2DButtonControlImpl; import de.extio.game_engine.renderer.g2d.control.impl.G2DLabelControlImpl; +import de.extio.game_engine.renderer.g2d.control.impl.G2DMultiLineTextAreaControlImpl; import de.extio.game_engine.renderer.g2d.control.impl.G2DSetFocusControl; import de.extio.game_engine.renderer.g2d.control.impl.G2DSliderControlImpl; import de.extio.game_engine.renderer.g2d.control.impl.G2DSwitchControlImpl; @@ -64,6 +65,8 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen private TextfieldData textfieldData; + private MultiLineTextAreaData multiLineTextAreaData; + private SliderData sliderData; private TableData tableData; @@ -140,6 +143,9 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen else if (data instanceof final TextfieldData textfieldData) { this.textfieldData = textfieldData; } + else if (data instanceof final MultiLineTextAreaData multiLineTextAreaData) { + this.multiLineTextAreaData = multiLineTextAreaData; + } else if (data instanceof final SliderData sliderData) { this.sliderData = sliderData; } @@ -229,6 +235,9 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen else if (this.clazz == TextfieldControl.class) { control = new G2DTextfieldControlImpl2(); } + else if (this.clazz == MultiLineTextAreaControl.class) { + control = new G2DMultiLineTextAreaControlImpl(); + } else if (this.clazz == ToggleButtonControl.class) { control = new G2DToggleButtonControlImpl(); } @@ -355,6 +364,12 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen tfc2.setLastCaptionUpdateTime(this.lastCaptionUpdateTime); } } + else if (this.clazz == MultiLineTextAreaControl.class && this.multiLineTextAreaData != null) { + ((MultiLineTextAreaControl) control).setCustomData(this.multiLineTextAreaData); + if (control instanceof final G2DMultiLineTextAreaControlImpl mtac) { + mtac.setLastCaptionUpdateTime(this.lastCaptionUpdateTime); + } + } else { for (final var customControlConfiguration : this.customControlConfigurations) { if (customControlConfiguration.getControlClass().equals(this.clazz)) { @@ -383,6 +398,7 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen this.windowCloseButtonData = o.windowCloseButtonData; this.windowPanelData = o.windowPanelData; this.textfieldData = o.textfieldData; + this.multiLineTextAreaData = o.multiLineTextAreaData; this.sliderData = o.sliderData; this.tableData = o.tableData; this.popupMenuData = o.popupMenuData; @@ -414,6 +430,7 @@ public class G2DDrawControl extends G2DAbstractRenderingBo implements ControlRen this.windowCloseButtonData = null; this.windowPanelData = null; this.textfieldData = null; + this.multiLineTextAreaData = null; this.sliderData = null; this.tableData = null; this.popupMenuData = null; diff --git a/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DMultiLineTextAreaControlImpl.java b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DMultiLineTextAreaControlImpl.java new file mode 100644 index 0000000..0a48fdd --- /dev/null +++ b/src/main/java/de/extio/game_engine/renderer/g2d/control/impl/G2DMultiLineTextAreaControlImpl.java @@ -0,0 +1,170 @@ +package de.extio.game_engine.renderer.g2d.control.impl; + +import java.awt.Graphics2D; + +import de.extio.game_engine.renderer.RendererData; +import de.extio.game_engine.renderer.g2d.G2DRenderer; +import de.extio.game_engine.renderer.g2d.control.components.CustomMultiLineTextArea; +import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.BaseControl; +import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.MultiLineTextAreaControl; +import de.extio.game_engine.renderer.model.bo.ControlRenderingBo.MultiLineTextAreaData; +import de.extio.game_engine.renderer.model.color.RgbaColor; +import de.extio.game_engine.renderer.model.event.UiControlEvent; + +public class G2DMultiLineTextAreaControlImpl extends G2DBaseControlImpl implements MultiLineTextAreaControl { + + private CustomMultiLineTextArea textArea; + + private boolean readonly; + + private long lastCaptionUpdateTime; + + private long lastCaptionUpdateTimeInternal; + + private String lastText = ""; + + private RgbaColor backgroundColor; + + private boolean scrollPositionModified; + + @Override + public void setCustomData(final MultiLineTextAreaData data) { + if (data != null) { + this.setReadonly(data.readonly()); + this.setBackgroundColor(data.backgroundColor()); + } + } + + public G2DMultiLineTextAreaControlImpl() { + } + + private void setBackgroundColor(final RgbaColor color) { + this.modified |= (color == null) ? this.backgroundColor != null : !color.equals(this.backgroundColor); + this.backgroundColor = color; + } + + private void setReadonly(final boolean readonly) { + this.modified |= readonly != this.readonly; + this.readonly = readonly; + } + + @Override + public BaseControl setCaption(final String caption) { + this.caption = caption; + return this; + } + + public void setLastCaptionUpdateTime(final long lastCaptionUpdateTime) { + this.modified |= this.lastCaptionUpdateTime != lastCaptionUpdateTime; + this.lastCaptionUpdateTime = lastCaptionUpdateTime; + } + + @Override + public void build() { + super.build(); + + this.textArea = new CustomMultiLineTextArea(this.rendererData.getThemeManager(), text -> { + this.lastText = text; + this.lastCaptionUpdateTimeInternal = System.currentTimeMillis(); + this.rendererData.getEventService().fire(new UiControlEvent(this.id, text)); + }); + + this.textArea.setName(this.id); + this.textArea.setFocusable(true); + this.initControl(); + + final var mainFrame = ((G2DRenderer) this.rendererData.getRenderer()).getMainFrame(); + mainFrame.add(this.textArea); + this.updateAllComponentZOrder(); + } + + @Override + public void performAction() { + } + + @Override + public void render() { + if (this.lastCaptionUpdateTime > this.lastCaptionUpdateTimeInternal && this.caption != null && !this.caption.equals(this.lastText)) { + this.textArea.setText(this.caption); + this.lastText = this.caption; + this.lastCaptionUpdateTimeInternal = this.lastCaptionUpdateTime; + } + + final boolean componentDirty = this.textArea.isDirty(); + if (this.modified || componentDirty || this.scrollPositionModified) { + this.rebuildBufferedImage(); + this.bufferedImageGraphics.setClip(0, 0, this.bufferedImage.getWidth(), this.bufferedImage.getHeight()); + this.textArea.setSize(this.bufferedImage.getWidth(), this.bufferedImage.getHeight()); + if (this.modified || componentDirty) { + this.initControl(); + } + this.textArea.paint(this.bufferedImageGraphics); + this.textArea.setDirty(false); + this.scrollPositionModified = false; + this.updateAllComponentZOrder(); + } + else if (this.positionModified) { + this.textArea.setLocation(this.x, this.y); + this.positionModified = false; + this.updateAllComponentZOrder(); + } + + this.textArea.paint(this.bufferedImageGraphics); + + super.render(); + } + + @Override + public void close() { + if (this.textArea.isFocusOwner()) { + ((G2DRenderer) this.rendererData.getRenderer()).getMainFrame().requestFocus(); + } + this.textArea.setVisible(false); + this.textArea.invalidate(); + ((G2DRenderer) this.rendererData.getRenderer()).getMainFrame().remove(this.textArea); + + super.close(); + } + + private void initControl() { + final var theme = this.rendererData.getThemeManager().getCurrentTheme(); + final var bgColor = this.backgroundColor != null ? this.backgroundColor.toAwtColor() : theme.getBackgroundNormal().toColor(); + final var fgColor = theme.getTextNormal().toColor(); + + this.textArea.setBackgroundColor(bgColor); + this.textArea.setForegroundColor(fgColor); + this.textArea.setFontSize(this.fontSize); + this.textArea.setScaleFactor(this.scaleFactor); + this.textArea.setLocation(this.x, this.y); + this.textArea.setSize(this.width, this.height); + this.positionModified = false; + this.textArea.setVisible(this.visible); + this.textArea.setEnabled(this.enabled); + this.textArea.setReadonly(this.readonly); + } + + @Override + public G2DBaseControlImpl setScaleFactor(final double scaleFactor) { + return super.setScaleFactor(scaleFactor); + } + + @Override + public BaseControl setControlGroup(final String controlGroup) { + return super.setControlGroup(controlGroup); + } + + @Override + public BaseControl setRendererData(final RendererData RendererData) { + return super.setRendererData(RendererData); + } + + @Override + public G2DBaseControlImpl setMainFrameGraphics(final Graphics2D graphics) { + return super.setMainFrameGraphics(graphics); + } + + @Override + public BaseControl setControlId(final String id) { + return super.setControlId(id); + } +} diff --git a/src/main/java/de/extio/game_engine/renderer/model/bo/ControlRenderingBo.java b/src/main/java/de/extio/game_engine/renderer/model/bo/ControlRenderingBo.java index aa0bea8..baf6d76 100644 --- a/src/main/java/de/extio/game_engine/renderer/model/bo/ControlRenderingBo.java +++ b/src/main/java/de/extio/game_engine/renderer/model/bo/ControlRenderingBo.java @@ -24,7 +24,9 @@ public interface ControlRenderingBo extends RenderingBoHasDimension { record WindowPanelData(boolean thickBorder, RgbaColor color) {} - record TextfieldData(boolean multiLine, boolean readonly, RgbaColor backgroundColor) {} + record TextfieldData(boolean readonly, RgbaColor backgroundColor) {} + + record MultiLineTextAreaData(boolean readonly, RgbaColor backgroundColor) {} record SliderData(boolean horizontal, double value, double value2, RgbaColor color) {} @@ -163,6 +165,15 @@ public interface ControlRenderingBo extends RenderingBoHasDimension { } + /** + * Multi-line text area (Java2D-based, no Swing) + */ + public static interface MultiLineTextAreaControl extends BaseControl { + + void setCustomData(MultiLineTextAreaData data); + + } + /** * Slider */