// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using osuTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Input.Events; using osu.Framework.Platform; using osu.Game.Input.Bindings; using osuTK.Input; using osu.Framework.Input.Bindings; using osu.Game.Overlays; namespace osu.Game.Graphics.UserInterface { /// /// A textbox which holds focus eagerly. /// public partial class FocusedTextBox : OsuTextBox, IKeyBindingHandler { private bool focus; private bool allowImmediateFocus => host?.OnScreenKeyboardOverlapsGameWindow != true; /// /// Whether the content of the text box should be cleared on the first "back" key press. /// protected virtual bool ClearTextOnBackKey => true; public void TakeFocus() { if (!allowImmediateFocus) return; Scheduler.Add(() => GetContainingFocusManager()!.ChangeFocus(this)); } public new void KillFocus() => base.KillFocus(); public bool HoldFocus { get => allowImmediateFocus && focus; set { focus = value; if (!focus && HasFocus) base.KillFocus(); } } [Resolved] private GameHost? host { get; set; } [BackgroundDependencyLoader(true)] private void load(OverlayColourProvider? colourProvider) { BackgroundUnfocused = colourProvider?.Background5 ?? new Color4(10, 10, 10, 255); BackgroundFocused = colourProvider?.Background5 ?? new Color4(10, 10, 10, 255); } // We may not be focused yet, but we need to handle keyboard input to be able to request focus public override bool HandleNonPositionalInput => HoldFocus || base.HandleNonPositionalInput; protected override void OnFocus(FocusEvent e) { base.OnFocus(e); BorderThickness = 0; } protected override bool OnKeyDown(KeyDownEvent e) { if (!HasFocus) return false; if (e.Key == Key.Escape) return false; // disable the framework-level handling of escape key for conformity (we use GlobalAction.Back). return base.OnKeyDown(e); } public virtual bool OnPressed(KeyBindingPressEvent e) { if (e.Repeat) return false; if (!HasFocus) return false; if (ClearTextOnBackKey && e.Action == GlobalAction.Back) { if (Text.Length > 0) { Text = string.Empty; PlayFeedbackSample(FeedbackSampleType.TextRemove); return true; } } return false; } public void OnReleased(KeyBindingReleaseEvent e) { } public override bool RequestsFocus => HoldFocus; } }