Add statusline widget
This commit is contained in:
parent
46756487fb
commit
a073d7613f
3 changed files with 119 additions and 7 deletions
|
@ -73,10 +73,22 @@ func main() {
|
||||||
grid.AddChild(tabs.TabContent).At(1, 1)
|
grid.AddChild(tabs.TabContent).At(1, 1)
|
||||||
|
|
||||||
statusbar := libui.NewStack()
|
statusbar := libui.NewStack()
|
||||||
exline := widgets.NewExLine()
|
|
||||||
statusbar.Push(exline)
|
|
||||||
grid.AddChild(statusbar).At(2, 1)
|
grid.AddChild(statusbar).At(2, 1)
|
||||||
|
|
||||||
|
statusline := widgets.NewStatusLine()
|
||||||
|
statusline.Push("test status!", 6*time.Second)
|
||||||
|
statusline.Push("test error!", 3*time.Second).
|
||||||
|
Color(tb.ColorRed, tb.ColorBlack)
|
||||||
|
statusbar.Push(statusline)
|
||||||
|
|
||||||
|
exline := widgets.NewExLine(func(command string) {
|
||||||
|
statusbar.Pop()
|
||||||
|
logger.Printf("TODO: execute command: %s\n", command)
|
||||||
|
}, func() {
|
||||||
|
statusbar.Pop()
|
||||||
|
})
|
||||||
|
statusbar.Push(exline)
|
||||||
|
|
||||||
ui, err := libui.Initialize(conf, grid)
|
ui, err := libui.Initialize(conf, grid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
|
|
|
@ -9,21 +9,24 @@ import (
|
||||||
|
|
||||||
// TODO: history
|
// TODO: history
|
||||||
// TODO: tab completion
|
// TODO: tab completion
|
||||||
// TODO: commit
|
|
||||||
// TODO: cancel (via esc/ctrl+c)
|
|
||||||
// TODO: scrolling
|
// TODO: scrolling
|
||||||
|
|
||||||
type ExLine struct {
|
type ExLine struct {
|
||||||
command []rune
|
command []rune
|
||||||
commit func(cmd *string)
|
commit func(cmd string)
|
||||||
|
cancel func()
|
||||||
index int
|
index int
|
||||||
scroll int
|
scroll int
|
||||||
|
|
||||||
onInvalidate func(d ui.Drawable)
|
onInvalidate func(d ui.Drawable)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewExLine() *ExLine {
|
func NewExLine(commit func (cmd string), cancel func()) *ExLine {
|
||||||
return &ExLine{command: []rune{}}
|
return &ExLine{
|
||||||
|
cancel: cancel,
|
||||||
|
commit: commit,
|
||||||
|
command: []rune{},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ex *ExLine) OnInvalidate(onInvalidate func(d ui.Drawable)) {
|
func (ex *ExLine) OnInvalidate(onInvalidate func(d ui.Drawable)) {
|
||||||
|
@ -118,6 +121,12 @@ func (ex *ExLine) Event(event tb.Event) bool {
|
||||||
ex.Invalidate()
|
ex.Invalidate()
|
||||||
case tb.KeyCtrlW:
|
case tb.KeyCtrlW:
|
||||||
ex.deleteWord()
|
ex.deleteWord()
|
||||||
|
case tb.KeyEnter:
|
||||||
|
tb.HideCursor()
|
||||||
|
ex.commit(string(ex.command))
|
||||||
|
case tb.KeyEsc, tb.KeyCtrlC:
|
||||||
|
tb.HideCursor()
|
||||||
|
ex.cancel()
|
||||||
default:
|
default:
|
||||||
if event.Ch != 0 {
|
if event.Ch != 0 {
|
||||||
ex.insert(event.Ch)
|
ex.insert(event.Ch)
|
||||||
|
|
91
widgets/status.go
Normal file
91
widgets/status.go
Normal file
|
@ -0,0 +1,91 @@
|
||||||
|
package widgets
|
||||||
|
|
||||||
|
import (
|
||||||
|
"time"
|
||||||
|
|
||||||
|
tb "github.com/nsf/termbox-go"
|
||||||
|
|
||||||
|
"git.sr.ht/~sircmpwn/aerc2/lib/ui"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StatusLine struct {
|
||||||
|
stack []*StatusMessage
|
||||||
|
fallback StatusMessage
|
||||||
|
|
||||||
|
onInvalidate func(d ui.Drawable)
|
||||||
|
}
|
||||||
|
|
||||||
|
type StatusMessage struct {
|
||||||
|
bg tb.Attribute
|
||||||
|
fg tb.Attribute
|
||||||
|
message string
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewStatusLine() *StatusLine {
|
||||||
|
return &StatusLine{
|
||||||
|
fallback: StatusMessage{
|
||||||
|
bg: tb.ColorWhite,
|
||||||
|
fg: tb.ColorBlack,
|
||||||
|
message: "Idle",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (status *StatusLine) OnInvalidate(onInvalidate func (d ui.Drawable)) {
|
||||||
|
status.onInvalidate = onInvalidate
|
||||||
|
}
|
||||||
|
|
||||||
|
func (status *StatusLine) Invalidate() {
|
||||||
|
if status.onInvalidate != nil {
|
||||||
|
status.onInvalidate(status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (status *StatusLine) Draw(ctx *ui.Context) {
|
||||||
|
line := &status.fallback
|
||||||
|
if len(status.stack) != 0 {
|
||||||
|
line = status.stack[len(status.stack)-1]
|
||||||
|
}
|
||||||
|
cell := tb.Cell{
|
||||||
|
Fg: line.fg,
|
||||||
|
Bg: line.bg,
|
||||||
|
Ch: ' ',
|
||||||
|
}
|
||||||
|
ctx.Fill(0, 0, ctx.Width(), ctx.Height(), cell)
|
||||||
|
ctx.Printf(0, 0, cell, "%s", line.message)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (status *StatusLine) Set(text string) *StatusMessage {
|
||||||
|
status.fallback = StatusMessage{
|
||||||
|
bg: tb.ColorWhite,
|
||||||
|
fg: tb.ColorBlack,
|
||||||
|
message: text,
|
||||||
|
}
|
||||||
|
status.Invalidate()
|
||||||
|
return &status.fallback
|
||||||
|
}
|
||||||
|
|
||||||
|
func (status *StatusLine) Push(text string, expiry time.Duration) *StatusMessage {
|
||||||
|
msg := &StatusMessage{
|
||||||
|
bg: tb.ColorWhite,
|
||||||
|
fg: tb.ColorBlack,
|
||||||
|
message: text,
|
||||||
|
}
|
||||||
|
status.stack = append(status.stack, msg)
|
||||||
|
go (func () {
|
||||||
|
time.Sleep(expiry)
|
||||||
|
for i, m := range status.stack {
|
||||||
|
if m == msg {
|
||||||
|
status.stack = append(status.stack[:i], status.stack[i+1:]...)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
status.Invalidate()
|
||||||
|
})()
|
||||||
|
return msg
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *StatusMessage) Color(bg tb.Attribute, fg tb.Attribute) {
|
||||||
|
msg.bg = bg
|
||||||
|
msg.fg = fg
|
||||||
|
}
|
Loading…
Reference in a new issue