diff --git a/Terminal.Gui/Drawing/Color.cs b/Terminal.Gui/Drawing/Color.cs index 82e4e361e..001e8588b 100644 --- a/Terminal.Gui/Drawing/Color.cs +++ b/Terminal.Gui/Drawing/Color.cs @@ -6,6 +6,7 @@ using System.Numerics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Text.Json.Serialization; +using ColorHelper; namespace Terminal.Gui; @@ -237,6 +238,27 @@ public readonly partial record struct Color : ISpanParsable, IUtf8SpanPar [SkipLocalsInit] private static float CalculateColorDistance (in Vector4 color1, in Vector4 color2) { return Vector4.Distance (color1, color2); } + /// + /// Gets a color that is the same hue as the current color, but with a different lightness. + /// + /// + public Color GetHighlightColor () + { + // TODO: This is a temporary implementation; just enough to show how it could work. + var hsl = ColorHelper.ColorConverter.RgbToHsl(new RGB (R, G, B)); + + var amount = .7; + if (hsl.L < 50) + { + amount += 1; + } + hsl.L = (byte)(hsl.L * amount); + + var rgb = ColorHelper.ColorConverter.HslToRgb (hsl); + return new (rgb.R, rgb.G, rgb.B); + + } + #region Legacy Color Names /// The black color. diff --git a/Terminal.Gui/Terminal.Gui.csproj b/Terminal.Gui/Terminal.Gui.csproj index 2180f0334..c2f39edb8 100644 --- a/Terminal.Gui/Terminal.Gui.csproj +++ b/Terminal.Gui/Terminal.Gui.csproj @@ -44,6 +44,7 @@ + diff --git a/Terminal.Gui/View/Adornment/Border.cs b/Terminal.Gui/View/Adornment/Border.cs index a67de3edd..6eefd5626 100644 --- a/Terminal.Gui/View/Adornment/Border.cs +++ b/Terminal.Gui/View/Adornment/Border.cs @@ -73,11 +73,13 @@ public class Border : Adornment /// public override void BeginInit () { +#if HOVER // TOOD: Hack - make Arragnement overidable if ((Parent?.Arrangement & ViewArrangement.Movable) != 0) { HighlightStyle |= HighlightStyle.Hover; - } + } +#endif base.BeginInit (); @@ -208,6 +210,7 @@ public class Border : Adornment } LineStyle = LineStyle.Heavy; } +#if HOVER else if (e.HighlightStyle.HasFlag (HighlightStyle.Hover)) { if (!_savedHighlightLineStyle.HasValue) @@ -216,6 +219,7 @@ public class Border : Adornment } LineStyle = LineStyle.Double; } +#endif if (e.HighlightStyle == HighlightStyle.None && _savedHighlightLineStyle.HasValue) { @@ -339,7 +343,7 @@ public class Border : Adornment } } - #endregion Mouse Support +#endregion Mouse Support /// public override void OnDrawContent (Rectangle contentArea) diff --git a/Terminal.Gui/View/ViewMouse.cs b/Terminal.Gui/View/ViewMouse.cs index ec0f99942..567cff39b 100644 --- a/Terminal.Gui/View/ViewMouse.cs +++ b/Terminal.Gui/View/ViewMouse.cs @@ -13,10 +13,12 @@ public enum HighlightStyle /// None = 0, +#if HOVER /// /// The mouse is hovering over the view. /// Hover = 1, +#endif /// /// The mouse is pressed within the . @@ -95,11 +97,15 @@ public partial class View return true; } +#if HOVER if (HighlightStyle.HasFlag(HighlightStyle.Hover)) { - SetHighlight (HighlightStyle.Hover); + if (SetHighlight (HighlightStyle.Hover)) + { + return true; + } } - +#endif return false; } @@ -160,15 +166,16 @@ public partial class View return false; } - if (OnMouseEnter (mouseEvent) == true) + if (OnMouseLeave (mouseEvent) == true) { return true; } - +#if HOVER if (HighlightStyle.HasFlag (HighlightStyle.Hover)) { SetHighlight (HighlightStyle.None); } +#endif return false; } @@ -322,11 +329,18 @@ public partial class View if (Bounds.Contains (mouseEvent.X, mouseEvent.Y)) { - SetHighlight (HighlightStyle.HasFlag(HighlightStyle.Pressed) ? HighlightStyle.Pressed : HighlightStyle.None); + if (SetHighlight (HighlightStyle.HasFlag (HighlightStyle.Pressed) ? HighlightStyle.Pressed : HighlightStyle.None) == true) + { + return true; + } } else { - SetHighlight (HighlightStyle.HasFlag (HighlightStyle.PressedOutside) ? HighlightStyle.PressedOutside : HighlightStyle.None); + if (SetHighlight (HighlightStyle.HasFlag (HighlightStyle.PressedOutside) ? HighlightStyle.PressedOutside : HighlightStyle.None) == true) + + { + return true; + } } if (WantContinuousButtonPressed && Application.MouseGrabView == this) @@ -387,7 +401,11 @@ public partial class View { // We're grabbed. Clicked event comes after the last Release. This is our signal to ungrab Application.UngrabMouse (); - SetHighlight (HighlightStyle.None); + + if (SetHighlight (HighlightStyle.None)) + { + return true; + } // If mouse is still in bounds, click if (!WantContinuousButtonPressed && Bounds.Contains (mouseEvent.X, mouseEvent.Y)) @@ -418,16 +436,18 @@ public partial class View /// Marked internal just to support unit tests /// /// - internal void SetHighlight (HighlightStyle style) + /// , if the Highlight event was handled, otherwise. + + internal bool SetHighlight (HighlightStyle style) { // TODO: Make the highlight colors configurable // Enable override via virtual method and/or event if (OnHighlight (style) == true) { - return; + return true; } - +#if HOVER if (style.HasFlag (HighlightStyle.Hover)) { if (_savedHighlightColorScheme is null && ColorScheme is { }) @@ -436,15 +456,17 @@ public partial class View var cs = new ColorScheme (ColorScheme) { - Normal = new (ColorName.BrightRed, ColorName.Black), + Normal = GetFocusColor (), + HotNormal = ColorScheme.HotFocus }; ColorScheme = cs; } - } + return true; + } +#endif if (style.HasFlag (HighlightStyle.Pressed) || style.HasFlag (HighlightStyle.PressedOutside)) { - if (_savedHighlightColorScheme is null && ColorScheme is { }) { _savedHighlightColorScheme ??= ColorScheme; @@ -453,7 +475,7 @@ public partial class View { var cs = new ColorScheme (ColorScheme) { - Focus = new (ColorScheme.Normal.Foreground, ColorScheme.Focus.Background), + Focus = new (ColorScheme.Focus.Foreground.GetHighlightColor (), ColorScheme.Focus.Background.GetHighlightColor ()), }; ColorScheme = cs; } @@ -466,9 +488,12 @@ public partial class View }; ColorScheme = cs; } + + return true; } } + if (style == HighlightStyle.None) { // Unhighlight @@ -478,6 +503,8 @@ public partial class View _savedHighlightColorScheme = null; } } + + return false; } /// diff --git a/Terminal.Gui/Views/Button.cs b/Terminal.Gui/Views/Button.cs index f77063934..a710bc2d9 100644 --- a/Terminal.Gui/Views/Button.cs +++ b/Terminal.Gui/Views/Button.cs @@ -54,8 +54,9 @@ public class Button : View CanFocus = true; AutoSize = true; HighlightStyle |= HighlightStyle.Pressed; +#if HOVER HighlightStyle |= HighlightStyle.Hover; - +#endif // Override default behavior of View AddCommand (Command.HotKey, () => { diff --git a/UICatalog/Scenarios/TrueColors.cs b/UICatalog/Scenarios/TrueColors.cs index 7e8962617..a392f2347 100644 --- a/UICatalog/Scenarios/TrueColors.cs +++ b/UICatalog/Scenarios/TrueColors.cs @@ -67,6 +67,14 @@ public class TrueColors : Scenario new Label { X = Pos.AnchorEnd (44), Y = 6, Text = "Blue:" } ); + Win.Add ( + new Label { X = Pos.AnchorEnd (44), Y = 8, Text = "Darker:" } + ); + + Win.Add ( + new Label { X = Pos.AnchorEnd (44), Y = 9, Text = "Lighter:" } + ); + var lblRed = new Label { X = Pos.AnchorEnd (32), Y = 4, Text = "na" }; Win.Add (lblRed); var lblGreen = new Label { X = Pos.AnchorEnd (32), Y = 5, Text = "na" }; @@ -74,9 +82,31 @@ public class TrueColors : Scenario var lblBlue = new Label { X = Pos.AnchorEnd (32), Y = 6, Text = "na" }; Win.Add (lblBlue); + var lblDarker = new Label { X = Pos.AnchorEnd (32), Y = 8, Text = " " }; + Win.Add (lblDarker); + + var lblLighter = new Label { X = Pos.AnchorEnd (32), Y = 9, Text = " " }; + Win.Add (lblLighter); + Application.MouseEvent += (s, e) => { - if (e.View != null) + if (e.View == null) + { + return; + } + if (e.Flags == MouseFlags.Button1Clicked) + { + Attribute normal = e.View.GetNormalColor (); + + lblLighter.ColorScheme = new ColorScheme(e.View.ColorScheme) + { + Normal = new Attribute ( + normal.Foreground, + normal.Background.GetHighlightColor () + ) + }; + } + else { Attribute normal = e.View.GetNormalColor (); lblRed.Text = normal.Foreground.R.ToString ();