...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package views
16
17 import (
18 "sync"
19
20 "github.com/gdamore/tcell/v2"
21 )
22
23
24 type Application struct {
25 widget Widget
26 screen tcell.Screen
27 style tcell.Style
28 err error
29 wg sync.WaitGroup
30 paste bool
31 }
32
33
34 func (app *Application) SetRootWidget(widget Widget) {
35 app.widget = widget
36 }
37
38
39
40 func (app *Application) EnablePaste(on bool) {
41 app.paste = on
42 }
43
44
45
46 func (app *Application) initialize() error {
47 if app.screen == nil {
48 if app.screen, app.err = tcell.NewScreen(); app.err != nil {
49 return app.err
50 }
51 app.screen.SetStyle(app.style)
52 }
53 return nil
54 }
55
56
57
58 func (app *Application) Quit() {
59 ev := &eventAppQuit{}
60 ev.SetEventNow()
61 if scr := app.screen; scr != nil {
62 go func() { scr.PostEventWait(ev) }()
63 }
64 }
65
66
67
68 func (app *Application) Refresh() {
69 ev := &eventAppRefresh{}
70 ev.SetEventNow()
71 if scr := app.screen; scr != nil {
72 go func() { scr.PostEventWait(ev) }()
73 }
74 }
75
76
77
78 func (app *Application) Update() {
79 ev := &eventAppUpdate{}
80 ev.SetEventNow()
81 if scr := app.screen; scr != nil {
82 go func() { scr.PostEventWait(ev) }()
83 }
84 }
85
86
87
88
89 func (app *Application) PostFunc(fn func()) {
90 ev := &eventAppFunc{fn: fn}
91 ev.SetEventNow()
92 if scr := app.screen; scr != nil {
93 go func() { scr.PostEventWait(ev) }()
94 }
95 }
96
97
98
99 func (app *Application) SetScreen(scr tcell.Screen) {
100 if app.screen == nil {
101 app.screen = scr
102 app.err = nil
103 }
104 }
105
106
107
108 func (app *Application) SetStyle(style tcell.Style) {
109 app.style = style
110 if app.screen != nil {
111 app.screen.SetStyle(style)
112 }
113 }
114
115 func (app *Application) run() {
116
117 screen := app.screen
118 widget := app.widget
119
120 if widget == nil {
121 app.wg.Done()
122 return
123 }
124 if screen == nil {
125 if e := app.initialize(); e != nil {
126 app.wg.Done()
127 return
128 }
129 screen = app.screen
130 }
131 defer func() {
132 screen.Fini()
133 app.wg.Done()
134 }()
135 screen.Init()
136 screen.EnableMouse()
137 if app.paste {
138 screen.EnablePaste()
139 }
140 screen.Clear()
141 widget.SetView(screen)
142
143 loop:
144 for {
145 if widget = app.widget; widget == nil {
146 break
147 }
148 widget.Draw()
149 screen.Show()
150
151 ev := screen.PollEvent()
152 switch nev := ev.(type) {
153 case *eventAppQuit:
154 break loop
155 case *eventAppUpdate:
156 screen.Show()
157 case *eventAppRefresh:
158 screen.Sync()
159 case *eventAppFunc:
160 nev.fn()
161 case *tcell.EventResize:
162 screen.Sync()
163 widget.Resize()
164 default:
165 widget.HandleEvent(ev)
166 }
167 }
168 }
169
170
171
172
173 func (app *Application) Start() {
174 app.wg.Add(1)
175 go app.run()
176 }
177
178
179 func (app *Application) Wait() error {
180 app.wg.Wait()
181 return app.err
182 }
183
184
185
186 func (app *Application) Run() error {
187 app.Start()
188 return app.Wait()
189 }
190
191 type eventAppUpdate struct {
192 tcell.EventTime
193 }
194
195 type eventAppQuit struct {
196 tcell.EventTime
197 }
198
199 type eventAppRefresh struct {
200 tcell.EventTime
201 }
202
203 type eventAppFunc struct {
204 tcell.EventTime
205 fn func()
206 }
207
View as plain text