Пример #1
0
        protected ControlFocusManager(IStaticContainerControl root, ControlFocusManagerContext context)
        {
            Root    = root;
            Context = context ?? throw new ArgumentNullException(nameof(context));

            HookContainerEventHandlers(root);
        }
Пример #2
0
        private static IEnumerable <IControl> Controls(IStaticContainerControl container)
        {
            // Return the container being queried.
            yield return(container);

            for (var i = 0; i < container.ControlsCount; i++)
            {
                if (container[i] is IStaticContainerControl inner)
                {
                    // Query all controls. This will also return the
                    // target control.
                    var controls = Controls(inner);

                    foreach (var control in controls)
                    {
                        yield return(control);
                    }
                }
                else
                {
                    // Not a container, return next.
                    yield return(container[i]);
                }
            }
        }
Пример #3
0
        private static void Focus(IStaticContainerControl container, int index)
        {
            var controls = Controls(container).Where(c => c.VisibleFromParent).ToList();

            if (controls.Count == 0)
            {
                return;
            }

            var next = -1;

            if (index == controls.Max(c => c.TabIndex) || index == -1)
            {
                var candidates = controls.Where(c => c.TabIndex >= 0).ToList();

                if (candidates.Any())
                {
                    next = candidates.Min(c => c.TabIndex);
                }
            }
            else
            {
                var candidates = controls.Where(c => c.TabIndex > index).ToList();

                if (candidates.Any())
                {
                    candidates = controls.Where(c => c.TabIndex >= 0).ToList();

                    if (candidates.Count() != 0)
                    {
                        next = candidates.Min(c => c.TabIndex);
                    }
                }
                else
                {
                    next = candidates.Min(c => c.TabIndex);
                }
            }

            var control = controls.FirstOrDefault(c => next == c.TabIndex);

            if (control == null)
            {
                throw new FatalRuntimeException("could not focus on any control");
            }

            control.Focus();
        }
Пример #4
0
        protected virtual void UnhookContainerEventHandlers(IStaticContainerControl container)
        {
            container.ControlAdded   -= Container_ControlAdded;
            container.ControlRemoved -= Container_ControlRemoved;

            foreach (var control in container.Controls)
            {
                control.FocusChanged   -= Control_FocusChanged;
                control.EnabledChanged -= Control_EnabledChanged;

                if (control is IStaticContainerControl inner)
                {
                    UnhookContainerEventHandlers(inner);
                }

                UnhookCustomEvents(control);
            }
        }
Пример #5
0
        public Ui(string name,
                  IView view,
                  IStaticContainerControl root,
                  IMouseDevice mouse,
                  IKeyboardDevice keyboard)
        {
            Name = !string.IsNullOrEmpty(name) ? name : throw new ArgumentNullException(nameof(name));
            View = view ?? throw new ArgumentNullException(nameof(view));
            Root = root ?? throw new ArgumentNullException(nameof(root));

            this.mouse    = mouse ?? throw new ArgumentNullException(nameof(mouse));
            this.keyboard = keyboard ?? throw new ArgumentNullException(nameof(keyboard));

            var context = new ControlFocusManagerContext();

            mouseFocusManager    = new ControlMouseFocusManager(root, context);
            keyboardFocusManager = new ControlKeyboardFocusManager(root, context);

            UiCanvas.ScreenSizeChanged += UserInterfaceCanvas_ScreenSizeChanged;
        }
Пример #6
0
 public ControlKeyboardFocusManager(IStaticContainerControl root, ControlFocusManagerContext context)
     : base(root, context)
 {
 }
Пример #7
0
        /// <summary>
        /// Attempt to focus a control in given container. Returns boolean declaring
        /// if a control was focused.
        /// </summary>
        private bool Focus(IStaticContainerControl container, Rectf mouse)
        {
            // Container not enabled or does not accept mouse input,
            // can't focus.
            if (!container.Enabled || !container.AcceptsMouseInput)
            {
                return(false);
            }

            // Not inside container, can't have focus to anything then.
            if (!Rectf.Intersects(container.CollisionBoundingBox, mouse))
            {
                return(false);
            }

            if (container.UseRenderTarget)
            {
                mouse = new Rectf(mouse.Position, mouse.Bounds);
            }

            for (var i = container.ControlsCount - 1; i >= 0; i--)
            {
                var child = container[i];

                if (!child.Enabled ||
                    !child.Visible ||
                    !child.VisibleFromParent ||
                    !child.AcceptsMouseInput ||
                    !Rectf.Intersects(child.CollisionBoundingBox, mouse))
                {
                    continue;
                }

                if (child is IStaticContainerControl inner)
                {
                    // Keep track of the currently focused control.
                    var last = Context.Mouse;

                    // Attempt to focus to inner container.
                    if (Focus(inner, mouse))
                    {
                        return(true);
                    }

                    // If the currently focused control changed, focus has changed.
                    // In other case, keep looking for the control that could contain the
                    // focus.
                    var current = Context.Mouse;

                    if (!ReferenceEquals(current, last))
                    {
                        return(true);
                    }

                    // If no focus was applied to any child control, apply focus to current container.
                    Context.Mouse?.Defocus();

                    inner.Focus();
                }
                else
                {
                    // Do not refocus if focused control has not changed.
                    if (ReferenceEquals(Context.Mouse, child))
                    {
                        return(true);
                    }

                    Context.Mouse?.Defocus();

                    child.Focus();
                }
            }

            return(false);
        }
Пример #8
0
 public ControlMouseFocusManager(IStaticContainerControl root, ControlFocusManagerContext context)
     : base(root, context)
 {
 }