public void ValidateEnterAndLeaveInOverlapArea() { GuiWidget container = new GuiWidget(); container.Name = "container"; container.LocalBounds = new RectangleDouble(0, 0, 200, 200); GuiWidget bottomWidget = new GuiWidget(); bottomWidget.Name = "bottom"; bottomWidget.BoundsRelativeToParent = new RectangleDouble(10, 10, 190, 190); int bottomGotEnter = 0; int bottomGotLeave = 0; bottomWidget.MouseEnter += (sender, e) => { if (bottomWidget.UnderMouseState == UnderMouseState.NotUnderMouse) throw new Exception("It must be under the mouse."); bottomGotEnter++; }; bottomWidget.MouseLeave += (sender, e) => { if (bottomWidget.UnderMouseState == UnderMouseState.FirstUnderMouse) throw new Exception("It must not be the first under the mouse."); bottomGotLeave++; }; int bottomGotEnterBounds = 0; int bottomGotLeaveBounds = 0; bottomWidget.MouseEnterBounds += (sender, e) => { if (bottomWidget.UnderMouseState == UnderMouseState.NotUnderMouse) throw new Exception("It must be under the mouse."); bottomGotEnterBounds++; }; bottomWidget.MouseLeaveBounds += (sender, e) => { if (bottomWidget.UnderMouseState != UnderMouseState.NotUnderMouse) throw new Exception("It must not be under the mouse."); bottomGotLeaveBounds++; }; container.AddChild(bottomWidget); GuiWidget topWidget = new GuiWidget(); topWidget.Name = "top"; topWidget.BoundsRelativeToParent = new RectangleDouble(5, 20, 190, 190); int topGotEnter = 0; int topGotLeave = 0; topWidget.MouseEnter += (sender, e) => { if (topWidget.UnderMouseState == UnderMouseState.NotUnderMouse) throw new Exception("It must be under the mouse."); topGotEnter++; }; topWidget.MouseLeave += (sender, e) => { if (topWidget.UnderMouseState == UnderMouseState.FirstUnderMouse) throw new Exception("It must not be the first under the mouse."); topGotLeave++; }; int topGotEnterBounds = 0; int topGotLeaveBounds = 0; topWidget.MouseEnterBounds += (sender, e) => { if (topWidget.UnderMouseState == UnderMouseState.NotUnderMouse) throw new Exception("It must be under the mouse."); topGotEnterBounds++; }; topWidget.MouseLeaveBounds += (sender, e) => { if (topWidget.UnderMouseState != UnderMouseState.NotUnderMouse) throw new Exception("It must not be under the mouse."); topGotLeaveBounds++; }; container.AddChild(topWidget); Assert.IsTrue(topGotEnter == 0); Assert.IsTrue(topGotLeave == 0); Assert.IsTrue(topGotEnterBounds == 0); Assert.IsTrue(topGotLeaveBounds == 0); // move into the bottom widget only container.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, 1, 15, 0)); container.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, 15, 15, 0)); Assert.IsTrue(bottomGotLeave == 0); Assert.IsTrue(bottomGotEnter == 1); Assert.IsTrue(bottomGotLeaveBounds == 0); Assert.IsTrue(bottomGotEnterBounds == 1); Assert.IsTrue(topGotLeave == 0); Assert.IsTrue(topGotEnter == 0); Assert.IsTrue(topGotLeaveBounds == 0); Assert.IsTrue(topGotEnterBounds == 0); // clear our states bottomGotEnter = bottomGotLeave = bottomGotEnterBounds = bottomGotLeaveBounds = 0; topGotEnter = topGotLeave = topGotEnterBounds = topGotLeaveBounds = 0; // move out of the bottom widget only container.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, 1, 15, 0)); Assert.IsTrue(bottomGotLeave == 1); Assert.IsTrue(bottomGotEnter == 0); Assert.IsTrue(bottomGotLeaveBounds == 1); Assert.IsTrue(bottomGotEnterBounds == 0); Assert.IsTrue(topGotLeave == 0); Assert.IsTrue(topGotEnter == 0); Assert.IsTrue(topGotLeaveBounds == 0); Assert.IsTrue(topGotEnterBounds == 0); // move to just outside both widgets container.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, 1, 25, 0)); Assert.IsTrue(bottomWidget.TransformRectangleToScreenSpace(bottomWidget.LocalBounds).Contains(1, 25) == false); Assert.IsTrue(topWidget.TransformRectangleToScreenSpace(topWidget.LocalBounds).Contains(1, 25) == false); // clear our states bottomGotEnter = bottomGotLeave = bottomGotEnterBounds = bottomGotLeaveBounds = 0; topGotEnter = topGotLeave = topGotEnterBounds = topGotLeaveBounds = 0; // move over the top widget when it is over the bottom widget (only the top should see this) container.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, 15, 25, 0)); Assert.IsTrue(bottomGotEnter == 0); Assert.IsTrue(bottomGotLeave == 0); Assert.IsTrue(bottomGotEnterBounds == 1); Assert.IsTrue(bottomGotLeaveBounds == 0); Assert.IsTrue(topGotEnter == 1); Assert.IsTrue(topGotLeave == 0); Assert.IsTrue(topGotEnterBounds == 1); Assert.IsTrue(topGotLeaveBounds == 0); // clear our states bottomGotEnter = bottomGotLeave = bottomGotEnterBounds = bottomGotLeaveBounds = 0; topGotEnter = topGotLeave = topGotEnterBounds = topGotLeaveBounds = 0; // move out of the top widget into the bottom container.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, 15, 15, 0)); Assert.IsTrue(bottomGotEnter == 1); Assert.IsTrue(bottomGotLeave == 0); Assert.IsTrue(bottomGotEnterBounds == 0); Assert.IsTrue(bottomGotLeaveBounds == 0); Assert.IsTrue(topGotEnter == 0); Assert.IsTrue(topGotLeave == 1); Assert.IsTrue(topGotEnterBounds == 0); Assert.IsTrue(topGotLeaveBounds == 1); // clear our states bottomGotEnter = bottomGotLeave = bottomGotEnterBounds = bottomGotLeaveBounds = 0; topGotEnter = topGotLeave = topGotEnterBounds = topGotLeaveBounds = 0; // move back up into the top and make sure we see the leave in the bottom container.OnMouseMove(new MouseEventArgs(MouseButtons.Left, 1, 15, 25, 0)); Assert.IsTrue(bottomGotEnter == 0); Assert.IsTrue(bottomGotLeave == 1); Assert.IsTrue(bottomGotEnterBounds == 0); Assert.IsTrue(bottomGotLeaveBounds == 0); Assert.IsTrue(topGotEnter == 1); Assert.IsTrue(topGotLeave == 0); Assert.IsTrue(topGotEnterBounds == 1); Assert.IsTrue(topGotLeaveBounds == 0); }