-
Notifications
You must be signed in to change notification settings - Fork 0
/
double_counter.exs
103 lines (83 loc) · 2.34 KB
/
double_counter.exs
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
defmodule Counter.Child do
@behaviour Orange.Component
import Orange.Macro
@impl true
def init(_attrs), do: %{state: 0}
@impl true
def handle_event(event, state, _attrs) do
case event do
%Orange.Terminal.KeyEvent{code: :up} ->
state + 1
%Orange.Terminal.KeyEvent{code: :down} ->
state - 1
%Orange.Terminal.KeyEvent{code: {:char, "k"}} ->
state + 1
%Orange.Terminal.KeyEvent{code: {:char, "j"}} ->
state - 1
_ ->
state
end
end
@impl true
def after_mount(_state, _attrs, update) do
spawn(fn ->
Process.sleep(3000)
update.(100)
end)
end
@impl true
def render(state, attrs, update) do
rect style: [width: 20, height: 20, border: attrs[:highlighted]] do
span do
"Counter: #{state}"
end
end
end
end
defmodule Counter.App do
@behaviour Orange.Component
import Orange.Macro
@impl true
def init(_attrs), do: %{state: %{focus: nil, count: 2}, events_subscription: true}
@impl true
def handle_event(event, state, _attrs) do
case event do
%Orange.Terminal.KeyEvent{code: {:char, "h"}} ->
old_focus = state.focus
case state.focus do
nil -> %{state | focus: :counter1}
:counter1 -> %{state | focus: :counter2}
:counter2 -> %{state | focus: :counter1}
end
|> tap(fn state ->
if old_focus, do: Orange.unsubscribe(old_focus)
Orange.subscribe(state.focus)
end)
%Orange.Terminal.KeyEvent{code: {:char, "l"}} ->
old_focus = state.focus
case state.focus do
nil -> %{state | focus: :counter1}
:counter1 -> %{state | focus: :counter2}
:counter2 -> %{state | focus: :counter1}
end
|> tap(fn state ->
if old_focus, do: Orange.unsubscribe(old_focus)
Orange.subscribe(state.focus)
end)
%Orange.Terminal.KeyEvent{code: {:char, "q"}} ->
Orange.stop()
state
_ ->
state
end
end
@impl true
def render(state, _attrs, _update) do
rect direction: :row do
{Counter.Child, [id: :counter1, highlighted: state.focus == :counter1]}
{Counter.Child, [id: :counter2, highlighted: state.focus == :counter2]}
end
end
end
# Start the application. To quit, press 'q'.
Orange.start(Counter.App)