ColorPickerTests.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
  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.HasFocus = false;
  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. #if DEBUG_IDISPOSABLE
  492. Assert.All (new View [] { b1, b2, b3, tf1, tf2, tf3, hex }, b => Assert.False (b.WasDisposed));
  493. #endif
  494. cp.Style.ColorModel = ColorModel.RGB;
  495. cp.ApplyStyleChanges ();
  496. var b1After = GetColorBar (cp, ColorPickerPart.Bar1);
  497. var b2After = GetColorBar (cp, ColorPickerPart.Bar2);
  498. var b3After = GetColorBar (cp, ColorPickerPart.Bar3);
  499. var tf1After = GetTextField (cp, ColorPickerPart.Bar1);
  500. var tf2After = GetTextField (cp, ColorPickerPart.Bar2);
  501. var tf3After = GetTextField (cp, ColorPickerPart.Bar3);
  502. var hexAfter = GetTextField (cp, ColorPickerPart.Hex);
  503. // Old bars should be disposed
  504. #if DEBUG_IDISPOSABLE
  505. Assert.All (new View [] { b1, b2, b3, tf1, tf2, tf3, hex }, b => Assert.True (b.WasDisposed));
  506. #endif
  507. Assert.NotSame (hex, hexAfter);
  508. Assert.NotSame (b1, b1After);
  509. Assert.NotSame (b2, b2After);
  510. Assert.NotSame (b3, b3After);
  511. Assert.NotSame (tf1, tf1After);
  512. Assert.NotSame (tf2, tf2After);
  513. Assert.NotSame (tf3, tf3After);
  514. }
  515. [Fact]
  516. [SetupFakeDriver]
  517. public void ColorPicker_TabCompleteColorName ()
  518. {
  519. var cp = GetColorPicker (ColorModel.RGB, true, true);
  520. cp.Draw ();
  521. var r = GetColorBar (cp, ColorPickerPart.Bar1);
  522. var g = GetColorBar (cp, ColorPickerPart.Bar2);
  523. var b = GetColorBar (cp, ColorPickerPart.Bar3);
  524. var name = GetTextField (cp, ColorPickerPart.ColorName);
  525. var hex = GetTextField (cp, ColorPickerPart.Hex);
  526. name.SetFocus ();
  527. Assert.True (name.HasFocus);
  528. Assert.Same (name, cp.Focused);
  529. name.Text = "";
  530. Assert.Empty (name.Text);
  531. Application.OnKeyDown (Key.A);
  532. Application.OnKeyDown (Key.Q);
  533. Assert.Equal ("aq", name.Text);
  534. // Auto complete the color name
  535. Application.OnKeyDown (Key.Tab);
  536. Assert.Equal ("Aquamarine", name.Text);
  537. // Tab out of the text field
  538. Application.OnKeyDown (Key.Tab);
  539. Assert.False (name.HasFocus);
  540. Assert.NotSame (name, cp.Focused);
  541. Assert.Equal ("#7FFFD4", hex.Text);
  542. Application.Current?.Dispose ();
  543. }
  544. [Fact]
  545. [SetupFakeDriver]
  546. public void ColorPicker_EnterHexFor_ColorName ()
  547. {
  548. var cp = GetColorPicker (ColorModel.RGB, true, true);
  549. cp.Draw ();
  550. var name = GetTextField (cp, ColorPickerPart.ColorName);
  551. var hex = GetTextField (cp, ColorPickerPart.Hex);
  552. hex.SetFocus ();
  553. Assert.True (hex.HasFocus);
  554. Assert.Same (hex, cp.Focused);
  555. hex.Text = "";
  556. name.Text = "";
  557. Assert.Empty (hex.Text);
  558. Assert.Empty (name.Text);
  559. Application.OnKeyDown ('#');
  560. Assert.Empty (name.Text);
  561. //7FFFD4
  562. Assert.Equal ("#", hex.Text);
  563. Application.OnKeyDown ('7');
  564. Application.OnKeyDown ('F');
  565. Application.OnKeyDown ('F');
  566. Application.OnKeyDown ('F');
  567. Application.OnKeyDown ('D');
  568. Assert.Empty (name.Text);
  569. Application.OnKeyDown ('4');
  570. Assert.True (hex.HasFocus);
  571. // Tab out of the hex field - should wrap to first focusable subview
  572. Application.OnKeyDown (Key.Tab);
  573. Assert.False (hex.HasFocus);
  574. Assert.NotSame (hex, cp.Focused);
  575. // Color name should be recognised as a known string and populated
  576. Assert.Equal ("#7FFFD4", hex.Text);
  577. Assert.Equal ("Aquamarine", name.Text);
  578. Application.Current?.Dispose ();
  579. }
  580. [Fact]
  581. public void TestColorNames ()
  582. {
  583. var colors = new W3CColors ();
  584. Assert.Contains ("Aquamarine", colors.GetColorNames ());
  585. Assert.DoesNotContain ("Save as", colors.GetColorNames ());
  586. }
  587. private ColorPicker GetColorPicker (ColorModel colorModel, bool showTextFields, bool showName = false)
  588. {
  589. var cp = new ColorPicker { Width = 20, SelectedColor = new (0, 0) };
  590. cp.Style.ColorModel = colorModel;
  591. cp.Style.ShowTextFields = showTextFields;
  592. cp.Style.ShowColorName = showName;
  593. cp.ApplyStyleChanges ();
  594. Application.Current = new Toplevel () { Width = 20, Height = 5 };
  595. Application.Current.Add (cp);
  596. Application.Current.LayoutSubviews ();
  597. Application.Current.SetFocus ();
  598. return cp;
  599. }
  600. }