Split UI library and widgets
This commit is contained in:
parent
661e3ec2a4
commit
1418e1b9dc
11 changed files with 34 additions and 25 deletions
widgets
97
widgets/account.go.old
Normal file
97
widgets/account.go.old
Normal file
|
@ -0,0 +1,97 @@
|
|||
package ui
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
tb "github.com/nsf/termbox-go"
|
||||
|
||||
"git.sr.ht/~sircmpwn/aerc2/config"
|
||||
"git.sr.ht/~sircmpwn/aerc2/worker"
|
||||
"git.sr.ht/~sircmpwn/aerc2/worker/types"
|
||||
)
|
||||
|
||||
type AccountTab struct {
|
||||
Config *config.AccountConfig
|
||||
Worker *types.Worker
|
||||
Parent *UIState
|
||||
logger *log.Logger
|
||||
counter int
|
||||
}
|
||||
|
||||
func NewAccountTab(conf *config.AccountConfig,
|
||||
logger *log.Logger) (*AccountTab, error) {
|
||||
|
||||
work, err := worker.NewWorker(conf.Source, logger)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
go work.Backend.Run()
|
||||
acc := &AccountTab{
|
||||
Config: conf,
|
||||
Worker: work,
|
||||
logger: logger,
|
||||
}
|
||||
acc.Worker.PostAction(&types.Configure{Config: conf}, nil)
|
||||
acc.Worker.PostAction(&types.Connect{}, func(msg types.WorkerMessage) {
|
||||
switch msg := msg.(type) {
|
||||
case *types.Done:
|
||||
acc.logger.Println("Connected.")
|
||||
acc.Worker.PostAction(&types.ListDirectories{}, nil)
|
||||
case *types.CertificateApprovalRequest:
|
||||
// TODO: Ask the user
|
||||
acc.logger.Println("Approving certificate")
|
||||
acc.Worker.PostAction(&types.ApproveCertificate{
|
||||
Message: types.RespondTo(msg),
|
||||
Approved: true,
|
||||
}, nil)
|
||||
default:
|
||||
acc.logger.Println("Connection failed.")
|
||||
}
|
||||
})
|
||||
return acc, nil
|
||||
}
|
||||
|
||||
func (acc *AccountTab) Name() string {
|
||||
return acc.Config.Name
|
||||
}
|
||||
|
||||
func (acc *AccountTab) SetParent(parent *UIState) {
|
||||
acc.Parent = parent
|
||||
}
|
||||
|
||||
func (acc *AccountTab) Render(at Geometry) {
|
||||
cell := tb.Cell{
|
||||
Ch: ' ',
|
||||
Fg: tb.ColorDefault,
|
||||
Bg: tb.ColorDefault,
|
||||
}
|
||||
TFill(at, cell)
|
||||
TPrintf(&at, cell, "%s %d\n", acc.Name(), acc.counter)
|
||||
acc.counter++
|
||||
if acc.counter%10000 == 0 {
|
||||
acc.counter = 0
|
||||
}
|
||||
acc.Parent.InvalidateFrom(acc)
|
||||
}
|
||||
|
||||
func (acc *AccountTab) GetChannel() chan types.WorkerMessage {
|
||||
return acc.Worker.Messages
|
||||
}
|
||||
|
||||
func (acc *AccountTab) HandleMessage(msg types.WorkerMessage) {
|
||||
msg = acc.Worker.ProcessMessage(msg)
|
||||
switch msg := msg.(type) {
|
||||
case *types.Done:
|
||||
case *types.CertificateApprovalRequest:
|
||||
case *types.Unsupported:
|
||||
// no-op
|
||||
case *types.Error:
|
||||
acc.logger.Printf("Error: %v\n", msg.Error)
|
||||
case *types.Directory:
|
||||
acc.logger.Printf("Directory: %s\n", msg.Name)
|
||||
default:
|
||||
acc.Worker.PostAction(&types.Unsupported{
|
||||
Message: types.RespondTo(msg),
|
||||
}, nil)
|
||||
}
|
||||
}
|
129
widgets/exline.go
Normal file
129
widgets/exline.go
Normal file
|
@ -0,0 +1,129 @@
|
|||
package widgets
|
||||
|
||||
import (
|
||||
tb "github.com/nsf/termbox-go"
|
||||
|
||||
"git.sr.ht/~sircmpwn/aerc2/lib/ui"
|
||||
)
|
||||
|
||||
// TODO: history
|
||||
// TODO: tab completion
|
||||
// TODO: commit
|
||||
// TODO: cancel (via esc/ctrl+c)
|
||||
// TODO: scrolling
|
||||
|
||||
type ExLine struct {
|
||||
command *string
|
||||
commit func(cmd *string)
|
||||
index int
|
||||
scroll int
|
||||
|
||||
onInvalidate func(d ui.Drawable)
|
||||
}
|
||||
|
||||
func NewExLine() *ExLine {
|
||||
cmd := ""
|
||||
return &ExLine{command: &cmd}
|
||||
}
|
||||
|
||||
func (ex *ExLine) OnInvalidate(onInvalidate func(d ui.Drawable)) {
|
||||
ex.onInvalidate = onInvalidate
|
||||
}
|
||||
|
||||
func (ex *ExLine) Invalidate() {
|
||||
if ex.onInvalidate != nil {
|
||||
ex.onInvalidate(ex)
|
||||
}
|
||||
}
|
||||
|
||||
func (ex *ExLine) Draw(ctx *ui.Context) {
|
||||
cell := tb.Cell{
|
||||
Fg: tb.ColorDefault,
|
||||
Bg: tb.ColorDefault,
|
||||
Ch: ' ',
|
||||
}
|
||||
ctx.Fill(0, 0, ctx.Width(), ctx.Height(), cell)
|
||||
ctx.Printf(0, 0, cell, ":%s", *ex.command)
|
||||
tb.SetCursor(ctx.X()+ex.index-ex.scroll+1, ctx.Y())
|
||||
}
|
||||
|
||||
func (ex *ExLine) insert(ch rune) {
|
||||
newCmd := (*ex.command)[:ex.index] + string(ch) + (*ex.command)[ex.index:]
|
||||
ex.command = &newCmd
|
||||
ex.index++
|
||||
ex.Invalidate()
|
||||
}
|
||||
|
||||
func (ex *ExLine) deleteWord() {
|
||||
// TODO: Break on any of / " '
|
||||
if len(*ex.command) == 0 {
|
||||
return
|
||||
}
|
||||
i := ex.index - 1
|
||||
if (*ex.command)[i] == ' ' {
|
||||
i--
|
||||
}
|
||||
for ; i >= 0; i-- {
|
||||
if (*ex.command)[i] == ' ' {
|
||||
break
|
||||
}
|
||||
}
|
||||
newCmd := (*ex.command)[:i+1] + (*ex.command)[ex.index:]
|
||||
ex.command = &newCmd
|
||||
ex.index = i + 1
|
||||
ex.Invalidate()
|
||||
}
|
||||
|
||||
func (ex *ExLine) deleteChar() {
|
||||
if len(*ex.command) > 0 && ex.index != len(*ex.command) {
|
||||
newCmd := (*ex.command)[:ex.index] + (*ex.command)[ex.index+1:]
|
||||
ex.command = &newCmd
|
||||
ex.Invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
func (ex *ExLine) backspace() {
|
||||
if len(*ex.command) > 0 && ex.index != 0 {
|
||||
newCmd := (*ex.command)[:ex.index-1] + (*ex.command)[ex.index:]
|
||||
ex.command = &newCmd
|
||||
ex.index--
|
||||
ex.Invalidate()
|
||||
}
|
||||
}
|
||||
|
||||
func (ex *ExLine) Event(event tb.Event) bool {
|
||||
switch event.Type {
|
||||
case tb.EventKey:
|
||||
switch event.Key {
|
||||
case tb.KeySpace:
|
||||
ex.insert(' ')
|
||||
case tb.KeyBackspace, tb.KeyBackspace2:
|
||||
ex.backspace()
|
||||
case tb.KeyCtrlD, tb.KeyDelete:
|
||||
ex.deleteChar()
|
||||
case tb.KeyCtrlB, tb.KeyArrowLeft:
|
||||
if ex.index > 0 {
|
||||
ex.index--
|
||||
ex.Invalidate()
|
||||
}
|
||||
case tb.KeyCtrlF, tb.KeyArrowRight:
|
||||
if ex.index < len(*ex.command) {
|
||||
ex.index++
|
||||
ex.Invalidate()
|
||||
}
|
||||
case tb.KeyCtrlA, tb.KeyHome:
|
||||
ex.index = 0
|
||||
ex.Invalidate()
|
||||
case tb.KeyCtrlE, tb.KeyEnd:
|
||||
ex.index = len(*ex.command)
|
||||
ex.Invalidate()
|
||||
case tb.KeyCtrlW:
|
||||
ex.deleteWord()
|
||||
default:
|
||||
if event.Ch != 0 {
|
||||
ex.insert(event.Ch)
|
||||
}
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue