public void Grab() { var layout = _guiElement.GetLayout(); // create the container where we will move the draggable inside and where we create highlight for drop targets DragAndDropStage = new Canvas(); _guiElement.GetStage().AddChild(DragAndDropStage); // replace the guiElement with a spacer while it is draggeed Replacer = new Spacer(layout.GetCalculatedWidth(), layout.GetCalculatedHeight()); _guiElement.GetParent().ReplaceChild(_guiElement, Replacer); OriginalPosition = new Vector2(layout.X, layout.Y); var absoluteGeometry = _guiElement.GetLayoutProcessingData().AbsoluteGeometry; layout.X = absoluteGeometry.X; layout.Y = absoluteGeometry.Y; // add the draggable on to the DragAndDropStage DragAndDropStage.AddChild(_guiElement); MousePosInComponent = new Point( GuiStage.MousePosition.X - layout.X, GuiStage.MousePosition.Y - layout.Y ); }
protected void TestAcceptanceFor(IRenderer renderer, IGuiElement guiElement) { var hardware = new NullHardware(1024, 768); var stage = new GuiStage(); stage.AddChild(guiElement); // Layout and Render stage.CalculateLayout(hardware); stage.ProcessInteraction(hardware); stage.Render(renderer); var processingData = guiElement.GetLayoutProcessingData(); // drawing geometry Assert.AreEqual(processingData.DrawingGeometry.X, 50); Assert.AreEqual(processingData.DrawingGeometry.Y, 75); Assert.AreEqual(processingData.DrawingGeometry.Width, 100); Assert.AreEqual(processingData.DrawingGeometry.Height, 200); // absolute geometry Assert.AreEqual(processingData.AbsoluteGeometry.X, 50); Assert.AreEqual(processingData.AbsoluteGeometry.Y, 75); Assert.AreEqual(processingData.AbsoluteGeometry.Width, 100); Assert.AreEqual(processingData.AbsoluteGeometry.Height, 200); // clip rect Assert.AreEqual(processingData.ClipRect.X, 50); Assert.AreEqual(processingData.ClipRect.Y, 75); Assert.AreEqual(processingData.ClipRect.Width, 100); Assert.AreEqual(processingData.AbsoluteGeometry.Height, 200); }
private void ProcessInputsRecursive(IGuiElement component, IRectangle clipRect) { if (!component.GetVisible()) { return; } if (component is IGuiElementContainer) { var container = (IGuiElementContainer)component; var children = container.GetChildren(); var componenetClipRect = component.GetLayoutProcessingData().ClipRect; // merge the two rectangle to get the cut-set var resultingClipRect = clipRect.Intersect(componenetClipRect); // just go further in the recursion if there is space left in the clip rect if (resultingClipRect.Width > 0 && resultingClipRect.Height > 0) { // first go down the recursion // But we have to go from the last to the first child. We have to do it, so the top most child (with same parent as its sibblings) // will receive events like Clicked, that are only sent to one gui element. var count = children.Count; for (var i = count - 1; i >= 0; --i) { var child = children[i]; ProcessInputsRecursive(child, resultingClipRect); } } // on the back path check for events ProcessComponentInputs(component, clipRect); } else { ProcessComponentInputs(component, clipRect); } }
private void ProcessComponentInputs(IGuiElement component, IRectangle clipRect) { // does the element have mouse processing enabled? if (!component.GetMouseEnabled()) { return; } var processingData = component.GetLayoutProcessingData(); // is the mouse actually hovering over the element var containsCurrent = processingData.AbsoluteGeometry.Contains(GuiStage.MousePosition) && clipRect.Contains(GuiStage.MousePosition) && component.GetLayout().Visible ; // was it hovering over the element in the last frame var containsPrevious = processingData.MouseWasOver; // remember the current situation for the next frame processingData.MouseWasOver = containsCurrent; if (containsCurrent) { _result.GuiElementsUnderMouse.Add(component); } // check for mouse over if (containsCurrent && !containsPrevious) { _result.MouseOverEvent.Add(component); } // check for mouse out if (!containsCurrent && containsPrevious) { _result.MouseOutEvent.Add(component); } // check for clicks if (containsCurrent) { // check for left mouse down if (!_previousMouseButtonLeft && _currentMouseButtonLeft) { _result.LeftMouseDownEvent.Add(component); } // check for left mouse up / clicked if (_previousMouseButtonLeft && !_currentMouseButtonLeft) { _result.LeftMouseUpEvent.Add(component); _result.ClickedEvent.Add(component); // detect double click var now = DateTime.Now; if ((now - processingData.LastClickTimestamp).TotalMilliseconds < 500) { _result.DoubleClickedEvent.Add(component); } // remember the last click time processingData.LastClickTimestamp = DateTime.Now; } // check for right mouse down if (!_previousMouseButtonRight && _currentMouseButtonRight) { _result.RightMouseDownEvent.Add(component); } // check for right mouse up if (_previousMouseButtonRight && !_currentMouseButtonRight) { _result.RightMouseUpEvent.Add(component); } // check for middle mouse down if (!_previousMouseButtonMiddle && _currentMouseButtonMiddle) { _result.MiddleMouseDownEvent.Add(component); } // check for right mouse up if (_previousMouseButtonMiddle && !_currentMouseButtonMiddle) { _result.MiddleMouseUpEvent.Add(component); } } }