public void AddUILayer(UILayer uiLayer) { if (!_allUILayers.ContainsKey(uiLayer.Key)) { _allUILayers.Add(uiLayer.Key, uiLayer); } }
/** * Recursively generates the UI structure and applies the UIConstraints and modifiers */ public void BuildComponent(UILayer layer, UIComponent node) { node.ParentLayer = layer; node.Build(layer); foreach (UIComponent childNode in node.Children) { BuildComponent(layer, childNode); } }
/** * 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); }
/** * Recursive method to draw the UI */ private void RenderComponents(UIComponent node, SpriteBatch graphics, UILayer layer) { if (node == null || node.RenderAttributes.Width < 10 || node.RenderAttributes.Height < 10) { return; } if (node.RenderAttributes.Overflow == Overflow.Hide) { #region graphics.Begin() //Stop global buffer graphics.End(); //indicate how we are redrawing the text RasterizerState r = new RasterizerState { ScissorTestEnable = true }; graphics.GraphicsDevice.ScissorRectangle = new Rectangle(node.RenderAttributes.X, node.RenderAttributes.Y, node.RenderAttributes.Width, node.RenderAttributes.Height); //Start new special buffer graphics.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.None, r); #endregion } node.Render(graphics, _contentManager); #region Debug Border if (layer.Debug) { graphics.DrawBorder( new Rectangle( node.RenderAttributes.X, node.RenderAttributes.Y, node.RenderAttributes.Width, node.RenderAttributes.Height), 1, Color.Black, _contentManager.GetTexture("default")); } #endregion #region Focus Border if (node.Focused) { graphics.DrawBorder( new Rectangle( node.RenderAttributes.X, node.RenderAttributes.Y, node.RenderAttributes.Width, node.RenderAttributes.Height), 3, Color.Red, _contentManager.GetTexture("default")); } #endregion foreach (UIComponent childNode in node.Children) { RenderComponents(childNode, graphics, layer); } if (node.RenderAttributes.Overflow == Overflow.Hide) { #region graphics.End() graphics.End(); graphics.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.PointClamp, DepthStencilState.None, RasterizerState.CullCounterClockwise); #endregion } }