public int CreateComponent(Component toAdd) { int freeHandle = components.IndexOf(null); if (freeHandle == -1) { toAdd.Handle = components.Count; components.Add(toAdd); return components.Count - 1; } else { toAdd.Handle = freeHandle; components.Add(toAdd); return freeHandle; } }
/// <summary> /// Updates which control the mouse is hovering over. /// </summary> /// <param name="mouseState">The current mouse state.</param> private void UpdateHoveredComponent(MouseState mouseState) { // TODO: Refactor this Rectangle cursorBounds = new Rectangle(mouseState.X, mouseState.Y, 1, 1); if (currentHoveringComponent != null && currentHoveringComponent is IMouseResponder && !currentHoveringComponent.Style.Bounds.Intersects(cursorBounds)) { (currentHoveringComponent as IMouseResponder).InvokeMouseLeave(mouseState); currentHoveringComponent = null; } for (int i = components.Count - 1; i >= 0; i--) { if (!components[i].Style.Bounds.Intersects(cursorBounds)) continue; if (mouseState.LeftButton == ButtonState.Pressed || mouseState.RightButton == ButtonState.Pressed) ComponentToFront(components[i].Handle); var hoveringComponent = GetHoveredChild(cursorBounds, components[i]); if (!(hoveringComponent is IMouseResponder)) continue; if (currentHoveringComponent != null && currentHoveringComponent != hoveringComponent) { (currentHoveringComponent as IMouseResponder).InvokeMouseLeave(mouseState); currentHoveringComponent = null; } if (currentHoveringComponent != hoveringComponent) (hoveringComponent as IMouseResponder).InvokeMouseEnter(mouseState); currentHoveringComponent = hoveringComponent; break; } }
/// <summary> /// Gets the child of the initialComponent that is under the cursor. Returns the initial /// component if no child is under the cursor. /// </summary> /// <param name="cursorBounds">The location and size of the cursor.</param> /// <param name="initialOwner">The component whose children are being checked.</param> private Component GetHoveredChild(Rectangle cursorBounds, Component initialOwner) { // Replacement for a nasty recursive algorithm to find the component under the cursor. var currentComponent = initialOwner; bool childIntersects = true; while (childIntersects) { childIntersects = false; for (int i = currentComponent.Children.Count - 1; i >= 0; i--) { if (currentComponent.Children[i].Style.Bounds.Intersects(cursorBounds)) { currentComponent = currentComponent.Children[i]; childIntersects = true; break; } } } return currentComponent; }