haxe/ui/styles/Style.hx
package haxe.ui.styles;
import haxe.ui.filters.Filter;
import haxe.ui.filters.FilterParser;
import haxe.ui.styles.animation.Animation.AnimationOptions;
import haxe.ui.styles.elements.Directive;
import haxe.ui.styles.elements.DirectiveExtension;
import haxe.ui.util.Variant;
enum StyleBorderType {
None;
Full;
Compound;
}
@:structInit
class Style {
/** The left (x) position relative to its parent. **/ @:optional public var left:Null<Float>;
/** The top (y) position relative to its parent. **/ @:optional public var top:Null<Float>;
/** Whether the component's width is calculated from its children's width **/ @:optional public var autoWidth:Null<Bool>;
/** A hard-coded value in pixels for the component's width **/ @:optional public var width:Null<Float>;
/** Sets the width of the component to `X` percent of the parent's width **/ @:optional public var percentWidth:Null<Float>;
/** The minimum width in pixels the component can get **/ @:optional public var minWidth:Null<Float>;
/** The minimum width the component can get in percent of its parent's width**/ @:optional public var minPercentWidth:Null<Float>;
/** The maximum width in pixels the component can get**/ @:optional public var maxWidth:Null<Float>;
/** The maximum width the component can get in percent of its parent's width**/ @:optional public var maxPercentWidth:Null<Float>;
/** The starting, automatically assigned `width` of the component **/ @:optional public var initialWidth:Null<Float>;
/** The starting, automatically assigned `percentWidth` of the component**/ @:optional public var initialPercentWidth:Null<Float>;
/** Whether the component's height is calculated from its children's height**/ @:optional public var autoHeight:Null<Bool>;
/** A hard-coded value in pixels for the component's height **/ @:optional public var height:Null<Float>;
/** Sets the width of the object to `X` percent of the parent's height **/ @:optional public var percentHeight:Null<Float>;
/** The minimum height in pixels the component can get **/ @:optional public var minHeight:Null<Float>;
/** The minimum height the component can get, in percent of its parent's height **/ @:optional public var minPercentHeight:Null<Float>;
/** The tallest this object can get **/ @:optional public var maxHeight:Null<Float>;
/** The tallest this object can get, by percentage of its parent's height **/ @:optional public var maxPercentHeight:Null<Float>;
/** The starting, automatically assigned `height` of the component **/ @:optional public var initialHeight:Null<Float>;
/** The starting, automatically assigned `heightWidth` of the component **/ @:optional public var initialPercentHeight:Null<Float>;
/** The gap between the container and its children, on all sides **/ @:optional public var padding(default, set):Null<Float>;
/** The gap between the container and its children, on the top **/ @:optional public var paddingTop:Null<Float>;
/** The gap between the container and its children, on the left side **/ @:optional public var paddingLeft:Null<Float>;
/** The gap between the container and its children, on the right side **/ @:optional public var paddingRight:Null<Float>;
/** The gap between the container and its children, on the bottom **/ @:optional public var paddingBottom:Null<Float>;
private function set_padding(value:Null<Float>):Null<Float> {
paddingTop = value;
paddingLeft = value;
paddingRight = value;
paddingBottom = value;
return value;
}
/** The amount of top offset to apply to the calculated position **/ @:optional public var marginTop:Null<Float>;
/** The amount of left offset to apply to the calculated position **/ @:optional public var marginLeft:Null<Float>;
/** The amount of right offset to apply to the calculated position **/ @:optional public var marginRight:Null<Float>;
/** The amount of bottom offset to apply to the calculated position **/ @:optional public var marginBottom:Null<Float>;
/** The horizontal spacing between the component's children in pixels**/ @:optional public var horizontalSpacing:Null<Float>;
/** The vertical spacing between the component's children in pixels**/ @:optional public var verticalSpacing:Null<Float>;
/** The color of the text **/ @:optional public var color:Null<Int>;
/** The color of the component's background **/ @:optional public var backgroundColor:Null<Int>;
/** A value between 0 and 1 setting the component's background opacity
0 is transparent **/ @:optional public var backgroundOpacity:Null<Float>;
@:optional public var backgroundColorEnd:Null<Int>;
@:optional public var backgroundGradientStyle:Null<String>;
@:optional public var backgroundImage:Variant;
@:optional public var backgroundImageRepeat:Null<String>;
@:optional public var backgroundPositionX:Null<Float>;
@:optional public var backgroundPositionY:Null<Float>;
@:optional public var backgroundImageClipTop:Null<Float>;
@:optional public var backgroundImageClipLeft:Null<Float>;
@:optional public var backgroundImageClipBottom:Null<Float>;
@:optional public var backgroundImageClipRight:Null<Float>;
@:optional public var backgroundImageSliceTop:Null<Float>;
@:optional public var backgroundImageSliceLeft:Null<Float>;
@:optional public var backgroundImageSliceBottom:Null<Float>;
@:optional public var backgroundImageSliceRight:Null<Float>;
/** The color of the border **/ @:optional public var borderColor:Null<Int>;
/** The color of the upper side of the border **/ @:optional public var borderTopColor:Null<Int>;
/** The color of the left side of the border **/ @:optional public var borderLeftColor:Null<Int>;
/** The color of the lower side of the border **/ @:optional public var borderBottomColor:Null<Int>;
/** The color of the right side of the border **/ @:optional public var borderRightColor:Null<Int>;
/** The size of the border, in pixels **/ @:optional public var borderSize:Null<Float>;
/** The size of the upper of the border, in pixels **/ @:optional public var borderTopSize:Null<Float>;
/** The size of the left side of the border, in pixels **/ @:optional public var borderLeftSize:Null<Float>;
/** The size of the lower side of the border, in pixels **/ @:optional public var borderBottomSize:Null<Float>;
/** The size of the right side of the border, in pixels **/ @:optional public var borderRightSize:Null<Float>;
/** The amount of rounding to apply to the border **/ @:optional public var borderRadius:Null<Float>;
/** The amount of rounding to apply to the top-left of the border **/ @:optional public var borderRadiusTopLeft:Null<Float>;
/** The amount of rounding to apply to the top-right of the border **/ @:optional public var borderRadiusTopRight:Null<Float>;
/** The amount of rounding to apply to the bottom-left of the border **/ @:optional public var borderRadiusBottomLeft:Null<Float>;
/** The amount of rounding to apply to the bottom-right of the border **/ @:optional public var borderRadiusBottomRight:Null<Float>;
/** A value between 0 and 1 deciding the object's border opacity
0 is transparent **/ @:optional public var borderOpacity:Null<Float>;
/** The style to use for this border's design **/ @:optional public var borderStyle:Null<String>;
/** A path to an image file to be shown as an icon inside of the object **/ @:optional public var icon:Variant;
/** The position of the icon inside the object - `left`, `right`... **/ @:optional public var iconPosition:Null<String>;
/** Alignment to use for this object: `right`, `center`, `left` **/ @:optional public var horizontalAlign:Null<String>;
/** Alignment to use for this object: `top`, `center`, `bottom` **/ @:optional public var verticalAlign:Null<String>;
/** Alignment to use for the component's text:
`right`, `center`, `left`, `justify` **/ @:optional public var textAlign:Null<String>;
/** A value between 0 and 1, deciding the transparency of this object **/ @:optional public var opacity:Null<Float>;
/** Whether the children are clipped (cut) to the the component boundings **/ @:optional public var clip:Null<Bool>;
/** Whether it used the native version of the component**/ @:optional public var native:Null<Bool>;
/** A path to a font file to be used for the text inside the object **/ @:optional public var fontName:Null<String>;
/** The visual size of the font **/ @:optional public var fontSize:Null<Float>;
/** Whether or not this text should use the **bold** variation of its font **/ @:optional public var fontBold:Null<Bool>;
/** Whether or not to underline the text **/ @:optional public var fontUnderline:Null<Bool>;
/** Whether or not this text should use the *italic* variation of its font **/ @:optional public var fontItalic:Null<Bool>;
@:optional public var fontStrikeThrough:Null<Bool>;
/** The mouse cursor: `default`, `pointer`, `row-resize`, `col-resize` **/ @:optional public var cursor:Null<String>;
@:optional public var cursorOffsetX:Null<Int>;
@:optional public var cursorOffsetY:Null<Int>;
/** Whether the component is hidden or not **/ @:optional public var hidden:Null<Bool>;
@:optional public var filter:Array<Filter>;
@:optional public var backdropFilter:Array<Filter>;
@:optional public var resource:Variant;
@:optional public var animationName:Null<String>;
@:optional public var animationOptions:AnimationOptions;
@:optional public var mode:String;
@:optional public var pointerEvents:String;
@:optional public var contentType:String;
@:optional public var direction:String;
@:optional public var scaleMode:String;
/** The width at which the children will be clipped inside a scrollview **/ @:optional public var contentWidth:Null<Float>;
/** The width in % unit of the component at which the children will be clipped inside a scrollview **/ @:optional public var contentWidthPercent:Null<Float>;
/** The height at which the children will be clipped inside a scrollview **/ @:optional public var contentHeight:Null<Float>;
/** The height in % unit of the component at which the children will be clipped inside a scrollview **/ @:optional public var contentHeightPercent:Null<Float>;
/** Whether or not the text inside this object should be wrapped **/ @:optional public var wordWrap:Null<Bool>;
/** The optional image rendering. Only `pixelated` is supported **/ @:optional public var imageRendering:String;
@:optional public var backgroundWidth:Null<Float>;
@:optional public var backgroundWidthPercent:Null<Float>;
@:optional public var backgroundHeight:Null<Float>;
@:optional public var backgroundHeightPercent:Null<Float>;
/** The name of the layout to use, for example for a box: `vertical`, horizontal` **/ @:optional public var layout:String;
/** Whether the `top` and `left` of the component can be modified by its parent layout **/ @:optional public var includeInLayout:Null<Bool>;
@:optional public var justifyContent:String;
/** The type of the border. can be `Compound`, `Full` or `None` **/ @:optional public var borderType(get, null):StyleBorderType;
private function get_borderType():StyleBorderType {
var t = StyleBorderType.Compound;
var hasLeftBorder = (borderLeftSize != null && borderLeftSize > 0);
var hasRightBorder = (borderRightSize != null && borderRightSize > 0);
var hasTopBorder = (borderTopSize != null && borderTopSize > 0);
var hasBottomBorder = (borderBottomSize != null && borderBottomSize > 0);
var borderColoursEqual = (borderLeftColor == borderRightColor && borderLeftColor == borderTopColor && borderLeftColor == borderBottomColor);
if (!hasLeftBorder && !hasRightBorder && !hasTopBorder && !hasBottomBorder) {
t = StyleBorderType.None;
} else if (hasLeftBorder && hasRightBorder && hasTopBorder && hasBottomBorder && borderColoursEqual) {
borderSize = borderLeftSize;
borderColor = borderLeftColor;
t = StyleBorderType.Full;
}
return t;
}
/** Whether or not this object has a visible border **/ @:optional public var hasBorder(get, null):Bool;
private function get_hasBorder():Bool {
return borderType != StyleBorderType.None;
}
/** The size of the border. only used when `borderType` is `Full` **/ @:optional public var fullBorderSize(get, null):Null<Float>;
private function get_fullBorderSize():Null<Float> {
if (borderType == StyleBorderType.Full) {
return borderLeftSize;
}
return 0;
}
@:optional public var layoutProperties:Map<String, Any> = null;
@:optional public var customDirectives:Map<String, Directive> = null;
public function mergeDirectives(map:Map<String, Directive>) {
for (key in map.keys()) {
var v = map.get(key);
if ((v is DirectiveExtension)) {
var ruleElements = Toolkit.styleSheet.findMatchingRules(v.directive, true);
if (ruleElements != null) {
for (ruleElement in ruleElements) {
mergeDirectives(ruleElement.directives);
}
}
}
switch (key) {
case "left":
left = ValueTools.calcDimension(v.value);
case "top":
top = ValueTools.calcDimension(v.value);
case "width":
autoWidth = ValueTools.constant(v.value, "auto");
width = ValueTools.calcDimension(v.value);
percentWidth = ValueTools.percent(v.value);
case "initial-width":
initialWidth = ValueTools.calcDimension(v.value);
initialPercentWidth = ValueTools.percent(v.value);
case "min-width":
minWidth = ValueTools.calcDimension(v.value);
minPercentWidth = ValueTools.percent(v.value);
case "max-width":
maxWidth = ValueTools.calcDimension(v.value);
maxPercentWidth = ValueTools.percent(v.value);
case "height":
autoHeight = ValueTools.constant(v.value, "auto");
height = ValueTools.calcDimension(v.value);
percentHeight = ValueTools.percent(v.value);
case "initial-height":
initialHeight = ValueTools.calcDimension(v.value);
initialPercentHeight = ValueTools.calcDimension(v.value);
case "min-height":
minHeight = ValueTools.calcDimension(v.value);
minPercentHeight = ValueTools.percent(v.value);
case "max-height":
maxHeight = ValueTools.calcDimension(v.value);
maxPercentHeight = ValueTools.percent(v.value);
case "padding-top":
paddingTop = ValueTools.calcDimension(v.value);
case "padding-left":
paddingLeft = ValueTools.calcDimension(v.value);
case "padding-right":
paddingRight = ValueTools.calcDimension(v.value);
case "padding-bottom":
paddingBottom = ValueTools.calcDimension(v.value);
case "margin-top":
marginTop = ValueTools.calcDimension(v.value);
case "margin-left":
marginLeft = ValueTools.calcDimension(v.value);
case "margin-right":
marginRight = ValueTools.calcDimension(v.value);
case "margin-bottom":
marginBottom = ValueTools.calcDimension(v.value);
case "horizontal-spacing":
horizontalSpacing = ValueTools.calcDimension(v.value);
case "vertical-spacing":
verticalSpacing = ValueTools.calcDimension(v.value);
case "color":
color = ValueTools.int(v.value);
case "background-color":
switch (v.value) {
default:
backgroundColor = ValueTools.int(v.value);
if (map.exists("background-color-end")) {
backgroundColorEnd = ValueTools.int(map.get("background-color-end").value);
} else {
backgroundColorEnd = null;
}
}
case "background-color-end":
backgroundColorEnd = ValueTools.int(v.value);
case "background-gradient-style":
backgroundGradientStyle = ValueTools.string(v.value);
case "background-opacity":
backgroundOpacity = ValueTools.float(v.value);
case "background-image":
backgroundImage = ValueTools.variant(v.value);
case "background-image-repeat":
backgroundImageRepeat = ValueTools.string(v.value);
case "background-width":
backgroundWidth = ValueTools.calcDimension(v.value);
backgroundWidthPercent = ValueTools.percent(v.value);
case "background-height":
backgroundHeight = ValueTools.calcDimension(v.value);
backgroundHeightPercent = ValueTools.percent(v.value);
case "background-position-x":
backgroundPositionX = ValueTools.calcDimension(v.value);
case "background-position-y":
backgroundPositionY = ValueTools.calcDimension(v.value);
case "background-image-clip-top":
backgroundImageClipTop = ValueTools.calcDimension(v.value);
case "background-image-clip-left":
backgroundImageClipLeft = ValueTools.calcDimension(v.value);
case "background-image-clip-right":
backgroundImageClipRight = ValueTools.calcDimension(v.value);
case "background-image-clip-bottom":
backgroundImageClipBottom = ValueTools.calcDimension(v.value);
case "background-image-slice-top":
backgroundImageSliceTop = ValueTools.calcDimension(v.value);
case "background-image-slice-left":
backgroundImageSliceLeft = ValueTools.calcDimension(v.value);
case "background-image-slice-right":
backgroundImageSliceRight = ValueTools.calcDimension(v.value);
case "background-image-slice-bottom":
backgroundImageSliceBottom = ValueTools.calcDimension(v.value);
case "border-color":
borderColor = ValueTools.int(v.value);
case "border-top-color":
borderTopColor = ValueTools.int(v.value);
case "border-left-color":
borderLeftColor = ValueTools.int(v.value);
case "border-right-color":
borderRightColor = ValueTools.int(v.value);
case "border-bottom-color":
borderBottomColor = ValueTools.int(v.value);
case "border-size" | "border-width":
if (v.value == VNone) {
borderSize = 0;
borderTopSize = 0;
borderLeftSize = 0;
borderBottomSize = 0;
borderRightSize = 0;
} else {
borderSize = ValueTools.calcDimension(v.value);
borderTopSize = ValueTools.calcDimension(v.value);
borderLeftSize = ValueTools.calcDimension(v.value);
borderBottomSize = ValueTools.calcDimension(v.value);
borderRightSize = ValueTools.calcDimension(v.value);
}
case "border-top-size" | "border-top-width":
if (v.value == VNone) {
borderTopSize = 0;
} else {
borderTopSize = ValueTools.calcDimension(v.value);
}
case "border-left-size" | "border-left-width":
if (v.value == VNone) {
borderLeftSize = 0;
} else {
borderLeftSize = ValueTools.calcDimension(v.value);
}
case "border-right-size" | "border-right-width":
if (v.value == VNone) {
borderRightSize = 0;
} else {
borderRightSize = ValueTools.calcDimension(v.value);
}
case "border-bottom-size" | "border-bottom-width":
if (v.value == VNone) {
borderBottomSize = 0;
} else {
borderBottomSize = ValueTools.calcDimension(v.value);
}
case "border-radius":
borderRadius = ValueTools.calcDimension(v.value);
case "border-top-left-radius":
borderRadiusTopLeft = ValueTools.calcDimension(v.value);
case "border-top-right-radius":
borderRadiusTopRight = ValueTools.calcDimension(v.value);
case "border-bottom-left-radius":
borderRadiusBottomLeft = ValueTools.calcDimension(v.value);
case "border-bottom-right-radius":
borderRadiusBottomRight = ValueTools.calcDimension(v.value);
case "border-opacity":
borderOpacity = ValueTools.float(v.value);
case "border-style":
borderStyle = ValueTools.string(v.value);
case "icon":
switch (v.value) {
case Value.VNone:
icon = "";
case _:
icon = ValueTools.variant(v.value);
}
case "icon-position":
iconPosition = ValueTools.string(v.value);
case "horizontal-align":
horizontalAlign = ValueTools.string(v.value);
case "vertical-align":
verticalAlign = ValueTools.string(v.value);
case "text-align":
textAlign = ValueTools.string(v.value);
case "opacity":
opacity = ValueTools.float(v.value);
case "font-name" | "font-family":
fontName = ValueTools.string(v.value);
case "font-size":
fontSize = ValueTools.calcDimension(v.value);
case "font-weight":
if (ValueTools.string(v.value) != null) {
fontBold = ValueTools.string(v.value).toLowerCase() == "bold";
}
case "font-bold":
fontBold = ValueTools.bool(v.value);
case "font-underline":
fontUnderline = ValueTools.bool(v.value);
case "font-italic":
fontItalic = ValueTools.bool(v.value);
case "font-style":
if (ValueTools.string(v.value) != null) {
fontItalic = ValueTools.string(v.value).toLowerCase() == "italic";
}
case "text-decoration":
if (ValueTools.string(v.value) != null) {
fontUnderline = ValueTools.string(v.value).toLowerCase() == "underline";
fontStrikeThrough = ValueTools.string(v.value).toLowerCase() == "line-through";
}
case "cursor-name":
cursorOffsetX = null;
cursorOffsetY = null;
cursor = ValueTools.string(v.value);
case "cursor-offset-x":
cursorOffsetX = ValueTools.int(v.value);
case "cursor-offset-y":
cursorOffsetY = ValueTools.int(v.value);
case "hidden":
hidden = ValueTools.bool(v.value);
case "display":
hidden = ValueTools.none(v.value);
case "clip":
clip = ValueTools.bool(v.value);
case "native":
native = ValueTools.bool(v.value);
case "filter":
#if (!haxeui_nofilters && !haxeui_no_filters)
filter = parseFilter(v.value);
#end
case "backdrop-filter":
#if (!haxeui_nofilters && !haxeui_no_filters)
backdropFilter = parseFilter(v.value);
#end
case "resource":
resource = ValueTools.variant(v.value);
case "animation-name":
animationName = ValueTools.string(v.value);
case "animation-duration":
createAnimationOptions();
animationOptions.duration = ValueTools.time(v.value);
case "animation-timing-function":
createAnimationOptions();
animationOptions.easingFunction = ValueTools.calcEasing(v.value);
case "animation-delay":
createAnimationOptions();
animationOptions.delay = ValueTools.time(v.value);
case "animation-iteration-count":
createAnimationOptions();
animationOptions.iterationCount = switch (v.value) {
case Value.VConstant(val):
(val == "infinite") ? -1 : 0;
case _:
ValueTools.int(v.value);
};
case "animation-direction":
createAnimationOptions();
animationOptions.direction = ValueTools.string(v.value);
case "animation-fill-mode":
createAnimationOptions();
animationOptions.fillMode = ValueTools.string(v.value);
case "mode":
mode = ValueTools.string(v.value);
case "pointer-events":
switch (v.value) {
case VNone:
pointerEvents = "none";
case _:
pointerEvents = ValueTools.string(v.value);
}
case "content-type":
contentType = ValueTools.string(v.value);
case "direction":
direction = ValueTools.string(v.value);
case "scale-mode":
if (ValueTools.none(v.value)) {
scaleMode = "none";
} else {
scaleMode = ValueTools.string(v.value);
}
case "content-width":
contentWidth = ValueTools.calcDimension(v.value);
contentWidthPercent = ValueTools.percent(v.value);
case "content-height":
contentHeight = ValueTools.calcDimension(v.value);
contentHeightPercent = ValueTools.percent(v.value);
case "word-wrap":
wordWrap = ValueTools.bool(v.value);
case "image-rendering":
switch (v.value) {
case VNone:
imageRendering = null;
case _:
imageRendering = ValueTools.string(v.value);
}
case "layout":
switch (v.value) {
case VNone:
layout = null;
case _:
layout = ValueTools.string(v.value);
}
case "include-in-layout":
includeInLayout = ValueTools.bool(v.value);
case "justify-content":
justifyContent = ValueTools.string(v.value);
case _:
if (StringTools.startsWith(key, "layout-")) {
var layoutPropName = key.substring("layout-".length);
if (layoutProperties == null) {
layoutProperties = new Map<String, Any>();
}
layoutProperties.set(layoutPropName, ValueTools.any(v.value));
} else {
var use = DirectiveHandler.hasDirectiveHandler(v.directive);
#if haxeui_custom_directives_relaxed // means we dont require a handler, so the backend can just do "anything" with them
use = true;
#end
if (use) {
if (customDirectives == null) {
customDirectives = new Map<String, Directive>();
}
if (v.value == null || v.value == VNone) {
customDirectives.remove(v.directive);
} else {
customDirectives.set(v.directive, v);
}
}
}
}
}
}
public function apply(s:Style) {
if (s.cursor != null) cursor = s.cursor;
if (s.cursorOffsetX != null) cursorOffsetX = s.cursorOffsetX;
if (s.cursorOffsetY != null) cursorOffsetY = s.cursorOffsetY;
if (s.hidden != null) hidden = s.hidden;
if (s.left != null) left = s.left;
if (s.top != null) top = s.top;
if (s.autoWidth != null) autoWidth = s.autoWidth;
if (s.autoHeight != null) autoHeight = s.autoHeight;
if (s.verticalSpacing != null) verticalSpacing = s.verticalSpacing;
if (s.horizontalSpacing != null) horizontalSpacing = s.horizontalSpacing;
if (s.width != null) {
width = s.width;
autoWidth = false;
}
if (s.initialWidth != null) initialWidth = s.initialWidth;
if (s.initialPercentWidth != null) initialPercentWidth = s.initialPercentWidth;
if (s.minWidth != null) minWidth = s.minWidth;
if (s.minPercentWidth != null) minPercentWidth = s.minPercentWidth;
if (s.maxWidth != null) maxWidth = s.maxWidth;
if (s.maxPercentWidth != null) maxPercentWidth = s.maxPercentWidth;
if (s.height != null) {
height = s.height;
autoHeight = false;
}
if (s.initialHeight != null) initialHeight = s.initialHeight;
if (s.initialPercentHeight != null) initialPercentHeight = s.initialPercentHeight;
if (s.minHeight != null) minHeight = s.minHeight;
if (s.minPercentHeight != null) minPercentHeight = s.minPercentHeight;
if (s.maxHeight != null) maxHeight = s.maxHeight;
if (s.maxPercentHeight != null) maxPercentHeight = s.maxPercentHeight;
if (s.percentWidth != null) {
percentWidth = s.percentWidth;
autoWidth = false;
}
if (s.percentHeight != null) {
percentHeight = s.percentHeight;
autoHeight = false;
}
if (s.paddingTop != null) paddingTop = s.paddingTop;
if (s.paddingLeft != null) paddingLeft = s.paddingLeft;
if (s.paddingRight != null) paddingRight = s.paddingRight;
if (s.paddingBottom != null) paddingBottom = s.paddingBottom;
if (s.marginTop != null) marginTop = s.marginTop;
if (s.marginLeft != null) marginLeft = s.marginLeft;
if (s.marginRight != null) marginRight = s.marginRight;
if (s.marginBottom != null) marginBottom = s.marginBottom;
if (s.color != null) color = s.color;
if (s.backgroundColor != null) {
backgroundColor = s.backgroundColor;
backgroundColorEnd = null;
}
if (s.backgroundColorEnd != null) backgroundColorEnd = s.backgroundColorEnd;
if (s.backgroundGradientStyle != null) backgroundGradientStyle = s.backgroundGradientStyle;
if (s.backgroundOpacity != null) backgroundOpacity = s.backgroundOpacity;
if (s.backgroundImage != null) backgroundImage = s.backgroundImage;
if (s.backgroundImageRepeat != null) backgroundImageRepeat = s.backgroundImageRepeat;
if (s.backgroundImageClipTop != null) backgroundImageClipTop = s.backgroundImageClipTop;
if (s.backgroundImageClipLeft != null) backgroundImageClipLeft = s.backgroundImageClipLeft;
if (s.backgroundImageClipBottom != null) backgroundImageClipBottom = s.backgroundImageClipBottom;
if (s.backgroundImageClipRight != null) backgroundImageClipRight = s.backgroundImageClipRight;
if (s.backgroundImageSliceTop != null) backgroundImageSliceTop = s.backgroundImageSliceTop;
if (s.backgroundImageSliceLeft != null) backgroundImageSliceLeft = s.backgroundImageSliceLeft;
if (s.backgroundImageSliceBottom != null) backgroundImageSliceBottom = s.backgroundImageSliceBottom;
if (s.backgroundImageSliceRight != null) backgroundImageSliceRight = s.backgroundImageSliceRight;
if (s.borderColor != null) borderColor = s.borderColor;
if (s.borderTopColor != null) borderTopColor = s.borderTopColor;
if (s.borderLeftColor != null) borderLeftColor = s.borderLeftColor;
if (s.borderBottomColor != null) borderBottomColor = s.borderBottomColor;
if (s.borderRightColor != null) borderRightColor = s.borderRightColor;
if (s.borderSize != null) borderSize = s.borderSize;
if (s.borderTopSize != null) borderTopSize = s.borderTopSize;
if (s.borderLeftSize != null) borderLeftSize = s.borderLeftSize;
if (s.borderBottomSize != null) borderBottomSize = s.borderBottomSize;
if (s.borderRightSize != null) borderRightSize = s.borderRightSize;
if (s.borderRadius != null) borderRadius = s.borderRadius;
if (s.borderRadiusTopLeft != null) borderRadiusTopLeft = s.borderRadiusTopLeft;
if (s.borderRadiusTopRight != null) borderRadiusTopRight = s.borderRadiusTopRight;
if (s.borderRadiusBottomLeft != null) borderRadiusBottomLeft = s.borderRadiusBottomLeft;
if (s.borderRadiusBottomRight != null) borderRadiusBottomRight = s.borderRadiusBottomRight;
if (s.borderOpacity != null) borderOpacity = s.borderOpacity;
if (s.borderStyle != null) borderStyle = s.borderStyle;
if (s.filter != null) filter = s.filter.copy();
if (s.backdropFilter != null) backdropFilter = s.backdropFilter.copy();
if (s.resource != null) resource = s.resource;
if (s.icon != null) icon = s.icon;
if (s.iconPosition != null) iconPosition = s.iconPosition;
if (s.horizontalAlign != null) horizontalAlign = s.horizontalAlign;
if (s.verticalAlign != null) verticalAlign = s.verticalAlign;
if (s.textAlign != null) textAlign = s.textAlign;
if (s.opacity != null) opacity = s.opacity;
if (s.clip != null) clip = s.clip;
if (s.native != null) native = s.native;
if (s.fontName != null) fontName = s.fontName;
if (s.fontSize != null) fontSize = s.fontSize;
if (s.fontBold != null) fontBold = s.fontBold;
if (s.fontUnderline != null) fontUnderline = s.fontUnderline;
if (s.fontStrikeThrough != null) fontStrikeThrough = s.fontStrikeThrough;
if (s.fontItalic != null) fontItalic = s.fontItalic;
if (s.animationName != null) animationName = s.animationName;
if (s.animationOptions != null) {
createAnimationOptions();
if (s.animationOptions.duration != null) animationOptions.duration = s.animationOptions.duration;
if (s.animationOptions.delay != null) animationOptions.delay = s.animationOptions.delay;
if (s.animationOptions.iterationCount != null) animationOptions.iterationCount = s.animationOptions.iterationCount;
if (s.animationOptions.easingFunction != null) animationOptions.easingFunction = s.animationOptions.easingFunction;
if (s.animationOptions.direction != null) animationOptions.direction = s.animationOptions.direction;
if (s.animationOptions.fillMode != null) animationOptions.fillMode = s.animationOptions.fillMode;
}
if (s.mode != null) mode = s.mode;
if (s.pointerEvents != null) pointerEvents = s.pointerEvents;
if (s.contentType != null) contentType = s.contentType;
if (s.direction != null) direction = s.direction;
if (s.scaleMode != null) scaleMode = s.scaleMode;
if (s.contentWidth != null) contentWidth = s.contentWidth;
if (s.contentWidthPercent != null) contentWidthPercent = s.contentWidthPercent;
if (s.contentHeight != null) contentHeight = s.contentHeight;
if (s.contentHeightPercent != null) contentHeightPercent = s.contentHeightPercent;
if (s.wordWrap != null) wordWrap = s.wordWrap;
if (s.imageRendering != null) imageRendering = s.imageRendering;
if (s.backgroundWidth != null) backgroundWidth = s.backgroundWidth;
if (s.backgroundWidthPercent != null) backgroundWidthPercent = s.backgroundWidthPercent;
if (s.backgroundHeight != null) backgroundHeight = s.backgroundHeight;
if (s.backgroundHeightPercent != null) backgroundHeightPercent = s.backgroundHeightPercent;
if (s.layout != null) layout = s.layout;
if (s.includeInLayout != null) includeInLayout = s.includeInLayout;
if (s.justifyContent != null) justifyContent = s.justifyContent;
if (s.layoutProperties != null) {
if (this.layoutProperties == null) {
this.layoutProperties = new Map<String, Any>();
}
for (layoutPropName in s.layoutProperties.keys()) {
var v = s.layoutProperties.get(layoutPropName);
this.layoutProperties.set(layoutPropName, v);
}
}
if (s.customDirectives != null) {
if (this.customDirectives == null) {
this.customDirectives = new Map<String, Directive>();
}
for (directive in s.customDirectives.keys()) {
var v = s.customDirectives.get(directive);
if (v.value == null || v.value == VNone) {
this.customDirectives.remove(directive);
} else {
this.customDirectives.set(directive, v);
}
}
}
}
public function equalTo(s:Style):Bool {
if (s.backgroundColor != backgroundColor) return false;
if (s.backgroundColorEnd != backgroundColorEnd) return false;
if (s.backgroundGradientStyle != backgroundGradientStyle) return false;
if (s.backgroundOpacity != backgroundOpacity) return false;
if (s.borderColor != borderColor) return false;
if (s.borderTopColor != borderTopColor) return false;
if (s.borderLeftColor != borderLeftColor) return false;
if (s.borderBottomColor != borderBottomColor) return false;
if (s.borderRightColor != borderRightColor) return false;
if (s.borderSize != borderSize) return false;
if (s.borderTopSize != borderTopSize) return false;
if (s.borderLeftSize != borderLeftSize) return false;
if (s.borderBottomSize != borderBottomSize) return false;
if (s.borderRightSize != borderRightSize) return false;
if (s.borderRadius != borderRadius) return false;
if (s.borderRadiusTopLeft != borderRadiusTopLeft) return false;
if (s.borderRadiusTopRight != borderRadiusTopRight) return false;
if (s.borderRadiusBottomLeft != borderRadiusBottomLeft) return false;
if (s.borderRadiusBottomRight != borderRadiusBottomRight) return false;
if (s.borderOpacity != borderOpacity) return false;
if (s.borderStyle != borderStyle) return false;
if (s.color != color) return false;
if (s.cursor != cursor) return false;
if (s.cursorOffsetX != cursorOffsetX) return false;
if (s.cursorOffsetY != cursorOffsetY) return false;
if (s.hidden != hidden) return false;
if (s.left != left) return false;
if (s.top != top) return false;
if (s.autoWidth != autoWidth) return false;
if (s.autoHeight != autoHeight) return false;
if (s.verticalSpacing != verticalSpacing) return false;
if (s.horizontalSpacing != horizontalSpacing) return false;
if (s.width != width) return false;
if (s.initialWidth != initialWidth) return false;
if (s.initialPercentWidth != initialPercentWidth) return false;
if (s.minWidth != minWidth) return false;
if (s.minPercentWidth != minPercentWidth) return false;
if (s.maxWidth != maxWidth) return false;
if (s.maxPercentWidth != maxPercentWidth) return false;
if (s.height != height) return false;
if (s.initialHeight != initialHeight) return false;
if (s.initialPercentHeight != initialPercentHeight) return false;
if (s.minHeight != minHeight) return false;
if (s.minPercentHeight != minPercentHeight) return false;
if (s.maxHeight != maxHeight) return false;
if (s.maxPercentHeight != maxPercentHeight) return false;
if (s.percentWidth != percentWidth) return false;
if (s.percentHeight != percentHeight) return false;
if (s.paddingTop != paddingTop) return false;
if (s.paddingLeft != paddingLeft) return false;
if (s.paddingRight != paddingRight) return false;
if (s.paddingBottom != paddingBottom) return false;
if (s.marginTop != marginTop) return false;
if (s.marginLeft != marginLeft) return false;
if (s.marginRight != marginRight) return false;
if (s.marginBottom != marginBottom) return false;
if (s.backgroundImage != backgroundImage) return false;
if (s.backgroundImageRepeat != backgroundImageRepeat) return false;
if (s.backgroundImageClipTop != backgroundImageClipTop) return false;
if (s.backgroundImageClipLeft != backgroundImageClipLeft) return false;
if (s.backgroundImageClipBottom != backgroundImageClipBottom) return false;
if (s.backgroundImageClipRight != backgroundImageClipRight) return false;
if (s.backgroundImageSliceTop != backgroundImageSliceTop) return false;
if (s.backgroundImageSliceLeft != backgroundImageSliceLeft) return false;
if (s.backgroundImageSliceBottom != backgroundImageSliceBottom) return false;
if (s.backgroundImageSliceRight != backgroundImageSliceRight) return false;
if (s.filter != filter) return false;
if (s.backdropFilter != backdropFilter) return false;
if (s.resource != resource) return false;
if (s.icon != icon) return false;
if (s.iconPosition != iconPosition) return false;
if (s.horizontalAlign != horizontalAlign) return false;
if (s.verticalAlign != verticalAlign) return false;
if (s.textAlign != textAlign) return false;
if (s.opacity != opacity) return false;
if (s.clip != clip) return false;
if (s.native != native) return false;
if (s.fontName != fontName) return false;
if (s.fontSize != fontSize) return false;
if (s.fontBold != fontBold) return false;
if (s.fontUnderline != fontUnderline) return false;
if (s.fontStrikeThrough != fontStrikeThrough) return false;
if (s.fontItalic != fontItalic) return false;
if (s.resource != resource) return false;
if (s.animationName != animationName) return false;
if (animationOptions != null && animationOptions.compareTo(s.animationOptions) == false) return false;
if (s.mode != mode) return false;
if (s.pointerEvents != pointerEvents) return false;
if (s.contentType != contentType) return false;
if (s.direction != direction) return false;
if (s.scaleMode != scaleMode) return false;
if (s.contentWidth != contentWidth) return false;
if (s.contentWidthPercent != contentWidthPercent) return false;
if (s.contentHeight != contentHeight) return false;
if (s.contentHeightPercent != contentHeightPercent) return false;
if (s.wordWrap != wordWrap) return false;
if (s.imageRendering != imageRendering) return false;
if (s.backgroundWidth != backgroundWidth) return false;
if (s.backgroundWidthPercent != backgroundWidthPercent) return false;
if (s.backgroundHeight != backgroundHeight) return false;
if (s.backgroundHeightPercent != backgroundHeightPercent) return false;
if (s.layout != layout) return false;
if (s.includeInLayout != includeInLayout) return false;
if (s.justifyContent != justifyContent) return false;
if (s.layoutProperties != null && s.layoutProperties != null) {
for (layoutPropName in s.layoutProperties) {
if (!this.layoutProperties.exists(layoutPropName)) {
return false;
}
}
for (layoutPropName in this.layoutProperties) {
if (!s.layoutProperties.exists(layoutPropName)) {
return false;
}
}
}
if (s.customDirectives != null && this.customDirectives != null) {
for (directive in s.customDirectives.keys()) {
if (!this.customDirectives.exists(directive)) {
return false;
}
}
for (directive in this.customDirectives.keys()) {
if (!s.customDirectives.exists(directive)) {
return false;
}
}
}
return true;
}
private inline function createAnimationOptions() {
if (animationOptions == null) animationOptions = {};
}
private function parseFilter(value:Value, filters:Array<Filter> = null) {
if (filters == null) {
filters = [];
}
switch (value) {
case Value.VCall(f, vl):
var arr = ValueTools.array(vl);
arr.insert(0, f);
var filter = FilterParser.parseFilter(arr);
if (filter != null) {
filters.push(filter);
}
case Value.VConstant(f):
var filter = FilterParser.parseFilter([f]);
if (filter != null) {
filters.push(filter);
}
case Value.VComposite(vl):
for (v in vl) {
parseFilter(v, filters);
}
case Value.VNone:
filters = null;
case _:
}
return filters;
}
public function clone():Style {
var c:Style = {};
c.apply(this);
return c;
}
}