mirror of
https://github.com/gui-cs/Terminal.Gui.git
synced 2026-01-01 00:46:39 +01:00
* Readonly HSL view * Make it possible to move between bars by moving to subview * Basically working and with mouse support * Fix HSL to work properly with double values instead of color matching * Fix Value on ColorPicker to match HSL values * Fix color spectrum * Add Swatch and better sync with text box * Work on jitter * ColorPicker HSL working * More keybindings * Add ColorModel * Support both HSL and HSV * Add RGB * Better mouse handling * WIP: AttributeView and integrate into LineDrawing (does not currently work properly) * Fix color picking * Add concept of an ITool * Add ColorPickerStyle * Fix selected cell rendering * Add first test for ColorPicker2 * Add more RGB tests * Improve ColorPicker2 setup process * Tests and fixes for keyboard changing value R * Fix margin on bars when no textfields * Add mouse test * Add tests for with text field * Add more tests and fix bug sync component text field change with hex text field (WIP - failing tests) * Fix tests and fix clicking in a bar label area possibly not selecting * Move AttributeView to LineDrawing and adjust to have a 'transparent pattern' too * Render triangle in dark gray if background is black * Add ColorChanged event * Resharper Cleanup * Xml comments and public/private adjustments * Explore replacing diagram test with fragile Subview diving * Migrate ColorPicker_DefaultBoot to sub asserts * Port other tests * Replace ColorPicker with new view * Fix ColorPicker size to match scenarios size assumptions * Split to separate files and ignore invalid test for ColorPicker * Ignore also in mouse version of AllViews_Enter_Leave_Events * Remove bool _updating from ColorPicker Now instead we are more selective about what we update when and do so deterministically * Typo fix * Fix ReSharper bad renames in comments for "Value" * Refactor to single implementation of 'prompt for color' logic - Now called PromptForColor - Shared by LineDrawing and ProgressBarStyles scenarios * Sum runes instead of Length * Hide ColorBar and SetValueWithoutRaisingEvent from public API * Move ColorEventArgs to Drawing folder * Move ColorModel to Drawing folder * First try at Dim.Auto for ColorPicker * Remove explicit width/height setting in most scenarios * Remove explicit heights * Fixed build/test issues. Illustrated test best practice. * WIP: Start working on test changes and add new options to ColorPickers scenario (Color Model and show textfields). * Fix for R indicator arrow sometimes 'falling off' the drawn area. * Add nullable enable * Test fixes and refactor for avoiding Begin * Make ColorEventArgs inherit from EventArgs<Color> * Fix Dispose not being called on bars when switching color models * Remove 'oldColor' from test now it is not supported * Add initial stab at ColorPickerStyle.ShowName * Use AppendAutocomplete for color names * Implemented resoruce based colorname resolver * Update GetTextField to support getting the color names field Change style setting to ShowColorName * Color name updates when navigating away from the named color * Restore old color picker as ColorPicker16 * Add test that shows 'Save as' is currently considered a named color >< * Fix GetW3CColorNames * Removed dupe colors * Revert to old color pickers * Nullability question marks for everyone! --------- Co-authored-by: Tig <tig@users.noreply.github.com>
This commit is contained in:
79
UnitTests/Views/ColorPicker16Tests.cs
Normal file
79
UnitTests/Views/ColorPicker16Tests.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
namespace Terminal.Gui.ViewsTests;
|
||||
|
||||
public class ColorPicker16Tests
|
||||
{
|
||||
[Fact]
|
||||
public void Constructors ()
|
||||
{
|
||||
var colorPicker = new ColorPicker16 ();
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
Assert.Equal (Point.Empty, colorPicker.Cursor);
|
||||
Assert.True (colorPicker.CanFocus);
|
||||
|
||||
colorPicker.BeginInit ();
|
||||
colorPicker.EndInit ();
|
||||
colorPicker.LayoutSubviews ();
|
||||
Assert.Equal (new (0, 0, 32, 4), colorPicker.Frame);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyBindings_Command ()
|
||||
{
|
||||
var colorPicker = new ColorPicker16 ();
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorRight));
|
||||
Assert.Equal (ColorName.Blue, colorPicker.SelectedColor);
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorDown));
|
||||
Assert.Equal (ColorName.BrightBlue, colorPicker.SelectedColor);
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorLeft));
|
||||
Assert.Equal (ColorName.DarkGray, colorPicker.SelectedColor);
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorUp));
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorLeft));
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorUp));
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void MouseEvents ()
|
||||
{
|
||||
var colorPicker = new ColorPicker16 { X = 0, Y = 0, Height = 4, Width = 32 };
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
var top = new Toplevel ();
|
||||
top.Add (colorPicker);
|
||||
Application.Begin (top);
|
||||
|
||||
Assert.False (colorPicker.NewMouseEvent (new ()));
|
||||
|
||||
Assert.True (colorPicker.NewMouseEvent (new () { Position = new (4, 1), Flags = MouseFlags.Button1Clicked }));
|
||||
Assert.Equal (ColorName.Blue, colorPicker.SelectedColor);
|
||||
top.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SelectedColorAndCursor ()
|
||||
{
|
||||
var colorPicker = new ColorPicker16 ();
|
||||
colorPicker.SelectedColor = ColorName.White;
|
||||
Assert.Equal (7, colorPicker.Cursor.X);
|
||||
Assert.Equal (1, colorPicker.Cursor.Y);
|
||||
|
||||
colorPicker.SelectedColor = Color.Black;
|
||||
Assert.Equal (0, colorPicker.Cursor.X);
|
||||
Assert.Equal (0, colorPicker.Cursor.Y);
|
||||
|
||||
colorPicker.Cursor = new (7, 1);
|
||||
Assert.Equal (ColorName.White, colorPicker.SelectedColor);
|
||||
|
||||
colorPicker.Cursor = Point.Empty;
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
}
|
||||
}
|
||||
@@ -1,79 +1,766 @@
|
||||
namespace Terminal.Gui.ViewsTests;
|
||||
using Xunit.Abstractions;
|
||||
using Color = Terminal.Gui.Color;
|
||||
|
||||
namespace Terminal.Gui.ViewsTests;
|
||||
|
||||
public class ColorPickerTests
|
||||
{
|
||||
[Fact]
|
||||
public void Constructors ()
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_Construct_DefaultValue ()
|
||||
{
|
||||
var colorPicker = new ColorPicker ();
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
Assert.Equal (Point.Empty, colorPicker.Cursor);
|
||||
Assert.True (colorPicker.CanFocus);
|
||||
var cp = GetColorPicker (ColorModel.HSV, false);
|
||||
|
||||
colorPicker.BeginInit ();
|
||||
colorPicker.EndInit ();
|
||||
colorPicker.LayoutSubviews ();
|
||||
Assert.Equal (new (0, 0, 32, 4), colorPicker.Frame);
|
||||
// Should be only a single text field (Hex) because ShowTextFields is false
|
||||
Assert.Single (cp.Subviews.OfType<TextField> ());
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
// All bars should be at 0 with the triangle at 0 (+2 because of "H:", "S:" etc)
|
||||
var h = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
Assert.Equal ("H:", h.Text);
|
||||
Assert.Equal (2, h.TrianglePosition);
|
||||
Assert.IsType<HueBar> (h);
|
||||
|
||||
var s = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
Assert.Equal ("S:", s.Text);
|
||||
Assert.Equal (2, s.TrianglePosition);
|
||||
Assert.IsType<SaturationBar> (s);
|
||||
|
||||
var v = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
Assert.Equal ("V:", v.Text);
|
||||
Assert.Equal (2, v.TrianglePosition);
|
||||
Assert.IsType<ValueBar> (v);
|
||||
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
Assert.Equal ("#000000", hex.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void KeyBindings_Command ()
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_RGB_KeyboardNavigation ()
|
||||
{
|
||||
var colorPicker = new ColorPicker ();
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
var cp = GetColorPicker (ColorModel.RGB, false);
|
||||
cp.Draw ();
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorRight));
|
||||
Assert.Equal (ColorName.Blue, colorPicker.SelectedColor);
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorDown));
|
||||
Assert.Equal (ColorName.BrightBlue, colorPicker.SelectedColor);
|
||||
Assert.Equal ("R:", r.Text);
|
||||
Assert.Equal (2, r.TrianglePosition);
|
||||
Assert.IsType<RBar> (r);
|
||||
Assert.Equal ("G:", g.Text);
|
||||
Assert.Equal (2, g.TrianglePosition);
|
||||
Assert.IsType<GBar> (g);
|
||||
Assert.Equal ("B:", b.Text);
|
||||
Assert.Equal (2, b.TrianglePosition);
|
||||
Assert.IsType<BBar> (b);
|
||||
Assert.Equal ("#000000", hex.Text);
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorLeft));
|
||||
Assert.Equal (ColorName.DarkGray, colorPicker.SelectedColor);
|
||||
Assert.IsAssignableFrom<IColorBar> (cp.Focused);
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorUp));
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
cp.Draw ();
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorLeft));
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
Application.OnKeyDown (Key.CursorRight);
|
||||
|
||||
Assert.True (colorPicker.NewKeyDownEvent (Key.CursorUp));
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
cp.Draw ();
|
||||
|
||||
Assert.Equal (3, r.TrianglePosition);
|
||||
Assert.Equal ("#0F0000", hex.Text);
|
||||
|
||||
Application.OnKeyDown (Key.CursorRight);
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
Assert.Equal (4, r.TrianglePosition);
|
||||
Assert.Equal ("#1E0000", hex.Text);
|
||||
|
||||
// Use cursor to move the triangle all the way to the right
|
||||
for (int i = 0; i < 1000; i++)
|
||||
{
|
||||
Application.OnKeyDown (Key.CursorRight);
|
||||
}
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
// 20 width and TrianglePosition is 0 indexed
|
||||
// Meaning we are asserting that triangle is at end
|
||||
Assert.Equal (19, r.TrianglePosition);
|
||||
Assert.Equal ("#FF0000", hex.Text);
|
||||
|
||||
Application.Current.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[AutoInitShutdown]
|
||||
public void MouseEvents ()
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_RGB_MouseNavigation ()
|
||||
{
|
||||
var colorPicker = new ColorPicker { X = 0, Y = 0, Height = 4, Width = 32 };
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
var top = new Toplevel ();
|
||||
top.Add (colorPicker);
|
||||
Application.Begin (top);
|
||||
var cp = GetColorPicker (ColorModel.RGB,false);
|
||||
|
||||
Assert.False (colorPicker.NewMouseEvent (new ()));
|
||||
cp.Draw ();
|
||||
|
||||
Assert.True (colorPicker.NewMouseEvent (new() { Position = new (4, 1), Flags = MouseFlags.Button1Clicked }));
|
||||
Assert.Equal (ColorName.Blue, colorPicker.SelectedColor);
|
||||
top.Dispose ();
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
Assert.Equal ("R:", r.Text);
|
||||
Assert.Equal (2, r.TrianglePosition);
|
||||
Assert.IsType<RBar> (r);
|
||||
Assert.Equal ("G:", g.Text);
|
||||
Assert.Equal (2, g.TrianglePosition);
|
||||
Assert.IsType<GBar> (g);
|
||||
Assert.Equal ("B:", b.Text);
|
||||
Assert.Equal (2, b.TrianglePosition);
|
||||
Assert.IsType<BBar> (b);
|
||||
Assert.Equal ("#000000", hex.Text);
|
||||
|
||||
Assert.IsAssignableFrom<IColorBar> (cp.Focused);
|
||||
|
||||
cp.Focused.OnMouseEvent (
|
||||
new ()
|
||||
{
|
||||
Flags = MouseFlags.Button1Pressed,
|
||||
Position = new (3, 0)
|
||||
});
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
Assert.Equal (3, r.TrianglePosition);
|
||||
Assert.Equal ("#0F0000", hex.Text);
|
||||
|
||||
cp.Focused.OnMouseEvent (
|
||||
new ()
|
||||
{
|
||||
Flags = MouseFlags.Button1Pressed,
|
||||
Position = new (4, 0)
|
||||
});
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
Assert.Equal (4, r.TrianglePosition);
|
||||
Assert.Equal ("#1E0000", hex.Text);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
|
||||
public static IEnumerable<object []> ColorPickerTestData ()
|
||||
{
|
||||
yield return new object []
|
||||
{
|
||||
new Color(255, 0),
|
||||
"R:", 19, "G:", 2, "B:", 2, "#FF0000"
|
||||
};
|
||||
|
||||
yield return new object []
|
||||
{
|
||||
new Color(0, 255),
|
||||
"R:", 2, "G:", 19, "B:", 2, "#00FF00"
|
||||
};
|
||||
|
||||
yield return new object []
|
||||
{
|
||||
new Color(0, 0, 255),
|
||||
"R:", 2, "G:", 2, "B:", 19, "#0000FF"
|
||||
};
|
||||
|
||||
yield return new object []
|
||||
{
|
||||
new Color(125, 125, 125),
|
||||
"R:", 11, "G:", 11, "B:", 11, "#7D7D7D"
|
||||
};
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[SetupFakeDriver]
|
||||
[MemberData (nameof (ColorPickerTestData))]
|
||||
public void ColorPicker_RGB_NoText (Color c, string expectedR, int expectedRTriangle, string expectedG, int expectedGTriangle, string expectedB, int expectedBTriangle, string expectedHex)
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.RGB, false);
|
||||
cp.SelectedColor = c;
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
Assert.Equal (expectedR, r.Text);
|
||||
Assert.Equal (expectedRTriangle, r.TrianglePosition);
|
||||
Assert.Equal (expectedG, g.Text);
|
||||
Assert.Equal (expectedGTriangle, g.TrianglePosition);
|
||||
Assert.Equal (expectedB, b.Text);
|
||||
Assert.Equal (expectedBTriangle, b.TrianglePosition);
|
||||
Assert.Equal (expectedHex, hex.Text);
|
||||
|
||||
Application.Current.Dispose ();
|
||||
}
|
||||
|
||||
public static IEnumerable<object []> ColorPickerTestData_WithTextFields ()
|
||||
{
|
||||
yield return new object []
|
||||
{
|
||||
new Color(255, 0),
|
||||
"R:", 15, 255, "G:", 2, 0, "B:", 2, 0, "#FF0000"
|
||||
};
|
||||
|
||||
yield return new object []
|
||||
{
|
||||
new Color(0, 255),
|
||||
"R:", 2, 0, "G:", 15, 255, "B:", 2, 0, "#00FF00"
|
||||
};
|
||||
|
||||
yield return new object []
|
||||
{
|
||||
new Color(0, 0, 255),
|
||||
"R:", 2, 0, "G:", 2, 0, "B:", 15, 255, "#0000FF"
|
||||
};
|
||||
|
||||
yield return new object []
|
||||
{
|
||||
new Color(125, 125, 125),
|
||||
"R:", 9, 125, "G:", 9, 125, "B:", 9, 125, "#7D7D7D"
|
||||
};
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[SetupFakeDriver]
|
||||
[MemberData (nameof (ColorPickerTestData_WithTextFields))]
|
||||
public void ColorPicker_RGB_NoText_WithTextFields (Color c, string expectedR, int expectedRTriangle, int expectedRValue, string expectedG, int expectedGTriangle, int expectedGValue, string expectedB, int expectedBTriangle, int expectedBValue, string expectedHex)
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.RGB, true);
|
||||
cp.SelectedColor = c;
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
var rTextField = GetTextField (cp, ColorPickerPart.Bar1);
|
||||
var gTextField = GetTextField (cp, ColorPickerPart.Bar2);
|
||||
var bTextField = GetTextField (cp, ColorPickerPart.Bar3);
|
||||
|
||||
Assert.Equal (expectedR, r.Text);
|
||||
Assert.Equal (expectedRTriangle, r.TrianglePosition);
|
||||
Assert.Equal (expectedRValue.ToString (), rTextField.Text);
|
||||
Assert.Equal (expectedG, g.Text);
|
||||
Assert.Equal (expectedGTriangle, g.TrianglePosition);
|
||||
Assert.Equal (expectedGValue.ToString (), gTextField.Text);
|
||||
Assert.Equal (expectedB, b.Text);
|
||||
Assert.Equal (expectedBTriangle, b.TrianglePosition);
|
||||
Assert.Equal (expectedBValue.ToString (), bTextField.Text);
|
||||
Assert.Equal (expectedHex, hex.Text);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SelectedColorAndCursor ()
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_ClickingAtEndOfBar_SetsMaxValue ()
|
||||
{
|
||||
var colorPicker = new ColorPicker ();
|
||||
colorPicker.SelectedColor = ColorName.White;
|
||||
Assert.Equal (7, colorPicker.Cursor.X);
|
||||
Assert.Equal (1, colorPicker.Cursor.Y);
|
||||
var cp = GetColorPicker (ColorModel.RGB, false);
|
||||
|
||||
colorPicker.SelectedColor = Color.Black;
|
||||
Assert.Equal (0, colorPicker.Cursor.X);
|
||||
Assert.Equal (0, colorPicker.Cursor.Y);
|
||||
cp.Draw ();
|
||||
|
||||
colorPicker.Cursor = new (7, 1);
|
||||
Assert.Equal (ColorName.White, colorPicker.SelectedColor);
|
||||
// Click at the end of the Red bar
|
||||
cp.Focused.OnMouseEvent (
|
||||
new ()
|
||||
{
|
||||
Flags = MouseFlags.Button1Pressed,
|
||||
Position = new (19, 0) // Assuming 0-based indexing
|
||||
});
|
||||
|
||||
colorPicker.Cursor = Point.Empty;
|
||||
Assert.Equal (ColorName.Black, colorPicker.SelectedColor);
|
||||
cp.Draw ();
|
||||
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
Assert.Equal ("R:", r.Text);
|
||||
Assert.Equal (19, r.TrianglePosition);
|
||||
Assert.Equal ("G:", g.Text);
|
||||
Assert.Equal (2, g.TrianglePosition);
|
||||
Assert.Equal ("B:", b.Text);
|
||||
Assert.Equal (2, b.TrianglePosition);
|
||||
Assert.Equal ("#FF0000", hex.Text);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_ClickingBeyondBar_ChangesToMaxValue ()
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.RGB, false);
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
// Click beyond the bar
|
||||
cp.Focused.OnMouseEvent (
|
||||
new ()
|
||||
{
|
||||
Flags = MouseFlags.Button1Pressed,
|
||||
Position = new (21, 0) // Beyond the bar
|
||||
});
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
Assert.Equal ("R:", r.Text);
|
||||
Assert.Equal (19, r.TrianglePosition);
|
||||
Assert.Equal ("G:", g.Text);
|
||||
Assert.Equal (2, g.TrianglePosition);
|
||||
Assert.Equal ("B:", b.Text);
|
||||
Assert.Equal (2, b.TrianglePosition);
|
||||
Assert.Equal ("#FF0000", hex.Text);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_ChangeValueOnUI_UpdatesAllUIElements ()
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.RGB, true);
|
||||
|
||||
View otherView = new View () { CanFocus = true };
|
||||
|
||||
Application.Current?.Add (otherView);
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
// Change value using text field
|
||||
TextField rBarTextField = cp.Subviews.OfType<TextField> ().First (tf => tf.Text == "0");
|
||||
|
||||
rBarTextField.Text = "128";
|
||||
//rBarTextField.OnLeave (cp); // OnLeave should be protected virtual. Don't call it.
|
||||
otherView.SetFocus (); // Remove focus from the color picker
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
var rTextField = GetTextField (cp, ColorPickerPart.Bar1);
|
||||
var gTextField = GetTextField (cp, ColorPickerPart.Bar2);
|
||||
var bTextField = GetTextField (cp, ColorPickerPart.Bar3);
|
||||
|
||||
Assert.Equal ("R:", r.Text);
|
||||
Assert.Equal (9, r.TrianglePosition);
|
||||
Assert.Equal ("128", rTextField.Text);
|
||||
Assert.Equal ("G:", g.Text);
|
||||
Assert.Equal (2, g.TrianglePosition);
|
||||
Assert.Equal ("0", gTextField.Text);
|
||||
Assert.Equal ("B:", b.Text);
|
||||
Assert.Equal (2, b.TrianglePosition);
|
||||
Assert.Equal ("0", bTextField.Text);
|
||||
Assert.Equal ("#800000", hex.Text);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_InvalidHexInput_DoesNotChangeColor ()
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.RGB, true);
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
// Enter invalid hex value
|
||||
TextField hexField = cp.Subviews.OfType<TextField> ().First (tf => tf.Text == "#000000");
|
||||
hexField.Text = "#ZZZZZZ";
|
||||
hexField.OnLeave (cp);
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
Assert.Equal ("R:", r.Text);
|
||||
Assert.Equal (2, r.TrianglePosition);
|
||||
Assert.Equal ("G:", g.Text);
|
||||
Assert.Equal (2, g.TrianglePosition);
|
||||
Assert.Equal ("B:", b.Text);
|
||||
Assert.Equal (2, b.TrianglePosition);
|
||||
Assert.Equal ("#000000", hex.Text);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_ClickingDifferentBars_ChangesFocus ()
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.RGB, false);
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
// Click on Green bar
|
||||
cp.Subviews.OfType<GBar> ()
|
||||
.Single ()
|
||||
.OnMouseEvent (
|
||||
new ()
|
||||
{
|
||||
Flags = MouseFlags.Button1Pressed,
|
||||
Position = new (0, 1)
|
||||
});
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
Assert.IsAssignableFrom<GBar> (cp.Focused);
|
||||
|
||||
// Click on Blue bar
|
||||
cp.Subviews.OfType<BBar> ()
|
||||
.Single ()
|
||||
.OnMouseEvent (
|
||||
new ()
|
||||
{
|
||||
Flags = MouseFlags.Button1Pressed,
|
||||
Position = new (0, 2)
|
||||
});
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
Assert.IsAssignableFrom<BBar> (cp.Focused);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_SwitchingColorModels_ResetsBars ()
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.RGB, false);
|
||||
cp.SelectedColor = new (255, 0);
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
Assert.Equal ("R:", r.Text);
|
||||
Assert.Equal (19, r.TrianglePosition);
|
||||
Assert.Equal ("G:", g.Text);
|
||||
Assert.Equal (2, g.TrianglePosition);
|
||||
Assert.Equal ("B:", b.Text);
|
||||
Assert.Equal (2, b.TrianglePosition);
|
||||
Assert.Equal ("#FF0000", hex.Text);
|
||||
|
||||
// Switch to HSV
|
||||
cp.Style.ColorModel = ColorModel.HSV;
|
||||
cp.ApplyStyleChanges ();
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
var h = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var s = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var v = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
|
||||
Assert.Equal ("H:", h.Text);
|
||||
Assert.Equal (2, h.TrianglePosition);
|
||||
Assert.Equal ("S:", s.Text);
|
||||
Assert.Equal (19, s.TrianglePosition);
|
||||
Assert.Equal ("V:", v.Text);
|
||||
Assert.Equal (19, v.TrianglePosition);
|
||||
Assert.Equal ("#FF0000", hex.Text);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_SyncBetweenTextFieldAndBars ()
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.RGB, true);
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
// Change value using the bar
|
||||
RBar rBar = cp.Subviews.OfType<RBar> ().First ();
|
||||
rBar.Value = 128;
|
||||
|
||||
cp.Draw ();
|
||||
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
var rTextField = GetTextField (cp, ColorPickerPart.Bar1);
|
||||
var gTextField = GetTextField (cp, ColorPickerPart.Bar2);
|
||||
var bTextField = GetTextField (cp, ColorPickerPart.Bar3);
|
||||
|
||||
Assert.Equal ("R:", r.Text);
|
||||
Assert.Equal (9, r.TrianglePosition);
|
||||
Assert.Equal ("128", rTextField.Text);
|
||||
Assert.Equal ("G:", g.Text);
|
||||
Assert.Equal (2, g.TrianglePosition);
|
||||
Assert.Equal ("0", gTextField.Text);
|
||||
Assert.Equal ("B:", b.Text);
|
||||
Assert.Equal (2, b.TrianglePosition);
|
||||
Assert.Equal ("0", bTextField.Text);
|
||||
Assert.Equal ("#800000", hex.Text);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
enum ColorPickerPart
|
||||
{
|
||||
Bar1 = 0,
|
||||
Bar2 = 1,
|
||||
Bar3 = 2,
|
||||
ColorName = 3,
|
||||
Hex = 4,
|
||||
}
|
||||
|
||||
private TextField GetTextField (ColorPicker cp, ColorPickerPart toGet)
|
||||
{
|
||||
var hasBarValueTextFields = cp.Style.ShowTextFields;
|
||||
var hasColorNameTextField = cp.Style.ShowColorName;
|
||||
|
||||
switch (toGet)
|
||||
{
|
||||
case ColorPickerPart.Bar1:
|
||||
case ColorPickerPart.Bar2:
|
||||
case ColorPickerPart.Bar3:
|
||||
if (!hasBarValueTextFields)
|
||||
{
|
||||
throw new NotSupportedException ("Corresponding Style option is not enabled");
|
||||
}
|
||||
|
||||
return cp.Subviews.OfType<TextField> ().ElementAt ((int)toGet);
|
||||
case ColorPickerPart.ColorName:
|
||||
if (!hasColorNameTextField)
|
||||
{
|
||||
throw new NotSupportedException ("Corresponding Style option is not enabled");
|
||||
}
|
||||
|
||||
return cp.Subviews.OfType<TextField> ().ElementAt (hasBarValueTextFields ? (int)toGet : (int)toGet -3);
|
||||
case ColorPickerPart.Hex:
|
||||
|
||||
int offset = hasBarValueTextFields ? 0 : 3;
|
||||
offset += hasColorNameTextField ? 0 : 1;
|
||||
|
||||
return cp.Subviews.OfType<TextField> ().ElementAt ((int)toGet - offset);
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException (nameof (toGet), toGet, null);
|
||||
}
|
||||
}
|
||||
|
||||
private ColorBar GetColorBar (ColorPicker cp, ColorPickerPart toGet)
|
||||
{
|
||||
if (toGet <= ColorPickerPart.Bar3)
|
||||
{
|
||||
return cp.Subviews.OfType<ColorBar> ().ElementAt ((int)toGet);
|
||||
}
|
||||
throw new NotSupportedException ("ColorPickerPart must be a bar");
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_ChangedEvent_Fires ()
|
||||
{
|
||||
Color newColor = default;
|
||||
var count = 0;
|
||||
|
||||
var cp = new ColorPicker ();
|
||||
|
||||
cp.ColorChanged += (s, e) =>
|
||||
{
|
||||
count++;
|
||||
newColor = e.CurrentValue;
|
||||
|
||||
Assert.Equal (cp.SelectedColor, e.CurrentValue);
|
||||
};
|
||||
|
||||
cp.SelectedColor = new (1, 2, 3);
|
||||
Assert.Equal (1, count);
|
||||
Assert.Equal (new (1, 2, 3), newColor);
|
||||
|
||||
cp.SelectedColor = new (2, 3, 4);
|
||||
|
||||
Assert.Equal (2, count);
|
||||
Assert.Equal (new (2, 3, 4), newColor);
|
||||
|
||||
// Set to same value
|
||||
cp.SelectedColor = new (2, 3, 4);
|
||||
|
||||
// Should have no effect
|
||||
Assert.Equal (2, count);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_DisposesOldViews_OnModelChange ()
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.HSL,true);
|
||||
|
||||
var b1 = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var b2 = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b3 = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
|
||||
var tf1 = GetTextField (cp, ColorPickerPart.Bar1);
|
||||
var tf2 = GetTextField (cp, ColorPickerPart.Bar2);
|
||||
var tf3 = GetTextField (cp, ColorPickerPart.Bar3);
|
||||
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
Assert.All (new View [] { b1, b2, b3, tf1, tf2, tf3,hex }, b => Assert.False (b.WasDisposed));
|
||||
|
||||
cp.Style.ColorModel = ColorModel.RGB;
|
||||
cp.ApplyStyleChanges ();
|
||||
|
||||
var b1After = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var b2After = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b3After = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
|
||||
var tf1After = GetTextField (cp, ColorPickerPart.Bar1);
|
||||
var tf2After = GetTextField (cp, ColorPickerPart.Bar2);
|
||||
var tf3After = GetTextField (cp, ColorPickerPart.Bar3);
|
||||
|
||||
var hexAfter = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
// Old bars should be disposed
|
||||
Assert.All (new View [] { b1, b2, b3, tf1, tf2, tf3,hex }, b => Assert.True (b.WasDisposed));
|
||||
Assert.NotSame (hex,hexAfter);
|
||||
|
||||
Assert.NotSame (b1,b1After);
|
||||
Assert.NotSame (b2, b2After);
|
||||
Assert.NotSame (b3, b3After);
|
||||
|
||||
Assert.NotSame (tf1, tf1After);
|
||||
Assert.NotSame (tf2, tf2After);
|
||||
Assert.NotSame (tf3, tf3After);
|
||||
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_TabCompleteColorName()
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.RGB, true,true);
|
||||
cp.Draw ();
|
||||
|
||||
var r = GetColorBar (cp, ColorPickerPart.Bar1);
|
||||
var g = GetColorBar (cp, ColorPickerPart.Bar2);
|
||||
var b = GetColorBar (cp, ColorPickerPart.Bar3);
|
||||
var name = GetTextField (cp, ColorPickerPart.ColorName);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
name.FocusFirst (TabBehavior.TabStop);
|
||||
|
||||
Assert.True (name.HasFocus);
|
||||
Assert.Same (name, cp.Focused);
|
||||
|
||||
name.Text = "";
|
||||
Assert.Empty (name.Text);
|
||||
|
||||
Application.OnKeyDown (Key.A);
|
||||
Application.OnKeyDown (Key.Q);
|
||||
|
||||
Assert.Equal ("aq",name.Text);
|
||||
|
||||
|
||||
// Auto complete the color name
|
||||
Application.OnKeyDown (Key.Tab);
|
||||
|
||||
Assert.Equal ("Aquamarine", name.Text);
|
||||
|
||||
// Tab out of the text field
|
||||
Application.OnKeyDown (Key.Tab);
|
||||
|
||||
Assert.False (name.HasFocus);
|
||||
Assert.NotSame (name, cp.Focused);
|
||||
|
||||
Assert.Equal ("#7FFFD4", hex.Text);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
[SetupFakeDriver]
|
||||
public void ColorPicker_EnterHexFor_ColorName ()
|
||||
{
|
||||
var cp = GetColorPicker (ColorModel.RGB, true, true);
|
||||
cp.Draw ();
|
||||
|
||||
var name = GetTextField (cp, ColorPickerPart.ColorName);
|
||||
var hex = GetTextField (cp, ColorPickerPart.Hex);
|
||||
|
||||
hex.FocusFirst (TabBehavior.TabStop);
|
||||
|
||||
Assert.True (hex.HasFocus);
|
||||
Assert.Same (hex, cp.Focused);
|
||||
|
||||
hex.Text = "";
|
||||
name.Text = "";
|
||||
|
||||
Assert.Empty (hex.Text);
|
||||
Assert.Empty (name.Text);
|
||||
|
||||
Application.OnKeyDown ('#');
|
||||
Assert.Empty (name.Text);
|
||||
//7FFFD4
|
||||
|
||||
Assert.Equal ("#", hex.Text);
|
||||
Application.OnKeyDown ('7');
|
||||
Application.OnKeyDown ('F');
|
||||
Application.OnKeyDown ('F');
|
||||
Application.OnKeyDown ('F');
|
||||
Application.OnKeyDown ('D');
|
||||
Assert.Empty (name.Text);
|
||||
|
||||
Application.OnKeyDown ('4');
|
||||
|
||||
// Tab out of the text field
|
||||
Application.OnKeyDown (Key.Tab);
|
||||
Assert.False (hex.HasFocus);
|
||||
Assert.NotSame (hex, cp.Focused);
|
||||
|
||||
// Color name should be recognised as a known string and populated
|
||||
Assert.Equal ("#7FFFD4", hex.Text);
|
||||
Assert.Equal("Aquamarine", name.Text);
|
||||
|
||||
Application.Current?.Dispose ();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestColorNames ()
|
||||
{
|
||||
var colors = new W3CColors ();
|
||||
Assert.Contains ("Aquamarine", colors.GetColorNames ());
|
||||
Assert.DoesNotContain ("Save as",colors.GetColorNames ());
|
||||
}
|
||||
private ColorPicker GetColorPicker (ColorModel colorModel, bool showTextFields, bool showName = false)
|
||||
{
|
||||
var cp = new ColorPicker { Width = 20, SelectedColor = new (0, 0) };
|
||||
cp.Style.ColorModel = colorModel;
|
||||
cp.Style.ShowTextFields = showTextFields;
|
||||
cp.Style.ShowColorName = showName;
|
||||
cp.ApplyStyleChanges ();
|
||||
|
||||
Application.Current = new Toplevel () { Width = 20 ,Height = 5};
|
||||
Application.Current.Add (cp);
|
||||
Application.Current.FocusFirst (null);
|
||||
|
||||
Application.Current.LayoutSubviews ();
|
||||
|
||||
Application.Current.FocusFirst (null);
|
||||
return cp;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user