diff --git a/embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/core/controlmgr/ComponentSettingsBuilder.java b/embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/core/controlmgr/ComponentSettingsBuilder.java index 718c8dd8..bdf332ad 100644 --- a/embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/core/controlmgr/ComponentSettingsBuilder.java +++ b/embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/core/controlmgr/ComponentSettingsBuilder.java @@ -16,6 +16,8 @@ * justification, position, control type, drawing mode, and custom drawing configuration. */ public class ComponentSettingsBuilder { + public enum BuildingMode { MENU, TEXT, IMAGE } + private final static Set POSSIBLE_TIME_TYPES = Set.of( EditItemType.TIME_12H, EditItemType.TIME_24_HUNDREDS, @@ -23,6 +25,8 @@ public class ComponentSettingsBuilder { EditItemType.TIME_12H_HHMM, EditItemType.TIME_24H_HHMM); + private BuildingMode mode; + private String text; private MenuItem item; private FontInformation fontInfo = FONT_100_PERCENT; private ConditionalColoring colors; @@ -39,6 +43,7 @@ public class ComponentSettingsBuilder { /// @param color the colors to use for the control public static ComponentSettingsBuilder forMenuItem(MenuItem item, ConditionalColoring color) { var b = new ComponentSettingsBuilder(); + b.mode = BuildingMode.MENU; b.colors = color; b.item = item; b.withControlType(defaultControlForType(item)); @@ -46,6 +51,16 @@ public static ComponentSettingsBuilder forMenuItem(MenuItem item, ConditionalCol return b; } + public static ComponentSettingsBuilder forText(String text, ConditionalColoring color) { + var b = new ComponentSettingsBuilder(); + b.mode = BuildingMode.TEXT; + b.colors = color; + b.text = text; + b.withControlType(ControlType.TEXT_CONTROL); + b.withJustification(PortableAlignment.LEFT); + return b; + } + private static PortableAlignment defaultJustificationForType(ControlType controlType) { return switch(controlType) { case HORIZONTAL_SLIDER, UP_DOWN_CONTROL -> PortableAlignment.LEFT_VAL_RIGHT; @@ -89,22 +104,34 @@ public ComponentSettingsBuilder withJustification(PortableAlignment justificatio return this; } - /// Set the position of the control in the grid. Pretty much must always be set + /// Set the position of the control in the grid. Must always be set, for simpler cases with + /// no span you can use `withRowCol` /// @param position the position and span in the grid to create with public ComponentSettingsBuilder withPosition(ComponentPositioning position) { this.position = position; return this; } + /// Set the position of the control in the grid. Must always be set + /// @param row the zero based row + /// @param col the zero based column + public ComponentSettingsBuilder withRowCol(int row, int col) { + this.position = new ComponentPositioning(row, col); + return this; + } + /// Override the control type that was guessed during `forMenuItem`. You should be careful that the control type /// you choose is compatible with the menu item type. /// @param controlType the control type to use /// @throws IllegalArgumentException if the control type is invalid for the menu item public ComponentSettingsBuilder withControlType(ControlType controlType) { - if(!controlType.isSupportedFor(item)) { + if(mode != BuildingMode.MENU) { + controlType = ControlType.TEXT_CONTROL; + } else if(!controlType.isSupportedFor(item)) { throw new IllegalArgumentException("Control type %s cannot render %s".formatted(controlType, item.getClass().getSimpleName())); + } else { + this.controlType = controlType; } - this.controlType = controlType; return this; } @@ -132,6 +159,18 @@ public MenuItem getItem() { return item; } + /// Get the static text associated with this builder + /// @return the static text + public String getText() { + return text; + } + + /// Get the mode of the building, IE text, menu item etc. + /// @return the building mode + public BuildingMode getMode() { + return mode; + } + /// Creates the component settings /// @return the built object public ComponentSettings build() { diff --git a/embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/jfx/controlmgr/panels/BaseCustomMenuPanel.java b/embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/jfx/controlmgr/panels/BaseCustomMenuPanel.java index d72dcbac..2b5831b8 100644 --- a/embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/jfx/controlmgr/panels/BaseCustomMenuPanel.java +++ b/embedCONTROLCore/src/main/java/com/thecoderscorner/embedcontrol/jfx/controlmgr/panels/BaseCustomMenuPanel.java @@ -2,15 +2,19 @@ import com.thecoderscorner.embedcontrol.core.controlmgr.*; import com.thecoderscorner.embedcontrol.core.controlmgr.color.ConditionalColoring; +import com.thecoderscorner.embedcontrol.customization.FontInformation; import com.thecoderscorner.embedcontrol.jfx.controlmgr.UpdatablePanel; import com.thecoderscorner.menu.domain.MenuItem; import com.thecoderscorner.menu.domain.state.MenuTree; import com.thecoderscorner.menu.remote.commands.AckStatus; import com.thecoderscorner.menu.remote.protocol.CorrelationId; import javafx.scene.Node; +import javafx.scene.control.Label; import javafx.scene.layout.Background; import javafx.scene.layout.BackgroundFill; import javafx.scene.layout.GridPane; +import javafx.scene.text.Font; +import javafx.scene.text.TextAlignment; import java.util.HashMap; @@ -59,8 +63,36 @@ public Node getPanelToPresent(double width) throws Exception { } protected abstract void populateGrid(); + private Font calculateFont(FontInformation fontInfo, Font current) { + if(fontInfo.sizeMeasurement() == FontInformation.SizeMeasurement.PERCENT) { + return Font.font(current.getSize() * (fontInfo.fontSize() / 100.0)); + } else { + return Font.font(fontInfo.fontSize()); + } + } + + private TextAlignment toTextAlign(EditorComponent.PortableAlignment justification) { + return switch (justification) { + case LEFT, LEFT_VAL_RIGHT -> TextAlignment.LEFT; + case RIGHT -> TextAlignment.RIGHT; + case CENTER -> TextAlignment.CENTER; + }; + } + protected void putIntoGrid(ComponentSettingsBuilder builder) { - putIntoGrid(builder.getItem(), builder.build()); + if(builder.getMode() == ComponentSettingsBuilder.BuildingMode.TEXT) { + var settings = builder.build(); + var comp = new Label(builder.getText()); + comp.setFont(calculateFont(settings.getFontInfo(), comp.getFont())); + comp.setTextAlignment(toTextAlign(settings.getJustification())); + comp.setTextFill(asFxColor(settings.getColors().foregroundFor(NORMAL, TEXT_FIELD))); + var pos = settings.getPosition(); + gridPane.add(comp, pos.getCol(), pos.getRow(), pos.getColSpan(), pos.getRowSpan()); + } else if(builder.getMode() == ComponentSettingsBuilder.BuildingMode.MENU){ + putIntoGrid(builder.getItem(), builder.build()); + } else { + throw new IllegalArgumentException("Unsupported mode " + builder.getMode()); + } } protected void putIntoGrid(MenuItem item, ComponentSettings componentSettings) {