Program.fs 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. open System
  2. open System.Diagnostics
  3. open System.Globalization
  4. open System.IO
  5. open NStack
  6. open Terminal.Gui
  7. let ustr (x: string) = ustring.Make(x)
  8. let mutable ml2 = Unchecked.defaultof<Label>
  9. let mutable ml = Unchecked.defaultof<Label>
  10. let mutable menu = Unchecked.defaultof<MenuBar>
  11. let mutable menuKeysStyle = Unchecked.defaultof<CheckBox>
  12. let mutable menuAutoMouseNav = Unchecked.defaultof<CheckBox>
  13. type Box10x (x: int, y: int) =
  14. inherit View (Rect(x, y, 20, 10))
  15. let w = 40
  16. let h = 50
  17. new () =
  18. new Box10x ()
  19. member _.GetContentSize () =
  20. Size (w, h)
  21. member _.SetCursorPosition (_ : Point) =
  22. raise (NotImplementedException())
  23. override this.Redraw (_: Rect) =
  24. Application.Driver.SetAttribute this.ColorScheme.Focus
  25. do
  26. let mutable y = 0
  27. while y < h do
  28. this.Move (0, y)
  29. Application.Driver.AddStr (ustr (string y))
  30. do
  31. let mutable x = 0
  32. while x < w - (y.ToString ()).Length do
  33. if (string y).Length < w
  34. then Application.Driver.AddStr (ustr " ")
  35. x <- x + 1
  36. y <- y + 1
  37. type Filler (rect: Rect) =
  38. inherit View(rect)
  39. new () =
  40. new Filler ()
  41. override this.Redraw (_: Rect) =
  42. Application.Driver.SetAttribute this.ColorScheme.Focus
  43. let mutable f = this.Frame
  44. do
  45. let mutable y = 0
  46. while y < f.Width do
  47. this.Move (0, y)
  48. do
  49. let mutable x = 0
  50. while x < f.Height do
  51. let r =
  52. match x % 3 with
  53. | 0 ->
  54. Application.Driver.AddRune ((Rune ((string y).ToCharArray (0, 1)).[0]))
  55. if y > 9 then
  56. Application.Driver.AddRune ((Rune ((string y).ToCharArray (1, 1)).[0]))
  57. Rune '.'
  58. | 1 -> Rune 'o'
  59. | _ -> Rune 'O'
  60. Application.Driver.AddRune r
  61. x <- x + 1
  62. y <- y + 1
  63. let ShowTextAlignments () =
  64. let okButton = new Button (ustr "Ok", true)
  65. okButton.add_Clicked (Action (Application.RequestStop))
  66. let cancelButton = new Button (ustr "Cancel", true)
  67. cancelButton.add_Clicked (Action (Application.RequestStop))
  68. let container = new Dialog (ustr "Text Alignments", 50, 20, okButton, cancelButton)
  69. let txt = "Hello world, how are you doing today"
  70. container.Add (
  71. new Label (Rect(0, 1, 40, 3), ustr ((sprintf "%O-%O" 1) txt), TextAlignment = TextAlignment.Left),
  72. new Label (Rect(0, 3, 40, 3), ustr ((sprintf "%O-%O" 2) txt), TextAlignment = TextAlignment.Right),
  73. new Label (Rect(0, 5, 40, 3), ustr ((sprintf "%O-%O" 3) txt), TextAlignment = TextAlignment.Centered),
  74. new Label (Rect(0, 7, 40, 3), ustr ((sprintf "%O-%O" 4) txt), TextAlignment = TextAlignment.Justified))
  75. Application.Run container
  76. let ShowEntries (container: View) =
  77. let scrollView =
  78. new ScrollView (Rect (50, 10, 20, 8),
  79. ContentSize = Size (20, 50),
  80. ShowVerticalScrollIndicator = true,
  81. ShowHorizontalScrollIndicator = true)
  82. scrollView.Add (new Filler (Rect (0, 0, 40, 40)))
  83. let scrollView2 =
  84. new ScrollView (Rect (72, 10, 3, 3),
  85. ContentSize = Size (100, 100),
  86. ShowVerticalScrollIndicator = true,
  87. ShowHorizontalScrollIndicator = true)
  88. scrollView2.Add (new Box10x (0, 0))
  89. let progress = new ProgressBar (Rect(68, 1, 10, 1))
  90. let timer = Func<MainLoop, bool> (fun _ ->
  91. progress.Pulse ()
  92. true)
  93. Application.MainLoop.AddTimeout (TimeSpan.FromMilliseconds (300.), timer) |> ignore
  94. let login =
  95. new Label (ustr "Login: ",
  96. X = Pos.At 3,
  97. Y = Pos.At 6)
  98. let password =
  99. new Label (ustr "Password: ",
  100. X = Pos.Left login,
  101. Y = Pos.Bottom login + Pos.At 1)
  102. let loginText =
  103. new TextField (ustr "",
  104. X = Pos.Right password,
  105. Y = Pos.Top login,
  106. Width = Dim.op_Implicit 40)
  107. let passText =
  108. new TextField (ustr "",
  109. Secret = true,
  110. X = Pos.Left loginText,
  111. Y = Pos.Top password,
  112. Width = Dim.Width loginText)
  113. let tf = new Button (3, 19, ustr "Ok")
  114. container.Add (login, loginText, password, passText,
  115. new FrameView (Rect (3, 10, 25, 6), ustr "Options",
  116. [| new CheckBox (1, 0, ustr "Remember me")
  117. new RadioGroup (1, 2,
  118. [| ustr "_Personal"; ustr "_Company"|])|]),
  119. new ListView (Rect (59, 6, 16, 4),
  120. [| "First row"
  121. "<>"
  122. "This is a very long row that should overflow what is shown"
  123. "4th"
  124. "There is an empty slot on the second row"
  125. "Whoa"
  126. "This is so cool" |]),
  127. scrollView, scrollView2, tf,
  128. new Button (10, 19, ustr "Cancel"),
  129. new TimeField (3, 20, DateTime.Now.TimeOfDay),
  130. new TimeField (23, 20, DateTime.Now.TimeOfDay, true),
  131. new DateField (3, 22, DateTime.Now),
  132. new DateField (23, 22, DateTime.Now, true),
  133. progress,
  134. new Label (3, 24, ustr "Press F9 (on Unix, ESC+9 is an alias) to activate the menubar"),
  135. menuKeysStyle,
  136. menuAutoMouseNav)
  137. container.SendSubviewToBack tf
  138. let NewFile () =
  139. let okButton = new Button (ustr "Ok", true)
  140. okButton.add_Clicked (Action (Application.RequestStop))
  141. let cancelButton = new Button (ustr "Cancel", true)
  142. cancelButton.add_Clicked (Action (Application.RequestStop))
  143. let d = new Dialog (ustr "New File", 50, 20, okButton, cancelButton)
  144. ml2 <- new Label (1, 1, ustr "Mouse Debug Line")
  145. d.Add ml2
  146. Application.Run d
  147. let GetFileName () =
  148. let mutable fname = Unchecked.defaultof<_>
  149. for s in [| "/etc/passwd"; "c:\\windows\\win.ini" |] do
  150. if File.Exists s
  151. then fname <- s
  152. fname
  153. let Editor (top: Toplevel) =
  154. let tframe = top.Frame
  155. let ntop = new Toplevel(tframe)
  156. let menu =
  157. new MenuBar(
  158. [| MenuBarItem (ustr "_File",
  159. [| MenuItem (ustr "_Close", ustring.Empty, (fun () -> Application.RequestStop ())) |]);
  160. MenuBarItem (ustr "_Edit",
  161. [| MenuItem (ustr "_Copy", ustring.Empty, Unchecked.defaultof<_>)
  162. MenuItem (ustr "C_ut", ustring.Empty, Unchecked.defaultof<_>)
  163. MenuItem (ustr "_Paste", ustring.Empty, Unchecked.defaultof<_>) |]) |])
  164. ntop.Add menu
  165. let fname = GetFileName ()
  166. let win =
  167. new Window (
  168. ustr (if not (isNull fname) then fname else "Untitled"),
  169. X = Pos.At 0,
  170. Y = Pos.At 1,
  171. Width = Dim.Fill (),
  172. Height = Dim.Fill ())
  173. ntop.Add win
  174. let text = new TextView (Rect(0, 0, (tframe.Width - 2), (tframe.Height - 3)))
  175. if fname <> Unchecked.defaultof<_>
  176. then text.Text <- ustr (File.ReadAllText fname)
  177. win.Add text
  178. Application.Run ntop
  179. let Quit () =
  180. MessageBox.Query (50, 7, ustr "Quit Demo", ustr "Are you sure you want to quit this demo?", ustr "Yes", ustr "No") = 0
  181. let Close () =
  182. MessageBox.ErrorQuery (50, 7, ustr "Error", ustr "There is nothing to close", ustr "Ok")
  183. |> ignore
  184. let Open () =
  185. let d = new OpenDialog (ustr "Open", ustr "Open a file", AllowsMultipleSelection = true)
  186. Application.Run d
  187. if not d.Canceled
  188. then MessageBox.Query (50, 7, ustr "Selected File", ustr (String.Join (", ", d.FilePaths)), ustr "Ok") |> ignore
  189. let ShowHex (top: Toplevel) =
  190. let tframe = top.Frame
  191. let ntop = new Toplevel (tframe)
  192. let menu =
  193. new MenuBar (
  194. [| MenuBarItem (ustr "_File",
  195. [| MenuItem (ustr "_Close", ustring.Empty, (fun () -> Application.RequestStop ())) |]) |])
  196. ntop.Add menu
  197. let win =
  198. new Window (ustr "/etc/passwd",
  199. X = Pos.At 0,
  200. Y = Pos.At 1,
  201. Width = Dim.Fill (),
  202. Height = Dim.Fill ())
  203. ntop.Add win
  204. let fname = GetFileName ()
  205. let source = File.OpenRead fname
  206. let hex =
  207. new HexView (source,
  208. X = Pos.At 0,
  209. Y = Pos.At 0,
  210. Width = Dim.Fill (),
  211. Height = Dim.Fill ())
  212. win.Add hex
  213. Application.Run ntop
  214. type MenuItemDetails () =
  215. inherit MenuItem ()
  216. new (title: ustring, help: ustring, action: Action) as this =
  217. MenuItemDetails ()
  218. then
  219. this.Title <- title
  220. this.Help <- help
  221. this.Action <- action
  222. static member Instance (mi: MenuItem) =
  223. (mi.GetMenuItem ()) :?> MenuItemDetails
  224. type MenuItemDelegate = delegate of MenuItemDetails -> MenuItem
  225. let ShowMenuItem (mi: MenuItemDetails) =
  226. MessageBox.Query (70, 7, ustr (mi.Title.ToString ()),
  227. ustr ((sprintf "%O selected. Is from submenu: %O" (mi.Title.ToString ())) (mi.GetMenuBarItem ())), ustr "Ok")
  228. |> ignore
  229. let MenuKeysStyleToggled (_: bool) =
  230. menu.UseKeysUpDownAsKeysLeftRight <- menuKeysStyle.Checked
  231. let MenuAutoMouseNavToggled (_: bool) =
  232. menu.WantMousePositionReports <- menuAutoMouseNav.Checked
  233. let Copy () =
  234. let textField = menu.LastFocused :?> TextField
  235. if textField <> Unchecked.defaultof<_> && textField.SelectedLength <> 0
  236. then textField.Copy ()
  237. let Cut () =
  238. let textField = menu.LastFocused :?> TextField
  239. if textField <> Unchecked.defaultof<_> && textField.SelectedLength <> 0
  240. then textField.Cut ()
  241. let Paste () =
  242. let textField = menu.LastFocused :?> TextField
  243. if textField <> Unchecked.defaultof<_>
  244. then textField.Paste ()
  245. let Help () =
  246. MessageBox.Query (50, 7, ustr "Help", ustr "This is a small help\nBe kind.", ustr "Ok")
  247. |> ignore
  248. let Load () =
  249. MessageBox.Query (50, 7, ustr "Load", ustr "This is a small load\nBe kind.", ustr "Ok")
  250. |> ignore
  251. let Save () =
  252. MessageBox.Query (50, 7, ustr "Save ", ustr "This is a small save\nBe kind.", ustr "Ok")
  253. |> ignore
  254. let ListSelectionDemo (multiple: bool) =
  255. let okButton = new Button (ustr "Ok", true)
  256. okButton.add_Clicked (Action (Application.RequestStop))
  257. let cancelButton = new Button (ustr "Cancel")
  258. cancelButton.add_Clicked (Action (Application.RequestStop))
  259. let d = new Dialog (ustr "Selection Demo", 60, 20, okButton, cancelButton)
  260. let animals = ResizeArray<_> ()
  261. animals.AddRange([| "Alpaca"; "Llama"; "Lion"; "Shark"; "Goat" |])
  262. let msg =
  263. new Label (ustr "Use space bar or control-t to toggle selection",
  264. X = Pos.At 1,
  265. Y = Pos.At 1,
  266. Width = Dim.Fill () - Dim.op_Implicit 1,
  267. Height = Dim.op_Implicit 1)
  268. let list =
  269. new ListView (animals,
  270. X = Pos.At 1,
  271. Y = Pos.At 3,
  272. Width = Dim.Fill () - Dim.op_Implicit 4,
  273. Height = Dim.Fill () - Dim.op_Implicit 4,
  274. AllowsMarking = true,
  275. AllowsMultipleSelection = multiple)
  276. d.Add (msg, list)
  277. Application.Run d
  278. let mutable result = ""
  279. do
  280. let mutable i = 0
  281. while i < animals.Count do
  282. if list.Source.IsMarked i
  283. then result <- result + animals.[i] + " "
  284. i <- i + 1
  285. MessageBox.Query (60, 10, ustr "Selected Animals", ustr (if result = "" then "No animals selected" else result), ustr "Ok") |> ignore
  286. let OnKeyDownPressUpDemo () =
  287. let closeButton = new Button (ustr "Close")
  288. closeButton.add_Clicked (Action (Application.RequestStop))
  289. let container = new Dialog (ustr "KeyDown & KeyPress & KeyUp demo", 80, 20, closeButton, Width = Dim.Fill (), Height = Dim.Fill ())
  290. let list = ResizeArray<_> ()
  291. let listView =
  292. new ListView (list,
  293. X = Pos.At 0,
  294. Y = Pos.At 0,
  295. Width = Dim.Fill () - Dim.op_Implicit 1,
  296. Height = Dim.Fill () - Dim.op_Implicit 2,
  297. ColorScheme = Colors.TopLevel)
  298. container.Add (listView)
  299. let keyDownPressUp (keyEvent: KeyEvent, updown: string) =
  300. match updown with
  301. | "Down"
  302. | "Up"
  303. | "Press" ->
  304. list.Add (keyEvent.ToString ())
  305. | _ -> failwithf "Unknown: %s" updown
  306. listView.MoveDown ()
  307. container.add_KeyDown(Action<View.KeyEventEventArgs> (fun (e: View.KeyEventEventArgs) -> keyDownPressUp (e.KeyEvent, "Down") |> ignore))
  308. container.add_KeyPress(Action<View.KeyEventEventArgs> (fun (e: View.KeyEventEventArgs) -> keyDownPressUp (e.KeyEvent, "Press") |> ignore))
  309. container.add_KeyUp(Action<View.KeyEventEventArgs> (fun (e: View.KeyEventEventArgs) -> keyDownPressUp (e.KeyEvent, "Up") |> ignore))
  310. Application.Run (container)
  311. let Main () =
  312. if Debugger.IsAttached then
  313. CultureInfo.DefaultThreadCurrentUICulture <- CultureInfo.GetCultureInfo ("en-US")
  314. Application.Init()
  315. let top = Application.Top
  316. let margin = 3
  317. let win =
  318. new Window (ustr "Hello",
  319. X = Pos.At 1,
  320. Y = Pos.At 1,
  321. Width = Dim.Fill () - Dim.op_Implicit margin,
  322. Height = Dim.Fill () - Dim.op_Implicit margin)
  323. let menuItems =
  324. [|MenuItemDetails (ustr "F_ind",ustr "", Unchecked.defaultof<_>);
  325. MenuItemDetails (ustr "_Replace", ustr "", Unchecked.defaultof<_>);
  326. MenuItemDetails (ustr "_Item1", ustr "", Unchecked.defaultof<_>);
  327. MenuItemDetails (ustr "_Also From Sub Menu", ustr "", Unchecked.defaultof<_>)|]
  328. menuItems.[0].Action <- fun _ -> ShowMenuItem (menuItems.[0])
  329. menuItems.[1].Action <- fun _ -> ShowMenuItem (menuItems.[1])
  330. menuItems.[2].Action <- fun _ -> ShowMenuItem (menuItems.[2])
  331. menuItems.[3].Action <- fun _ -> ShowMenuItem (menuItems.[3])
  332. menu <-
  333. new MenuBar (
  334. [| MenuBarItem(ustr "_File",
  335. [| MenuItem (ustr "Text _Editor Demo", ustring.Empty, (fun () -> Editor top))
  336. MenuItem (ustr "_New", ustr "Creates new file", fun () -> NewFile())
  337. MenuItem (ustr "_Open", ustring.Empty, fun () -> Open())
  338. MenuItem (ustr "_Hex", ustring.Empty, (fun () -> ShowHex top))
  339. MenuItem (ustr "_Close", ustring.Empty, (fun () -> Close()))
  340. MenuItem (ustr "_Disabled", ustring.Empty, (fun () -> ()), (fun () -> false))
  341. Unchecked.defaultof<_>
  342. MenuItem (ustr "_Quit", ustring.Empty, (fun () -> if Quit() then top.Running <- false)) |])
  343. MenuBarItem (ustr "_Edit",
  344. [| MenuItem (ustr "_Copy", ustring.Empty, fun () -> Copy())
  345. MenuItem (ustr "C_ut", ustring.Empty, fun () -> Cut())
  346. MenuItem (ustr "_Paste", ustring.Empty, fun () -> Paste())
  347. MenuBarItem (ustr "_Find and Replace",
  348. [| menuItems.[0] :> MenuItem
  349. menuItems.[1] :> MenuItem |]) :> MenuItem
  350. menuItems.[3] :> MenuItem
  351. |])
  352. MenuBarItem (ustr "_List Demos",
  353. [| MenuItem (ustr "Select _Multiple Items", ustring.Empty, (fun () -> ListSelectionDemo true))
  354. MenuItem (ustr "Select _Single Item", ustring.Empty, (fun () -> ListSelectionDemo false)) |])
  355. MenuBarItem (ustr "A_ssorted",
  356. [| MenuItem (ustr "_Show text alignments", ustring.Empty, (fun () -> ShowTextAlignments()))
  357. MenuItem (ustr "_OnKeyDown/Press/Up", ustring.Empty, (fun () -> OnKeyDownPressUpDemo())) |])
  358. MenuBarItem (ustr "_Test Menu and SubMenus",
  359. [| MenuBarItem (ustr "SubMenu1Item_1",
  360. [| MenuBarItem (ustr "SubMenu2Item_1",
  361. [| MenuBarItem (ustr "SubMenu3Item_1",
  362. [| menuItems.[2] :> MenuItem |]) :> MenuItem
  363. |]) :> MenuItem
  364. |]) :> MenuItem
  365. |])
  366. MenuBarItem (ustr "_About...", ustr "Demonstrates top-level menu item", (fun () -> MessageBox.ErrorQuery (50, 7, ustr "Error", ustr "This is a demo app for gui.cs", ustr "Ok") |> ignore)) |])
  367. menuKeysStyle <- new CheckBox (3, 25, ustr "UseKeysUpDownAsKeysLeftRight", true)
  368. menuKeysStyle.add_Toggled (Action<bool> (MenuKeysStyleToggled))
  369. menuAutoMouseNav <- new CheckBox (40, 25, ustr "UseMenuAutoNavigation", true)
  370. menuAutoMouseNav.add_Toggled (Action<bool> (MenuAutoMouseNavToggled))
  371. ShowEntries win
  372. let mutable count = 0
  373. ml <- new Label (Rect (3, 17, 47, 1), ustr "Mouse: ")
  374. Application.RootMouseEvent <- Action<MouseEvent> (
  375. fun (me: MouseEvent) ->
  376. ml.Text <- ustr (
  377. (((sprintf "Mouse: (%O,%O) - %O %O" me.X) me.Y) me.Flags) (count <- count + 1; count)))
  378. let test = new Label (3, 18, ustr "Se iniciará el análisis")
  379. win.Add test
  380. win.Add ml
  381. let drag = new Label (ustr "Drag: ", X = Pos.At 70, Y = Pos.At 24)
  382. let dragText =
  383. new TextField (ustr "",
  384. X = Pos.Right drag,
  385. Y = Pos.Top drag,
  386. Width = Dim.op_Implicit 40)
  387. let statusBar = new StatusBar ([|
  388. StatusItem(Key.F1, ustr "~F1~ Help", Action Help)
  389. StatusItem(Key.F2, ustr "~F2~ Load", Action Load)
  390. StatusItem(Key.F3, ustr "~F3~ Save", Action Save)
  391. StatusItem(Key.Q, ustr "~^Q~ Quit", fun () -> if (Quit()) then top.Running <- false) |])
  392. win.Add (drag, dragText)
  393. let bottom = new Label (ustr "This should go on the bottom of the same top-level!")
  394. win.Add bottom
  395. let bottom2 = new Label (ustr "This should go on the bottom of another top-level!")
  396. top.Add bottom2
  397. top.add_LayoutComplete (Action<View.LayoutEventArgs>
  398. (fun e ->
  399. bottom.X <- win.X
  400. bottom.Y <- Pos.Bottom win - Pos.Top win - Pos.At margin
  401. bottom2.X <- Pos.Left win
  402. bottom2.Y <- Pos.Bottom win)
  403. )
  404. top.Add win
  405. top.Add (menu, statusBar)
  406. Application.Run ()
  407. Application.Shutdown ();
  408. module Demo =
  409. [<EntryPoint>]
  410. let main _ =
  411. Main ()
  412. 0