/// <summary> /// Creates a UIButton element. /// </summary> /// <param name="parent">The containing UIElement for this button (required).</param> /// <param name="position">The position of this button's center relative to its parent center.</param> /// <param name="width">The render width of the button in pixels.</param> /// <param name="height">The render height of this button in pixels.</param> public UIButton(UIElement parent, Vector2 position, int width, int height) : base(parent, position, width, height) { buttonStateMachine = new ButtonStateMachine(Controller, (int)width, (int)height); buttonStateMachine.Click += OnButtonClick; base.StateMachine = buttonStateMachine; StateMachine.Tag = this; }
/// <summary> /// Creates a UIButton element. /// </summary> /// <param name="game">XNA Game that owns this element.</param> /// <param name="controller">UIController associated with the state machine for this element.</param> /// <param name="positionX">Element position X-coordinate (relative or screen coordinate).</param> /// <param name="positionY">Element position Y-coordinate (relative or screen coordinate).</param> /// <param name="width">Desired width of the element in pixels.</param> /// <param name="height">Desired height of the element in pixels.</param> /// <param name="parent">The containing UIElement for this button (optional).</param> /// <remarks>If parent is not null (x,y) position coordinates are expected to be relative to the parent, /// otherwise they are interpreted as screen coordinates.</remarks> public UIButton(Game game, UIController controller, float positionX, float positionY, int width, int height, UIElement parent) : base(game, controller, null, new Vector2(positionX, positionY), width, height, parent) { buttonStateMachine = new ButtonStateMachine(controller, (int)width, (int)height); buttonStateMachine.Click += OnButtonClick; base.StateMachine = buttonStateMachine; StateMachine.Tag = this; }
/// <summary> /// Create a UIContainer with the specified parameters. /// </summary> /// <param name="game">Game to which the element belongs.</param> /// <param name="controller">UIController associated with this element.</param> /// <param name="texture"></param> /// <param name="position"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="parent"></param> public UIContainer(Game game, UIController controller, string texture, Vector2? position, int width, int height, UIElement parent) : base(game, controller, texture, position, width, height, parent) { nullStateMachine = new NullStateMachine(controller, width, height); StateMachine = nullStateMachine; StateMachine.Tag = this; }
/// <summary> /// Creates a Button element. /// </summary> /// <param name="parent">The containing UIElement for this button (required).</param> /// <param name="position">The position of this button's center relative to its parent center.</param> /// <param name="width">The render width of the button in pixels.</param> /// <param name="height">The render height of this button in pixels.</param> public Button(UIElement parent, Vector2 position, int width, int height) : base(parent, position, width, height) { ViewState = ViewStates.Minimized; // Default animations steps based on the default Game.TargetElapsedType of 1/60 of a second. AnimationSteps = Convert.ToInt32(animationDuration/targetElapsedMilliSeconds); scaleStep = new Vector2((float)(maxItemWidth - minItemWidth)/maxItemWidth , (float)(maxItemHeight - minItemHeight)/maxItemHeight); scaleStep /= (float) AnimationSteps; }
/// <summary> /// Adds a child to this UIElement. /// </summary> /// <remarks>Maintain children in LayerDepth order to ensure proper hit testing.</remarks> /// <param name="child"></param> public void AddChild(UIElement child) { // Require that the child have been created with this element as its parent. Debug.Assert(child.Parent == this); if (!children.Contains(child)) { children.Add(child); SortChildrenByLayerDepth(); } }
/// <summary> /// Finds the layerDepth of the front-most element starting at node. /// </summary> /// <param name="node">UIElement node to begin search.</param> /// <returns>The minimum layerDepth for all elements below node.</returns> public float MinimumLayerDepth(UIElement node) { float minimum = node.LayerDepth; foreach (UIElement child in node.children) { float newMininum = MinimumLayerDepth(child); if (newMininum < minimum) { minimum = newMininum; } } return minimum; }
/// <summary> /// Private contructor invoked by overloaded base contructors to build the UIElement. /// </summary> /// <param name="game"></param> /// <param name="controller"></param> /// <param name="textureFile"></param> /// <param name="texture"></param> /// <param name="position">Position of the UIElement (relative or screen coordinates)</param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="parent"></param> private UIElement(Game game, UIController controller, string textureFile, Texture2D texture, Vector2? position, int width, int height, UIElement parent) : base(game) { // Should only set one or the other, not both. Debug.Assert(textureFile == null || texture == null); this.controller = controller; this.textureSourceFile = textureFile; this.texture = texture; this.width = width; this.height = height; this.parent = parent; instanceCount++; Name = "UIElement " + instanceCount.ToString(CultureInfo.InvariantCulture); if (parent != null) { // Inherit some properties from the parent (containing) UIElement. currentOrientation = parent.currentOrientation; screenTransform = parent.ScreenTransform; spriteBlendState = parent.SpriteBlendState; spriteSortMode = parent.spriteSortMode; // Draw children in front of parents. layerDepth = parent.layerDepth * 0.9f; // Position is a relative to parent's Center. if (position != null) { relativePosition = Vector2.Clamp(position.Value, new Vector2(-0.5f, -0.5f), new Vector2(0.5f, 0.5f)); Vector2 center = parent.Center; float x = center.X + relativePosition.X * parent.Width; float y = center.Y + relativePosition.Y * parent.Height; Center = new Vector2(x, y); } // Add this to parent's liest of children. parent.AddChild(this); } else { // Position is in screen coordinates. if (position != null) { Center = position.Value; } } }
/// <summary> /// Base constructor for UIElement. Only derived classes may call the base constructor. /// </summary> /// <param name="parent"></param> /// <param name="position"></param> /// <param name="width"></param> /// <param name="height"></param> protected UIElement(UIElement parent, Vector2 position, int width, int height) : this(parent.Game, parent.Controller, (string) null, (Texture2D) null, position, width, height, parent) { // Empty. }
/// <summary> /// Base constructor for UIElement. Only derived classes may call the base constructor. /// </summary> /// <param name="game"></param> /// <param name="controller"></param> /// <param name="position"></param> /// <param name="width"></param> /// <param name="height"></param> /// <param name="parent"></param> protected UIElement(Game game, UIController controller, Vector2? position, int width, int height, UIElement parent) : this(game, controller, null, null, position, width, height, parent) { // Empty. }
/// <summary> /// Computes a relative position for a child element. /// </summary> /// <remarks> /// The child will be centered horizontally and the top edge of the child /// will be atthe specified offset from the top edge of the parent. /// </remarks> /// <param name="verticalOffset">Desired offset from top edge of the parent in pixels.</param> /// <param name="childHeight">Height of child in pixels.</param> /// <param name="parent">The containing UIElement.</param> /// <returns>A Vector2 containing the computed center relative position.</returns> public static Vector2 CenterHorizontal(int verticalOffset, float childHeight, UIElement parent) { float y = (verticalOffset + (childHeight / 2f)) / parent.Height - 0.5f; return new Vector2(0.0f, y); }
/// <summary> /// Removes a child from this UIElements list of children. /// </summary> /// <param name="child"></param> public void RemoveChild(UIElement child) { children.Remove(child); // Assumption: removing an element from a list does not alter the order of other elements. }
/// <summary> /// Creates a ScrollBar HUD element with the specified parameters. /// </summary> public ScrollBar(Game game, UIController controller, Vector2? position, float length, ListBoxStateMachine listBox, ScrollBarStateMachine scrollBar, UIElement parent) : base(game, controller, null, position, scrollBar.NumberOfPixelsInHorizontalAxis, scrollBar.NumberOfPixelsInVerticalAxis, parent) { if (scrollBar.Orientation != Orientation.Horizontal) { throw new InvalidOperationException(Properties.Resources.ScrollBarStateMachineShouldBeHorizontal); } this.listBox = listBox; StateMachine = scrollBar; StateMachine.Tag = this; StateMachine.MaximumFlickVelocity = MaximumFlickVelocity; scrollBarLength = length; }
/// <summary> /// Creates a ScrollBar HUD element with the specified parent UIElement. /// </summary> public ScrollBar(UIElement parent, Vector2? position, float length, ListBoxStateMachine listBox, ScrollBarStateMachine scrollBar) : this(parent.Game, parent.Controller, position, length, listBox, scrollBar, parent) { // Empty. }
/// <summary> /// Creates a Listbox UIElement that may or may not have a parent UIElement. /// </summary> /// <param name="game">XNA Game that contains this ListBox</param> /// <param name="contoller">UIController to associate with the ListBoxStateMachine.</param> /// <param name="x">X-coordinate of elements position (relative or screen).</param> /// <param name="y">Y-coordinate of elements position (relative or screen).</param> /// <param name="width">Width of the ListBox in pixels.</param> /// <param name="height">Height of the ListBox in pixels.</param> /// <param name="parent">UIElement that contains the Listbox.</param> /// <param name="textiles">Textiles UIElement controlled by this list box</param> public ListBox(Game game, UIController contoller, float x, float y, int width, int height, UIElement parent, Textiles textiles) : base(game, contoller, new Vector2(x, y), width, height, parent) { listBoxStateMachine = new ListBoxStateMachine(Controller, (int)width, (int)height) { SelectionMode = SelectionMode.Single, Orientation = Orientation.Horizontal, HorizontalElasticity = 0.0f, VerticalElasticity = 0.0f, HorizontalViewportSize = 1f, VerticalViewportSize = 1f, }; StateMachine = listBoxStateMachine; StateMachine.Tag = this; this.textiles = textiles; listBoxStateMachine.ItemStateChanged += OnItemStateChanged; iconScale = new Vector2((float)iconWidth / itemWidth, (float)iconHeight / itemHeight); UIContainer container = parent as UIContainer; if (container != null) { // Create the scrollbar and position it below the listbox. int offset = Convert.ToInt32(Top - parent.Top + Height); Vector2 position = UIElement.CenterHorizontal(offset, scrollBarBackgroundHeight, container); ScrollBar = new ScrollBar(parent, position, width, listBoxStateMachine, listBoxStateMachine.HorizontalScrollBarStateMachine); // Create the Maximze/Minimize button and position it above the listbox. offset = Convert.ToInt32(Top - parent.Top - buttonHeight); position = UIElement.CenterHorizontal(offset, (float) buttonHeight, Parent); minMaxButton = new Button(parent, position, buttonWidth, buttonHeight); minMaxButton.Name = "button"; minMaxButton.AutoScaleTexture = false; } else { throw new InvalidOperationException(Properties.Resources.ListBoxShouldBeInUIContainer); } }
/// <summary> /// Create a ListBox UIElement contained within another UIElement /// </summary> /// <param name="parent">UIElement that contains the Listbox (required).</param> /// <param name="position">Position relative to parent's center (-0.5f .. 0.5f) </param> /// <param name="width">Width of the ListBox in pixels.</param> /// <param name="height">Height of the ListBox in pixels.</param> /// <param name="textiles">Textiles UIElement controlled by this list box</param> public ListBox(UIElement parent, Vector2 position, int width, int height, Textiles textiles) : this(parent.Game, parent.Controller, position.X, position.Y, width, height, parent, textiles) { // Empty. }