From f41e9939fd20f856dded79f48e87248116788b39 Mon Sep 17 00:00:00 2001 From: Roman Shapiro Date: Mon, 23 Oct 2023 16:12:02 +0700 Subject: [PATCH] Fixes #409 --- .../UI/Containers/SingleItemContainer.cs | 10 +++ src/Myra/Graphics2D/UI/TextBox.cs | 61 ++++++++++++------- src/Myra/Graphics2D/UI/Widget.cs | 4 +- src/Myra/Utility/InputHelpers.cs | 24 ++++++++ 4 files changed, 74 insertions(+), 25 deletions(-) diff --git a/src/Myra/Graphics2D/UI/Containers/SingleItemContainer.cs b/src/Myra/Graphics2D/UI/Containers/SingleItemContainer.cs index c0f0be07..e88594a8 100644 --- a/src/Myra/Graphics2D/UI/Containers/SingleItemContainer.cs +++ b/src/Myra/Graphics2D/UI/Containers/SingleItemContainer.cs @@ -30,6 +30,16 @@ protected internal virtual T InternalChild } } + protected override void InternalArrange() + { + base.InternalArrange(); + + if (InternalChild != null && InternalChild.Visible) + { + InternalChild.Arrange(ActualBounds); + } + } + protected override Point InternalMeasure(Point availableSize) { var result = Mathematics.PointZero; diff --git a/src/Myra/Graphics2D/UI/TextBox.cs b/src/Myra/Graphics2D/UI/TextBox.cs index 5813c487..c30e00c0 100644 --- a/src/Myra/Graphics2D/UI/TextBox.cs +++ b/src/Myra/Graphics2D/UI/TextBox.cs @@ -25,6 +25,9 @@ namespace Myra.Graphics2D.UI { public class TextBox : Widget { + private const int CursorUpdateDelayInMs = 30; + + private DateTime _lastCursorUpdate; private DateTime _lastBlinkStamp = DateTime.Now; private bool _cursorOn = true; private bool _wrap = false; @@ -328,6 +331,7 @@ internal set if (Desktop != null) { Desktop.TouchUp -= DesktopTouchUp; + Desktop.TouchDown -= DesktopTouchDown; } base.Desktop = value; @@ -335,11 +339,11 @@ internal set if (Desktop != null) { Desktop.TouchUp += DesktopTouchUp; + Desktop.TouchDown += DesktopTouchDown; } } } - /// /// Fires when the value is about to be changed /// Set Cancel to true if you want to cancel the change @@ -1164,10 +1168,25 @@ public override void OnChar(char c) private void SetCursorByTouch() { + if (Desktop == null) + { + return; + } + var mousePos = ToLocal(Desktop.TouchPosition); mousePos.X += _internalScrolling.X; mousePos.Y += _internalScrolling.Y; + if (mousePos.X < 0) + { + mousePos.X = 0; + } + + if (mousePos.Y < 0) + { + mousePos.Y = 0; + } + var line = _richTextLayout.GetLineByY(mousePos.Y); if (line != null) { @@ -1186,33 +1205,24 @@ private void SetCursorByTouch() } } - public override bool OnTouchDown() + private void DesktopTouchUp(object sender, EventArgs args) { - base.OnTouchDown(); - - if (!Enabled) - { - return false; - } + _isTouchDown = false; + } - if (Length == 0) + private void DesktopTouchDown(object sender, EventArgs e) + { + if (!Enabled || !IsTouchInside || Length == 0) { - return false; + return; } SetCursorByTouch(); + _lastCursorUpdate = DateTime.Now; _isTouchDown = true; - - return true; } - public override void OnTouchMoved() - { - base.OnTouchMoved(); - - SetCursorByTouch(); - } public override void OnTouchDoubleClick() { @@ -1398,6 +1408,16 @@ public override void InternalRender(RenderContext context) return; } + if (_isTouchDown) + { + var passed = DateTime.Now - _lastCursorUpdate; + if (passed.TotalMilliseconds > CursorUpdateDelayInMs) + { + SetCursorByTouch(); + _lastCursorUpdate = DateTime.Now; + } + } + var bounds = ActualBounds; RenderSelection(context); @@ -1540,10 +1560,5 @@ public float GetWidth(int index) return glyph.Value.Bounds.Width; } - - private void DesktopTouchUp(object sender, EventArgs args) - { - _isTouchDown = false; - } } } \ No newline at end of file diff --git a/src/Myra/Graphics2D/UI/Widget.cs b/src/Myra/Graphics2D/UI/Widget.cs index 5f1bf404..afd3650d 100644 --- a/src/Myra/Graphics2D/UI/Widget.cs +++ b/src/Myra/Graphics2D/UI/Widget.cs @@ -1304,7 +1304,7 @@ protected virtual void InternalSetStyle(Stylesheet stylesheet, string name) public virtual void OnMouseLeft() { - ChildrenCopy.ProcessMouseMovement(); + ChildrenCopy.ProcessMouseLeft(); MouseLeft.Invoke(this); } @@ -1338,7 +1338,7 @@ public virtual void OnMouseWheel(float delta) public virtual void OnTouchLeft() { IsTouchInside = false; - ChildrenCopy.ProcessTouchMovement(); + ChildrenCopy.ProcessTouchLeft(); TouchLeft.Invoke(this); } diff --git a/src/Myra/Utility/InputHelpers.cs b/src/Myra/Utility/InputHelpers.cs index f9aa2161..a4f5f02b 100644 --- a/src/Myra/Utility/InputHelpers.cs +++ b/src/Myra/Utility/InputHelpers.cs @@ -120,6 +120,18 @@ public static void ProcessTouchDoubleClick(this List widgets) } } + public static void ProcessMouseLeft(this List widgets) + { + for (var i = widgets.Count - 1; i >= 0; --i) + { + var w = widgets[i]; + if (w.IsMouseInside) + { + w.IsMouseInside = false; + } + } + } + public static void ProcessMouseMovement(this List widgets) { // First run: call on OnMouseLeft on all widgets if it is required @@ -154,6 +166,18 @@ public static void ProcessMouseMovement(this List widgets) } } + public static void ProcessTouchLeft(this List widgets) + { + for (var i = widgets.Count - 1; i >= 0; --i) + { + var w = widgets[i]; + if (w.IsTouchInside) + { + w.OnTouchLeft(); + } + } + } + public static void ProcessTouchMovement(this List widgets) { // First run: call on OnTouchLeft on all widgets if it is required