TabViewTests.cs 44 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504
  1. using System.Globalization;
  2. using Xunit.Abstractions;
  3. namespace Terminal.Gui.ViewsTests;
  4. public class TabViewTests (ITestOutputHelper output)
  5. {
  6. [Fact]
  7. public void AddTab_SameTabMoreThanOnce ()
  8. {
  9. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  10. Assert.Equal (2, tv.Tabs.Count);
  11. // Tab is already part of the control so shouldn't result in duplication
  12. tv.AddTab (tab1, false);
  13. tv.AddTab (tab1, false);
  14. tv.AddTab (tab1, false);
  15. tv.AddTab (tab1, false);
  16. Assert.Equal (2, tv.Tabs.Count);
  17. }
  18. [Fact]
  19. [SetupFakeDriver]
  20. public void AddTwoTabs_SecondIsSelected ()
  21. {
  22. var tv = new TabView ();
  23. Tab tab1;
  24. Tab tab2;
  25. tv.AddTab (tab1 = new () { DisplayText = "Tab1", View = new TextField { Text = "hi" } }, false);
  26. tv.AddTab (tab2 = new () { DisplayText = "Tab1", View = new Label { Text = "hi2" } }, true);
  27. Assert.Equal (2, tv.Tabs.Count);
  28. Assert.Equal (tab2, tv.SelectedTab);
  29. }
  30. [Fact]
  31. public void EnsureSelectedTabVisible_MustScroll ()
  32. {
  33. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  34. // Make tab width small to force only one tab visible at once
  35. tv.Width = 4;
  36. tv.SelectedTab = tab1;
  37. Assert.Equal (0, tv.TabScrollOffset);
  38. tv.EnsureSelectedTabIsVisible ();
  39. Assert.Equal (0, tv.TabScrollOffset);
  40. // Asking to show tab2 should automatically move scroll offset accordingly
  41. tv.SelectedTab = tab2;
  42. Assert.Equal (1, tv.TabScrollOffset);
  43. }
  44. [Fact]
  45. public void EnsureSelectedTabVisible_NullSelect ()
  46. {
  47. TabView tv = GetTabView ();
  48. tv.SelectedTab = null;
  49. Assert.Null (tv.SelectedTab);
  50. Assert.Equal (0, tv.TabScrollOffset);
  51. tv.EnsureSelectedTabIsVisible ();
  52. Assert.Null (tv.SelectedTab);
  53. Assert.Equal (0, tv.TabScrollOffset);
  54. }
  55. [Fact]
  56. public void EnsureValidScrollOffsets_TabScrollOffset ()
  57. {
  58. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  59. // Make tab width small to force only one tab visible at once
  60. tv.Width = 4;
  61. tv.SelectedTab = tab1;
  62. Assert.Equal (0, tv.TabScrollOffset);
  63. tv.TabScrollOffset = 10;
  64. tv.SelectedTab = tab2;
  65. Assert.Equal (1, tv.TabScrollOffset);
  66. tv.TabScrollOffset = -1;
  67. tv.SelectedTab = tab1;
  68. Assert.Equal (0, tv.TabScrollOffset);
  69. }
  70. [Fact]
  71. [AutoInitShutdown]
  72. public void MouseClick_ChangesTab ()
  73. {
  74. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  75. tv.Width = 20;
  76. tv.Height = 5;
  77. tv.Draw ();
  78. View tabRow = tv.Subviews [0];
  79. Assert.Equal ("TabRow", tabRow.GetType ().Name);
  80. TestHelpers.AssertDriverContentsAre (
  81. @"
  82. ╭────┬────╮
  83. │Tab1│Tab2│
  84. │ ╰────┴────────╮
  85. │hi │
  86. └──────────────────┘
  87. ",
  88. output
  89. );
  90. Tab clicked = null;
  91. tv.TabClicked += (s, e) => { clicked = e.Tab; };
  92. var top = new Toplevel ();
  93. top.Add (tv);
  94. Application.Begin (top);
  95. MouseEventArgs args;
  96. // Waving mouse around does not trigger click
  97. for (var i = 0; i < 100; i++)
  98. {
  99. args = new () { ScreenPosition = new (i, 1), Flags = MouseFlags.ReportMousePosition };
  100. Application.RaiseMouseEvent (args);
  101. Application.LayoutAndDraw ();
  102. Assert.Null (clicked);
  103. Assert.Equal (tab1, tv.SelectedTab);
  104. }
  105. args = new () { ScreenPosition = new (3, 1), Flags = MouseFlags.Button1Clicked };
  106. Application.RaiseMouseEvent (args);
  107. Application.LayoutAndDraw ();
  108. Assert.Equal (tab1, clicked);
  109. Assert.Equal (tab1, tv.SelectedTab);
  110. // Click to tab2
  111. args = new () { ScreenPosition = new (6, 1), Flags = MouseFlags.Button1Clicked };
  112. Application.RaiseMouseEvent (args);
  113. Application.LayoutAndDraw ();
  114. Assert.Equal (tab2, clicked);
  115. Assert.Equal (tab2, tv.SelectedTab);
  116. // cancel navigation
  117. tv.TabClicked += (s, e) =>
  118. {
  119. clicked = e.Tab;
  120. e.MouseEvent.Handled = true;
  121. };
  122. args = new () { ScreenPosition = new (3, 1), Flags = MouseFlags.Button1Clicked };
  123. Application.RaiseMouseEvent (args);
  124. Application.LayoutAndDraw ();
  125. // Tab 1 was clicked but event handler blocked navigation
  126. Assert.Equal (tab1, clicked);
  127. Assert.Equal (tab2, tv.SelectedTab);
  128. args = new () { ScreenPosition = new (12, 1), Flags = MouseFlags.Button1Clicked };
  129. Application.RaiseMouseEvent (args);
  130. Application.LayoutAndDraw ();
  131. // Clicking beyond last tab should raise event with null Tab
  132. Assert.Null (clicked);
  133. Assert.Equal (tab2, tv.SelectedTab);
  134. top.Dispose ();
  135. }
  136. [Fact]
  137. [AutoInitShutdown]
  138. public void MouseClick_Right_Left_Arrows_ChangesTab ()
  139. {
  140. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  141. tv.Width = 7;
  142. tv.Height = 5;
  143. tv.Draw ();
  144. View tabRow = tv.Subviews [0];
  145. Assert.Equal ("TabRow", tabRow.GetType ().Name);
  146. TestHelpers.AssertDriverContentsAre (
  147. @"
  148. ╭────╮
  149. │Tab1│
  150. │ ╰►
  151. │hi │
  152. └─────┘
  153. ",
  154. output
  155. );
  156. Tab clicked = null;
  157. tv.TabClicked += (s, e) => { clicked = e.Tab; };
  158. Tab oldChanged = null;
  159. Tab newChanged = null;
  160. tv.SelectedTabChanged += (s, e) =>
  161. {
  162. oldChanged = e.OldTab;
  163. newChanged = e.NewTab;
  164. };
  165. var top = new Toplevel ();
  166. top.Add (tv);
  167. Application.Begin (top);
  168. // Click the right arrow
  169. var args = new MouseEventArgs { ScreenPosition = new (6, 2), Flags = MouseFlags.Button1Clicked };
  170. Application.RaiseMouseEvent (args);
  171. Application.LayoutAndDraw ();
  172. Assert.Null (clicked);
  173. Assert.Equal (tab1, oldChanged);
  174. Assert.Equal (tab2, newChanged);
  175. Assert.Equal (tab2, tv.SelectedTab);
  176. TestHelpers.AssertDriverContentsAre (
  177. @"
  178. ╭────╮
  179. │Tab2│
  180. ◄ ╰╮
  181. │hi2 │
  182. └─────┘
  183. ",
  184. output
  185. );
  186. // Click the left arrow
  187. args = new () { ScreenPosition = new (0, 2), Flags = MouseFlags.Button1Clicked };
  188. Application.RaiseMouseEvent (args);
  189. Application.LayoutAndDraw ();
  190. Assert.Null (clicked);
  191. Assert.Equal (tab2, oldChanged);
  192. Assert.Equal (tab1, newChanged);
  193. Assert.Equal (tab1, tv.SelectedTab);
  194. TestHelpers.AssertDriverContentsAre (
  195. @"
  196. ╭────╮
  197. │Tab1│
  198. │ ╰►
  199. │hi │
  200. └─────┘
  201. ",
  202. output
  203. );
  204. top.Dispose ();
  205. }
  206. [Fact]
  207. [AutoInitShutdown]
  208. public void MouseClick_Right_Left_Arrows_ChangesTab_With_Border ()
  209. {
  210. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  211. tv.Width = 9;
  212. tv.Height = 7;
  213. Assert.Equal (LineStyle.None, tv.BorderStyle);
  214. tv.BorderStyle = LineStyle.Single;
  215. tv.Layout ();
  216. tv.Draw ();
  217. View tabRow = tv.Subviews [0];
  218. Assert.Equal ("TabRow", tabRow.GetType ().Name);
  219. TestHelpers.AssertDriverContentsAre (
  220. @"
  221. ┌───────┐
  222. │╭────╮ │
  223. ││Tab1│ │
  224. ││ ╰►│
  225. ││hi ││
  226. │└─────┘│
  227. └───────┘
  228. ",
  229. output
  230. );
  231. Tab clicked = null;
  232. tv.TabClicked += (s, e) => { clicked = e.Tab; };
  233. Tab oldChanged = null;
  234. Tab newChanged = null;
  235. tv.SelectedTabChanged += (s, e) =>
  236. {
  237. oldChanged = e.OldTab;
  238. newChanged = e.NewTab;
  239. };
  240. var top = new Toplevel ();
  241. top.Add (tv);
  242. Application.Begin (top);
  243. // Click the right arrow
  244. var args = new MouseEventArgs { ScreenPosition = new (7, 3), Flags = MouseFlags.Button1Clicked };
  245. Application.RaiseMouseEvent (args);
  246. Application.LayoutAndDraw ();
  247. Assert.Null (clicked);
  248. Assert.Equal (tab1, oldChanged);
  249. Assert.Equal (tab2, newChanged);
  250. Assert.Equal (tab2, tv.SelectedTab);
  251. TestHelpers.AssertDriverContentsAre (
  252. @"
  253. ┌───────┐
  254. │╭────╮ │
  255. ││Tab2│ │
  256. │◄ ╰╮│
  257. ││hi2 ││
  258. │└─────┘│
  259. └───────┘
  260. ",
  261. output
  262. );
  263. // Click the left arrow
  264. args = new () { ScreenPosition = new (1, 3), Flags = MouseFlags.Button1Clicked };
  265. Application.RaiseMouseEvent (args);
  266. Application.LayoutAndDraw ();
  267. Assert.Null (clicked);
  268. Assert.Equal (tab2, oldChanged);
  269. Assert.Equal (tab1, newChanged);
  270. Assert.Equal (tab1, tv.SelectedTab);
  271. TestHelpers.AssertDriverContentsAre (
  272. @"
  273. ┌───────┐
  274. │╭────╮ │
  275. ││Tab1│ │
  276. ││ ╰►│
  277. ││hi ││
  278. │└─────┘│
  279. └───────┘
  280. ",
  281. output
  282. );
  283. top.Dispose ();
  284. }
  285. [Fact]
  286. [AutoInitShutdown]
  287. public void ProcessKey_Down_Up_Right_Left_Home_End_PageDown_PageUp_F6 ()
  288. {
  289. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  290. tv.Width = 7;
  291. tv.Height = 5;
  292. var btn = new Button
  293. {
  294. Id = "btn",
  295. Y = Pos.Bottom (tv) + 1,
  296. Height = 1,
  297. Width = 7,
  298. Text = "Ok"
  299. };
  300. Toplevel top = new ();
  301. top.Add (tv, btn);
  302. Application.Begin (top);
  303. // Is the selected tab view hosting focused
  304. Assert.Equal (tab1, tv.SelectedTab);
  305. Assert.Equal (tv, top.Focused);
  306. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  307. Assert.Equal (tv.SelectedTab.View, top.Focused.MostFocused);
  308. // Press the cursor up key to focus the selected tab
  309. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  310. Application.LayoutAndDraw ();
  311. // Is the selected tab focused
  312. Assert.Equal (tab1, tv.SelectedTab);
  313. Assert.Equal (tv, top.Focused);
  314. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  315. Tab oldChanged = null;
  316. Tab newChanged = null;
  317. tv.SelectedTabChanged += (s, e) =>
  318. {
  319. oldChanged = e.OldTab;
  320. newChanged = e.NewTab;
  321. };
  322. // Press the cursor right key to select the next tab
  323. Assert.True (Application.RaiseKeyDownEvent (Key.CursorRight));
  324. Application.LayoutAndDraw ();
  325. Assert.Equal (tab1, oldChanged);
  326. Assert.Equal (tab2, newChanged);
  327. Assert.Equal (tab2, tv.SelectedTab);
  328. Assert.Equal (tv, top.Focused);
  329. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  330. // Press the cursor down key. Since the selected tab has no focusable views, the focus should move to the next view in the toplevel
  331. Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
  332. Assert.Equal (tab2, tv.SelectedTab);
  333. Assert.Equal (btn, top.MostFocused);
  334. // Add a focusable subview to Selected Tab View which is a Label with CanFocus as false
  335. var btnSubView = new View ()
  336. {
  337. Id = "btnSubView",
  338. Title = "_Subview",
  339. CanFocus = true
  340. };
  341. tv.SelectedTab.View.Add (btnSubView);
  342. Assert.False (tv.SelectedTab.View.CanFocus);
  343. // Press cursor up. Should focus the subview in the selected tab.
  344. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  345. Assert.Equal (tab2, tv.SelectedTab);
  346. Assert.NotEqual (btnSubView, top.MostFocused);
  347. Assert.Equal (tab2, top.MostFocused);
  348. tv.SelectedTab.View.CanFocus = true;
  349. Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
  350. Assert.Equal (tab2, tv.SelectedTab);
  351. Assert.Equal (btnSubView, top.MostFocused);
  352. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  353. // TabRow now has TabGroup which only F6 is allowed
  354. Assert.NotEqual (tab2, top.MostFocused);
  355. Assert.Equal (btn, top.MostFocused);
  356. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  357. Assert.Equal (btnSubView, top.MostFocused);
  358. Assert.True (Application.RaiseKeyDownEvent (Key.F6));
  359. Assert.Equal (tab2, top.MostFocused);
  360. // Press the cursor down key twice.
  361. Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
  362. Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
  363. Assert.Equal (btn, top.MostFocused);
  364. // Press the cursor down key again will focus next view in the toplevel, which is the TabView
  365. Assert.True (Application.RaiseKeyDownEvent (Key.CursorDown));
  366. Assert.Equal (tab2, tv.SelectedTab);
  367. Assert.Equal (tv, top.Focused);
  368. // Due to the RestoreFocus method prioritize the _previouslyFocused, so btnSubView will be focused again
  369. Assert.Equal (btnSubView, tv.MostFocused);
  370. // Press the cursor up key to focus the selected tab which it's the only way to do that
  371. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  372. Assert.Equal (tab2, tv.SelectedTab);
  373. Assert.Equal (btn, top.Focused);
  374. Assert.True (Application.RaiseKeyDownEvent (Key.CursorUp));
  375. Assert.Equal (tv, top.Focused);
  376. Assert.Equal (btnSubView, top.MostFocused);
  377. Assert.True (Application.RaiseKeyDownEvent (Key.F6));
  378. Assert.Equal (tv, top.Focused);
  379. Assert.Equal (tab2, top.Focused.MostFocused);
  380. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  381. // Press the cursor left key to select the previous tab
  382. Assert.True (Application.RaiseKeyDownEvent (Key.CursorLeft));
  383. Application.LayoutAndDraw ();
  384. Assert.Equal (tab2, oldChanged);
  385. Assert.Equal (tab1, newChanged);
  386. Assert.Equal (tab1, tv.SelectedTab);
  387. Assert.Equal (tv, top.Focused);
  388. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  389. Assert.Equal (tab1, top.Focused.MostFocused);
  390. // Press the end key to select the last tab
  391. Assert.True (Application.RaiseKeyDownEvent (Key.End));
  392. Application.LayoutAndDraw ();
  393. Assert.Equal (tab1, oldChanged);
  394. Assert.Equal (tab2, newChanged);
  395. Assert.Equal (tab2, tv.SelectedTab);
  396. Assert.Equal (tv, top.Focused);
  397. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  398. // Press the home key to select the first tab
  399. Assert.True (Application.RaiseKeyDownEvent (Key.Home));
  400. Application.LayoutAndDraw ();
  401. Assert.Equal (tab2, oldChanged);
  402. Assert.Equal (tab1, newChanged);
  403. Assert.Equal (tab1, tv.SelectedTab);
  404. Assert.Equal (tv, top.Focused);
  405. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  406. // Press the page down key to select the next set of tabs
  407. Assert.True (Application.RaiseKeyDownEvent (Key.PageDown));
  408. Application.LayoutAndDraw ();
  409. Assert.Equal (tab1, oldChanged);
  410. Assert.Equal (tab2, newChanged);
  411. Assert.Equal (tab2, tv.SelectedTab);
  412. Assert.Equal (tv, top.Focused);
  413. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  414. // Press the page up key to select the previous set of tabs
  415. Assert.True (Application.RaiseKeyDownEvent (Key.PageUp));
  416. Application.LayoutAndDraw ();
  417. Assert.Equal (tab2, oldChanged);
  418. Assert.Equal (tab1, newChanged);
  419. Assert.Equal (tab1, tv.SelectedTab);
  420. Assert.Equal (tv, top.Focused);
  421. Assert.Equal (tv.MostFocused, top.Focused.MostFocused);
  422. top.Dispose ();
  423. }
  424. [Fact]
  425. public void RemoveAllTabs_ClearsSelection ()
  426. {
  427. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  428. tv.SelectedTab = tab1;
  429. tv.RemoveTab (tab1);
  430. tv.RemoveTab (tab2);
  431. Assert.Null (tv.SelectedTab);
  432. }
  433. [Fact]
  434. public void RemoveTab_ChangesSelection ()
  435. {
  436. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  437. tv.SelectedTab = tab1;
  438. tv.RemoveTab (tab1);
  439. Assert.Equal (tab2, tv.SelectedTab);
  440. }
  441. [Fact]
  442. public void RemoveTab_MultipleCalls_NotAnError ()
  443. {
  444. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  445. tv.SelectedTab = tab1;
  446. // Repeated calls to remove a tab that is not part of
  447. // the collection should be ignored
  448. tv.RemoveTab (tab1);
  449. tv.RemoveTab (tab1);
  450. tv.RemoveTab (tab1);
  451. tv.RemoveTab (tab1);
  452. Assert.Equal (tab2, tv.SelectedTab);
  453. }
  454. [Fact]
  455. public void SelectedTabChanged_Called ()
  456. {
  457. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  458. tv.SelectedTab = tab1;
  459. Tab oldTab = null;
  460. Tab newTab = null;
  461. var called = 0;
  462. tv.SelectedTabChanged += (s, e) =>
  463. {
  464. oldTab = e.OldTab;
  465. newTab = e.NewTab;
  466. called++;
  467. };
  468. tv.SelectedTab = tab2;
  469. Assert.Equal (1, called);
  470. Assert.Equal (tab1, oldTab);
  471. Assert.Equal (tab2, newTab);
  472. }
  473. [Fact]
  474. [SetupFakeDriver]
  475. public void ShowTopLine_False_TabsOnBottom_False_TestTabView_Width3 ()
  476. {
  477. TabView tv = GetTabView (out _, out _);
  478. tv.Width = 3;
  479. tv.Height = 5;
  480. tv.Style = new () { ShowTopLine = false };
  481. tv.ApplyStyleChanges ();
  482. tv.Layout ();
  483. tv.Draw ();
  484. TestHelpers.AssertDriverContentsWithFrameAre (
  485. @"
  486. ││
  487. │╰►
  488. │h│
  489. │ │
  490. └─┘",
  491. output
  492. );
  493. }
  494. [Fact]
  495. [SetupFakeDriver]
  496. public void ShowTopLine_False_TabsOnBottom_False_TestTabView_Width4 ()
  497. {
  498. TabView tv = GetTabView (out _, out _);
  499. tv.Width = 4;
  500. tv.Height = 5;
  501. tv.Style = new () { ShowTopLine = false };
  502. tv.ApplyStyleChanges ();
  503. tv.Layout ();
  504. tv.Draw ();
  505. TestHelpers.AssertDriverContentsWithFrameAre (
  506. @"
  507. │T│
  508. │ ╰►
  509. │hi│
  510. │ │
  511. └──┘",
  512. output
  513. );
  514. }
  515. [Fact]
  516. [SetupFakeDriver]
  517. public void ShowTopLine_False_TabsOnBottom_False_TestThinTabView_WithLongNames ()
  518. {
  519. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  520. tv.Width = 10;
  521. tv.Height = 5;
  522. tv.Style = new () { ShowTopLine = false };
  523. tv.ApplyStyleChanges ();
  524. // Test two tab names that fit
  525. tab1.DisplayText = "12";
  526. tab2.DisplayText = "13";
  527. // Ensures that the tab bar subview gets the bounds of the parent TabView
  528. tv.Layout ();
  529. tv.Draw ();
  530. TestHelpers.AssertDriverContentsWithFrameAre (
  531. @"
  532. │12│13│
  533. │ ╰──┴──╮
  534. │hi │
  535. │ │
  536. └────────┘",
  537. output
  538. );
  539. tv.SelectedTab = tab2;
  540. Assert.Equal (tab2, tv.Subviews.First (v => v.Id.Contains ("tabRow")).MostFocused);
  541. tv.Layout ();
  542. View.SetClipToScreen ();
  543. tv.Draw ();
  544. TestHelpers.AssertDriverContentsWithFrameAre (
  545. @"
  546. │12│13│
  547. ├──╯ ╰──╮
  548. │hi2 │
  549. │ │
  550. └────────┘",
  551. output
  552. );
  553. tv.SelectedTab = tab1;
  554. // Test first tab name too long
  555. tab1.DisplayText = "12345678910";
  556. tab2.DisplayText = "13";
  557. tv.Layout ();
  558. View.SetClipToScreen ();
  559. tv.Draw ();
  560. TestHelpers.AssertDriverContentsWithFrameAre (
  561. @"
  562. │1234567│
  563. │ ╰►
  564. │hi │
  565. │ │
  566. └────────┘",
  567. output
  568. );
  569. //switch to tab2
  570. tv.SelectedTab = tab2;
  571. tv.Layout ();
  572. View.SetClipToScreen ();
  573. tv.Draw ();
  574. TestHelpers.AssertDriverContentsWithFrameAre (
  575. @"
  576. │13│
  577. ◄ ╰─────╮
  578. │hi2 │
  579. │ │
  580. └────────┘",
  581. output
  582. );
  583. // now make both tabs too long
  584. tab1.DisplayText = "12345678910";
  585. tab2.DisplayText = "abcdefghijklmnopq";
  586. tv.Layout ();
  587. View.SetClipToScreen ();
  588. tv.Draw ();
  589. TestHelpers.AssertDriverContentsWithFrameAre (
  590. @"
  591. │abcdefg│
  592. ◄ ╰╮
  593. │hi2 │
  594. │ │
  595. └────────┘",
  596. output
  597. );
  598. }
  599. [Fact]
  600. [SetupFakeDriver]
  601. public void ShowTopLine_False_TabsOnBottom_True_TestTabView_Width3 ()
  602. {
  603. TabView tv = GetTabView (out _, out _);
  604. tv.Width = 3;
  605. tv.Height = 5;
  606. tv.Style = new () { ShowTopLine = false, TabsOnBottom = true };
  607. tv.ApplyStyleChanges ();
  608. tv.Layout ();
  609. tv.Draw ();
  610. TestHelpers.AssertDriverContentsWithFrameAre (
  611. @"
  612. ┌─┐
  613. │h│
  614. │ │
  615. │╭►
  616. ││ ",
  617. output
  618. );
  619. }
  620. [Fact]
  621. [SetupFakeDriver]
  622. public void ShowTopLine_False_TabsOnBottom_True_TestTabView_Width4 ()
  623. {
  624. TabView tv = GetTabView (out _, out _);
  625. tv.Width = 4;
  626. tv.Height = 5;
  627. tv.Style = new () { ShowTopLine = false, TabsOnBottom = true };
  628. tv.ApplyStyleChanges ();
  629. tv.Layout ();
  630. tv.Draw ();
  631. TestHelpers.AssertDriverContentsWithFrameAre (
  632. @"
  633. ┌──┐
  634. │hi│
  635. │ │
  636. │ ╭►
  637. │T│ ",
  638. output
  639. );
  640. }
  641. [Fact]
  642. [SetupFakeDriver]
  643. public void ShowTopLine_False_TabsOnBottom_True_TestThinTabView_WithLongNames ()
  644. {
  645. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  646. tv.Width = 10;
  647. tv.Height = 5;
  648. tv.Style = new () { ShowTopLine = false, TabsOnBottom = true };
  649. tv.ApplyStyleChanges ();
  650. tv.Layout ();
  651. // Test two tab names that fit
  652. tab1.DisplayText = "12";
  653. tab2.DisplayText = "13";
  654. tv.Layout ();
  655. tv.Draw ();
  656. TestHelpers.AssertDriverContentsWithFrameAre (
  657. @"
  658. ┌────────┐
  659. │hi │
  660. │ │
  661. │ ╭──┬──╯
  662. │12│13│ ",
  663. output
  664. );
  665. tv.SelectedTab = tab2;
  666. Assert.Equal (tab2, tv.Subviews.First (v => v.Id.Contains ("tabRow")).MostFocused);
  667. tv.Layout ();
  668. View.SetClipToScreen ();
  669. tv.Draw ();
  670. TestHelpers.AssertDriverContentsWithFrameAre (
  671. @"
  672. ┌────────┐
  673. │hi2 │
  674. │ │
  675. ├──╮ ╭──╯
  676. │12│13│ ",
  677. output
  678. );
  679. tv.SelectedTab = tab1;
  680. // Test first tab name too long
  681. tab1.DisplayText = "12345678910";
  682. tab2.DisplayText = "13";
  683. tv.Layout ();
  684. View.SetClipToScreen ();
  685. tv.Draw ();
  686. TestHelpers.AssertDriverContentsWithFrameAre (
  687. @"
  688. ┌────────┐
  689. │hi │
  690. │ │
  691. │ ╭►
  692. │1234567│ ",
  693. output
  694. );
  695. //switch to tab2
  696. tv.SelectedTab = tab2;
  697. tv.Layout ();
  698. View.SetClipToScreen ();
  699. tv.Draw ();
  700. TestHelpers.AssertDriverContentsWithFrameAre (
  701. @"
  702. ┌────────┐
  703. │hi2 │
  704. │ │
  705. ◄ ╭─────╯
  706. │13│ ",
  707. output
  708. );
  709. // now make both tabs too long
  710. tab1.DisplayText = "12345678910";
  711. tab2.DisplayText = "abcdefghijklmnopq";
  712. tv.Layout ();
  713. View.SetClipToScreen ();
  714. tv.Draw ();
  715. TestHelpers.AssertDriverContentsWithFrameAre (
  716. @"
  717. ┌────────┐
  718. │hi2 │
  719. │ │
  720. ◄ ╭╯
  721. │abcdefg│ ",
  722. output
  723. );
  724. }
  725. [Fact]
  726. [SetupFakeDriver]
  727. public void ShowTopLine_True_TabsOnBottom_False_TestTabView_Width3 ()
  728. {
  729. TabView tv = GetTabView (out _, out _);
  730. tv.Width = 3;
  731. tv.Height = 5;
  732. tv.Layout ();
  733. tv.Draw ();
  734. TestHelpers.AssertDriverContentsWithFrameAre (
  735. @"
  736. ╭╮
  737. ││
  738. │╰►
  739. │h│
  740. └─┘",
  741. output
  742. );
  743. }
  744. [Fact]
  745. [SetupFakeDriver]
  746. public void ShowTopLine_True_TabsOnBottom_False_TestTabView_Width4 ()
  747. {
  748. TabView tv = GetTabView (out _, out _);
  749. tv.Width = 4;
  750. tv.Height = 5;
  751. tv.Layout ();
  752. View.SetClipToScreen ();
  753. tv.Draw ();
  754. TestHelpers.AssertDriverContentsWithFrameAre (
  755. @"
  756. ╭─╮
  757. │T│
  758. │ ╰►
  759. │hi│
  760. └──┘",
  761. output
  762. );
  763. }
  764. [Fact]
  765. [SetupFakeDriver]
  766. public void ShowTopLine_True_TabsOnBottom_False_TestThinTabView_WithLongNames ()
  767. {
  768. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  769. tv.Width = 10;
  770. tv.Height = 5;
  771. // Test two tab names that fit
  772. tab1.DisplayText = "12";
  773. tab2.DisplayText = "13";
  774. tv.Layout ();
  775. tv.Draw ();
  776. TestHelpers.AssertDriverContentsWithFrameAre (
  777. @"
  778. ╭──┬──╮
  779. │12│13│
  780. │ ╰──┴──╮
  781. │hi │
  782. └────────┘",
  783. output
  784. );
  785. tv.SelectedTab = tab2;
  786. tv.Layout ();
  787. View.SetClipToScreen ();
  788. tv.Draw ();
  789. TestHelpers.AssertDriverContentsWithFrameAre (
  790. @"
  791. ╭──┬──╮
  792. │12│13│
  793. ├──╯ ╰──╮
  794. │hi2 │
  795. └────────┘",
  796. output
  797. );
  798. tv.SelectedTab = tab1;
  799. // Test first tab name too long
  800. tab1.DisplayText = "12345678910";
  801. tab2.DisplayText = "13";
  802. tv.Layout ();
  803. View.SetClipToScreen ();
  804. tv.Draw ();
  805. TestHelpers.AssertDriverContentsWithFrameAre (
  806. @"
  807. ╭───────╮
  808. │1234567│
  809. │ ╰►
  810. │hi │
  811. └────────┘",
  812. output
  813. );
  814. //switch to tab2
  815. tv.SelectedTab = tab2;
  816. tv.Layout ();
  817. View.SetClipToScreen ();
  818. tv.Draw ();
  819. TestHelpers.AssertDriverContentsWithFrameAre (
  820. @"
  821. ╭──╮
  822. │13│
  823. ◄ ╰─────╮
  824. │hi2 │
  825. └────────┘",
  826. output
  827. );
  828. // now make both tabs too long
  829. tab1.DisplayText = "12345678910";
  830. tab2.DisplayText = "abcdefghijklmnopq";
  831. tv.Layout ();
  832. View.SetClipToScreen ();
  833. tv.Draw ();
  834. TestHelpers.AssertDriverContentsWithFrameAre (
  835. @"
  836. ╭───────╮
  837. │abcdefg│
  838. ◄ ╰╮
  839. │hi2 │
  840. └────────┘",
  841. output
  842. );
  843. }
  844. [Fact]
  845. [SetupFakeDriver]
  846. public void ShowTopLine_True_TabsOnBottom_False_With_Unicode ()
  847. {
  848. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  849. tv.Width = 20;
  850. tv.Height = 5;
  851. tab1.DisplayText = "Tab0";
  852. tab2.DisplayText = "Les Mise" + char.ConvertFromUtf32 (int.Parse ("0301", NumberStyles.HexNumber)) + "rables";
  853. tv.Layout ();
  854. tv.Draw ();
  855. TestHelpers.AssertDriverContentsWithFrameAre (
  856. @"
  857. ╭────╮
  858. │Tab0│
  859. │ ╰─────────────►
  860. │hi │
  861. └──────────────────┘",
  862. output
  863. );
  864. tv.SelectedTab = tab2;
  865. tv.Layout ();
  866. View.SetClipToScreen ();
  867. tv.Draw ();
  868. TestHelpers.AssertDriverContentsWithFrameAre (
  869. @"
  870. ╭──────────────╮
  871. │Les Misérables│
  872. ◄ ╰───╮
  873. │hi2 │
  874. └──────────────────┘",
  875. output
  876. );
  877. }
  878. [Fact]
  879. [SetupFakeDriver]
  880. public void ShowTopLine_True_TabsOnBottom_True_TestTabView_Width3 ()
  881. {
  882. TabView tv = GetTabView (out _, out _);
  883. tv.Width = 3;
  884. tv.Height = 5;
  885. tv.Style = new () { TabsOnBottom = true };
  886. tv.ApplyStyleChanges ();
  887. tv.Layout ();
  888. tv.Draw ();
  889. TestHelpers.AssertDriverContentsWithFrameAre (
  890. @"
  891. ┌─┐
  892. │h│
  893. │╭►
  894. ││
  895. ╰╯ ",
  896. output
  897. );
  898. }
  899. [Fact]
  900. [SetupFakeDriver]
  901. public void ShowTopLine_True_TabsOnBottom_True_TestTabView_Width4 ()
  902. {
  903. TabView tv = GetTabView (out _, out _);
  904. tv.Width = 4;
  905. tv.Height = 5;
  906. tv.Style = new () { TabsOnBottom = true };
  907. tv.ApplyStyleChanges ();
  908. tv.Layout ();
  909. tv.Draw ();
  910. TestHelpers.AssertDriverContentsWithFrameAre (
  911. @"
  912. ┌──┐
  913. │hi│
  914. │ ╭►
  915. │T│
  916. ╰─╯ ",
  917. output
  918. );
  919. }
  920. [Fact]
  921. [SetupFakeDriver]
  922. public void ShowTopLine_True_TabsOnBottom_True_TestThinTabView_WithLongNames ()
  923. {
  924. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  925. tv.Width = 10;
  926. tv.Height = 5;
  927. tv.Style = new () { TabsOnBottom = true };
  928. tv.ApplyStyleChanges ();
  929. tv.Layout ();
  930. // Test two tab names that fit
  931. tab1.DisplayText = "12";
  932. tab2.DisplayText = "13";
  933. tv.Layout ();
  934. tv.Draw ();
  935. TestHelpers.AssertDriverContentsWithFrameAre (
  936. @"
  937. ┌────────┐
  938. │hi │
  939. │ ╭──┬──╯
  940. │12│13│
  941. ╰──┴──╯ ",
  942. output
  943. );
  944. // Test first tab name too long
  945. tab1.DisplayText = "12345678910";
  946. tab2.DisplayText = "13";
  947. tv.Layout ();
  948. View.SetClipToScreen ();
  949. tv.Draw ();
  950. TestHelpers.AssertDriverContentsWithFrameAre (
  951. @"
  952. ┌────────┐
  953. │hi │
  954. │ ╭►
  955. │1234567│
  956. ╰───────╯ ",
  957. output
  958. );
  959. //switch to tab2
  960. tv.SelectedTab = tab2;
  961. tv.Layout ();
  962. View.SetClipToScreen ();
  963. tv.Draw ();
  964. TestHelpers.AssertDriverContentsWithFrameAre (
  965. @"
  966. ┌────────┐
  967. │hi2 │
  968. ◄ ╭─────╯
  969. │13│
  970. ╰──╯ ",
  971. output
  972. );
  973. // now make both tabs too long
  974. tab1.DisplayText = "12345678910";
  975. tab2.DisplayText = "abcdefghijklmnopq";
  976. tv.Layout ();
  977. View.SetClipToScreen ();
  978. tv.Draw ();
  979. TestHelpers.AssertDriverContentsWithFrameAre (
  980. @"
  981. ┌────────┐
  982. │hi2 │
  983. ◄ ╭╯
  984. │abcdefg│
  985. ╰───────╯ ",
  986. output
  987. );
  988. }
  989. [Fact]
  990. [SetupFakeDriver]
  991. public void ShowTopLine_True_TabsOnBottom_True_With_Unicode ()
  992. {
  993. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  994. tv.Width = 20;
  995. tv.Height = 5;
  996. tv.Style = new () { TabsOnBottom = true };
  997. tv.ApplyStyleChanges ();
  998. tab1.DisplayText = "Tab0";
  999. tab2.DisplayText = "Les Mise" + char.ConvertFromUtf32 (int.Parse ("0301", NumberStyles.HexNumber)) + "rables";
  1000. tv.Layout ();
  1001. tv.Draw ();
  1002. TestHelpers.AssertDriverContentsWithFrameAre (
  1003. @"
  1004. ┌──────────────────┐
  1005. │hi │
  1006. │ ╭─────────────►
  1007. │Tab0│
  1008. ╰────╯ ",
  1009. output
  1010. );
  1011. tv.SelectedTab = tab2;
  1012. tv.Layout ();
  1013. View.SetClipToScreen ();
  1014. tv.Draw ();
  1015. TestHelpers.AssertDriverContentsWithFrameAre (
  1016. @"
  1017. ┌──────────────────┐
  1018. │hi2 │
  1019. ◄ ╭───╯
  1020. │Les Misérables│
  1021. ╰──────────────╯ ",
  1022. output
  1023. );
  1024. }
  1025. [Fact]
  1026. public void SwitchTabBy_NormalUsage ()
  1027. {
  1028. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  1029. Tab tab3;
  1030. Tab tab4;
  1031. Tab tab5;
  1032. tv.AddTab (tab3 = new (), false);
  1033. tv.AddTab (tab4 = new (), false);
  1034. tv.AddTab (tab5 = new (), false);
  1035. tv.SelectedTab = tab1;
  1036. var called = 0;
  1037. tv.SelectedTabChanged += (s, e) => { called++; };
  1038. tv.SwitchTabBy (1);
  1039. Assert.Equal (1, called);
  1040. Assert.Equal (tab2, tv.SelectedTab);
  1041. //reset called counter
  1042. called = 0;
  1043. // go right 2
  1044. tv.SwitchTabBy (2);
  1045. // even though we go right 2 indexes the event should only be called once
  1046. Assert.Equal (1, called);
  1047. Assert.Equal (tab4, tv.SelectedTab);
  1048. }
  1049. [Fact]
  1050. public void SwitchTabBy_OutOfTabsRange ()
  1051. {
  1052. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  1053. tv.SelectedTab = tab1;
  1054. tv.SwitchTabBy (500);
  1055. Assert.Equal (tab2, tv.SelectedTab);
  1056. tv.SwitchTabBy (-500);
  1057. Assert.Equal (tab1, tv.SelectedTab);
  1058. }
  1059. [Fact]
  1060. public void RemoveTab_ThatHasFocus ()
  1061. {
  1062. TabView tv = GetTabView (out Tab _, out Tab tab2);
  1063. tv.SelectedTab = tab2;
  1064. tab2.HasFocus = true;
  1065. Assert.Equal (2, tv.Tabs.Count);
  1066. foreach (Tab t in tv.Tabs.ToArray ())
  1067. {
  1068. tv.RemoveTab (t);
  1069. }
  1070. Assert.Empty (tv.Tabs);
  1071. }
  1072. [Fact]
  1073. [SetupFakeDriver]
  1074. public void Add_Three_TabsOnTop_ChangesTab ()
  1075. {
  1076. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  1077. Tab tab3;
  1078. tv.AddTab (
  1079. tab3 = new () { Id = "tab3", DisplayText = "Tab3", View = new TextView { Id = "tab3.TextView", Width = 3, Height = 1, Text = "hi3" } },
  1080. false);
  1081. tv.Width = 20;
  1082. tv.Height = 5;
  1083. tv.Layout ();
  1084. tv.Draw ();
  1085. Assert.Equal (tab1, tv.SelectedTab);
  1086. TestHelpers.AssertDriverContentsAre (
  1087. @"
  1088. ╭────┬────┬────╮
  1089. │Tab1│Tab2│Tab3│
  1090. │ ╰────┴────┴───╮
  1091. │hi │
  1092. └──────────────────┘
  1093. ",
  1094. output
  1095. );
  1096. tv.SelectedTab = tab2;
  1097. tv.Layout ();
  1098. View.SetClipToScreen ();
  1099. tv.Draw ();
  1100. TestHelpers.AssertDriverContentsWithFrameAre (
  1101. @"
  1102. ╭────┬────┬────╮
  1103. │Tab1│Tab2│Tab3│
  1104. ├────╯ ╰────┴───╮
  1105. │hi2 │
  1106. └──────────────────┘
  1107. ",
  1108. output
  1109. );
  1110. tv.SelectedTab = tab3;
  1111. tv.Layout ();
  1112. View.SetClipToScreen ();
  1113. tv.Draw ();
  1114. TestHelpers.AssertDriverContentsWithFrameAre (
  1115. @"
  1116. ╭────┬────┬────╮
  1117. │Tab1│Tab2│Tab3│
  1118. ├────┴────╯ ╰───╮
  1119. │hi3 │
  1120. └──────────────────┘
  1121. ",
  1122. output
  1123. );
  1124. }
  1125. [Fact]
  1126. [SetupFakeDriver]
  1127. public void Add_Three_TabsOnBottom_ChangesTab ()
  1128. {
  1129. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  1130. Tab tab3;
  1131. tv.AddTab (
  1132. tab3 = new () { Id = "tab3", DisplayText = "Tab3", View = new TextView { Id = "tab3.TextView", Width = 3, Height = 1, Text = "hi3" } },
  1133. false);
  1134. tv.Width = 20;
  1135. tv.Height = 5;
  1136. tv.Style = new () { TabsOnBottom = true };
  1137. tv.ApplyStyleChanges ();
  1138. tv.Layout ();
  1139. tv.Draw ();
  1140. Assert.Equal (tab1, tv.SelectedTab);
  1141. TestHelpers.AssertDriverContentsAre (
  1142. @"
  1143. ┌──────────────────┐
  1144. │hi │
  1145. │ ╭────┬────┬───╯
  1146. │Tab1│Tab2│Tab3│
  1147. ╰────┴────┴────╯
  1148. ",
  1149. output
  1150. );
  1151. tv.SelectedTab = tab2;
  1152. tv.Layout ();
  1153. View.SetClipToScreen ();
  1154. tv.Draw ();
  1155. TestHelpers.AssertDriverContentsWithFrameAre (
  1156. @"
  1157. ┌──────────────────┐
  1158. │hi2 │
  1159. ├────╮ ╭────┬───╯
  1160. │Tab1│Tab2│Tab3│
  1161. ╰────┴────┴────╯
  1162. ",
  1163. output
  1164. );
  1165. tv.SelectedTab = tab3;
  1166. tv.Layout ();
  1167. View.SetClipToScreen ();
  1168. tv.Draw ();
  1169. TestHelpers.AssertDriverContentsWithFrameAre (
  1170. @"
  1171. ┌──────────────────┐
  1172. │hi3 │
  1173. ├────┬────╮ ╭───╯
  1174. │Tab1│Tab2│Tab3│
  1175. ╰────┴────┴────╯
  1176. ",
  1177. output
  1178. );
  1179. }
  1180. [Fact]
  1181. [AutoInitShutdown]
  1182. public void Tab_Get_Focus_By_Press_F6 ()
  1183. {
  1184. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  1185. tv.Width = 20;
  1186. tv.Height = 5;
  1187. Toplevel top = new ();
  1188. top.Add (tv);
  1189. Application.Begin (top);
  1190. Assert.False (tab1.HasFocus);
  1191. Assert.True (Application.RaiseKeyDownEvent (Key.F6));
  1192. Assert.True (tab1.HasFocus);
  1193. top.Dispose ();
  1194. }
  1195. [Fact]
  1196. [SetupFakeDriver]
  1197. public void Mouse_Wheel_Changes_Tab ()
  1198. {
  1199. TabView tv = GetTabView (out Tab tab1, out Tab tab2);
  1200. tv.Width = 20;
  1201. tv.Height = 5;
  1202. Toplevel top = new ();
  1203. top.Add (tv);
  1204. Application.Begin (top);
  1205. Assert.False (tab1.HasFocus);
  1206. Application.RaiseMouseEvent (new () { Position = new (1, 1), Flags = MouseFlags.WheeledDown });
  1207. Assert.True (tab2.HasFocus);
  1208. Application.RaiseMouseEvent (new () { Position = new (1, 1), Flags = MouseFlags.WheeledUp });
  1209. Assert.True (tab1.HasFocus);
  1210. Application.RaiseMouseEvent (new () { Position = new (1, 1), Flags = MouseFlags.WheeledRight });
  1211. Assert.True (tab2.HasFocus);
  1212. Application.RaiseMouseEvent (new () { Position = new (1, 1), Flags = MouseFlags.WheeledLeft });
  1213. Assert.True (tab1.HasFocus);
  1214. top.Dispose ();
  1215. }
  1216. private TabView GetTabView () { return GetTabView (out _, out _); }
  1217. private TabView GetTabView (out Tab tab1, out Tab tab2)
  1218. {
  1219. var tv = new TabView () { Id = "tv " };
  1220. tv.BeginInit ();
  1221. tv.EndInit ();
  1222. tv.ColorScheme = new ();
  1223. tv.AddTab (
  1224. tab1 = new () { Id = "tab1", DisplayText = "Tab1", View = new TextField { Id = "tab1.TextField", Width = 2, Text = "hi" } },
  1225. false
  1226. );
  1227. tv.AddTab (tab2 = new () { Id = "tab2", DisplayText = "Tab2", View = new Label { Id = "tab1.Label", Text = "hi2" } }, false);
  1228. return tv;
  1229. }
  1230. }