forked from mdouchement/standardfile
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tui.go
137 lines (116 loc) · 3.12 KB
/
tui.go
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
package tui
import (
"time"
"github.com/gcla/gowid"
"github.com/gcla/gowid/widgets/columns"
"github.com/gcla/gowid/widgets/framed"
"github.com/gcla/gowid/widgets/null"
"github.com/gcla/gowid/widgets/pile"
"github.com/gcla/gowid/widgets/styled"
"github.com/gcla/gowid/widgets/text"
"github.com/gdamore/tcell"
"github.com/pkg/errors"
)
// A TUI is a text-based interface.
type TUI struct {
App *gowid.App
SortBy string
list *NoteList
editor *framed.Widget
status *text.Widget
}
// New returns a new TUI.
func New() (*TUI, error) {
ui := new(TUI)
ui.SortBy = "name"
app, err := gowid.NewApp(layout(ui))
if err != nil {
return ui, errors.Wrap(err, "could not create application widgets")
}
ui.App = app
return ui, nil
}
// Run starts the application and thus the event loop.
func (ui *TUI) Run() {
ui.App.MainLoop(gowid.UnhandledInputFunc(ui.unhandled))
}
// Cleanup cleans the application properly (in case of panic).
func (ui *TUI) Cleanup() {
ui.App.GetScreen().Fini() // Cleanup tcell screen's objects
}
// Register registers an item.
func (ui *TUI) Register(i *Item) {
ui.list.Register(i)
}
// SortItems sorts the items on ui.SortBy.
func (ui *TUI) SortItems() {
ui.list.Sort(ui.SortBy)
}
// DisplayStatus displays a message in the status bar (aka notifications).
func (ui *TUI) DisplayStatus(message string) {
ui.App.Run(gowid.RunFunction(func(app gowid.IApp) {
ui.status.SetText(message, ui.App)
}))
go func() {
timer := time.NewTimer(1200 * time.Millisecond)
<-timer.C
ui.App.Run(gowid.RunFunction(func(app gowid.IApp) {
ui.status.SetText("", ui.App)
}))
}()
}
////////////////////
// //
// Layout //
// //
////////////////////
func layout(ui *TUI) gowid.AppArgs {
ui.list = NewNoteList(ui)
ui.editor = framed.NewUnicode(null.New())
ui.status = text.New("")
notePane := columns.New([]gowid.IContainerWidget{
&gowid.ContainerWidget{
IWidget: styled.New(framed.NewUnicode(ui.list), gowid.MakePaletteRef("mainpane")),
D: gowid.RenderWithWeight{W: 1},
},
&gowid.ContainerWidget{
IWidget: styled.New(ui.editor, gowid.MakePaletteRef("mainpane")),
D: gowid.RenderWithWeight{W: 8},
},
})
main := pile.New([]gowid.IContainerWidget{
&gowid.ContainerWidget{IWidget: notePane, D: gowid.RenderWithWeight{W: 20}},
&gowid.ContainerWidget{
IWidget: styled.New(framed.NewUnicode(ui.status), gowid.MakePaletteRef("mainpane")),
D: gowid.RenderWithWeight{W: 2},
},
})
return gowid.AppArgs{
View: main,
Palette: &gowid.Palette{
"mainpane": gowid.MakePaletteEntry(gowid.ColorLightGray, gowid.ColorBlack),
// List style
"normal": gowid.MakePaletteEntry(gowid.ColorLightGray, gowid.ColorBlack),
"focused": gowid.MakePaletteEntry(gowid.ColorBlack, gowid.ColorRed),
},
Log: NewLogger(),
}
}
////////////////////
// //
// Events //
// //
////////////////////
func (ui *TUI) unhandled(app gowid.IApp, ev interface{}) bool {
evk, ok := ev.(*tcell.EventKey)
if !ok {
return false
}
handled := false
switch evk.Key() {
case tcell.KeyCtrlQ:
handled = true
app.Quit()
}
return handled
}