aboutsummaryrefslogblamecommitdiffstats
path: root/widgets/status.go
blob: 960f244526789fad0d40be118595ad6073ff4ff0 (plain) (tree)
1
2
3
4
5
6
7
8
9
10




               
                                     
                                       
 

                                       


                        
                        

                                 
                       
                      
                                


                           
                           


                      
                                                          

                                        
                                                                                    

                                        
                             
                                   


         
                                        
                                   






                                                        
                                                                  





                                                                    




                                                                            
                                                                  



                                                           









                                                                                   







                                                                                  
                                                                                   


                                                
                    








                                                                                              
                           


                  











                                                                            







                                                 



                                    



                                               

                                                    
 
package widgets

import (
	"time"

	"github.com/gdamore/tcell/v2"
	"github.com/mattn/go-runewidth"

	"git.sr.ht/~rjarry/aerc/config"
	"git.sr.ht/~rjarry/aerc/lib/ui"
)

type StatusLine struct {
	ui.Invalidatable
	stack    []*StatusMessage
	fallback StatusMessage
	extra    string
	aerc     *Aerc
	uiConfig config.UIConfig
}

type StatusMessage struct {
	style   tcell.Style
	message string
}

func NewStatusLine(uiConfig config.UIConfig) *StatusLine {
	return &StatusLine{
		fallback: StatusMessage{
			style:   uiConfig.GetStyle(config.STYLE_STATUSLINE_DEFAULT),
			message: "Idle",
		},
		extra:    "",
		uiConfig: uiConfig,
	}
}

func (status *StatusLine) Invalidate() {
	status.DoInvalidate(status)
}

func (status *StatusLine) Draw(ctx *ui.Context) {
	line := &status.fallback
	if len(status.stack) != 0 {
		line = status.stack[len(status.stack)-1]
	}
	ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', line.style)
	pendingKeys := ""
	if status.aerc != nil {
		for _, pendingKey := range status.aerc.pendingKeys {
			pendingKeys += string(pendingKey.Rune)
		}
	}
	text := line.message
	if status.extra != "" {
		text += " " + status.extra
	}
	message := runewidth.FillRight(text, ctx.Width()-len(pendingKeys)-5)
	ctx.Printf(0, 0, line.style, "%s%s", message, pendingKeys)
}

func (status *StatusLine) Set(text string) *StatusMessage {
	status.fallback = StatusMessage{
		style:   status.uiConfig.GetStyle(config.STYLE_STATUSLINE_DEFAULT),
		message: text,
	}
	status.Invalidate()
	return &status.fallback
}

func (status *StatusLine) SetError(text string) *StatusMessage {
	status.fallback = StatusMessage{
		style:   status.uiConfig.GetStyle(config.STYLE_STATUSLINE_ERROR),
		message: text,
	}
	status.Invalidate()
	return &status.fallback
}

func (status *StatusLine) Push(text string, expiry time.Duration) *StatusMessage {
	msg := &StatusMessage{
		style:   status.uiConfig.GetStyle(config.STYLE_STATUSLINE_DEFAULT),
		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()
	})()
	status.Invalidate()
	return msg
}

func (status *StatusLine) PushError(text string) *StatusMessage {
	msg := status.Push(text, 10*time.Second)
	msg.Color(status.uiConfig.GetStyle(config.STYLE_STATUSLINE_ERROR))
	return msg
}

func (status *StatusLine) PushSuccess(text string) *StatusMessage {
	msg := status.Push(text, 10*time.Second)
	msg.Color(status.uiConfig.GetStyle(config.STYLE_STATUSLINE_SUCCESS))
	return msg
}

func (status *StatusLine) SetExtra(text string) {
	status.extra = text
}

func (status *StatusLine) ClearExtra() {
	status.extra = ""
}

func (status *StatusLine) Expire() {
	status.stack = nil
}

func (status *StatusLine) SetAerc(aerc *Aerc) {
	status.aerc = aerc
}

func (msg *StatusMessage) Color(style tcell.Style) {
	msg.style = style
}