diff --git a/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java b/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java index e926256..091e6c4 100644 --- a/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java +++ b/app/src/main/java/com/annimon/hotarufx/bundles/BundleLoader.java @@ -16,7 +16,8 @@ public final class BundleLoader { CompositionBundle.class, NodesBundle.class, NodeUtilsBundle.class, - InterpolatorsBundle.class + InterpolatorsBundle.class, + FontBundle.class ); } diff --git a/app/src/main/java/com/annimon/hotarufx/bundles/FontBundle.java b/app/src/main/java/com/annimon/hotarufx/bundles/FontBundle.java new file mode 100644 index 0000000..3141bd4 --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/bundles/FontBundle.java @@ -0,0 +1,39 @@ +package com.annimon.hotarufx.bundles; + +import com.annimon.hotarufx.lib.Context; +import com.annimon.hotarufx.lib.FontValue; +import com.annimon.hotarufx.lib.Function; +import com.annimon.hotarufx.lib.MapValue; +import com.annimon.hotarufx.lib.Types; +import com.annimon.hotarufx.lib.Validator; +import java.util.HashMap; +import java.util.Map; +import javafx.scene.text.Font; +import lombok.val; +import static com.annimon.hotarufx.bundles.FunctionInfo.of; +import static com.annimon.hotarufx.bundles.FunctionType.COMMON; + +public class FontBundle implements Bundle { + + private static final Map FUNCTIONS; + static { + FUNCTIONS = new HashMap<>(); + FUNCTIONS.put("font", of(COMMON, FontBundle::newFont)); + } + + @Override + public Map functionsInfo() { + return FUNCTIONS; + } + + private static Function newFont(Context context) { + return args -> { + val validator = Validator.with(args); + validator.check(1); + if (args[0].type() == Types.MAP) { + return new FontValue(FontValue.toFont((MapValue) args[0])); + } + return new FontValue(Font.font(args[0].asDouble())); + }; + } +} diff --git a/app/src/main/java/com/annimon/hotarufx/lib/FontValue.java b/app/src/main/java/com/annimon/hotarufx/lib/FontValue.java new file mode 100644 index 0000000..c84474e --- /dev/null +++ b/app/src/main/java/com/annimon/hotarufx/lib/FontValue.java @@ -0,0 +1,68 @@ +package com.annimon.hotarufx.lib; + +import com.annimon.hotarufx.exceptions.TypeException; +import javafx.scene.text.Font; +import javafx.scene.text.FontPosture; +import javafx.scene.text.FontWeight; +import lombok.val; + +public class FontValue extends MapValue { + + public static Font toFont(MapValue mapValue) { + val map = mapValue.getMap(); + val family = map.getOrDefault("family", new StringValue(Font.getDefault().getFamily())).asString(); + val weight = map.getOrDefault("weight", NumberValue.of(FontWeight.NORMAL.getWeight())).asInt(); + val isItalic = map.getOrDefault("italic", NumberValue.ZERO).asBoolean(); + val posture = isItalic ? FontPosture.ITALIC : FontPosture.REGULAR; + val size = map.getOrDefault("size", NumberValue.MINUS_ONE).asDouble(); + return Font.font(family, FontWeight.findByWeight(weight), posture, size); + } + + private final Font font; + + public FontValue(Font font) { + super(4); + this.font = font; + init(); + } + + private void init() { + val map = super.getMap(); + map.put("family", new StringValue(font.getFamily())); + map.put("isItalic", NumberValue.fromBoolean(font.getStyle().toLowerCase().contains("italic"))); + val weight = FontWeight.findByName(font.getStyle()); + map.put("weight", NumberValue.of(weight != null + ? (weight.getWeight()) + : FontWeight.NORMAL.getWeight())); + map.put("size", NumberValue.of(font.getSize())); + } + + @Override + public int type() { + return Types.MAP; + } + + public Font getFont() { + return font; + } + + @Override + public Object raw() { + return font; + } + + @Override + public Number asNumber() { + throw new TypeException("Cannot cast font to number"); + } + + @Override + public String asString() { + throw new TypeException("Cannot cast font to string"); + } + + @Override + public int compareTo(Value o) { + return 0; + } +} diff --git a/app/src/main/java/com/annimon/hotarufx/visual/PropertyType.java b/app/src/main/java/com/annimon/hotarufx/visual/PropertyType.java index b3458ed..8392a72 100644 --- a/app/src/main/java/com/annimon/hotarufx/visual/PropertyType.java +++ b/app/src/main/java/com/annimon/hotarufx/visual/PropertyType.java @@ -1,5 +1,6 @@ package com.annimon.hotarufx.visual; +import com.annimon.hotarufx.lib.FontValue; import com.annimon.hotarufx.lib.MapValue; import com.annimon.hotarufx.lib.NodeValue; import com.annimon.hotarufx.lib.NumberValue; @@ -8,16 +9,12 @@ import com.annimon.hotarufx.lib.Types; import com.annimon.hotarufx.lib.Value; import com.annimon.hotarufx.visual.objects.ObjectNode; import com.annimon.hotarufx.visual.visitors.NodeVisitor; -import java.util.HashMap; import java.util.function.Function; import javafx.scene.Node; import javafx.scene.paint.Color; import javafx.scene.text.Font; -import javafx.scene.text.FontPosture; -import javafx.scene.text.FontWeight; import lombok.AccessLevel; import lombok.RequiredArgsConstructor; -import lombok.val; @SuppressWarnings("ConstantConditions") @RequiredArgsConstructor(access = AccessLevel.PACKAGE) @@ -29,7 +26,7 @@ public enum PropertyType { NODE(toNode(), fromNode()), CLIP_NODE(toClipNode(), fromNode()), PAINT(v -> Color.valueOf(v.asString()), o -> new StringValue(o.toString())), - FONT(toFont(), fromFont()); + FONT(toFont(), object -> new FontValue((Font) object)); private final Function fromHFX; private final Function toHFX; @@ -77,32 +74,10 @@ public enum PropertyType { private static Function toFont() { return value -> { - // TODO: FontValue + FontBundle if (value.type() == Types.MAP) { - val map = ((MapValue) value).getMap(); - val family = map.getOrDefault("family", new StringValue(Font.getDefault().getFamily())).asString(); - val weight = map.getOrDefault("weight", NumberValue.of(FontWeight.NORMAL.getWeight())).asInt(); - val isItalic = map.getOrDefault("italic", NumberValue.ZERO).asBoolean(); - val posture = isItalic ? FontPosture.ITALIC : FontPosture.REGULAR; - val size = map.getOrDefault("size", NumberValue.MINUS_ONE).asDouble(); - return Font.font(family, FontWeight.findByWeight(weight), posture, size); + return FontValue.toFont((MapValue) value); } return Font.font(value.asDouble()); }; } - - private static Function fromFont() { - return object -> { - val font = (Font) object; - val map = new HashMap(4); - map.put("family", new StringValue(font.getFamily())); - map.put("isItalic", NumberValue.fromBoolean(font.getStyle().toLowerCase().contains("italic"))); - val weight = FontWeight.findByName(font.getStyle()); - map.put("weight", NumberValue.of(weight != null - ? (weight.getWeight()) - : FontWeight.NORMAL.getWeight())); - map.put("size", NumberValue.of(font.getSize())); - return new MapValue(map); - }; - } }