internal void Click(InputEngines.XnaMouseEventArgs e)
        {
            if (!e.Handled)
            {
                if (OnClick != null)
                {
                    OnClick(this, e);
                }
                if (e.Target != this)
                {
                    XnaUIComponent nextTarget = e.Target;
                    while (nextTarget.Parent != this)
                    {
                        nextTarget = nextTarget.Parent;
                    }
                    Point currentPoint = e.ClickLocation;
                    Point offsetPoint  = new Point(currentPoint.X, currentPoint.Y);
                    offsetPoint.X  -= ScrollX;
                    offsetPoint.X  -= nextTarget.drawBox.X;
                    offsetPoint.Y  -= ScrollY;
                    offsetPoint.Y  -= nextTarget.drawBox.Y;
                    e.ClickLocation = offsetPoint;
                    nextTarget.Click(e);

                    // Repair event
                    e.ClickLocation = currentPoint;
                }
                e.Bubbled = true;
                if (!e.Handled && (OnClick != null))
                {
                    OnClick(this, e);
                }
            }
        }
        public override void DoLayout()
        {
            int count = GetChildren().Count;

            if (count > 0)
            {
                // TODO: how to set space between icons
                //System.Console.Out.WriteLine(count);
                XnaUIComponent firstComponent = GetChildren()[0];
                int            boxWidth       = firstComponent.DrawBox.Width;
                int            boxHeight      = firstComponent.DrawBox.Height;

                int totalAllowableWidthAfterFirstElementInRow = DrawBox.Width - boxWidth;
                int numberOfElementInRow = 1 + totalAllowableWidthAfterFirstElementInRow / (boxWidth + SpacingBetween);
                int current = 0;
                foreach (XnaUIComponent component in GetChildren())
                {
                    int x = (current % numberOfElementInRow) * (boxWidth + SpacingBetween);
                    int y = (current / numberOfElementInRow) * (boxHeight + SpacingBetween);

                    component.DrawBox = new Rectangle(x, y, boxWidth, boxHeight);

                    current++;
                }
            }
        }
 /// <summary>
 /// Removes child from the component list, and updates the child's parent.
 /// </summary>
 /// <param name="child"></param>
 public virtual void RemoveChild(XnaUIComponent child)
 {
     if (child != null)
     {
         // This will remove the child from the component list.
         child.SetParent(null);
         //DoLayout();
     }
 }
 /// <summary>
 /// Adds child to the component list, and updates the child's parent.
 /// </summary>
 /// <param name="child"></param>
 public virtual void AddChild(XnaUIComponent child)
 {
     if (child != null)
     {
         child.SetParent(this);
         components.Add(child);
         //DoLayout();
     }
 }
        // Composite pattern methods

        /// <summary>
        /// Called from AddChild and RemoveChild only.  Updates the child so that it references the parent as its container.
        /// If AddChild is called from a different parent, it should remove its reference to its current container.
        /// </summary>
        /// <param name="parent"></param>
        public void SetParent(XnaUIComponent parent)
        {
            if (container != null)
            {
                // Remove it from the parent.
                container.GetChildren().Remove(this);
            }
            container = parent;
        }
        /// <summary>
        /// Returns the sprite batch from the XnaUIFrame that this XnaUIComponent is in.  The frame may
        /// hold on to several sprite batches, and depend on the requester to determine which one to return back
        /// for drawing.
        /// </summary>
        /// <param name="requester"></param>
        /// <returns></returns>
        public virtual SpriteBatch GetSpriteBatch(XnaUIComponent requester)
        {
            SpriteBatch sb = null;

            if (container != null)
            {
                sb = container.GetSpriteBatch(requester);
            }
            return(sb);
        }
        private bool overlapsDragBox(XnaUIComponent child)
        {
            // Two rectangles overlap if one of their corners is contained in the other, or if one is completely contained in the other.
            // This can be tested by testing 4 corners in one and one corner in the other.
            Point point1 = new Point(child.DrawBox.X, child.DrawBox.Y);

            if (rectContainsPoint(dragBox.DrawBox, point1))
            {
                return(true);
            }
            Point point2 = new Point(child.DrawBox.X + child.DrawBox.Width, child.DrawBox.Y);

            if (rectContainsPoint(dragBox.DrawBox, point2))
            {
                return(true);
            }
            Point point3 = new Point(child.DrawBox.X, child.DrawBox.Y + child.DrawBox.Height);

            if (rectContainsPoint(dragBox.DrawBox, point3))
            {
                return(true);
            }
            Point point4 = new Point(child.DrawBox.X + child.DrawBox.Width, child.DrawBox.Y + child.DrawBox.Height);

            if (rectContainsPoint(dragBox.DrawBox, point4))
            {
                return(true);
            }
            Point point5 = new Point(dragBox.DrawBox.X, dragBox.DrawBox.Y);

            if (rectContainsPoint(child.DrawBox, point5))
            {
                return(true);
            }
            return(false);
        }
 private bool overlapsDragBox(XnaUIComponent child)
 {
     // Two rectangles overlap if one of their corners is contained in the other, or if one is completely contained in the other.
     // This can be tested by testing 4 corners in one and one corner in the other.
     Point point1 = new Point(child.DrawBox.X, child.DrawBox.Y);
     if (rectContainsPoint(dragBox.DrawBox, point1))
         return true;
     Point point2 = new Point(child.DrawBox.X + child.DrawBox.Width, child.DrawBox.Y);
     if (rectContainsPoint(dragBox.DrawBox, point2))
         return true;
     Point point3 = new Point(child.DrawBox.X, child.DrawBox.Y + child.DrawBox.Height);
     if (rectContainsPoint(dragBox.DrawBox, point3))
         return true;
     Point point4 = new Point(child.DrawBox.X + child.DrawBox.Width, child.DrawBox.Y + child.DrawBox.Height);
     if (rectContainsPoint(dragBox.DrawBox, point4))
         return true;
     Point point5 = new Point(dragBox.DrawBox.X, dragBox.DrawBox.Y);
     if (rectContainsPoint(child.DrawBox, point5))
         return true;
     return false;
 }
        public override void Update(GameTime gameTime)
        {
            MouseState mouseState = Mouse.GetState();
            Point mousePoint = new Point(mouseState.X, mouseState.Y);
            XnaUIComponent currentUIOn = GetTarget(mousePoint);

            // Fire all events for mouse down, mouse up, and clicks
            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                if (leftMouseDownTarget == null)
                {
                    leftMouseDownTarget = GetTarget(mousePoint);
                    XnaMouseEventArgs e = new XnaMouseEventArgs();
                    e.Target = leftMouseDownTarget;
                    e.ClickLocation = mousePoint;
                    e.Handled = false;
                    e.Bubbled = false;
                    e.ButtonPressed = MouseButton.Left;
                    e.SingleTarget = true;
                    e.time = System.Environment.TickCount;
                    frame.MouseDown(e);
                }
            }
            else
            {
                if (leftMouseDownTarget != null)
                {
                    XnaUIComponent leftMouseUpTarget = currentUIOn;
                    XnaUIComponent commonAncestor = getCommonAncestor(leftMouseDownTarget, leftMouseUpTarget);
                    if (commonAncestor != null)
                    {
                        XnaMouseEventArgs mouseUpEventArgs = new XnaMouseEventArgs();
                        mouseUpEventArgs.Target = commonAncestor;
                        mouseUpEventArgs.ClickLocation = mousePoint;
                        mouseUpEventArgs.Handled = false;
                        mouseUpEventArgs.Bubbled = false;
                        mouseUpEventArgs.ButtonPressed = MouseButton.Left;
                        mouseUpEventArgs.SingleTarget = (leftMouseDownTarget == leftMouseUpTarget);
                        mouseUpEventArgs.time = System.Environment.TickCount;
                        frame.MouseUp(mouseUpEventArgs);

                        XnaMouseEventArgs e = new XnaMouseEventArgs();
                        e.Target = commonAncestor;
                        e.ClickLocation = mousePoint;
                        e.Handled = false;
                        e.Bubbled = false;
                        e.ButtonPressed = MouseButton.Left;
                        e.SingleTarget = (leftMouseDownTarget == leftMouseUpTarget);
                        e.time = System.Environment.TickCount;
                        frame.Click(e);
                    }
                    // Reset the state.
                    leftMouseDownTarget = null;
                }
            }

            if (mouseState.RightButton == ButtonState.Pressed)
            {
                if (rightMouseDownTarget == null)
                {
                    rightMouseDownTarget = currentUIOn;
                    XnaMouseEventArgs e = new XnaMouseEventArgs();
                    e.Target = rightMouseDownTarget;
                    e.ClickLocation = mousePoint;
                    e.Handled = false;
                    e.Bubbled = false;
                    e.ButtonPressed = MouseButton.Right;
                    e.SingleTarget = true;
                    e.time = System.Environment.TickCount;
                    frame.MouseDown(e);
                }
            }
            else
            {
                if (rightMouseDownTarget != null)
                {
                    XnaUIComponent rightMouseUpTarget = GetTarget(mousePoint);
                    XnaUIComponent commonAncestor = getCommonAncestor(rightMouseDownTarget, rightMouseUpTarget);

                    if (commonAncestor != null)
                    {
                        XnaMouseEventArgs mouseUpEventArgs = new XnaMouseEventArgs();
                        mouseUpEventArgs.Target = commonAncestor;
                        mouseUpEventArgs.ClickLocation = mousePoint;
                        mouseUpEventArgs.Handled = false;
                        mouseUpEventArgs.Bubbled = false;
                        mouseUpEventArgs.ButtonPressed = MouseButton.Left;
                        mouseUpEventArgs.SingleTarget = (rightMouseDownTarget == rightMouseUpTarget);
                        mouseUpEventArgs.time = System.Environment.TickCount;
                        frame.MouseUp(mouseUpEventArgs);

                        XnaMouseEventArgs e = new XnaMouseEventArgs();
                        e.Target = commonAncestor;
                        e.ClickLocation = mousePoint;
                        e.Handled = false;
                        e.Bubbled = false;
                        e.ButtonPressed = MouseButton.Right;
                        e.SingleTarget = (rightMouseDownTarget == rightMouseUpTarget);
                        e.time = System.Environment.TickCount;
                        frame.Click(e);
                    }
                    // Reset the state.
                    rightMouseDownTarget = null;
                }
            }

            // Handle mouse enter and exit events.
            if (mouseHoverTarget != currentUIOn)
            {
                // Base case : First time entering.
                if (mouseHoverTarget == null)
                {
                    XnaUIComponent current = currentUIOn;
                    Stack<XnaUIComponent> stack = new Stack<XnaUIComponent>();
                    while (current != null)
                    {
                        stack.Push(current);
                        current = current.Parent;
                    }
                    while (stack.Count > 0)
                    {
                        current = stack.Pop();
                        current.MouseEnter();
                    }
                }
                else
                {
                    // Mouse has moved
                    XnaUIComponent current = mouseHoverTarget;
                    XnaUIComponent ancestor = getCommonAncestor(currentUIOn, mouseHoverTarget);
                    while (current != ancestor)
                    {
                        current.MouseLeave();
                        current = current.Parent;
                    }
                    current = currentUIOn;
                    Stack<XnaUIComponent> stack = new Stack<XnaUIComponent>();
                    while (current != ancestor)
                    {
                        stack.Push(current);
                        current = current.Parent;
                    }
                    while (stack.Count > 0)
                    {
                        current = stack.Pop();
                        current.MouseEnter();
                    }
                }
                mouseHoverTarget = currentUIOn;
            }
            base.Update(gameTime);
        }
        private XnaUIComponent getCommonAncestor(XnaUIComponent c1, XnaUIComponent c2)
        {
            List<XnaUIComponent> list1 = new List<XnaUIComponent>();
            XnaUIComponent current = c1;
            while (current != null)
            {
                list1.Add(current);
                current = current.Parent;
            }
            List<XnaUIComponent> list2 = new List<XnaUIComponent>();
            current = c2;
            while (current != null)
            {
                list2.Add(current);
                current = current.Parent;
            }
            int differenceInSize = Math.Abs(list1.Count - list2.Count);
            List<XnaUIComponent> longerList = list2.Count > list1.Count ? list2 : list1;
            while (differenceInSize > 0)
            {
                longerList.RemoveAt(0);
                differenceInSize--;
            }

            XnaUIComponent commonAncestor = null;
            for (int i = 0; i < list1.Count; i++)
            {
                if (list1[i] == list2[i])
                {
                    commonAncestor = list1[i];
                    break;
                }
            }
            return commonAncestor;
        }
 public override SpriteBatch GetSpriteBatch(XnaUIComponent requester)
 {
     return(spriteBatch);
 }
 public override SpriteBatch GetSpriteBatch(XnaUIComponent requester)
 {
     return spriteBatch;
 }
 /// <summary>
 /// Adds child to the component list, and updates the child's parent.
 /// </summary>
 /// <param name="child"></param>
 public virtual void AddChild(XnaUIComponent child)
 {
     if (child != null)
     {
         child.SetParent(this);
         components.Add(child);
         DoLayout();
     }
 }
 // Composite pattern methods
 /// <summary>
 /// Called from AddChild and RemoveChild only.  Updates the child so that it references the parent as its container.
 /// If AddChild is called from a different parent, it should remove its reference to its current container.
 /// </summary>
 /// <param name="parent"></param>
 public void SetParent(XnaUIComponent parent)
 {
     if (container != null)
     {
         // Remove it from the parent.
         container.GetChildren().Remove(this);
     }
     container = parent;
 }
 /// <summary>
 /// Removes child from the component list, and updates the child's parent.
 /// </summary>
 /// <param name="child"></param>
 public virtual void RemoveChild(XnaUIComponent child)
 {
     if (child != null)
     {
         // This will remove the child from the component list.
         child.SetParent(null);
         DoLayout();
     }
 }
 /// <summary>
 /// Returns the sprite batch from the XnaUIFrame that this XnaUIComponent is in.  The frame may
 /// hold on to several sprite batches, and depend on the requester to determine which one to return back
 /// for drawing.
 /// </summary>
 /// <param name="requester"></param>
 /// <returns></returns>
 public virtual SpriteBatch GetSpriteBatch(XnaUIComponent requester)
 {
     SpriteBatch sb = null;
     if (container != null)
     {
         sb = container.GetSpriteBatch(requester);
     }
     return sb;
 }