From a6b561f2832f814a623d38b0b16397c87f42e251 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Thu, 28 Jan 2021 19:51:54 +0100 Subject: [PATCH] text box Validate event --- Crow/src/DebugUtils/DebugLogger.cs | 11 +- Crow/src/EventArgs/DragDropEventArgs.cs | 33 +--- Crow/src/EventArgs/LayoutingEventArgs.cs | 38 ++-- Crow/src/EventArgs/ListChangedEventArg.cs | 2 +- .../EventArgs/MouseCursorChangedEventArgs.cs | 30 +-- Crow/src/EventArgs/ScrollingEventArgs.cs | 27 +-- Crow/src/EventArgs/TextChangeEventArgs.cs | 32 +--- Crow/src/EventArgs/ValidateEventArgs.cs | 22 +++ Crow/src/Interface.cs | 7 +- Crow/src/Widgets/Label.cs | 2 +- Crow/src/Widgets/TextBox.cs | 171 ++++++++++-------- Crow/src/Widgets/Widget.cs | 8 +- Directory.Build.props | 2 +- 13 files changed, 161 insertions(+), 224 deletions(-) create mode 100644 Crow/src/EventArgs/ValidateEventArgs.cs diff --git a/Crow/src/DebugUtils/DebugLogger.cs b/Crow/src/DebugUtils/DebugLogger.cs index ce0fa214..cbaec88c 100644 --- a/Crow/src/DebugUtils/DebugLogger.cs +++ b/Crow/src/DebugUtils/DebugLogger.cs @@ -32,9 +32,10 @@ namespace Crow IFaceInit = IFace | 0x06, CreateITor = IFace | 0x07, - HoverWidget = Focus | 0x01, - FocusedWidget = Focus | 0x02, - ActiveWidget = Focus | 0x03, + HoverWidget = IFace | Focus | Widget | 0x01, + FocusedWidget = IFace | Focus | Widget | 0x02, + ActiveWidget = IFace | Focus | Widget | 0x03, + UnfocusedWidget = IFace | Focus | Widget | 0x04, //10 nth bit set for graphic obj TemplatedGroup = 0x1000, @@ -51,8 +52,8 @@ namespace Crow GOAddChild = Widget | 0x08, GOSearchLargestChild = Widget | 0x09, - GOSearchTallestChild = Widget | 0x10, - GORegisterForRedraw = Widget | 0x11, + GOSearchTallestChild = Widget | 0x0A, + GORegisterForRedraw = Widget | 0x0B, AlreadyDisposed = Dispose | Widget | Error | 0x01, DisposedByGC = Dispose | Widget | Error | 0x02, diff --git a/Crow/src/EventArgs/DragDropEventArgs.cs b/Crow/src/EventArgs/DragDropEventArgs.cs index b79c3669..3a505527 100644 --- a/Crow/src/EventArgs/DragDropEventArgs.cs +++ b/Crow/src/EventArgs/DragDropEventArgs.cs @@ -1,29 +1,6 @@ -// -// LayoutingEventArgs.cs +// Copyright (c) 2013-2021 Jean-Philippe Bruyère // -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; namespace Crow @@ -39,7 +16,11 @@ namespace Crow /// public Widget DropTarget; - //public DragDropEventArgs (GraphicObject source, GraphicObject target = null) : base() + /// + /// Create a new instance of DragDropEventArgs. + /// + /// the widget instance source of the event + /// the target widget of the event public DragDropEventArgs (Widget source = null, Widget target = null) : base() { DragSource = source; diff --git a/Crow/src/EventArgs/LayoutingEventArgs.cs b/Crow/src/EventArgs/LayoutingEventArgs.cs index 9254aec4..a71548de 100644 --- a/Crow/src/EventArgs/LayoutingEventArgs.cs +++ b/Crow/src/EventArgs/LayoutingEventArgs.cs @@ -1,37 +1,23 @@ -// -// LayoutingEventArgs.cs +// Copyright (c) 2013-2021 Jean-Philippe Bruyère // -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; namespace Crow { + /// + /// Event argument for layouting events. + /// public class LayoutingEventArgs: EventArgs { + /// + /// The layout type that has changed. + /// public LayoutingType LayoutType; - + /// + /// Create a new instance of LayoutingEventArgs. + /// + /// The layout type that trigger the event. public LayoutingEventArgs (LayoutingType _layoutType) : base() { LayoutType = _layoutType; diff --git a/Crow/src/EventArgs/ListChangedEventArg.cs b/Crow/src/EventArgs/ListChangedEventArg.cs index 3fc509e4..3651e3ba 100644 --- a/Crow/src/EventArgs/ListChangedEventArg.cs +++ b/Crow/src/EventArgs/ListChangedEventArg.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Jean-Philippe Bruyère +// Copyright (c) 2013-2021 Jean-Philippe Bruyère // // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; diff --git a/Crow/src/EventArgs/MouseCursorChangedEventArgs.cs b/Crow/src/EventArgs/MouseCursorChangedEventArgs.cs index 5e58b861..10c366ac 100644 --- a/Crow/src/EventArgs/MouseCursorChangedEventArgs.cs +++ b/Crow/src/EventArgs/MouseCursorChangedEventArgs.cs @@ -1,33 +1,13 @@ -// -// MouseCursorChangedEventArgs.cs +// Copyright (c) 2013-2021 Jean-Philippe Bruyère // -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; namespace Crow { + /// + /// Occurs when the mouse cursor changes. + /// public class MouseCursorChangedEventArgs : EventArgs { public MouseCursor NewCursor; diff --git a/Crow/src/EventArgs/ScrollingEventArgs.cs b/Crow/src/EventArgs/ScrollingEventArgs.cs index 3ff42065..76b38ce8 100644 --- a/Crow/src/EventArgs/ScrollingEventArgs.cs +++ b/Crow/src/EventArgs/ScrollingEventArgs.cs @@ -1,29 +1,6 @@ -// -// ScrollingEventArgs.cs +// Copyright (c) 2013-2021 Jean-Philippe Bruyère // -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using System; namespace Crow diff --git a/Crow/src/EventArgs/TextChangeEventArgs.cs b/Crow/src/EventArgs/TextChangeEventArgs.cs index a51ce29f..4a1cc9a3 100644 --- a/Crow/src/EventArgs/TextChangeEventArgs.cs +++ b/Crow/src/EventArgs/TextChangeEventArgs.cs @@ -1,36 +1,20 @@ -// -// TextChangeEventArgs.cs +// Copyright (c) 2013-2021 Jean-Philippe Bruyère // -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) using Crow.Text; using System; namespace Crow { + /// + /// Occurs in the TextBox widget when the text has changed. + /// public class TextChangeEventArgs: EventArgs { + /// + /// The TextChange structure representing the change. + /// public TextChange Change; public TextChangeEventArgs (TextChange _newValue) : base() diff --git a/Crow/src/EventArgs/ValidateEventArgs.cs b/Crow/src/EventArgs/ValidateEventArgs.cs new file mode 100644 index 00000000..eabaf35a --- /dev/null +++ b/Crow/src/EventArgs/ValidateEventArgs.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2013-2021 Jean-Philippe Bruyère +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) +using System; + +namespace Crow +{ + /// + /// Occurs in the TextBox widget when the text has changed. Contains the + /// validated text. + /// + public class ValidateEventArgs : EventArgs + { + /// + /// The validated text. + /// + public string ValidatedText; + public ValidateEventArgs (string _text) : base () { + ValidatedText = _text; + } + } +} diff --git a/Crow/src/Interface.cs b/Crow/src/Interface.cs index 1c55ad38..b17a8dc5 100644 --- a/Crow/src/Interface.cs +++ b/Crow/src/Interface.cs @@ -62,10 +62,6 @@ namespace Crow #region CTOR static Interface () { - /*if (Type.GetType ("Mono.Runtime") == null) { - throw new Exception (@"C.R.O.W. run only on Mono, download latest version at: http://www.mono-project.com/download/stable/"); - }*/ - CROW_CONFIG_ROOT = System.IO.Path.Combine ( Environment.GetFolderPath (Environment.SpecialFolder.UserProfile), @@ -678,8 +674,7 @@ namespace Crow _focusedWidget.HasFocus = false; _focusedWidget = value; - NotifyValueChanged ("FocusedWidget", _focusedWidget); - DbgLogger.AddEvent (DbgEvtType.FocusedWidget, _focusedWidget); + NotifyValueChanged ("FocusedWidget", _focusedWidget); if (_focusedWidget != null) _focusedWidget.HasFocus = true; } diff --git a/Crow/src/Widgets/Label.cs b/Crow/src/Widgets/Label.cs index fc261cb5..81632de7 100644 --- a/Crow/src/Widgets/Label.cs +++ b/Crow/src/Widgets/Label.cs @@ -444,7 +444,7 @@ namespace Crow { OnTextChanged (this, new TextChangeEventArgs (Text)); } */ - bool textMeasureIsUpToDate = false; + protected bool textMeasureIsUpToDate = false; Size cachedTextSize = default(Size); protected LineCollection lines; protected void getLines () { diff --git a/Crow/src/Widgets/TextBox.cs b/Crow/src/Widgets/TextBox.cs index 3564ee49..61af4127 100644 --- a/Crow/src/Widgets/TextBox.cs +++ b/Crow/src/Widgets/TextBox.cs @@ -9,93 +9,108 @@ using System; namespace Crow { - public class TextBox : Label + public class TextBox : Label { - #region CTOR - protected TextBox() {} - public TextBox(Interface iface, string style = null) : base (iface, style) { } - #endregion + #region CTOR + protected TextBox () { } + public TextBox (Interface iface, string style = null) : base (iface, style) { } + #endregion + + /// + /// Validate content of the text box. Occurs in non multiline TextBox when 'Enter' key + /// is pressed. + /// + public event EventHandler Validate; + public virtual void OnValidate (Object sender, ValidateEventArgs e) { + Validate.Raise (this, e); + } + - #region Keyboard handling - public override void onKeyDown (object sender, KeyEventArgs e) - { - Key key = e.Key; - TextSpan selection = Selection; - switch (key) - { - case Key.Backspace: - if (selection.Length == 0) { - if (selection.Start == 0) - return; - update (new TextChange (selection.Start - 1, 1, "")); - } else - update (new TextChange (selection.Start, selection.Length, "")); - break; - case Key.Delete: - if (selection.Length == 0) { - if (selection.Start == Text.Length) - return; - update (new TextChange (selection.Start, 1, "")); - } else { - if (IFace.Shift) - IFace.Clipboard = Text.AsSpan(selection.Start, selection.End).ToString(); - update (new TextChange (selection.Start, selection.Length, "")); - } - break; - case Key.Insert: - if (IFace.Shift) - update (new TextChange (selection.Start, selection.Length, IFace.Clipboard)); - else if (IFace.Ctrl && !selection.IsEmpty) - IFace.Clipboard = Text.AsSpan (selection.Start, selection.End).ToString (); - break; - case Key.KeypadEnter: - case Key.Enter: - if (Multiline) - update (new TextChange (selection.Start, selection.Length, "\n")); - else - OnTextChanged(this,new TextChangeEventArgs(default)); - break; - case Key.Escape: - selectionStart = null; - currentLoc = lines.GetLocation (selection.Start); - RegisterForRedraw (); - break; - case Key.Tab: - update (new TextChange (selection.Start, selection.Length, "\t")); - break; - default: - base.onKeyDown (sender, e); - break; - } - e.Handled = true; - } - public override void onKeyPress (object sender, KeyPressEventArgs e) - { - base.onKeyPress (sender, e); + public override void onKeyDown (object sender, KeyEventArgs e) { + Key key = e.Key; + TextSpan selection = Selection; + switch (key) { + case Key.Backspace: + if (selection.Length == 0) { + if (selection.Start == 0) + return; + update (new TextChange (selection.Start - 1, 1, "")); + } else + update (new TextChange (selection.Start, selection.Length, "")); + break; + case Key.Delete: + if (selection.Length == 0) { + if (selection.Start == Text.Length) + return; + update (new TextChange (selection.Start, 1, "")); + } else { + if (IFace.Shift) + IFace.Clipboard = Text.AsSpan (selection.Start, selection.End).ToString (); + update (new TextChange (selection.Start, selection.Length, "")); + } + break; + case Key.Insert: + if (IFace.Shift) + update (new TextChange (selection.Start, selection.Length, IFace.Clipboard)); + else if (IFace.Ctrl && !selection.IsEmpty) + IFace.Clipboard = Text.AsSpan (selection.Start, selection.End).ToString (); + break; + case Key.KeypadEnter: + case Key.Enter: + if (Multiline) + update (new TextChange (selection.Start, selection.Length, "\n")); + else + OnValidate (this, new ValidateEventArgs(_text)); + break; + case Key.Escape: + selectionStart = null; + currentLoc = lines.GetLocation (selection.Start); + RegisterForRedraw (); + break; + case Key.Tab: + update (new TextChange (selection.Start, selection.Length, "\t")); + break; + default: + base.onKeyDown (sender, e); + break; + } + e.Handled = true; + } + public override void onKeyPress (object sender, KeyPressEventArgs e) { + base.onKeyPress (sender, e); - TextSpan selection = Selection; - update (new TextChange (selection.Start, selection.Length, e.KeyChar.ToString ())); - - /*Insert (e.KeyChar.ToString()); + TextSpan selection = Selection; + update (new TextChange (selection.Start, selection.Length, e.KeyChar.ToString ())); + + /*Insert (e.KeyChar.ToString()); SelRelease = -1; SelBegin = new Point(CurrentColumn, SelBegin.Y); RegisterForGraphicUpdate();*/ - } + } #endregion - void update(TextChange change) { - Span tmp = stackalloc char[Text.Length + (change.ChangedText.Length - change.Length)]; - ReadOnlySpan src = Text.AsSpan (); - src.Slice (0, change.Start).CopyTo (tmp); - change.ChangedText.AsSpan ().CopyTo (tmp.Slice (change.Start)); - src.Slice (change.End).CopyTo (tmp.Slice (change.Start + change.ChangedText.Length)); - Text = tmp.ToString (); - - selectionStart = null; - currentLoc = lines.GetLocation (change.Start + change.ChangedText.Length); - } - } + void update (TextChange change) { + Span tmp = stackalloc char[Text.Length + (change.ChangedText.Length - change.Length)]; + ReadOnlySpan src = Text.AsSpan (); + src.Slice (0, change.Start).CopyTo (tmp); + change.ChangedText.AsSpan ().CopyTo (tmp.Slice (change.Start)); + src.Slice (change.End).CopyTo (tmp.Slice (change.Start + change.ChangedText.Length)); + + _text = tmp.ToString (); + + getLines (); + + textMeasureIsUpToDate = false; + NotifyValueChanged ("Text", Text); + OnTextChanged (this, new TextChangeEventArgs (change)); + + selectionStart = null; + currentLoc = lines.GetLocation (change.Start + change.ChangedText.Length); + + RegisterForGraphicUpdate (); + } + } } diff --git a/Crow/src/Widgets/Widget.cs b/Crow/src/Widgets/Widget.cs index 8a844ed0..92711e27 100644 --- a/Crow/src/Widgets/Widget.cs +++ b/Crow/src/Widgets/Widget.cs @@ -2044,15 +2044,11 @@ namespace Crow #endregion protected virtual void onFocused(object sender, EventArgs e){ - #if DEBUG_FOCUS - Debug.WriteLine("Focused => " + this.ToString()); - #endif + DbgLogger.AddEvent (DbgEvtType.FocusedWidget, this); Focused.Raise (this, e); } protected virtual void onUnfocused(object sender, EventArgs e){ - #if DEBUG_FOCUS - Debug.WriteLine("UnFocused => " + this.ToString()); - #endif + DbgLogger.AddEvent (DbgEvtType.UnfocusedWidget, this); Unfocused.Raise (this, e); } diff --git a/Directory.Build.props b/Directory.Build.props index a05750a6..c9936924 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -7,7 +7,7 @@ Jean-Philippe Bruyère 7.2 - 0.9.2 + 0.9.3 $(CrowVersion)-beta true -- 2.47.3