DynamicMenuBar.cs 61 KB

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