protected ControlFocusManager(IStaticContainerControl root, ControlFocusManagerContext context) { Root = root; Context = context ?? throw new ArgumentNullException(nameof(context)); HookContainerEventHandlers(root); }
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]); } } }
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(); }
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); } }
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; }
public ControlKeyboardFocusManager(IStaticContainerControl root, ControlFocusManagerContext context) : base(root, context) { }
/// <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); }
public ControlMouseFocusManager(IStaticContainerControl root, ControlFocusManagerContext context) : base(root, context) { }