ColorPickerTests.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766
  1. using Xunit.Abstractions;
  2. using Color = Terminal.Gui.Color;
  3. namespace Terminal.Gui.ViewsTests;
  4. public class ColorPickerTests
  5. {
  6. [Fact]
  7. [SetupFakeDriver]
  8. public void ColorPicker_Construct_DefaultValue ()
  9. {
  10. var cp = GetColorPicker (ColorModel.HSV, false);
  11. // Should be only a single text field (Hex) because ShowTextFields is false
  12. Assert.Single (cp.Subviews.OfType<TextField> ());
  13. cp.Draw ();
  14. // All bars should be at 0 with the triangle at 0 (+2 because of "H:", "S:" etc)
  15. var h = GetColorBar (cp, ColorPickerPart.Bar1);
  16. Assert.Equal ("H:", h.Text);
  17. Assert.Equal (2, h.TrianglePosition);
  18. Assert.IsType<HueBar> (h);
  19. var s = GetColorBar (cp, ColorPickerPart.Bar2);
  20. Assert.Equal ("S:", s.Text);
  21. Assert.Equal (2, s.TrianglePosition);
  22. Assert.IsType<SaturationBar> (s);
  23. var v = GetColorBar (cp, ColorPickerPart.Bar3);
  24. Assert.Equal ("V:", v.Text);
  25. Assert.Equal (2, v.TrianglePosition);
  26. Assert.IsType<ValueBar> (v);
  27. var hex = GetTextField (cp, ColorPickerPart.Hex);
  28. Assert.Equal ("#000000", hex.Text);
  29. }
  30. [Fact]
  31. [SetupFakeDriver]
  32. public void ColorPicker_RGB_KeyboardNavigation ()
  33. {
  34. var cp = GetColorPicker (ColorModel.RGB, false);
  35. cp.Draw ();
  36. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  37. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  38. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  39. var hex = GetTextField (cp, ColorPickerPart.Hex);
  40. Assert.Equal ("R:", r.Text);
  41. Assert.Equal (2, r.TrianglePosition);
  42. Assert.IsType<RBar> (r);
  43. Assert.Equal ("G:", g.Text);
  44. Assert.Equal (2, g.TrianglePosition);
  45. Assert.IsType<GBar> (g);
  46. Assert.Equal ("B:", b.Text);
  47. Assert.Equal (2, b.TrianglePosition);
  48. Assert.IsType<BBar> (b);
  49. Assert.Equal ("#000000", hex.Text);
  50. Assert.IsAssignableFrom<IColorBar> (cp.Focused);
  51. cp.Draw ();
  52. Application.OnKeyDown (Key.CursorRight);
  53. cp.Draw ();
  54. Assert.Equal (3, r.TrianglePosition);
  55. Assert.Equal ("#0F0000", hex.Text);
  56. Application.OnKeyDown (Key.CursorRight);
  57. cp.Draw ();
  58. Assert.Equal (4, r.TrianglePosition);
  59. Assert.Equal ("#1E0000", hex.Text);
  60. // Use cursor to move the triangle all the way to the right
  61. for (int i = 0; i < 1000; i++)
  62. {
  63. Application.OnKeyDown (Key.CursorRight);
  64. }
  65. cp.Draw ();
  66. // 20 width and TrianglePosition is 0 indexed
  67. // Meaning we are asserting that triangle is at end
  68. Assert.Equal (19, r.TrianglePosition);
  69. Assert.Equal ("#FF0000", hex.Text);
  70. Application.Current.Dispose ();
  71. }
  72. [Fact]
  73. [SetupFakeDriver]
  74. public void ColorPicker_RGB_MouseNavigation ()
  75. {
  76. var cp = GetColorPicker (ColorModel.RGB,false);
  77. cp.Draw ();
  78. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  79. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  80. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  81. var hex = GetTextField (cp, ColorPickerPart.Hex);
  82. Assert.Equal ("R:", r.Text);
  83. Assert.Equal (2, r.TrianglePosition);
  84. Assert.IsType<RBar> (r);
  85. Assert.Equal ("G:", g.Text);
  86. Assert.Equal (2, g.TrianglePosition);
  87. Assert.IsType<GBar> (g);
  88. Assert.Equal ("B:", b.Text);
  89. Assert.Equal (2, b.TrianglePosition);
  90. Assert.IsType<BBar> (b);
  91. Assert.Equal ("#000000", hex.Text);
  92. Assert.IsAssignableFrom<IColorBar> (cp.Focused);
  93. cp.Focused.OnMouseEvent (
  94. new ()
  95. {
  96. Flags = MouseFlags.Button1Pressed,
  97. Position = new (3, 0)
  98. });
  99. cp.Draw ();
  100. Assert.Equal (3, r.TrianglePosition);
  101. Assert.Equal ("#0F0000", hex.Text);
  102. cp.Focused.OnMouseEvent (
  103. new ()
  104. {
  105. Flags = MouseFlags.Button1Pressed,
  106. Position = new (4, 0)
  107. });
  108. cp.Draw ();
  109. Assert.Equal (4, r.TrianglePosition);
  110. Assert.Equal ("#1E0000", hex.Text);
  111. Application.Current?.Dispose ();
  112. }
  113. public static IEnumerable<object []> ColorPickerTestData ()
  114. {
  115. yield return new object []
  116. {
  117. new Color(255, 0),
  118. "R:", 19, "G:", 2, "B:", 2, "#FF0000"
  119. };
  120. yield return new object []
  121. {
  122. new Color(0, 255),
  123. "R:", 2, "G:", 19, "B:", 2, "#00FF00"
  124. };
  125. yield return new object []
  126. {
  127. new Color(0, 0, 255),
  128. "R:", 2, "G:", 2, "B:", 19, "#0000FF"
  129. };
  130. yield return new object []
  131. {
  132. new Color(125, 125, 125),
  133. "R:", 11, "G:", 11, "B:", 11, "#7D7D7D"
  134. };
  135. }
  136. [Theory]
  137. [SetupFakeDriver]
  138. [MemberData (nameof (ColorPickerTestData))]
  139. public void ColorPicker_RGB_NoText (Color c, string expectedR, int expectedRTriangle, string expectedG, int expectedGTriangle, string expectedB, int expectedBTriangle, string expectedHex)
  140. {
  141. var cp = GetColorPicker (ColorModel.RGB, false);
  142. cp.SelectedColor = c;
  143. cp.Draw ();
  144. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  145. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  146. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  147. var hex = GetTextField (cp, ColorPickerPart.Hex);
  148. Assert.Equal (expectedR, r.Text);
  149. Assert.Equal (expectedRTriangle, r.TrianglePosition);
  150. Assert.Equal (expectedG, g.Text);
  151. Assert.Equal (expectedGTriangle, g.TrianglePosition);
  152. Assert.Equal (expectedB, b.Text);
  153. Assert.Equal (expectedBTriangle, b.TrianglePosition);
  154. Assert.Equal (expectedHex, hex.Text);
  155. Application.Current.Dispose ();
  156. }
  157. public static IEnumerable<object []> ColorPickerTestData_WithTextFields ()
  158. {
  159. yield return new object []
  160. {
  161. new Color(255, 0),
  162. "R:", 15, 255, "G:", 2, 0, "B:", 2, 0, "#FF0000"
  163. };
  164. yield return new object []
  165. {
  166. new Color(0, 255),
  167. "R:", 2, 0, "G:", 15, 255, "B:", 2, 0, "#00FF00"
  168. };
  169. yield return new object []
  170. {
  171. new Color(0, 0, 255),
  172. "R:", 2, 0, "G:", 2, 0, "B:", 15, 255, "#0000FF"
  173. };
  174. yield return new object []
  175. {
  176. new Color(125, 125, 125),
  177. "R:", 9, 125, "G:", 9, 125, "B:", 9, 125, "#7D7D7D"
  178. };
  179. }
  180. [Theory]
  181. [SetupFakeDriver]
  182. [MemberData (nameof (ColorPickerTestData_WithTextFields))]
  183. 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)
  184. {
  185. var cp = GetColorPicker (ColorModel.RGB, true);
  186. cp.SelectedColor = c;
  187. cp.Draw ();
  188. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  189. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  190. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  191. var hex = GetTextField (cp, ColorPickerPart.Hex);
  192. var rTextField = GetTextField (cp, ColorPickerPart.Bar1);
  193. var gTextField = GetTextField (cp, ColorPickerPart.Bar2);
  194. var bTextField = GetTextField (cp, ColorPickerPart.Bar3);
  195. Assert.Equal (expectedR, r.Text);
  196. Assert.Equal (expectedRTriangle, r.TrianglePosition);
  197. Assert.Equal (expectedRValue.ToString (), rTextField.Text);
  198. Assert.Equal (expectedG, g.Text);
  199. Assert.Equal (expectedGTriangle, g.TrianglePosition);
  200. Assert.Equal (expectedGValue.ToString (), gTextField.Text);
  201. Assert.Equal (expectedB, b.Text);
  202. Assert.Equal (expectedBTriangle, b.TrianglePosition);
  203. Assert.Equal (expectedBValue.ToString (), bTextField.Text);
  204. Assert.Equal (expectedHex, hex.Text);
  205. Application.Current?.Dispose ();
  206. }
  207. [Fact]
  208. [SetupFakeDriver]
  209. public void ColorPicker_ClickingAtEndOfBar_SetsMaxValue ()
  210. {
  211. var cp = GetColorPicker (ColorModel.RGB, false);
  212. cp.Draw ();
  213. // Click at the end of the Red bar
  214. cp.Focused.OnMouseEvent (
  215. new ()
  216. {
  217. Flags = MouseFlags.Button1Pressed,
  218. Position = new (19, 0) // Assuming 0-based indexing
  219. });
  220. cp.Draw ();
  221. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  222. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  223. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  224. var hex = GetTextField (cp, ColorPickerPart.Hex);
  225. Assert.Equal ("R:", r.Text);
  226. Assert.Equal (19, r.TrianglePosition);
  227. Assert.Equal ("G:", g.Text);
  228. Assert.Equal (2, g.TrianglePosition);
  229. Assert.Equal ("B:", b.Text);
  230. Assert.Equal (2, b.TrianglePosition);
  231. Assert.Equal ("#FF0000", hex.Text);
  232. Application.Current?.Dispose ();
  233. }
  234. [Fact]
  235. [SetupFakeDriver]
  236. public void ColorPicker_ClickingBeyondBar_ChangesToMaxValue ()
  237. {
  238. var cp = GetColorPicker (ColorModel.RGB, false);
  239. cp.Draw ();
  240. // Click beyond the bar
  241. cp.Focused.OnMouseEvent (
  242. new ()
  243. {
  244. Flags = MouseFlags.Button1Pressed,
  245. Position = new (21, 0) // Beyond the bar
  246. });
  247. cp.Draw ();
  248. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  249. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  250. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  251. var hex = GetTextField (cp, ColorPickerPart.Hex);
  252. Assert.Equal ("R:", r.Text);
  253. Assert.Equal (19, r.TrianglePosition);
  254. Assert.Equal ("G:", g.Text);
  255. Assert.Equal (2, g.TrianglePosition);
  256. Assert.Equal ("B:", b.Text);
  257. Assert.Equal (2, b.TrianglePosition);
  258. Assert.Equal ("#FF0000", hex.Text);
  259. Application.Current?.Dispose ();
  260. }
  261. [Fact]
  262. [SetupFakeDriver]
  263. public void ColorPicker_ChangeValueOnUI_UpdatesAllUIElements ()
  264. {
  265. var cp = GetColorPicker (ColorModel.RGB, true);
  266. View otherView = new View () { CanFocus = true };
  267. Application.Current?.Add (otherView);
  268. cp.Draw ();
  269. // Change value using text field
  270. TextField rBarTextField = cp.Subviews.OfType<TextField> ().First (tf => tf.Text == "0");
  271. rBarTextField.Text = "128";
  272. //rBarTextField.OnLeave (cp); // OnLeave should be protected virtual. Don't call it.
  273. otherView.SetFocus (); // Remove focus from the color picker
  274. cp.Draw ();
  275. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  276. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  277. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  278. var hex = GetTextField (cp, ColorPickerPart.Hex);
  279. var rTextField = GetTextField (cp, ColorPickerPart.Bar1);
  280. var gTextField = GetTextField (cp, ColorPickerPart.Bar2);
  281. var bTextField = GetTextField (cp, ColorPickerPart.Bar3);
  282. Assert.Equal ("R:", r.Text);
  283. Assert.Equal (9, r.TrianglePosition);
  284. Assert.Equal ("128", rTextField.Text);
  285. Assert.Equal ("G:", g.Text);
  286. Assert.Equal (2, g.TrianglePosition);
  287. Assert.Equal ("0", gTextField.Text);
  288. Assert.Equal ("B:", b.Text);
  289. Assert.Equal (2, b.TrianglePosition);
  290. Assert.Equal ("0", bTextField.Text);
  291. Assert.Equal ("#800000", hex.Text);
  292. Application.Current?.Dispose ();
  293. }
  294. [Fact]
  295. [SetupFakeDriver]
  296. public void ColorPicker_InvalidHexInput_DoesNotChangeColor ()
  297. {
  298. var cp = GetColorPicker (ColorModel.RGB, true);
  299. cp.Draw ();
  300. // Enter invalid hex value
  301. TextField hexField = cp.Subviews.OfType<TextField> ().First (tf => tf.Text == "#000000");
  302. hexField.Text = "#ZZZZZZ";
  303. hexField.OnLeave (cp);
  304. cp.Draw ();
  305. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  306. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  307. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  308. var hex = GetTextField (cp, ColorPickerPart.Hex);
  309. Assert.Equal ("R:", r.Text);
  310. Assert.Equal (2, r.TrianglePosition);
  311. Assert.Equal ("G:", g.Text);
  312. Assert.Equal (2, g.TrianglePosition);
  313. Assert.Equal ("B:", b.Text);
  314. Assert.Equal (2, b.TrianglePosition);
  315. Assert.Equal ("#000000", hex.Text);
  316. Application.Current?.Dispose ();
  317. }
  318. [Fact]
  319. [SetupFakeDriver]
  320. public void ColorPicker_ClickingDifferentBars_ChangesFocus ()
  321. {
  322. var cp = GetColorPicker (ColorModel.RGB, false);
  323. cp.Draw ();
  324. // Click on Green bar
  325. cp.Subviews.OfType<GBar> ()
  326. .Single ()
  327. .OnMouseEvent (
  328. new ()
  329. {
  330. Flags = MouseFlags.Button1Pressed,
  331. Position = new (0, 1)
  332. });
  333. cp.Draw ();
  334. Assert.IsAssignableFrom<GBar> (cp.Focused);
  335. // Click on Blue bar
  336. cp.Subviews.OfType<BBar> ()
  337. .Single ()
  338. .OnMouseEvent (
  339. new ()
  340. {
  341. Flags = MouseFlags.Button1Pressed,
  342. Position = new (0, 2)
  343. });
  344. cp.Draw ();
  345. Assert.IsAssignableFrom<BBar> (cp.Focused);
  346. Application.Current?.Dispose ();
  347. }
  348. [Fact]
  349. [SetupFakeDriver]
  350. public void ColorPicker_SwitchingColorModels_ResetsBars ()
  351. {
  352. var cp = GetColorPicker (ColorModel.RGB, false);
  353. cp.SelectedColor = new (255, 0);
  354. cp.Draw ();
  355. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  356. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  357. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  358. var hex = GetTextField (cp, ColorPickerPart.Hex);
  359. Assert.Equal ("R:", r.Text);
  360. Assert.Equal (19, r.TrianglePosition);
  361. Assert.Equal ("G:", g.Text);
  362. Assert.Equal (2, g.TrianglePosition);
  363. Assert.Equal ("B:", b.Text);
  364. Assert.Equal (2, b.TrianglePosition);
  365. Assert.Equal ("#FF0000", hex.Text);
  366. // Switch to HSV
  367. cp.Style.ColorModel = ColorModel.HSV;
  368. cp.ApplyStyleChanges ();
  369. cp.Draw ();
  370. var h = GetColorBar (cp, ColorPickerPart.Bar1);
  371. var s = GetColorBar (cp, ColorPickerPart.Bar2);
  372. var v = GetColorBar (cp, ColorPickerPart.Bar3);
  373. Assert.Equal ("H:", h.Text);
  374. Assert.Equal (2, h.TrianglePosition);
  375. Assert.Equal ("S:", s.Text);
  376. Assert.Equal (19, s.TrianglePosition);
  377. Assert.Equal ("V:", v.Text);
  378. Assert.Equal (19, v.TrianglePosition);
  379. Assert.Equal ("#FF0000", hex.Text);
  380. Application.Current?.Dispose ();
  381. }
  382. [Fact]
  383. [SetupFakeDriver]
  384. public void ColorPicker_SyncBetweenTextFieldAndBars ()
  385. {
  386. var cp = GetColorPicker (ColorModel.RGB, true);
  387. cp.Draw ();
  388. // Change value using the bar
  389. RBar rBar = cp.Subviews.OfType<RBar> ().First ();
  390. rBar.Value = 128;
  391. cp.Draw ();
  392. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  393. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  394. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  395. var hex = GetTextField (cp, ColorPickerPart.Hex);
  396. var rTextField = GetTextField (cp, ColorPickerPart.Bar1);
  397. var gTextField = GetTextField (cp, ColorPickerPart.Bar2);
  398. var bTextField = GetTextField (cp, ColorPickerPart.Bar3);
  399. Assert.Equal ("R:", r.Text);
  400. Assert.Equal (9, r.TrianglePosition);
  401. Assert.Equal ("128", rTextField.Text);
  402. Assert.Equal ("G:", g.Text);
  403. Assert.Equal (2, g.TrianglePosition);
  404. Assert.Equal ("0", gTextField.Text);
  405. Assert.Equal ("B:", b.Text);
  406. Assert.Equal (2, b.TrianglePosition);
  407. Assert.Equal ("0", bTextField.Text);
  408. Assert.Equal ("#800000", hex.Text);
  409. Application.Current?.Dispose ();
  410. }
  411. enum ColorPickerPart
  412. {
  413. Bar1 = 0,
  414. Bar2 = 1,
  415. Bar3 = 2,
  416. ColorName = 3,
  417. Hex = 4,
  418. }
  419. private TextField GetTextField (ColorPicker cp, ColorPickerPart toGet)
  420. {
  421. var hasBarValueTextFields = cp.Style.ShowTextFields;
  422. var hasColorNameTextField = cp.Style.ShowColorName;
  423. switch (toGet)
  424. {
  425. case ColorPickerPart.Bar1:
  426. case ColorPickerPart.Bar2:
  427. case ColorPickerPart.Bar3:
  428. if (!hasBarValueTextFields)
  429. {
  430. throw new NotSupportedException ("Corresponding Style option is not enabled");
  431. }
  432. return cp.Subviews.OfType<TextField> ().ElementAt ((int)toGet);
  433. case ColorPickerPart.ColorName:
  434. if (!hasColorNameTextField)
  435. {
  436. throw new NotSupportedException ("Corresponding Style option is not enabled");
  437. }
  438. return cp.Subviews.OfType<TextField> ().ElementAt (hasBarValueTextFields ? (int)toGet : (int)toGet -3);
  439. case ColorPickerPart.Hex:
  440. int offset = hasBarValueTextFields ? 0 : 3;
  441. offset += hasColorNameTextField ? 0 : 1;
  442. return cp.Subviews.OfType<TextField> ().ElementAt ((int)toGet - offset);
  443. default:
  444. throw new ArgumentOutOfRangeException (nameof (toGet), toGet, null);
  445. }
  446. }
  447. private ColorBar GetColorBar (ColorPicker cp, ColorPickerPart toGet)
  448. {
  449. if (toGet <= ColorPickerPart.Bar3)
  450. {
  451. return cp.Subviews.OfType<ColorBar> ().ElementAt ((int)toGet);
  452. }
  453. throw new NotSupportedException ("ColorPickerPart must be a bar");
  454. }
  455. [Fact]
  456. [SetupFakeDriver]
  457. public void ColorPicker_ChangedEvent_Fires ()
  458. {
  459. Color newColor = default;
  460. var count = 0;
  461. var cp = new ColorPicker ();
  462. cp.ColorChanged += (s, e) =>
  463. {
  464. count++;
  465. newColor = e.CurrentValue;
  466. Assert.Equal (cp.SelectedColor, e.CurrentValue);
  467. };
  468. cp.SelectedColor = new (1, 2, 3);
  469. Assert.Equal (1, count);
  470. Assert.Equal (new (1, 2, 3), newColor);
  471. cp.SelectedColor = new (2, 3, 4);
  472. Assert.Equal (2, count);
  473. Assert.Equal (new (2, 3, 4), newColor);
  474. // Set to same value
  475. cp.SelectedColor = new (2, 3, 4);
  476. // Should have no effect
  477. Assert.Equal (2, count);
  478. }
  479. [Fact]
  480. [SetupFakeDriver]
  481. public void ColorPicker_DisposesOldViews_OnModelChange ()
  482. {
  483. var cp = GetColorPicker (ColorModel.HSL,true);
  484. var b1 = GetColorBar (cp, ColorPickerPart.Bar1);
  485. var b2 = GetColorBar (cp, ColorPickerPart.Bar2);
  486. var b3 = GetColorBar (cp, ColorPickerPart.Bar3);
  487. var tf1 = GetTextField (cp, ColorPickerPart.Bar1);
  488. var tf2 = GetTextField (cp, ColorPickerPart.Bar2);
  489. var tf3 = GetTextField (cp, ColorPickerPart.Bar3);
  490. var hex = GetTextField (cp, ColorPickerPart.Hex);
  491. Assert.All (new View [] { b1, b2, b3, tf1, tf2, tf3,hex }, b => Assert.False (b.WasDisposed));
  492. cp.Style.ColorModel = ColorModel.RGB;
  493. cp.ApplyStyleChanges ();
  494. var b1After = GetColorBar (cp, ColorPickerPart.Bar1);
  495. var b2After = GetColorBar (cp, ColorPickerPart.Bar2);
  496. var b3After = GetColorBar (cp, ColorPickerPart.Bar3);
  497. var tf1After = GetTextField (cp, ColorPickerPart.Bar1);
  498. var tf2After = GetTextField (cp, ColorPickerPart.Bar2);
  499. var tf3After = GetTextField (cp, ColorPickerPart.Bar3);
  500. var hexAfter = GetTextField (cp, ColorPickerPart.Hex);
  501. // Old bars should be disposed
  502. Assert.All (new View [] { b1, b2, b3, tf1, tf2, tf3,hex }, b => Assert.True (b.WasDisposed));
  503. Assert.NotSame (hex,hexAfter);
  504. Assert.NotSame (b1,b1After);
  505. Assert.NotSame (b2, b2After);
  506. Assert.NotSame (b3, b3After);
  507. Assert.NotSame (tf1, tf1After);
  508. Assert.NotSame (tf2, tf2After);
  509. Assert.NotSame (tf3, tf3After);
  510. }
  511. [Fact]
  512. [SetupFakeDriver]
  513. public void ColorPicker_TabCompleteColorName()
  514. {
  515. var cp = GetColorPicker (ColorModel.RGB, true,true);
  516. cp.Draw ();
  517. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  518. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  519. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  520. var name = GetTextField (cp, ColorPickerPart.ColorName);
  521. var hex = GetTextField (cp, ColorPickerPart.Hex);
  522. name.FocusFirst (TabBehavior.TabStop);
  523. Assert.True (name.HasFocus);
  524. Assert.Same (name, cp.Focused);
  525. name.Text = "";
  526. Assert.Empty (name.Text);
  527. Application.OnKeyDown (Key.A);
  528. Application.OnKeyDown (Key.Q);
  529. Assert.Equal ("aq",name.Text);
  530. // Auto complete the color name
  531. Application.OnKeyDown (Key.Tab);
  532. Assert.Equal ("Aquamarine", name.Text);
  533. // Tab out of the text field
  534. Application.OnKeyDown (Key.Tab);
  535. Assert.False (name.HasFocus);
  536. Assert.NotSame (name, cp.Focused);
  537. Assert.Equal ("#7FFFD4", hex.Text);
  538. Application.Current?.Dispose ();
  539. }
  540. [Fact]
  541. [SetupFakeDriver]
  542. public void ColorPicker_EnterHexFor_ColorName ()
  543. {
  544. var cp = GetColorPicker (ColorModel.RGB, true, true);
  545. cp.Draw ();
  546. var name = GetTextField (cp, ColorPickerPart.ColorName);
  547. var hex = GetTextField (cp, ColorPickerPart.Hex);
  548. hex.FocusFirst (TabBehavior.TabStop);
  549. Assert.True (hex.HasFocus);
  550. Assert.Same (hex, cp.Focused);
  551. hex.Text = "";
  552. name.Text = "";
  553. Assert.Empty (hex.Text);
  554. Assert.Empty (name.Text);
  555. Application.OnKeyDown ('#');
  556. Assert.Empty (name.Text);
  557. //7FFFD4
  558. Assert.Equal ("#", hex.Text);
  559. Application.OnKeyDown ('7');
  560. Application.OnKeyDown ('F');
  561. Application.OnKeyDown ('F');
  562. Application.OnKeyDown ('F');
  563. Application.OnKeyDown ('D');
  564. Assert.Empty (name.Text);
  565. Application.OnKeyDown ('4');
  566. // Tab out of the text field
  567. Application.OnKeyDown (Key.Tab);
  568. Assert.False (hex.HasFocus);
  569. Assert.NotSame (hex, cp.Focused);
  570. // Color name should be recognised as a known string and populated
  571. Assert.Equal ("#7FFFD4", hex.Text);
  572. Assert.Equal("Aquamarine", name.Text);
  573. Application.Current?.Dispose ();
  574. }
  575. [Fact]
  576. public void TestColorNames ()
  577. {
  578. var colors = new W3CColors ();
  579. Assert.Contains ("Aquamarine", colors.GetColorNames ());
  580. Assert.DoesNotContain ("Save as",colors.GetColorNames ());
  581. }
  582. private ColorPicker GetColorPicker (ColorModel colorModel, bool showTextFields, bool showName = false)
  583. {
  584. var cp = new ColorPicker { Width = 20, SelectedColor = new (0, 0) };
  585. cp.Style.ColorModel = colorModel;
  586. cp.Style.ShowTextFields = showTextFields;
  587. cp.Style.ShowColorName = showName;
  588. cp.ApplyStyleChanges ();
  589. Application.Current = new Toplevel () { Width = 20 ,Height = 5};
  590. Application.Current.Add (cp);
  591. Application.Current.FocusFirst (null);
  592. Application.Current.LayoutSubviews ();
  593. Application.Current.FocusFirst (null);
  594. return cp;
  595. }
  596. }