DynamicMenuBar.cs 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430
  1. using System;
  2. using System.Collections.ObjectModel;
  3. using System.ComponentModel;
  4. using System.Reflection;
  5. using System.Runtime.CompilerServices;
  6. using System.Text;
  7. using Terminal.Gui;
  8. namespace UICatalog.Scenarios;
  9. [ScenarioMetadata ("Dynamic MenuBar", "Demonstrates how to change a MenuBar dynamically.")]
  10. [ScenarioCategory ("Top Level Windows")]
  11. [ScenarioCategory ("Menus")]
  12. public class DynamicMenuBar : Scenario
  13. {
  14. public override void Init ()
  15. {
  16. Application.Init ();
  17. Top = new ();
  18. Top.Add (
  19. new DynamicMenuBarSample { Title = $"{Application.QuitKey} to Quit - Scenario: {GetName ()}" }
  20. );
  21. }
  22. public class Binding
  23. {
  24. private readonly PropertyInfo _sourceBindingProperty;
  25. private readonly object _sourceDataContext;
  26. private readonly IValueConverter _valueConverter;
  27. public Binding (
  28. View source,
  29. string sourcePropertyName,
  30. View target,
  31. string targetPropertyName,
  32. IValueConverter valueConverter = null
  33. )
  34. {
  35. Target = target;
  36. Source = source;
  37. SourcePropertyName = sourcePropertyName;
  38. TargetPropertyName = targetPropertyName;
  39. _sourceDataContext = Source.GetType ().GetProperty ("DataContext").GetValue (Source);
  40. _sourceBindingProperty = _sourceDataContext.GetType ().GetProperty (SourcePropertyName);
  41. _valueConverter = valueConverter;
  42. UpdateTarget ();
  43. var notifier = (INotifyPropertyChanged)_sourceDataContext;
  44. if (notifier != null)
  45. {
  46. notifier.PropertyChanged += (s, e) =>
  47. {
  48. if (e.PropertyName == SourcePropertyName)
  49. {
  50. UpdateTarget ();
  51. }
  52. };
  53. }
  54. }
  55. public View Source { get; }
  56. public string SourcePropertyName { get; }
  57. public View Target { get; }
  58. public string TargetPropertyName { get; }
  59. private void UpdateTarget ()
  60. {
  61. try
  62. {
  63. object sourceValue = _sourceBindingProperty.GetValue (_sourceDataContext);
  64. if (sourceValue == null)
  65. {
  66. return;
  67. }
  68. object finalValue = _valueConverter?.Convert (sourceValue) ?? sourceValue;
  69. PropertyInfo targetProperty = Target.GetType ().GetProperty (TargetPropertyName);
  70. targetProperty.SetValue (Target, finalValue);
  71. }
  72. catch (Exception ex)
  73. {
  74. MessageBox.ErrorQuery ("Binding Error", $"Binding failed: {ex}.", "Ok");
  75. }
  76. }
  77. }
  78. public class DynamicMenuBarDetails : FrameView
  79. {
  80. private bool _hasParent;
  81. private MenuItem _menuItem;
  82. public DynamicMenuBarDetails (MenuItem menuItem = null, bool hasParent = false) : this ()
  83. {
  84. _menuItem = menuItem;
  85. _hasParent = hasParent;
  86. Title = menuItem == null ? "Adding New Menu." : "Editing Menu.";
  87. }
  88. public DynamicMenuBarDetails ()
  89. {
  90. var _lblTitle = new Label { Y = 1, Text = "Title:" };
  91. Add (_lblTitle);
  92. TextTitle = new() { X = Pos.Right (_lblTitle) + 2, Y = Pos.Top (_lblTitle), Width = Dim.Fill () };
  93. Add (TextTitle);
  94. var _lblHelp = new Label { X = Pos.Left (_lblTitle), Y = Pos.Bottom (_lblTitle) + 1, Text = "Help:" };
  95. Add (_lblHelp);
  96. TextHelp = new() { X = Pos.Left (TextTitle), Y = Pos.Top (_lblHelp), Width = Dim.Fill () };
  97. Add (TextHelp);
  98. var _lblAction = new Label { X = Pos.Left (_lblTitle), Y = Pos.Bottom (_lblHelp) + 1, Text = "Action:" };
  99. Add (_lblAction);
  100. TextAction = new()
  101. {
  102. X = Pos.Left (TextTitle), Y = Pos.Top (_lblAction), Width = Dim.Fill (), Height = 5
  103. };
  104. Add (TextAction);
  105. CkbIsTopLevel = new()
  106. {
  107. X = Pos.Left (_lblTitle), Y = Pos.Bottom (_lblAction) + 5, Text = "IsTopLevel"
  108. };
  109. Add (CkbIsTopLevel);
  110. CkbSubMenu = new()
  111. {
  112. X = Pos.Left (_lblTitle),
  113. Y = Pos.Bottom (CkbIsTopLevel),
  114. Checked = _menuItem == null ? !_hasParent : HasSubMenus (_menuItem),
  115. Text = "Has sub-menus"
  116. };
  117. Add (CkbSubMenu);
  118. CkbNullCheck = new()
  119. {
  120. X = Pos.Left (_lblTitle), Y = Pos.Bottom (CkbSubMenu), Text = "Allow null checked"
  121. };
  122. Add (CkbNullCheck);
  123. var _rChkLabels = new [] { "NoCheck", "Checked", "Radio" };
  124. RbChkStyle = new()
  125. {
  126. X = Pos.Left (_lblTitle), Y = Pos.Bottom (CkbSubMenu) + 1, RadioLabels = _rChkLabels
  127. };
  128. Add (RbChkStyle);
  129. var _lblShortcut = new Label
  130. {
  131. X = Pos.Right (CkbSubMenu) + 10, Y = Pos.Top (CkbSubMenu), Text = "Shortcut:"
  132. };
  133. Add (_lblShortcut);
  134. TextShortcut = new()
  135. {
  136. X = Pos.X (_lblShortcut), Y = Pos.Bottom (_lblShortcut), Width = Dim.Fill (), ReadOnly = true
  137. };
  138. TextShortcut.KeyDown += (s, e) =>
  139. {
  140. if (!ProcessKey (e))
  141. {
  142. return;
  143. }
  144. if (CheckShortcut (e.KeyCode, true))
  145. {
  146. e.Handled = true;
  147. }
  148. };
  149. bool ProcessKey (Key ev)
  150. {
  151. switch (ev.KeyCode)
  152. {
  153. case KeyCode.CursorUp:
  154. case KeyCode.CursorDown:
  155. case KeyCode.Tab:
  156. case KeyCode.Tab | KeyCode.ShiftMask:
  157. return false;
  158. }
  159. return true;
  160. }
  161. bool CheckShortcut (KeyCode k, bool pre)
  162. {
  163. MenuItem m = _menuItem != null ? _menuItem : new ();
  164. if (pre && !ShortcutHelper.PreShortcutValidation (k))
  165. {
  166. TextShortcut.Text = "";
  167. return false;
  168. }
  169. if (!pre)
  170. {
  171. if (!ShortcutHelper.PostShortcutValidation (
  172. ShortcutHelper.GetShortcutFromTag (TextShortcut.Text)
  173. ))
  174. {
  175. TextShortcut.Text = "";
  176. return false;
  177. }
  178. return true;
  179. }
  180. TextShortcut.Text =
  181. Key.ToString (
  182. k,
  183. MenuBar.ShortcutDelimiter
  184. ); // ShortcutHelper.GetShortcutTag (k);
  185. return true;
  186. }
  187. TextShortcut.KeyUp += (s, e) =>
  188. {
  189. if (CheckShortcut (e.KeyCode, false))
  190. {
  191. e.Handled = true;
  192. }
  193. };
  194. Add (TextShortcut);
  195. var _btnShortcut = new Button
  196. {
  197. X = Pos.X (_lblShortcut), Y = Pos.Bottom (TextShortcut) + 1, Text = "Clear Shortcut"
  198. };
  199. _btnShortcut.Accept += (s, e) => { TextShortcut.Text = ""; };
  200. Add (_btnShortcut);
  201. CkbIsTopLevel.Toggled += (s, e) =>
  202. {
  203. if ((_menuItem != null && _menuItem.Parent != null && (bool)CkbIsTopLevel.Checked)
  204. || (_menuItem == null && _hasParent && (bool)CkbIsTopLevel.Checked))
  205. {
  206. MessageBox.ErrorQuery (
  207. "Invalid IsTopLevel",
  208. "Only menu bar can have top level menu item!",
  209. "Ok"
  210. );
  211. CkbIsTopLevel.Checked = false;
  212. return;
  213. }
  214. if (CkbIsTopLevel.Checked == true)
  215. {
  216. CkbSubMenu.Checked = false;
  217. CkbSubMenu.SetNeedsDisplay ();
  218. TextHelp.Enabled = true;
  219. TextAction.Enabled = true;
  220. TextShortcut.Enabled =
  221. CkbIsTopLevel.Checked == false && CkbSubMenu.Checked == false;
  222. }
  223. else
  224. {
  225. if ((_menuItem == null && !_hasParent) || _menuItem.Parent == null)
  226. {
  227. CkbSubMenu.Checked = true;
  228. CkbSubMenu.SetNeedsDisplay ();
  229. TextShortcut.Enabled = false;
  230. }
  231. TextHelp.Text = "";
  232. TextHelp.Enabled = false;
  233. TextAction.Text = "";
  234. TextAction.Enabled = false;
  235. }
  236. };
  237. CkbSubMenu.Toggled += (s, e) =>
  238. {
  239. if ((bool)CkbSubMenu.Checked)
  240. {
  241. CkbIsTopLevel.Checked = false;
  242. CkbIsTopLevel.SetNeedsDisplay ();
  243. TextHelp.Text = "";
  244. TextHelp.Enabled = false;
  245. TextAction.Text = "";
  246. TextAction.Enabled = false;
  247. TextShortcut.Text = "";
  248. TextShortcut.Enabled = false;
  249. }
  250. else
  251. {
  252. if (!_hasParent)
  253. {
  254. CkbIsTopLevel.Checked = true;
  255. CkbIsTopLevel.SetNeedsDisplay ();
  256. TextShortcut.Enabled = false;
  257. }
  258. TextHelp.Enabled = true;
  259. TextAction.Enabled = true;
  260. TextShortcut.Enabled =
  261. CkbIsTopLevel.Checked == false && CkbSubMenu.Checked == false;
  262. }
  263. };
  264. CkbNullCheck.Toggled += (s, e) =>
  265. {
  266. if (_menuItem != null)
  267. {
  268. _menuItem.AllowNullChecked = (bool)CkbNullCheck.Checked;
  269. }
  270. };
  271. //Add (_frmMenuDetails);
  272. }
  273. public CheckBox CkbIsTopLevel { get; }
  274. public CheckBox CkbNullCheck { get; }
  275. public CheckBox CkbSubMenu { get; }
  276. public RadioGroup RbChkStyle { get; }
  277. public TextView TextAction { get; }
  278. public TextField TextHelp { get; }
  279. public TextField TextShortcut { get; }
  280. public TextField TextTitle { get; }
  281. public Action CreateAction (MenuItem menuItem, DynamicMenuItem item)
  282. {
  283. switch (menuItem.CheckType)
  284. {
  285. case MenuItemCheckStyle.NoCheck:
  286. return () => MessageBox.ErrorQuery (item.Title, item.Action, "Ok");
  287. case MenuItemCheckStyle.Checked:
  288. return menuItem.ToggleChecked;
  289. case MenuItemCheckStyle.Radio:
  290. break;
  291. }
  292. return () =>
  293. {
  294. menuItem.Checked = true;
  295. var parent = menuItem?.Parent as MenuBarItem;
  296. if (parent != null)
  297. {
  298. MenuItem [] childrens = parent.Children;
  299. for (var i = 0; i < childrens.Length; i++)
  300. {
  301. MenuItem child = childrens [i];
  302. if (child != menuItem)
  303. {
  304. child.Checked = false;
  305. }
  306. }
  307. }
  308. };
  309. }
  310. public void EditMenuBarItem (MenuItem menuItem)
  311. {
  312. if (menuItem == null)
  313. {
  314. _hasParent = false;
  315. Enabled = false;
  316. CleanEditMenuBarItem ();
  317. return;
  318. }
  319. _hasParent = menuItem.Parent != null;
  320. Enabled = true;
  321. _menuItem = menuItem;
  322. TextTitle.Text = menuItem?.Title ?? "";
  323. TextHelp.Text = menuItem?.Help ?? "";
  324. TextAction.Text = menuItem != null && menuItem.Action != null
  325. ? GetTargetAction (menuItem.Action)
  326. : string.Empty;
  327. CkbIsTopLevel.Checked = IsTopLevel (menuItem);
  328. CkbSubMenu.Checked = HasSubMenus (menuItem);
  329. CkbNullCheck.Checked = menuItem.AllowNullChecked;
  330. TextHelp.Enabled = (bool)!CkbSubMenu.Checked;
  331. TextAction.Enabled = (bool)!CkbSubMenu.Checked;
  332. RbChkStyle.SelectedItem = (int)(menuItem?.CheckType ?? MenuItemCheckStyle.NoCheck);
  333. TextShortcut.Text = menuItem?.ShortcutTag ?? "";
  334. TextShortcut.Enabled = CkbIsTopLevel.Checked == false && CkbSubMenu.Checked == false;
  335. }
  336. public DynamicMenuItem EnterMenuItem ()
  337. {
  338. var valid = false;
  339. if (_menuItem == null)
  340. {
  341. var m = new DynamicMenuItem ();
  342. TextTitle.Text = m.Title;
  343. TextHelp.Text = m.Help;
  344. TextAction.Text = m.Action;
  345. CkbIsTopLevel.Checked = false;
  346. CkbSubMenu.Checked = !_hasParent;
  347. CkbNullCheck.Checked = false;
  348. TextHelp.Enabled = _hasParent;
  349. TextAction.Enabled = _hasParent;
  350. TextShortcut.Enabled = _hasParent;
  351. }
  352. else
  353. {
  354. EditMenuBarItem (_menuItem);
  355. }
  356. var btnOk = new Button { IsDefault = true, Text = "Ok" };
  357. btnOk.Accept += (s, e) =>
  358. {
  359. if (string.IsNullOrEmpty (TextTitle.Text))
  360. {
  361. MessageBox.ErrorQuery ("Invalid title", "Must enter a valid title!.", "Ok");
  362. }
  363. else
  364. {
  365. valid = true;
  366. Application.RequestStop ();
  367. }
  368. };
  369. var btnCancel = new Button { Text = "Cancel" };
  370. btnCancel.Accept += (s, e) =>
  371. {
  372. TextTitle.Text = string.Empty;
  373. Application.RequestStop ();
  374. };
  375. var dialog = new Dialog { Title = "Enter the menu details.", Buttons = [btnOk, btnCancel], Height = Dim.Auto (DimAutoStyle.Content, 22, Driver.Rows) };
  376. Width = Dim.Fill ();
  377. Height = Dim.Fill () - 1;
  378. dialog.Add (this);
  379. TextTitle.SetFocus ();
  380. TextTitle.CursorPosition = TextTitle.Text.Length;
  381. Application.Run (dialog);
  382. dialog.Dispose ();
  383. if (valid)
  384. {
  385. return new()
  386. {
  387. Title = TextTitle.Text,
  388. Help = TextHelp.Text,
  389. Action = TextAction.Text,
  390. IsTopLevel = CkbIsTopLevel?.Checked ?? false,
  391. HasSubMenu = CkbSubMenu?.Checked ?? false,
  392. CheckStyle = RbChkStyle.SelectedItem == 0 ? MenuItemCheckStyle.NoCheck :
  393. RbChkStyle.SelectedItem == 1 ? MenuItemCheckStyle.Checked :
  394. MenuItemCheckStyle.Radio,
  395. Shortcut = TextShortcut.Text,
  396. AllowNullChecked = CkbNullCheck.Checked != null && (bool)CkbNullCheck.Checked
  397. };
  398. }
  399. return null;
  400. }
  401. public void UpdateParent (ref MenuItem menuItem)
  402. {
  403. var parent = menuItem.Parent as MenuBarItem;
  404. int idx = parent.GetChildrenIndex (menuItem);
  405. if (!(menuItem is MenuBarItem))
  406. {
  407. menuItem = new MenuBarItem (menuItem.Title, new MenuItem [] { }, menuItem.Parent);
  408. if (idx > -1)
  409. {
  410. parent.Children [idx] = menuItem;
  411. }
  412. }
  413. else
  414. {
  415. menuItem = new (
  416. menuItem.Title,
  417. menuItem.Help,
  418. CreateAction (menuItem, new ()),
  419. null,
  420. menuItem.Parent
  421. );
  422. if (idx > -1)
  423. {
  424. parent.Children [idx] = menuItem;
  425. }
  426. }
  427. }
  428. private void CleanEditMenuBarItem ()
  429. {
  430. TextTitle.Text = "";
  431. TextHelp.Text = "";
  432. TextAction.Text = "";
  433. CkbIsTopLevel.Checked = false;
  434. CkbSubMenu.Checked = false;
  435. RbChkStyle.SelectedItem = (int)MenuItemCheckStyle.NoCheck;
  436. TextShortcut.Text = "";
  437. }
  438. private string GetTargetAction (Action action)
  439. {
  440. object me = action.Target;
  441. if (me == null)
  442. {
  443. throw new ArgumentException ();
  444. }
  445. var v = new object ();
  446. foreach (FieldInfo field in me.GetType ().GetFields ())
  447. {
  448. if (field.Name == "item")
  449. {
  450. v = field.GetValue (me);
  451. }
  452. }
  453. return v == null || !(v is DynamicMenuItem item) ? string.Empty : item.Action;
  454. }
  455. private bool HasSubMenus (MenuItem menuItem)
  456. {
  457. var menuBarItem = menuItem as MenuBarItem;
  458. if (menuBarItem != null && menuBarItem.Children != null && (menuBarItem.Children.Length > 0 || menuBarItem.Action == null))
  459. {
  460. return true;
  461. }
  462. return false;
  463. }
  464. private bool IsTopLevel (MenuItem menuItem)
  465. {
  466. var topLevel = menuItem as MenuBarItem;
  467. if (topLevel != null && topLevel.Parent == null && (topLevel.Children == null || topLevel.Children.Length == 0) && topLevel.Action != null)
  468. {
  469. return true;
  470. }
  471. return false;
  472. }
  473. }
  474. public class DynamicMenuBarSample : Window
  475. {
  476. private readonly ListView _lstMenus;
  477. private MenuItem _currentEditMenuBarItem;
  478. private MenuItem _currentMenuBarItem;
  479. private int _currentSelectedMenuBar;
  480. private MenuBar _menuBar;
  481. public DynamicMenuBarSample ()
  482. {
  483. DataContext = new ();
  484. var _frmDelimiter = new FrameView
  485. {
  486. X = Pos.Center (),
  487. Y = 3,
  488. Width = 25,
  489. Height = 4,
  490. Title = "Shortcut Delimiter:"
  491. };
  492. var _txtDelimiter = new TextField
  493. {
  494. X = Pos.Center (), Width = 2, Text = MenuBar.ShortcutDelimiter.ToString ()
  495. };
  496. _txtDelimiter.TextChanged += (s, _) =>
  497. MenuBar.ShortcutDelimiter = _txtDelimiter.Text.ToRunes () [0];
  498. _frmDelimiter.Add (_txtDelimiter);
  499. Add (_frmDelimiter);
  500. var _frmMenu = new FrameView { Y = 7, Width = Dim.Percent (50), Height = Dim.Fill (), Title = "Menus:" };
  501. var _btnAddMenuBar = new Button { Y = 1, Text = "Add a MenuBar" };
  502. _frmMenu.Add (_btnAddMenuBar);
  503. var _btnMenuBarUp = new Button { X = Pos.Center (), Text = CM.Glyphs.UpArrow.ToString () };
  504. _frmMenu.Add (_btnMenuBarUp);
  505. var _btnMenuBarDown = new Button { X = Pos.Center (), Y = Pos.Bottom (_btnMenuBarUp), Text = CM.Glyphs.DownArrow.ToString () };
  506. _frmMenu.Add (_btnMenuBarDown);
  507. var _btnRemoveMenuBar = new Button { Y = 1, Text = "Remove a MenuBar" };
  508. _btnRemoveMenuBar.X = Pos.AnchorEnd (0) - (Pos.Right (_btnRemoveMenuBar) - Pos.Left (_btnRemoveMenuBar));
  509. _frmMenu.Add (_btnRemoveMenuBar);
  510. var _btnPrevious = new Button
  511. {
  512. X = Pos.Left (_btnAddMenuBar), Y = Pos.Top (_btnAddMenuBar) + 2, Text = CM.Glyphs.LeftArrow.ToString ()
  513. };
  514. _frmMenu.Add (_btnPrevious);
  515. var _btnAdd = new Button { Y = Pos.Top (_btnPrevious) + 2, Text = " Add " };
  516. _btnAdd.X = Pos.AnchorEnd ();
  517. _frmMenu.Add (_btnAdd);
  518. var _btnNext = new Button { X = Pos.X (_btnAdd), Y = Pos.Top (_btnPrevious), Text = CM.Glyphs.RightArrow.ToString () };
  519. _frmMenu.Add (_btnNext);
  520. var _lblMenuBar = new Label
  521. {
  522. ColorScheme = Colors.ColorSchemes ["Dialog"],
  523. TextAlignment = Alignment.Center,
  524. X = Pos.Right (_btnPrevious) + 1,
  525. Y = Pos.Top (_btnPrevious),
  526. Width = Dim.Fill () - Dim.Func (() => _btnAdd.Frame.Width + 1),
  527. Height = 1
  528. };
  529. _frmMenu.Add (_lblMenuBar);
  530. _lblMenuBar.WantMousePositionReports = true;
  531. _lblMenuBar.CanFocus = true;
  532. var _lblParent = new Label
  533. {
  534. TextAlignment = Alignment.Center,
  535. X = Pos.Right (_btnPrevious) + 1,
  536. Y = Pos.Top (_btnPrevious) + 1,
  537. Width = Dim.Fill () - Dim.Width (_btnAdd) - 1
  538. };
  539. _frmMenu.Add (_lblParent);
  540. var _btnPreviowsParent = new Button
  541. {
  542. X = Pos.Left (_btnAddMenuBar), Y = Pos.Top (_btnPrevious) + 1, Text = ".."
  543. };
  544. _frmMenu.Add (_btnPreviowsParent);
  545. _lstMenus = new()
  546. {
  547. ColorScheme = Colors.ColorSchemes ["Dialog"],
  548. X = Pos.Right (_btnPrevious) + 1,
  549. Y = Pos.Top (_btnPrevious) + 2,
  550. Width = _lblMenuBar.Width,
  551. Height = Dim.Fill (),
  552. Source = new ListWrapper<DynamicMenuItemList> ([])
  553. };
  554. _frmMenu.Add (_lstMenus);
  555. _lblMenuBar.TabIndex = _btnPrevious.TabIndex + 1;
  556. _lstMenus.TabIndex = _lblMenuBar.TabIndex + 1;
  557. _btnNext.TabIndex = _lstMenus.TabIndex + 1;
  558. _btnAdd.TabIndex = _btnNext.TabIndex + 1;
  559. var _btnRemove = new Button { X = Pos.Left (_btnAdd), Y = Pos.Top (_btnAdd) + 1, Text = "Remove" };
  560. _frmMenu.Add (_btnRemove);
  561. var _btnUp = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (_btnRemove) + 2, Text = CM.Glyphs.UpArrow.ToString () };
  562. _frmMenu.Add (_btnUp);
  563. var _btnDown = new Button { X = Pos.Right (_lstMenus) + 2, Y = Pos.Top (_btnUp) + 1, Text = CM.Glyphs.DownArrow.ToString () };
  564. _frmMenu.Add (_btnDown);
  565. Add (_frmMenu);
  566. var _frmMenuDetails = new DynamicMenuBarDetails
  567. {
  568. X = Pos.Right (_frmMenu),
  569. Y = Pos.Top (_frmMenu),
  570. Width = Dim.Fill (),
  571. Height = Dim.Fill (2),
  572. Title = "Menu Details:"
  573. };
  574. Add (_frmMenuDetails);
  575. _btnMenuBarUp.Accept += (s, e) =>
  576. {
  577. int i = _currentSelectedMenuBar;
  578. MenuBarItem menuItem = _menuBar != null && _menuBar.Menus.Length > 0
  579. ? _menuBar.Menus [i]
  580. : null;
  581. if (menuItem != null)
  582. {
  583. MenuBarItem [] menus = _menuBar.Menus;
  584. if (i > 0)
  585. {
  586. menus [i] = menus [i - 1];
  587. menus [i - 1] = menuItem;
  588. _currentSelectedMenuBar = i - 1;
  589. _menuBar.SetNeedsDisplay ();
  590. }
  591. }
  592. };
  593. _btnMenuBarDown.Accept += (s, e) =>
  594. {
  595. int i = _currentSelectedMenuBar;
  596. MenuBarItem menuItem = _menuBar != null && _menuBar.Menus.Length > 0
  597. ? _menuBar.Menus [i]
  598. : null;
  599. if (menuItem != null)
  600. {
  601. MenuBarItem [] menus = _menuBar.Menus;
  602. if (i < menus.Length - 1)
  603. {
  604. menus [i] = menus [i + 1];
  605. menus [i + 1] = menuItem;
  606. _currentSelectedMenuBar = i + 1;
  607. _menuBar.SetNeedsDisplay ();
  608. }
  609. }
  610. };
  611. _btnUp.Accept += (s, e) =>
  612. {
  613. int i = _lstMenus.SelectedItem;
  614. MenuItem menuItem = DataContext.Menus.Count > 0 ? DataContext.Menus [i].MenuItem : null;
  615. if (menuItem != null)
  616. {
  617. MenuItem [] childrens = ((MenuBarItem)_currentMenuBarItem).Children;
  618. if (i > 0)
  619. {
  620. childrens [i] = childrens [i - 1];
  621. childrens [i - 1] = menuItem;
  622. DataContext.Menus [i] = DataContext.Menus [i - 1];
  623. DataContext.Menus [i - 1] =
  624. new() { Title = menuItem.Title, MenuItem = menuItem };
  625. _lstMenus.SelectedItem = i - 1;
  626. }
  627. }
  628. };
  629. _btnDown.Accept += (s, e) =>
  630. {
  631. int i = _lstMenus.SelectedItem;
  632. MenuItem menuItem = DataContext.Menus.Count > 0 ? DataContext.Menus [i].MenuItem : null;
  633. if (menuItem != null)
  634. {
  635. MenuItem [] childrens = ((MenuBarItem)_currentMenuBarItem).Children;
  636. if (i < childrens.Length - 1)
  637. {
  638. childrens [i] = childrens [i + 1];
  639. childrens [i + 1] = menuItem;
  640. DataContext.Menus [i] = DataContext.Menus [i + 1];
  641. DataContext.Menus [i + 1] =
  642. new() { Title = menuItem.Title, MenuItem = menuItem };
  643. _lstMenus.SelectedItem = i + 1;
  644. }
  645. }
  646. };
  647. _btnPreviowsParent.Accept += (s, e) =>
  648. {
  649. if (_currentMenuBarItem != null && _currentMenuBarItem.Parent != null)
  650. {
  651. MenuItem mi = _currentMenuBarItem;
  652. _currentMenuBarItem = _currentMenuBarItem.Parent as MenuBarItem;
  653. SetListViewSource (_currentMenuBarItem, true);
  654. int i = ((MenuBarItem)_currentMenuBarItem).GetChildrenIndex (mi);
  655. if (i > -1)
  656. {
  657. _lstMenus.SelectedItem = i;
  658. }
  659. if (_currentMenuBarItem.Parent != null)
  660. {
  661. DataContext.Parent = _currentMenuBarItem.Title;
  662. }
  663. else
  664. {
  665. DataContext.Parent = string.Empty;
  666. }
  667. }
  668. else
  669. {
  670. DataContext.Parent = string.Empty;
  671. }
  672. };
  673. var _btnOk = new Button { X = Pos.Right (_frmMenu) + 20, Y = Pos.Bottom (_frmMenuDetails), Text = "Ok" };
  674. Add (_btnOk);
  675. var _btnCancel = new Button { X = Pos.Right (_btnOk) + 3, Y = Pos.Top (_btnOk), Text = "Cancel" };
  676. _btnCancel.Accept += (s, e) => { SetFrameDetails (_currentEditMenuBarItem); };
  677. Add (_btnCancel);
  678. _lstMenus.SelectedItemChanged += (s, e) => { SetFrameDetails (); };
  679. _btnOk.Accept += (s, e) =>
  680. {
  681. if (string.IsNullOrEmpty (_frmMenuDetails.TextTitle.Text) && _currentEditMenuBarItem != null)
  682. {
  683. MessageBox.ErrorQuery ("Invalid title", "Must enter a valid title!.", "Ok");
  684. }
  685. else if (_currentEditMenuBarItem != null)
  686. {
  687. var menuItem = new DynamicMenuItem
  688. {
  689. Title = _frmMenuDetails.TextTitle.Text,
  690. Help = _frmMenuDetails.TextHelp.Text,
  691. Action = _frmMenuDetails.TextAction.Text,
  692. IsTopLevel = _frmMenuDetails.CkbIsTopLevel?.Checked ?? false,
  693. HasSubMenu = _frmMenuDetails.CkbSubMenu?.Checked ?? false,
  694. CheckStyle = _frmMenuDetails.RbChkStyle.SelectedItem == 0
  695. ? MenuItemCheckStyle.NoCheck
  696. : _frmMenuDetails.RbChkStyle.SelectedItem == 1
  697. ? MenuItemCheckStyle.Checked
  698. : MenuItemCheckStyle.Radio,
  699. Shortcut = _frmMenuDetails.TextShortcut.Text
  700. };
  701. UpdateMenuItem (_currentEditMenuBarItem, menuItem, _lstMenus.SelectedItem);
  702. }
  703. };
  704. _btnAdd.Accept += (s, e) =>
  705. {
  706. if (MenuBar == null)
  707. {
  708. MessageBox.ErrorQuery ("Menu Bar Error", "Must add a MenuBar first!", "Ok");
  709. _btnAddMenuBar.SetFocus ();
  710. return;
  711. }
  712. var frameDetails = new DynamicMenuBarDetails (null, _currentMenuBarItem != null);
  713. DynamicMenuItem item = frameDetails.EnterMenuItem ();
  714. if (item == null)
  715. {
  716. return;
  717. }
  718. if (_currentMenuBarItem is not MenuBarItem)
  719. {
  720. var parent = _currentMenuBarItem.Parent as MenuBarItem;
  721. int idx = parent.GetChildrenIndex (_currentMenuBarItem);
  722. _currentMenuBarItem = new MenuBarItem (
  723. _currentMenuBarItem.Title,
  724. new MenuItem [] { },
  725. _currentMenuBarItem.Parent
  726. );
  727. _currentMenuBarItem.CheckType = item.CheckStyle;
  728. parent.Children [idx] = _currentMenuBarItem;
  729. }
  730. else
  731. {
  732. MenuItem newMenu = CreateNewMenu (item, _currentMenuBarItem);
  733. var menuBarItem = _currentMenuBarItem as MenuBarItem;
  734. if (menuBarItem == null)
  735. {
  736. menuBarItem = new (
  737. _currentMenuBarItem.Title,
  738. new [] { newMenu },
  739. _currentMenuBarItem.Parent
  740. );
  741. }
  742. else if (menuBarItem.Children == null)
  743. {
  744. menuBarItem.Children = new [] { newMenu };
  745. }
  746. else
  747. {
  748. MenuItem [] childrens = menuBarItem.Children;
  749. Array.Resize (ref childrens, childrens.Length + 1);
  750. childrens [childrens.Length - 1] = newMenu;
  751. menuBarItem.Children = childrens;
  752. }
  753. DataContext.Menus.Add (new() { Title = newMenu.Title, MenuItem = newMenu });
  754. _lstMenus.MoveDown ();
  755. }
  756. };
  757. _btnRemove.Accept += (s, e) =>
  758. {
  759. MenuItem menuItem = DataContext.Menus.Count > 0
  760. ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
  761. : null;
  762. if (menuItem != null)
  763. {
  764. MenuItem [] childrens = ((MenuBarItem)_currentMenuBarItem).Children;
  765. childrens [_lstMenus.SelectedItem] = null;
  766. var i = 0;
  767. foreach (MenuItem c in childrens)
  768. {
  769. if (c != null)
  770. {
  771. childrens [i] = c;
  772. i++;
  773. }
  774. }
  775. Array.Resize (ref childrens, childrens.Length - 1);
  776. if (childrens.Length == 0)
  777. {
  778. if (_currentMenuBarItem.Parent == null)
  779. {
  780. ((MenuBarItem)_currentMenuBarItem).Children = null;
  781. //_currentMenuBarItem.Action = _frmMenuDetails.CreateAction (_currentEditMenuBarItem, new DynamicMenuItem (_currentMenuBarItem.Title));
  782. }
  783. else
  784. {
  785. _currentMenuBarItem = new (
  786. _currentMenuBarItem.Title,
  787. _currentMenuBarItem.Help,
  788. _frmMenuDetails.CreateAction (
  789. _currentEditMenuBarItem,
  790. new()
  791. {
  792. Title = _currentEditMenuBarItem
  793. .Title
  794. }
  795. ),
  796. null,
  797. _currentMenuBarItem.Parent
  798. );
  799. }
  800. }
  801. else
  802. {
  803. ((MenuBarItem)_currentMenuBarItem).Children = childrens;
  804. }
  805. DataContext.Menus.RemoveAt (_lstMenus.SelectedItem);
  806. if (_lstMenus.Source.Count > 0 && _lstMenus.SelectedItem > _lstMenus.Source.Count - 1)
  807. {
  808. _lstMenus.SelectedItem = _lstMenus.Source.Count - 1;
  809. }
  810. _lstMenus.SetNeedsDisplay ();
  811. SetFrameDetails ();
  812. }
  813. };
  814. _lstMenus.OpenSelectedItem += (s, e) =>
  815. {
  816. _currentMenuBarItem = DataContext.Menus [e.Item].MenuItem;
  817. if (!(_currentMenuBarItem is MenuBarItem))
  818. {
  819. MessageBox.ErrorQuery ("Menu Open Error", "Must allows sub menus first!", "Ok");
  820. return;
  821. }
  822. DataContext.Parent = _currentMenuBarItem.Title;
  823. DataContext.Menus = new ();
  824. SetListViewSource (_currentMenuBarItem, true);
  825. MenuItem menuBarItem = DataContext.Menus.Count > 0 ? DataContext.Menus [0].MenuItem : null;
  826. SetFrameDetails (menuBarItem);
  827. };
  828. _lstMenus.Enter += (s, e) =>
  829. {
  830. MenuItem menuBarItem = _lstMenus.SelectedItem > -1 && DataContext.Menus.Count > 0
  831. ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
  832. : null;
  833. SetFrameDetails (menuBarItem);
  834. };
  835. _btnNext.Accept += (s, e) =>
  836. {
  837. if (_menuBar != null && _currentSelectedMenuBar + 1 < _menuBar.Menus.Length)
  838. {
  839. _currentSelectedMenuBar++;
  840. }
  841. SelectCurrentMenuBarItem ();
  842. };
  843. _btnPrevious.Accept += (s, e) =>
  844. {
  845. if (_currentSelectedMenuBar - 1 > -1)
  846. {
  847. _currentSelectedMenuBar--;
  848. }
  849. SelectCurrentMenuBarItem ();
  850. };
  851. _lblMenuBar.Enter += (s, e) =>
  852. {
  853. if (_menuBar?.Menus != null)
  854. {
  855. _currentMenuBarItem = _menuBar.Menus [_currentSelectedMenuBar];
  856. SetFrameDetails (_menuBar.Menus [_currentSelectedMenuBar]);
  857. }
  858. };
  859. _btnAddMenuBar.Accept += (s, e) =>
  860. {
  861. var frameDetails = new DynamicMenuBarDetails (null);
  862. DynamicMenuItem item = frameDetails.EnterMenuItem ();
  863. if (item == null)
  864. {
  865. return;
  866. }
  867. if (MenuBar == null)
  868. {
  869. _menuBar = new ();
  870. Add (_menuBar);
  871. }
  872. var newMenu = CreateNewMenu (item) as MenuBarItem;
  873. MenuBarItem [] menus = _menuBar.Menus;
  874. Array.Resize (ref menus, menus.Length + 1);
  875. menus [^1] = newMenu;
  876. _menuBar.Menus = menus;
  877. _currentMenuBarItem = newMenu;
  878. _currentMenuBarItem.CheckType = item.CheckStyle;
  879. _currentSelectedMenuBar = menus.Length - 1;
  880. _menuBar.Menus [_currentSelectedMenuBar] = newMenu;
  881. _lblMenuBar.Text = newMenu.Title;
  882. SetListViewSource (_currentMenuBarItem, true);
  883. SetFrameDetails (_menuBar.Menus [_currentSelectedMenuBar]);
  884. _menuBar.SetNeedsDisplay ();
  885. };
  886. _btnRemoveMenuBar.Accept += (s, e) =>
  887. {
  888. if (_menuBar == null || _menuBar.Menus.Length == 0)
  889. {
  890. return;
  891. }
  892. if (_menuBar != null && _menuBar.Menus.Length > 0)
  893. {
  894. _menuBar.Menus [_currentSelectedMenuBar] = null;
  895. var i = 0;
  896. foreach (MenuBarItem m in _menuBar.Menus)
  897. {
  898. if (m != null)
  899. {
  900. _menuBar.Menus [i] = m;
  901. i++;
  902. }
  903. }
  904. MenuBarItem [] menus = _menuBar.Menus;
  905. Array.Resize (ref menus, menus.Length - 1);
  906. _menuBar.Menus = menus;
  907. if (_currentSelectedMenuBar - 1 >= 0 && _menuBar.Menus.Length > 0)
  908. {
  909. _currentSelectedMenuBar--;
  910. }
  911. _currentMenuBarItem = _menuBar.Menus?.Length > 0
  912. ? _menuBar.Menus [_currentSelectedMenuBar]
  913. : null;
  914. }
  915. if (MenuBar != null && _currentMenuBarItem == null && _menuBar.Menus.Length == 0)
  916. {
  917. Remove (_menuBar);
  918. _menuBar = null;
  919. DataContext.Menus = new ();
  920. _currentMenuBarItem = null;
  921. _currentSelectedMenuBar = -1;
  922. _lblMenuBar.Text = string.Empty;
  923. }
  924. else
  925. {
  926. _lblMenuBar.Text = _menuBar.Menus [_currentSelectedMenuBar].Title;
  927. }
  928. SetListViewSource (_currentMenuBarItem, true);
  929. SetFrameDetails ();
  930. };
  931. SetFrameDetails ();
  932. var ustringConverter = new UStringValueConverter ();
  933. var listWrapperConverter = new ListWrapperConverter<DynamicMenuItemList> ();
  934. var lblMenuBar = new Binding (this, "MenuBar", _lblMenuBar, "Text", ustringConverter);
  935. var lblParent = new Binding (this, "Parent", _lblParent, "Text", ustringConverter);
  936. var lstMenus = new Binding (this, "Menus", _lstMenus, "Source", listWrapperConverter);
  937. void SetFrameDetails (MenuItem menuBarItem = null)
  938. {
  939. MenuItem menuItem;
  940. if (menuBarItem == null)
  941. {
  942. menuItem = _lstMenus.SelectedItem > -1 && DataContext.Menus.Count > 0
  943. ? DataContext.Menus [_lstMenus.SelectedItem].MenuItem
  944. : null;
  945. }
  946. else
  947. {
  948. menuItem = menuBarItem;
  949. }
  950. _currentEditMenuBarItem = menuItem;
  951. _frmMenuDetails.EditMenuBarItem (menuItem);
  952. bool f = _btnOk.Enabled == _frmMenuDetails.Enabled;
  953. if (!f)
  954. {
  955. _btnOk.Enabled = _frmMenuDetails.Enabled;
  956. _btnCancel.Enabled = _frmMenuDetails.Enabled;
  957. }
  958. }
  959. void SelectCurrentMenuBarItem ()
  960. {
  961. MenuBarItem menuBarItem = null;
  962. if (_menuBar?.Menus != null)
  963. {
  964. menuBarItem = _menuBar.Menus [_currentSelectedMenuBar];
  965. _lblMenuBar.Text = menuBarItem.Title;
  966. }
  967. SetFrameDetails (menuBarItem);
  968. _currentMenuBarItem = menuBarItem;
  969. DataContext.Menus = new ();
  970. SetListViewSource (_currentMenuBarItem, true);
  971. _lblParent.Text = string.Empty;
  972. }
  973. void SetListViewSource (MenuItem _currentMenuBarItem, bool fill = false)
  974. {
  975. DataContext.Menus = [];
  976. var menuBarItem = _currentMenuBarItem as MenuBarItem;
  977. if (menuBarItem != null && menuBarItem?.Children == null)
  978. {
  979. return;
  980. }
  981. if (!fill)
  982. {
  983. return;
  984. }
  985. if (menuBarItem != null)
  986. {
  987. foreach (MenuItem child in menuBarItem?.Children)
  988. {
  989. var m = new DynamicMenuItemList { Title = child.Title, MenuItem = child };
  990. DataContext.Menus.Add (m);
  991. }
  992. }
  993. }
  994. MenuItem CreateNewMenu (DynamicMenuItem item, MenuItem parent = null)
  995. {
  996. MenuItem newMenu;
  997. if (item.HasSubMenu)
  998. {
  999. newMenu = new MenuBarItem (item.Title, new MenuItem [] { }, parent);
  1000. }
  1001. else if (parent != null)
  1002. {
  1003. newMenu = new (item.Title, item.Help, null, null, parent);
  1004. newMenu.CheckType = item.CheckStyle;
  1005. newMenu.Action = _frmMenuDetails.CreateAction (newMenu, item);
  1006. newMenu.Shortcut = ShortcutHelper.GetShortcutFromTag (item.Shortcut);
  1007. newMenu.AllowNullChecked = item.AllowNullChecked;
  1008. }
  1009. else if (item.IsTopLevel)
  1010. {
  1011. newMenu = new MenuBarItem (item.Title, item.Help, null);
  1012. newMenu.Action = _frmMenuDetails.CreateAction (newMenu, item);
  1013. }
  1014. else
  1015. {
  1016. newMenu = new MenuBarItem (item.Title, item.Help, null);
  1017. ((MenuBarItem)newMenu).Children [0].Action =
  1018. _frmMenuDetails.CreateAction (newMenu, item);
  1019. ((MenuBarItem)newMenu).Children [0].Shortcut =
  1020. ShortcutHelper.GetShortcutFromTag (item.Shortcut);
  1021. }
  1022. return newMenu;
  1023. }
  1024. void UpdateMenuItem (MenuItem _currentEditMenuBarItem, DynamicMenuItem menuItem, int index)
  1025. {
  1026. _currentEditMenuBarItem.Title = menuItem.Title;
  1027. _currentEditMenuBarItem.Help = menuItem.Help;
  1028. _currentEditMenuBarItem.CheckType = menuItem.CheckStyle;
  1029. var parent = _currentEditMenuBarItem.Parent as MenuBarItem;
  1030. if (parent != null && parent.Children.Length == 1 && _currentEditMenuBarItem.CheckType == MenuItemCheckStyle.Radio)
  1031. {
  1032. _currentEditMenuBarItem.Checked = true;
  1033. }
  1034. if (menuItem.IsTopLevel && _currentEditMenuBarItem is MenuBarItem)
  1035. {
  1036. ((MenuBarItem)_currentEditMenuBarItem).Children = null;
  1037. _currentEditMenuBarItem.Action =
  1038. _frmMenuDetails.CreateAction (_currentEditMenuBarItem, menuItem);
  1039. SetListViewSource (_currentEditMenuBarItem, true);
  1040. }
  1041. else if (menuItem.HasSubMenu)
  1042. {
  1043. _currentEditMenuBarItem.Action = null;
  1044. if (_currentEditMenuBarItem is MenuBarItem && ((MenuBarItem)_currentEditMenuBarItem).Children == null)
  1045. {
  1046. ((MenuBarItem)_currentEditMenuBarItem).Children = new MenuItem [] { };
  1047. }
  1048. else if (_currentEditMenuBarItem.Parent != null)
  1049. {
  1050. _frmMenuDetails.UpdateParent (ref _currentEditMenuBarItem);
  1051. }
  1052. else
  1053. {
  1054. _currentEditMenuBarItem =
  1055. new MenuBarItem (
  1056. _currentEditMenuBarItem.Title,
  1057. new MenuItem [] { },
  1058. _currentEditMenuBarItem.Parent
  1059. );
  1060. }
  1061. SetListViewSource (_currentEditMenuBarItem, true);
  1062. }
  1063. else if (_currentEditMenuBarItem is MenuBarItem && _currentEditMenuBarItem.Parent != null)
  1064. {
  1065. _frmMenuDetails.UpdateParent (ref _currentEditMenuBarItem);
  1066. _currentEditMenuBarItem = new (
  1067. menuItem.Title,
  1068. menuItem.Help,
  1069. _frmMenuDetails.CreateAction (_currentEditMenuBarItem, menuItem),
  1070. null,
  1071. _currentEditMenuBarItem.Parent
  1072. );
  1073. }
  1074. else
  1075. {
  1076. if (_currentEditMenuBarItem is MenuBarItem)
  1077. {
  1078. ((MenuBarItem)_currentEditMenuBarItem).Children = null;
  1079. DataContext.Menus = new ();
  1080. }
  1081. _currentEditMenuBarItem.Action =
  1082. _frmMenuDetails.CreateAction (_currentEditMenuBarItem, menuItem);
  1083. _currentEditMenuBarItem.Shortcut =
  1084. ShortcutHelper.GetShortcutFromTag (menuItem.Shortcut);
  1085. }
  1086. if (_currentEditMenuBarItem.Parent == null)
  1087. {
  1088. DataContext.MenuBar = _currentEditMenuBarItem.Title;
  1089. }
  1090. else
  1091. {
  1092. if (DataContext.Menus.Count == 0)
  1093. {
  1094. DataContext.Menus.Add (
  1095. new()
  1096. {
  1097. Title = _currentEditMenuBarItem.Title, MenuItem = _currentEditMenuBarItem
  1098. }
  1099. );
  1100. }
  1101. DataContext.Menus [index] =
  1102. new()
  1103. {
  1104. Title = _currentEditMenuBarItem.Title, MenuItem = _currentEditMenuBarItem
  1105. };
  1106. }
  1107. _currentEditMenuBarItem.CheckType = menuItem.CheckStyle;
  1108. SetFrameDetails (_currentEditMenuBarItem);
  1109. }
  1110. //_frmMenuDetails.Initialized += (s, e) => _frmMenuDetails.Enabled = false;
  1111. }
  1112. public DynamicMenuItemModel DataContext { get; set; }
  1113. }
  1114. public class DynamicMenuItem
  1115. {
  1116. public string Action { get; set; } = string.Empty;
  1117. public bool AllowNullChecked { get; set; }
  1118. public MenuItemCheckStyle CheckStyle { get; set; }
  1119. public bool HasSubMenu { get; set; }
  1120. public string Help { get; set; } = string.Empty;
  1121. public bool IsTopLevel { get; set; }
  1122. public string Shortcut { get; set; }
  1123. public string Title { get; set; } = "_New";
  1124. }
  1125. public class DynamicMenuItemList
  1126. {
  1127. public MenuItem MenuItem { get; set; }
  1128. public string Title { get; set; }
  1129. public override string ToString () { return $"{Title}, {MenuItem}"; }
  1130. }
  1131. public class DynamicMenuItemModel : INotifyPropertyChanged
  1132. {
  1133. private string _menuBar;
  1134. private ObservableCollection<DynamicMenuItemList> _menus;
  1135. private string _parent;
  1136. public DynamicMenuItemModel () { Menus = []; }
  1137. public string MenuBar
  1138. {
  1139. get => _menuBar;
  1140. set
  1141. {
  1142. if (value == _menuBar)
  1143. {
  1144. return;
  1145. }
  1146. _menuBar = value;
  1147. PropertyChanged?.Invoke (
  1148. this,
  1149. new (GetPropertyName ())
  1150. );
  1151. }
  1152. }
  1153. public ObservableCollection<DynamicMenuItemList> Menus
  1154. {
  1155. get => _menus;
  1156. set
  1157. {
  1158. if (value == _menus)
  1159. {
  1160. return;
  1161. }
  1162. _menus = value;
  1163. PropertyChanged?.Invoke (
  1164. this,
  1165. new (GetPropertyName ())
  1166. );
  1167. }
  1168. }
  1169. public string Parent
  1170. {
  1171. get => _parent;
  1172. set
  1173. {
  1174. if (value == _parent)
  1175. {
  1176. return;
  1177. }
  1178. _parent = value;
  1179. PropertyChanged?.Invoke (
  1180. this,
  1181. new (GetPropertyName ())
  1182. );
  1183. }
  1184. }
  1185. public event PropertyChangedEventHandler PropertyChanged;
  1186. public string GetPropertyName ([CallerMemberName] string propertyName = null) { return propertyName; }
  1187. }
  1188. public interface IValueConverter
  1189. {
  1190. object Convert (object value, object parameter = null);
  1191. }
  1192. public class ListWrapperConverter<T> : IValueConverter
  1193. {
  1194. public object Convert (object value, object parameter = null) { return new ListWrapper<T> ((ObservableCollection<T>)value); }
  1195. }
  1196. public class UStringValueConverter : IValueConverter
  1197. {
  1198. public object Convert (object value, object parameter = null)
  1199. {
  1200. byte [] data = Encoding.ASCII.GetBytes (value.ToString () ?? string.Empty);
  1201. return StringExtensions.ToString (data);
  1202. }
  1203. }
  1204. }