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);
        }
示例#3
0
        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);
            }
        }
示例#4
0
        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);
                }
            }
        }