about summary refs log tree commit diff stats
path: root/ranger/api/__init__.py
diff options
context:
space:
mode:
authorhut <hut@lepus.uberspace.de>2016-06-18 20:01:13 +0200
committerhut <hut@lepus.uberspace.de>2016-06-18 20:01:13 +0200
commit904d3df13a96c2ded55919ff2a3ed873b8da3c9e (patch)
tree0f70975a2c808401d521a3d3ba79b13e9fbbef39 /ranger/api/__init__.py
parent6179ee16fbd49546edd3b8d720b7a7dd05e6ff54 (diff)
parent275c2d0063402323efa2477ced1c79c6ff257a11 (diff)
downloadranger-904d3df13a96c2ded55919ff2a3ed873b8da3c9e.tar.gz
Merge branch 'whitespaces' of https://github.com/stepshal/ranger
Diffstat (limited to 'ranger/api/__init__.py')
0 files changed, 0 insertions, 0 deletions
n119'>119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
package widgets

import (
	"log"

	"github.com/gdamore/tcell"

	"git.sr.ht/~sircmpwn/aerc2/config"
	"git.sr.ht/~sircmpwn/aerc2/lib"
	"git.sr.ht/~sircmpwn/aerc2/lib/ui"
	"git.sr.ht/~sircmpwn/aerc2/worker/types"
)

type MessageList struct {
	conf         *config.AercConfig
	logger       *log.Logger
	height       int
	onInvalidate func(d ui.Drawable)
	scroll       int
	selected     int
	spinner      *Spinner
	store        *lib.MessageStore
}

// TODO: fish in config
func NewMessageList(logger *log.Logger) *MessageList {
	ml := &MessageList{
		logger:   logger,
		selected: 0,
		spinner:  NewSpinner(),
	}
	ml.spinner.OnInvalidate(func(_ ui.Drawable) {
		ml.Invalidate()
	})
	// TODO: stop spinner, probably
	ml.spinner.Start()
	return ml
}

func (ml *MessageList) OnInvalidate(onInvalidate func(d ui.Drawable)) {
	ml.onInvalidate = onInvalidate
}

func (ml *MessageList) Invalidate() {
	if ml.onInvalidate != nil {
		ml.onInvalidate(ml)
	}
}

func (ml *MessageList) Draw(ctx *ui.Context) {
	ml.height = ctx.Height()
	ctx.Fill(0, 0, ctx.Width(), ctx.Height(), ' ', tcell.StyleDefault)

	if ml.store == nil {
		ml.spinner.Draw(ctx)
		return
	}

	var (
		needsHeaders []uint32
		row          int = 0
	)

	for i := len(ml.store.Uids) - 1 - ml.scroll; i >= 0; i-- {
		uid := ml.store.Uids[i]
		msg := ml.store.Messages[uid]

		if row >= ctx.Height() {
			break
		}

		if msg == nil {
			needsHeaders = append(needsHeaders, uid)
			ml.spinner.Draw(ctx.Subcontext(0, row, ctx.Width(), 1))
			row += 1
			continue
		}

		style := tcell.StyleDefault
		if row == ml.selected-ml.scroll {
			style = style.Reverse(true)
		}
		if _, ok := ml.store.Deleted[msg.Uid]; ok {
			style = style.Foreground(tcell.ColorGray)
		}
		ctx.Fill(0, row, ctx.Width(), 1, ' ', style)
		ctx.Printf(0, row, style, "%s", msg.Envelope.Subject)

		row += 1
	}

	if len(needsHeaders) != 0 {
		ml.store.FetchHeaders(needsHeaders, nil)
		ml.spinner.Start()
	} else {
		ml.spinner.Stop()
	}
}

func (ml *MessageList) Height() int {
	return ml.height
}

func (ml *MessageList) storeUpdate(store *lib.MessageStore) {
	if ml.store != store {
		return
	}
	for ml.selected >= len(ml.store.Uids) {
		ml.Prev()
	}
	ml.Invalidate()
}

func (ml *MessageList) SetStore(store *lib.MessageStore) {
	if ml.store == store {
		ml.scroll = 0
		ml.selected = 0
	}
	ml.store = store
	if store != nil {
		ml.spinner.Stop()
		ml.store.OnUpdate(ml.storeUpdate)
	} else {
		ml.spinner.Start()
	}
	ml.Invalidate()
}

func (ml *MessageList) Store() *lib.MessageStore {
	return ml.store
}

func (ml *MessageList) Selected() *types.MessageInfo {
	return ml.store.Messages[ml.store.Uids[len(ml.store.Uids)-ml.selected-1]]
}

func (ml *MessageList) Select(index int) {
	ml.selected = index
	for ; ml.selected < 0; ml.selected = len(ml.store.Uids) + ml.selected {
	}
	if ml.selected > len(ml.store.Uids) {
		ml.selected = len(ml.store.Uids)
	}
	// I'm too lazy to do the math right now
	for ml.selected-ml.scroll >= ml.Height() {
		ml.scroll += 1
	}
	for ml.selected-ml.scroll < 0 {
		ml.scroll -= 1
	}
}

func (ml *MessageList) nextPrev(delta int) {
	if ml.store == nil || len(ml.store.Uids) == 0 {
		return
	}
	ml.selected += delta
	if ml.selected < 0 {
		ml.selected = 0
	}
	if ml.selected >= len(ml.store.Uids) {
		ml.selected = len(ml.store.Uids) - 1
	}
	if ml.Height() != 0 {
		if ml.selected-ml.scroll >= ml.Height() {
			ml.scroll += 1
		} else if ml.selected-ml.scroll < 0 {
			ml.scroll -= 1
		}
	}
	ml.Invalidate()
}

func (ml *MessageList) Next() {
	ml.nextPrev(1)
}

func (ml *MessageList) Prev() {
	ml.nextPrev(-1)
}