-
Notifications
You must be signed in to change notification settings - Fork 39
/
Demo.swift
152 lines (138 loc) · 3.74 KB
/
Demo.swift
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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//
// Demo.swift
// Few
//
// Created by Josh Abernathy on 3/10/15.
// Copyright (c) 2015 Josh Abernathy. All rights reserved.
//
import Foundation
import Few
import AppKit
struct LoginState {
let username: String
let password: String
init(username: String = "", password: String = "") {
self.username = username
self.password = password
}
}
private func renderInput(component: Component<LoginState>, label: String, secure: Bool, fn: (LoginState, String) -> LoginState) -> Element {
let action: String -> () = { str in
component.updateState { fn($0, str) }
}
var input: Element!
if secure {
input = Password(action: action)
} else {
input = Input(action: action).autofocus(true)
}
return Element()
.direction(.Row)
.padding(Edges(bottom: 4))
.children([
Label(label).size(75, 19),
input.size(100, 23),
])
}
struct ScrollViewState {
let selectedRow: Int?
let items: [Int]
init(items: [Int] = Array(1...100), selectedRow: Int? = nil) {
self.items = items
self.selectedRow = selectedRow
}
}
private func keyDown(event: NSEvent, component: Component<ScrollViewState>) -> Bool {
let characters = event.charactersIgnoringModifiers!.utf16
let firstCharacter = first(characters)
if firstCharacter == UInt16(NSDeleteCharacter) {
component.updateState { state in
var items = state.items
items.removeAtIndex <^> state.selectedRow
return ScrollViewState(selectedRow: state.selectedRow, items: items)
}
return true
} else {
return false
}
}
private func renderScrollView() -> Element {
return Component(initialState: ScrollViewState()) { component, state in
let items = state.items.map { row -> Element in
if row % 2 == 0 {
return renderRow1(row)
} else {
return renderRow2(row)
}
}
let itemPlurality = (items.count == 1 ? "item" : "items")
return View(
keyDown: { _, event in
return keyDown(event, component)
})
.direction(.Column)
.children([
Label("\(items.count) \(itemPlurality)"),
TableView(items, selectionChanged: { row in
component.updateState { ScrollViewState(selectedRow: row, items: $0.items) }
})
.flex(1)
])
}
}
private func renderRow1(row: Int) -> Element {
return Element()
.direction(.Column)
.children([
Label("\(row)"),
Label("I am a banana.", textColor: .blackColor(), font: .systemFontOfSize(18)),
Image(NSImage(named: NSImageNameApplicationIcon)).size(42, 42),
])
}
private func renderRow2(row: Int) -> Element {
return Element()
.direction(.Row)
.children([
Image(NSImage(named: NSImageNameApplicationIcon)).size(14, 14),
Label("I am a banana.", textColor: .redColor(), font: .systemFontOfSize(11)),
])
}
private func renderLogin() -> Element {
return Component(initialState: LoginState()) { component, state in
let loginEnabled = !state.username.isEmpty && !state.password.isEmpty
return Element()
.direction(.Column)
.children([
renderThingy(count(state.username.utf16)),
renderInput(component, "Username", false) {
LoginState(username: $1, password: $0.password)
},
renderInput(component, "Password", true) {
LoginState(username: $0.username, password: $1)
},
Button(title: "Login", enabled: loginEnabled, action: {})
.selfAlignment(.FlexEnd)
.margin(Edges(bottom: 10, top: 10)),
])
}
}
private func renderThingy(count: Int) -> Element {
let even = count % 2 == 0
return (even ? Element() : View(backgroundColor: NSColor.blueColor())).size(100, 50)
}
typealias Demo = Demo_<()>
class Demo_<LOL>: Component<()> {
init() {
super.init(initialState: ())
}
override func render() -> Element {
return Element()
.justification(.Center)
.childAlignment(.Center)
.direction(.Column)
.children([
renderLogin(),
renderScrollView().size(100, 200),
])
}
}