AdvanceFocusTests.cs 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647
  1. using System.Runtime.Intrinsics;
  2. using Xunit.Abstractions;
  3. namespace Terminal.Gui.ViewTests;
  4. public class AdvanceFocusTests ()
  5. {
  6. [Fact]
  7. public void AdvanceFocus_CanFocus_Mixed ()
  8. {
  9. var r = new View ();
  10. var v1 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  11. var v2 = new View { CanFocus = false, TabStop = TabBehavior.TabStop };
  12. var v3 = new View { CanFocus = false, TabStop = TabBehavior.NoStop };
  13. r.Add (v1, v2, v3);
  14. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  15. Assert.False (v1.HasFocus);
  16. Assert.False (v2.HasFocus);
  17. Assert.False (v3.HasFocus);
  18. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  19. Assert.False (v1.HasFocus);
  20. Assert.False (v2.HasFocus);
  21. Assert.False (v3.HasFocus);
  22. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  23. Assert.False (v1.HasFocus);
  24. Assert.False (v2.HasFocus);
  25. Assert.False (v3.HasFocus);
  26. r.Dispose ();
  27. }
  28. [Theory]
  29. [CombinatorialData]
  30. public void AdvanceFocus_Change_CanFocus_Works ([CombinatorialValues (TabBehavior.NoStop, TabBehavior.TabStop, TabBehavior.TabGroup)] TabBehavior behavior)
  31. {
  32. var r = new View { CanFocus = true };
  33. var v1 = new View ();
  34. var v2 = new View ();
  35. var v3 = new View ();
  36. Assert.True (r.CanFocus);
  37. Assert.False (v1.CanFocus);
  38. Assert.False (v2.CanFocus);
  39. Assert.False (v3.CanFocus);
  40. r.Add (v1, v2, v3);
  41. r.AdvanceFocus (NavigationDirection.Forward, behavior);
  42. Assert.False (v1.HasFocus);
  43. Assert.False (v2.HasFocus);
  44. Assert.False (v3.HasFocus);
  45. v1.CanFocus = true;
  46. v1.TabStop = behavior;
  47. r.AdvanceFocus (NavigationDirection.Forward, behavior);
  48. Assert.True (v1.HasFocus);
  49. Assert.False (v2.HasFocus);
  50. Assert.False (v3.HasFocus);
  51. v2.CanFocus = true;
  52. v2.TabStop = behavior;
  53. r.AdvanceFocus (NavigationDirection.Forward, behavior);
  54. Assert.False (v1.HasFocus);
  55. Assert.True (v2.HasFocus);
  56. Assert.False (v3.HasFocus);
  57. v3.CanFocus = true;
  58. v3.TabStop = behavior;
  59. r.AdvanceFocus (NavigationDirection.Forward, behavior);
  60. Assert.False (v1.HasFocus);
  61. Assert.False (v2.HasFocus);
  62. Assert.True (v3.HasFocus);
  63. r.Dispose ();
  64. }
  65. [Fact]
  66. public void AdvanceFocus_Subviews_TabStop ()
  67. {
  68. TabBehavior behavior = TabBehavior.TabStop;
  69. var top = new View { Id = "top", CanFocus = true };
  70. var v1 = new View { Id = "v1", CanFocus = true, TabStop = behavior };
  71. var v2 = new View { Id = "v2", CanFocus = true, TabStop = behavior };
  72. var v3 = new View { Id = "v3", CanFocus = false, TabStop = behavior };
  73. top.Add (v1, v2, v3);
  74. // Cycle through v1 & v2
  75. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  76. Assert.True (v1.HasFocus);
  77. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  78. Assert.True (v2.HasFocus);
  79. // Should cycle back to v1
  80. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  81. Assert.True (v1.HasFocus);
  82. // Go backwards
  83. top.AdvanceFocus (NavigationDirection.Backward, behavior);
  84. Assert.True (v2.HasFocus);
  85. top.AdvanceFocus (NavigationDirection.Backward, behavior);
  86. Assert.True (v1.HasFocus);
  87. top.Dispose ();
  88. }
  89. [Fact]
  90. public void AdvanceFocus_Compound_Subview_TabStop ()
  91. {
  92. TabBehavior behavior = TabBehavior.TabStop;
  93. var top = new View { Id = "top", CanFocus = true };
  94. var compoundSubview = new View
  95. {
  96. CanFocus = true,
  97. Id = "compoundSubview",
  98. TabStop = behavior
  99. };
  100. var v1 = new View { Id = "v1", CanFocus = true, TabStop = behavior };
  101. var v2 = new View { Id = "v2", CanFocus = true, TabStop = behavior };
  102. var v3 = new View { Id = "v3", CanFocus = false, TabStop = behavior };
  103. compoundSubview.Add (v1, v2, v3);
  104. top.Add (compoundSubview);
  105. // Cycle through v1 & v2
  106. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  107. Assert.True (v1.HasFocus);
  108. Assert.False (v2.HasFocus);
  109. Assert.False (v3.HasFocus);
  110. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  111. Assert.False (v1.HasFocus);
  112. Assert.True (v2.HasFocus);
  113. Assert.False (v3.HasFocus);
  114. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  115. Assert.True (v1.HasFocus);
  116. Assert.False (v2.HasFocus);
  117. Assert.False (v3.HasFocus);
  118. // Add another subview
  119. View otherSubview = new ()
  120. {
  121. CanFocus = true,
  122. TabStop = behavior,
  123. Id = "otherSubview"
  124. };
  125. top.Add (otherSubview);
  126. // Adding a focusable subview causes advancefocus
  127. Assert.True (otherSubview.HasFocus);
  128. Assert.False (v1.HasFocus);
  129. // Cycle through v1 & v2
  130. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  131. Assert.True (v1.HasFocus);
  132. Assert.False (v2.HasFocus);
  133. Assert.False (v3.HasFocus);
  134. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  135. Assert.False (v1.HasFocus);
  136. Assert.True (v2.HasFocus);
  137. Assert.False (v3.HasFocus);
  138. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  139. Assert.False (v1.HasFocus);
  140. Assert.False (v2.HasFocus);
  141. Assert.False (v3.HasFocus);
  142. Assert.True (otherSubview.HasFocus);
  143. // v2 was previously focused down the compoundSubView focus chain
  144. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  145. Assert.False (v1.HasFocus);
  146. Assert.True (v2.HasFocus);
  147. Assert.False (v3.HasFocus);
  148. top.Dispose ();
  149. }
  150. [Fact]
  151. public void AdvanceFocus_CompoundCompound_Subview_TabStop ()
  152. {
  153. TabBehavior behavior = TabBehavior.TabStop;
  154. var top = new View { Id = "top", CanFocus = true };
  155. var topv1 = new View { Id = "topv1", CanFocus = true, TabStop = behavior };
  156. var topv2 = new View { Id = "topv2", CanFocus = true, TabStop = behavior };
  157. var topv3 = new View { Id = "topv3", CanFocus = false, TabStop = behavior };
  158. top.Add (topv1, topv2, topv3);
  159. var compoundSubview = new View
  160. {
  161. CanFocus = true,
  162. Id = "compoundSubview",
  163. TabStop = behavior
  164. };
  165. var v1 = new View { Id = "v1", CanFocus = true, TabStop = behavior };
  166. var v2 = new View { Id = "v2", CanFocus = true, TabStop = behavior };
  167. var v3 = new View { Id = "v3", CanFocus = false, TabStop = behavior };
  168. compoundSubview.Add (v1, v2, v3);
  169. var compoundCompoundSubview = new View
  170. {
  171. CanFocus = true,
  172. Id = "compoundCompoundSubview",
  173. TabStop = behavior
  174. };
  175. var v4 = new View { Id = "v4", CanFocus = true, TabStop = behavior };
  176. var v5 = new View { Id = "v5", CanFocus = true, TabStop = behavior };
  177. var v6 = new View { Id = "v6", CanFocus = false, TabStop = behavior };
  178. compoundCompoundSubview.Add (v4, v5, v6);
  179. compoundSubview.Add (compoundCompoundSubview);
  180. top.Add (compoundSubview);
  181. top.SetFocus ();
  182. Assert.True (topv1.HasFocus);
  183. // Cycle through topv2
  184. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  185. Assert.True (topv2.HasFocus);
  186. // Cycle v1, v2, v4, v5
  187. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  188. Assert.True (v1.HasFocus);
  189. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  190. Assert.True (v2.HasFocus);
  191. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  192. Assert.True (v4.HasFocus);
  193. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  194. Assert.True (v5.HasFocus);
  195. // Should cycle back to topv1
  196. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  197. Assert.True (topv1.HasFocus);
  198. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  199. Assert.True (topv2.HasFocus);
  200. // Add another top subview. Should cycle to it after v5
  201. View otherSubview = new ()
  202. {
  203. CanFocus = true,
  204. TabStop = behavior,
  205. Id = "otherSubview"
  206. };
  207. top.Add (otherSubview);
  208. // Adding a focusable subview causes advancefocus
  209. Assert.True (otherSubview.HasFocus);
  210. // Cycle through topv1, topv2, v1, v2, v4, v5
  211. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  212. Assert.True (topv1.HasFocus);
  213. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  214. Assert.True (topv2.HasFocus);
  215. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  216. // the above should have cycled to v5 since it was the previously most focused subview of compoundSubView
  217. Assert.True (v5.HasFocus);
  218. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  219. Assert.True (otherSubview.HasFocus);
  220. // Should cycle back to topv1
  221. top.AdvanceFocus (NavigationDirection.Forward, behavior);
  222. Assert.True (topv1.HasFocus);
  223. top.Dispose ();
  224. }
  225. [Fact]
  226. public void AdvanceFocus_Compound_Subview_TabGroup ()
  227. {
  228. var top = new View { Id = "top", CanFocus = true, TabStop = TabBehavior.TabGroup };
  229. var compoundSubview = new View
  230. {
  231. CanFocus = true,
  232. Id = "compoundSubview",
  233. TabStop = TabBehavior.TabGroup
  234. };
  235. var tabStopView = new View { Id = "tabStop", CanFocus = true, TabStop = TabBehavior.TabStop };
  236. var tabGroupView1 = new View { Id = "tabGroup1", CanFocus = true, TabStop = TabBehavior.TabGroup };
  237. var tabGroupView2 = new View { Id = "tabGroup2", CanFocus = true, TabStop = TabBehavior.TabGroup };
  238. compoundSubview.Add (tabStopView, tabGroupView1, tabGroupView2);
  239. top.Add (compoundSubview);
  240. top.SetFocus ();
  241. Assert.True (tabStopView.HasFocus);
  242. // TabGroup should cycle to tabGroup1 then tabGroup2
  243. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup);
  244. Assert.False (tabStopView.HasFocus);
  245. Assert.True (tabGroupView1.HasFocus);
  246. Assert.False (tabGroupView2.HasFocus);
  247. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup);
  248. Assert.False (tabStopView.HasFocus);
  249. Assert.False (tabGroupView1.HasFocus);
  250. Assert.True (tabGroupView2.HasFocus);
  251. // Add another TabGroup subview
  252. View otherTabGroupSubview = new ()
  253. {
  254. CanFocus = true,
  255. TabStop = TabBehavior.TabGroup,
  256. Id = "otherTabGroupSubview"
  257. };
  258. top.Add (otherTabGroupSubview);
  259. // Adding a focusable subview causes advancefocus
  260. Assert.True (otherTabGroupSubview.HasFocus);
  261. Assert.False (tabStopView.HasFocus);
  262. // TagBroup navs to the other subview
  263. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup);
  264. Assert.Equal (compoundSubview, top.Focused);
  265. Assert.True (tabStopView.HasFocus);
  266. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup);
  267. Assert.Equal (compoundSubview, top.Focused);
  268. Assert.True (tabGroupView1.HasFocus);
  269. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabGroup);
  270. Assert.Equal (compoundSubview, top.Focused);
  271. Assert.True (tabGroupView2.HasFocus);
  272. // Now go backwards
  273. top.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabGroup);
  274. Assert.Equal (compoundSubview, top.Focused);
  275. Assert.True (tabGroupView1.HasFocus);
  276. top.AdvanceFocus (NavigationDirection.Backward, TabBehavior.TabGroup);
  277. Assert.Equal (otherTabGroupSubview, top.Focused);
  278. Assert.True (otherTabGroupSubview.HasFocus);
  279. top.Dispose ();
  280. }
  281. [Fact]
  282. public void AdvanceFocus_NoStop_And_CanFocus_True_No_Focus ()
  283. {
  284. var r = new View ();
  285. var v1 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  286. var v2 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  287. var v3 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  288. r.Add (v1, v2, v3);
  289. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  290. Assert.False (v1.HasFocus);
  291. Assert.False (v2.HasFocus);
  292. Assert.False (v3.HasFocus);
  293. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  294. Assert.False (v1.HasFocus);
  295. Assert.False (v2.HasFocus);
  296. Assert.False (v3.HasFocus);
  297. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  298. Assert.False (v1.HasFocus);
  299. Assert.False (v2.HasFocus);
  300. Assert.False (v3.HasFocus);
  301. r.Dispose ();
  302. }
  303. [Fact]
  304. public void AdvanceFocus_NoStop_Change_Enables_Stop ()
  305. {
  306. var r = new View { CanFocus = true };
  307. var v1 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  308. var v2 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  309. var v3 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  310. r.Add (v1, v2, v3);
  311. v1.TabStop = TabBehavior.TabStop;
  312. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  313. Assert.True (v1.HasFocus);
  314. Assert.False (v2.HasFocus);
  315. Assert.False (v3.HasFocus);
  316. v2.TabStop = TabBehavior.TabStop;
  317. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  318. Assert.False (v1.HasFocus);
  319. Assert.True (v2.HasFocus);
  320. Assert.False (v3.HasFocus);
  321. v3.TabStop = TabBehavior.TabStop;
  322. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  323. Assert.False (v1.HasFocus);
  324. Assert.False (v2.HasFocus);
  325. Assert.True (v3.HasFocus);
  326. r.Dispose ();
  327. }
  328. [Fact]
  329. public void AdvanceFocus_NoStop_Prevents_Stop ()
  330. {
  331. var r = new View ();
  332. var v1 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  333. var v2 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  334. var v3 = new View { CanFocus = true, TabStop = TabBehavior.NoStop };
  335. r.Add (v1, v2, v3);
  336. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  337. Assert.False (v1.HasFocus);
  338. Assert.False (v2.HasFocus);
  339. Assert.False (v3.HasFocus);
  340. }
  341. [Fact]
  342. public void AdvanceFocus_Null_And_CanFocus_False_No_Advance ()
  343. {
  344. var r = new View ();
  345. var v1 = new View ();
  346. var v2 = new View ();
  347. var v3 = new View ();
  348. Assert.False (v1.CanFocus);
  349. Assert.Null (v1.TabStop);
  350. r.Add (v1, v2, v3);
  351. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  352. Assert.False (v1.HasFocus);
  353. Assert.False (v2.HasFocus);
  354. Assert.False (v3.HasFocus);
  355. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  356. Assert.False (v1.HasFocus);
  357. Assert.False (v2.HasFocus);
  358. Assert.False (v3.HasFocus);
  359. r.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  360. Assert.False (v1.HasFocus);
  361. Assert.False (v2.HasFocus);
  362. Assert.False (v3.HasFocus);
  363. r.Dispose ();
  364. }
  365. [Fact]
  366. public void AdvanceFocus_Subviews_Raises_HasFocusChanged ()
  367. {
  368. var top = new View
  369. {
  370. Id = "top",
  371. CanFocus = true
  372. };
  373. var subView1 = new View
  374. {
  375. Id = "subView1",
  376. CanFocus = true
  377. };
  378. var subView2 = new View
  379. {
  380. Id = "subView2",
  381. CanFocus = true
  382. };
  383. top.Add (subView1, subView2);
  384. var subView1HasFocusChangedTrueCount = 0;
  385. var subView1HasFocusChangedFalseCount = 0;
  386. subView1.HasFocusChanged += (s, e) =>
  387. {
  388. if (e.NewValue)
  389. {
  390. subView1HasFocusChangedTrueCount++;
  391. }
  392. else
  393. {
  394. subView1HasFocusChangedFalseCount++;
  395. }
  396. };
  397. var subView2HasFocusChangedTrueCount = 0;
  398. var subView2HasFocusChangedFalseCount = 0;
  399. subView2.HasFocusChanged += (s, e) =>
  400. {
  401. if (e.NewValue)
  402. {
  403. subView2HasFocusChangedTrueCount++;
  404. }
  405. else
  406. {
  407. subView2HasFocusChangedFalseCount++;
  408. }
  409. };
  410. top.SetFocus ();
  411. Assert.True (top.HasFocus);
  412. Assert.True (subView1.HasFocus);
  413. Assert.False (subView2.HasFocus);
  414. Assert.Equal (1, subView1HasFocusChangedTrueCount);
  415. Assert.Equal (0, subView1HasFocusChangedFalseCount);
  416. Assert.Equal (0, subView2HasFocusChangedTrueCount);
  417. Assert.Equal (0, subView2HasFocusChangedFalseCount);
  418. top.AdvanceFocus (NavigationDirection.Forward, null);
  419. Assert.False (subView1.HasFocus);
  420. Assert.True (subView2.HasFocus);
  421. Assert.Equal (1, subView1HasFocusChangedTrueCount);
  422. Assert.Equal (1, subView1HasFocusChangedFalseCount);
  423. Assert.Equal (1, subView2HasFocusChangedTrueCount);
  424. Assert.Equal (0, subView2HasFocusChangedFalseCount);
  425. top.AdvanceFocus (NavigationDirection.Forward, null);
  426. Assert.True (subView1.HasFocus);
  427. Assert.False (subView2.HasFocus);
  428. Assert.Equal (2, subView1HasFocusChangedTrueCount);
  429. Assert.Equal (1, subView1HasFocusChangedFalseCount);
  430. Assert.Equal (1, subView2HasFocusChangedTrueCount);
  431. Assert.Equal (1, subView2HasFocusChangedFalseCount);
  432. }
  433. [Fact]
  434. public void AdvanceFocus_Subviews_Raises_HasFocusChanging ()
  435. {
  436. var top = new View
  437. {
  438. Id = "top",
  439. CanFocus = true
  440. };
  441. var subView1 = new View
  442. {
  443. Id = "subView1",
  444. CanFocus = true
  445. };
  446. var subView2 = new View
  447. {
  448. Id = "subView2",
  449. CanFocus = true
  450. };
  451. top.Add (subView1, subView2);
  452. var subView1HasFocusChangingTrueCount = 0;
  453. var subView1HasFocusChangingFalseCount = 0;
  454. subView1.HasFocusChanging += (s, e) =>
  455. {
  456. if (e.NewValue)
  457. {
  458. subView1HasFocusChangingTrueCount++;
  459. }
  460. else
  461. {
  462. subView1HasFocusChangingFalseCount++;
  463. }
  464. };
  465. var subView2HasFocusChangingTrueCount = 0;
  466. var subView2HasFocusChangingFalseCount = 0;
  467. subView2.HasFocusChanging += (s, e) =>
  468. {
  469. if (e.NewValue)
  470. {
  471. subView2HasFocusChangingTrueCount++;
  472. }
  473. else
  474. {
  475. subView2HasFocusChangingFalseCount++;
  476. }
  477. };
  478. top.SetFocus ();
  479. Assert.True (top.HasFocus);
  480. Assert.True (subView1.HasFocus);
  481. Assert.False (subView2.HasFocus);
  482. Assert.Equal (1, subView1HasFocusChangingTrueCount);
  483. Assert.Equal (0, subView1HasFocusChangingFalseCount);
  484. Assert.Equal (0, subView2HasFocusChangingTrueCount);
  485. Assert.Equal (0, subView2HasFocusChangingFalseCount);
  486. top.AdvanceFocus (NavigationDirection.Forward, null);
  487. Assert.False (subView1.HasFocus);
  488. Assert.True (subView2.HasFocus);
  489. Assert.Equal (1, subView1HasFocusChangingTrueCount);
  490. Assert.Equal (1, subView1HasFocusChangingFalseCount);
  491. Assert.Equal (1, subView2HasFocusChangingTrueCount);
  492. Assert.Equal (0, subView2HasFocusChangingFalseCount);
  493. top.AdvanceFocus (NavigationDirection.Forward, null);
  494. Assert.True (subView1.HasFocus);
  495. Assert.False (subView2.HasFocus);
  496. Assert.Equal (2, subView1HasFocusChangingTrueCount);
  497. Assert.Equal (1, subView1HasFocusChangingFalseCount);
  498. Assert.Equal (1, subView2HasFocusChangingTrueCount);
  499. Assert.Equal (1, subView2HasFocusChangingFalseCount);
  500. }
  501. [Fact]
  502. public void AdvanceFocus_With_CanFocus_Are_All_True ()
  503. {
  504. var top = new View { Id = "top", CanFocus = true };
  505. var v1 = new View { Id = "v1", CanFocus = true };
  506. var v2 = new View { Id = "v2", CanFocus = true };
  507. var v3 = new View { Id = "v3", CanFocus = true };
  508. top.Add (v1, v2, v3);
  509. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  510. Assert.True (v1.HasFocus);
  511. Assert.False (v2.HasFocus);
  512. Assert.False (v3.HasFocus);
  513. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  514. Assert.False (v1.HasFocus);
  515. Assert.True (v2.HasFocus);
  516. Assert.False (v3.HasFocus);
  517. top.AdvanceFocus (NavigationDirection.Forward, TabBehavior.TabStop);
  518. Assert.False (v1.HasFocus);
  519. Assert.False (v2.HasFocus);
  520. Assert.True (v3.HasFocus);
  521. top.Dispose ();
  522. }
  523. [Theory]
  524. [CombinatorialData]
  525. public void TabStop_And_CanFocus_Are_Decoupled (bool canFocus, TabBehavior tabStop)
  526. {
  527. var view = new View { CanFocus = canFocus, TabStop = tabStop };
  528. Assert.Equal (canFocus, view.CanFocus);
  529. Assert.Equal (tabStop, view.TabStop);
  530. }
  531. }