using System; using System.Text; namespace Terminal.Gui { /// /// Event arguments for the events. /// public class ColorEventArgs : EventArgs { /// /// Initializes a new instance of /// public ColorEventArgs () { } /// /// The new Thickness. /// public Color Color { get; set; } /// /// The previous Thickness. /// public Color PreviousColor { get; set; } } /// /// The Color picker. /// public class ColorPicker : View { private int _selectColorIndex = (int)Color.Black; /// /// Columns of color boxes /// private int _cols = 8; /// /// Rows of color boxes /// private int _rows = 2; /// /// Width of a color box /// public int BoxWidth { get => _boxWidth; set { if (_boxWidth != value) { _boxWidth = value; SetNeedsLayout (); } } } private int _boxWidth = 4; /// /// Height of a color box /// public int BoxHeight { get => _boxHeight; set { if (_boxHeight != value) { _boxHeight = value; SetNeedsLayout (); } } } int _boxHeight = 2; /// /// Cursor for the selected color. /// public Point Cursor { get { return new Point (_selectColorIndex % _cols, _selectColorIndex / _cols); } set { var colorIndex = value.Y * _cols + value.X; SelectedColor = (Color)colorIndex; } } /// /// Fired when a color is picked. /// public event EventHandler ColorChanged; /// /// Selected color. /// public Color SelectedColor { get { return (Color)_selectColorIndex; } set { Color prev = (Color)_selectColorIndex; _selectColorIndex = (int)value; ColorChanged?.Invoke (this, new ColorEventArgs () { PreviousColor = prev, Color = value, }); SetNeedsDisplay (); } } /// /// Initializes a new instance of . /// public ColorPicker () { SetInitialProperties (); } private void SetInitialProperties () { CanFocus = true; AddCommands (); AddKeyBindings (); LayoutStarted += (o, a) => { Bounds = new Rect (Bounds.Location, new Size (_cols * BoxWidth, _rows * BoxHeight)); }; } /// /// Add the commands. /// private void AddCommands () { AddCommand (Command.Left, () => MoveLeft ()); AddCommand (Command.Right, () => MoveRight ()); AddCommand (Command.LineUp, () => MoveUp ()); AddCommand (Command.LineDown, () => MoveDown ()); } /// /// Add the KeyBindinds. /// private void AddKeyBindings () { AddKeyBinding (Key.CursorLeft, Command.Left); AddKeyBinding (Key.CursorRight, Command.Right); AddKeyBinding (Key.CursorUp, Command.LineUp); AddKeyBinding (Key.CursorDown, Command.LineDown); } /// public override void OnDrawContent (Rect contentArea) { base.OnDrawContent (contentArea); Driver.SetAttribute (HasFocus ? ColorScheme.Focus : GetNormalColor ()); var colorIndex = 0; for (var y = 0; y < (Bounds.Height / BoxHeight); y++) { for (var x = 0; x < (Bounds.Width / BoxWidth); x++) { var foregroundColorIndex = y == 0 ? colorIndex + _cols : colorIndex - _cols; Driver.SetAttribute (Driver.MakeAttribute ((Color)foregroundColorIndex, (Color)colorIndex)); var selected = x == Cursor.X && y == Cursor.Y; DrawColorBox (x, y, selected); colorIndex++; } } } /// /// Draw a box for one color. /// /// X location. /// Y location /// private void DrawColorBox (int x, int y, bool selected) { var index = 0; for (var zoomedY = 0; zoomedY < BoxHeight; zoomedY++) { for (var zoomedX = 0; zoomedX < BoxWidth; zoomedX++) { Move (x * BoxWidth + zoomedX, y * BoxHeight + zoomedY); Driver.AddRune ((Rune)' '); index++; } } if (selected) { DrawFocusRect (new Rect (x * BoxWidth, y * BoxHeight, BoxWidth, BoxHeight)); } } private void DrawFocusRect (Rect rect) { var lc = new LineCanvas (); if (rect.Width == 1) { lc.AddLine (rect.Location, rect.Height, Orientation.Vertical, LineStyle.Dotted); } else if (rect.Height == 1) { lc.AddLine (rect.Location, rect.Width, Orientation.Horizontal, LineStyle.Dotted); } else { lc.AddLine (rect.Location, rect.Width, Orientation.Horizontal, LineStyle.Dotted); lc.AddLine (new Point (rect.Location.X, rect.Location.Y + rect.Height - 1), rect.Width, Orientation.Horizontal, LineStyle.Dotted); lc.AddLine (rect.Location, rect.Height, Orientation.Vertical, LineStyle.Dotted); lc.AddLine (new Point (rect.Location.X + rect.Width - 1, rect.Location.Y), rect.Height, Orientation.Vertical, LineStyle.Dotted); } foreach (var p in lc.GetMap ()) { AddRune (p.Key.X, p.Key.Y, p.Value); } } /// /// Moves the selected item index to the previous column. /// /// public virtual bool MoveLeft () { if (Cursor.X > 0) SelectedColor--; return true; } /// /// Moves the selected item index to the next column. /// /// public virtual bool MoveRight () { if (Cursor.X < _cols - 1) SelectedColor++; return true; } /// /// Moves the selected item index to the previous row. /// /// public virtual bool MoveUp () { if (Cursor.Y > 0) SelectedColor -= _cols; return true; } /// /// Moves the selected item index to the next row. /// /// public virtual bool MoveDown () { if (Cursor.Y < _rows - 1) SelectedColor += _cols; return true; } /// public override bool ProcessKey (KeyEvent kb) { var result = InvokeKeybindings (kb); if (result != null) return (bool)result; return false; } /// public override bool MouseEvent (MouseEvent me) { if (!me.Flags.HasFlag (MouseFlags.Button1Clicked) || !CanFocus) { return false; } SetFocus (); Cursor = new Point ((me.X - GetFramesThickness ().Left) / _boxWidth, (me.Y - GetFramesThickness ().Top) / _boxHeight); return true; } /// public override bool OnEnter (View view) { Application.Driver.SetCursorVisibility (CursorVisibility.Invisible); return base.OnEnter (view); } } }