using System; using NStack; namespace Terminal.Gui { /// /// The Color picker. /// public class ColorPicker : View { /// /// Number of colors on a line. /// private static readonly int colorsPerLine = 8; /// /// Number of color lines. /// private static readonly int lineCount = 2; /// /// Horizontal zoom. /// private static readonly int horizontalZoom = 4; /// /// Vertical zoom. /// private static readonly int verticalZoom = 2; // Cursor runes. private static readonly Rune [] cursorRunes = new Rune [] { 0x250C, 0x2500, 0x2500, 0x2510, 0x2514, 0x2500, 0x2500, 0x2518 }; /// /// Cursor for the selected color. /// public Point Cursor { get { return new Point (selectColorIndex % colorsPerLine, selectColorIndex / colorsPerLine); } set { var colorIndex = value.Y * colorsPerLine + value.X; SelectedColor = (Color)colorIndex; } } /// /// Fired when a color is picked. /// public event EventHandler ColorChanged; private int selectColorIndex = (int)Color.Black; /// /// Selected color. /// public Color SelectedColor { get { return (Color)selectColorIndex; } set { selectColorIndex = (int)value; ColorChanged?.Invoke (this, EventArgs.Empty); SetNeedsDisplay (); } } /// /// Initializes a new instance of . /// public ColorPicker () : base ("Color Picker") { Initialize (); } /// /// Initializes a new instance of . /// /// Title. public ColorPicker (ustring title) : base (title) { Initialize (); } /// /// Initializes a new instance of . /// /// Location point. /// Title. public ColorPicker (Point point, ustring title) : this (point.X, point.Y, title) { } /// /// Initializes a new instance of . /// /// X location. /// Y location. /// Title public ColorPicker (int x, int y, ustring title) : base (x, y, title) { Initialize (); } private void Initialize() { CanFocus = true; Width = colorsPerLine * horizontalZoom; Height = lineCount * verticalZoom + 1; AddCommands (); AddKeyBindings (); } /// /// 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 Redraw (Rect bounds) { base.Redraw (bounds); Driver.SetAttribute (HasFocus ? ColorScheme.Focus : GetNormalColor ()); var colorIndex = 0; for (var y = 0; y < (Height.Anchor (0) - 1) / verticalZoom; y++) { for (var x = 0; x < Width.Anchor (0) / horizontalZoom; x++) { var foregroundColorIndex = y == 0 ? colorIndex + colorsPerLine : colorIndex - colorsPerLine; 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 zommedY = 0; zommedY < verticalZoom; zommedY++) { for (var zommedX = 0; zommedX < horizontalZoom; zommedX++) { Move (x * horizontalZoom + zommedX, y * verticalZoom + zommedY + 1); if (selected) { var character = cursorRunes [index]; Driver.AddRune (character); } else { Driver.AddRune (' '); } index++; } } } /// /// 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 < colorsPerLine - 1) SelectedColor++; return true; } /// /// Moves the selected item index to the previous row. /// /// public virtual bool MoveUp () { if (Cursor.Y > 0) SelectedColor -= colorsPerLine; return true; } /// /// Moves the selected item index to the next row. /// /// public virtual bool MoveDown () { if (Cursor.Y < lineCount - 1) SelectedColor += colorsPerLine; 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 / horizontalZoom, (me.Y - 1) / verticalZoom); return true; } } }