-
Notifications
You must be signed in to change notification settings - Fork 0
/
App.Contacts.fs
93 lines (84 loc) · 2.47 KB
/
App.Contacts.fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
module App.Contacts
open DeclarativeWPF
open NetAtom
open NetOptics
open System
open System.Windows
open System.Windows.Controls
type Contact = {Name: string; Phone: string}
module Contact =
let name = Optic.lens (fun t -> t.Name) (fun v t -> {t with Name = v})
let phone = Optic.lens (fun t -> t.Phone) (fun v t -> {t with Phone = v})
let empty = {Name = ""; Phone = ""}
let textBox (text: IAtom<_>) = UI.elem TextBox [UI.width 100.0; UI.text text]
let contactView contact =
UI.elem StackPanel [
UI.orientation Orientation.Horizontal
UI.children [
UI.elem Button [UI.content "Remove"; UI.onClick <| Atom.removeAct contact]
Atom.view Contact.name contact |> textBox
Atom.view Contact.phone contact |> textBox
]
]
let contactsView contacts =
UI.elem StackPanel [
UI.orientation Orientation.Vertical
UI.children [
UI.elem StackPanel [
UI.orientation Orientation.Horizontal
UI.children [
UI.elem Button [
UI.content "Add"
UI.onClick <| Atom.setAtAct Optic.appendL contacts [Contact.empty]
]
]
]
UI.elem StackPanel [
UI.orientation Orientation.Vertical
Atom.map contactView contacts |> UI.children
]
]
]
let countDownButton label value =
UI.elem Button [
UI.onClick <| Atom.modifyAct value ((+) -1)
UI.isEnabled <| UI.lift1 ((<>) 0) value
UI.lift1 (sprintf"%s (%d)" label) value |> UI.content
]
let historyView history =
UI.elem DockPanel [
UI.children [
countDownButton "Undo" <| Atom.view History.undoIndex history
countDownButton "Redo" <| Atom.view History.redoIndex history
UI.elem Slider [
UI.smallChange 1.0
UI.minimum 0.0
UI.maximum (UI.lift1 (History.indexMax >> float) history)
UI.value <| Atom.view (History.index << Optic.truncateI) history
]
]
]
[<EntryPoint; STAThread>]
let main _ =
let state =
Atom.create << History.init<IROL<_>> id
<| [|{Name = "Would"; Phone = "you"}
{Name = "like"; Phone = "to know?"}|]
UI.run <| Application (
MainWindow = UI.show (
UI.window Window [
UI.title "Contacts"
UI.width 300.0
UI.height 300.0
UI.content (
UI.elem StackPanel [
UI.orientation Orientation.Vertical
UI.children [
historyView state
contactsView (Atom.view History.present state)
]
]
)
]
)
)