From 6b1e5f8dd9cb908ab449a7d3e04a71e42a2a3561 Mon Sep 17 00:00:00 2001 From: Ellpeck Date: Thu, 4 Jun 2020 20:52:21 +0200 Subject: [PATCH] better implementation of the touch mousing from yesterday --- MLEM.Ui/Elements/Element.cs | 17 ++++++++++- MLEM.Ui/UiControls.cs | 60 ++++++++++++++++++++++++++++++------- MLEM.Ui/UiSystem.cs | 13 ++++++++ 3 files changed, 79 insertions(+), 11 deletions(-) diff --git a/MLEM.Ui/Elements/Element.cs b/MLEM.Ui/Elements/Element.cs index 6da76a7..5445b95 100644 --- a/MLEM.Ui/Elements/Element.cs +++ b/MLEM.Ui/Elements/Element.cs @@ -259,7 +259,7 @@ namespace MLEM.Ui.Elements { public float DrawAlpha = 1; /// - /// Stores whether this element is currently being moused over. + /// Stores whether this element is currently being moused over or touched. /// public bool IsMouseOver { get; protected set; } /// @@ -300,6 +300,14 @@ namespace MLEM.Ui.Elements { /// public GenericCallback OnMouseExit; /// + /// Event that is called when this element starts being touched + /// + public GenericCallback OnTouchEnter; + /// + /// Event that is called when this element stops being touched + /// + public GenericCallback OnTouchExit; + /// /// Event that is called when text input is made. /// Note that this event is called for every element, even if it is not selected. /// Also note that if is true, this event is never called. @@ -315,6 +323,11 @@ namespace MLEM.Ui.Elements { /// public OtherElementCallback OnMousedElementChanged; /// + /// Event that is called when the element that is currently being touched changes within the ui system. + /// Note that the event fired doesn't necessarily correlate to this specific element. + /// + public OtherElementCallback OnTouchedElementChanged; + /// /// Event that is called when the element that is currently selected changes within the ui system. /// Note that the event fired doesn't necessarily correlate to this specific element. /// @@ -362,6 +375,8 @@ namespace MLEM.Ui.Elements { this.OnMouseEnter += element => this.IsMouseOver = true; this.OnMouseExit += element => this.IsMouseOver = false; + this.OnTouchEnter += element => this.IsMouseOver = true; + this.OnTouchExit += element => this.IsMouseOver = false; this.OnSelected += element => this.IsSelected = true; this.OnDeselected += element => this.IsSelected = false; this.GetTabNextElement += (backward, next) => next; diff --git a/MLEM.Ui/UiControls.cs b/MLEM.Ui/UiControls.cs index 7fe791f..6250685 100644 --- a/MLEM.Ui/UiControls.cs +++ b/MLEM.Ui/UiControls.cs @@ -35,11 +35,15 @@ namespace MLEM.Ui { /// The that is currently active. /// The active root element is the one with the highest that whose property is true. /// - public RootElement ActiveRoot { get; private set; } + public RootElement ActiveRoot { get; protected set; } /// /// The that the mouse is currently over. /// - public Element MousedElement { get; private set; } + public Element MousedElement { get; protected set; } + /// + /// The that is currently touched. + /// + public Element TouchedElement { get; protected set; } private readonly Dictionary selectedElements = new Dictionary(); /// /// The element that is currently selected. @@ -141,14 +145,7 @@ namespace MLEM.Ui { // MOUSE INPUT if (this.HandleMouse) { var mousedNow = this.GetElementUnderPos(this.Input.MousePosition.ToVector2()); - if (mousedNow != this.MousedElement) { - if (this.MousedElement != null) - this.System.OnElementMouseExit?.Invoke(this.MousedElement); - if (mousedNow != null) - this.System.OnElementMouseEnter?.Invoke(mousedNow); - this.MousedElement = mousedNow; - this.System.OnMousedElementChanged?.Invoke(mousedNow); - } + this.SetMousedElement(mousedNow); if (this.Input.IsMouseButtonPressed(MouseButton.Left)) { this.IsAutoNavMode = false; @@ -200,6 +197,19 @@ namespace MLEM.Ui { this.SelectElement(this.ActiveRoot, held); if (held != null && held.CanBePressed) this.System.OnElementSecondaryPressed?.Invoke(held); + } else if (this.Input.TouchState.Count <= 0) { + this.SetTouchedElement(null); + } else { + foreach (var location in this.Input.TouchState) { + var element = this.GetElementUnderPos(location.Position); + if (location.State == TouchLocationState.Pressed) { + // start touching an element if we just touched down on it + this.SetTouchedElement(element); + } else if (element != this.TouchedElement) { + // if we moved off of the touched element, we stop touching + this.SetTouchedElement(null); + } + } } } @@ -269,6 +279,36 @@ namespace MLEM.Ui { this.IsAutoNavMode = autoNav.Value; } + /// + /// Sets the to the given value, calling the appropriate events. + /// + /// The element to set as moused + public void SetMousedElement(Element element) { + if (element != this.MousedElement) { + if (this.MousedElement != null) + this.System.OnElementMouseExit?.Invoke(this.MousedElement); + if (element != null) + this.System.OnElementMouseEnter?.Invoke(element); + this.MousedElement = element; + this.System.OnMousedElementChanged?.Invoke(element); + } + } + + /// + /// Sets the to the given value, calling the appropriate events. + /// + /// The element to set as touched + public void SetTouchedElement(Element element) { + if (element != this.TouchedElement) { + if (this.TouchedElement != null) + this.System.OnElementTouchExit?.Invoke(this.TouchedElement); + if (element != null) + this.System.OnElementTouchEnter?.Invoke(element); + this.TouchedElement = element; + this.System.OnTouchedElementChanged?.Invoke(element); + } + } + /// /// Returns the selected element for the given root element. /// A property equivalent to this method is . diff --git a/MLEM.Ui/UiSystem.cs b/MLEM.Ui/UiSystem.cs index 0a4bbc7..2a398b6 100644 --- a/MLEM.Ui/UiSystem.cs +++ b/MLEM.Ui/UiSystem.cs @@ -141,6 +141,14 @@ namespace MLEM.Ui { /// public Element.GenericCallback OnElementMouseExit = e => e.OnMouseExit?.Invoke(e); /// + /// Event that is invoked when an starts being touched + /// + public Element.GenericCallback OnElementTouchEnter = e => e.OnTouchEnter?.Invoke(e); + /// + /// Event that is invoked when an stops being touched + /// + public Element.GenericCallback OnElementTouchExit = e => e.OnTouchExit?.Invoke(e); + /// /// Event that is invoked when an 's display area changes /// public Element.GenericCallback OnElementAreaUpdated = e => e.OnAreaUpdated?.Invoke(e); @@ -149,6 +157,10 @@ namespace MLEM.Ui { /// public Element.GenericCallback OnMousedElementChanged; /// + /// Event that is invoked when the that is being touched changes + /// + public Element.GenericCallback OnTouchedElementChanged; + /// /// Event that is invoked when the selected changes, either through automatic navigation, or by pressing on an element with the mouse /// public Element.GenericCallback OnSelectedElementChanged; @@ -184,6 +196,7 @@ namespace MLEM.Ui { TextInputWrapper.Current.AddListener(window, (sender, key, character) => this.ApplyToAll(e => e.OnTextInput?.Invoke(e, key, character))); this.OnMousedElementChanged = e => this.ApplyToAll(t => t.OnMousedElementChanged?.Invoke(t, e)); + this.OnTouchedElementChanged = e => this.ApplyToAll(t => t.OnTouchedElementChanged?.Invoke(t, e)); this.OnSelectedElementChanged = e => this.ApplyToAll(t => t.OnSelectedElementChanged?.Invoke(t, e)); this.OnSelectedElementDrawn = (element, time, batch, alpha) => { if (this.Controls.IsAutoNavMode && element.SelectionIndicator.HasValue()) {