/** * This methods takes a attribute object and overrides styles that * are present and not null. All properties are null by default and * will only be cascaded if is present */ public UIAttributes CascadeAttributes(UIAttributes cascadingAttributes) { return(new UIAttributes { TextureKey = cascadingAttributes.TextureKey ?? TextureKey, FontKey = cascadingAttributes.FontKey ?? FontKey, // ReSharper disable once CompareOfFloatsByEqualityOperator FontSize = cascadingAttributes.FontSize != 1f ? cascadingAttributes.FontSize : FontSize, X = cascadingAttributes.X != 0 ? cascadingAttributes.X : X, Y = cascadingAttributes.Y != 0 ? cascadingAttributes.Y : Y, OffsetX = cascadingAttributes.OffsetX != 0 ? cascadingAttributes.OffsetX : OffsetX, OffsetY = cascadingAttributes.OffsetY != 0 ? cascadingAttributes.OffsetY : OffsetY, Width = cascadingAttributes.Width != 0 ? cascadingAttributes.Width : Width, Height = cascadingAttributes.Height != 0 ? cascadingAttributes.Height : Height, Color = cascadingAttributes.Color != Color.Black ? cascadingAttributes.Color : Color, Background = cascadingAttributes.Background != Color.Transparent ? cascadingAttributes.Background : Background, Grow = cascadingAttributes.Grow != 1 ? cascadingAttributes.Grow : Grow, BorderSize = cascadingAttributes.BorderSize != 0 ? cascadingAttributes.BorderSize : BorderSize, BorderColor = cascadingAttributes.BorderColor != Color.Black ? cascadingAttributes.BorderColor : BorderColor, Position = cascadingAttributes.Position != Position.Relative ? cascadingAttributes.Position : Position, Sizing = cascadingAttributes.Sizing != Sizing.Proportion ? cascadingAttributes.Sizing : Sizing, Overflow = cascadingAttributes.Overflow != Overflow.Show ? cascadingAttributes.Overflow : Overflow, JustifyText = cascadingAttributes.JustifyText != JustifyText.Center ? cascadingAttributes.JustifyText : JustifyText, VerticalAlignText = cascadingAttributes.VerticalAlignText != VerticalAlignText.Center ? cascadingAttributes.VerticalAlignText : VerticalAlignText, TextWrap = cascadingAttributes.TextWrap != TextWrap.Wrap ? cascadingAttributes.TextWrap : TextWrap, FontScaleMode = cascadingAttributes.FontScaleMode != FontScaleMode.FontSizeScale ? cascadingAttributes.FontScaleMode : FontScaleMode, StackDirection = cascadingAttributes.StackDirection != StackDirection.None ? cascadingAttributes.StackDirection : StackDirection, }); }
protected UIComponent(string name, bool updateable = false) { //Component name Name = name; //Indexing for drawing children Index = 0; NextChildIndex = 0; //Parent and children Parent = null; Children = new List <UIComponent>(); //UIConstraints and attributes Constraints = new List <UIConstraint>(); DefaultAttributes = new UIAttributes { TextureKey = "default", FontKey = "default", Grow = 1, FontSize = 1, Background = Color.Transparent, Color = Color.Black, Position = Position.Relative }; RenderAttributes = new UIAttributes(); //Events and focus Focusable = false; Updateable = updateable; EventHandlers = new Dictionary <string, Action <UIEvent> >(); }
/** * Used to generate a UIComponent making use of all applied constraints and modifiers. * Modifiers and constraints are applied in the same order as they are defined */ public void Build(UILayer layer) { #region Inherit/Defaults DefaultAttributes.X = Parent?.DefaultAttributes.X ?? 0; DefaultAttributes.Y = Parent?.DefaultAttributes.Y ?? 0; DefaultAttributes.Width = Parent?.DefaultAttributes.Width ?? DefaultAttributes.Width; DefaultAttributes.Height = Parent?.DefaultAttributes.Height ?? DefaultAttributes.Height; if (DefaultAttributes.StackDirection == StackDirection.Inherit) { DefaultAttributes.StackDirection = Parent?.DefaultAttributes.StackDirection ?? StackDirection.None; } if (DefaultAttributes.Overflow == Overflow.Inherit) { DefaultAttributes.Overflow = Parent?.DefaultAttributes.Overflow ?? Overflow.Show; } if (DefaultAttributes.Sizing == Sizing.Inherit) { DefaultAttributes.Sizing = Parent?.DefaultAttributes.Sizing ?? Sizing.Proportion; } if (DefaultAttributes.Position == Position.Inherit) { DefaultAttributes.Position = Parent?.DefaultAttributes.Position ?? Position.Relative; } if (DefaultAttributes.JustifyText == JustifyText.Inherit) { DefaultAttributes.JustifyText = Parent?.DefaultAttributes.JustifyText ?? JustifyText.Start; } if (DefaultAttributes.TextWrap == TextWrap.Inherit) { DefaultAttributes.TextWrap = Parent?.DefaultAttributes.TextWrap ?? TextWrap.Wrap; } if (DefaultAttributes.FontScaleMode == FontScaleMode.Inherit) { DefaultAttributes.FontScaleMode = Parent?.DefaultAttributes.FontScaleMode ?? FontScaleMode.FontSizeScale; } if (DefaultAttributes.VerticalAlignText == VerticalAlignText.Inherit) { DefaultAttributes.VerticalAlignText = Parent?.DefaultAttributes.VerticalAlignText ?? VerticalAlignText.Start; } #endregion #region Apply Contraints/ Build Indexes if (EventHandlers.Any()) { layer.AddEventComponent(this); } if (Focusable) { layer.AddTabIndexComponent(this); } if (Updateable) { layer.AddUpdateIndexComponent(this); } #endregion //If the parent node is null then we stop here if (Parent != null) { if (Parent.DefaultAttributes.Sizing == Sizing.Proportion) { #region Proportional Container Positioning int totalProportionNumber = Parent.Children.Sum(x => x.DefaultAttributes.Grow); int leadingProportionNumber = Parent.Children.TakeWhile(child => child.Index != Index).Sum(x => x.DefaultAttributes.Grow); //Correctly render in the correct stack direction switch (Parent.DefaultAttributes.StackDirection) { case StackDirection.Horizontal: int oneProportionWidth = DefaultAttributes.Width / totalProportionNumber; DefaultAttributes.X += leadingProportionNumber * oneProportionWidth; DefaultAttributes.OffsetX = leadingProportionNumber * oneProportionWidth; DefaultAttributes.Width = oneProportionWidth * DefaultAttributes.Grow; break; case StackDirection.Vertical: int oneProportionHeight = DefaultAttributes.Height / totalProportionNumber; DefaultAttributes.Y += leadingProportionNumber * oneProportionHeight; DefaultAttributes.OffsetY = leadingProportionNumber * oneProportionHeight; DefaultAttributes.Height = oneProportionHeight * DefaultAttributes.Grow; break; } #endregion } else if (Parent.DefaultAttributes.Sizing == Sizing.Dimension) { #region Dimensional Container Positioning switch (Parent.DefaultAttributes.StackDirection) { case StackDirection.Horizontal: int nextWidth = Index * Parent.Children[0].DefaultAttributes.Width; DefaultAttributes.X += nextWidth; DefaultAttributes.OffsetX = nextWidth; break; case StackDirection.Vertical: int nextHeight = Index * Parent.Children[0].DefaultAttributes.Height; DefaultAttributes.Y += nextHeight; DefaultAttributes.OffsetY = nextHeight; break; } #endregion } } foreach (UIConstraint uiConstraint in Constraints) { uiConstraint.Apply(this); } RenderAttributes = DefaultAttributes.CascadeAttributes(DefaultAttributes); }