TabViewTests.cs 44 KB

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